gpt4 book ai didi

c - 在 C 函数中定义唯一的全局程序集标签/符号

转载 作者:太空宇宙 更新时间:2023-11-04 07:52:45 24 4
gpt4 key购买 nike

我想用某种汇编器标签/符号来标记特定的 C 行,这些标签/符号不会占用二进制文件中的任何空间,但是通过检查链接器输出映射文件,我将知道所有出现的此类生成的标签,并最终知道 C以这种方式“标记”的代码。所以我希望能够定义这样的标签,并使它们成为全局标签,并使用,这样链接器就不会丢弃它我还需要一些宏魔法,让这些标签在每次预处理 C 代码时都有一个唯一的名称(以确保函数的每个内联实例都有自己的标签——我想否则我会有重复的符号)

示例:

// my build system will pass -DMYFILE_ID for each file, here I am trying to create a unique literal for each inline instance of the function
#define UN(X) #X
#define UNIQUE(X,Y) UN(X##Y)

void my_func(void)
{
_asm("GLOBAL_LABEL_"UNIQUE(MYFILE_ID,__LINE__)":\n\t")
my_c_code_I_want_to_track();
}

最后我想要的是链接器输出符号映射文件,类似的东西

0xsome_address GLOBAL_LABEL_12_1
0xdifferent_address GLOBAL_LABEL_12_2
0xyeanotheraddress GLOBAL_LABEL_13_1

这基本上应该让我知道 my_c_code_i_want_to_track 在哪些地址被实例化

整个想法有点受到汇编中标签实际上是具有位置的“符号”的启发,因此可以检查它们的地址,但它们实际上并不占用自己的空间。

问题:1.是否有可能像那样定义 assembly 标签2. 如何让这些标签在输出符号映射文件中保留和出现3. UNIQUE 宏有问题,因为我在尝试编译时得到“标签重新定义”

最佳答案

您可以在 Extended-asm template 中使用 %=(例如 label%=:)当包含 inline-asm 的函数在一个编译单元中被内联多次时,让编译器生成一个唯一的编号以避免名称冲突。

#define STRINGIFY(x) #x
#define STR(x) STRINGIFY(x)
int foo(int x) {
asm("marker" __FILE__ "_line" STR(__LINE__) "_uniqueid%=:" :::);
return x+1;
}


int caller1(int x) {
return foo(x);
}

int caller2(int x) {
return foo(x);
}

使用 gcc -O3 ( on Godbolt ) 编译成以下汇编:

foo(int):
marker/tmp/compiler-explorer-compiler11899-55-1ki0cth.pehm/example.cpp_line4_uniqueid7:
lea eax, [rdi+1]
ret
caller1(int):
marker/tmp/compiler-explorer-compiler11899-55-1ki0cth.pehm/example.cpp_line4_uniqueid22:
lea eax, [rdi+1]
ret
caller2(int):
marker/tmp/compiler-explorer-compiler11899-55-1ki0cth.pehm/example.cpp_line4_uniqueid41:
lea eax, [rdi+3]
ret

这当然不会汇编,因为 / 在 GAS 中不是有效的标签字符。

使用 MYFILE_ID,它只包含可以出现在符号名称中的字符,这会很好地组装,您应该能够看到 中的所有 marker 标签>nm 输出。

关于c - 在 C 函数中定义唯一的全局程序集标签/符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52730007/

24 4 0