Question

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.

Was it helpful?

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.

OTHER TIPS

You can compile the code with gcc -S to output an assembler listing, instead of compiling fully into an object file or executable. Then, just replace the desired instructions with no-ops (e.g. using sed), and continue compilation from there.

If you also want to do this for object files or libraries that you don't have the original source code for, you'll instead have to use a tool such as objdump(1) to disassemble them and get the addresses of the instructions you wish to replace. Then, parse the object file headers to find the offsets within the file of those instructions, and then replace the machine instructions with no-ops directly in the object files. This is a little trickier, but doable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top