Я пытаюсь разобраться в исполняемом коде, который GCC (4.4.3) генерирует для машины x86_64, работающей под управлением Ubuntu Linux. В частности, я не понимаю, как код отслеживает кадры стека. В старые времена, в 32-битном коде, я привык видеть этот «пролог» почти в каждой функции:
push %ebp
movl %esp, %ebp
Затем, в конце функции, должен был быть «эпилог», либо
sub $xx, %esp # Where xx is a number based on GCC's accounting.
pop %ebp
ret
или просто
leave
ret
который выполняет то же самое:
- Установите указатель стека в верхнюю часть текущего кадра, чуть ниже адреса возврата.
- Восстановите старое значение указателя кадра.
В 64-битном коде, как я вижу при дизассемблировании objdump, многие функции не следуют этому соглашению — они не передают %rbp, а затем сохраняют %rsp в %rbp. Как отладчик, такой как GDB, строит трассировку?
Моя реальная цель здесь состоит в том, чтобы попытаться выяснить разумный адрес, который следует рассматривать как вершину (самый высокий адрес) пользовательского стека, когда выполнение достигает начала произвольной функции дальше в программе, где, возможно, указатель стека переместился вниз. Для «верха», например, исходный адрес argv был бы идеальным, но у меня нет доступа к нему из произвольной функции, которую вызывает main. Сначала я подумал, что могу использовать старый метод обратной трассировки: отслеживание сохраненных значений указателя кадра до тех пор, пока сохраненное значение не станет равным 0, а затем следующее после этого может считаться наивысшим практическим значением. (Это не то же самое, что получить адрес argv, но сгодится, скажем, чтобы узнать значение указателя стека в _start или что-то еще, что вызывает _start [например, __libc_start_main].) Теперь я не знаю, как получить эквивалентный адрес в 64-битном коде.
Спасибо.
-fomit-frame-pointer
. - person jørgensen   schedule 24.12.2011libunwind
может быть полезен. - person Nemo   schedule 25.12.2011sub $xx, %esp
является частью пролога. Он резервирует место в стеке. Эпилог делаетadd $xx, %esp
, чтобы вернуть указатель стека на то, что нужно извлечь. (Или в простых случаяхleave
включаетmov %ebp, %esp
, поэтому вы можете использовать его без предварительной настройки ESP. .) - person Peter Cordes   schedule 01.12.2016