Ld (Linker): Unterschied zwischen den Versionen

Aus C und Assembler mit Raspberry
Die Seite wurde neu angelegt: „**GNU ld** ist der Linker der GNU Toolchain, der für die Verknüpfung von Objektdateien und Bibliotheken zu einer ausführbaren Datei, einem dynamischen Shared Object (DSO) oder einer Bibliothek verwendet wird. Der Linker spielt eine entscheidende Rolle in der Build-Pipeline eines C/C++-Projekts, indem er verschiedene Kompilierungsoutputs zusammenführt und externe Symbole auflöst. ### Hauptaufgaben des GNU Linkers (ld) 1. **Zusammenführung von Objek…“
 
 
(Eine dazwischenliegende Version desselben Benutzers wird nicht angezeigt)
Zeile 1: Zeile 1:
**GNU ld** ist der Linker der GNU Toolchain, der für die Verknüpfung von Objektdateien und Bibliotheken zu einer ausführbaren Datei, einem dynamischen Shared Object (DSO) oder einer Bibliothek verwendet wird. Der Linker spielt eine entscheidende Rolle in der Build-Pipeline eines C/C++-Projekts, indem er verschiedene Kompilierungsoutputs zusammenführt und externe Symbole auflöst.
'''GNU ld''' ist der Linker der GNU Toolchain, der für die Verknüpfung von Objektdateien und Bibliotheken zu einer ausführbaren Datei, einem dynamischen Shared Object (DSO) oder einer Bibliothek verwendet wird. Der Linker spielt eine entscheidende Rolle in der Build-Pipeline eines C/C++-Projekts, indem er verschiedene Kompilierungsoutputs zusammenführt und externe Symbole auflöst.


### Hauptaufgaben des GNU Linkers (ld)
== Hauptaufgaben des GNU Linkers (ld) ==


1. **Zusammenführung von Objektdateien**
=== Zusammenführung von Objektdateien ===
  Der Linker kombiniert verschiedene **Objektdateien** (`.o`-Dateien), die durch den Compiler erzeugt wurden, zu einem einzigen Programm oder einer Bibliothek. Dabei werden die Objektdateien nacheinander eingelesen und ihre Symbole verknüpft.
Der Linker kombiniert verschiedene ''Objektdateien'' (`.o`-Dateien), die durch den Compiler erzeugt wurden, zu einem einzigen Programm oder einer Bibliothek. Dabei werden die Objektdateien nacheinander eingelesen und ihre Symbole verknüpft.


2. **Auflösen von Symbolen**
=== Auflösen von Symbolen ===
  Während des Verlinkungsvorgangs löst der Linker Symbole auf. Symbole sind Funktionen, Variablen und Objekte, die in den Objektdateien und Bibliotheken definiert oder referenziert werden. Der Linker stellt sicher, dass alle externen Verweise auf Symbole (wie Funktionsaufrufe oder globale Variablen) auf eine gültige Definition verweisen.
Während des Verlinkungsvorgangs löst der Linker Symbole auf. Symbole sind Funktionen, Variablen und Objekte, die in den Objektdateien und Bibliotheken definiert oder referenziert werden. Der Linker stellt sicher, dass alle externen Verweise auf Symbole (wie Funktionsaufrufe oder globale Variablen) auf eine gültige Definition verweisen.


3. **Erstellen von ausführbaren Dateien**
=== Erstellen von ausführbaren Dateien ===
  Der GNU ld-Linker erstellt die endgültige **ausführbare Datei** aus den verknüpften Objektdateien und Bibliotheken. Dies kann eine statische oder dynamische Verknüpfung sein:
Der GNU ld-Linker erstellt die endgültige ''ausführbare Datei'' aus den verknüpften Objektdateien und Bibliotheken. Dies kann eine statische oder dynamische Verknüpfung sein:
  - **Statische Verknüpfung**: Alle notwendigen Bibliotheksinhalte werden direkt in die ausführbare Datei eingefügt, wodurch sie unabhängig von externen Bibliotheken ausgeführt werden kann.
:'''Statische Verknüpfung:''' Alle notwendigen Bibliotheksinhalte werden direkt in die ausführbare Datei eingefügt, wodurch sie unabhängig von externen Bibliotheken ausgeführt werden kann.
  - **Dynamische Verknüpfung**: Die ausführbare Datei enthält Referenzen auf externe, zur Laufzeit zu ladende dynamische Bibliotheken (Shared Libraries, z.B. `.so`-Dateien auf Unix-Systemen oder `.dll` auf Windows).
:'''Dynamische Verknüpfung:''' Die ausführbare Datei enthält Referenzen auf externe, zur Laufzeit zu ladende dynamische Bibliotheken (Shared Libraries, z.B. `.so`-Dateien auf Unix-Systemen oder `.dll` auf Windows).


4. **Bibliotheken verlinken**
=== Bibliotheken verlinken ===
  Der Linker kann sowohl statische Bibliotheken (`.a` in Unix/Linux) als auch dynamische Bibliotheken (`.so`) verknüpfen. Abhängig von den Verknüpfungsoptionen kann der Linker:
Der Linker kann sowohl statische Bibliotheken (`.a` in Unix/Linux) als auch dynamische Bibliotheken (`.so`) verknüpfen. Abhängig von den Verknüpfungsoptionen kann der Linker:
  - **Statische Bibliotheken** in die endgültige ausführbare Datei aufnehmen.
:'''Statische Bibliotheken''' in die endgültige ausführbare Datei aufnehmen.
  - **Dynamische Bibliotheken** zur Laufzeit verwenden, sodass die Bibliothek erst geladen wird, wenn das Programm ausgeführt wird.
:'''Dynamische Bibliotheken''' zur Laufzeit verwenden, sodass die Bibliothek erst geladen wird, wenn das Programm ausgeführt wird.


5. **Verwalten von Speicheradressen und Abschnitten**
=== Verwalten von Speicheradressen und Abschnitten ===
  Der GNU ld verwaltet die **Speicherabschnitte** (Text, Daten, BSS) der einzelnen Objektdateien und legt fest, welche Speicherbereiche für verschiedene Datenarten verwendet werden. Die Speicherorganisation umfasst:
Der GNU ld verwaltet die ''Speicherabschnitte'' (Text, Daten, BSS) der einzelnen Objektdateien und legt fest, welche Speicherbereiche für verschiedene Datenarten verwendet werden. Die Speicherorganisation umfasst:
  - **Textsegment**: Enthält den ausführbaren Maschinencode.
*'''Textsegment''': Enthält den ausführbaren Maschinencode.
  - **Datensegment**: Enthält initialisierte globale und statische Variablen.
*'''Datensegment''': Enthält initialisierte globale und statische Variablen.
  - **BSS-Segment**: Enthält uninitialisierte globale und statische Variablen.
*'''BSS-Segment''': Enthält uninitialisierte globale und statische Variablen.
    
    
  Außerdem kann der Linker die Startadresse des Programms festlegen und das Layout der Speichersegmente konfigurieren.
Außerdem kann der Linker die Startadresse des Programms festlegen und das Layout der Speichersegmente konfigurieren.


6. **Laden von Startcode und dynamischen Loadern**
=== Laden von Startcode und dynamischen Loadern ===
  Der Linker integriert den notwendigen **Startcode** (wie den C-Runtime-Startcode) und erstellt den Einstiegspunkt der ausführbaren Datei (normalerweise die Funktion `main()` für C-Programme). Bei dynamisch gelinkten Programmen sorgt er für die Integration des dynamischen Loaders, der für das Laden der Shared Libraries zur Laufzeit verantwortlich ist.
Der Linker integriert den notwendigen ''Startcode'' (wie den C-Runtime-Startcode) und erstellt den Einstiegspunkt der ausführbaren Datei (normalerweise die Funktion `main()` für C-Programme). Bei dynamisch gelinkten Programmen sorgt er für die Integration des dynamischen Loaders, der für das Laden der Shared Libraries zur Laufzeit verantwortlich ist.


### Verknüpfungsprozess: Statische und Dynamische Verknüpfung
== Verknüpfungsprozess: Statische und Dynamische Verknüpfung ===


- **Statische Verknüpfung**:
=== Statische Verknüpfung ===
  Hierbei wird der gesamte Code aus den Bibliotheken direkt in die ausführbare Datei eingebettet. Dies führt zu größeren Binärdateien, aber die ausführbare Datei kann eigenständig ohne externe Abhängigkeiten laufen. Der Befehl könnte folgendermaßen aussehen:
Hierbei wird der gesamte Code aus den Bibliotheken direkt in die ausführbare Datei eingebettet. Dies führt zu größeren Binärdateien, aber die ausführbare Datei kann eigenständig ohne externe Abhängigkeiten laufen. Der Befehl könnte folgendermaßen aussehen:
    
    
  ```bash
<syntaxhighlight lang="shell">
  gcc -o meinprogramm main.o libmylib.a
gcc -o meinprogramm main.o libmylib.a
  ```
</syntaxhighlight>


- **Dynamische Verknüpfung**:
=== Dynamische Verknüpfung ===
  Bei der dynamischen Verknüpfung referenziert das Programm zur Laufzeit externe Shared Libraries (`.so`-Dateien). Die ausführbare Datei ist kleiner, benötigt jedoch, dass die benötigten Bibliotheken zur Laufzeit verfügbar sind:
Bei der dynamischen Verknüpfung referenziert das Programm zur Laufzeit externe Shared Libraries (`.so`-Dateien). Die ausführbare Datei ist kleiner, benötigt jedoch, dass die benötigten Bibliotheken zur Laufzeit verfügbar sind:
    
    
  ```bash
<syntaxhighlight lang="shell">
  gcc -o meinprogramm main.o -lmylib
gcc -o meinprogramm main.o -lmylib
  ```
</syntaxhighlight>


### GNU ld-Optionen
== GNU ld-Optionen ==


Der GNU Linker bietet zahlreiche Optionen, um den Verknüpfungsvorgang zu steuern. Hier sind einige häufig verwendete:
Der GNU Linker bietet zahlreiche Optionen, um den Verknüpfungsvorgang zu steuern. Hier sind einige häufig verwendete:


1. **-o**: Legt den Namen der Ausgabedatei fest:
'''-o''': Legt den Namen der Ausgabedatei fest:
  ```bash
:<syntaxhighlight lang="shell">
  ld -o meinprogramm start.o main.o
ld -o meinprogramm start.o main.o
  ```
</syntaxhighlight>


2. **-L**: Gibt den Pfad zu Verzeichnissen an, in denen nach Bibliotheken gesucht werden soll:
'''-L''': Gibt den Pfad zu Verzeichnissen an, in denen nach Bibliotheken gesucht werden soll:
  ```bash
:<syntaxhighlight lang="shell">
  ld -L/path/to/libs -lmylib
ld -L/path/to/libs -lmylib
  ```
</syntaxhighlight>


3. **-l**: Verknüpft eine Bibliothek (ohne den Präfix `lib` und die Erweiterung `.a` oder `.so`):
'''-l''': Verknüpft eine Bibliothek (ohne den Präfix `lib` und die Erweiterung `.a` oder `.so`):
  ```bash
:<syntaxhighlight lang="shell">
  ld -o meinprogramm main.o -lmylib  # Verknüpft libmylib.a oder libmylib.so
ld -o meinprogramm main.o -lmylib  # Verknüpft libmylib.a oder libmylib.so
  ```
</syntaxhighlight>


4. **-rpath**: Gibt an, wo zur Laufzeit nach dynamischen Bibliotheken gesucht werden soll:
'''-rpath''': Gibt an, wo zur Laufzeit nach dynamischen Bibliotheken gesucht werden soll:
  ```bash
:<syntaxhighlight lang="shell">
  ld -o meinprogramm main.o -lmylib -rpath /usr/local/lib
ld -o meinprogramm main.o -lmylib -rpath /usr/local/lib
  ```
</syntaxhighlight>


5. **-static**: Erzwingt statische Verknüpfung, selbst wenn dynamische Bibliotheken verfügbar sind:
'''-static''': Erzwingt statische Verknüpfung, selbst wenn dynamische Bibliotheken verfügbar sind:
  ```bash
:<syntaxhighlight lang="shell">
  gcc -o meinprogramm main.o -static -lmylib
gcc -o meinprogramm main.o -static -lmylib
  ```
</syntaxhighlight>


6. **-T**: Ermöglicht die Verwendung eines Linker-Skripts, um den Verknüpfungsvorgang genauer zu steuern. Mit einem Linker-Skript kannst du Speicherlayouts, Startadressen und Speichersegmentierung definieren.
'''-T''': Ermöglicht die Verwendung eines Linker-Skripts, um den Verknüpfungsvorgang genauer zu steuern. Mit einem Linker-Skript kannst du Speicherlayouts, Startadressen und Speichersegmentierung definieren.
  ```bash
:<syntaxhighlight lang="shell">
  ld -T linkerskript.ld -o meinprogramm main.o
ld -T linkerskript.ld -o meinprogramm main.o
  ```
</syntaxhighlight>


### Verwendung eines Linker-Skripts
== Verwendung eines Linker-Skripts ==


Linker-Skripte geben dem Entwickler präzise Kontrolle über das Layout der erzeugten Binärdatei. Ein einfaches Linker-Skript könnte folgendermaßen aussehen:
Linker-Skripte geben dem Entwickler präzise Kontrolle über das Layout der erzeugten Binärdatei. Ein einfaches Linker-Skript könnte folgendermaßen aussehen:


```ld
:<syntaxhighlight lang="ld">
SECTIONS {
SECTIONS {
   .text 0x1000 : { *(.text) }
   .text 0x1000 : { *(.text) }
Zeile 90: Zeile 90:
   .bss  0xA000 : { *(.bss) }
   .bss  0xA000 : { *(.bss) }
}
}
```
</syntaxhighlight>


Dieses Skript spezifiziert, dass das Textsegment bei der Adresse `0x1000`, das Datensegment bei `0x8000` und das BSS-Segment bei `0xA000` beginnen sollen. Der GNU ld-Linker nutzt dieses Skript, um die Speicheraufteilung des Programms genau zu kontrollieren.
Dieses Skript spezifiziert, dass das Textsegment bei der Adresse `0x1000`, das Datensegment bei `0x8000` und das BSS-Segment bei `0xA000` beginnen sollen. Der GNU ld-Linker nutzt dieses Skript, um die Speicheraufteilung des Programms genau zu kontrollieren.


### Debugging und Fehlerbehebung
== Debugging und Fehlerbehebung ==


Der Linker bietet nützliche Werkzeuge zur Fehlersuche:
Der Linker bietet nützliche Werkzeuge zur Fehlersuche:
- **Undefinierte Symbole**: Wenn ein Symbol, auf das verwiesen wird, nicht gefunden wird, meldet ld einen Fehler. Dies passiert häufig, wenn Bibliotheken in der falschen Reihenfolge angegeben werden oder wenn eine Bibliothek fehlt.
*'''Undefinierte Symbole''': Wenn ein Symbol, auf das verwiesen wird, nicht gefunden wird, meldet '''ld''' einen Fehler. Dies passiert häufig, wenn Bibliotheken in der falschen Reihenfolge angegeben werden oder wenn eine Bibliothek fehlt.
- **Verbose-Modus**: Mit der Option `-v` oder `--verbose` kannst du den Linker dazu bringen, detaillierte Informationen über den Verknüpfungsvorgang auszugeben:
*'''Verbose-Modus''': Mit der Option `-v` oder `--verbose` kannst du den Linker dazu bringen, detaillierte Informationen über den Verknüpfungsvorgang auszugeben:
  ```bash
:<syntaxhighlight lang="shell">
  ld --verbose
ld --verbose
  ```
</syntaxhighlight>


### Zusammenfassung
== Zusammenfassung ==


Der GNU Linker (ld) ist ein leistungsstarkes Tool, das essenziell für die Erstellung von ausführbaren Dateien und Bibliotheken ist. Es vereint Objektdateien, löst Symbole auf, verknüpft Bibliotheken und erstellt die endgültige Binärdatei. Durch seine Flexibilität bei der statischen und dynamischen Verknüpfung, seine Fähigkeit zur Nutzung von Linker-Skripten und seine erweiterbaren Optionen ist ld ein unverzichtbares Werkzeug für Entwickler in der GNU-Umgebung.
Der GNU Linker (ld) ist ein leistungsstarkes Tool, das essenziell für die Erstellung von ausführbaren Dateien und Bibliotheken ist. Es vereint Objektdateien, löst Symbole auf, verknüpft Bibliotheken und erstellt die endgültige Binärdatei. Durch seine Flexibilität bei der statischen und dynamischen Verknüpfung, seine Fähigkeit zur Nutzung von Linker-Skripten und seine erweiterbaren Optionen ist ld ein unverzichtbares Werkzeug für Entwickler in der GNU-Umgebung.
-----
{| style="width: 100%;
| style="width: 33%;" | [[GNU Debugger|< Zurück (GNU Debugger)]]
| style="width: 33%; text-align:center;" | [[Hauptseite|< Hauptseite >]]
| style="width: 33%; text-align:right;" | [[objdump|Weiter (objdump) >]]
|}

Aktuelle Version vom 24. September 2024, 08:15 Uhr

GNU ld ist der Linker der GNU Toolchain, der für die Verknüpfung von Objektdateien und Bibliotheken zu einer ausführbaren Datei, einem dynamischen Shared Object (DSO) oder einer Bibliothek verwendet wird. Der Linker spielt eine entscheidende Rolle in der Build-Pipeline eines C/C++-Projekts, indem er verschiedene Kompilierungsoutputs zusammenführt und externe Symbole auflöst.

Hauptaufgaben des GNU Linkers (ld)

Zusammenführung von Objektdateien

Der Linker kombiniert verschiedene Objektdateien (`.o`-Dateien), die durch den Compiler erzeugt wurden, zu einem einzigen Programm oder einer Bibliothek. Dabei werden die Objektdateien nacheinander eingelesen und ihre Symbole verknüpft.

Auflösen von Symbolen

Während des Verlinkungsvorgangs löst der Linker Symbole auf. Symbole sind Funktionen, Variablen und Objekte, die in den Objektdateien und Bibliotheken definiert oder referenziert werden. Der Linker stellt sicher, dass alle externen Verweise auf Symbole (wie Funktionsaufrufe oder globale Variablen) auf eine gültige Definition verweisen.

Erstellen von ausführbaren Dateien

Der GNU ld-Linker erstellt die endgültige ausführbare Datei aus den verknüpften Objektdateien und Bibliotheken. Dies kann eine statische oder dynamische Verknüpfung sein:

Statische Verknüpfung: Alle notwendigen Bibliotheksinhalte werden direkt in die ausführbare Datei eingefügt, wodurch sie unabhängig von externen Bibliotheken ausgeführt werden kann.
Dynamische Verknüpfung: Die ausführbare Datei enthält Referenzen auf externe, zur Laufzeit zu ladende dynamische Bibliotheken (Shared Libraries, z.B. `.so`-Dateien auf Unix-Systemen oder `.dll` auf Windows).

Bibliotheken verlinken

Der Linker kann sowohl statische Bibliotheken (`.a` in Unix/Linux) als auch dynamische Bibliotheken (`.so`) verknüpfen. Abhängig von den Verknüpfungsoptionen kann der Linker:

Statische Bibliotheken in die endgültige ausführbare Datei aufnehmen.
Dynamische Bibliotheken zur Laufzeit verwenden, sodass die Bibliothek erst geladen wird, wenn das Programm ausgeführt wird.

Verwalten von Speicheradressen und Abschnitten

Der GNU ld verwaltet die Speicherabschnitte (Text, Daten, BSS) der einzelnen Objektdateien und legt fest, welche Speicherbereiche für verschiedene Datenarten verwendet werden. Die Speicherorganisation umfasst:

  • Textsegment: Enthält den ausführbaren Maschinencode.
  • Datensegment: Enthält initialisierte globale und statische Variablen.
  • BSS-Segment: Enthält uninitialisierte globale und statische Variablen.

Außerdem kann der Linker die Startadresse des Programms festlegen und das Layout der Speichersegmente konfigurieren.

Laden von Startcode und dynamischen Loadern

Der Linker integriert den notwendigen Startcode (wie den C-Runtime-Startcode) und erstellt den Einstiegspunkt der ausführbaren Datei (normalerweise die Funktion `main()` für C-Programme). Bei dynamisch gelinkten Programmen sorgt er für die Integration des dynamischen Loaders, der für das Laden der Shared Libraries zur Laufzeit verantwortlich ist.

Verknüpfungsprozess: Statische und Dynamische Verknüpfung =

Statische Verknüpfung

Hierbei wird der gesamte Code aus den Bibliotheken direkt in die ausführbare Datei eingebettet. Dies führt zu größeren Binärdateien, aber die ausführbare Datei kann eigenständig ohne externe Abhängigkeiten laufen. Der Befehl könnte folgendermaßen aussehen:

gcc -o meinprogramm main.o libmylib.a

Dynamische Verknüpfung

Bei der dynamischen Verknüpfung referenziert das Programm zur Laufzeit externe Shared Libraries (`.so`-Dateien). Die ausführbare Datei ist kleiner, benötigt jedoch, dass die benötigten Bibliotheken zur Laufzeit verfügbar sind:

gcc -o meinprogramm main.o -lmylib

GNU ld-Optionen

Der GNU Linker bietet zahlreiche Optionen, um den Verknüpfungsvorgang zu steuern. Hier sind einige häufig verwendete:

-o: Legt den Namen der Ausgabedatei fest:

ld -o meinprogramm start.o main.o

-L: Gibt den Pfad zu Verzeichnissen an, in denen nach Bibliotheken gesucht werden soll:

ld -L/path/to/libs -lmylib

-l: Verknüpft eine Bibliothek (ohne den Präfix `lib` und die Erweiterung `.a` oder `.so`):

ld -o meinprogramm main.o -lmylib  # Verknüpft libmylib.a oder libmylib.so

-rpath: Gibt an, wo zur Laufzeit nach dynamischen Bibliotheken gesucht werden soll:

ld -o meinprogramm main.o -lmylib -rpath /usr/local/lib

-static: Erzwingt statische Verknüpfung, selbst wenn dynamische Bibliotheken verfügbar sind:

gcc -o meinprogramm main.o -static -lmylib

-T: Ermöglicht die Verwendung eines Linker-Skripts, um den Verknüpfungsvorgang genauer zu steuern. Mit einem Linker-Skript kannst du Speicherlayouts, Startadressen und Speichersegmentierung definieren.

ld -T linkerskript.ld -o meinprogramm main.o

Verwendung eines Linker-Skripts

Linker-Skripte geben dem Entwickler präzise Kontrolle über das Layout der erzeugten Binärdatei. Ein einfaches Linker-Skript könnte folgendermaßen aussehen:

SECTIONS {
  .text 0x1000 : { *(.text) }
  .data 0x8000 : { *(.data) }
  .bss  0xA000 : { *(.bss) }
}

Dieses Skript spezifiziert, dass das Textsegment bei der Adresse `0x1000`, das Datensegment bei `0x8000` und das BSS-Segment bei `0xA000` beginnen sollen. Der GNU ld-Linker nutzt dieses Skript, um die Speicheraufteilung des Programms genau zu kontrollieren.

Debugging und Fehlerbehebung

Der Linker bietet nützliche Werkzeuge zur Fehlersuche:

  • Undefinierte Symbole: Wenn ein Symbol, auf das verwiesen wird, nicht gefunden wird, meldet ld einen Fehler. Dies passiert häufig, wenn Bibliotheken in der falschen Reihenfolge angegeben werden oder wenn eine Bibliothek fehlt.
  • Verbose-Modus: Mit der Option `-v` oder `--verbose` kannst du den Linker dazu bringen, detaillierte Informationen über den Verknüpfungsvorgang auszugeben:
ld --verbose

Zusammenfassung

Der GNU Linker (ld) ist ein leistungsstarkes Tool, das essenziell für die Erstellung von ausführbaren Dateien und Bibliotheken ist. Es vereint Objektdateien, löst Symbole auf, verknüpft Bibliotheken und erstellt die endgültige Binärdatei. Durch seine Flexibilität bei der statischen und dynamischen Verknüpfung, seine Fähigkeit zur Nutzung von Linker-Skripten und seine erweiterbaren Optionen ist ld ein unverzichtbares Werkzeug für Entwickler in der GNU-Umgebung.


< Zurück (GNU Debugger) < Hauptseite > Weiter (objdump) >