我想用某种汇编标签/符号标记特定的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.是否有可能像这样定义装配标签 2.如何使这些标签停留并出现在输出符号映射文件中 3. UNIQUE宏出了点问题,因为在尝试编译时会得到“标签重新定义”
答案 0 :(得分:2)
您可以在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)编译为以下asm:
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
标签。 / p>
答案 1 :(得分:0)
一个问题是,由于内联,您可能会获得同一标签的多个副本。将以下属性添加到包含这些标签的函数中:
__attribute__((noinline))
还请注意,您需要将符号标记为全局符号。让我们将其提取到宏中,以便我们可以很好地格式化而不更改__LINE__
的值:
#define MAKE_LABEL \
__asm__( \
"GLOBAL_LABEL_" UNIQUE(MYFILE_ID, __LINE__) ":" \
"\n\t.global GLOBAL_LABEL_" UNIQUE(MYFILE_ID, __LINE__) \
)
但是宏扩展已关闭。不幸的是,我无法向您解释为什么这样做。但这是正确的宏定义:
#define UN(X) #X
#define UNIQUE2(X,Y) UN(X##Y)
#define UNIQUE(X,Y) UNIQUE2(X,Y)
否则,您将获得__LINE__
而不是23。