次の 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(); }
バー.cpp:
#include "frob.hpp"
int bar() { return frob(42); }
ここでLinuxカーネルのメカニズムを模倣する方法として、これらの風変わりなカスタムセクションのことを行っています(ただし、ユーザーランドとC++の方法で)。
私の問題は、のインスタンス化がfrob<int>
弱いシンボルとして認識されることです。これは問題ありません。2 つのうちの 1 つが最終的にリンカーによって省略されますが、これも問題ありません。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 ステートメントがこのメカニズムを介して同じシンボルを取得する可能性があるのではないかと心配しています (そうでしょうか?)。
私が見落とした回避策はありますか?