macosobjectdisassemblyobjdumpotool

How to just print the binary code of a function in an object file?


I am able to disassemble an object file like below. But I'd like to just dump the raw number like 55, 48, ... of instructions in a binary format for a specific function, e.g., add4, to a file.

I could write a program to parse the output of otool. But is there an easier way to do so?

My OS is Mac OS X.

$ cat add.c
long x;
long add2(long num) {
  return num + 2;
}
long add4(long num) {
  return num + 4;
}
$ clang -c -o add.o add.c
$ otool -tvjV add.o 
add.o:
(__TEXT,__text) section
_add4:
0000000000000000    55  pushq   %rbp
0000000000000001    48 89 e5    movq    %rsp, %rbp
0000000000000004    48 89 7d f8     movq    %rdi, -0x8(%rbp)
0000000000000008    48 8b 7d f8     movq    -0x8(%rbp), %rdi
000000000000000c    48 83 c7 04     addq    $0x4, %rdi
0000000000000010    48 89 f8    movq    %rdi, %rax
0000000000000013    5d  popq    %rbp
0000000000000014    c3  retq
0000000000000015    66 2e 0f 1f 84 00 00 00 00 00   nopw    %cs:_add4(%rax,%rax)
000000000000001f    90  nop
_add2:
0000000000000020    55  pushq   %rbp
0000000000000021    48 89 e5    movq    %rsp, %rbp
0000000000000024    48 89 7d f8     movq    %rdi, -0x8(%rbp)
0000000000000028    48 8b 7d f8     movq    -0x8(%rbp), %rdi
000000000000002c    48 83 c7 02     addq    $0x2, %rdi
0000000000000030    48 89 f8    movq    %rdi, %rax
0000000000000033    5d  popq    %rbp
0000000000000034    c3  retq

Solution

  • You can use nm -nU add.o to get the symbol addresses. You can search for the symbol of interest and get its address and the subsequent address. That gives you the start and (roughly) length of the symbol. Then, you can use any tool for hex dumping from a file to read just that portion.

    For example:

    exec 3< <(nm -nU add.o | grep -A1 -w _add4 | cut -d ' ' -f 1)
    read start <&3
    read end <&3
    3<&-
    offset=$(otool -lV add.o | grep -A3 -w "segname __TEXT" | grep -m1 offset | cut -c 12-)
    if [ -n "$end" ] ; then length_arg="-n $(( "0x$end" - "0x$start" ))" ; fi
    hexdump -C -s $((0x$start + $offset)) $length_arg add.o