8
votes

Pourquoi GCC ne supporte-vous pas les fonctions nues?

J'utilise des fonctions nues pour corriger des parties d'un programme pendant son exécution. Je peux facilement le faire en VC ++ dans Windows. J'essaie de le faire sous Linux et il semble que GCC ne supporte pas les fonctions nues. Compilation de code avec des fonctions nues me donne ceci: AVERTISSEMENT: «Naked» Directive Attribut Ignoré. Compilé sous Centos 5.5 I386.


1 commentaires

Cela semble être une caractéristique particulière de VC: MSDN .microsoft.com / fr-US / US / Bibliothèque / 21D5KD3A (v = vs.80) .aspx


4 Réponses :


6
votes

L'attribut nu n'est supporté que par GCC sur certaines plates-formes (ARM, AVR, MCORE, RX et SPU) en fonction du docs :

nu : Utilisez cet attribut sur les ports ARM, AVR, MCORE, RX et SPU indiquer que la fonction spécifiée n'a pas besoin de prologue / épilogue séquences générées par le compilateur. Il appartient au programmeur de fournir ces séquences. Les seules déclarations qui peuvent être en sécurité inclus dans les fonctions nues sont des déclarations d'ASM qui n'ont pas opérandes. Toutes les autres déclarations, y compris les déclarations de local Les variables, si des déclarations, etc., devraient être évitées. Nu Les fonctions doivent être utilisées pour mettre en œuvre le corps d'un assemblage fonction, tout en permettant au compilateur de construire la condition requise Déclaration de fonction pour l'assembleur.

Je ne suis pas sûr de savoir pourquoi.


2 commentaires

Pourquoi n'avez-vous besoin que d'utiliser des déclarations d'ASM qui n'ont pas d'opérande? Ne pas presque toutes les commandes ont des opérandes (même des choses comme JMP prendre un opérande)?


@Seth: Les instructions utilisées dans le code de l'assembleur peuvent avoir des opérandes, mais une "déclaration ASM" ne signifie pas l'instruction Assembler, c'est l'ensemble ASM ("Certains insnications": sortieBlah: INPUTBLAH: CLOBERBERBLAH); . Les "blahs" sont les opérandes de la déclaration ASM, et c'est ce que vous ne pouvez pas utiliser si vous n'avez pas le prologue généré par le compilateur. Vous pouvez écrire Assembler, mais vous ne pouvez pas l'accrocher aux variables C.



1
votes

GCC prend uniquement en charge les fonctions nues sur les bras et autres plates-formes intégrées. http://gcc.gnu.org/onlinedocs/gcc/function-atributes.html

Aussi, ce que vous faites est intrinsèquement dangereux, car vous ne pouvez pas garantir que le code que vous corrigez n'est pas exécuté si le programme est en cours d'exécution.


0 commentaires

2
votes

C'est une solution laide. Lien contre un fichier .ASM pour votre architecture cible.


0 commentaires

3
votes

On x86 Vous pouvez planer des opérations de contournement en utilisant ASM à la portée globale à la place:

int write(int fd, const void *buf, int count);                                            

asm                                                                              
(                                                                                
".global 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()                                                                    
{                                                                                
#define w(x) write(1, x, sizeof(x));                                             
    w("hello\n");                                                                
    w("bye\n");                                                                  
}                                                                                


0 commentaires