mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 03:46:00 +02:00
* changed calling of external procedures to be the same as under gcc
(don't worry about all the generated stubs, they're optimized away by the linker) -> side effect: no need anymore to use special declarations for external C functions under Darwin compared to other platforms (it's still necessary for variables though)
This commit is contained in:
parent
5c5c449ecf
commit
174cea8023
@ -133,6 +133,8 @@ unit cgcpu;
|
||||
|
||||
function save_regs(list : taasmoutput):longint;
|
||||
procedure restore_regs(list : taasmoutput);
|
||||
|
||||
function get_darwin_call_stub(const s: string): tasmsymbol;
|
||||
end;
|
||||
|
||||
tcg64fppc = class(tcg64f32)
|
||||
@ -311,6 +313,52 @@ const
|
||||
end;
|
||||
|
||||
|
||||
function tcgppc.get_darwin_call_stub(const s: string): tasmsymbol;
|
||||
var
|
||||
stubname: string;
|
||||
href: treference;
|
||||
l1: tasmsymbol;
|
||||
begin
|
||||
{ function declared in the current unit? }
|
||||
result := objectlibrary.getasmsymbol(s);
|
||||
if not(assigned(result)) then
|
||||
begin
|
||||
stubname := 'L'+s+'$stub';
|
||||
result := objectlibrary.getasmsymbol(stubname);
|
||||
end;
|
||||
if assigned(result) then
|
||||
exit;
|
||||
|
||||
if not(assigned(importssection)) then
|
||||
importssection:=TAAsmoutput.create;
|
||||
|
||||
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));
|
||||
result := objectlibrary.newasmsymbol(stubname,AB_EXTERNAL,AT_FUNCTION);
|
||||
importsSection.concat(Tai_symbol.Create(result,0));
|
||||
importsSection.concat(Tai_direct.create(strpnew((#9+'.indirect_symbol ')+s)));
|
||||
l1 := objectlibrary.newasmsymbol('L'+s+'$lazy_ptr',AB_EXTERNAL,AT_FUNCTION);
|
||||
reference_reset_symbol(href,l1,0);
|
||||
{$ifdef powerpc}
|
||||
href.refaddr := addr_hi;
|
||||
importsSection.concat(taicpu.op_reg_ref(A_LIS,NR_R11,href));
|
||||
href.refaddr := addr_lo;
|
||||
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 powerpc}
|
||||
internalerror(2004010502);
|
||||
{$endif powerpc}
|
||||
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 ')+s)));
|
||||
importsSection.concat(tai_const_symbol.createname(strpnew('dyld_stub_binding_helper'),AT_FUNCTION,0));
|
||||
end;
|
||||
|
||||
|
||||
{ calling a procedure by name }
|
||||
procedure tcgppc.a_call_name(list : taasmoutput;const s : string);
|
||||
var
|
||||
@ -319,9 +367,16 @@ const
|
||||
{ MacOS: The linker on MacOS (PPCLink) inserts a call to glue code,
|
||||
if it is a cross-TOC call. If so, it also replaces the NOP
|
||||
with some restore code.}
|
||||
list.concat(taicpu.op_sym(A_BL,objectlibrary.newasmsymbol(s,AB_EXTERNAL,AT_FUNCTION)));
|
||||
if target_info.system=system_powerpc_macos then
|
||||
list.concat(taicpu.op_none(A_NOP));
|
||||
if (target_info.system <> system_powerpc_darwin) then
|
||||
begin
|
||||
list.concat(taicpu.op_sym(A_BL,objectlibrary.newasmsymbol(s,AB_EXTERNAL,AT_FUNCTION)));
|
||||
if target_info.system=system_powerpc_macos then
|
||||
list.concat(taicpu.op_none(A_NOP));
|
||||
end
|
||||
else
|
||||
begin
|
||||
list.concat(taicpu.op_sym(A_BL,get_darwin_call_stub(s)));
|
||||
end;
|
||||
if not(pi_do_call in current_procinfo.flags) then
|
||||
internalerror(2003060703);
|
||||
end;
|
||||
@ -2356,7 +2411,15 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.169 2004-04-04 17:50:36 olle
|
||||
Revision 1.170 2004-05-31 18:08:41 jonas
|
||||
* changed calling of external procedures to be the same as under gcc
|
||||
(don't worry about all the generated stubs, they're optimized away
|
||||
by the linker)
|
||||
-> side effect: no need anymore to use special declarations for
|
||||
external C functions under Darwin compared to other platforms
|
||||
(it's still necessary for variables though)
|
||||
|
||||
Revision 1.169 2004/04/04 17:50:36 olle
|
||||
* macos: fixed large offsets in references
|
||||
|
||||
Revision 1.168 2004/03/06 21:37:45 florian
|
||||
|
@ -53,8 +53,6 @@ implementation
|
||||
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);
|
||||
end;
|
||||
|
||||
timportlibbsd=class(timportlib)
|
||||
@ -96,59 +94,27 @@ implementation
|
||||
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);
|
||||
{ insert sharedlibrary }
|
||||
current_module.linkothersharedlibs.add(SplitName(module),link_allways);
|
||||
{ force the mangledname }
|
||||
if assigned(aprocdef) then
|
||||
begin
|
||||
if (aprocdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
|
||||
aprocdef.setmangledname(target_info.Cprefix+name)
|
||||
else
|
||||
aprocdef.setmangledname(name);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure timportlibdarwin.importvariable(vs:tvarsym;const name,module:string);
|
||||
begin
|
||||
{ this is handled in the nppcld.pas tppcloadnode }
|
||||
{ insert sharedlibrary }
|
||||
current_module.linkothersharedlibs.add(SplitName(module),link_allways);
|
||||
{ the rest is handled in the nppcld.pas tppcloadnode }
|
||||
vs.set_mangledname(name);
|
||||
end;
|
||||
|
||||
|
||||
@ -159,91 +125,7 @@ implementation
|
||||
|
||||
|
||||
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^;
|
||||
{$ifdef powerpc}
|
||||
{ if (po_public in hp2.procdef.procoptions) or
|
||||
(hp2.procdef.hasforward and
|
||||
(po_public in hp2.procdef.forwarddef.procoptions)) then
|
||||
}
|
||||
begin
|
||||
importsSection.concat(Tai_section.Create(sec_code));
|
||||
importsSection.concat(Tai_symbol.createname_global(mangledstring,AT_FUNCTION,0));
|
||||
mangledstring := '_$'+mangledstring;
|
||||
importsSection.concat(taicpu.op_sym(A_B,objectlibrary.newasmsymbol(mangledstring,AB_EXTERNAL,AT_FUNCTION)));
|
||||
end;
|
||||
{$else powerpc}
|
||||
internalerror(2004010501);
|
||||
{$endif powerpc}
|
||||
|
||||
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,AT_FUNCTION,0));
|
||||
importsSection.concat(Tai_direct.create(strpnew((#9+'.indirect_symbol ')+symname)));
|
||||
l1 := objectlibrary.newasmsymbol(mangledstring+'$lazy_ptr',AB_EXTERNAL,AT_FUNCTION);
|
||||
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 powerpc}
|
||||
href.refaddr := addr_hi;
|
||||
importsSection.concat(taicpu.op_reg_ref(A_LIS,NR_R11,href));
|
||||
href.refaddr := addr_lo;
|
||||
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 powerpc}
|
||||
internalerror(2004010502);
|
||||
{$endif powerpc}
|
||||
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'),AT_FUNCTION,0));
|
||||
end;
|
||||
hp2:=tdarwinimported_item(hp2.next);
|
||||
end;
|
||||
hp1:=timportlist(hp1.next);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -736,7 +618,15 @@ initialization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.14 2004-04-04 10:53:21 marco
|
||||
Revision 1.15 2004-05-31 18:08:41 jonas
|
||||
* changed calling of external procedures to be the same as under gcc
|
||||
(don't worry about all the generated stubs, they're optimized away
|
||||
by the linker)
|
||||
-> side effect: no need anymore to use special declarations for
|
||||
external C functions under Darwin compared to other platforms
|
||||
(it's still necessary for variables though)
|
||||
|
||||
Revision 1.14 2004/04/04 10:53:21 marco
|
||||
* small c_r fix, also link plain libc (like for x11)
|
||||
|
||||
Revision 1.13 2004/03/29 21:19:33 florian
|
||||
|
Loading…
Reference in New Issue
Block a user