你如何获得函数的原始地址?

sir*_*lot 2 c c++ assembly

我正在编写一个Jit编译器,我需要根据汇编中的(偏移)地址调用一个函数.IE,给出:

void myfunction() { }
Run Code Online (Sandbox Code Playgroud)

我希望能够获得此函数的实际地址,以便我可以通过程序集偏移来调用它.我尝试了几件事,但我得到了不同的答案:

void *address1 = (void *&)myfunction;
void (*address2)() = &myfunction;

cout << &address1 << endl; // 0x7fff5fbff800
cout << &(*address1) << endl; // 0x20ec8348e5894855
cout << &(address2) << endl; // 0x7fff5fbff808
Run Code Online (Sandbox Code Playgroud)

哪一个是正确的(如果其中任何一个是)?如果有一种我更容易忽视的方式,那么对它也很感兴趣.

更新

我做了一件聪明的事,做了一件objdump,其中说:

000000010000fd70 <__Z10myfunctionv>:
10000fe76:  48 8d 05 f3 fe ff ff    lea    -0x10d(%rip),%rax        # 10000fd70 <__Z10myfunctionv>
Run Code Online (Sandbox Code Playgroud)

所以正确答案似乎是:

cout << (void *)(void (*)())myfunction << endl; // 0x10000fd70
Run Code Online (Sandbox Code Playgroud)

以下是Eric,这是最好的答案:

cout << hex << (uintptr_t)myfunction << endl;
Run Code Online (Sandbox Code Playgroud)

Eri*_*hil 6

在C++中没有标准的方法可以做到这一点,因为标准没有定义从指针到整数或非函数指针的任何转换,也没有定义打印函数指针的任何行为,而不是将它们解释为true/false,并且函数指针总是如此true(非null).函数指针不打算从程序打印或导出.

在C中,您可以将函数指针转换为uintptr_t并打印:

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
…
    printf("0x%" PRIxPTR "\n", (uintptr_t) myfunction);
Run Code Online (Sandbox Code Playgroud)

某些C++实现允许您将函数指针强制转换为其他类型的指针或整数类型.您应确保在依赖它们之前,您正在使用的C++实现支持这些强制转换所执行的转换.在一些实现中,函数指针的值可能不是实际代码的地址; 它可能是函数描述符的地址.在这种情况下,分支到该地址是行不通的; 您需要符合平台调用函数的要求.

打印功能的地址以便在其他程序中进一步使用很可能没有任何用处.使用打印的地址来调用函数通常需要使用使用从打印派生的地址的新代码重新编译程序,并且更改程序然后重新编译可能会更改函数的地址.从程序集调用函数的常用方法是将其地址通过常规链接机制提供给汇编代码(在程序集中按名称引用它,让链接器解析引用)或者通过将指针传递给函数作为参数组装例程.

另一种选择是将函数放在动态库中,在这种情况下,可以通过动态加载器的功能(例如dlsym例程)查找其地址.