我需要可执行文件中代码段的位置(begin和ebn地址)。我试图使用两个虚函数:
void begin_address(){}
void f(){
...
}
void end_address(){}
...
printf("Function length: %td\n", (intptr_t)end_address - (intptr_t)begin_address);
问题是,-O4
使用gcc
进行优化时,我得到了一个负长度。似乎这不适用于优化。
我将f
编译为程序集,并尝试了以下内容:
__asm__(
"func_begin:"
"movq $10, %rax;"
"movq $20, %rbx;"
"addq %rbx, %rax;"
"func_end:"
);
extern unsigned char* func_begin;
extern unsigned char* func_end;
int main(){
printf("Function begin and end address: %p\t%p\n", func_begin, func_end);
printf("Function length: %td\n", (intptr_t)func_end - (intptr_t)func_begin);
}
问题在于,即使没有优化,我也会得到一些奇怪的输出:
Function begin and end address: 0x480000000ac0c748 0xf5158b48e5894855
Function length: -5974716185612615411
如何在可执行文件中获取函数的位置?我的第二个问题是,const char*
是否安全,是否提及此地址。如果存在差异,我对32位和64位解决方案感兴趣。
答案 0 :(得分:1)
如果要查看函数在二进制文件中占用的字节数,可以使用objdump反汇编二进制文件以查看函数的第一个ip和最后一个ip。或者你可以打印$ ebp - $ esp如果你想知道一个函数在堆栈上使用了多少空间。
答案 1 :(得分:0)
如果您有可行的选择,请告诉gcc使用-O0
编译所需的部分:
#include <stdio.h>
#include <stdint.h>
void __attribute__((optimize("O0"))) func_begin(){}
void __attribute__((optimize("O0"))) f(){
return;
}
void __attribute__((optimize("O0"))) func_end(){}
int main()
{
printf("Function begin and end address: %p\t%p\n", func_begin, func_end);
printf("Function length: %td\n", (uintptr_t)func_end - (uintptr_t)func_begin);
}
我不确定__attribute__((optimize("O0")))
是否需要f()
。
答案 2 :(得分:0)
我不了解GCC,但对于某些Microsoft编译器或某些版本的Visual Studio,如果您在调试模式下构建,它会为函数条目创建一个跳转表,然后跳转到实际函数。在发布模式下,它通常不使用跳转表。
我认为大多数链接器都有一个地图输出选项,至少会显示功能的偏移量。
您可以使用可以搜索的asm指令:
movel $12345678,eax ;search for this instruction
这适用于Microsoft C / C ++ 4.1,VS2005和VS2010发布版本:
#include <stdio.h>
void swap(char **a, char **b){
char *temp = *a;
*a = *b;
*b = temp;
}
void sortLine(char *a[], int size){
int i, j;
for (i = 0; i < size; i++){
for (j = i + 1; j < size; j++){
if(memcmp(a[i], a[j], 80) > 0){
swap(&a[i], &a[j]);
}
}
}
}
int main(int argc, char **argv)
{
void (*pswap)(char **a, char **b) = swap;
void (*psortLine)(char *a[], int size) = sortLine;
char *pfun1 = (void *) pswap;
char *pfun2 = (void *) psortLine;
printf("%p %p %x\n", pfun1, pfun2, pfun2-pfun1);
return(0);
}