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
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
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).
@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!!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.