运行时的函数地址与可执行二进制文件的函数地址不同

时间:2016-03-07 09:36:40

标签: android c clang

在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,我可以这样做)

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

正在使用PIE(位置无关可执行文件)标志编译AOSP的可执行文件。当二进制文件映射到内存时,每次运行时都不会映射到完全相同的地址。将应用偏移量(基数),从而指针地址的差异。如果您确实要禁用PIE,请将LOCAL_NO_FPIE添加到fastboot makefile(system / core / fastboot / Android.mk)。您需要在include $(CLEAR_VARS)之后添加它。

要验证它是否未编译为PIE,请调用hardening-check <executable-file>