Search code examples
assemblygcclinkerbinutils

Trying to no-op an instruction


Is it possible using GNU tools (gcc, binutils, etc) to modify all occurrences of an assembly instruction into a no-op? Specifically, gcc with the -pg option generates the following assembly (ARM):

   0x0: e1a0c00d    mov ip, sp
   0x4: e92dd800    stmdb   sp!, {fp, ip, lr, pc}
   0x8: e24cb004    sub fp, ip, #4  ; 0x4
   0xc: ebfffffe    bl  0 <mcount>

I want to record the address of this last instruction, and then change it to a nop like in the following code

   0x0: e1a0c00d    mov ip, sp
   0x4: e92dd800    stmdb   sp!, {fp, ip, lr, pc}
   0x8: e24cb004    sub fp, ip, #4  ; 0x4
   0xc: e1a00000    nop         (mov r0,r0)

The Linux kernel can do something similar to this at run-time, but I'm looking for a build-time solution.


Solution

  • This will certainly be easier with a RISC-ish fixed-length instruction format than for e.g. x86.

    It should be relatively straightforward to use libelf (nice tutorial here: http://people.freebsd.org/~jkoshy/download/libelf/article.html) or libbfd (http://sourceware.org/binutils/docs-2.19/bfd/index.html) to open the object file, modify instructions within the .text section, and write it out again using provided APIs. Whether it's worth the effort or not will depend on non-technical considerations (I am a bit curious though...).

    It's worth mentioning that there might be a few wrinkles with using libelf or libbfd if this needs to work in a cross-development environment.