GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Ladewarnung:Eintragssymbol _start kann nicht gefunden werden

Verwenden Sie das Label _start statt main für den ELF-Einstiegspunkt. main impliziert, dass es wie C main ist Funktion, aber dies ist nicht einmal eine Funktion (z. B. können Sie nicht ret ).

Sie sagen es nicht, aber aufgrund der Fehlermeldungen und des Codes gehe ich davon aus, dass Sie Ihren 32-Bit-Code mit nasm -felf32 hello32.asm && ld -melf_i386 -o hello32 hello32.o erstellen

(Wenn Sie tatsächlich 64-Bit-Code erstellen, haben Sie Glück, dass es zufällig funktioniert, aber es bricht zusammen, sobald Sie irgendetwas mit esp tun statt rsp .)

Die Fehlermeldung ist von ld , nicht von nasm . So steht es direkt in der Nachricht. Tims Kommentar ist richtig:ld sucht nach einem _start Symbol in den verknüpften Dateien, setzt den Einstiegspunkt jedoch auf den Anfang des Textsegments, wenn es keinen findet.

Es spielt keine Rolle, welche anderen globalen/externen Symbole Sie definieren. main hat hier überhaupt keine Relevanz und könnte überall hin zeigen, wo Sie wollen. Es ist nur nützlich für eine Disassemblierungsausgabe und ähnliches. Ihr Code würde genauso funktionieren, wenn Sie global main herausnehmen würden / main: Zeilen oder ändern Sie sie in einen anderen Namen.

Kennzeichnung als main ist unklug, da der ELF-Einstiegspunkt keine Funktion ist . Es ist nicht main() , und erhält argc nicht und argv Argumente und kann nicht ret weil ESP auf argc zeigt anstelle einer Absenderadresse.

Verwenden Sie nur main wenn Sie mit dem CRT-Startcode von gcc / glibc verknüpfen, der nach einem main sucht Symbol und ruft es nach der Initialisierung von libc auf. (Funktionen wie printf funktionieren also. Technisch dynamische Linker-Hooks lassen libc sich selbst vor Ihrem _start initialisieren wenn Sie es verlinkt haben, aber tun Sie das im Allgemeinen nicht, es sei denn, Sie verstehen genau, was Sie tun). Verwandt:Assemblieren von 32-Bit-Binärdateien auf einem 64-Bit-System (GNU-Toolchain)

z.B. gcc -m32 -no-pie -o hello main.o wenn Sie einen main: definieren
statt gcc -m32 -static -nostdlib -o hello start.o
(was Ihrem bloßen ld entspricht ).

(In den letzten Jahren haben Linux-Distributionen GCC mit -pie konfiguriert als Standard, der positionsunabhängigen Code will. Aber das ist im 32-Bit-Modus ohne RIP-relative Adressierung (sehen Sie sich zum Beispiel die Ausgabe von GCC asm an) wirklich unpraktisch und bedeutet ld konvertiert call printf nicht in call [email protected] für dich. Für die meisten handgeschriebenen Asms, die den meisten Tutorials folgen, möchten Sie also traditionelle ausführbare Nicht-PIE-Dateien, sodass keine Textverschiebungen erforderlich sind.)


Ich würde vorschlagen, dass Sie Ihre Objektdateien (wie auch immer sie erzeugt werden) mit gcc verknüpfen , nicht ld .

gcc ruft ld auf mit den entsprechenden Optionen, da es mehr über den Quellcode weiß und alles Notwendige für die Annahmen erstellt, dass ld macht.


Linux
  1. So beheben Sie den Konfigurationsfehler:Makroverzeichnis „m4“ kann nicht gefunden werden [Gelöst]

  2. Kann keine gültige Basis-URL finden:YumRepo-Fehler [Gelöst]

  3. Pspell kann nicht gefunden werden – PHP-Konfigurationsfehler behoben

  4. Kann -lm nicht finden?

  5. ld kann keine vorhandene Bibliothek finden

libcrypto-Bibliotheksfehler kann nicht gefunden werden

Beim Installieren von Qt unter Linux kann -lGL nicht gefunden werden

node.js:Modul 'request' kann nicht gefunden werden

usr/bin/ld:kann -l<nameOfTheLibrary> nicht finden

pkg-config-Fehler kann nicht gefunden werden

Fehler beim Erstellen von cmake:kann -lpthreads nicht finden