我遇到了一个问题,下面的 g++ 代码说明了这个问题:
frob.hpp:
template<typename T> T frob(T x);
template<> inline int frob<int>(int x) {
asm("1: nop\n"
".pushsection \"extra\",\"a\"\n"
".quad 1b\n"
".popsection\n");
return x+1;
}
foo.cpp:
#include "frob.hpp"
extern int bar();
int foo() { return frob(17); }
int main() { return foo() + bar(); }
bar.cpp:
#include "frob.hpp"
int bar() { return frob(42); }
我正在做这些古怪的自定义部分的事情,以此来模仿linux 内核中的机制(但以用户态和 C++ 方式)。
我的问题是实例化frob<int>
被识别为弱符号,这很好,并且两者中的一个最终被链接器忽略,这也很好。除了链接器不受该extra
部分引用该符号(通过.quad 1b
)这一事实的干扰,并且链接器希望在本地解析它们。我得到:
localhost /tmp $ g++ -O3 foo.cpp bar.cpp
localhost /tmp $ g++ -O0 foo.cpp bar.cpp
`.text._Z4frobIiET_S0_' referenced in section `extra' of /tmp/ccr5s7Zg.o: defined in discarded section `.text._Z4frobIiET_S0_[_Z4frobIiET_S0_]' of /tmp/ccr5s7Zg.o
collect2: error: ld returned 1 exit status
(-O3
很好,因为完全没有发出任何符号)。
我不知道如何解决这个问题。
- 有没有办法告诉链接器也注意该
extra
部分中的符号解析? 也许可以将本地标签换成
.weak
全球标签?例如:asm(".weak exception_handler_%=\n" "exception_handler_%=: nop\n" ".pushsection \"extra\",\"a\"\n" ".quad exception_handler_%=\n" ".popsection\n"::);
但是我担心如果我这样做,不同编译单元中的不同 asm 语句可能会通过这种机制获得相同的符号(可能吗?)。
有没有我忽略的方法?