
\section{Der Linker ({\tt m2l})}

\label{refLink}
Der Linker {\bf m2l} bindet Objektdateien zu einem ausf"uhrbaren Programm.
Als Hauptmodul wird dasjenige Modul verwendet, dessen Objektdatei
als Argument "ubergeben wird. Die Objektdateien aller ben"otigten
(importierten) Moduln werden dem Pfad folgend gesucht und eingelesen.
Sind alle Referenzen aufgel"ost, wird eine neue Datei erzeugt.
Diese Datei enth"alt ein ausf"uhrbares Programm und tr"agt den Namen
des Hauptmoduls ohne Erweiterung. W"ahrend des Linkvorgangs werden
die Namen der gelesenen Dateien ausgegeben.

\begin{figure}[bht]
\begin{center}
\unitlength1cm
\begin{picture}(8,3)
\put(4,0.7){\oval(2.0,1.4)} \put(3,0){\makebox(2.0,1.4){\tt m2l}}
\put(2,0.7){\vector(1,0){1}}
  \put(2.6,1){\makebox(0,0)[rb]{\cmsltt prog\/\tt.ob\cmsltt n}}
\put(5,0.7){\vector(1,0){1}}
  \put(5.4,1){\makebox(0,0)[lb]{\cmsltt prog}}
\put(4,1.5){\line(2,1){0.6}}
  \put(4.6,1.8){\line(-1,0){0.3}}
  \put(4.3,1.8){\line(0,1){0.4}}
\put(4,1.5){\line(-2,1){0.6}}
  \put(3.4,1.8){\line(1,0){0.3}}
  \put(3.7,1.8){\line(0,1){0.4}}
\put(3.7,2.2){\line(1,0){0.6}}
\put(4,2.4){\makebox(0,0)[b]{{\tt ob\cmsltt x\/}-Dateien}}
\end{picture}
\caption{Umgebung f\protect"ur den Linker}
\end{center}
\end{figure}

\begin{note}
Der Linker kann nur Programm-Moduln linken, aus einem
Implementationsmodul kann --- im Gegensatz zu fr"uheren Versionen ---
{\em kein\/} lauf"|f"ahiges
Programm erstellt werden!
\end{note}

\subsection{Aufruf und Bedienung}

\begin{quote}\tt
m2l \{+-012348acdimpqrx -g{\cmsltt{}Directory} -l{\cmsltt{}LibFile\/} \\
~~-s{\cmsltt{}Stack} -t{\cmsltt{}TargetFile} ? ??\} \{{\cmsltt{}Objektfile\/}\}
\end{quote}

\begin{example}
Ein Beispiel:
\begin{quote}\tt
m2l -i+rcd Modul1 -rlHilfsdatei Modul2
\end{quote}
\end{example}
Diese Eingabe bewirkt, dass {\tt Modul1} und {\tt Modul2} ohne Ikone
und als SmallCode sowie Smalldata gelinkt werden. {\tt Modul1} wird
residentf"ahig, f"ur das Linken von {\tt Modul2} wird
zus"atzlich die Datei "`Hilfsdatei"' geladen, da {\tt Modul2} bestimmte
Objekte hieraus ben"otigt. {\tt Modul2} wird
{\em nicht\/} re\-si\-dent\-f"a\-hig.


Falls beim Aufruf keine Objektdatei angegeben wird oder sp"ater ein
Fehler auftritt, geht der Linker in den interaktiven Modus,
in dem die Kommandos und Optionen direkt eingegeben werden k"onnen.

Zun"achst liest {\tt m2l} beim Start die Datei "`{\tt ENV:m2l}"', die
als Text aus einer einzigen Zeile besteht und in der
die Standard-Optionen angegeben werden k"onnen. Danach werden die
Optionen der Kommandozeile ausgewertet und die angegebenen Dateien
gelinkt.

Im interaktiven Modus k"onnen durch einfache Eingabe von \keyret{} der
Linker beendet, einzelne Optionen mit "`{\tt -}"' gel"oscht oder
mit "`{\tt +}"' gesetzt, oder ein neuer Objektdateiname zum erneuten
Starten des Linkers eingegeben werden.

Daraufhin wird je nach Option ein bestimmtes Laufzeitmodul {\tt Arts}
geladen, danach das
Hauptmodul und dann die weiteren ben"otigten Moduln. Tritt hierbei
kein Fehler auf, gibt der Linker am Schluss eine kurze Statistik
"uber Programm-Aufbau und -gr"osse. Danach folgt eine Meldung,
ob das fertige
Programm reentrant und damit residentf"ahig ist. Falls es
re\-si\-dent\-f"a\-hig ist,
wird f"ur die erzeugte Datei auch das "'pure"'-Bit gesetzt, sodass
es einfach mit "`{\tt RESIDENT \cmsltt Name}"' resident geladen werden
kann. Schliesslich folgt die Angabe, welcher Prozessor mindestens vorhanden
sein muss, um dieses Programm laufen zu lassen.

\subsection{Optionen}

Die einzelnen Optionen lassen sich mit "`{\tt -}"' l"oschen
und mit "`{\tt +}"'
setzen (siehe \ref{refBedien}, Seite \pageref{refBedien}).
Gross- und Kleinschreibung spielen hier keine Rolle.
\begin{description}
\item[a] (AskModule) Durch die Option "`{\tt +a}"' gibt der Linker
dem Benutzer die M"oglichkeit, vor dem Einlesen jeder Datei 
alternative Dateinamen anzugeben.
Hierbei zeigt er in eckigen Klammern den vorgegebenen Dateinamen an. Wenn
Sie einfach \keyret{} dr"ucken, wird die angezeigte Datei eingelesen,
andernfalls die von Ihnen eingegebene. Dieser Vorgang wird solange
wiederholt, bis die Datei erfolgreich eingelesen werden konnte.
Geben Sie einfach nur ein Minuszeichen ein, wird {\em f"ur diesen
Linkvorgang\/} die Option ausgeschaltet und die restlichen, noch
zu lesenden Dateien, ohne weitere Nachfrage geladen.

Diese Option ist sehr n"utzlich im Zusammenhang mit der bedingten
Compilation. Falls beispielsweise ein Quelltext mit Hilfe der Compiler-Option
\hbox{"`{\tt +oDemo}"'} als Demoversion kompiliert und dabei die
{\tt t}-Option des Compilers benutzt wurde, beispielsweise also mit
\begin{quote}
\tt m2c -oDemo -t\cmsltt Name\/\tt Demo
\end{quote}
kann man den Linker zwingen, diese Demoversion statt der
normalen zu laden.

\item[i] F"ur das fertige Programm wird eine Workbench-Ikone erzeugt.
Die Option "`{\tt -i}"' unterdr"uckt dies. Wurde der Linker
von der Workbench gestartet,
ist die Ikonen-Erzeugung standardm"assig eingeschaltet,
beim Start vom CLI ist sie ausgeschaltet.
\item[c] steht f"ur "'CODE"'. "`{\tt +c}"' bewirkt, dass die einzelnen
CODE-Hunks soweit wie m"oglich in maximal 32\,kByte grossen Hunks
zusammengelegt werden, was zu einem erheblich k"urzeren Programm
f"uhren kann. Standardeinstellung f"ur diese Option ist "`{\tt +}"'.

\item[d] steht f"ur "'DATA"'. Nach "`{\tt +d}"' legt der Linker alle
DATA- und BSS-Hunks gleichen Typs (CHIP, FAST,"`normal"') zusammen.
 Standardeinstellung f"ur diese Option ist "`{\tt +}"'. Hierdurch wird
 das fertige Programm etwas kleiner. In einem residenten Programm
 d"urfen keine DATA- oder BSS-Hunks vorhanden sein, einzig MERGDATA-
 und MERGBSS-Hunks sind erlaubt (\near-Modell); diese werden immer unabh"angig
 von der Option {\tt d} zusammengelegt.

 Falls jedoch {\em sehr grosse\/}
 Hunks erzeugt werden, kann ein Programm eventuell
 bei stark fragmentiertem Speicher nicht geladen werden, da
 kein gen"ugend grosser zusammenh"angender Speicherbereich zur
 Verf"ugung steht. In diesem Fall sollte man vorsichtshalber
 die Option mit "`{\tt -d}"' ausschalten.

\item[p] Bei Aktivierung dieser Option wird
eine Map-Datei generiert, aus
der der Aufbau des Programms hervorgeht. Ohne Angabe wird
{\em keine\/} Map-Datei generiert.

Meldet das Programm "`{\tt enforcer}"'
Fehler im getesteten Programms, 
wird deren Position mit Hunk und Offset angegeben.
Mit dieser Information kann man
jedoch wenig anfangen, wenn man den genauen Aufbau seines Programms
nicht kennt.

Mit Hilfe der Map-Datei und des Dekoders kann man nun die Fehlerposition
relativ genau lokalisieren, indem man den entsprechenden Hunk und Offset
aufsucht und dann mit {\tt m2decobj} die exakte Position sucht.
Zur weiteren Vereinfachung der Fehlersuche kann
man auch mit der Option "`{\tt +x}"' linken,
dann werden die Moduln komplett gelinkt und keine Prozeduren wegoptimiert.
Dadurch erspart man sich etwas Rechnerei.

In der Map-Datei befindet sich zun"achst eine Beschreibung der Hunks
mit Gr"osse und Typ. Direkt daran schliesst sich die Symboltabelle des
Linkers an. Diese ist jedoch nach unbrauchbaren Kriterien sortiert.
Der Dos-Befehl {\tt sort} schafft jedoch leicht Abhilfe. Die Zeilen sind
so aufgebaut, dass die Struktur der Datei beim Sortieren erhalten
bleibt (erst Hunks, dann die Symbole) und danach die Symbole in
aufsteigender Hunk-, Offset-Reihenfolge stehen. Wegen des seltenen
Gebrauchs wurde davon abgesehen, eine eigene Sortierroutine in den
Linker zu integrieren, um ihn nicht unn"otig zu vergr"ossern.

\begin{example}
Ein Beispiel f"ur eine sortierte Datei:
\begin{alltt}
  Hunk  0:  $000005AC Byte,  Typ: CODE
  Hunk  1:  $0000000C Byte,  Typ: CHIPDATA
  Hunk  2:  $0000000C Byte,  Typ: BSS
  Hunk  3:  $000000A8 Byte,  Typ: MERGBSS
Hunk:  0  Offset: $000002D6  (rel)   Arts$19
Hunk:  0  Offset: $0000031C  (rel)   Arts$22
Hunk:  0  Offset: $0000048C  (rel)   Arts$16
Hunk:  0  Offset: $00000560  (rel)   Arts_Exit
Hunk:  0  Offset: $00000568  (rel)   Arts_Terminate
Hunk:  0  Offset: $00000570  (rel)   Arts_12C1028006AB
Hunk:  0  Offset: $00000572  (rel)   Arts_END
Hunk:  0  Offset: $00000574  (rel)   __main
Hunk:  0  Offset: $0000059E  (rel)   __mainEnd
Hunk:  0  Offset: $000005A4  (rel)   MapTest_BY
Hunk:  1  Offset: $00000000  (rel)   MapTest_IN
Hunk:  2  Offset: $00000000  (rel)   MapTest_VAR
Hunk:  3  Offset: $00000000  (rel)   Arts_VAR
Hunk:---  Wert:   $00000000  (drel)  _LinkerDB
Hunk:---  Wert:   $00000000  (drel)  __BSSBAS
Hunk:---  Wert:   $0000002A  (abs)   __BSSLEN
\end{alltt}
\end{example}

\item[{l\cmsltt LibFile}] Hier ist "`{\tt +}"' oder "`{\tt -}"' ohne Wirkung.
Durch diese
Option wird dem Linker mitgeteilt, in welchen Dateien  undefinierte
Symbole zu finden sind. Das Argument {\cmsltt LibFile}
muss den kompletten Pfad enthalten.
Der Buchstabe "`{\tt l}"' kann sich direkt an die anderen
Optionen anschliessen; falls
jedoch mehrere Dateien geladen werden sollen, muss jeweils eine
eigene Option hierf"ur angegeben werden, da alle Zeichen nach dem
"`{\tt l}"' als Teil des Dateinamens eingelesen werden.
Die Angabe einer oder mehreren zus"atzlichen Dateien mit Symboldefinitionen
gilt immer nur f"ur die n"achste
zu erstellende Programmdatei. Danach oder auch bei Misserfolg
werden diese Angaben vergessen.
\begin{example}
 Ein Beispiel, in dem die zwei Dateien {\tt Menu.o} und
  {\tt demos:Requester.o} explizit angegeben werden sollen;
  zus"atzlich wird hierbei die Option m gesetzt und r gel"oscht:
\begin{quote}\tt
 m2l +m-rlMenu.o -ldemos:Requester.o MyDemo
\end{quote}
\end{example}

\item[{t\cmsltt TargetFile}] bietet die M"oglichkeit, der erzeugten Datei
einen anderen Namen zu geben. Diese Option gilt (wie "`{\tt l}"') nur
f"ur den n"achsten Linkvorgang. Direkt an den Buchstaben "`{\tt t}"' schliesst
sich ein Dateiname einschliesslich des Pfads an. Standardeinstellung ist der
Modulname.
\begin{example}
Der Compiler f"ur die 68020-CPU wird beispielsweise so erzeugt:
\begin{verbatim}
 m2l -2s20000 -tm2c68020 m2c
\end{verbatim}
\end{example}

\item[{s\cmsltt MinStack}] Die Option "`{\tt s}"' erlaubt die Angabe einer
Dezimalzahl, die nur f"ur das Linken {\em residenter\/} Programme eine Bedeutung
hat. Sie bestimmt die Gr"osse des Stacks, die das Programm mindestens
ben"otigt. Falls der Stack zur Laufzeit kleiner als dieser angegebene
Wert ist, wird der Speicher vom Laufzeitsystem Arts alloziert.
Vorgabewert ist 4000 Byte. Die ge"anderte Einstellung gilt f"ur alle
weiteren Linkvorg"ange.
\begin{example}
 Ein Beispiel, in dem der Compiler mit einem Minimalstack von
 20000 Byte gelinkt wird:
\begin{quote}\tt
 m2l -s20000 m2c
\end{quote}
\end{example}

\item[{g\cmsltt Directory}] wechselt in das angegebene Verzeichnis. Siehe
hierzu Abschnitt \ref{refBedien} auf Seite \pageref{refBedien}.
Die Option {\tt -gm2:Tools} setzt
"`{\tt m2:Tools}"' als aktuelles Verzeichnis,
{\tt -g} kehrt zur"uck ins Startverzeichnis.

\item[012348] Auch hierbei sind "`{\tt +}"' oder "`{\tt -}"' wirkungslos.
Durch die Ziffer --- nur eine, d.h.\ die zuletzt angegebene ist g"ultig ---
wird dem
Linker mitgeteilt, welche Art Objektdateien einzubinden sind, um den
bestm"oglichen Code f"ur den Zielprozessor zu erzeugen. Gibt man
etwa die Option \hbox{"`{\tt -8}"'}, so verwendet der Linker m"oglichst
"`{\tt .ob8}"'-Files, damit das Programm mit einer 68881-FPU m"oglichst
ef"|fizient l"auft. Standardeinstellung ist "`{\tt 0}"'.

\item[q] Durch "`{\tt -q}"' werden alle Meldungen des Linkers unterdr"uckt.
Ausserdem wird im Fehlerfall nicht in den interaktiven Modus
verzweigt, damit der Linker auch in Batch-Dateien aufgerufen
werden kann.

\item[r] steht f"ur "'Resident"' Die Angabe "`{\tt +r}"' hat zur Folge,
 dass statt {\tt Arts.obj} (oder {\tt Arts.ob1} usw.)
das File {\tt RArts.obj} geladen wird, was unter bestimmten,
im Abschnitt \ref{refResident} beschriebenen
Bedingungen zu einem residentf"ahigen Programm f"uhrt.
Wenn diese Bedingungen nicht erf"ullt sind, wird das Programm zwar
gelinkt, aber als nicht-residentf"ahig deklariert. Man sollte
die Abschlussmeldungen des Linkers also immer genau lesen!
Ohne spezielle Angaben wird die nicht residentf"ahige Version
des Laufzeitsystems dazugebunden.

\item[m] bestimmt zusammen mit der Option "`{\tt r}"' das zu ladende
spezielle Arts. Hier steht "`{\tt m}"' f"ur "`Minimal"'-Arts, das gegen"uber dem
normalen Arts k"urzer, aber auch gef"ahrlicher ist, da Laufzeitfehler
nicht durch Requester abgefangen werden, sondern zu "`Guru Meditationen"'
f"uhren.\footnote{Es wird kein Traphandler installiert} Standardeinstellung
ist "`{\tt -}"'.

\item[x] ist vonn"oten, um Debugger-f"ahige Programme zu linken.
Mit der Option "`{\tt +x}"' --- der Vorgabe --- werden Informationen f"ur den
Debugger erzeugt und entsprechend der Option "`{\tt r}"'
das Laufzeitsystem {\tt DArts.obj} oder {\tt DRArts.obj}
eingebunden. Wird eines dieser beiden Laufzeitsysteme 
verlangt, ist die Option "`{\tt +m}"' {\em ohne Wirkung\/}!
Das Debugger-f"ahige Laufzeitsystem braucht n"amlich die gesamte
Unterst"utzung. Ausserdem ist zu beachten, dass
mit dieser Option {\em alle\/} Hunks --- also auch unbenutzte ---
mit eingebunden werden. Die Optimierung
ist auf Seite \pageref{refSpecLink} beschrieben. Debugbare Programme sind also
immer gr"osser als nicht debugf"ahige.

Die Optionen "`{\tt r}"', "`{\tt m}"' und "`{\tt x}"'
bestimmen gem"ass Tabelle \ref{ArtsNames} gemeinsam, welches
Laufzeitsystem eingebunden wird:
\begin{table}
\begin{center}
\begin{tabular}{|c|c|c|c|} \hline
Option R & Option M & Option X & zu ladendes Arts \\ \hline
-- & -- & -- & Arts \\
-- & -- & + & DArts \\
-- & + & -- & MArts \\
-- & + & + & DArts\footnotemark \\
+ & -- & -- & RArts \\
+ & -- & + & DRArts \\
+ & + & -- & MRArts \\
+ & + & + & DRArts\footnotemark \\ \hline
\end{tabular}
\end{center}
\caption{\label{ArtsNames}Vom Linker zu verwendendes Laufzeitsystem}
\end{table}
\addtocounter{footnote}{-1}
\footnotetext{Hier wird die Option "`{\tt +m}"' ignoriert,
  da bereits '`{\tt +x}"' gesetzt ist.}
\stepcounter{footnote} \footnotetext{Auch hier ist der
  Wert der Option "`{\tt m}"' nicht von Bedeutung}

\item[??] Die Eingabe zweier Fragezeichen zeigt die Version des Linkers
und den aktuellen Zustand aller Optionen.
\end{description}

In der Tabelle \ref{refLinkOpts} sind alle Optionen
des Linkers in Kurzform dargestellt. Zu beachten ist
zus"atzlich die oben beschriebene Einschr"ankung
bez"uglich der Option "`{\tt m}"' in Zusammenhang mit der
Option "`{\tt x}"'.

\begin{table}[tbp]
\begin{center}
\begin{tabular}{|c|c|l|} \hline
Option & Vorgabe & Wirkung \\ \hline \hline
  ? &     & Version und Syntax \\ \hline
  ?? &    & Version, Syntax und Status \\ \hline
  a & -- & Abfrage der Dateinamen \\ \hline
  c & +  & SmallCode \\ \hline
  d & +  & SmallData \\ \hline
  i & WB:+, CLI:-- & Ikonen-Erzeugung \\ \hline
  m & -- & Minimal-Arts \\ \hline
  p & - & Erzeugung einer Map-Datei \\ \hline
  q & + & Ausgabe von Meldungen \\ \hline
  r & -- & reentrant \\ \hline
  x & + & debugInfo \\ \hline \hline
  l &    & Lade Extradateien \\ \hline
  s & 4000 & Minimale Stackgr"osse \\ \hline
  t & Modulname & Name der Zieldatei \\ \hline
  g &     & Directory-Wechsel \\ \hline
 012348 & 0 & Typ der Objektdateien (.ob1 \ldots)\\ \hline
\end{tabular}
\caption{\label{refLinkOpts} Optionen des Linkers}
\end{center}
\end{table}

\subsection{Suchverhalten des Linkers}

Je nach eingestellter Option l"adt der Linker zun"achst das entsprechende
Arts (Laufzeitsystem)
und danach das Hauptmodul. Daraufhin durchsucht er die Symboltabelle
auf undefinierte Symbole, extrahiert den Modulnamen und versucht,
die zugeh"orige Objektdatei zu laden. Dieser Zyklus wiederholt sich solange,
bis alle Symbolreferenzen aufgel"ost sind. Da alle vom Compiler erzeugten
Symbole in der Form "`{\bf modulname\_name}"' vorliegen, l"asst sich der
Modulname einfach bilden. Sollte der Symbolname jedoch anders
aussehen, so sucht der Linker in den per Option "`{\tt l}"' angegebenen
Zusatzdateien
nach den Symbolen. Erst wenn die Suche erfolglos bleibt,
kommt eine Fehlermeldung.

Falls das Programm f"ur einen dem 68000 "uberlegenen Prozessor gelinkt
werden soll, sucht der Linker zuerst nach dem
Objektfile mit der entsprechenden Endung (z.B.\ "`{\tt .ob8}"'). Falls er
die Datei nicht findet, sucht er in der Reihenfolge
\begin{center}
\begin{tabular}{cccccc}
{\tt ob8} & {\tt ob4} & {\tt ob3} & {\tt ob2} & {\tt ob1} &{\tt obj}
\end{tabular}
\end{center}

Hierbei schraubt er seine Anspr"uche herab, gibt ein
"`\verb|<|"'--Zeichen aus und sucht die "`n"achst schw"achere"'
Objektdatei.
Erst wenn er keine "`{\tt obj}"'-Datei findet, kommt eine Fehlermeldung.

\begin{note}
Da jeweils das aktuelle Projekt, danach den Eintr"agen
in der Datei "`{\tt path}"' entsprechend
und danach denen von "`{\tt m2:path}"' entsprechend gesucht wird, kann dies
unter Umst"anden  sehr
langwierig werden; insbesondere wenn Pfad-Listen
lang und weitverzweigt sind.
Man sollte sich dann f"ur den gew"unschten
Prozessor die richtigen Objektdateien compilieren, auch wenn einige
Moduln etwa auf einem 68020--Prozessor gar keinen Code sparen. Danach
d"urfte jedoch das Linken einiges schneller gehen!
\end{note}

\subsection{Meldungen des Linkers}

Der Linker erzeugt einige Fehlermeldungen, die meist selbsterkl"arend
sind:
\begin{itemize}
\item {\cmsltt Dateiname\/\tt: nicht gefunden}

Eine Objektdatei konnte nicht gefunden werden. Der Linker bricht den
 Linkvorgang ab und geht in den interaktiven Modus. Ursache kann
 ein unvollst"andiger Pfad (siehe \ref{project}, Projekt-Konzept) oder
 ein Tippfehler
 bei der Eingabe des Modulnamens sein.

\item {\tt Symbol doppelt definiert: \verb|"|\cmsltt Symbolname\/\verb|"|}

Dieser Fehler tritt vor allem beim Einbinden \mtwo-fremder Objektdateien
auf. Ein Symbol existiert zweimal, der Linker kann nicht weiterarbeiten.
M"oglich ist auch die Fehlbedienung im Zusammenhang mit der
Option "`{\tt +a}"'; dann kann passieren, dass das gleiche
Modul mehrmals geladen wird.

\item {\tt Symbol \verb|"|\cmsltt name\/\tt\verb|"| nicht zu finden!}

Der Linker hat in keiner der geladenen Dateien das Symbol gefunden.
Wahrscheinlich fehlt die Angabe einer Zusatz-Datei mit der Option {\tt l}.

Sollte jedoch das Symbol die Form "`{\tt name\_\cmsltt xxxxxxxxxxxxxx\/}"'
haben
(also ein Modulname, durch einen Unterstrich von
einer 12stelligen Hexadezimalzahl getrennt), so haben Sie die
falsche Version eines Moduls geladen. H"ochstwahrscheinlich muss das
zuletzt eingeladene Modul neu kompiliert werden. In diesem
Fall bietet sich generell der Einsatz von {\tt M2Make}
(Abschnitt \ref{m2make}) an.


Die Meldung "`\verb|"__main" nicht zu finden|"' zeigt an,
dass Sie versucht haben,
ein Implementationsmodul zu binden. Es d"urfen nur Programm-Moduln
gelinkt werden; nur in diesen wird das Symbol "`{\tt \_\_main}"' definiert!

\item {\tt Dies Programm KANN NICHT reentrant gelinkt werden!}

Sie haben durch "`{\tt +r}"' versucht, ein Programm residentf"ahig zu linken.
Es existiert aber mehr als eine Referenz auf das spezielle Symbol
"`\_LinkerDB"'. Dadurch ist das Programm auf keinen Fall lauf"|f"ahig
und wird gel"oscht. Derartige Referenzen werden durch die
Compiler-Option "`{\tt LoadA4:=TRUE}"' erzeugt. Sie sollten entweder
auf die Re\-si\-dent\-f"ahig\-keit verzichten oder das Programm "andern.

Falls DATA- oder BSS-Hunks vorhanden sind, ist das Programm
ebenfalls nicht reentrant, es ist jedoch lauf"|f"ahig, und
wird nicht gel"oscht. Dies tritt beispielsweise immer bei
Benutzung des Profilers auf.

\end{itemize}

Nach erfolgreichem Linkvorgang gibt {\tt m2l}
einige statistische Informationen
"uber das erzeugte Programm. Zum Beispiel:
\begin{verbatim}
 +Demo 3776 Bytes  2 Hunks 0 ALVs erzeugt.
 CODE: 3672  MERGBSS: 648
 Programm ist reentrant. Pure bit gesetzt.
\end{verbatim}
\noindent
oder
\begin{alltt}
 +Demo2 3624 Bytes  3 Hunks 0 ALVs erzeugt.
 CODE: 3520  CHIPBSS: 8 MERGBSS: 648
 Das Programm ben"otigt mindestens eine 68020-CPU!
 Programm ist NICHT reentrant. Pure bit gel"oscht.
\end{alltt}

Zun"achst sehen wir den Namen der erzeugten Datei
und ihre L"ange in Byte. Daran
anschliessend die Anzahl der erzeugten Hunks und ALVs.%
\footnote{ALV: Automatic Link Vector; diese sind in
n"achsten Abschnitt, Seite \pageref{ALV}, beschrieben}

In der zweiten
Zeile werden die erzeugten Hunktypen und ihre jeweiligen Gr"ossen
aufgezeigt. Kommen dort nur CODE, CHIPCODE, MERGBSS und MERGDATA vor,
k"onnte
man das Programm wahrscheinlich reentrant linken;
einen Versuch ist es auf jeden Fall wert.

Falls eine Objektdatei mit der Endung "`{\tt .ob1}"' oder
h"oher eingebunden wurde,
gibt der Linker an, welche CPU oder FPU mindestens im System vorhanden sein
muss, um das Programm laufen zu lassen.

In der letzten Zeile schliesslich befindet sich die Angabe, ob das Programm
reentrant ist oder nicht. Diese Angabe ist aber nicht sicher!
Der Linker kann nur beschr"ankt feststellen, ob ein Programm
reentrant ist. Selbstmodifizierender Code kann  {\em nicht\/}
erkannt werden! Das Pure-Bit ist ein Attribut der Datei.
Ist es gesetzt, kann das
Programm mit dem Dos-Befehl "`{\tt RESIDENT \cmsltt datei}"'
resident geladen werden.

\subsection{Spezielles Linkverhalten}

\label{refSpecLink}
\subsubsection{Hochoptimierender Linker}

Wenn die Option {\tt x} gel"oscht ist, linkt
der Linker nur Hunks, auf die eine Referenz
vorhanden ist.
Dadurch optimiert er weit besser als andere
Linker, die erst auf Unit-Ebene ansetzen. Im fertigen
Programm wird nur noch vorhanden sein, was wirklich
ben"otigt wird. Man kann somit eine Prozedur aus einem
sehr grossen Modul importieren und benutzen, ohne Ballast
in Form von totem Code mitzuschleppen. Nur der Initialisierungs- und
{\tt CLOSE}-Code (siehe \ref{refClose}) des Moduls sowie diese
einzelne Prozedur werden dazugelinkt. Ebenfalls dazugelinkt
wird nat"urlich all das,
was diese drei Teile zus"atzlich ben"otigen.

\subsubsection{Kurze Spr\protect"unge}

Wie im Abschnitt \ref{refObject} auf Seite \pageref{refObject}
angeschnitten, werden {\em alle\/} Prozeduren mit einem 16Bit-Offset
angesprungen, auch wenn sie in fremden Moduln, g"anzlich
extern oder gar in CHIP-Hunks liegen. Dies spart eine Menge Code
und beschleunigt Programme. Nun wird jeder, der den Amiga
n"aher kennt, wissen, dass dies eigentlich unm"oglich ist!\footnote{Jeder, der
noch mehr weiss, wird aber auch wissen, dass {\em nichts\/} unm"oglich
ist.} \label{ALV}Der Linker bemerkt diesen Umstand selbstverst"andlich und
erzeugt bei Bedarf sogenannte \hbox{{\bf ALV}s} (automatic link vector). Falls
ein 16Bit-Sprung in einen anderen Hunk verweist, wird im eigenen
Hunk ein absoluter Sprung auf das Ziel erzeugt und alle Spr"unge
darauf umgeleitet.

\begin{example}
Ruft nun eine Prozedur die Funktion {\tt Arts.Mulu32} auf und Arts ist
sp"ater im fertigen Programm weiter als 32\,KByte "`entfernt"', wird
folgender Code erzeugt:
\begin{verbatim}
eigener Hunk:
        JSR   ALVArts_Mulu32(PC)
        ...
   ALVArts_Mulu32:
        JMP   Arts_Mulu32

anderer Hunk:
   Arts_Mulu32:
        ...
        RTS
\end{verbatim}
\end{example}

Hieraus wird auch ersichtlich, dass dies nur mit Spr"ungen auf "`normale"'
Prozeduren funktionieren kann. Der Prozessor springt pc-relativ auf
den ALV und von dort einfach weiter, was nur eine kurze Zeitverz"ogerung
mit sich bringt. Falls jedoch eine Prozedur nur
als "`Verpackung"' f"ur Daten dient und via "`{\tt ADR}"' angesprochen
wird, kann diese Umleitung nicht klappen! Der Linker wird es
aber nicht bemerken und brav seinen ALV generieren. Der Compiler
weiss nat"urlich um diesen Umstand und verwendet eine entsprechende
Adressierung.
Wichtig wird es allerdings bei {\tt ASSEMBLE}-Code. Es empfiehlt sich,
innerhalb eines {\tt ASSEMBLE}-Teils nur moduleigene Adressen relativ
zu adressieren, modulfremde jedoch absolut.

Das gleiche gilt auch f"ur Zeichenketten-Konstanten. Diese werden immer im
gleichen Hunk wie der Code des zugeh"origen Moduls untergebracht, k"onnen
folglich vom {\em eigenen\/} Modul pc-relativ, von fremden Moduln
hingegen nur absolut adressiert werden.

\begin{example}
Angenommen, man m"ochte nach obigen Beispiel das erste Wort der Prozedur
{\tt Arts.Mulu32} in ein Register laden, so wird man nur das erste Wort
des ALV-Sprunges (also eine {\tt JMP}-Instruktion) erreichen! In diesem
Fall muss von vornherein eine absolute Referenz erzeugt werden:
\begin{verbatim}
eigener Hunk:
        MOVE.W  Arts_Mulu32,D0
oder
        LEA     Arts_Mulu32,A0
        MOVE.W  (A0),D0
        ...
anderer Hunk:
   Arts_Mulu32:
        ...
        RTS
\end{verbatim}
\end{example}


Als zweite Lehre sollte man daraus ziehen, m"oglichst immer die Option
"`{\tt +c}"' anzugeben bzw. die Standardeinstellung zu belassen,
woraufhin soviel Code wie m"oglich in einen
einzelnen Hunk gepackt, und die Erzeugung von ALVs unn"otig wird.
Da die meisten Programme k"urzer als 32\,kByte sind, wird hierdurch
ein sehr kompakter und schneller Code erreicht.
CHIP-Code und "`normaler"' Code k"onnen allerdings niemals in demselben
Hunk untergebracht werden, wodurch ALVs erzwungen werden.
 Man sollte CHIP-Code also vermeiden.

\subsection{Einbindung von C- und Assembler-Code}
Referenzen auf M2Amiga-fremde Symbole k"onnen auf drei Arten erzeugt
werden: durch {\tt ASSEMBLE( XREF\ldots)} sowie durch die Deklaration
externer Prozeduren oder Variablen (\ref{refExtProc} und \ref{refExtVars}).
\begin{example}
Beipiel:
\begin{verbatim}
  VAR MyMenu [ < "MyMenu_Strip" ]: Menu;
  ASSEMBLE(
     XREF PointerImage
     LEA  MyMenu(A4),A0
     LEA  PointerImage,A1
  END);
\end{verbatim}
\end{example}

Der Unterstrich in den Symbolen bietet die freie Namenswahl. Der Linker kann
nur in zwei F"allen wissen, in welchen Dateien er die Symbole suchen
soll: bei der Option "`{\tt -l\cmsltt Name\/}"' oder wenn der Name in der Mitte einen
Unterstrich besitzt.

Im zweiten Fall muss die Datei allerdings den Namen des Teils vor
dem ersten Unterstrich und die Endung "`{\tt .obj}"' (oder
"`{\tt .ob1}"' usw.) haben und im Projekt oder Pfad richtig plaziert sein.
Dies hat den enormen Vorteil, dass beim Linken keine zus"atzlichen Namen
angegeben werden m"ussen, und dass sogar mehrere Versionen f"ur
verschiedene Prozessoren existieren k"onnen!
In obigem Beispiel wird das Symbol "`{\tt MyMenu\_Strip}"' automatisch
in der Datei {\tt MyMenu.obj} gesucht. Da "`{\tt PointerImage}"' keinen
Unterstrich enth"alt, muss die zugeh"orige Datei per Option
"`{\tt-l\cmsltt File}"'
angegeben
werden.

\label{refParaC}
Beim Einbinden von C-Prozeduren ist zu bedenken, dass
diese ihre Parameter im Gegensatz zu \mtwo{} in umgekehrter
Reihenfolge auf dem Stack erwarten, keine
offenen Feldparameter kennen und ihre Parameter nicht deallozieren.
\mtwo{} legt die Parameter von links nach rechts auf dem Stack ab, der
erste Parameter liegt also auf der h"ochsten Adresse (der Stack "`w"achst"'
nach unten!), in C liegt der erste Parameter an der niedrigsten
Adresse.
\begin{warning}
 W"ahrend man durch "`Umdrehen"' der Parameter-Reihenfolge in der
 Definition die erste H"urde "uberwinden k"onnte, macht der fehlende
 Parameter-Abbau einen Aufruf von C-Prozeduren mit Stack-Parametern
 nur vom Assembler aus m"oglich! Die Parameter muss man
 nach dem Aufruf dann allerdings selbst abbauen. Einfacher
 lassen sich Prozeduren mit reinen Register-Parametern
 einbinden.
\end{warning}

Alle bekannten C-Compiler halten sich an die Register-Konventionen,
sodass keine Probleme mit zerst"orten Registern auftreten.

Variablen, die als externe \near-Variablen oder via {\tt XREF} eingebunden
werden sollen, m"ussen in einem Hunk mit dem Namen "`{\tt \_\_MERGED}"' liegen,
d"urfen dann aber auch nur vom Typ DATA oder BSS sein, keinesfalls CHIP
oder CODE. Weiterhin d"urfen keine 32Bit-Relokationen von
anderen Hunks auf diese Variablen existieren.

Um ein Programm reentrant zu linken, d"urfen {\em keine\/} \far-Variablen
im Programm vorhanden sein, ebenso keine CHIP-DATA- oder CHIP-BSS-Hunks.
Sollen Daten eingebunden werden, die von vornherein im
CHIP-Memory liegen (z.B.\ Image-Daten, {\em nicht\/} die Image-Struktur),
so sollten diese unver"anderlich sein und als CHIPCODE deklariert werden.

Wird auf die Residentf"ahigkeit des Programmes verzichtet, so ist
bis auf eines alles erlaubt: CODE darf niemals in einem Hunk mit dem Namen
"`{\tt \_\_MERGED}"' liegen. Alle Merged-Hunks zusammen d"urfen niemals
mehr als 64\,kByte belegen.

\subsection{M2Amiga-Prozeduren in fremden Sprachen}

Die Einbindung von \mtwo-Prozeduren in anderen Programmiersprachen
d"urfte eher selten sein,
dennoch sollen einige Hinweise gegeben werden:

Eine \mtwo-Prozedur kann eingebunden werden, wenn ihr Name bekannt
ist, also sollte man zun"acht ein Definitionsmodul daf"ur schreiben.
Der Name besteht dann aus dem Modulnamen, einem Unterstrich und dem
Prozedurnamen. Weiterhin sollte darauf geachtet werden, dass kein
Pr"ufcode erzeugt wird, nur die moduleigenen Variablen und Prozeduren
benutzt werden d"urfen --- insbesondere keine Library-Aufrufe ---,
 und dass der Modulrumpf nicht ausgef"uhrt wird,%
\footnote{es sei denn, man macht sich die M"uhe,
den 12stelligen Hexadezimal-
Schl"ussel des Hauptmoduls abzutippen} eine Initialisierung erfolgt
somit {\em nicht\/}!

Um Probleme zu vermeiden sollte man nur vollst"andig von ihrer Umgebung
unabh"angige Prozeduren einbinden.

