mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-08 09:26:11 +02:00
+ Support GOT/gp-relative constants in GAS and internal assemblers, MIPS and i386.
* Change MIPS jump tables in PIC mode to use gp-relative constants, making them ABI-compliant and not requiring dynamic relocations. git-svn-id: trunk@26886 -
This commit is contained in:
parent
31d160aaf5
commit
46f8e78d1f
@ -137,7 +137,10 @@ interface
|
|||||||
aitconst_64bit_unaligned,
|
aitconst_64bit_unaligned,
|
||||||
{ i8086 far pointer; emits: 'DW symbol, SEG symbol' }
|
{ i8086 far pointer; emits: 'DW symbol, SEG symbol' }
|
||||||
aitconst_farptr,
|
aitconst_farptr,
|
||||||
aitconst_got
|
{ offset of symbol's GOT slot in GOT }
|
||||||
|
aitconst_got,
|
||||||
|
{ offset of symbol itself from GOT }
|
||||||
|
aitconst_gotoff_symbol
|
||||||
);
|
);
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -1838,6 +1841,8 @@ implementation
|
|||||||
result:=LengthSleb128(value);
|
result:=LengthSleb128(value);
|
||||||
aitconst_half16bit:
|
aitconst_half16bit:
|
||||||
result:=2;
|
result:=2;
|
||||||
|
aitconst_gotoff_symbol:
|
||||||
|
result:=4;
|
||||||
else
|
else
|
||||||
internalerror(200603253);
|
internalerror(200603253);
|
||||||
end;
|
end;
|
||||||
|
@ -951,6 +951,32 @@ implementation
|
|||||||
AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
|
AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
|
||||||
Asmln;
|
Asmln;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
aitconst_gotoff_symbol:
|
||||||
|
begin
|
||||||
|
if (tai_const(hp).sym=nil) then
|
||||||
|
InternalError(2014022601);
|
||||||
|
case target_info.cpu of
|
||||||
|
|
||||||
|
cpu_mipseb,cpu_mipsel:
|
||||||
|
begin
|
||||||
|
AsmWrite(#9'.gpword'#9);
|
||||||
|
AsmWrite(tai_const(hp).sym.name);
|
||||||
|
end;
|
||||||
|
|
||||||
|
cpu_i386:
|
||||||
|
begin
|
||||||
|
AsmWrite(ait_const2str[aitconst_32bit]);
|
||||||
|
AsmWrite(tai_const(hp).sym.name);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
InternalError(2014022602);
|
||||||
|
end;
|
||||||
|
if (tai_const(hp).value<>0) then
|
||||||
|
AsmWrite(tostr_with_plus(tai_const(hp).value));
|
||||||
|
Asmln;
|
||||||
|
end;
|
||||||
|
|
||||||
aitconst_uleb128bit,
|
aitconst_uleb128bit,
|
||||||
aitconst_sleb128bit,
|
aitconst_sleb128bit,
|
||||||
{$ifdef cpu64bitaddr}
|
{$ifdef cpu64bitaddr}
|
||||||
|
@ -1488,6 +1488,8 @@ Implementation
|
|||||||
{ Required for DWARF2 support under Windows }
|
{ Required for DWARF2 support under Windows }
|
||||||
ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_SECREL32);
|
ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_SECREL32);
|
||||||
end;
|
end;
|
||||||
|
aitconst_gotoff_symbol:
|
||||||
|
ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_GOTOFF);
|
||||||
aitconst_uleb128bit,
|
aitconst_uleb128bit,
|
||||||
aitconst_sleb128bit :
|
aitconst_sleb128bit :
|
||||||
begin
|
begin
|
||||||
|
@ -110,6 +110,8 @@ implementation
|
|||||||
result:=R_386_GOTPC;
|
result:=R_386_GOTPC;
|
||||||
RELOC_PLT32 :
|
RELOC_PLT32 :
|
||||||
result:=R_386_PLT32;
|
result:=R_386_PLT32;
|
||||||
|
RELOC_GOTOFF:
|
||||||
|
result:=R_386_GOTOFF;
|
||||||
else
|
else
|
||||||
result:=0;
|
result:=0;
|
||||||
InternalError(2012082301);
|
InternalError(2012082301);
|
||||||
|
@ -71,6 +71,7 @@ var
|
|||||||
href: treference;
|
href: treference;
|
||||||
jumpsegment: TAsmlist;
|
jumpsegment: TAsmlist;
|
||||||
opcgsize: tcgsize;
|
opcgsize: tcgsize;
|
||||||
|
labeltyp: taiconst_type;
|
||||||
|
|
||||||
procedure genitem(t: pcaselabel);
|
procedure genitem(t: pcaselabel);
|
||||||
var
|
var
|
||||||
@ -80,9 +81,9 @@ var
|
|||||||
genitem(t^.less);
|
genitem(t^.less);
|
||||||
{ fill possible hole }
|
{ fill possible hole }
|
||||||
for i := last.svalue+1 to t^._low.svalue-1 do
|
for i := last.svalue+1 to t^._low.svalue-1 do
|
||||||
jumpSegment.concat(Tai_const.Create_sym(elselabel));
|
jumpSegment.concat(Tai_const.Create_type_sym(labeltyp,elselabel));
|
||||||
for i := t^._low.svalue to t^._high.svalue do
|
for i := t^._low.svalue to t^._high.svalue do
|
||||||
jumpSegment.concat(Tai_const.Create_sym(blocklabel(t^.blockid)));
|
jumpSegment.concat(Tai_const.Create_type_sym(labeltyp,blocklabel(t^.blockid)));
|
||||||
last := t^._high;
|
last := t^._high;
|
||||||
if assigned(t^.greater) then
|
if assigned(t^.greater) then
|
||||||
genitem(t^.greater);
|
genitem(t^.greater);
|
||||||
@ -108,6 +109,14 @@ begin
|
|||||||
jmpreg := cg.getaddressregister(current_asmdata.CurrAsmList);
|
jmpreg := cg.getaddressregister(current_asmdata.CurrAsmList);
|
||||||
cg.a_load_ref_reg(current_asmdata.CurrAsmList, OS_ADDR, OS_ADDR, href, jmpreg);
|
cg.a_load_ref_reg(current_asmdata.CurrAsmList, OS_ADDR, OS_ADDR, href, jmpreg);
|
||||||
|
|
||||||
|
if (cs_create_pic in current_settings.moduleswitches) then
|
||||||
|
begin
|
||||||
|
cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,NR_GP,jmpreg,jmpreg);
|
||||||
|
labeltyp:=aitconst_gotoff_symbol;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
labeltyp:=aitconst_ptr;
|
||||||
|
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_JR, jmpreg));
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_JR, jmpreg));
|
||||||
{ Delay slot }
|
{ Delay slot }
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_NOP));
|
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_NOP));
|
||||||
|
@ -84,6 +84,8 @@ interface
|
|||||||
RELOC_NONE,
|
RELOC_NONE,
|
||||||
{ Darwin relocation, using PAIR }
|
{ Darwin relocation, using PAIR }
|
||||||
RELOC_PIC_PAIR,
|
RELOC_PIC_PAIR,
|
||||||
|
{ Relative to GOT/gp }
|
||||||
|
RELOC_GOTOFF,
|
||||||
{ Untranslated target-specific value }
|
{ Untranslated target-specific value }
|
||||||
RELOC_RAW
|
RELOC_RAW
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user