为什么 gcc 不支持裸函数?

问题描述 投票:0回答:4

我使用裸函数在程序运行时修补部分程序。我可以在 Windows 的 VC++ 中轻松地做到这一点。我正在尝试在 Linux 中执行此操作,但 gcc 似乎不支持裸函数。用裸函数编译代码给我这个:警告:‘naked’属性指令被忽略。在 CentOS 5.5 i386 下编译。

c++ linux gcc g++
4个回答
6
投票

根据 docs

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

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

我不知道为什么。


4
投票

===更新===

截至 2023 年,他们开始工作:

__attribute__((naked))    
void my_write(int fd, char const* str, int size) {
    asm
    (
    "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);
}

使用

gcc -m32 -nostdlib my_write.c
gcc version 10.2.1 20210110 (Debian 10.2.1-6)

编译

===旧答案===

在 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函数属性中,所以我想它适用于较新的gcc。


2
投票

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


1
投票

GCC 仅支持 ARM 和其他嵌入式平台上的裸函数。 http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

另外,你所做的本质上是不安全的,因为你不能保证你正在修补的代码在程序运行时不会执行。

© www.soinside.com 2019 - 2024. All rights reserved.