为什么 gcc 不支持裸函数?

Why doesn't gcc support naked functions?

本文关键字:函数 不支持 gcc 为什么      更新时间:2023-10-16

我使用裸函数在程序运行时修补部分程序。我可以很容易地在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文件的链接。