Ich möchte meinen C-Code ohne die (g)libc kompilieren. Wie kann ich es deaktivieren und welche Funktionen hängen davon ab?
Ich habe -nostdlib versucht, aber es hilft nicht: Der Code ist kompilierbar und läuft, aber ich kann immer noch den Namen der libc im Hexdump meiner ausführbaren Datei finden.
-nostdlib sollte es tun, welche Plattform/Compiler-Version verwenden Sie?
– Karl Norum
30. März 2010 um 20:36 Uhr
“hilft nicht”, da dies die Bibliothek nicht deaktiviert hat, oder Sie konnten mit diesem Flag nichts kompilieren?
– Josh Lee
30. März 2010 um 20:47 Uhr
Sie möchten wahrscheinlich auch -nostartupfiles.
– Benutzer1831086
30. März 2010 um 22:03 Uhr
blog.ksplice.com/2010/03/libc-free-world hat eine sehr gute Beschreibung der präzisen Steuerung der programmatischen Ausgabe des gcc. Bearbeiten: Sie (ksplice) haben gerade Teil 2 des obigen Tutorials / Leitfadens veröffentlicht. Sehen Sie es hier: blog.ksplice.com/2010/04/libc-free-world-2 Dies betrifft hauptsächlich Linker-Einstellungen, um unnötige Flusen aus Dateien zu entfernen.
– Adam Schiemke
31. März 2010 um 1:18 Uhr
Es gibt keine Option -nostartupfiles. Sie meinen wahrscheinlich -nostartfiles, was bereits durch -nostdlib impliziert wird.
– ataylor
31. März 2010 um 18:24 Uhr
ataylor
Wenn Sie Ihren Code mit kompilieren -nostdlib, können Sie (natürlich) keine C-Bibliotheksfunktionen aufrufen, aber Sie erhalten auch nicht den regulären C-Bootstrap-Code. Insbesondere ist dies nicht der eigentliche Einstiegspunkt eines Programms unter Linux main()sondern eine aufgerufene Funktion _start(). Die Standardbibliotheken stellen normalerweise eine Version davon bereit, die einen Initialisierungscode ausführt und dann aufruft main().
Versuchen Sie, dies mit zu kompilieren gcc -nostdlib -m32:
// Tell the compiler incoming stack alignment is not RSP%16==8 or ESP%16==12
__attribute__((force_align_arg_pointer))
void _start() {
/* main body of program: call main(), etc */
/* exit system call */
asm("movl $1,%eax;"
"xorl %ebx,%ebx;"
"int $0x80"
);
__builtin_unreachable(); // tell the compiler to make sure side effects are done before the asm statement
}
Das _start() Die Funktion sollte immer mit einem Aufruf von enden exit (oder andere nicht zurückkehrende Systemaufrufe wie z exec). Das obige Beispiel ruft den Systemaufruf wie üblich direkt mit Inline-Assemblierung auf exit() ist nicht verfügbar.
Für 64 Bit muss der Assembler-Code so aussehen: asm("mov rax,60; mov rdi,0; syscall").
– Sigal
3. Mai 2016 um 18:03 Uhr
Hinzufügen zu @sigalors Kommentar, um damit zu kompilieren gcc Sie müssen die AT&T-Syntax verwenden, also sollte dies wie folgt aussehen: asm(mov $60,%rax; mov $0,%rdi; syscall)
– Lanox
11. Mai 2016 um 11:59 Uhr
@ataylor: Warum sollte die Funktion _start() immer mit dem Aufruf von exit() enden? Was ist, wenn ich exit() nicht in die Funktion start() schreibe?
– Destruktor
25. Mai 2017 um 5:52 Uhr
@Destructor auf meinem System hängt es für ein paar Sekunden, dann segfaults.
– Mondkind
15. August 2017 um 23:18 Uhr
Beachten Sie, dass der Stapel bei der Eingabe anders ausgerichtet ist _start: keine Rücksprungadresse auf dem Stack, also immer noch 16-Byte-ausgerichtet. GCC geht jedoch davon aus, dass es sich um eine normale Funktion handelt, und verletzt daher die ABI, wenn andere Funktionen aufgerufen werden. Verwenden -mincoming-stack-boundary=2 für diese Datei (Dokumente) um GCC mitzuteilen, dass der Stapel beim Funktionseintrag möglicherweise nur 4-Byte-ausgerichtet ist, oder vielleicht ein __attribte__((target("something"))) nur auf _start
– Peter Cordes
2. Juni 2020 um 12:59 Uhr
Der einfachste Weg ist, den C-Code in Objektdateien zu kompilieren (gcc -c Um Etwas zu bekommen *.o Dateien) und dann direkt mit dem Linker verlinken (ld). Sie müssen Ihre Objektdateien mit einigen zusätzlichen Objektdateien verknüpfen, z /usr/lib/crt1.o um eine funktionierende ausführbare Datei zu erhalten (zwischen dem Einstiegspunkt, wie er vom Kernel gesehen wird, und der main() Funktion, es gibt ein wenig Arbeit zu tun). Um zu wissen, womit Sie verknüpfen müssen, versuchen Sie, mit der glibc zu verknüpfen, indem Sie verwenden gcc -v: Dies sollte Ihnen zeigen, was normalerweise in die ausführbare Datei kommt.
Sie werden feststellen, dass gcc Code generiert, der einige Abhängigkeiten zu einigen versteckten Funktionen haben kann. Die meisten sind dabei libgcc.a. Es kann auch versteckte Anrufe geben memcpy(), memmove(), memset() und memcmp()die sich in der libc befinden, daher müssen Sie möglicherweise Ihre eigenen Versionen bereitstellen (was nicht schwierig ist, zumindest solange Sie nicht zu wählerisch in Bezug auf die Leistung sind).
Dinge könnte wird manchmal klarer, wenn Sie sich die produzierte Baugruppe ansehen (verwenden Sie die -S Flagge).
Ich muss _start anstelle von main verwenden, aber wenn ich versuche, eine libc-Funktion aufzurufen, beschwert sich gcc nicht. Verschwindet der libc-Link, wenn ich alle libc-Aufrufe entferne?
– u149796
1. April 2010 um 7:50 Uhr
Nicht direkt. Wenn du es versuchst gcc -vdu wirst das sehen gcc gibt dem Linker einige Objektdateien (die *.o). Der Linker schließt alle ihm übergebenen Objektdateien ein. “Verschwinden” tritt nur bei Bibliotheken auf (*.a), da es sich um Repositorys von Objektdateien handelt, die der Linker verwenden oder nicht verwenden kann.
-nostdlib
sollte es tun, welche Plattform/Compiler-Version verwenden Sie?– Karl Norum
30. März 2010 um 20:36 Uhr
“hilft nicht”, da dies die Bibliothek nicht deaktiviert hat, oder Sie konnten mit diesem Flag nichts kompilieren?
– Josh Lee
30. März 2010 um 20:47 Uhr
Sie möchten wahrscheinlich auch -nostartupfiles.
– Benutzer1831086
30. März 2010 um 22:03 Uhr
blog.ksplice.com/2010/03/libc-free-world hat eine sehr gute Beschreibung der präzisen Steuerung der programmatischen Ausgabe des gcc. Bearbeiten: Sie (ksplice) haben gerade Teil 2 des obigen Tutorials / Leitfadens veröffentlicht. Sehen Sie es hier: blog.ksplice.com/2010/04/libc-free-world-2 Dies betrifft hauptsächlich Linker-Einstellungen, um unnötige Flusen aus Dateien zu entfernen.
– Adam Schiemke
31. März 2010 um 1:18 Uhr
Es gibt keine Option -nostartupfiles. Sie meinen wahrscheinlich -nostartfiles, was bereits durch -nostdlib impliziert wird.
– ataylor
31. März 2010 um 18:24 Uhr