DEADSOFTWARE

added Meta for native compiler
[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 ELSE
108 Console.WriteStr("unknown option ");
109 Console.WriteStr(p); Console.WriteLn;
110 Kernel.Quit(1)
111 END
112 ELSE
113 IF h = NIL THEN NEW(h); t := h
114 ELSE NEW(t.next); t := t.next
115 END;
116 t.name := Kernel.argv[i]$;
117 INC(i)
118 END
119 END;
120 u := h
121 END InitOptions;
123 PROCEDURE CheckOptions;
124 BEGIN
125 IF (os = "linux") OR (os = "freebsd") OR (os = "openbsd") THEN
126 IF dll THEN LB.Init(tgtElfDll)
127 ELSIF static THEN LB.Init(tgtElfStatic)
128 ELSE LB.Init(tgtElfExe)
129 END;
130 LB.dynaInit := ~sinit;
131 IF os = "linux" THEN
132 LB.opt.OSABI := WrElf.ELFOSABI_NONE;
133 IF interp = "" THEN LB.opt.elfInterpreter := WrElf.linuxInterpreter
134 ELSE LB.opt.elfInterpreter := SHORT(interp$)
135 END
136 ELSIF os = "freebsd" THEN
137 LB.opt.OSABI := WrElf.ELFOSABI_FREEBSD;
138 IF interp = "" THEN LB.opt.elfInterpreter := WrElf.freeBSDInterpreter
139 ELSE LB.opt.elfInterpreter := SHORT(interp$)
140 END
141 ELSIF os = "openbsd" THEN
142 LB.opt.OSABI := WrElf.ELFOSABI_NONE;
143 IF interp = "" THEN LB.opt.elfInterpreter := WrElf.openBSDInterpreter
144 ELSE LB.opt.elfInterpreter := SHORT(interp$)
145 END
146 ELSE
147 HALT(100)
148 END;
149 IF outname = "" THEN
150 Files.dir.GetFileName("a", "out", outname)
151 END
152 ELSIF os = "win32" THEN
153 IF dll THEN LB.Init(tgtPeDll)
154 ELSE LB.Init(tgtPeExe)
155 END;
156 LB.dynaInit := ~sinit;
157 IF outname = "" THEN
158 Files.dir.GetFileName("a", "exe", outname)
159 END;
160 IF static THEN
161 Console.WriteStr("-static not supported for win32"); Console.WriteLn;
162 Kernel.Quit(1)
163 END;
164 IF interp # "" THEN
165 Console.WriteStr("-interp not supported for win32"); Console.WriteLn;
166 Kernel.Quit(1)
167 END
168 ELSIF os = "" THEN
169 Console.WriteStr("os not specified"); Console.WriteLn;
170 Kernel.Quit(1)
171 ELSE
172 Console.WriteStr("unknown os "); Console.WriteStr(os); Console.WriteLn;
173 Kernel.Quit(1)
174 END;
175 IF main = "" THEN
176 Console.WriteStr("main module not specified"); Console.WriteLn;
177 Kernel.Quit(1)
178 END;
179 IF outname = "" THEN
180 Console.WriteStr("required path to output file"); Console.WriteLn;
181 Kernel.Quit(1)
182 END;
183 IF inobj = NIL THEN
184 Console.WriteStr("required path to input objects"); Console.WriteLn;
185 Kernel.Quit(1)
186 END;
187 LB.objList := inobj;
188 LB.outputPath := outdir;
189 LB.outputName := SHORT(outname$);
190 LB.KernelName := SHORT(kernel$);
191 LB.mainName := SHORT(main$);
192 IF u = NIL THEN
193 Console.WriteStr("no input specified"); Console.WriteLn;
194 Kernel.Quit(1)
195 END;
196 END CheckOptions;
198 PROCEDURE LinkAll;
199 VAR m: Elem; codeBase, dataBase, varsBase: INTEGER;
200 BEGIN
201 m := u;
202 WHILE m # NIL DO
203 CASE LB.target OF
204 | tgtElfStatic, tgtElfExe, tgtPeExe: Load.AddModule(m.name)
205 | tgtElfDll, tgtPeDll: Load.ExportModule(m.name)
206 END;
207 m := m.next
208 END;
209 CASE LB.target OF
210 | tgtElfStatic, tgtElfDll, tgtPeDll: (* ok *)
211 | tgtElfExe:
212 IF os = "freebsd" THEN
213 Load.ExportVariable(LB.KernelName$, "__progname");
214 Load.ExportVariable(LB.KernelName$, "environ")
215 END;
216 Load.ExportAll
217 | tgtPeExe:
218 Load.ExportAll
219 END;
220 codeBase := 0; dataBase := 0; varsBase := 0;
221 LB.BeginLinking;
222 IF LB.outPe THEN
223 WrPe.Init;
224 WrPe.GetBases(codeBase, dataBase, varsBase);
225 LB.SetAddr(codeBase, dataBase, varsBase);
226 LB.DoFixups;
227 WrPe.WriteOut
228 ELSIF LB.outElf & LB.opt.elfStatic THEN
229 WrElfS.Init;
230 WrElfS.GetBases(codeBase, dataBase, varsBase);
231 LB.SetAddr(codeBase, dataBase, varsBase);
232 LB.DoFixups;
233 WrElfS.WriteOut
234 ELSIF LB.outElf THEN
235 WrElf.Init;
236 WrElf.GetBases(codeBase, dataBase, varsBase);
237 LB.SetAddr(codeBase, dataBase, varsBase);
238 LB.DoFixups;
239 WrElf.WriteOut
240 END;
241 IF LB.error THEN
242 Console.WriteStr("link failed"); Console.WriteLn;
243 Kernel.Quit(1)
244 END
245 END LinkAll;
247 PROCEDURE Init;
248 BEGIN
249 IF Kernel.trapCount # 0 THEN Kernel.Quit(1) END;
250 HostFiles.SetRootDir(".");
251 InitOptions;
252 CheckOptions;
253 LinkAll;
254 Kernel.Quit(0)
255 END Init;
257 BEGIN
258 Kernel.Start(Init)
259 END DswLinker486Main.