Autor Thema: Problem beim Ausführen von ELF32 Binary  (Gelesen 2851 mal)

Kuchen

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« am: 14. June 2009, 15:45 »
Hallo,

ich bin mit meinem Kernel langsam an der Stelle angelangt, wo ich Programme starten möchte.
Ich hab mir nach einem Tutorial von osdev.org (http://wiki.osdev.org/OS_Specific_Toolchain) einen Compiler mit Libc für mein OS gebaut. Das ganze funktioniert soweit recht gut, das Problem ist aber, dass beim Starten des Programms in der '__do_global_ctors_aux' Funktion (die wahrscheinlich vom GCC stammt) der Endmarker der .ctors Section nicht erkannt sondern ausgeführt wird. Das ganze resultiert in einer Invalid Opcode Exception (der Endmarker ist die Bytefolge 0xFFFFFFFF, was natürlich kein gültiger Opcode ist).

Hier ein paar Stücke aus dem Disassemblierten Programm:
Disassembly of section .init:

40000074 <.init>:
40000074: e8 77 00 00 00        call   400000f0 <frame_dummy>
40000079: e8 b2 2c 00 00        call   40002d30 <__do_global_ctors_aux>
Disassembly of section .text:

40000080 <_start>:
40000080: e8 cb 00 00 00        call   40000150 <main>
40000085: e8 c6 01 00 00        call   40000250 <_exit>

4000008a <.wait>:
4000008a: f4                    hlt   
4000008b: eb fd                jmp    4000008a <.wait>
4000008d: 90                    nop   
4000008e: 90                    nop   
4000008f: 90                    nop   
40000150 <main>:
40000150: 8d 4c 24 04          lea    0x4(%esp),%ecx
40000154: 83 e4 f0              and    $0xfffffff0,%esp
40000157: ff 71 fc              pushl  -0x4(%ecx)
4000015a: 55                    push   %ebp
4000015b: 89 e5                mov    %esp,%ebp
4000015d: 51                    push   %ecx
4000015e: 83 ec 04              sub    $0x4,%esp
40000161: 83 ec 0c              sub    $0xc,%esp
40000164: 68 78 2d 00 40        push   $0x40002d78
40000169: e8 92 00 00 00        call   40000200 <puts>
4000016e: 83 c4 10              add    $0x10,%esp
40000171: 8b 4d fc              mov    -0x4(%ebp),%ecx
40000174: c9                    leave 
40000175: 8d 61 fc              lea    -0x4(%ecx),%esp
40000178: c3                    ret   
40002d30 <__do_global_ctors_aux>:
40002d30: 55                    push   %ebp
40002d31: 89 e5                mov    %esp,%ebp
40002d33: 56                    push   %esi
40002d34: 53                    push   %ebx
40002d35: e8 00 00 00 00        call   40002d3a <__do_global_ctors_aux+0xa>
40002d3a: 5b                    pop    %ebx
40002d3b: 81 c3 ea 02 00 00    add    $0x2ea,%ebx
40002d41: 8d 83 e4 ff ff ff    lea    -0x1c(%ebx),%eax
40002d47: 8d 50 fc              lea    -0x4(%eax),%edx
40002d4a: 8b 40 fc              mov    -0x4(%eax),%eax
40002d4d: 83 f8 ff              cmp    $0xffffffff,%eax
40002d50: 74 1b                je     40002d6d <__do_global_ctors_aux+0x3d>
40002d52: 89 d6                mov    %edx,%esi
40002d54: 8d b6 00 00 00 00    lea    0x0(%esi),%esi
40002d5a: 8d bf 00 00 00 00    lea    0x0(%edi),%edi
40002d60: ff d0                call   *%eax
40002d62: 8b 46 fc              mov    -0x4(%esi),%eax
40002d65: 83 ee 04              sub    $0x4,%esi
40002d68: 83 f8 ff              cmp    $0xffffffff,%eax
40002d6b: 75 f3                jne    40002d60 <__do_global_ctors_aux+0x30>
40002d6d: 5b                    pop    %ebx
40002d6e: 5e                    pop    %esi
40002d6f: 5d                    pop    %ebp
40002d70: c3                    ret   
Disassembly of section .ctors:

40003004 <__CTOR_LIST__>:
40003004: ff                    (bad) 
40003005: ff                    (bad) 
40003006: ff                    (bad) 
40003007: ff 00                incl   (%eax)

40003008 <__CTOR_END__>:
40003008: 00 00                add    %al,(%eax)

Der Einsprungspunkt ist 0x40000080, also die Adresse von '_start'. Was ich unter Anderem nicht verstehe: Warum wird die Funktion '__do_global_ctors_aux' überhaupt ausgeführt, und warum funktioniert der Test für den Endmarker (bei 0x40002d68) nicht?

Mein Loader sieht ca. so aus, wie der tyndur module loader.

Vielen vielen Dank schonmal im Vorraus,
Kuchen

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 14. June 2009, 16:45 »
Bist du dir sicher, dass das alles richtig im Speicher landet und du wirklich an das richtige Offset springst? Du könntest dir mal in qemu die Ausgabe von x /20i 0x40000080 oder sowas anschauen, ob es wirklich mit dem Sprung nach main losgeht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Kuchen

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 15. June 2009, 17:29 »
Wenn ich in bochsdbg einen Breakpoint auf 0x1B:0x40000080 (also die Startadresse) setze wird das Programm vor dem Absturz angehalten, der Speicherinhalt sieht auch richtig aus.

Programme die ich mit '-ffreestanding -nostdlib -nodefautlibs -nostartfiles' und einem eigenen Linkerscript übersetze funktionieren so wie sie sollen.

Ich versuche mal irgendwie auf Kooperatives Multitasking umzustellen und das Programm durchzusteppen.

Edit:
Hab den Fehler gefunden, danke für die Idee, dass der Speicherinhalt nicht ganz richtig sein könnte. Beim Laden der Datei wird scheinbar nur die erste Page jeder ELF-Sektion kopiert. Das fiel erst nicht auf, weil die Daten an 0x40003004 ja richtig kopiert wurden, die liegen zufällig aber auf der 1. Page der 2. Sektion.
« Letzte Änderung: 15. June 2009, 17:58 von Kuchen »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 15. June 2009, 17:58 »
Okay, ich sehe schon, die grundlegenden Dinge braucht man dir nicht vorzuschlagen. ;)

Durchsteppen klingt nach einer guten Idee, ja. Für dieses Testprogramm brauchst du doch aber kein kooperatives Multitasking? Genauer gesagt braucht das doch eher gar kein Multitasking. Also einfach so durchsteppen und wenn der Timer anfängt zu nerven evtl. Interrupts vorher ausschalten.

Davon abgesehen, ja, sobald du wirklich mehr als einen Task brauchst, ist es ganz nett, kooperatives Multitasking zu haben. Es vereinfacht das Debugging manchmal gewaltig, weil Dinge, die vorher vom Timing abhängen und mehr oder weniger zufällig auftreten, plötzlich deterministisch werden.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 15. June 2009, 18:02 »
Edit:
Hab den Fehler gefunden, danke für die Idee, dass der Speicherinhalt nicht ganz richtig sein könnte. Beim Laden der Datei wird scheinbar nur die erste Page jeder ELF-Sektion kopiert. Das fiel erst nicht auf, weil die Daten an 0x40003004 ja richtig kopiert wurden, die liegen zufällig aber auf der 1. Page der 2. Sektion.
Oh ja, die Freuden des ELF-Loaders. An dem habe ich bis vor einer Weile auch immer wieder rumgefixt, weil irgendein Detail doch nicht ganz gestimmt hat. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Kuchen

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 15. June 2009, 18:21 »
Fehler gefunden, ist schon etwas doof wenn man von der Zieladresse zur Zieladresse kopiert -.-

 

Einloggen