Forum: Compiler & IDEs Wie funktioniert ein Linker?


von CMosSwitcher (Gast)


Lesenswert?

Hallo,

ich habe eine sehr allgemeine Frage:
Wie funktioniert ein Linker?

Die Aufgabe von einem Linker ist mir klar. Er "linkt" Object Files oder 
Librarys in bestimmte Speichersegmente.

Globale Daten werden an bestimmte Adressen im RAM gelinkt.

Aber nun sieht der Aufruf bei meinem Linker etwas so aus:

Linker <options> OUTPUTFILE <linker file> <files>

Man kann entweder die Objectfiles die gelinkt werden sollen direkt im 
Linkerfile oder Linkerscript angeben, oder die Files die gelinkt werden 
sollen separat angeben.

Und genau das verstehe ich nicht! Warum kann man die Files auch separat 
angeben? Woher weiß dann der Linker in welches Segment welches Object 
File soll?

Würde es auch reichen nur das Linkerfile oder Linkerscript anzugeben???

Das man bei options so Sachen wie Map-File angeben kann ist jetzt net so 
wichtig, mir gehts nur um die grundlegende Funktion von so einem Linker.

Danke!!!

Lg

von Daniel D. (Gast)


Lesenswert?

Im Linker-Script wird ja festgelegt, wie die Sections der Object-Files 
zusammengefügt werden. Standardmäßig ist Code in .text und das 
Standard-Linker Script belässt es dabei (bei c mit gcc und ld. Bei c++ 
wird das vermutlich komplizierter sein). D.h. alles in .text der 
Object-Files landet in .text vom elf-File (bei der Windows-exe wirds 
ähnlich sein). Diese Zuordnung kann über ein nutzerdefiniertes 
Linker-Script geändert werden. Damit der Linker aber weiß, welche 
Dateien er überhaupt linken soll, müssen diese auf der Befehlszeile 
mitlaufen. Kann sein, dass man das auch übers Script machen kann, hab 
ich noch nie gebraucht...

VG, Daniel

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Der Dreh- und Angelpunkt, den du vermutlich noch nicht verstanden hast
dabei ist, dass der Linker sogenannte verschiebliche (englisch:
relocatable) Objektmoduln als Eingabe erwartet.  Diese haben an
allen Stellen, an denen später absolute Speicheradressen erwartet
werden, erst einmal eine Zahl stehen (0 oder ein Offset bezogen auf
den Anfang des Segments innerhalb des Moduls), zu dem dann noch ein
Verschiebe-Datensatz (relocation record) innerhalb des Objektmoduls
gehört.  Dieser Datensatz beschreibt, wie der Linker die tatsächliche
Adresse an der entsprechenden Stelle bilden soll.

Der Linker fügt dann die einzelnen Speicheranforderungen (Segmente)
der Objektmodule erst einmal zusammen.  Danach weiß er, welcher
Modul in welchem der Segmente welche Anfangsadresse bekommt bzw.
bei globalen Segmenten (Variablen) überlagert er diese an Hand der
gegebenen Namen (die sogenannten Symbole).  Danach kann er durch
alles noch einmal durch gehen und die Verschiebungen auflösen, indem
er die (nunmehr berechenbaren) absoluten Adressen einträgt.  Dabei
überschreibt er die vorher dort stehenden Werte dann mit den
tatsächlichen, d. h. der jeweilige Modul wird dabei nicht etwa
nachträglich länger (sonst könnte er ja vorher die Offsets nicht
berechnen).

von CMosSwitcher (Gast)


Lesenswert?

@Daniel und Jörg

vielen Dank für die Erklärungen.

Was für eine Rolle spielt dann "link order" in diesem Zusammenhang?
Sollte es nicht egal sein in welcher Reihenfolge die Objectfiles gelinkt 
werden bzw. was für Adressen sie dann schlussendlich erhalten?

Nochmal zur Handhabung des Linkers:
Ich habe z.B. schon Linkerfiles gesehen da werden die ganzen 
Applikationsobjekte nacheinander aufgeführt.. also erst die Segment 
Angabe und dann alle Object untereinander.

Davon abgesetzt wird dann z.b. das Segement 0xFFC0 definiert und dann 
folgt die Angabe des Object mit der Vectortabelle.

Meiner Meinung nach macht es dann aber gar keinen Sinn zusätzlich zu dem 
Linkerfile die einzelnen Objekte als Kommandozeilen Parameter zu 
übergeben, oder? Sonst wäre ja auch die Angabe mit dem Segment 0xFFC0 im 
Linkerfile unnötig.

@Jörg

Wenn ich dich richtig verstanden habe, dann sind z.B. auch fertige 
Librarys verschiebbar, da sie sonst ja nicht universell auf 
verschiedenen Controllerplattformen (unterschiedliche Speicher) 
eingesetzt werden könnten.

Danke!!

von (prx) A. K. (prx)


Lesenswert?

CMosSwitcher schrieb:

> Was für eine Rolle spielt dann "link order" in diesem Zusammenhang?
> Sollte es nicht egal sein in welcher Reihenfolge die Objectfiles gelinkt
> werden bzw. was für Adressen sie dann schlussendlich erhalten?

Philosophiefrage.

Es gibt Linker, die streng der Reihe nach arbeiten. Speziell bei 
Libraries merkt man das. Wenn an der Position in 
Kommandozeile/Steuerfile eine Funktion noch nicht gebraucht wird, wird 
sie nicht eingebunden, auch wenn später Bedarf bestünde. 
Unix/Linux-Linker arbeiten üblicherweise so.

Andere Linker wiederum arbeiten in mehreren Phasen und sammeln erst alle 
Informationen aller Files ein bevor sie die Abhängigkeiten auflösen.

> Wenn ich dich richtig verstanden habe, dann sind z.B. auch fertige
> Librarys verschiebbar

Libraries sind im Grunde nichts anderes als ein Archiv aus normalen 
Objektfiles, jedenfalls ist der Unix "ar" so entstanden. Eine das 
Verfahren vereinfachte Symboltabelle hat er erst später verpasst 
bekommen.

Auch fertige ausführbare Programme sind oft noch verschieblich, 
insbesondere bei DLLs / shared libs ist das unvermeidlich.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.