2
$Id: t_sunos.pas,v 1.7 2004/03/02 00:36:33 olle Exp $
3
Copyright (c) 1998-2002 by Peter Vreman
5
This unit implements support import,export,link routines
6
for the (i386) sunos target
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
****************************************************************************
31
// Up to now we use gld since the solaris ld seems not support .res-files}
32
{-$DEFINE LinkTest} { DON't del link.res and write Info }
33
{$DEFINE GnuLd} {The other is not implemented }
39
verbose,systems,globtype,globals,
41
fmodule,aasmbase,aasmtai,aasmcpu,cpubase,symsym,symdef,
42
import,export,link,i_sunos;
45
timportlibsunos=class(timportlib)
46
procedure preparelib(const s:string);override;
47
procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
48
procedure importvariable(vs:tvarsym;const name,module:string);override;
49
procedure generatelib;override;
52
texportlibsunos=class(texportlib)
53
procedure preparelib(const s : string);override;
54
procedure exportprocedure(hp : texported_item);override;
55
procedure exportvar(hp : texported_item);override;
56
procedure generatelib;override;
59
tlinkersunos=class(texternallinker)
63
Function WriteResponseFile(isdll:boolean) : Boolean;
65
constructor Create;override;
66
procedure SetDefaultInfo;override;
67
function MakeExecutable:boolean;override;
68
function MakeSharedLibrary:boolean;override;
72
{*****************************************************************************
74
*****************************************************************************}
76
procedure timportlibsunos.preparelib(const s : string);
79
WriteLN('Prepare import: ',s);
84
procedure timportlibsunos.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
86
{ insert sharedlibrary }
88
WriteLN('Import: f:',func,' m:',module,' n:',name);
90
current_module.linkothersharedlibs.add(SplitName(module),link_allways);
91
{ do nothing with the procedure, only set the mangledname }
94
aprocdef.setmangledname(name);
97
message(parser_e_empty_import_name);
101
procedure timportlibsunos.importvariable(vs:tvarsym;const name,module:string);
103
{ insert sharedlibrary }
104
current_module.linkothersharedlibs.add(SplitName(module),link_allways);
105
{ reset the mangledname and turn off the dll_var option }
106
vs.set_mangledname(name);
107
exclude(vs.varoptions,vo_is_dll_var);
111
procedure timportlibsunos.generatelib;
116
{*****************************************************************************
118
*****************************************************************************}
120
procedure texportlibsunos.preparelib(const s:string);
125
procedure texportlibsunos.exportprocedure(hp : texported_item);
127
hp2 : texported_item;
129
{ first test the index value }
130
if (hp.options and eo_index)<>0 then
132
Message1(parser_e_no_export_with_index_for_target,'SunOS');
135
{ use pascal name is none specified }
136
if (hp.options and eo_name)=0 then
138
hp.name:=stringdup(hp.sym.name);
139
hp.options:=hp.options or eo_name;
141
{ now place in correct order }
142
hp2:=texported_item(current_module._exports.first);
143
while assigned(hp2) and
144
(hp.name^>hp2.name^) do
145
hp2:=texported_item(hp2.next);
146
{ insert hp there !! }
147
if assigned(hp2) and (hp2.name^=hp.name^) then
149
{ this is not allowed !! }
150
Message1(parser_e_export_name_double,hp.name^);
153
if hp2=texported_item(current_module._exports.first) then
154
current_module._exports.insert(hp)
155
else if assigned(hp2) then
158
hp.previous:=hp2.previous;
159
if assigned(hp2.previous) then
160
hp2.previous.next:=hp;
164
current_module._exports.concat(hp);
168
procedure texportlibsunos.exportvar(hp : texported_item);
175
procedure texportlibsunos.generatelib;
177
hp2 : texported_item;
179
hp2:=texported_item(current_module._exports.first);
180
while assigned(hp2) do
182
if (not hp2.is_var) and
183
(hp2.sym.typ=procsym) then
185
{ the manglednames can already be the same when the procedure
186
is declared with cdecl }
187
if tprocsym(hp2.sym).first_procdef.mangledname<>hp2.name^ then
190
{ place jump in codesegment }
191
codesegment.concat(Tai_align.Create_op(4,$90));
192
codeSegment.concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
193
codeSegment.concat(Taicpu.Op_sym(A_JMP,S_NO,objectlibrary.newasmsymbol(tprocsym(hp2.sym).first_procdef.mangledname,AB_EXTERNAL,AT_FUNCTION)));
194
codeSegment.concat(Tai_symbol_end.Createname(hp2.name^));
199
Message1(parser_e_no_export_of_variables_for_target,'SunOS');
200
hp2:=texported_item(hp2.next);
205
{*****************************************************************************
207
*****************************************************************************}
209
Constructor TLinkersunos.Create;
212
if NOT Dontlinkstdlibpath Then
213
LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib;/opt/sfw/lib',true);
215
if (cs_link_staticflag in aktglobalswitches) then WriteLN('ForceLinkStaticFlag');
216
if (cs_link_static in aktglobalswitches) then WriteLN('LinkStatic-Flag');
217
if (cs_link_shared in aktglobalswitches) then WriteLN('LinkSynamicFlag');
222
procedure TLinkersunos.SetDefaultInfo;
224
This will also detect which libc version will be used
232
ExeCmd[1]:='gld $OPT $DYNLINK $STATIC $STRIP -L. -o $EXE $RES';
233
DllCmd[1]:='gld $OPT -shared -L. -o $EXE $RES';
234
DllCmd[2]:='strip --strip-unneeded $EXE';
235
DynamicLinker:=''; { Gnu uses the default }
240
(* Linux Stuff not needed?
241
{ first try glibc2 } // muss noch gendert werden
242
if FileExists(DynamicLinker) then
245
{ Check for 2.0 files, else use the glibc 2.1 stub }
246
if FileExists('/lib/ld-2.0.*') then
252
DynamicLinker:='/lib/ld-linux.so.1';
259
Function TLinkersunos.WriteResponseFile(isdll:boolean) : Boolean;
266
HPath : TStringListItem;
271
WriteResponseFile:=False;
272
{ set special options for some targets }
273
linkdynamic:=not(SharedLibFiles.empty);
274
{ linkdynamic:=false; // da nicht getestet }
275
linklibc:=(SharedLibFiles.Find('c')<>nil);
279
if cs_profile in aktmoduleswitches then
283
AddSharedLibrary('gmon');
284
AddSharedLibrary('c');
292
AddSharedLibrary('c'); { quick hack: this sunos implementation needs alwys libc }
295
{ Open link.res file }
296
LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
298
{ Write path to search libraries }
299
HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
300
while assigned(HPath) do
302
LinkRes.Add('SEARCH_DIR('+HPath.Str+')');
303
HPath:=TStringListItem(HPath.Next);
305
HPath:=TStringListItem(LibrarySearchPath.First);
306
while assigned(HPath) do
308
LinkRes.Add('SEARCH_DIR('+HPath.Str+')');
309
HPath:=TStringListItem(HPath.Next);
312
LinkRes.Add('INPUT(');
313
{ add objectfiles, start with prt0 always }
315
LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
316
{ try to add crti and crtbegin if linking to C }
317
if linklibc then { Needed in sunos? }
319
{ if librarysearchpath.FindFile('crtbegin.o',s) then
320
LinkRes.AddFileName(s);}
321
if librarysearchpath.FindFile('crti.o',s) then
322
LinkRes.AddFileName(s);
325
while not ObjectFiles.Empty do
327
s:=ObjectFiles.GetFirst;
329
LinkRes.AddFileName(s);
333
{ Write staticlibraries }
334
if not StaticLibFiles.Empty then
336
LinkRes.Add('GROUP(');
337
While not StaticLibFiles.Empty do
339
S:=StaticLibFiles.GetFirst;
340
LinkRes.AddFileName(s)
345
{ Write sharedlibraries like -l<lib>, also add the needed dynamic linker
346
here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
347
if not SharedLibFiles.Empty then
349
LinkRes.Add('INPUT(');
350
While not SharedLibFiles.Empty do
352
S:=SharedLibFiles.GetFirst;
355
i:=Pos(target_info.sharedlibext,S);
363
linkdynamic:=false; { libc will include the ld-sunos (war ld-linux) for us }
366
{ be sure that libc is the last lib }
369
{ when we have -static for the linker the we also need libgcc }
370
if (cs_link_staticflag in aktglobalswitches) then begin
371
LinkRes.Add('-lgcc');
373
if linkdynamic and (Info.DynamicLinker<>'') then { gld has a default, DynamicLinker is not set in sunos }
374
LinkRes.AddFileName(Info.DynamicLinker);
377
{ objects which must be at the end }
378
if linklibc then {needed in sunos ? }
380
if {librarysearchpath.FindFile('crtend.o',s1) or}
381
librarysearchpath.FindFile('crtn.o',s2) then
383
LinkRes.Add('INPUT(');
384
{ LinkRes.AddFileName(s1);}
385
LinkRes.AddFileName(s2);
389
{ Write and Close response }
393
WriteResponseFile:=True;
397
function TLinkersunos.MakeExecutable:boolean;
402
DynLinkStr : string[60];
404
StripStr : string[40];
406
if not(cs_link_extern in aktglobalswitches) then
407
Message1(exec_i_linking,current_module.exefilename^);
409
{ Create some replacements }
413
if (cs_link_staticflag in aktglobalswitches) then
414
StaticStr:='-Bstatic';
415
if (cs_link_strip in aktglobalswitches) then
417
If (cs_profile in aktmoduleswitches) or
418
((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
419
DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
420
{ sunos sets DynamicLinker, but gld will (hopefully) defaults to -Bdynamic and add the default-linker }
421
{ Write used files and libraries }
422
WriteResponseFile(false);
425
SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
426
Replace(cmdstr,'$EXE',current_module.exefilename^);
427
Replace(cmdstr,'$OPT',Info.ExtraOptions);
428
Replace(cmdstr,'$RES',outputexedir+Info.ResName);
429
Replace(cmdstr,'$STATIC',StaticStr);
430
Replace(cmdstr,'$STRIP',StripStr);
431
Replace(cmdstr,'$DYNLINK',DynLinkStr);
432
success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
434
{ Remove ReponseFile }
436
if (success) and not(cs_link_extern in aktglobalswitches) then
437
RemoveFile(outputexedir+Info.ResName);
439
MakeExecutable:=success; { otherwise a recursive call to link method }
443
Function TLinkersunos.MakeSharedLibrary:boolean;
449
MakeSharedLibrary:=false;
450
if not(cs_link_extern in aktglobalswitches) then
451
Message1(exec_i_linking,current_module.sharedlibfilename^);
453
{ Write used files and libraries }
454
WriteResponseFile(true);
457
SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
458
Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
459
Replace(cmdstr,'$OPT',Info.ExtraOptions);
460
Replace(cmdstr,'$RES',outputexedir+Info.ResName);
461
success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
463
{ Strip the library ? }
464
if success and (cs_link_strip in aktglobalswitches) then
466
SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
467
Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
468
success:=DoExec(utilsprefix+FindUtil(binstr),cmdstr,true,false);
471
{ Remove ReponseFile }
473
if (success) and not(cs_link_extern in aktglobalswitches) then
474
RemoveFile(outputexedir+Info.ResName);
476
MakeSharedLibrary:=success; { otherwise a recursive call to link method }
480
{*****************************************************************************
482
*****************************************************************************}
485
RegisterExternalLinker(system_i386_sunos_info,TLinkerSunos);
486
RegisterImport(system_i386_sunos,TImportLibSunos);
487
RegisterExport(system_i386_sunos,TExportLibSunos);
488
RegisterTarget(system_i386_sunos_info);
491
$Log: t_sunos.pas,v $
492
Revision 1.7 2004/03/02 00:36:33 olle
493
* big transformation of Tai_[const_]Symbol.Create[data]name*
495
Revision 1.6 2003/10/11 19:32:04 marco
498
Revision 1.5 2003/10/03 14:16:48 marco
499
* -XP<prefix> support
501
Revision 1.4 2003/04/27 07:29:52 peter
502
* aktprocdef cleanup, aktprocdef is now always nil when parsing
503
a new procdef declaration
505
* lexlevel removed, use symtable.symtablelevel instead
506
* implicit init/final code uses the normal genentry/genexit
507
* funcret state checking updated for new funcret handling
509
Revision 1.3 2003/04/26 09:16:08 peter
510
* .o files belonging to the unit are first searched in the same dir
513
Revision 1.2 2002/09/09 17:34:17 peter
514
* tdicationary.replace added to replace and item in a dictionary. This
515
is only allowed for the same name
516
* varsyms are inserted in symtable before the types are parsed. This
517
fixes the long standing "var longint : longint" bug
518
- consume_idlist and idstringlist removed. The loops are inserted
519
at the callers place and uses the symtable for duplicate id checking
521
Revision 1.1 2002/09/06 15:03:50 carl
522
* moved files to systems directory
524
Revision 1.29 2002/09/03 16:26:29 daniel
525
* Make Tprocdef.defs protected
527
Revision 1.28 2002/08/12 15:08:44 carl
528
+ stab register indexes for powerpc (moved from gdb to cpubase)
529
+ tprocessor enumeration moved to cpuinfo
530
+ linker in target_info is now a class
531
* many many updates for m68k (will soon start to compile)
532
- removed some ifdef or correct them for correct cpu
534
Revision 1.27 2002/08/11 14:32:32 peter
535
* renamed current_library to objectlibrary
537
Revision 1.26 2002/08/11 13:24:20 peter
538
* saving of asmsymbols in ppu supported
539
* asmsymbollist global is removed and moved into a new class
540
tasmlibrarydata that will hold the info of a .a file which
541
corresponds with a single module. Added librarydata to tmodule
542
to keep the library info stored for the module. In the future the
543
objectfiles will also be stored to the tasmlibrarydata class
544
* all getlabel/newasmsymbol and friends are moved to the new class
546
Revision 1.25 2002/07/26 21:15:46 florian
547
* rewrote the system handling
549
Revision 1.24 2002/07/01 18:46:35 peter
551
* reorganized aasm layer
553
Revision 1.23 2002/05/18 13:34:27 peter
554
* readded missing revisions
556
Revision 1.22 2002/05/16 19:46:53 carl
557
+ defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
558
+ try to fix temp allocation (still in ifdef)
559
+ generic constructor calls
560
+ start of tassembler / tmodulebase class cleanup
562
Revision 1.20 2002/04/22 18:19:22 carl
563
- remove use_bound_instruction field
565
Revision 1.19 2002/04/20 21:43:18 carl
566
* fix stack size for some targets
567
+ add offset to parameters from frame pointer info.
568
- remove some unused stuff
570
Revision 1.18 2002/04/19 15:46:05 peter
571
* mangledname rewrite, tprocdef.mangledname is now created dynamicly
572
in most cases and not written to the ppu
573
* add mangeledname_prefix() routine to generate the prefix of
574
manglednames depending on the current procedure, object and module
575
* removed static procprefix since the mangledname is now build only
576
on demand from tprocdef.mangledname
578
Revision 1.17 2002/04/15 19:16:57 carl
579
- remove size_of_pointer field
581
Revision 1.16 2002/03/04 19:10:14 peter
582
* removed compiler warnings