2016-05-13 4 views
1

Я пытаюсь получить адрес возврата на __builtin_return_address() в OS X:Как отключить перенос .text в OS X?

/* foo.c */ 
#include <stdio.h> 

void foo() { 
    printf("return address: %p\n", __builtin_return_address(0)); 
} 

int main() { 
    foo(); 
} 

bash-3.2$ clang foo.c 
bash-3.2$ nm a.out 
0000000100000000 T __mh_execute_header 
0000000100000f40 T _foo 
0000000100000f70 T _main 
       U _printf 
       U dyld_stub_binder 

Однако, он не возвращает адрес, я хочу.

bash-3.2$ ./a.out 
return address: 0x10c25cf79 
bash-3.2$ atos -o a.out 0x10c25cf79 
0x10c25cf79         

Это хорошо работает в LLDB.

bash-3.2$ lldb a.out 
(lldb) target create "a.out" 
Current executable set to 'a.out' (x86_64). 
(lldb) r 
Process 77500 launched: '/private/tmp/a.out' (x86_64) 
return address: 0x100000f79 
Process 77500 exited with status = 0 (0x00000000) 
(lldb) q 
bash-3.2$ atos -o a.out 0x100000f79 
main (in a.out) + 9                

Что происходит и как я могу это решить?

+0

я уверен, что это связано с функцией безопасности [ASLR] (https://en.wikipedia.org/wiki/Address_space_layout_randomization), найденной на многих современных реализаций ОС. Размер страницы памяти в OS X (Darwin) составляет 4KiB (4096 байт), что компенсирует вашу адресацию на страницах «49756», то есть 0xC25C000. Я считаю, что это тот же размер страницы для x86 [-64] для Linux тоже. Не уверен в отношении других BSD и т. Д. Я понимаю, что LLDB отключает ASLR - по-видимому, потому, что упрощает отладку при повторных запусках. Возможно, вы можете отключить ASLR для нормального выполнения ... –

+0

@BrettHale Он работал, когда я отключил ASLR. Спасибо! –

ответ

1

@BrettHale ответил в комментарии. Это вызвано ASLR.

Отключение ASLR на -no_pie вариант разрешает эту проблему.

$ clang -Wl,-no_pie foo.c 
$ ./a.out 
return address: 0x100000f79 
+0

Я не был уверен, что * как * отключить его, или если это единственный механизм. Вы должны быть готовы принять свой собственный ответ. –

+0

Еще раз спасибо @BrettHale! –

Смежные вопросы