内联装配中的弱符号和自定义截面
weak symbols and custom sections in inline assembly
我遇到了一个问题,由以下 g++ 代码说明:
frob.hpp:
template<typename T> T frob(T x);
template<> inline int frob<int>(int x) {
asm("1: nopn"
".pushsection "extra","a"n"
".quad 1bn"
".popsectionn");
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>
的实例化被识别为弱符号,这很好,并且两者中的一个最终被链接器省略,这也很好。除了链接器不会受到以下事实的干扰: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_%=: nopn" ".pushsection "extra","a"n" ".quad exception_handler_%=n" ".popsectionn"::);
但是,我担心如果我这样做,不同编译单元中的不同 asm 语句可能会通过这种机制获得相同的符号(他们可以吗?
有没有我忽略的方法?
g++(至少 5,6)编译一个带有外部链接的内联函数 - 例如template<> inline int frob<int>(int x)
- 全球疲软 [COMDAT] [功能部分] 中的符号 它自己的部分组。看:-
g++ -S -O0 bar.cpp
酒吧。
.file "bar.cpp"
.section .text._Z4frobIiET_S0_,"axG",@progbits,_Z4frobIiET_S0_,comdat
.weak _Z4frobIiET_S0_
.type _Z4frobIiET_S0_, @function
_Z4frobIiET_S0_:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
#APP
# 8 "frob.hpp" 1
1: nop
.pushsection "extra","a"
.quad 1b
.popsection
# 0 "" 2
#NO_APP
movl -4(%rbp), %eax
addl $1, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
...
...
相关指令是:
.section .text._Z4frobIiET_S0_,"axG",@progbits,_Z4frobIiET_S0_,comdat
.weak _Z4frobIiET_S0_
(编译器生成的#APP
和#NO_APP
分隔内联程序集)。
像extra
编译器一样,在 一个部分组:
frob.hpp (固定)
template<typename T> T frob(T x);
template<> inline int frob<int>(int x) {
asm("1: nopn"
".pushsection "extra", "axG", @progbits,extra,comdat" "n"
".quad 1bn"
".popsectionn");
return x+1;
}
并且链接错误将得到纠正:
$ g++ -O0 foo.cpp bar.cpp
$ ./a.out; echo $?
61
相关文章:
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- C++自定义比较函数
- 如何比较自定义类的std::变体
- std::设置自定义比较器
- 如何正确实现和访问运算符的各种自定义枚举器
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 自定义先决条件对移动分配运算符有效吗
- 内联装配中的弱符号和自定义截面
- 自定义 Python 构建 - time.so:未定义的符号:PyExc_ValueError
- 在 TensorFlow 中加载自定义操作时出现未定义的符号错误
- 未解决的外部符号,具有自定义阻塞队列实现
- G 自定义动态库链接错误未定义符号
- 如何将自定义类指针转换为无符号int
- Python ImportError-未定义的符号-用于自定义C++模块
- 实现自定义非线性最小化,从符号数学到C
- 无符号短至自定义浮点数 16 位
- 与自定义命名空间的链接失败未解析的外部符号
- 使用自定义谓词的Unordered_set导致链接器错误(重复符号)
- Qt设计器未定义符号与自定义小部件插件