CLink Manual für CLink V 1.01 © 1992/1993 Maxon Computer GmbH Geschrieben von Michael Rock. Vorwort: oder - Das Bessere ist des Guten Feind. Leidgeprüfte Programmierer kennen sie, die Amiga-Gedenk-Minute. Eingeführt wurde sie mit dem ALink (heute vom Aussterben bedroht). Wie viele Tassen Kaffee wurden in ihr getrunken ? Was hätte man mit der Zeit alles machen können ? Die Software-Distillery schrieb den BLink. Aus der Amiga-Gedenk-Minute wurden einige Gedenk-Sekunden. Der BLink offenbarte jedoch sonderbare Verhaltensweisen, wenn man ihm sonderbare Programme gab. Er lehnte die neue amiga2.0.lib sogar völlig ab. Auch seine Optionsvielfalt hatte nicht für alle Benutzer genug zu bieten. So wurden viele Tools geschrieben um die fertigen Programme an die Bedürfnisse anzupassen. Ich schrieb den CLink. Seine Auswirkungen auf die Programmentwicklungen sind noch nicht absehbar. Inhalt: 1 .......................Was ist CLink 2 .......................Benutzung 2.1 .......................Parser 2.1.1 .......................FROM 2.1.2 .......................TO 2.1.3 .......................MAP 2.1.4 .......................LIBRARY | LIB 2.1.5 .......................CHIP 2.1.6 .......................FAST 2.1.7 .......................CHIPCODE FASTCODE CHIPDATA FASTDATA CHIPBSS FASTBSS 2.1.8 .......................DEBUG 2.1.9 .......................ROMCODE 2.1.10 ......................BASE 2.1.11 ......................WITH 2.1.12 ......................ONEHUNK 2.1.13 ......................MERGE 2.1.14 ......................VERBOSE 2.1.15 ......................SMALLCODE SMALLDATA SMALLBSS 2.1.15 ......................MAXCODE MAXDATA MAXBSS 2.1.16 ......................RESIDENT | RES 2.1.17 ......................WARNREL 2.1.18 ......................OPTIMIZE 2.1.19 ......................OOP 2.2 .......................Verhaltensstudien 2.2.1 .......................Hints 2.2.2 .......................Namensgebung 2.2.3 .......................Vor- und Nachteile 3 .......................Technische Einzelheiten. 3.1 .......................Arbeitsweise 3.2 .......................Vordefinierte Werte 3.2.1 ......................._LinkerDB 3.2.2 .......................__SmallData 3.2.3 .......................RESIDENT 3.2.4 .......................__DATALEN __BSSBAS __BSSLEN __OFFSET 3.3 .......................Hunkzusammenlegung 3.3.1 .......................Seicherklassen 3.3.2 .......................Reihenfolgen 3.3.3 .......................NearCode / NearData 4 .......................Warnungen/Fehlermeldungen 5 .......................Undokumentierte Verhaltensweisen (bugs) 6 .......................Danksagungen 1. Was ist CLink ? CLink ist ein Smartlinker für AmigaDOS Objektdateien. Die Standardlinker arbeiten auf Unitebene, d.h. wenn aus einem Objektmodul, das aus code/data/bss Hunks bestehen kann, nur der Datahunk benötigt wird, linken diese Linker den ganzen Code/Bsshunk mit, auch wenn dieser nicht angesprochen wird. CLink geht einen anderen Weg. Ausgehend vom ersten Codehunk werden alle benötigten Hunks markiert. Somit enthält das fertige Programm nur die nötigen Sektionen und ist deshalb so klein wie möglich. 2. Wie benutze ich ihn ? CLink wird von einer Kommandozeile aus gestartet und mit übergebenen Parametern gesteuert. 2.1 Parser. Der Parser des Linkers erkennt folgende Optionen: 2.1.1 FROM Lädt als erstes die Datei ein. Diese Option ist in WITH-Dateien zwar erlaubt, wenn sie aber nicht die erste Option ist, führt sie zu falschen Ergebnissen. 2.1.2 TO Setzt den Namen der Zieldatei. CLink prüft nicht, ob die Datei bereits existiert, er überschreibt also ev. irrtümlich angegebene Dateien. Diese Option ist in WITH-Dateien nicht erlaubt. 2.1.3 MAP [] Wenn der Name nil: angegeben ist, wird kein Mapfile erzeugt. MAP funktioniert also nicht. CLink versucht zu parsen, wenn es keine Option ist, zu laden, und wenn er sie nicht laden kann, wird eine Fehlermeldung ausgegeben. Der Name der Linkermapdatei ist abhängig von dem Namen des erzeugten Programmes, angehängt wird '.map'. 2.1.4 LIB | LIBRARY Schaltet den Suchpfad für Bibliotheken ein. Alle nach dieser Option spezifizierten Objectcodes werden zuerst unter ihrem Namen gesucht. Sollte die Datei nicht dort sein, wird lib: geöffnet. Sollte auch dies nicht funktionieren, probiert CLink es mit lib:.lib . Erst wenn dies auch nicht geht, wird ein Fehler gemeldet. 2.1.5 CHIP Legt den Speichertyp für das fertige Programm fest. Die Angabe von 'CHIP' erzwingt das Laden des gesamten Programmes in das Chipmemory. 2.1.6 FAST Siehe CHIP, erzwingt jedoch Laden in FastMemory. ACHTUNG : Sollte ein Rechner kein FastRAM haben, führt der Versuch ein solches Programm zu starten zu dem AmigaDOS Fehler 103 (out of memory). 2.1.7 CHIPCODE FASTCODE CHIPDATA FASTDATA CHIPBSS FASTBSS Mit diesen Optionen kann man den Speichertyp für Code, Daten und Bss separat bestimmen. Sollte Ihr Programm BOB-Daten oder Images oder irgendetwas enthalten, das in das CHIP-RAM geladen werden muss, kann es ausreichen, die Option CHIPDATA zu setzen. Der Programmcode belegt nun kein ChipRAM mehr, wenn FastRAM vorhanden ist. 2.1.8 DEBUG Erzeugt HUNK_SYMBOL Daten. Diese Option kopiert Symbolinformationen aus dem Objectcode in die Zieldatei, so daß Sprungmarken in einem Debugger im Klartext lesbar sind. CLink beschränkt sich nicht nur darauf die Symbolinformation zu kopieren, er fügt auch alle globalen Symbole zu, wodurch manchmal eine Addresse zweimal mit dem selben Namen versehen wird. 2.1.9 ROMCODE Für die User, die EPROMS brennen. Nur für die Leute zu empfehlen, die GENAU wissen, was sie vorhaben. Die erzeugte Datei enthält die reinen Binärdaten der Code- und Datenhunks. Die Bss-hunks sollte mittels AllocAbs() an der zu bestimmenden Adresse belegt werden. Code- und Datenhunks sind an die vorgegebene Adresse reloziert, das AmigaDOS Overhead, wie z.B. Reloziertabellen, entfällt. Nach den angegebenen Bytes an Code stehen in der Zieldatei nur noch die Daten. Vorsicht : sollte Ihr Programm die Daten relativ zu einem Adressregister nutzen, wird auch hier der Bss-hunk direkt hinter dem Datenhunk vermutet. Die Addresse für Bss ist somit + Die Optionen für SmallCode, SmallData und SmallBss werden automatisch gesetzt. Somit gibt es keine Fragmentierung. 2.1.10 BASE Setzt den Offsetwert der LinkerDataBase im erzeugten Programm auf den Wert Erstes Datenobjekt + . Sollte Ihr Programm viele Daten enthalten und CLink Ihnen eine Fehlermeldung für 16 Bit Referenz/Reloc Überlauf anzeigen, kann eine BASE-Nummer von 0x8000 eventuell Abhilfe schaffen. Wenn auch dies nicht funktioniert, muß man 32 Bit Adressen verwenden. Anmerkung : Manche Compiler ( auch der Maxon C++ ) gehen davon aus, daß die LinkerDataBase konstant 0x8000 ist. Dem muss nicht so sein ! Da der Maxon C++ jedoch nicht mit der _LinkerDB als NearDataBase arbeitet, (das Symbol heißt hier __SmallData) gibt es keine Probleme, solange Sie BASE auf null lassen. 2.1.11 WITH Lädt alle in aufgeführten Dateien. Es darf nur EIN Name pro Zeile angegeben werden. Es können mehrere WITH-Optionen in der Kommandozeile angegeben werden. Rekursive WITH-Anweisungen sind nicht gestattet. 2.1.12 ONEHUNK Erzeugt nur einen CODE-Hunk, der alle Code, Daten und Bss-Sektionen enthält. Dies ist interessant für Spieleprogrammierer. Eine Relozierroutine braucht nun nur einen Hunk zu behandeln. Sollte das Programm im SmallDataModell vorliegen, kann man hiermit in einer Hochsprache komplett PC-relative Programme schreiben. Das Basisregister für den Datenzugriff (Normalerweise A4) wird nun mittels lea _LinkerDB(PC),a4 initialisiert. Wenn alle anderen Zugriffe mittels d16(pc) oder d16(a4) gemacht werden, enthält das Programm keine absoluten Addressen mehr. Solche Programme werden sehr schnell geladen, sind jedoch in den meisten Fällen nicht reentrant. In Verbindung mit ROMCODE erhält man ein Programm, das man mittels Read(File, buffer, len) an irgendeine (GERADE) Adresse laden kann, und das dort sofort lauffähig ist. 2.1.13 MERGE Erzeugt nur einen Hunk für Daten und Bss. Achtung: der Bss-Hunk wird nun von AmigaDOS NICHT mehr mit Nullen initialisiert. CLink setzt diese Option selbständig, wenn er 16-Bit Code->Data Offsets entdeckt, also NearData vorliegt. Wenn die Optionen SmallData oder SmallBss nicht gesetzt werden und keine MERGED Hunks existieren, hat diese Option keinen Effekt. Sie sollten diese Option dem Linker überlassen. 2.1.14 VERBOSE Schaltet die Prüfung auf mehrfache Symbole ein. Wenn VERBOSE gesetzt wurde, zeigt CLink den Namen der gerade geladenen Datei an und sucht nach mehrfach vorkommenden Symbolen. Sollten solche gefunden werden, zeigt CLink den Dateinamen an, in welcher das Symbol definiert wurde. Die Prüfung erstreckt sich auch auf die Bibliotheken, weil dort Namen mehrfach benutzt werden können, jedoch unterschiedliche Bedeutung haben. Bestes Beispiel : die C-Funktion printf gibt es auch noch- mal in der math.lib, diese jedoch kann auch Fließkommawerte drucken. 2.1.15 SMALLCODE SMALLDATA SMALLBSS Normalerweise legt CLink die Hunks anhand ihrer Speicherklasse zusammen. Ausnahmen bilden Hunks, die mit anderen über 16/8 Bit Referenzen verbunden sind. Solche Hunks müssen zusammengelegt werden, CLink erledigt das Anpassen der Speicherklasse für Sie selbständig. Die Angabe von SMALLCODE erzwingt die Zusammenlegung aller Code-hunks. 2.1.15 MAXCODE MAXDATA MAXBSS Normalerweise legt CLink alle Hunks mit dem selben Typ zusammen, also alle NEAR Hunks, alle PUBLIC_CODE Hunks, ... Mittels dieser Optionen ist es möglich, sein Programm zu fragmentieren, d.h. mehrere Hunks mit gleichem Typ zu erzeugen, die aber kleiner sind. CLink fügt zu jedem Hunk solange einen anderen des selben Typs zu, bis er die angegebene Größe überschreiten würde. Sollte man schreiben 'MAXCODE 1', so wird kein CODEHUNK mit einem anderen verbunden, (fast) jeder CODEHUNK wird einzeln erscheinen. Eine Ausnahme wird für Hunks gemacht, die als MERGED ausgezeichnet wurden, diese werden IMMER zusammengelegt. 2.1.16 RESIDENT | RES Normalerweise enthält ein Hunk mit SmallData auch die SmallBss-Bereiche, die vom Startupcode mit Nullen gefüllt werden müssen. +--------------+ | NearData | +--------------+ | NearBss | +--------------+ Sollte Ihr Programm frei von direkten 32 Bit Daten/Bss Zugriffen sein, so kann man durch das Allokieren von Speicher und dem Kopieren der Daten für ein residentes Programm für jede Instanz eine private Datensammlung erstellen. Dabei stört nun jedoch der Bss-Bereich. Die Resident-option entfernt ihn. +--------------+ | NearData | +--------------+ Nichts mehr 2.1.17 WARNREL Sollte das Programm 32 Bit Relocs enthalten, gibt CLink eine Warnung aus. Nicht zu verwechseln mit RESIDENT. 2.1.18 OPTIMIZE Diese Option ist im Moment noch im Experimentierstadium und mit EXTREMSTER Vorsicht zu handhaben. Ist OPTIMIZE gesetzt, führt CLink einen optimierenden Pass über den Code aus. Wenn eine 32-Bit Referenz gefunden wird, die in den selben Hunk zeigt, versucht CLink diese in eine PC-relative Form zu wandeln. Dabei wird der Reloceintrag frei, was etwa 4 Byte ausmacht. Die verwendete Methode ist alles andere als sicher, weshalb die Optimierung zu falschen Programmen führen kann. Der Optimierer enthält nur einen kleinen 'Disassembler', der die Befehle JSR, PEA und die LEA- Befehle kennt. Er hat keine Möglichkeit, zwischen Code und Daten im Code zu unterscheiden. Beispiel: Schreiben Sie in ein Programm etwas in der folgenden Art: dc.w OP_JSR_L dc.l LabelDahin Solche Konstruktionen werden in switch() Tabellen benutzt. Der Optimierer macht daraus folgendes: dc.w OP_JSR_PC dc.w LabelDahin-* dc.w OP_NOP Der Optimierer wird nur für globale Referenzen aufgerufen, wenn also zwischen Objectmodulen Referenzen gebildet werden. Für Relocationseinträge sollte ein Assembler oder Compiler diese Optimierungen durchführen. 2.1.19 OOP Erzeugt Autoinitroutinen kompatibel zu denen des Maxon C++. Wenn diese Option gesetzt wurde, assembliert CLink eine Routine namens '_InitModules' und eine namens '_CleanupModules'. Diese Routinen rufen alle benötigten _INIT_x_.... und _EXIT_x_.... Routinen auf. 'x' sei eine Nummer zwischen 0 und 9, '....' ein beliebiger Text. Die mehrfache Verwendung des selben Namens ist hier und nur hier erlaubt. Sollten die erzeugten Routinen nicht leer sein aber nicht benutzt werden, wird eine Warnung ausgegeben. Die _InitModules- Routine ruft zuerst die _INIT_0_... Routinen auf, die _INIT_9_... zuletzt. In der _CleanupModules- Routine ist diese Reihenfolge umgekehrt. 2.2 Verhaltensstudien Ein paar Absätze über das Verhalten von CLink im Normalfall. 2.2.1 Hints: Die Hintfunktion arbeitet etwa wie folgt : Aus der Importreferenz ist ersichtlich, wo das Symbol referiert wird. Nun kann man das Symbol suchen, das am dichtesten davor liegt und einen globalen Namen darstellt. Dies sollte nun eigentlich der Name der Funktion/der Struktur sein, die die nicht definierte Referenz enthält. Nun muss ja nicht jede Funktion global sein, somit kann der Hint auch auf Funktionen VOR der verursachenden zeigen, wenn diese nicht global ist. Beispiel: public main,test1,test2 main: pea test2(pc) jmp test1(pc) end Sollte nun test1 nicht gefunden werden, erzeugt CLink folgendes: Symbol 'test1' nicht definiert Erste Referenz in Datei 'dh20:KickStart7.0/Trackdisk/Guru.o' Tip: benutzt in main() ? Sollte der Programmierer auf die Idee kommen, 'main' nicht als global zu definieren, kann es zu Problemen kommen. CLink schreibt den Fehler nun der davor liegenden Funktion zu. 2.2.2 Der Name des fertigen Programmes: CLink leitet den Namen von der zweiten Objektdatei ab, die in der Kommandozeile steht. Sollte dort nur eine Objektdatei sein, wird die erste herangezogen. Wenn CLink gar keinen Anhaltspunkt hat, wird nach a.out geschrieben. Der Name der Zieldatei ist der der Quelldatei ohne Extension. Sollte der Name nicht mit '.xxx' (xxx = irgendwas) enden, wird '.exe' angehängt. Beispiele: CLink lib:start.o vogon.o lib amiga => vogon CLink lib:start test lib amiga => test.exe CLink with totalgaiol.lnk => a.out CLink with totalgaiol.lnk lib amiga => amiga.exe 2.2.3 Vor/Nachteile: Es folgt eine kleine Liste der Vor- und Nachteile, so wie ich sie subjektiv sehe. Vorteile: SmartLinker: CLink ist ein sog. SmartLinker, der nur die unbedingt nötigen Teile in ein Programm einlinkt. Geschwindigkeit: Da CLink alle Daten im RAM hält, läßt die Geschwindigkeit im Vergleich zu anderen Linkern nicht nach. Er ist bisher der schnellste mir bekannte Linker. Ein Beispiel: Der C-Compiler, den ich benutze, ist etwa 200 KByte groß. Um ihn zu Linken werden folgende Scritte benutzt: join Work:compiler/Obj/*.o ram:compiler.o clink work:lib/res.o ram:compiler.o lib cc\ amiga math Der gesamte Objectcode ist 161068 Bytes groß, die Bibliotheken belegen 120100 Bytes. CLink benötigt auf meinem 7Mhz Amiga etwa 13 Sekunden... CLink bietet Optionen, die das Programmieren von ROMs, Demos, Spielen und anderem unterstützen. CLink ist residentfähig. CLink hat eine Hint-Funktion für nicht definierte Symbole. CLink ist 'smart'. Der Abbruch mit Ctrl-C führt zu einem Requester, in dem man sich die Sache noch mal überlegen kann. Für den Fall, daß das RAM nicht reicht, erscheint ebenfalls ein Requester, der darauf hinweist. Man kann nun für Abhilfe sorgen (Editor schließen, ...), oder abbrechen. Sollte eine kritische RAM-Situation eintreten - wenn also nach einer Speicherallokierung weniger als 15 KB frei bleiben - erzeugt CLink einen Warn-Requester. Dies ist implementiert, weil einige Programme bei Speichermangel abstürzen könnten. Nachteile: CLink benötigt mehr Speicher als andere Linker. CLink behandelt die HUNK_DEBUG Informationen nicht. CLink erzeugt keine Warnungen für mehrfach auftretende Symbole. (ohne Option VERBOSE) CLink beachtet den HUNK_NAME nicht. Die Hintfunktion ist nicht perfekt, die Beschränkung ist jedoch im Objectfileformat begründet. CLink erkennt den HUNK_LIB (noch) nicht. 3. Technische Einzelheiten: Es folgen einige technische Einzelheiten, die es dem geneigten Leser erlauben, den Linker besser zu verstehen und auszunutzen. 3.1 Arbeitsweise: CLink lädt alle Dateien in das RAM, und startet erst dann das Linken. Somit müssen alle Dateien, auch die Bibliotheken in das RAM passen. Anschließend löst CLink alle Symbolreferenzen auf, wobei die Suche nach einem Namen im Codebereich startet, im Datenbereich fortfährt und der Bss-Bereich zum Schluß durchsucht wird. Ausnahmen sind ext_dext32/16/8 Symbole, diese werden zuerst im Datenbereich gesucht. Sollte also eine Funktion genau so heißen wie ein globales Datenelement, führt jeder Schreibzugriff auf dieses zu selbstmodifizierendem Code (auch Absturz genannt). Alle Hunks, die von einem Programm angesprochen werden, werden markiert. Der Rest wird aus den internen Listen gestrichen. Nun werden die Hunks zusammengefaßt, die Relocs angepasst und die Speicherklassen berechnet. Sollten keine schweren Fehler aufgetreten sein, wird das Programm nun abgespeichert 3.2 Vordefinierte Werte: CLink definiert konstante Symbole für die LinkerDataBase, für die Länge des Daten- und Bsshunks. Die Schreibweise ist kompatibel mit der des BLink 6.7. Der BLink weist nicht alle der angeführten Symbole auf. 3.2.1 _LinkerDB: (label) Zeiger auf erstes Datenelement + BASE . Zeigt bei BASE 0 (default) auf das erste Element des Datenhunks. 3.2.2 __SmallData: (label) Zeigt auf das erste Datenelement + $8000, wird vom Maxon C++ Compiler verwendet. Dieser Compiler geht davon aus, daß der BASE-Wert immer $8000 ist, das ist das Maximum. Das Mischen von Objectcodes, die unterschiedliche Auffassungen betreffend des BASE-Wertes haben, ist möglich, führt jedoch garantiert zu Abstürzen. Wenn Sie Ihr Programm mit Objectdateien des C++ Compilers linken wollen, schreiben Sie immer '(label+$8000)(A4)', nehmen Sie '__SmallData' zum Initialisieren des Basisregisters und setzen Sie den BASE-Wert auf 0. 3.2.3 RESIDENT: (const) 1 wenn man RESIDENT linkt, sonst NULL. 3.2.4 SmallData Symbole: __DATALEN: (const) Länge des Datenbereiches in LONGWords. Gültig für den MERGED-Hunk. __BSSBAS (label) Start des BSS-Bereiches im MERGED-Hunk. __BSSLEN: (const) Länge des BSS-Bereiches in LONGWords, Anteil im MERGED-Hunk. __OFFSET: (const) Der mittels BASE angegebene Offset. Diese Werte sind nützlich, wenn man ein Resident-Pure Programm schreiben will. Ausserdem kann ein Startupcode selbstständig feststellen, ob der BSS-Bereich noch initialisiert werden muss oder ob das Programm RESIDENT gelinkt wurde, womit er dann den MERGED-Hunk noch einmal erzeugen muss. 3.3 Hunkzusammenlegung: Da das von CLink ezeugte Programm möglichst klein sein soll, führt CLink massives Zusammenlegen von Hunks durch. 3.3.1 Speicherklassen: Zum Zusammenlegen bestimmt CLink für jeden Hunk eine Signatur In diese Signatur gehen ein: Der Hunktyp (Code, Data oder Bss) Die Speicherklasse (Publik, Chip oder Fast) Addressierungsweise (Near oder Far) Selbstverständlich kann man auch Hunks nutzen, die schon mit dem Chip- oder Fastbit gekennzeichent sind. in diesem Fall ist die Priorität folgende: CHIP (maximum) FAST PUBLIC (minimum, Speichertypus egal) Das Setzen des Fast-bits ist nicht ganz die feine Art, da es die Existenz von FastRAM vorraussetzt. Wenn möglich sollte man CHIP-Daten als Far deklarieren. Assemblerprogrammierer sollten sie nur mit 32-Bit addresieren. Somit kann CLink solche Daten in einen CHIP_DATA Hunk zusammenfassen. Diese Daten stören dann einen Smalldata-Hunk nicht mehr, er kann im Expansionsram liegen. Schon ein einziger 16-Bit Zugriff mittels xx(ax) auf ein Dataelement, das CHIP ist, führt dazu, daß der Neardata-Hunk im Chipram landet. 3.3.2 Reihenfolgen: CLink legt alle Hunks einer Signatur zusammen, wobei man mit Optionen wie SMALLCODE oder MAXDATA noch Einfluß nehmen kann. Man sollte sich nicht darauf verlassen, daß Hunks dieselbe Reihenfolge aufweisen wie im Objectcode, da CLink Hunks umsortieren kann und dies auch tut. Der Linker schreibt zuerst alle Codesektionen, anschließend die Daten und zum Schluß die BSS-Sektionen. Die Reihenfolge, in der CLink ihre Parameter verarbeitet, ist ebenfalls wichtig. CLink führt erst einen Pass über die Kommandozeile aus, um Optionen auszufiltern. Wenn in der Kommandozeile eine FROM- Datei angegeben wird, wird diese sofort geladen. Anschließend wird versucht, alles was keine Option war, zu laden. Wurde eine Datei über WITH angegeben, wird sie geöffnet und geparst, wenn sie an der Reihe ist. Wenn diese WITH-Datei nun ein FROM-Statement enthält, wird dieses nicht mehr beachtet, die angegebene Datei wird jetzt geladen. 3.3.3 NearCode / NearData: CLink unterstützt die Programmierung mit NearCode, wobei die Zugriffe auf Routinen mittels pc- relativen Addressierungen genutzt werden, um sowohl Laufzeit als auch Programmgröße einzusparen. NearData besteht aus einem Hunk, der alle vorinitialisierten Daten eines Programmes sowie gleichzeitig die uninitialisierten Daten (BSS) enthält. Auf diesen Hunk wird nun mittels relativer Addressierung über ein Basisregister zugegriffen. Auch diese Zugriffe haben gegenüber den 32-Bit absoluten Zugriffen den Vorteil, sowohl schneller als auch kürzer zu sein. Sollte der NearCode-Hunk größer als 32 KByte werden, fügt CLink zwischen einzelnen Hunks Sprungketten ein, um Aufrufe mit mehr als 32 KByte Addressdistanz möglich zu machen. Man sollte sich also vor globalen Daten im Code-bereich hüten, da es für einen Linker keine Möglichkeit gibt festzustellen, ob mit Daten oder Programmcode gearbeitet wird. Er wird an solchen Stellen einen Zwischensprung einfügen, der, wenn man eine Datenreferenz haben wollte, zu schwer zu findenden Fehlern führen wird. 4. Warnungen/Fehlermeldungen: Ich habe mich bemüht, den Linker mit möglichst aufschlussreichen Fehlermeldungen zu versehen. Diese Liste enthält alle Fehler/Warnungen, die man als Benutzer sehen dürfte. "Warnung : _InitModules nicht benutzt, aber nicht leer" Die von CLink assemblierte _InitModules-Routine wird nicht benutzt, obwohl sie nicht leer ist. Die Initialisierungen werden nicht ausgeführt. "Warnung : _CleanupModules nicht benutzt, aber nicht leer" Die von CLink assemblierte _CleanupModules-Routine wird nicht benutzt, obwohl sie nicht leer ist. Die ev. nötigen Freigaben von Resourcen werden nicht ausgeführt. "Warnung : FROM in WITHdateien. Reihenfolge nicht garantiert" Sie benutzen die FROM-Option in einer WITH-datei. CLink lädt dort jedoch alle Objectcodes in der Reihenfolge, in der sie dort aufgeführt werden. "Warnung : Erneute Definition von '%s' in Datei '%s'" Diese Warnung kann erst ausgegeben werden, wenn die Option VERBOSE gesetzt wurde. Sie besagt, daß Sie zwei Symbole mit gleichem Namen verwenden wollen. CLink findet jedoch nicht immer das Symbol, das Sie wollen. Siehe ->Arbeitsweise . "Warnung: Constructor '%s' findet Symbol '%s' nicht" Eine _INIT_x_ oder _EXIT_x_ Routine findet ein Symbol nicht. "Warnung : 32 Bit Referenz für %s" Wird ausgegeben, wenn die Option WARNREL angegeben wurde. CLink hat eine 32-Bit Referenz zu dem angegebenen Namen gefunden. "Warnung : 32 Bit Reloc nach Data" "Warnung : 32 Bit Reloc nach BSS" Wird ausgegeben, wenn die Option WARNREL angegeben wurde. CLink hat eine 32-Bit Relocation zu dem angegebenen Hunk gefunden. "Warnung : Mehr als 32 KByte Merged %s" (Code/Data/BSS) Die in %s angesammelte Menge wird zu groß für den 16-Bit Zugriff auf alle Elemente. Diese Warnung ist jedoch unkritisch, wenn CLink keine Fehler meldet. Nun kommen die Fehlermeldungen. Sie sind nicht extra als solche gekennzeichnet. "Unbekannter Typ" Die Objectdatei enthält einen Reloc- oder Referenztyp, mit dem CLink nichts anfangen kann. "16 Bit Datenrelozierung zu groß" Eine 16-Bit Relozierung wird nach dem Anpassen der Relokationstabellen zu groß. Dies ist möglich, wenn das Programm mehr als 32 KByte an MERGED-Data/BSS ansammelt. Mit der Option BASE $8000 kann man ev. Abhilfe schaffen. "8 Bit Datenrelozierung zu groß" Eine 8-Bit Relozierung wird zu groß, um in 8-Bit zu passen. "16 Bit Coderelozierung zu groß" Eine PC-relative Relozierung wird zu groß für ein 16 Bit Offset. Dies sollte eigentlich nicht passieren, da CLink in solchen Fällen einen 'Zwischensprung' selbständig einfügt. Diese Meldung wird jedoch ausgegeben, wenn CLink bei dem Versuch die Sprungketten einzusetzen, einen Hunk größer als 32 KByte überspringen musste, was mit einem PC-relativen Sprung nicht geht. Eine weitere Ursache können 16-Bit Referenzen von Data nach Code sein, da hier keine Ketten gebildet werden. "8 Bit Coderelozierung zu groß" Eine 8-Bit Relozierung zu einem Code-Hunk wird zu groß für ein Byte. "Offset zu Datenobject '%s' nicht 16 Bit" Die Referenz zu dem Object %s ist länger als ein 16-Bit Offset erlaubt. Abhilfe siehe 16-Bit Reloc ... "Offset zu Codeobject '%s' nicht 16 Bit" Die Referenz zu einem Code-label ist zu groß für ein 16-Bit Offset. Sollte eigentlich wegen der bei '16 Bit Coderelozierung ...' genannten Gründe nicht passieren. "Offset zu Datenobject '%s' nicht 8 Bit" "Offset zu Codeobject '%s' nicht 8 Bit" Die Refenezen werden zu groß für ein 8-Bit Offset. "Kann %s nicht öffnen (zum Lesen)" CLink kann eine Objectdatei nicht unter dem angegeben Namen finden. "Falsches Nummerformat" Der Nummerparser kann mit der Zeichendarstellung nichts anfangen. Erlaubt sind Oktalzahlen ( 0543 ) mit der Basis 8 ; Dezimalzahlen ( 256 ) mit Basis 10 und Hexadezimale Zahlen ( $AeF9 , 0xFF3E) . Ein '-' macht die Zahl negativ ( - 300 ). Leerzeichen sind vor der Zahl erlaubt, nicht jedoch in der Zahl. Zwei '-' haben keinen Einfluß. ( -- 42 = 42, ---3 = -3 ) Alle hier nicht aufgeführten Fehler sind interne Fehler. 5. Undokumentierte Verhaltensweisen (Bugs) : Motorische Störungen der Programmierer infolge von ERROR_NICHT_GENUG_KAFFEE, da die bei ALink eingeführte 'Amiga Gedenk Minute', meist zum DoIO(Kaffeetasse) benutzt, ersatzlos gestrichen wurde. Andere bisher unbekannt. 6. Danksagungen: Ein im Normalfall viel zu wenig beachtetes Gebiet. Es arbeiten immer mehr Personen, die das gar nicht wissen, an einem Projekt mit. Ich möchte diese Stelle nutzen, um einigen von ihnen meinen Dank auszusprechen: Jan-Claas Dirks Jan M. Anton Jörg "Sedl" Fred Fish ><> : Ohne ihn wäre diese Maschine bei weitem nicht das, was sie ist !