mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 12:39:09 +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;
|
function save_regs(list : taasmoutput):longint;
|
||||||
procedure restore_regs(list : taasmoutput);
|
procedure restore_regs(list : taasmoutput);
|
||||||
|
|
||||||
|
function get_darwin_call_stub(const s: string): tasmsymbol;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
tcg64fppc = class(tcg64f32)
|
tcg64fppc = class(tcg64f32)
|
||||||
@ -311,6 +313,52 @@ const
|
|||||||
end;
|
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 }
|
{ calling a procedure by name }
|
||||||
procedure tcgppc.a_call_name(list : taasmoutput;const s : string);
|
procedure tcgppc.a_call_name(list : taasmoutput;const s : string);
|
||||||
var
|
var
|
||||||
@ -319,9 +367,16 @@ const
|
|||||||
{ MacOS: The linker on MacOS (PPCLink) inserts a call to glue code,
|
{ 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
|
if it is a cross-TOC call. If so, it also replaces the NOP
|
||||||
with some restore code.}
|
with some restore code.}
|
||||||
list.concat(taicpu.op_sym(A_BL,objectlibrary.newasmsymbol(s,AB_EXTERNAL,AT_FUNCTION)));
|
if (target_info.system <> system_powerpc_darwin) then
|
||||||
if target_info.system=system_powerpc_macos then
|
begin
|
||||||
list.concat(taicpu.op_none(A_NOP));
|
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
|
if not(pi_do_call in current_procinfo.flags) then
|
||||||
internalerror(2003060703);
|
internalerror(2003060703);
|
||||||
end;
|
end;
|
||||||
@ -2356,7 +2411,15 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$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
|
* macos: fixed large offsets in references
|
||||||
|
|
||||||
Revision 1.168 2004/03/06 21:37:45 florian
|
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 importvariable(vs:tvarsym;const name,module:string);override;
|
||||||
procedure generatelib;override;
|
procedure generatelib;override;
|
||||||
procedure generatesmartlib;override;
|
procedure generatesmartlib;override;
|
||||||
private
|
|
||||||
procedure darwinimportproc(aprocdef:tprocdef;const func,module : string;index : longint;const name : string);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
timportlibbsd=class(timportlib)
|
timportlibbsd=class(timportlib)
|
||||||
@ -96,59 +94,27 @@ implementation
|
|||||||
end;
|
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);
|
procedure timportlibdarwin.importprocedure(aprocdef:tprocdef;const module : string;index : longint;const name : string);
|
||||||
begin
|
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;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure timportlibdarwin.importvariable(vs:tvarsym;const name,module:string);
|
procedure timportlibdarwin.importvariable(vs:tvarsym;const name,module:string);
|
||||||
begin
|
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;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -159,91 +125,7 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
procedure timportlibdarwin.generatelib;
|
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
|
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;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -736,7 +618,15 @@ initialization
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$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)
|
* small c_r fix, also link plain libc (like for x11)
|
||||||
|
|
||||||
Revision 1.13 2004/03/29 21:19:33 florian
|
Revision 1.13 2004/03/29 21:19:33 florian
|
||||||
|
Loading…
Reference in New Issue
Block a user