Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
software:deep:dev:crosscompiler:linker32 [2014-02-10 10:31] – graf | software:deep:dev:crosscompiler:linker32 [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== Linker32 ====== | ||
- | The linker32 is written for 32 bit platforms. The linker performs various tasks like: | ||
- | * Place code in the memory | ||
- | * Create type descriptors and constant blocks | ||
- | * Create system table | ||
- | * Create target image | ||
- | ===== Initialization ===== | ||
- | As a first step the linker must be initialized with the method //init()//. What happens is: | ||
- | * Determine size of // | ||
- | * Search segments for the system table | ||
- | * Delete previous target image | ||
- | |||
- | ===== Create Constant Block ===== | ||
- | Each class has a constant block. Certain interfaces need a reduced constant block and arrays just need a type descriptor, see [[.: | ||
- | * Header (base, size, ...) | ||
- | * Global pointer list | ||
- | * Type descriptor | ||
- | * String pool | ||
- | * Constant pool | ||
- | * Checksum | ||
- | [{{ .: | ||
- | The //const pool// contains values of type //float// and //double// which are not placed directly into the code. After all elements are added the // | ||
- | When the system ist starting up, the [[..: | ||
- | |||
- | In the compiler the constant block is modeled as linked list of '' | ||
- | * **'' | ||
- | * **'' | ||
- | * **'' | ||
- | * **'' | ||
- | * **'' | ||
- | * **'' | ||
- | |||
- | ==== Type Descriptor ==== | ||
- | The structure and purpose of the [[Type Descriptor]] is described separately. | ||
- | |||
- | ==== String pool ==== | ||
- | The string pool holds the constant strings of a class. They are stored as follows (also see [[strings|Strings]]: | ||
- | [ tag ] | ||
- | [ stringClassAddress ] | ||
- | [ Object | ||
- | [ nofChars | ||
- | [ chars ] | ||
- | [ ⋮ ] | ||
- | The characters of the string are stored in 2-Byte-Unicode. | ||
- | |||
- | ==== Constant Pool ==== | ||
- | The constant pool holds the constants of a class. Currently we only store there floating point numbers (//float// and // | ||
- | |||
- | **Example: | ||
- | [40490FDB] 3.1415927 (float) | ||
- | [401921FB] 6.283185307179586 (double) | ||
- | [54442D18] | ||
- | |||
- | |||
- | ===== Calculate Size and Offsets ===== | ||
- | [{{ .: | ||
- | Before the memory map can be fixed, a couple sizes and offsets must be calculated for each class: | ||
- | * '' | ||
- | * '' | ||
- | |||
- | ===== Create System Table ===== | ||
- | The linker assembles a system table for the whole system. This table must be loaded to a prefixed address in the target system and holds information for the [[..: | ||
- | - The system runs from the flash | ||
- | - The system runs from the RAM. | ||
- | - The base system is in the flash. Further classes are later loaded into the RAM. This case needs two system tables. The flash holds a system table which contains only classes which are present in the flash. The system table in the RAM must hold all classes. IMPORTANT This feature is not implemented yet IMPORTANT | ||
- | \\ | ||
- | Die Methode '' | ||
- | |||
- | Die Systemtabelle hat den folgenden Aufbau: | ||
- | [{{ .: | ||
- | |||
- | Bevor die Systemtabelle zusammengestellt werden kann, muss der Klassenkonstruktor der Kernel-Klasse gefunden werden. Dazu wird der Klassennamen aus der Konfiguration geladen und anschliessend die Methode ''< | ||
- | |||
- | Nun kann die Systemtabelle aufgebaut werden. Dazu wird als erstes der Offset zum Beginn der Klassenliste (Liste mit der Basisadresse des Konstantenblocks jeder Klasse) eingefügt. Anschliessend werden die Informationen zu Heap und Stack eingefügt. Anschliessend die Anzahl vorhandener Klassen und die bereits erwähnte Liste mit den Basisadressen der Konstantenblöcke. Die Systemtabelle wird mit dem Wert 0x0 abgeschlossen. | ||
- | |||
- | Der letzte Teil mit den Referenzen auf den Konstantenblock der einzelnen Klassen ist wie folgt zusammengestellt. Zuerst kommen alle Klassen mit einem Klassenkonstruktor. Diese Klassen sind bereits in der korrekten Reihenfolge gemäss [[class_initialization]] sortiert. Anschliessend kommen alle nicht-initialisierten Klassen. Arrays und Interfaces haben keinen Konstantenblock und kommen nicht in die Liste mit Ausnahme von Interfaces, die einen Klassenkonstruktor haben, siehe // | ||
- | \\ | ||
- | Beim MPC555 wird die Systemtabelle in der Dual-Mapped-Section direkt nach dem Exceptioncode positioniert (Addresse 0x2000 -> siehe Memory Map). | ||
- | |||
- | ===== Memory Map fixieren ===== | ||
- | [{{ .: | ||
- | Das Platzieren des Codes, der statischen Variablen und der Konstanten im Speicher geschieht wie folgt. Als erstes wird jeder Klasse ein Memory-Segment für den Code ('' | ||
- | Anschliessend wird die verwendete Grösse auch noch für das Systemtabellen-Segment gesetzt und das Speichersegment für die globale Konstantentabelle festgelegt. | ||
- | In einem weiteren Schritt wird die Grösse für jedes verwendete Segment festgelegt (sofern nicht bereits in der Konfiguration vorgegeben). Nun kann für jedes verwendete Segment die Basisadresse berechnet werden. | ||
- | \\ Achtung: Ganz zu Beginn müssen Systemmethoden, | ||
- | |||
- | ===== Absolute Adressen berechnen ===== | ||
- | Nachdem der Code, die statischen Variablen und der Konstantenblock jeder Klasse und auch die Systemtabelle und die globale Konstantentabelle platziert sind, werden nun die absoluten Adressen berechnet. Dazu steht die Methode '' | ||
- | In einem ersten Schritt werden die Adressen für die statischen Felder bestimmt. Dazu läuft der Linker durch die entsprechende Liste ('' | ||
- | Im nächsten Schritt werden die Adressen der Methoden berechnet. Dabei müssen die durch die Konfiguration absolut positionierten Methoden (Exception-Handlers)wiederum speziell behandelt werden. | ||
- | Als drittes werden die Adressen für die Konstanten im //Constant pool// und die Strings im //String pool// berechnet. | ||
- | |||
- | Als letztes wird noch die Adresse der Klasse selbst ('' | ||
- | |||
- | Diese Methode muss vom // | ||
- | |||
- | ===== Konstantenblock aktualisieren ===== | ||
- | Nach dem Festlegen der Adressen kann nun der Konstantenblock aktualisiert werden. Dazu legt die Methode '' | ||
- | |||
- | ===== Globale Konstantentabelle erstellen ===== | ||
- | In der globalen Konstantentabelle werden Konstanten gespeichert, | ||
- | |||
- | ===== Target Image erstellen ===== | ||
- | Zum Schluss wird das Target Image erstellt. Dabei wird für jede Methode jeder Klasse und für Konstantenblock (einer pro Klasse, Array oder Interface) je ein TargetSegment erzeugt und in einer Liste abgelegt. | ||
- | |||
- | ---- | ||
- | |||
- | ===== Verwendung von index, offset und address der Klasse Item ===== | ||
- | Die Felder //index//, //offset// und //address// der Klasse '' | ||
- | |||
- | **Bemerkung: | ||
- | |||
- | ==== Klassen [Class] ==== | ||
- | * //index//: Wird verwendet, um Interfaces für Interfacemethoden zu nummerieren. | ||
- | * //offset//: Wird nicht verwendet, ist immer -1. | ||
- | * // | ||
- | |||
- | ==== Arrays [Array] ==== | ||
- | * //index//: Wird nicht verwendet, ist immer -1. | ||
- | * //offset//: Offset des Typdescriptors im Segment. | ||
- | * // | ||
- | |||
- | ==== Methoden [Method] ==== | ||
- | * //index//: Bei Instanzmethoden der Index der Methode in der Methodentabelle (beginnend bei 0). Bei Klassenmethoden ist //index// immer -1. -> Wird vom CFR gesetzt. | ||
- | * //offset//: Byteoffset der Methode ausgehend von der Startadresse des Codes der Klasse. | ||
- | * // | ||
- | |||
- | ==== Felder [DataItem] ==== | ||
- | <box right 30% | IMPORTANT Konstante Referenzen> | ||
- | **Achtung: | ||
- | |||
- | **Beispiel: | ||
- | static final Object o = new Object(); | ||
- | </ | ||
- | - **Klassen-Felder [DataItem]: | ||
- | - Konstante Felder [NamedConst]: | ||
- | * //index//: Wird nicht verwendet, ist immer -1; | ||
- | * //offset//: Wird nicht verwendet, ist immer -1; | ||
- | * // | ||
- | - Nicht konstante Felder [DataItem]: | ||
- | * //index//: Wird nicht verwendet, ist immer -1. | ||
- | * //offset//: Byteoffset des Feldes (beginnend bei 0 für das erste Feld). | ||
- | * // | ||
- | - **Instanz-Felder [DataItem]: | ||
- | * //index//: Wird nicht verwendet, ist immer -1; | ||
- | * //offset//: Byteoffset des Feldes beginnend bei 0 (inkl. Berücksichtung der Felder der Oberklassen). | ||
- | * // | ||
- | |||
- | ==== Konstanten [Constant] ==== | ||
- | - **Zahlen [StdConstant]: | ||
- | * //index//: Wenn die Konstante vom Typ //float// oder //double// ist, ist //index// der Index der Konstante im Konstantenpool. Ansonsten immer -1; | ||
- | * //offset//: Wenn die Konstante vom Typ //float// oder //double// ist, ist //offset// der Byteoffset der Konstante im Konstantenpool. Ansonsten immer -1; | ||
- | * // | ||
- | - **Stings [StringLiteral]: | ||
- | * //index//: Wenn es sich bei der Konstante um einen String handelt, so wird in //index// der Index des Strings im Stringpool abgelegt. | ||
- | * //offset//: Wenn es sich bei der Konstante um einen String handelt, so wird in //offset// der Byteoffset des Strings im Stringpool abgelegt. | ||
- | * // |