Toon posts:

*BSD/ELF: core dump helloworld vanwege vage ELF-header?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb op een FreeBSD-machine een triviaal programmaatje geschreven geknipt en geplakt. Het programmaatje is geassembleerd met NASM en gelinkt met ld. Het draait prima op FreeBSD. Als ik dit programma overhevel naar mijn NetBSD-2.0-machine, werkt het ook voortreffelijk. Echter, als ik het object-bestand op mijn NetBSD-2.0 machine link, kan ik het niet draaien. Het besturingssysteem core dumpt het onmiddelijk. Vreemd genoeg werken beide versies van het programma wel goed op NetBSD-1.6.2.

Als ik het programma onder de loep neem, blijkt dat slechts een byte verschillend is tussen de versie die op FreeBSD is gelinkt en de versie die op NetBSD-2.0 is gelinkt. De eerste van de opvulbytes in de ELF-header is bij de FreeBSD-versie namelijk 09 en in de NetBSD-versie 00. Als de in de NetBSD-2.0 versie deze 00 met een hex-editor verander in 09, dan draait het weer. Dit is vreemd, omdat de ELF-specificatie vermeldt dat alle opvulbytes moeten worden genegeerd. Als ik trouwens de NetBSD-2.0-versie met 00 op FreeBSD probeer te draaien, gebeurt er dit:

code:
1
FreeBSD % ./hello
quote: FreeBSD
ELF binary type "0" not known.
Abort
De ELF-specificatie zegt ook dat alle opvulbytes in de ELF-header op 0 moeten staan. Dit klopt ook met andere binaries die ik op het NetBSD-2.0 systeem heb. Op het FreeBSD-systeem heb ik steekproefsgewijs ondervonden dat de eerste opvulbyte in binaries altijd op 09 staan. Weliswaar niet conform specs, maar in elk geval wel consistent ;)

Vraag rest: wat is hier aan de hand? Waarom maakt die ene byte in het opvulgedeelte zo veel uit? Is het een bug in NetBSD-2.0 vanwege de 00 in de opvulbyte reeks? Nee, want alle andere binaries hebben ook 00 als eerste byte in de opvulreeks in de ELF-header. Een bug in de linker? Zeer onwaarschijnlijk. Zoiets valt natuurlijk meteen op bij het builden van het systeem. Bovendien doet het probleem zich ook voor met andere versies (ook die van CVS) van ld. Is mijn programma dan foutief? En zo ja, waarom werkt het dan wel in FreeBSD en NetBSD-1.6.2. Als iemand mij het kan vertellen: GRAAG :)

code:
1
% ld -version
quote: FreeBSD
GNU ld version 2.12.1 [FreeBSD] 2002-07-20
Copyright 2002 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License. This program has absolutely no warranty.
quote: NetBSD-2.0
GNU ld version 2.14 20030612
Copyright 2002 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License. This program has absolutely no warranty.
quote: NetBSD-1.6.2
GNU ld 2.11.2
Copyright 2001 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License. This program has absolutely no warranty.
Supported emulations:
elf_i386
i386nbsd


Nog wat binaries ter onderwerping aan naar ik hoop het alziend oog van mijn mede-tweakers:

[ Voor 3% gewijzigd door Verwijderd op 15-12-2004 13:04 ]


Verwijderd

Topicstarter
Zucht, niemand voelt zich geroepen? :'(

Meer informatie dan maar: ik heb inmiddels ontdekt dat de versie van de ELF-specs die ik had, is verouderd. Die 09 waarvan ik dacht dat het de eerste byte van een opvulreeks moest zijn blijkt volgens man elf(5) een architectuur aanduiding te zijn. 09 is dus van FreeBSD en 00 van System V (waarnaar NetBSD zich conformeert.) Dat lijkt dus allemaal te kloppen. Maar het verklaart helaas niet waarom het progje SIGSEGV (Segmentation fault) krijgt toegezonden van de systeemkern.

Ik heb inmiddels een debugger gevonden om stap voor stap het programma te doorlopen. Het programma wordt wel juist ingeladen, maar bij de eerste instructie (push dword 0xe ;de lengte van het bericht) loopt het al mis en krijg het programma een SIGSEGV. Ik heb voor de grap als eerste instructie eens 'nop' (no operation) ingevuld. Deze instructie doet helemaal niets (behalve een clockcycle verbruiken en de IP vooruit doen ;)) Ook hiermee krijg het programma een SIGSEGV. Hoe kan dit?? Je hoort toch alleen een SIGSEGV te krijgen als je een geheugenlocatie probeert te benaderen die je niet zou mogen benaderen? En de 'FreeBSD-versie' werkt trouwels wel gewoon.

Hier een paar register dumps:
NetBSD:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
% ald hello
Assembly Language Debugger 0.0.19
Copyright (C) 2000-2002 Patrick Alken

hello: ELF Intel 80386 (32 bit), LSB, Executable, Version 1 (current)
Loading debugging symbols...(15 symbols loaded)
ald> register
eax = 0x00000000 ebx = 0xBFBFFFF0 ecx = 0x00000000 edx = 0x00000000
esp = 0xBFBFF684 ebp = 0x00000000 esi = 0x00000000 edi = 0x00000000
ds = 0x0000001F es = 0x0000001F fs = 0x0000001F gs = 0x0000001F
ss = 0x0000001F cs = 0x0000002B eip = 0x08048091 eflags = 0x00000202
ald> n

Program received signal SIGSEGV (Segmentation fault)
Location: 0x08048091
eax = 0x00000000 ebx = 0xBFBFFFF0 ecx = 0x00000000 edx = 0x00000000
esp = 0xBFBFF684 ebp = 0x00000000 esi = 0x00000000 edi = 0x00000000
ds = 0x0000001F es = 0x0000001F fs = 0x0000001F gs = 0x0000001F
ss = 0x0000001F cs = 0x00000023 eip = 0x08048091 eflags = 0x00000302

08048091  90                         nop


'FreeBSD'
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
% ald hello_FreeBSD
Assembly Language Debugger 0.0.19
Copyright (C) 2000-2002 Patrick Alken

hello_FreeBSD: ELF Intel 80386 (32 bit), LSB, Executable, Version 1 (current)
Loading debugging symbols...(15 symbols loaded)
ald> register
eax = 0x00000000 ebx = 0xBFBFFFF0 ecx = 0x00000000 edx = 0x00000000
esp = 0xBFBFF680 ebp = 0x00000000 esi = 0x00000000 edi = 0x00000000
ds = 0x0000001F es = 0x0000001F fs = 0x0000001F gs = 0x0000001F
ss = 0x0000001F cs = 0x00000017 eip = 0x08048091 eflags = 0x00000202
ald> n
eax = 0x00000000 ebx = 0xBFBFFFF0 ecx = 0x00000000 edx = 0x00000000
esp = 0xBFBFF680 ebp = 0x00000000 esi = 0x00000000 edi = 0x00000000
ds = 0x0000001F es = 0x0000001F fs = 0x0000001F gs = 0x0000001F
ss = 0x0000001F cs = 0x00000017 eip = 0x08048092 eflags = 0x00000302

08048092  680E000000                 push 0xe


Het valt me trouwens wel op dat het CS register bij de NetBSD-versie verandert en bij de FreeBSD-versie niet. Het zou te maken kunnen hebben met het dumpen van de core, maar ik durf het niet te zeggen. Wie wel? :)

Verwijderd

Topicstarter
W00h00, heb het uiteindelijk toch nog zelf opgelost! (8>

Blijkt dat NetBSD geen native binaries draait als ze niet zijn voorzien van een ELF PT_NOTE sectie. Als je de EI_OSABI op FreeBSD zet, gaat de systeemkern in een soort emulatiestand werken, die kennelijk wat vergevelijker is dan de native modus. Well, excuuuse me. Maar goed, op de website van NetBSD staat een en ander uitgelegd over vendor specific .note sections. Op de website van }) SCO }) gaan ze wat dieper in op de note section.

Blijft trouwens wel een beetje gek dat NetBSD-1.6.2 minder moeilijk doet. Erg verwarrend allemaal.