+ 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:
sergei 2014-02-26 14:54:47 +00:00
parent 31d160aaf5
commit 46f8e78d1f
6 changed files with 49 additions and 3 deletions

View File

@ -137,7 +137,10 @@ interface
aitconst_64bit_unaligned,
{ i8086 far pointer; emits: 'DW symbol, SEG symbol' }
aitconst_farptr,
aitconst_got
{ offset of symbol's GOT slot in GOT }
aitconst_got,
{ offset of symbol itself from GOT }
aitconst_gotoff_symbol
);
const
@ -1838,6 +1841,8 @@ implementation
result:=LengthSleb128(value);
aitconst_half16bit:
result:=2;
aitconst_gotoff_symbol:
result:=4;
else
internalerror(200603253);
end;

View File

@ -951,6 +951,32 @@ implementation
AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
Asmln;
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_sleb128bit,
{$ifdef cpu64bitaddr}

View File

@ -1488,6 +1488,8 @@ Implementation
{ Required for DWARF2 support under Windows }
ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_SECREL32);
end;
aitconst_gotoff_symbol:
ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_GOTOFF);
aitconst_uleb128bit,
aitconst_sleb128bit :
begin

View File

@ -110,6 +110,8 @@ implementation
result:=R_386_GOTPC;
RELOC_PLT32 :
result:=R_386_PLT32;
RELOC_GOTOFF:
result:=R_386_GOTOFF;
else
result:=0;
InternalError(2012082301);

View File

@ -71,6 +71,7 @@ var
href: treference;
jumpsegment: TAsmlist;
opcgsize: tcgsize;
labeltyp: taiconst_type;
procedure genitem(t: pcaselabel);
var
@ -80,9 +81,9 @@ var
genitem(t^.less);
{ fill possible hole }
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
jumpSegment.concat(Tai_const.Create_sym(blocklabel(t^.blockid)));
jumpSegment.concat(Tai_const.Create_type_sym(labeltyp,blocklabel(t^.blockid)));
last := t^._high;
if assigned(t^.greater) then
genitem(t^.greater);
@ -108,6 +109,14 @@ begin
jmpreg := cg.getaddressregister(current_asmdata.CurrAsmList);
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));
{ Delay slot }
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_NOP));

View File

@ -84,6 +84,8 @@ interface
RELOC_NONE,
{ Darwin relocation, using PAIR }
RELOC_PIC_PAIR,
{ Relative to GOT/gp }
RELOC_GOTOFF,
{ Untranslated target-specific value }
RELOC_RAW
);