[asm/c++] correct linken van crt*.o

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Robbiedobbie
  • Registratie: Augustus 2009
  • Laatst online: 16-09 19:30
Hey allemaal,

Ik ben sinds kort bezig aan een eigen simpele kernel te schrijven, puur voor de ervaring en het opdoen van kennis.

Nu is het mij bekend dat wanneer ik c++ gebruik, dat de constructors van globale objecten niet gecalled worden, aangezien dit zelf gedaan moet worden tijdens het laden van een programma. Zelf wil ik dit dus al doen, voordat de main van de kernel aangeroepen wordt.

Ik heb onderzoek zitten doen, en ik weet dat je hiervoor bepaalde files vanuit gcc mee moet linken met je eigen gemaakte files die dan gecombineerd worden, en een _init en een _fini functie maken.

Momenteel doe ik het volgende (ik heb wat code van osdev.org geleend om te kijken of ik het daarmee wel werkend krijg):
Ik heb 2 eigen files gemaakt, die de daadwerkelijke functies diffinieren (crti.s en crtn.s)
GAS: crti.s
1
2
3
4
5
6
7
8
9
10
11
12
13
.section .init
.global _init
.type _init, @function
_init:
        push %ebp
        movl %esp, %ebp

.section .fini
.global _fini
.type _fini, @function
_fini:
        push %ebp
        movl %esp, %ebp

GAS: crti.s
1
2
3
4
5
6
7
.section .init
        popl %ebp
        ret

.section .fini
        popl %ebp
        ret


Deze files creeren crti.o en crtn.o. Deze moeten dan samen gelinked worden met de loader, en met crtbegin.o en crtend.o van gcc.

Momenteel link ik als volgt:
code:
1
ld -m elf_i386 -T link.ld -nostdlib -o kernel loader.o crti.o /usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/32/crtbegin.o kernel_main.o /usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/32/crtend.o crtn.o


Hierbij zou de volgorde belangrijk zijn, en die is voor zover ik heb kunnen vinden: "loader, crti, crtbegin, {overige objecten}, crtend, crtn". Tijdens dit linken, zou er losse code die in de init en fini secties van crtbegin en crtend staan moeten worden geplaatst tussen de de code in je eigen crti en crtn. Dit gebeurt echter niet. Mijn uiteindelijke secties zien uit alsvolgt (disassembled):

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Disassembly of section .init:

00100369 <_init>:
  100369:   55                      push   %ebp
  10036a:   89 e5                   mov    %esp,%ebp
  10036c:   5d                      pop    %ebp
  10036d:   c3                      ret    

Disassembly of section .fini:

0010036e <_fini>:
  10036e:   55                      push   %ebp
  10036f:   89 e5                   mov    %esp,%ebp
  100371:   5d                      pop    %ebp
  100372:   c3                      ret


Mijn loader bestaat gewoon uit een _start functie in de .text sectie.

Zoals ook te zien is aan mijn _init functie, worden de globale constructors nooit geconstruct. Heeft iemand een idee waarom? Is mijn volgorde van linken verkeerd? Of maak ik een andere verkeerde assumptie hier?

Alvast bedankt voor de hulp,

Rob

Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Je elf loader moet volgens mij de code in die .init en .fini sections aanroepen (of je moet het in _start doen). Verder doen je _init anen _fini functies niet zo veel, als in, volgens mij moeten die over al de ctors & dtor loopen om ze aan te roepen.

Acties:
  • 0 Henk 'm!

  • Robbiedobbie
  • Registratie: Augustus 2009
  • Laatst online: 16-09 19:30
Het aanroepen van _init en _fini gebeurt inderdaad in de _start section. Dit voert echter niks uit, aangezien die init en fini functies momenteel niks doen.

Echter, voor wat ik heb begrepen, zou de inhoud van de init en fini sections van crtbegin en crtend geplaatst moeten worden tussen de code in diezelfde sections in crti en crtn. Dit gebeurd dus niet, waardoor deze functies inderdaad niet veel doen. De code van crtbegin en crtend is ook de enige code die de precieze functies weet die alles constructen (vanwege namewrangling, en compiler internals).

Acties:
  • 0 Henk 'm!

  • Robbiedobbie
  • Registratie: Augustus 2009
  • Laatst online: 16-09 19:30
Heb het al werkend. Nadat ik een crosscompiler had gebuild, ipv mijn default arch linux gcc te gebruiken, en daarna het linken via g++ te doen ipv handmatig met ld, werkt hij perfect :D

Acties:
  • 0 Henk 'm!

  • Rutix
  • Registratie: Augustus 2009
  • Laatst online: 05-09-2024
Robbiedobbie schreef op maandag 05 mei 2014 @ 11:49:
Heb het al werkend. Nadat ik een crosscompiler had gebuild, ipv mijn default arch linux gcc te gebruiken, en daarna het linken via g++ te doen ipv handmatig met ld, werkt hij perfect :D
Mooi dat je het werkend heb gekregen maar dan ben ik nog wel benieuwd wat het verschil tussen de default gcc en crosscompiler is dan :P

Nothing to see here!


Acties:
  • 0 Henk 'm!

  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 10:04

Super_ik

haklust!

Als je linkt met g++ ipv ld, roept g++ onderwater ld aan met een hele rits extra opties. de kans is dus ook groot dat je nu gewoon een systeem library hebt meegelinkt, die hetzelfde doet als jou eigen library.

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


Acties:
  • 0 Henk 'm!

  • Robbiedobbie
  • Registratie: Augustus 2009
  • Laatst online: 16-09 19:30
Rutix schreef op maandag 05 mei 2014 @ 12:27:
[...]

Mooi dat je het werkend heb gekregen maar dan ben ik nog wel benieuwd wat het verschil tussen de default gcc en crosscompiler is dan :P
Ik weet het niet precies, maar ik vermoed dat arch aangepaste crt*.o heeft, waardoor het linken anders gaat.
Super_ik schreef op maandag 05 mei 2014 @ 12:30:
Als je linkt met g++ ipv ld, roept g++ onderwater ld aan met een hele rits extra opties. de kans is dus ook groot dat je nu gewoon een systeem library hebt meegelinkt, die hetzelfde doet als jou eigen library.
Ik vermoed van niet aangezien ik -ffreestanding gebruik, en omdat de crosscompiler geen c lib heeft meecompiled. Die crosscompiler heeft alleen nog maar de bare minimum zaken die echt nodig zijn om een eigen kernel te compilen.
Pagina: 1