Первый пример:
$ readelf -S t.o | grep ' .text.'
[ 1] .text PROGBITS 0000000000000000 00000040
[ 4] .text.foo PROGBITS 0000000000000000 00000040
[ 6] .text.bar PROGBITS 0000000000000000 00000060
[ 9] .text.foo2 PROGBITS 0000000000000000 000000c0
[11] .text.munch PROGBITS 0000000000000000 00000110
[14] .text.startup.mai PROGBITS 0000000000000000 00000180
Это было составлено с -ffunction-sections
и есть четыре функции, foo()
, bar()
, foo2()
и munch()
в моем файле объекта. Я могу разобрать их по отдельности, так как:
$ objdump -w -d --section=.text.foo t.o
t.o: file format elf64-x86-64
Disassembly of section .text.foo:
0000000000000000 <foo>:
0: 48 83 ec 08 sub $0x8,%rsp
4: 8b 3d 00 00 00 00 mov 0(%rip),%edi # a <foo+0xa>
a: 31 f6 xor %esi,%esi
c: 31 c0 xor %eax,%eax
e: e8 00 00 00 00 callq 13 <foo+0x13>
13: 85 c0 test %eax,%eax
15: 75 01 jne 18 <foo+0x18>
17: 90 nop
18: 48 83 c4 08 add $0x8,%rsp
1c: c3 retq
Другой вариант может быть использован, как это (nm
отвалов записей таблицы символов):
$ nm -f sysv t.o | grep bar
bar |0000000000000020| T | FUNC|0000000000000026| |.text
$ objdump -w -d --start-address=0x20 --stop-address=0x46 t.o --section=.text
t.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000020 <bar>:
20: 48 83 ec 08 sub $0x8,%rsp
24: 8b 3d 00 00 00 00 mov 0(%rip),%edi # 2a <bar+0xa>
2a: 31 f6 xor %esi,%esi
2c: 31 c0 xor %eax,%eax
2e: e8 00 00 00 00 callq 33 <bar+0x13>
33: 85 c0 test %eax,%eax
35: 75 01 jne 38 <bar+0x18>
37: 90 nop
38: bf 3f 00 00 00 mov $0x3f,%edi
3d: 48 83 c4 08 add $0x8,%rsp
41: e9 00 00 00 00 jmpq 46 <bar+0x26>
В этом случае -ffunction-sections
вариант не имеет поэтому начальное смещение функции не равно нулю, и оно не находится в отдельном разделе (но в .text
).
Остерегайтесь, хотя при разборке объектных файлов ...
Это не точно то, что вы хотите, потому что, для объектных файлов, то call
целей (а также адрес глобальных переменных) не разрешены - вы не видите здесь, что foo
звонит printf
, потому что разрешение этого на двоичном уровне происходит только во время соединения. Однако источник сборки имел бы call printf
.Информация о том, что это callq
на самом деле равна printf
, находится в объектном файле, но отдельно от кода (находится в так называемом разделе relocation, в котором перечислены местоположения в объектном файле, «пропатченные» компоновщиком); дизассемблер не может это решить.
Некоторые IDE позволят вам установить точку останова и просмотреть код сборки, сгенерированный этой функцией. Это называется * разборным окном *. Это должно делать то, что вы ищете - вы используете IDE? – Aaron
Я предпочитаю компилировать (с оптимизацией), а затем разбирать, вы должны понимать, что компилятор оставит несколько инструкций неполными для внешних адресов и т. Д., Но читать IMO легче, чем использовать -S. gcc -O2 -c hello.c -o hello.o, objdump -D hello.o –
Перейдите сюда: http://gcc.godbolt.org/ вставьте функцию, выберите компилятор, очень полезно. – harold