mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 18:09:30 +02:00
+ Compiler support for pic on darwin/i386. The i386 rtl still needs
to be made pic-safe (mainly accesses to the global default8087cw) * At the same time also made the non-pic code abi-compliant (access external data via indirect symbol pointers etc) Darwin/i386 also puts the got into a virtual register (like Darwin/ppc), a.o. because the register allocator fails to colour a routine in aasmcpu.pas if we take away ebx from it. git-svn-id: trunk@8657 -
This commit is contained in:
parent
4492ee39c5
commit
3266f4e483
@ -1135,6 +1135,16 @@ implementation
|
||||
result := '.section __TEXT, .fpc, regular, no_dead_strip';
|
||||
exit;
|
||||
end;
|
||||
sec_code:
|
||||
begin
|
||||
if (aname='fpc_geteipasebx') or
|
||||
(aname='fpc_geteipasecx') then
|
||||
begin
|
||||
result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
|
||||
#10'.private_extern '+aname;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
result := inherited sectionname(atype,aname,aorder);
|
||||
end;
|
||||
|
@ -83,7 +83,8 @@ unit cgcpu;
|
||||
procedure tcg386.init_register_allocators;
|
||||
begin
|
||||
inherited init_register_allocators;
|
||||
if cs_create_pic in current_settings.moduleswitches then
|
||||
if (target_info.system<>system_i386_darwin) and
|
||||
(cs_create_pic in current_settings.moduleswitches) then
|
||||
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP])
|
||||
else
|
||||
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP]);
|
||||
@ -494,12 +495,26 @@ unit cgcpu;
|
||||
(pi_needs_got in current_procinfo.flags) and
|
||||
not(po_kylixlocal in current_procinfo.procdef.procoptions) then
|
||||
begin
|
||||
current_module.requires_ebx_pic_helper:=true;
|
||||
cg.a_call_name_static(list,'fpc_geteipasebx');
|
||||
list.concat(taicpu.op_sym_ofs_reg(A_ADD,S_L,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),0,NR_PIC_OFFSET_REG));
|
||||
list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG,nil));
|
||||
{ ecx could be used in leave procedures }
|
||||
current_procinfo.got:=NR_EBX;
|
||||
if (target_info.system<>system_i386_darwin) then
|
||||
begin
|
||||
current_module.requires_ebx_pic_helper:=true;
|
||||
cg.a_call_name_static(list,'fpc_geteipasebx');
|
||||
list.concat(taicpu.op_sym_ofs_reg(A_ADD,S_L,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),0,NR_PIC_OFFSET_REG));
|
||||
list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG,nil));
|
||||
{ ecx could be used in leaf procedures }
|
||||
current_procinfo.got:=NR_EBX;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ can't use ecx, since that one may overwrite a parameter }
|
||||
current_module.requires_ebx_pic_helper:=true;
|
||||
cg.a_call_name_static(list,'fpc_geteipasebx');
|
||||
list.concat(tai_regalloc.alloc(NR_EBX,nil));
|
||||
a_label(list,current_procinfo.CurrGotLabel);
|
||||
{ got is already set by ti386procinfo.allocate_got_register }
|
||||
list.concat(tai_regalloc.dealloc(NR_EBX,nil));
|
||||
a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_EBX,current_procinfo.got);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -28,7 +28,7 @@ unit cpupi;
|
||||
interface
|
||||
|
||||
uses
|
||||
psub,procinfo;
|
||||
psub,procinfo,aasmdata;
|
||||
|
||||
type
|
||||
ti386procinfo = class(tcgprocinfo)
|
||||
@ -36,6 +36,7 @@ unit cpupi;
|
||||
procedure set_first_temp_offset;override;
|
||||
function calc_stackframe_size:longint;override;
|
||||
procedure generate_parameter_info;override;
|
||||
procedure allocate_got_register(list: tasmlist);override;
|
||||
end;
|
||||
|
||||
|
||||
@ -43,8 +44,8 @@ unit cpupi;
|
||||
|
||||
uses
|
||||
cutils,
|
||||
systems,globals,
|
||||
tgobj,
|
||||
systems,globals,globtype,
|
||||
cgobj,tgobj,
|
||||
cpubase,
|
||||
cgutils,
|
||||
symconst;
|
||||
@ -88,6 +89,14 @@ unit cpupi;
|
||||
para_stack_size := 0;
|
||||
end;
|
||||
|
||||
procedure ti386procinfo.allocate_got_register(list: tasmlist);
|
||||
begin
|
||||
if (target_info.system = system_i386_darwin) and
|
||||
(cs_create_pic in current_settings.moduleswitches) then
|
||||
begin
|
||||
got := cg.getaddressregister(list);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
cprocinfo:=ti386procinfo;
|
||||
|
@ -460,7 +460,7 @@ unit i_bsd;
|
||||
system : system_i386_darwin;
|
||||
name : 'Darwin for i386';
|
||||
shortname : 'Darwin';
|
||||
flags : [tf_p_ext_support,tf_files_case_aware,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels];
|
||||
flags : [tf_p_ext_support,tf_files_case_aware,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_uses_got];
|
||||
cpu : cpu_i386;
|
||||
unit_env : 'BSDUNITS';
|
||||
extradefines : 'UNIX;BSD;HASUNIX';
|
||||
|
@ -113,6 +113,8 @@ interface
|
||||
owner.AsmWrite(gas_regname(segment)+':');
|
||||
if assigned(symbol) then
|
||||
owner.AsmWrite(symbol.name);
|
||||
if assigned(relsymbol) then
|
||||
owner.AsmWrite('-'+relsymbol.name);
|
||||
if ref.refaddr=addr_pic then
|
||||
{$ifdef x86_64}
|
||||
owner.AsmWrite('@GOTPCREL');
|
||||
|
@ -347,6 +347,9 @@ unit cgx86;
|
||||
var
|
||||
hreg : tregister;
|
||||
href : treference;
|
||||
{$ifndef x86_64}
|
||||
add_hreg: boolean;
|
||||
{$endif not x86_64}
|
||||
begin
|
||||
{$ifdef x86_64}
|
||||
{ Only 32bit is allowed }
|
||||
@ -403,18 +406,45 @@ unit cgx86;
|
||||
end;
|
||||
end;
|
||||
{$else x86_64}
|
||||
if (cs_create_pic in current_settings.moduleswitches) and
|
||||
assigned(ref.symbol) and not((ref.symbol.bind=AB_LOCAL) and (ref.symbol.typ in [AT_LABEL,AT_FUNCTION])) then
|
||||
add_hreg:=false;
|
||||
if (target_info.system=system_i386_darwin) then
|
||||
begin
|
||||
if assigned(ref.symbol) and
|
||||
not(assigned(ref.relsymbol)) and
|
||||
((ref.symbol.bind = AB_EXTERNAL) or
|
||||
(cs_create_pic in current_settings.moduleswitches)) then
|
||||
begin
|
||||
if (ref.symbol.bind = AB_EXTERNAL) or
|
||||
((cs_create_pic in current_settings.moduleswitches) and
|
||||
(ref.symbol.bind in [AB_COMMON,AB_GLOBAL])) then
|
||||
begin
|
||||
hreg:=g_indirect_sym_load(list,ref.symbol.name);
|
||||
ref.symbol:=nil;
|
||||
end
|
||||
else
|
||||
begin
|
||||
include(current_procinfo.flags,pi_needs_got);
|
||||
hreg:=current_procinfo.got;
|
||||
ref.relsymbol:=current_procinfo.CurrGOTLabel;
|
||||
end;
|
||||
add_hreg:=true
|
||||
end
|
||||
end
|
||||
else if (cs_create_pic in current_settings.moduleswitches) and
|
||||
assigned(ref.symbol) and
|
||||
not((ref.symbol.bind=AB_LOCAL) and
|
||||
(ref.symbol.typ in [AT_LABEL,AT_FUNCTION])) then
|
||||
begin
|
||||
reference_reset_symbol(href,ref.symbol,0);
|
||||
hreg:=getaddressregister(list);
|
||||
href.refaddr:=addr_pic;
|
||||
href.base:=current_procinfo.got;
|
||||
include(current_procinfo.flags,pi_needs_got);
|
||||
list.concat(taicpu.op_ref_reg(A_MOV,S_L,href,hreg));
|
||||
|
||||
ref.symbol:=nil;
|
||||
add_hreg:=true;
|
||||
end;
|
||||
|
||||
if add_hreg then
|
||||
begin
|
||||
if ref.base=NR_NO then
|
||||
ref.base:=hreg
|
||||
else if ref.index=NR_NO then
|
||||
@ -770,7 +800,29 @@ unit cgx86;
|
||||
begin
|
||||
if assigned(ref.symbol) then
|
||||
begin
|
||||
if (cs_create_pic in current_settings.moduleswitches) then
|
||||
if (target_info.system=system_i386_darwin) and
|
||||
((ref.symbol.bind = AB_EXTERNAL) or
|
||||
(cs_create_pic in current_settings.moduleswitches)) then
|
||||
begin
|
||||
if (ref.symbol.bind = AB_EXTERNAL) or
|
||||
((cs_create_pic in current_settings.moduleswitches) and
|
||||
(ref.symbol.bind in [AB_COMMON,AB_GLOBAL])) then
|
||||
begin
|
||||
reference_reset_base(tmpref,
|
||||
g_indirect_sym_load(list,ref.symbol.name),
|
||||
offset);
|
||||
a_loadaddr_ref_reg(list,tmpref,r);
|
||||
end
|
||||
else
|
||||
begin
|
||||
include(current_procinfo.flags,pi_needs_got);
|
||||
reference_reset_base(tmpref,current_procinfo.got,offset);
|
||||
tmpref.symbol:=symbol;
|
||||
tmpref.relsymbol:=current_procinfo.CurrGOTLabel;
|
||||
list.concat(Taicpu.op_ref_reg(A_LEA,tcgsize2opsize[OS_ADDR],tmpref,r));
|
||||
end;
|
||||
end
|
||||
else if (cs_create_pic in current_settings.moduleswitches) then
|
||||
begin
|
||||
{$ifdef x86_64}
|
||||
reference_reset_symbol(tmpref,ref.symbol,0);
|
||||
@ -1996,7 +2048,13 @@ unit cgx86;
|
||||
got loaded
|
||||
}
|
||||
g_maybe_got_init(list);
|
||||
ref.refaddr:=addr_pic;
|
||||
if (target_info.system<>system_i386_darwin) then
|
||||
ref.refaddr:=addr_pic
|
||||
else
|
||||
begin
|
||||
ref.refaddr:=addr_no;
|
||||
ref.relsymbol:=current_procinfo.CurrGOTLabel;
|
||||
end
|
||||
end
|
||||
else
|
||||
ref.refaddr:=addr_full;
|
||||
|
Loading…
Reference in New Issue
Block a user