为什么gcc不支持裸函数?

jfgube3f  于 2023-03-23  发布在  其他
关注(0)|答案(4)|浏览(175)

我使用裸函数在程序运行时修补程序的一部分。我可以在Windows的VC++中轻松做到这一点。我试图在Linux中做到这一点,似乎gcc不支持裸函数。用裸函数编译代码给我带来了这样的好处:警告:'naked'属性指令被忽略。在CentOS 5.5 i386下编译。

piah890a

piah890a1#

根据docs,GCC仅在某些平台(ARM、AVR、MCORE、RX和SPU)上支持裸属性:

一月一日:在ARM、AVR、MCORE、RX和SPU端口上使用此属性表示指定函数不需要编译器生成的序言/结尾序列。由程序员提供这些序列。裸函数中可以安全包含的唯一语句是没有操作数的asm语句。所有其他语句,包括局部变量的声明、if语句等,裸函数应该用来实现汇编函数的主体,同时允许编译器为汇编器构造必需的函数声明。

我不知道为什么。

xdyibdwo

xdyibdwo2#

===更新===

截至2023年,他们工作:

__attribute__((naked))    
void my_write(int fd, char const* str, int size) {
    asm
    (
    "       pusha                              \n\t"
    "       movl   $4, %eax                    \n\t"
    "       movl   36(%esp), %ebx              \n\t"
    "       movl   40(%esp), %ecx              \n\t"
    "       movl   44(%esp), %edx              \n\t"
    "       int    $0x80                       \n\t"
    "       popa                               \n\t"
    "       ret                                \n\t"
    );
}

void _start() {
    my_write(1, "hi\n", 3);
    my_write(1, "bye\n", 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                          \n\t"
"write:                                    \n\t"
"       pusha                              \n\t"
"       movl   $4, %eax                    \n\t"
"       movl   36(%esp), %ebx              \n\t"
"       movl   40(%esp), %ecx              \n\t"
"       movl   44(%esp), %edx              \n\t"
"       int    $0x80                       \n\t"
"       popa                               \n\t"
"       ret                                \n\t"
);

void _start()
{
    my_write(1, "hi\n", 3);
    my_write(1, "bye\n", 4);
}

naked也列在x86 function attributes中,所以我认为它适用于较新的gcc。

up9lanfz

up9lanfz3#

这是一个丑陋的解决方案。链接到目标架构的.asm文件。

ndh0cuux

ndh0cuux4#

GCC只支持ARM和其他嵌入式平台上的裸函数。http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
此外,您所做的事情本质上是不安全的,因为您无法保证正在修补的代码在程序运行时不会执行。

相关问题