在aosp 6.0源代码下,我想用跟踪调用状态构建fastboot,所以我添加了以下编译参数" -g -finstrument-functions"构建二进制文件。
我运行命令" readelf -s xxxxxx(我的目标二进制文件)",函数地址如下:
124: 0000000000002390 69 FUNC GLOBAL DEFAULT 14 usb_open
125: 00000000000021b0 306 FUNC GLOBAL DEFAULT 14 usb_read
126: 0000000000002080 294 FUNC GLOBAL DEFAULT 14 usb_write
127: 0000000000002340 71 FUNC GLOBAL DEFAULT 14 usb_close
128: 00000000000022f0 68 FUNC GLOBAL DEFAULT 14 usb_kick
129: 0000000000002670 151 FUNC GLOBAL DEFAULT 14 usb_wait_for_disconnect
76: 0000000000001f60 286 FUNC GLOBAL DEFAULT 14 main
我通过跟踪函数得到了运行时函数地址:
void main_constructor( void )
{
fp = fopen( "trace.txt", "w" );
if (fp == NULL) exit(-1);
}
void main_deconstructor( void )
{
fclose( fp );
}
void __cyg_profile_func_enter( void *this, void *callsite )
{
fprintf(fp, "E%p\n", (int *)this);
}
void __cyg_profile_func_exit( void *this, void *callsite )
{
fprintf(fp, "X%p\n", (int *)this);
}
但是,函数地址如下所示:
E0x7fd2a83bbf60
E0x7fd2a83bc390
E0x7fd2a83bc3e0
显然,运行时间的函数地址与可执行二进制文件的函数地址不同,运行时间比静态函数更多0X7fd2a83ba000。在谷歌搜索之后,它似乎是动态库加载模式,但我构建的是可执行二进制文件。 我想知道如何从静态二进制文件中获取相同的函数地址。然后我可以使用addr2line获取函数名称以生成调用状态图。
(顺便说一下,经过我的调查,我发现android 6.0源代码使用clang来构建主机X86 / X86_64程序,所以我猜这个问题起源于一些Clang的编译参数。在android下4.4,我可以这样做)非常感谢您的帮助!
答案 0 :(得分:1)
正在使用PIE(位置无关可执行文件)标志编译AOSP的可执行文件。当二进制文件映射到内存时,每次运行时都不会映射到完全相同的地址。将应用偏移量(基数),从而指针地址的差异。如果您确实要禁用PIE,请将LOCAL_NO_FPIE
添加到fastboot makefile(system / core / fastboot / Android.mk)。您需要在include $(CLEAR_VARS)
之后添加它。
要验证它是否未编译为PIE,请调用hardening-check <executable-file>
。