DEADSOFTWARE

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