Comment bien utiliser un simple éditeur de liens (linker script? Executable est SIGKILL lors de l'exécution
J'essaie de comprendre plus profondément processus de liaison et de linker scripts...en regardant binutils doc, j'ai trouvé un simple éditeur de liens (linker script de mise en œuvre que je me suis amélioré par l'ajout de certaines commandes:
OUTPUT_FORMAT("elf32-i386", "elf32-i386",
"elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(mymain)
SECTIONS
{
. = 0x10000;
.text : { *(.text) }
. = 0x8000000;
.data : { *(.data) }
.bss : { *(.bss) }
}
Mon programme est un programme très simple:
void mymain(void)
{
int a;
a++;
}
Maintenant, j'ai essayé de créer un fichier exécutable:
gcc -c main.c
ld -o prog -T my_script.lds main.o
Mais si j'essaie de le lancer prog
il reçoit un SIGKILL
lors du démarrage. Je sais que lorsqu'un programme est compilé et lié avec la commande:
gcc prog.c -o prog
l'exécutable final est le produit également d'autres fichiers de l'objet comme crt1.o
, crti.o
et crtn.o
mais qu'en est mon dossier? Qui est la façon correcte d'utiliser ce linker scripts?
Vous devez vous connecter pour publier un commentaire.
Je soupçonne que votre code s'exécute correctement, et avoir des ennuis à la fin: qu'attendez-vous pour arriver après la
a++
?mymain()
est juste un ordinaire C de la fonction, qui va essayer de revenir à son appelant.Mais vous aurez défini comme l'ELFE de point d'entrée, qui raconte le chargeur ELF pour sauter une fois qu'il a chargé les segments de programme à la bonne place, et il ne vous attendez pas à revenir.
Ces "autres fichiers objets comme
crt1.o
,crti.o
etcrtn.o
" normalement gérer ce genre de choses pour les programmes en C. L'ELFE point d'entrée pour un programme C n'est pasmain()
- au lieu de cela, c'est une surcouche qui met en place un environnement approprié pour lesmain()
(ex. mise en place de laargc
etargv
arguments sur la pile ou dans les registres, en fonction de plate-forme), les appelsmain()
(avec l'espoir qu'il peut retourner), puis appelle laexit
appel système (avec le code de retour demain()
).[Mise à jour à la suite des commentaires:]
Quand j'essaie votre exemple avec
gdb
, je vois qu'il ne fait échouer sur le retour demymain()
: après avoir défini un point d'arrêt surmymain
, puis marcher à travers les instructions, je vois qu'il effectue l'incrément, puis est en difficulté dans la fonction épilogue:Pour i386 au moins, le chargeur ELF met en place un sensible de la pile avant d'entrer dans le code chargé, de sorte que vous peut ensemble de l'ELFE point d'entrée à une fonction C et obtenez comportement raisonnable; cependant, comme je l'ai mentionné ci-dessus, vous devez gérer la sortie d'un processus propre à vous-même. Et si vous n'êtes pas à l'aide de la C runtime, vous feriez mieux de ne pas être à l'aide de bibliothèques qui dépendent de la C runtime soit.
Voici donc un exemple de cela, à l'aide de l'original de votre linker script mais avec le code C modifié pour initialiser
a
à une valeur connue, et invoquer unexit
appel système (à l'aide d'assembly en ligne) avec la valeur finale dea
que le code de sortie. (Note: j'ai juste réalisé que vous n'avez pas dit exactement ce que la plateforme que vous utilisez, je suis en supposant que Linux ici.)main
autre fonction est appelée, par exemple ctors je pense. Mais si je voulais un autre nom pourmain
où dois-je préciser que? Et, si j'ai un lien sur mon programme explicitement avecld
doit je passe aussi en c d'exécution de l'objet de fichiers?main
: qu'est ce que la C runtime appels. (Ce n'est pas la même chose que l'ELFE point d'entrée, ce qui est normalement_start
danscrt1.o
.) Si vous êtes en invoquantld
directement, alors oui, vous devez le lien entre les divers C runtime fichiers vous-même. Si vous utilisezgcc
, il le fera pour vous. Vous pouvez voir ce qu'il fait avecgcc -v
, mais vous devez savoir qu'il invoqueld
via un wrapper,collect2
(voir ici).During startup program terminated with signal SIGKILL, Killed.
, donc je ne peux même pas démarrer le débogage. Je suis en utilisantgcc 4.4.5
.oui pour fonctionner sur linux, nous avons besoin de changer .lds fichier