2
Copyright (c) 1998-2002 by Peter Vreman
4
This unit implements support import,export,link routines
5
for the (i386) solaris target
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
****************************************************************************
30
// Up to now we use gld since the solaris ld seems not support .res-files}
31
{-$DEFINE LinkTest} { DON't del link.res and write Info }
32
{$DEFINE GnuLd} {The other is not implemented }
38
cutils,cfileutils,cclasses,
39
verbose,systems,globtype,globals,
41
fmodule,aasmbase,aasmtai,aasmdata,aasmcpu,cpubase,symsym,symdef,
43
import,export,link,i_sunos,ogbase;
46
timportlibsolaris=class(timportlib)
47
procedure generatelib;override;
50
texportlibsolaris=class(texportlib)
51
procedure preparelib(const s : string);override;
52
procedure exportprocedure(hp : texported_item);override;
53
procedure exportvar(hp : texported_item);override;
54
procedure generatelib;override;
57
tlinkersolaris=class(texternallinker)
61
Function WriteResponseFile(isdll:boolean) : Boolean;
63
constructor Create;override;
64
procedure SetDefaultInfo;override;
65
function MakeExecutable:boolean;override;
66
function MakeSharedLibrary:boolean;override;
70
{*****************************************************************************
72
*****************************************************************************}
74
procedure timportlibsolaris.generatelib;
77
ImportLibrary : TImportLibrary;
79
for i:=0 to current_module.ImportLibraryList.Count-1 do
81
ImportLibrary:=TImportLibrary(current_module.ImportLibraryList[i]);
82
current_module.linkothersharedlibs.add(ImportLibrary.Name,link_always);
87
{*****************************************************************************
89
*****************************************************************************}
91
procedure texportlibsolaris.preparelib(const s:string);
96
procedure texportlibsolaris.exportprocedure(hp : texported_item);
100
{ first test the index value }
101
if (hp.options and eo_index)<>0 then
103
Message1(parser_e_no_export_with_index_for_target,'solaris');
106
{ use pascal name is none specified }
107
if (hp.options and eo_name)=0 then
109
hp.name:=stringdup(hp.sym.name);
110
hp.options:=hp.options or eo_name;
112
{ now place in correct order }
113
hp2:=texported_item(current_module._exports.first);
114
while assigned(hp2) and
115
(hp.name^>hp2.name^) do
116
hp2:=texported_item(hp2.next);
117
{ insert hp there !! }
118
if assigned(hp2) and (hp2.name^=hp.name^) then
120
{ this is not allowed !! }
121
Message1(parser_e_export_name_double,hp.name^);
124
if hp2=texported_item(current_module._exports.first) then
125
current_module._exports.insert(hp)
126
else if assigned(hp2) then
129
hp.previous:=hp2.previous;
130
if assigned(hp2.previous) then
131
hp2.previous.next:=hp;
135
current_module._exports.concat(hp);
139
procedure texportlibsolaris.exportvar(hp : texported_item);
146
procedure texportlibsolaris.generatelib;
148
hp2 : texported_item;
151
new_section(current_asmdata.asmlists[al_procedures],sec_code,'',0);
152
hp2:=texported_item(current_module._exports.first);
153
while assigned(hp2) do
155
if (not hp2.is_var) and
156
(hp2.sym.typ=procsym) then
158
{ the manglednames can already be the same when the procedure
159
is declared with cdecl }
160
pd:=tprocdef(tprocsym(hp2.sym).ProcdefList[0]);
161
if pd.mangledname<>hp2.name^ then
163
{ place jump in al_procedures }
164
current_asmdata.asmlists[al_procedures].concat(tai_align.create(target_info.alignment.procalign));
165
current_asmdata.asmlists[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
166
cg.a_jmp_name(current_asmdata.asmlists[al_procedures],pd.mangledname);
167
current_asmdata.asmlists[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
171
Message1(parser_e_no_export_of_variables_for_target,'linux');
172
hp2:=texported_item(hp2.next);
177
{*****************************************************************************
179
*****************************************************************************}
181
Constructor TLinkersolaris.Create;
184
if NOT Dontlinkstdlibpath Then
185
LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib;/opt/sfw/lib',true);
187
if (cs_link_staticflag in current_settings.globalswitches) then WriteLN('ForceLinkStaticFlag');
188
if (cs_link_static in current_settings.globalswitches) then WriteLN('LinkStatic-Flag');
189
if (cs_link_shared in current_settings.globalswitches) then WriteLN('LinkSynamicFlag');
194
procedure TLinkersolaris.SetDefaultInfo;
196
This will also detect which libc version will be used
204
ExeCmd[1]:='gld $OPT $DYNLINK $STATIC $STRIP -L. -o $EXE $RES';
205
DllCmd[1]:='gld $OPT -shared -L. -o $EXE $RES';
206
DllCmd[2]:='strip --strip-unneeded $EXE';
207
DynamicLinker:=''; { Gnu uses the default }
212
(* Linux Stuff not needed?
213
{ first try glibc2 } // muss noch gendert werden
214
if FileExists(DynamicLinker) then
217
{ Check for 2.0 files, else use the glibc 2.1 stub }
218
if FileExists('/lib/ld-2.0.*') then
224
DynamicLinker:='/lib/ld-linux.so.1';
231
Function TLinkersolaris.WriteResponseFile(isdll:boolean) : Boolean;
238
HPath : TCmdStrListItem;
243
WriteResponseFile:=False;
244
{ set special options for some targets }
245
linkdynamic:=not(SharedLibFiles.empty);
246
{ linkdynamic:=false; // da nicht getestet }
247
linklibc:=(SharedLibFiles.Find('c')<>nil);
251
if cs_profile in current_settings.moduleswitches then
255
AddSharedLibrary('gmon');
256
AddSharedLibrary('c');
264
AddSharedLibrary('c'); { quick hack: this solaris implementation needs alwys libc }
267
{ Open link.res file }
268
LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
270
{ Write path to search libraries }
271
HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First);
272
while assigned(HPath) do
274
LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
275
HPath:=TCmdStrListItem(HPath.Next);
277
HPath:=TCmdStrListItem(LibrarySearchPath.First);
278
while assigned(HPath) do
280
LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
281
HPath:=TCmdStrListItem(HPath.Next);
284
LinkRes.Add('INPUT(');
285
{ add objectfiles, start with prt0 always }
286
{ solaris port contains _start inside the system unit, it
287
needs only one entry because it is linked always against libc
289
LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
291
{ try to add crti and crtbegin if linking to C }
292
if linklibc then { Needed in solaris? }
294
{ if librarysearchpath.FindFile('crtbegin.o',s) then
295
LinkRes.AddFileName(s);}
296
if librarysearchpath.FindFile('crti.o',false,s) then
297
LinkRes.AddFileName(s);
300
while not ObjectFiles.Empty do
302
s:=ObjectFiles.GetFirst;
304
LinkRes.AddFileName(maybequoted(s));
308
{ Write staticlibraries }
309
if not StaticLibFiles.Empty then
311
LinkRes.Add('GROUP(');
312
While not StaticLibFiles.Empty do
314
S:=StaticLibFiles.GetFirst;
315
LinkRes.AddFileName(maybequoted(s))
320
{ Write sharedlibraries like -l<lib>, also add the needed dynamic linker
321
here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
322
if not SharedLibFiles.Empty then
324
LinkRes.Add('INPUT(');
325
While not SharedLibFiles.Empty do
327
S:=SharedLibFiles.GetFirst;
330
i:=Pos(target_info.sharedlibext,S);
338
linkdynamic:=false; { libc will include the ld-solaris (war ld-linux) for us }
341
{ be sure that libc is the last lib }
344
{ when we have -static for the linker the we also need libgcc }
345
if (cs_link_staticflag in current_settings.globalswitches) then begin
346
LinkRes.Add('-lgcc');
348
if linkdynamic and (Info.DynamicLinker<>'') then { gld has a default, DynamicLinker is not set in solaris }
349
LinkRes.AddFileName(Info.DynamicLinker);
352
{ objects which must be at the end }
353
if linklibc then {needed in solaris ? }
355
if {librarysearchpath.FindFile('crtend.o',s1) or}
356
librarysearchpath.FindFile('crtn.o',false,s2) then
358
LinkRes.Add('INPUT(');
359
{ LinkRes.AddFileName(s1);}
360
LinkRes.AddFileName(s2);
364
{ Write and Close response }
368
WriteResponseFile:=True;
372
function TLinkersolaris.MakeExecutable:boolean;
377
DynLinkStr : string[60];
379
StripStr : string[40];
381
if not(cs_link_nolink in current_settings.globalswitches) then
382
Message1(exec_i_linking,current_module.exefilename^);
384
{ Create some replacements }
388
if (cs_link_staticflag in current_settings.globalswitches) then
389
StaticStr:='-Bstatic';
390
if (cs_link_strip in current_settings.globalswitches) then
392
If (cs_profile in current_settings.moduleswitches) or
393
((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
394
DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
395
{ solaris sets DynamicLinker, but gld will (hopefully) defaults to -Bdynamic and add the default-linker }
396
{ Write used files and libraries }
397
WriteResponseFile(false);
400
SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
401
Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
402
Replace(cmdstr,'$OPT',Info.ExtraOptions);
403
Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
404
Replace(cmdstr,'$STATIC',StaticStr);
405
Replace(cmdstr,'$STRIP',StripStr);
406
Replace(cmdstr,'$DYNLINK',DynLinkStr);
407
success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
409
{ Remove ReponseFile }
411
if (success) and not(cs_link_nolink in current_settings.globalswitches) then
412
DeleteFile(outputexedir+Info.ResName);
414
MakeExecutable:=success; { otherwise a recursive call to link method }
418
Function TLinkersolaris.MakeSharedLibrary:boolean;
424
MakeSharedLibrary:=false;
425
if not(cs_link_nolink in current_settings.globalswitches) then
426
Message1(exec_i_linking,current_module.sharedlibfilename^);
428
{ Write used files and libraries }
429
WriteResponseFile(true);
432
SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
433
Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename^));
434
Replace(cmdstr,'$OPT',Info.ExtraOptions);
435
Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
436
success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
438
{ Strip the library ? }
439
if success and (cs_link_strip in current_settings.globalswitches) then
441
SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
442
Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename^));
443
success:=DoExec(utilsprefix+FindUtil(binstr),cmdstr,true,false);
446
{ Remove ReponseFile }
448
if (success) and not(cs_link_nolink in current_settings.globalswitches) then
449
DeleteFile(outputexedir+Info.ResName);
451
MakeSharedLibrary:=success; { otherwise a recursive call to link method }
455
{*****************************************************************************
457
*****************************************************************************}
461
RegisterExternalLinker(system_i386_solaris_info,TLinkersolaris);
462
RegisterImport(system_i386_solaris,TImportLibsolaris);
463
RegisterExport(system_i386_solaris,TExportLibsolaris);
464
RegisterTarget(system_i386_solaris_info);
468
RegisterExternalLinker(system_sparc_solaris_info,TLinkersolaris);
469
RegisterImport(system_sparc_solaris,TImportLibsolaris);
470
RegisterExport(system_sparc_solaris,TExportLibsolaris);
471
RegisterTarget(system_sparc_solaris_info);