Übersicht über Standard Linker Sections

Letztes Update: Dienstag, 16. August 2016 - 16:41 Uhr

Auf dieser Seite findest du eine Übersicht über typische Standard Linker Sections mit Informationen zur Initialisierung und das Schreibe- und Leseverhalten.

Einige Code-Beispiele zeigen außerdem "Was landet in welcher Linker Section?". Auch wenn man sich typischerweise für "normalen" Code und "normale" Daten nicht um Linker Sections kümmern muss, kann es manchmal (z.B. im Embedded Bereich) sehr hilfreich sein, die Zuordnungen zu kennen. In einigen Fällen kann auch eine bestimmte Festlegung sinnvoll sein, z.B. um bestimmte Daten in ein EEPROM zu legen oder ein vorhandenes SRAM für schnellen Zugriff zu nutzen.

Wenn du weitere nützliche Informationen oder Anmerkungen zu dem Thema hast, würde ich mich sehr über eine Nachricht freuen.

Standard Linker Sections - Übersicht

Section Name: Beschreibung:

.text
(.code)

Ausführbarer Programm-Code (executable).
nur-lesbare Daten (read-only data).
kein Schreibzugriff (write-protected; Schreibvorgänge auf Adressen innerhalb dieser Section lösen eine Assertion in Win32 u.a. Systemen aus).
Häufig in ROM-Speicher (bzw. Flash) abgebildet (rommable).
Die .text Section enthält die Maschinenbefehle, die das Programm ausmachen, wird daher auch häufig Code Section genannt.

.data

Initialisierte Daten (initialized data).
Schreib- und lesbare Daten (writable and readable).
Daten sind nicht ausführbar (not executable).
Nicht für ROM-Speicher geeignet (not rommable), die Daten können aber bei Programmstart aus dem ROM initialisiert werden.
Für statische Daten, die im Code definiert wurden; Wird vom Startup-Code initialisiert.

.rdata
(.rodata)

Ähnliche wie .data section, aber nicht schreibbare Daten (read-only, write-protected).
Typischerweise von Microsoft Compilern für Konstanten genutzt.

.bss

Uninitialisierte Daten (uninitialized data).
Reservierter Speicherbereich, mit Null initialisiert (zero-filled memory).
Typischerweise globale oder statische Variablen.

.ctors

Statische Konstruktoren (constructors of static objects).
In C++ Programmen eingesetzt.
Können in ROM-Speicher abgebildet werden (rommable).

.dtors

Statische Destruktoren (destructors of static objects).
In C++ Programmen eingesetzt.
Können in ROM-Speicher abgebildet werden (rommable).

.eeprom

Auf einigen Systemen für EEPROM Variablen gedacht.

.noinit

Auf einigen Systemen für Daten, wird nicht initialisiert.

Der folgende Code-Ausschnitt zeigt eine Beispiel-Zuordnung für Linker-Sections.
Je nach System und Compiler/Linker können die Daten natürlich anders optimiert und abweichenden Sections zugeordnet werden. Beispielsweise landen konstante Variablen häufig direkt im Programmcode.

Beispiel C-Sourcecode:

#include <stdio.h>
#include <stdlib.h>

const int  g_one = 1;             // constant initialized global variable: e.g. section .text/.data/.rdata
static int g_two = 2;             // initialized global variable:          e.g. section .data
static int g_three;               // un-initialized global variable:       e.g. section .bss

int main(int argc, char *argv[]) {
  const int  four = 4;            // constant initialized local data:      e.g. local stack/section .text
  static int five = 5;            // initialized local data:               e.g. section .data
  static int six;                 // un-initialized local variable:        e.g. section .bss
  int        seven;               // local variable:                       e.g. local stack/register
  char       str[] = "MyString";  // constant string:                      e.g. local stack/section .data

  // ...
  g_three = 3;
  six     = 6;
  seven   = 7;
  printf("g_one:   %d\n", g_one);
  printf("g_two:   %d\n", g_two);
  printf("g_three: %d\n", g_three);
  printf("four:    %d\n", four);
  printf("five:    %d\n", five);
  printf("six:     %d\n", six);
  printf("seven:   %d\n", seven);
  printf("str:     %s\n", str);

  return 0;
}

 

Beispiel C++ Sourcecode:

#include <MyClass.hpp>

int main() {
  MyClass test();        // call constructor of MyClass for initialization of the object
  test.SomeFunction();
  return 0;
}

In dem obigen Beispiel wird ein Objekt vom Typ "MyClass" mit dem Namen "test" durch Aufruf des "MyClass"-Konstruktors erzeugt. Anschließend wird die Member-Funktion "SomeFunction()" aufgerufen und das Programm beendet.

#include <MyClass.hpp>

static MyClass test();   // static constructor/destructor

int main() {
  test.do();
  return 0;
}

Das zweite Beispiel macht prinzipiell das Gleiche, allerdings wird der "MyClass"-Konstruktor diesmal ausgeführt, bevor die Programmeintrittsfunktion "main()" aufgerufen wird. Der Konstruktoraufruf wird also nicht innerhalb von "main()" initiiert, sondern vorher von der Laufzeitumgebung. Damit das möglich ist, erzeugt der Compiler eine spezielle .ctor Section (und eine .dtor Section für die Desktruktoren) mit entsprechenden Zeigern auf die statischen Konstruktoren/Desktruktoren.

 

Links zum Thema Linker Sections:


 

Fehlt etwas in der Übersicht der Standard Linker Sections? Hast du Anregungen oder einen Fehler gefunden? Schreibe doch einen Kommentar...

 

Neuen Kommentar abgeben

sbpkq