+ x86-64: implemented support for relocation needed by tls threadvars in the binary elf writer

git-svn-id: trunk@43067 -
This commit is contained in:
florian 2019-09-25 21:18:59 +00:00
parent 75216d3309
commit 14b7eaa46f
4 changed files with 63 additions and 21 deletions

View File

@ -60,6 +60,8 @@ interface
{ PIC }
RELOC_GOTPCREL,
RELOC_PLT32,
RELOC_TLSGD,
RELOC_TPOFF,
{$endif x86_64}
{$ifdef i386}
{ PIC }
@ -176,7 +178,9 @@ interface
{ Supports bss-like allocation of data, even though it is written in file (i.e. also has oso_Data) }
oso_sparse_data,
{ Section to support the resolution of multiple symbols with the same name }
oso_comdat
oso_comdat,
{ section containing thread variables }
oso_threadvar
);
TObjSectionOptions = set of TObjSectionOption;
@ -1196,7 +1200,7 @@ implementation
{roData} [oso_Data,oso_load,oso_write],
{roData_norel} [oso_Data,oso_load],
{bss} [oso_load,oso_write],
{threadvar} [oso_load,oso_write],
{threadvar} [oso_load,oso_write,oso_threadvar],
{pdata} [oso_data,oso_load],
{stub} [oso_Data,oso_load,oso_executable],
{data_nonlazy} [oso_Data,oso_load,oso_write],

View File

@ -401,6 +401,8 @@ implementation
Ashflags:=Ashflags or SHF_EXECINSTR;
if oso_write in aoptions then
Ashflags:=Ashflags or SHF_WRITE;
if oso_threadvar in aoptions then
Ashflags:=Ashflags or SHF_TLS;
end;
@ -419,6 +421,8 @@ implementation
include(aoptions,oso_write);
if Ashflags and SHF_EXECINSTR<>0 then
include(aoptions,oso_executable);
if Ashflags and SHF_TLS<>0 then
include(aoptions,oso_threadvar);
end;
@ -575,6 +579,15 @@ implementation
result:=secname+'.'+aname;
exit;
end;
if atype=sec_threadvar then
begin
if (target_info.system in (systems_windows+systems_wince)) then
secname:='.tls'
else if (target_info.system in systems_linux) then
secname:='.tbss';
end;
if create_smartlink_sections and (aname<>'') then
begin
case aorder of
@ -653,7 +666,7 @@ implementation
if assigned(objreloc) then
begin
objreloc.size:=len;
if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif}{$ifdef x86_64},RELOC_GOTPCREL{$endif}] then
if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif}{$ifdef x86_64},RELOC_GOTPCREL,RELOC_TLSGD{$endif}] then
dec(data,len);
if ElfTarget.relocs_use_addend then
begin

View File

@ -1510,7 +1510,7 @@ implementation
end;
top_ref :
begin
if (ref^.refaddr=addr_no)
if (ref^.refaddr in [addr_no{$ifdef x86_64},addr_tpoff{$endif x86_64}])
{$ifdef i386}
or (
(ref^.refaddr in [addr_pic]) and
@ -1519,7 +1519,7 @@ implementation
{$endif i386}
{$ifdef x86_64}
or (
(ref^.refaddr in [addr_pic,addr_pic_no_got]) and
(ref^.refaddr in [addr_pic,addr_pic_no_got,addr_tlsgd]) and
(ref^.base<>NR_NO)
)
{$endif x86_64}
@ -3592,6 +3592,18 @@ implementation
currabsreloc:=RELOC_RELATIVE;
currabsreloc32:=RELOC_RELATIVE;
end
else if oper[opidx]^.ref^.refaddr=addr_tpoff then
begin
currrelreloc:=RELOC_TPOFF;
currabsreloc:=RELOC_TPOFF;
currabsreloc32:=RELOC_TPOFF;
end
else if oper[opidx]^.ref^.refaddr=addr_tlsgd then
begin
currrelreloc:=RELOC_TLSGD;
currabsreloc:=RELOC_TLSGD;
currabsreloc32:=RELOC_TLSGD;
end
else
{$endif x86_64}
begin
@ -3630,22 +3642,22 @@ implementation
procedure objdata_writereloc(Data:TRelocDataInt;len:aword;p:TObjSymbol;Reloctype:TObjRelocationType);
begin
{$ifdef i386}
{ Special case of '_GLOBAL_OFFSET_TABLE_'
which needs a special relocation type R_386_GOTPC }
if assigned (p) and
(p.name='_GLOBAL_OFFSET_TABLE_') and
(tf_pic_uses_got in target_info.flags) then
begin
{ nothing else than a 4 byte relocation should occur
for GOT }
if len<>4 then
Message1(asmw_e_invalid_opcode_and_operands,GetString);
Reloctype:=RELOC_GOTPC;
{ We need to add the offset of the relocation
of _GLOBAL_OFFSET_TABLE symbol within
the current instruction }
inc(data,objdata.currobjsec.size-insoffset);
end;
{ Special case of '_GLOBAL_OFFSET_TABLE_'
which needs a special relocation type R_386_GOTPC }
if assigned (p) and
(p.name='_GLOBAL_OFFSET_TABLE_') and
(tf_pic_uses_got in target_info.flags) then
begin
{ nothing else than a 4 byte relocation should occur
for GOT }
if len<>4 then
Message1(asmw_e_invalid_opcode_and_operands,GetString);
Reloctype:=RELOC_GOTPC;
{ We need to add the offset of the relocation
of _GLOBAL_OFFSET_TABLE symbol within
the current instruction }
inc(data,objdata.currobjsec.size-insoffset);
end;
{$endif i386}
objdata.writereloc(data,len,p,Reloctype);
end;
@ -4534,6 +4546,10 @@ implementation
{$ifdef x86_64}
if oper[opidx]^.ref^.refaddr=addr_pic then
currabsreloc:=RELOC_GOTPCREL
else if oper[opidx]^.ref^.refaddr=addr_tlsgd then
currabsreloc:=RELOC_TLSGD
else if oper[opidx]^.ref^.refaddr=addr_tpoff then
currabsreloc:=RELOC_TPOFF
else
if oper[opidx]^.ref^.base=NR_RIP then
begin

View File

@ -171,6 +171,15 @@ implementation
result:=R_X86_64_GOTPCREL;
RELOC_PLT32 :
result:=R_X86_64_PLT32;
RELOC_TPOFF:
if objrel.size=8 then
result:=R_X86_64_TPOFF64
else if objrel.size=4 then
result:=R_X86_64_TPOFF32
else
InternalError(2019091701);
RELOC_TLSGD:
result:=R_X86_64_TLSGD
else
result:=0;
InternalError(2012082302);