为什么 gcc 不支持裸函数?
Why doesn't gcc support naked functions?
我使用裸函数在程序运行时修补部分程序。我可以很容易地在Windows的vc++中做到这一点。我试图在Linux中做到这一点,似乎gcc不支持裸函数。用naked函数编译代码会得到这样的结果:warning: ' naked '属性指令被忽略。在CentOS 5.5 i386下编译
根据文档,naked属性仅在某些平台(ARM, AVR, MCORE, RX和SPU)上由GCC支持:
naked
:在ARM, AVR, MCORE, RX和SPU端口上使用此属性指示指定的函数不需要序言/尾声编译器生成的序列。这取决于程序员提供这些序列。唯一可以安全的语句包含在裸函数中的asm语句没有操作数。所有其他语句,包括local的声明应该避免使用变量、if语句等。裸体函数应用于实现程序集的主体函数,同时允许编译器构造必要的汇编器的函数声明。
我不知道为什么
= = = = = =更新
截至2023年,它们确实有效:
__attribute__((naked))
void my_write(int fd, char const* str, int size) {
asm
(
" pusha nt"
" movl $4, %eax nt"
" movl 36(%esp), %ebx nt"
" movl 40(%esp), %ecx nt"
" movl 44(%esp), %edx nt"
" int $0x80 nt"
" popa nt"
" ret nt"
);
}
void _start() {
my_write(1, "hin", 3);
my_write(1, "byen", 4);
}
用gcc version 10.2.1 20210110 (Debian 10.2.1-6)
编译gcc -m32 -nostdlib my_write.c
===旧答案===
在x86上,您可以通过在全局作用域中使用asm来解决这个问题:
void my_write(int fd, const void *buf, int count);
asm
(
".global my_write nt"
"write: nt"
" pusha nt"
" movl $4, %eax nt"
" movl 36(%esp), %ebx nt"
" movl 40(%esp), %ecx nt"
" movl 44(%esp), %edx nt"
" int $0x80 nt"
" popa nt"
" ret nt"
);
void _start()
{
my_write(1, "hin", 3);
my_write(1, "byen", 4);
}
也naked
在x86函数属性中列出,所以我想它适用于较新的gcc。
GCC只支持ARM和其他嵌入式平台上的裸函数。http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
而且,您所做的事情本质上是不安全的,因为如果程序正在运行,您不能保证您正在修补的代码没有执行。
这是一个丑陋的解决方案。指向目标体系结构的.asm文件的链接。
- Casablanca/cpprestsdk listener.support接受函数,但不支持方法
- 为什么向量不支持 size 作为成员变量,就像 Java 类中的长度变量一样,而是函数 size()?
- C++11 NVCC 不支持函数 iota()?
- 如何将 MATLAB 图像处理库内置函数转换为 MATLAB 编码器代码生成不支持的 C++?
- PGI 不支持 OpenMP 4.5 运行时函数
- createProcessWithLogon返回不支持的函数
- QT快速UI表单不支持函数
- 错误C4430:丢失类型指定词 - 假设INT.注意:C 不支持对我的构造函数的默认设置
- 聚合初始化不支持构造函数访问
- 为什么 g++ 不支持在 Ubuntu 上使用分配器构造函数?
- 我的 cipher() 函数似乎不支持大写字母
- Matlab 编码器不支持的函数
- 函数指针是否不支持C++中的实例类型
- clang 3.5中不支持-finline函数
- Matlab Codegen:不支持匿名函数
- java.lang.IllegalArgumentException:函数参数0处不支持的参数
- 为什么C++"标准"不支持另一个函数中的函数定义?
- 为什么 gcc 不支持裸函数?
- 调用函数时不支持间接强制转换
- 对于不支持RTLD_DEEPBIND的平台,是否有替代 dlopen() 函数中 dlopen() 函数中的标志RTLD_DEEPBIND?