assembly 链接时,同一汇编文件中的函数/符号是否可以重新排序到不同的虚拟地址?

chhkpiq4  于 2023-03-30  发布在  其他
关注(0)|答案(1)|浏览(130)

我有一些用汇编语言编写的代码,需要在运行时复制(复制的代码是用C语言编写的),因此我需要得到函数的大小。我在汇编语言中这样编写了函数:

.globl function_foo
function_foo:
        ...
        ...
.globl function_foo_end
function_foo_end:
extern void function_foo(void);
extern void function_foo_end(void);

memcpy(dest, function_foo, (uintptr_t)function_foo_end - (uintptr_t)function_foo);

代码按预期工作,但我担心如果链接过程对符号进行了重新排序,例如如果function_foo_end被移动到function_foo之前,或者如果function_foofunction_foo_end在内存中不连续,那么memcpy可能会复制错误的大小。
是否保证这些符号在内存中是有序且连续放置的?

r6hnlfcb

r6hnlfcb1#

链接器以节的粒度工作,因此只要标签在同一个.text块中,链接器就不会将它们分开。
有一些链接后优化工具(如BOLT)可以对二进制代码进行更积极的转换,包括移动标签。
一种替代方法是将程序编译两次:

  • 第一个测试构建只是提取函数大小(通过readelf或类似方法)
  • 然后你可以通过宏(-DFUNC_SIZE=...)将提取的大小传递给第二次编译

相关问题