1 MODULE DswLinker486Main
;
3 IMPORT Kernel
, HostFiles
, Files
, Console
, Strings
,
4 LB
:= Dev2LnkBase
, Load
:= Dev2LnkLoad
, WrPe
:= Dev2LnkWritePe
,
5 WrElf
:= Dev2LnkWriteElf
, WrElfS
:= Dev2LnkWriteElfStatic
;
8 tgtElfStatic
= 0; tgtElfExe
= 1; tgtElfDll
= 2; tgtPeExe
= 3; tgtPeDll
= 4;
13 Elem
= POINTER TO RECORD
14 name
: ARRAY 256 OF CHAR;
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;
30 WHILE (i
>= 0) & (path
[i
] # '
/'
) DO DEC(i
) END;
32 FOR i
:= 0 TO i
- 1 DO
47 PROCEDURE InitOptions
;
48 VAR i
: INTEGER; h
, t
: Elem
; obj
: LB
.Directory
; p
: ARRAY 256 OF CHAR;
52 IF i
>= Kernel
.argc
THEN
53 Console
.WriteStr("required more parameters for ");
54 Console
.WriteStr(p
); Console
.WriteLn
;
61 WHILE i
< Kernel
.argc
DO
62 IF Kernel
.argv
[i
, 0] = "-" THEN
67 Strings
.ToLower(Kernel
.argv
[i
]$
, os
);
69 ELSIF p
= "-interp" THEN
71 interp
:= Kernel
.argv
[i
]$
;
75 GetPath(Kernel
.argv
[i
]$
, outdir
, outname
);
77 ELSIF p
= "-static" THEN
81 ELSIF p
= "-sinit" THEN
83 ELSIF (p
= "-m") OR (p
= "-main") THEN
85 main
:= Kernel
.argv
[i
]$
;
87 ELSIF (p
= "-k") OR (p
= "-kernel") THEN
89 kernel
:= Kernel
.argv
[i
]$
;
91 ELSIF p
= "-codedir" THEN
95 inobj
.path
:= Kernel
.argv
[i
]$
;
96 inobj
.legacy
:= FALSE
;
99 ELSIF p
= "-legacycodedir" THEN
103 inobj
.path
:= Kernel
.argv
[i
]$
;
104 inobj
.legacy
:= TRUE
;
107 ELSIF p
= "-trap" THEN
109 Kernel
.intTrap
:= TRUE
110 ELSIF p
= "-version" THEN
111 Console
.WriteStr(version
); Console
.WriteLn
;
114 Console
.WriteStr("unknown option ");
115 Console
.WriteStr(p
); Console
.WriteLn
;
119 IF h
= NIL THEN NEW(h
); t
:= h
120 ELSE NEW(t
.next
); t
:= t
.next
122 t
.name
:= Kernel
.argv
[i
]$
;
129 PROCEDURE CheckOptions
;
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
)
136 LB
.dynaInit
:= ~sinit
;
138 LB
.opt
.OSABI
:= WrElf
.ELFOSABI_NONE
;
139 IF interp
= "" THEN LB
.opt
.elfInterpreter
:= WrElf
.linuxInterpreter
140 ELSE LB
.opt
.elfInterpreter
:= SHORT(interp$
)
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$
)
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$
)
156 Files
.dir
.GetFileName("a", "out", outname
)
158 ELSIF os
= "win32" THEN
159 IF dll
THEN LB
.Init(tgtPeDll
)
160 ELSE LB
.Init(tgtPeExe
)
162 LB
.dynaInit
:= ~sinit
;
164 Files
.dir
.GetFileName("a", "exe", outname
)
167 Console
.WriteStr("-static not supported for win32"); Console
.WriteLn
;
171 Console
.WriteStr("-interp not supported for win32"); Console
.WriteLn
;
175 Console
.WriteStr("os not specified"); Console
.WriteLn
;
178 Console
.WriteStr("unknown os "); Console
.WriteStr(os
); Console
.WriteLn
;
182 Console
.WriteStr("main module not specified"); Console
.WriteLn
;
186 Console
.WriteStr("required path to output file"); Console
.WriteLn
;
190 Console
.WriteStr("required path to input objects"); Console
.WriteLn
;
194 LB
.outputPath
:= outdir
;
195 LB
.outputName
:= SHORT(outname$
);
196 LB
.KernelName
:= SHORT(kernel$
);
197 LB
.mainName
:= SHORT(main$
);
199 Console
.WriteStr("no input specified"); Console
.WriteLn
;
205 VAR m
: Elem
; codeBase
, dataBase
, varsBase
: INTEGER;
210 | tgtElfStatic
, tgtElfExe
, tgtPeExe
: Load
.AddModule(m
.name
)
211 | tgtElfDll
, tgtPeDll
: Load
.ExportModule(m
.name
)
216 | tgtElfStatic
, tgtElfDll
, tgtPeDll
: (* ok *)
218 IF os
= "freebsd" THEN
219 Load
.ExportVariable(LB
.KernelName$
, "__progname");
220 Load
.ExportVariable(LB
.KernelName$
, "environ")
226 codeBase
:= 0; dataBase
:= 0; varsBase
:= 0;
230 WrPe
.GetBases(codeBase
, dataBase
, varsBase
);
231 LB
.SetAddr(codeBase
, dataBase
, varsBase
);
234 ELSIF LB
.outElf
& LB
.opt
.elfStatic
THEN
236 WrElfS
.GetBases(codeBase
, dataBase
, varsBase
);
237 LB
.SetAddr(codeBase
, dataBase
, varsBase
);
242 WrElf
.GetBases(codeBase
, dataBase
, varsBase
);
243 LB
.SetAddr(codeBase
, dataBase
, varsBase
);
248 Console
.WriteStr("link failed"); Console
.WriteLn
;
255 IF Kernel
.trapCount
# 0 THEN Kernel
.Quit(1) END;
256 HostFiles
.SetRootDir(".");
264 Kernel
.intTrap
:= FALSE
;
266 END DswLinker486Main
.