DEADSOFTWARE

9396d01dc304c264baf08104e11363dd25ebb386
[cpc.git] / src / generic / Dsw / Mod / Linker486Main.cp
1 MODULE DswLinker486Main;
3 IMPORT Kernel, HostFiles, Files, Console, Strings,
4 LB := Dev2LnkBase, Load := Dev2LnkLoad, WrPe := Dev2LnkWritePe,
5 WrElf := Dev2LnkWriteElf, WrElfS := Dev2LnkWriteElfStatic;
7 CONST
8 tgtElfStatic = 0; tgtElfExe = 1; tgtElfDll = 2; tgtPeExe = 3; tgtPeDll = 4;
10 version = "0.2";
12 TYPE
13 Elem = POINTER TO RECORD
14 name: ARRAY 256 OF CHAR;
15 next: Elem
16 END;
18 VAR
19 u: Elem;
20 inobj: LB.Directory;
21 outdir, outname: Files.Name;
22 os, interp, main, kernel: ARRAY 256 OF CHAR;
23 static, dll, sinit: BOOLEAN;
25 PROCEDURE GetPath (IN path: ARRAY OF CHAR; OUT dir, name: Files.Name);
26 VAR i, j, len: INTEGER;
27 BEGIN
28 len := LEN(path$);
29 i := len - 1;
30 WHILE (i >= 0) & (path[i] # '/') DO DEC(i) END;
31 IF i >= 0 THEN
32 FOR i := 0 TO i - 1 DO
33 dir[i] := path[i]
34 END;
35 dir[i] := 0X
36 ELSE
37 dir := ""
38 END;
39 j := i + 1; i := 0;
40 WHILE path[j] # 0X DO
41 name[i] := path[j];
42 INC(i); INC(j)
43 END;
44 name[i] := 0X
45 END GetPath;
47 PROCEDURE InitOptions;
48 VAR i: INTEGER; h, t: Elem; obj: LB.Directory; p: ARRAY 256 OF CHAR;
50 PROCEDURE Check;
51 BEGIN
52 IF i >= Kernel.argc THEN
53 Console.WriteStr("required more parameters for ");
54 Console.WriteStr(p); Console.WriteLn;
55 Kernel.Quit(1)
56 END
57 END Check;
59 BEGIN
60 i := 1;
61 WHILE i < Kernel.argc DO
62 IF Kernel.argv[i, 0] = "-" THEN
63 p := Kernel.argv[i]$;
64 INC(i);
65 IF p = "-os" THEN
66 Check;
67 Strings.ToLower(Kernel.argv[i]$, os);
68 INC(i)
69 ELSIF p = "-interp" THEN
70 Check;
71 interp := Kernel.argv[i]$;
72 INC(i)
73 ELSIF p = "-o" THEN
74 Check;
75 GetPath(Kernel.argv[i]$, outdir, outname);
76 INC(i)
77 ELSIF p = "-static" THEN
78 static := TRUE
79 ELSIF p = "-dll" THEN
80 dll := TRUE
81 ELSIF p = "-sinit" THEN
82 sinit := TRUE
83 ELSIF (p = "-m") OR (p = "-main") THEN
84 Check;
85 main := Kernel.argv[i]$;
86 INC(i)
87 ELSIF (p = "-k") OR (p = "-kernel") THEN
88 Check;
89 kernel := Kernel.argv[i]$;
90 INC(i)
91 ELSIF p = "-codedir" THEN
92 Check;
93 obj := inobj;
94 NEW(inobj);
95 inobj.path := Kernel.argv[i]$;
96 inobj.legacy := FALSE;
97 inobj.next := obj;
98 INC(i)
99 ELSIF p = "-legacycodedir" THEN
100 Check;
101 obj := inobj;
102 NEW(inobj);
103 inobj.path := Kernel.argv[i]$;
104 inobj.legacy := TRUE;
105 inobj.next := obj;
106 INC(i)
107 ELSIF p = "-trap" THEN
108 LB.trap := TRUE;
109 Kernel.intTrap := TRUE
110 ELSIF p = "-version" THEN
111 Console.WriteStr(version); Console.WriteLn;
112 Kernel.Quit(0)
113 ELSE
114 Console.WriteStr("unknown option ");
115 Console.WriteStr(p); Console.WriteLn;
116 Kernel.Quit(1)
117 END
118 ELSE
119 IF h = NIL THEN NEW(h); t := h
120 ELSE NEW(t.next); t := t.next
121 END;
122 t.name := Kernel.argv[i]$;
123 INC(i)
124 END
125 END;
126 u := h
127 END InitOptions;
129 PROCEDURE CheckOptions;
130 BEGIN
131 IF (os = "linux") OR (os = "freebsd") OR (os = "openbsd") THEN
132 IF dll THEN LB.Init(tgtElfDll)
133 ELSIF static THEN LB.Init(tgtElfStatic)
134 ELSE LB.Init(tgtElfExe)
135 END;
136 LB.dynaInit := ~sinit;
137 IF os = "linux" THEN
138 LB.opt.OSABI := WrElf.ELFOSABI_NONE;
139 IF interp = "" THEN LB.opt.elfInterpreter := WrElf.linuxInterpreter
140 ELSE LB.opt.elfInterpreter := SHORT(interp$)
141 END
142 ELSIF os = "freebsd" THEN
143 LB.opt.OSABI := WrElf.ELFOSABI_FREEBSD;
144 IF interp = "" THEN LB.opt.elfInterpreter := WrElf.freeBSDInterpreter
145 ELSE LB.opt.elfInterpreter := SHORT(interp$)
146 END
147 ELSIF os = "openbsd" THEN
148 LB.opt.OSABI := WrElf.ELFOSABI_NONE;
149 IF interp = "" THEN LB.opt.elfInterpreter := WrElf.openBSDInterpreter
150 ELSE LB.opt.elfInterpreter := SHORT(interp$)
151 END
152 ELSE
153 HALT(100)
154 END;
155 IF outname = "" THEN
156 Files.dir.GetFileName("a", "out", outname)
157 END
158 ELSIF os = "win32" THEN
159 IF dll THEN LB.Init(tgtPeDll)
160 ELSE LB.Init(tgtPeExe)
161 END;
162 LB.dynaInit := ~sinit;
163 IF outname = "" THEN
164 Files.dir.GetFileName("a", "exe", outname)
165 END;
166 IF static THEN
167 Console.WriteStr("-static not supported for win32"); Console.WriteLn;
168 Kernel.Quit(1)
169 END;
170 IF interp # "" THEN
171 Console.WriteStr("-interp not supported for win32"); Console.WriteLn;
172 Kernel.Quit(1)
173 END
174 ELSIF os = "" THEN
175 Console.WriteStr("os not specified"); Console.WriteLn;
176 Kernel.Quit(1)
177 ELSE
178 Console.WriteStr("unknown os "); Console.WriteStr(os); Console.WriteLn;
179 Kernel.Quit(1)
180 END;
181 IF main = "" THEN
182 Console.WriteStr("main module not specified"); Console.WriteLn;
183 Kernel.Quit(1)
184 END;
185 IF outname = "" THEN
186 Console.WriteStr("required path to output file"); Console.WriteLn;
187 Kernel.Quit(1)
188 END;
189 IF inobj = NIL THEN
190 Console.WriteStr("required path to input objects"); Console.WriteLn;
191 Kernel.Quit(1)
192 END;
193 LB.objList := inobj;
194 LB.outputPath := outdir;
195 LB.outputName := SHORT(outname$);
196 LB.KernelName := SHORT(kernel$);
197 LB.mainName := SHORT(main$);
198 IF u = NIL THEN
199 Console.WriteStr("no input specified"); Console.WriteLn;
200 Kernel.Quit(1)
201 END;
202 END CheckOptions;
204 PROCEDURE LinkAll;
205 VAR m: Elem; codeBase, dataBase, varsBase: INTEGER;
206 BEGIN
207 m := u;
208 WHILE m # NIL DO
209 CASE LB.target OF
210 | tgtElfStatic, tgtElfExe, tgtPeExe: Load.AddModule(m.name)
211 | tgtElfDll, tgtPeDll: Load.ExportModule(m.name)
212 END;
213 m := m.next
214 END;
215 CASE LB.target OF
216 | tgtElfStatic, tgtElfDll, tgtPeDll: (* ok *)
217 | tgtElfExe:
218 IF os = "freebsd" THEN
219 Load.ExportVariable(LB.KernelName$, "__progname");
220 Load.ExportVariable(LB.KernelName$, "environ")
221 END;
222 Load.ExportAll
223 | tgtPeExe:
224 Load.ExportAll
225 END;
226 codeBase := 0; dataBase := 0; varsBase := 0;
227 LB.BeginLinking;
228 IF LB.outPe THEN
229 WrPe.Init;
230 WrPe.GetBases(codeBase, dataBase, varsBase);
231 LB.SetAddr(codeBase, dataBase, varsBase);
232 LB.DoFixups;
233 WrPe.WriteOut
234 ELSIF LB.outElf & LB.opt.elfStatic THEN
235 WrElfS.Init;
236 WrElfS.GetBases(codeBase, dataBase, varsBase);
237 LB.SetAddr(codeBase, dataBase, varsBase);
238 LB.DoFixups;
239 WrElfS.WriteOut
240 ELSIF LB.outElf THEN
241 WrElf.Init;
242 WrElf.GetBases(codeBase, dataBase, varsBase);
243 LB.SetAddr(codeBase, dataBase, varsBase);
244 LB.DoFixups;
245 WrElf.WriteOut
246 END;
247 IF LB.error THEN
248 Console.WriteStr("link failed"); Console.WriteLn;
249 Kernel.Quit(1)
250 END
251 END LinkAll;
253 PROCEDURE Init;
254 BEGIN
255 IF Kernel.trapCount # 0 THEN Kernel.Quit(1) END;
256 HostFiles.SetRootDir(".");
257 InitOptions;
258 CheckOptions;
259 LinkAll;
260 Kernel.Quit(0)
261 END Init;
263 BEGIN
264 Kernel.intTrap := FALSE;
265 Kernel.Start(Init)
266 END DswLinker486Main.