|
@@ -32,13 +32,32 @@ interface
|
|
|
implementation
|
|
|
|
|
|
uses
|
|
|
+{$ifdef gdb}
|
|
|
+ gdb,
|
|
|
+{$endif gdb}
|
|
|
cutils,cclasses,
|
|
|
verbose,systems,globtype,globals,
|
|
|
symconst,script,
|
|
|
fmodule,aasmbase,aasmtai,aasmcpu,cpubase,symsym,symdef,
|
|
|
- import,export,link,i_bsd;
|
|
|
+ import,export,link,i_bsd,
|
|
|
+ cgobj;
|
|
|
|
|
|
type
|
|
|
+ tdarwinimported_item = class(timported_item)
|
|
|
+ procdef : tprocdef;
|
|
|
+ end;
|
|
|
+
|
|
|
+ timportlibdarwin=class(timportlib)
|
|
|
+ procedure preparelib(const s:string);override;
|
|
|
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
|
|
|
+ procedure importvariable(vs:tvarsym;const name,module:string);override;
|
|
|
+ procedure generatelib;override;
|
|
|
+ procedure generatesmartlib;override;
|
|
|
+ private
|
|
|
+ procedure darwinimportproc(aprocdef:tprocdef;const func,module : string;index : longint;const name : string);
|
|
|
+ procedure importvariable_str(const s:string;const name,module:string);
|
|
|
+ end;
|
|
|
+
|
|
|
timportlibbsd=class(timportlib)
|
|
|
procedure preparelib(const s:string);override;
|
|
|
procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
|
|
@@ -68,8 +87,193 @@ implementation
|
|
|
end;
|
|
|
|
|
|
|
|
|
+
|
|
|
{*****************************************************************************
|
|
|
- TIMPORTLIBLINUX
|
|
|
+ TIMPORTLIBDARWIN
|
|
|
+*****************************************************************************}
|
|
|
+
|
|
|
+ procedure timportlibdarwin.preparelib(const s : string);
|
|
|
+ begin
|
|
|
+ if not(assigned(importssection)) then
|
|
|
+ importssection:=TAAsmoutput.create;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure timportlibdarwin.darwinimportproc(aprocdef:tprocdef;const func,module : string;index : longint;const name : string);
|
|
|
+ var
|
|
|
+ hp1 : timportlist;
|
|
|
+ hp2 : tdarwinimported_item;
|
|
|
+ begin
|
|
|
+ { force the current mangledname }
|
|
|
+ if assigned(aprocdef) then
|
|
|
+ aprocdef.has_mangledname:=true;
|
|
|
+ { search for the module }
|
|
|
+ hp1:=timportlist(current_module.imports.first);
|
|
|
+ { generate a new item ? }
|
|
|
+ if not(assigned(hp1)) then
|
|
|
+ begin
|
|
|
+ { we don't need an import section per library }
|
|
|
+ hp1:=timportlist.create('imports');
|
|
|
+ current_module.imports.concat(hp1);
|
|
|
+ end;
|
|
|
+ { search for reuse of old import item }
|
|
|
+ hp2:=tdarwinimported_item(hp1.imported_items.first);
|
|
|
+ while assigned(hp2) do
|
|
|
+ begin
|
|
|
+ if hp2.func^=func then
|
|
|
+ break;
|
|
|
+ { there's already another declaration refering to this imported symbol }
|
|
|
+ { -> make this declaration refer to that entry as well }
|
|
|
+ if (hp2.name^ = name) then
|
|
|
+ begin
|
|
|
+ if not assigned(aprocdef) then
|
|
|
+ internalerror(2004010306);
|
|
|
+ if assigned(aprocdef) then
|
|
|
+ aprocdef.setmangledname(hp2.func^);
|
|
|
+ break;
|
|
|
+ end;
|
|
|
+ hp2:=tdarwinimported_item(hp2.next);
|
|
|
+ end;
|
|
|
+ if not assigned(hp2) then
|
|
|
+ begin
|
|
|
+ hp2:=tdarwinimported_item.create(func,name,index);
|
|
|
+ hp2.procdef:=aprocdef;
|
|
|
+ hp1.imported_items.concat(hp2);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure timportlibdarwin.importprocedure(aprocdef:tprocdef;const module : string;index : longint;const name : string);
|
|
|
+ begin
|
|
|
+ darwinimportproc(aprocdef,aprocdef.mangledname,module,index,name);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure timportlibdarwin.importvariable(vs:tvarsym;const name,module:string);
|
|
|
+ begin
|
|
|
+ importvariable_str(vs.mangledname,name,module);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure timportlibdarwin.importvariable_str(const s:string;const name,module:string);
|
|
|
+ var
|
|
|
+ hp1 : timportlist;
|
|
|
+ hp2 : tdarwinimported_item;
|
|
|
+ begin
|
|
|
+ { search for the module }
|
|
|
+ hp1:=timportlist(current_module.imports.first);
|
|
|
+ { generate a new item ? }
|
|
|
+ if not(assigned(hp1)) then
|
|
|
+ begin
|
|
|
+ hp1:=timportlist.create('imports');
|
|
|
+ current_module.imports.concat(hp1);
|
|
|
+ end;
|
|
|
+ hp2:=tdarwinimported_item.create_var(s,name);
|
|
|
+ hp2.procdef:=nil;
|
|
|
+ hp1.imported_items.concat(hp2);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure timportlibdarwin.generatesmartlib;
|
|
|
+ begin
|
|
|
+ generatelib;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure timportlibdarwin.generatelib;
|
|
|
+ var
|
|
|
+ hp1 : timportlist;
|
|
|
+ hp2 : tdarwinimported_item;
|
|
|
+ l1 : tasmsymbol;
|
|
|
+ symname: string;
|
|
|
+ mangledstring : string;
|
|
|
+{$ifdef GDB}
|
|
|
+ importname : string;
|
|
|
+ suffix : integer;
|
|
|
+{$endif GDB}
|
|
|
+ href : treference;
|
|
|
+ begin
|
|
|
+ hp1:=timportlist(current_module.imports.first);
|
|
|
+ while assigned(hp1) do
|
|
|
+ begin
|
|
|
+ hp2:=tdarwinimported_item(hp1.imported_items.first);
|
|
|
+ while assigned(hp2) do
|
|
|
+ begin
|
|
|
+ if not assigned(hp2.name) then
|
|
|
+ internalerror(2004010302);
|
|
|
+ symname := hp2.name^;
|
|
|
+ if assigned(tdarwinimported_item(hp2).procdef) and
|
|
|
+ (tdarwinimported_item(hp2).procdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
|
|
|
+ symname := target_info.Cprefix+symname;
|
|
|
+ if not hp2.is_var then
|
|
|
+ begin
|
|
|
+{$IfDef GDB}
|
|
|
+ if (cs_debuginfo in aktmoduleswitches) then
|
|
|
+ importssection.concat(tai_stab_function_name.create(nil));
|
|
|
+{$EndIf GDB}
|
|
|
+ if not assigned(hp2.procdef) then
|
|
|
+ internalerror(2004010306);
|
|
|
+ mangledstring := hp2.func^;
|
|
|
+ if (po_public in hp2.procdef.procoptions) then
|
|
|
+ begin
|
|
|
+ importsSection.concat(Tai_section.Create(sec_code));
|
|
|
+ importsSection.concat(Tai_symbol.createname_global(mangledstring,0));
|
|
|
+ mangledstring := '_$'+mangledstring;
|
|
|
+ importsSection.concat(taicpu.op_sym(A_B,objectlibrary.newasmsymbol(mangledstring)));
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ importsSection.concat(Tai_section.Create(sec_data));
|
|
|
+ importsSection.concat(Tai_direct.create(strpnew('.section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16')));
|
|
|
+ importsSection.concat(Tai_align.Create(4));
|
|
|
+ importsSection.concat(Tai_symbol.Createname(mangledstring,0));
|
|
|
+ importsSection.concat(Tai_direct.create(strpnew((#9+'.indirect_symbol ')+symname)));
|
|
|
+ l1 := objectlibrary.newasmsymbol(mangledstring+'$lazy_ptr');
|
|
|
+ reference_reset_symbol(href,l1,0);
|
|
|
+{$IfDef GDB}
|
|
|
+ if (cs_debuginfo in aktmoduleswitches) and assigned(hp2.procdef) then
|
|
|
+ begin
|
|
|
+ mangledstring:=hp2.procdef.mangledname;
|
|
|
+ hp2.procdef.setmangledname(mangledstring);
|
|
|
+ hp2.procdef.concatstabto(importssection);
|
|
|
+ hp2.procdef.setmangledname(mangledstring);
|
|
|
+ end;
|
|
|
+{$EndIf GDB}
|
|
|
+{$ifdef CPUPOWERPC}
|
|
|
+ href.symaddr := refs_ha;
|
|
|
+ importsSection.concat(taicpu.op_reg_ref(A_LIS,NR_R11,href));
|
|
|
+ href.symaddr := refs_l;
|
|
|
+ href.base := NR_R11;
|
|
|
+ importsSection.concat(taicpu.op_reg_ref(A_LWZU,NR_R12,href));
|
|
|
+ importsSection.concat(taicpu.op_reg(A_MTCTR,NR_R12));
|
|
|
+ importsSection.concat(taicpu.op_none(A_BCTR));
|
|
|
+{$else CPUPOWERPC}
|
|
|
+{$error fixme for darwin x86}
|
|
|
+{$endif CPUPOWERPC}
|
|
|
+ importsSection.concat(Tai_section.Create(sec_data));
|
|
|
+ importsSection.concat(Tai_direct.create(strpnew('.lazy_symbol_pointer')));
|
|
|
+ importsSection.concat(Tai_symbol.Create(l1,0));
|
|
|
+ importsSection.concat(Tai_direct.create(strpnew((#9+'.indirect_symbol ')+symname)));
|
|
|
+ importsSection.concat(tai_const_symbol.createname(strpnew('dyld_stub_binding_helper')));
|
|
|
+
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ importsSection.concat(Tai_section.Create(sec_data));
|
|
|
+ importsSection.concat(Tai_direct.create(strpnew('.non_lazy_symbol_pointer')));
|
|
|
+ importsSection.concat(Tai_symbol.Createname(hp2.func^,0));
|
|
|
+ importsSection.concat(Tai_direct.create(strpnew((#9+'.indirect_symbol ')+hp2.name^)));
|
|
|
+ importsSection.concat(Tai_const.create_32bit(0));
|
|
|
+ end;
|
|
|
+ hp2:=tdarwinimported_item(hp2.next);
|
|
|
+ end;
|
|
|
+ hp1:=timportlist(hp1.next);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{*****************************************************************************
|
|
|
+ TIMPORTLIBBSD
|
|
|
*****************************************************************************}
|
|
|
|
|
|
procedure timportlibbsd.preparelib(const s : string);
|
|
@@ -107,7 +311,7 @@ end;
|
|
|
|
|
|
|
|
|
{*****************************************************************************
|
|
|
- TEXPORTLIBLINUX
|
|
|
+ TEXPORTLIBBSD
|
|
|
*****************************************************************************}
|
|
|
|
|
|
procedure texportlibbsd.preparelib(const s:string);
|
|
@@ -196,8 +400,12 @@ end;
|
|
|
Constructor TLinkerBSD.Create;
|
|
|
begin
|
|
|
Inherited Create;
|
|
|
- IF NOT Dontlinkstdlibpath Then
|
|
|
- LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib',true);
|
|
|
+ if not Dontlinkstdlibpath Then
|
|
|
+ if (target_info.system <> system_powerpc_darwin) then
|
|
|
+ LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib',true)
|
|
|
+ else
|
|
|
+ { Mac OS X doesn't have a /lib }
|
|
|
+ LibrarySearchPath.AddPath('/usr/lib',true)
|
|
|
end;
|
|
|
|
|
|
|
|
@@ -207,22 +415,12 @@ procedure TLinkerBSD.SetDefaultInfo;
|
|
|
}
|
|
|
begin
|
|
|
LibrarySuffix:=' ';
|
|
|
-{$ifdef NETBSD}
|
|
|
-{$ifdef M68K}
|
|
|
- LdSupportsNoResponseFile:=true;
|
|
|
-{$else : not M68K}
|
|
|
- LdSupportsNoResponseFile:=false;
|
|
|
-{$endif M68K}
|
|
|
-{$else : not NETBSD}
|
|
|
- LdSupportsNoResponseFile:=false;
|
|
|
-{$endif NETBSD}
|
|
|
+ LdSupportsNoResponseFile := (target_info.system in [system_m68k_netbsd,system_powerpc_darwin]);
|
|
|
with Info do
|
|
|
begin
|
|
|
if LdSupportsNoResponseFile then
|
|
|
begin
|
|
|
ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $STRIP -L. -o $EXE `cat $RES`';
|
|
|
- { We need external linking to interpret the `cat $RES` PM }
|
|
|
- include(aktglobalswitches,cs_link_extern);
|
|
|
end
|
|
|
else
|
|
|
ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $STRIP -L. -o $EXE $RES';
|
|
@@ -266,32 +464,44 @@ Var
|
|
|
begin
|
|
|
WriteResponseFile:=False;
|
|
|
{ set special options for some targets }
|
|
|
- linkdynamic:=not(SharedLibFiles.empty);
|
|
|
- linklibc:=(SharedLibFiles.Find('c')<>nil);
|
|
|
- prtobj:='prt0';
|
|
|
- cprtobj:='cprt0';
|
|
|
- gprtobj:='gprt0';
|
|
|
- if glibc21 then
|
|
|
- begin
|
|
|
- cprtobj:='cprt21';
|
|
|
- gprtobj:='gprt21';
|
|
|
- end;
|
|
|
- if cs_profile in aktmoduleswitches then
|
|
|
- begin
|
|
|
- prtobj:=gprtobj;
|
|
|
-{
|
|
|
- if not glibc2 then
|
|
|
- AddSharedLibrary('gmon');
|
|
|
-}
|
|
|
- AddSharedLibrary('c');
|
|
|
- LibrarySuffix:='p';
|
|
|
- linklibc:=true;
|
|
|
- end
|
|
|
+ if target_info.system <> system_powerpc_darwin then
|
|
|
+ begin
|
|
|
+ linkdynamic:=not(SharedLibFiles.empty);
|
|
|
+ linklibc:=(SharedLibFiles.Find('c')<>nil);
|
|
|
+ prtobj:='prt0';
|
|
|
+ cprtobj:='cprt0';
|
|
|
+ gprtobj:='gprt0';
|
|
|
+ if glibc21 then
|
|
|
+ begin
|
|
|
+ cprtobj:='cprt21';
|
|
|
+ gprtobj:='gprt21';
|
|
|
+ end;
|
|
|
+ if cs_profile in aktmoduleswitches then
|
|
|
+ begin
|
|
|
+ prtobj:=gprtobj;
|
|
|
+ {
|
|
|
+ if not glibc2 then
|
|
|
+ AddSharedLibrary('gmon');
|
|
|
+ }
|
|
|
+ AddSharedLibrary('c');
|
|
|
+ LibrarySuffix:='p';
|
|
|
+ linklibc:=true;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if linklibc then
|
|
|
+ prtobj:=cprtobj;
|
|
|
+ end;
|
|
|
+ end
|
|
|
else
|
|
|
- begin
|
|
|
- if linklibc then
|
|
|
- prtobj:=cprtobj;
|
|
|
- end;
|
|
|
+ begin
|
|
|
+ { for darwin: always link dynamically against libc }
|
|
|
+ linklibc := true;
|
|
|
+ if not(cs_profile in aktmoduleswitches) then
|
|
|
+ prtobj:='/usr/lib/crt1.o'
|
|
|
+ else
|
|
|
+ prtobj:='/usr/lib/gcrt1.o';
|
|
|
+ end;
|
|
|
|
|
|
{ Open link.res file }
|
|
|
LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
|
|
@@ -322,7 +532,8 @@ begin
|
|
|
if prtobj<>'' then
|
|
|
LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
|
|
|
{ try to add crti and crtbegin if linking to C }
|
|
|
- if linklibc then
|
|
|
+ if linklibc and
|
|
|
+ (target_info.system <> system_powerpc_darwin) then
|
|
|
begin
|
|
|
if librarysearchpath.FindFile('crtbegin.o',s) then
|
|
|
LinkRes.AddFileName(s);
|
|
@@ -392,7 +603,8 @@ begin
|
|
|
LinkRes.Add(')');
|
|
|
end;
|
|
|
{ objects which must be at the end }
|
|
|
- if linklibc then
|
|
|
+ if linklibc and
|
|
|
+ (target_info.system <> system_powerpc_darwin) then
|
|
|
begin
|
|
|
Fl1:=librarysearchpath.FindFile('crtend.o',s1);
|
|
|
Fl2:=librarysearchpath.FindFile('crtn.o',s2);
|
|
@@ -458,7 +670,7 @@ begin
|
|
|
Replace(cmdstr,'$STATIC',StaticStr);
|
|
|
Replace(cmdstr,'$STRIP',StripStr);
|
|
|
Replace(cmdstr,'$DYNLINK',DynLinkStr);
|
|
|
- success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
|
|
|
+ success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,LdSupportsNoResponseFile);
|
|
|
|
|
|
{ Remove ReponseFile }
|
|
|
if (success) and not(cs_link_extern in aktglobalswitches) then
|
|
@@ -529,7 +741,7 @@ initialization
|
|
|
{$ifdef powerpc}
|
|
|
// RegisterExternalLinker(system_m68k_FreeBSD_info,TLinkerBSD);
|
|
|
RegisterExternalLinker(system_powerpc_darwin_info,TLinkerBSD);
|
|
|
- RegisterImport(system_powerpc_darwin,timportlibbsd);
|
|
|
+ RegisterImport(system_powerpc_darwin,timportlibdarwin);
|
|
|
RegisterExport(system_powerpc_darwin,texportlibbsd);
|
|
|
RegisterTarget(system_powerpc_darwin_info);
|
|
|
RegisterExternalLinker(system_powerpc_netbsd_info,TLinkerBSD);
|
|
@@ -540,7 +752,16 @@ initialization
|
|
|
end.
|
|
|
{
|
|
|
$Log$
|
|
|
- Revision 1.5 2003-10-30 18:35:30 marco
|
|
|
+ Revision 1.6 2004-01-04 21:26:31 jonas
|
|
|
+ + Darwin support for routines imported from external libraries (not yet
|
|
|
+ ideal, we should generate stubs in all files where the routines are
|
|
|
+ used -> these are automatically merged by the linker; now we generate
|
|
|
+ one global symbol with a jump to a stub in unit where the routine is
|
|
|
+ declared)
|
|
|
+ + (not yet working) Darwin support for imported variables
|
|
|
+ + Darwin support for linking
|
|
|
+
|
|
|
+ Revision 1.5 2003/10/30 18:35:30 marco
|
|
|
* librarysuffix + profiling
|
|
|
|
|
|
Revision 1.4 2003/10/11 19:32:04 marco
|