mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-23 02:09:43 +02:00
+ MIPS internal linker: support TLS IE/LE and GPREL32 relocations, is now able to link tw14265.
git-svn-id: trunk@25181 -
This commit is contained in:
parent
11b72b5515
commit
e7f6b06969
compiler
@ -49,6 +49,7 @@ implementation
|
||||
stubcount: longint;
|
||||
trampolinesection: TObjSection;
|
||||
procedure MaybeWriteGOTEntry(relocval:aint;objsym:TObjSymbol);
|
||||
procedure MaybeWriteTLSIEGotEntry(relocval:aint;objsym:TObjSymbol);
|
||||
procedure CreatePICStub(objsym:TObjSymbol);
|
||||
protected
|
||||
procedure PrepareGOT;override;
|
||||
@ -225,9 +226,18 @@ implementation
|
||||
|
||||
|
||||
function elf_mips_loadsection(objinput:TElfObjInput;objdata:TObjData;const shdr:TElfsechdr;shindex:longint):boolean;
|
||||
var
|
||||
ri: TElfReginfo;
|
||||
begin
|
||||
case shdr.sh_type of
|
||||
SHT_MIPS_REGINFO:
|
||||
begin
|
||||
objinput.ReadBytes(shdr.sh_offset,ri,sizeof(ri));
|
||||
MaybeSwapElfReginfo(ri);
|
||||
TElfObjData(objdata).gp_value:=ri.ri_gp_value;
|
||||
result:=true;
|
||||
end;
|
||||
SHT_MIPS_DWARF:
|
||||
result:=true;
|
||||
else
|
||||
writeln('elf_mips_loadsection: ',hexstr(shdr.sh_type,8),' ',objdata.name);
|
||||
@ -555,6 +565,31 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TElfExeOutputMIPS.MaybeWriteTLSIEGotEntry(relocval:aint;objsym:TObjSymbol);
|
||||
var
|
||||
gotoff,tmp:aword;
|
||||
begin
|
||||
gotoff:=objsym.exesymbol.gotoffset;
|
||||
if gotoff=0 then
|
||||
InternalError(2012060903);
|
||||
|
||||
if gotoff=gotobjsec.Data.size+sizeof(pint) then
|
||||
begin
|
||||
tmp:=gotobjsec.mempos+gotoff-sizeof(pint);
|
||||
if (objsym.exesymbol.dynindex>0) then
|
||||
begin
|
||||
gotobjsec.writezeros(sizeof(pint));
|
||||
dynreloclist.Add(TObjRelocation.CreateRaw(tmp,objsym,R_MIPS_TLS_TPREL32));
|
||||
end
|
||||
else
|
||||
begin
|
||||
putword(gotobjsec,relocval);
|
||||
if IsSharedLibrary then
|
||||
dynreloclist.Add(TObjRelocation.CreateRaw(tmp,nil,R_MIPS_TLS_TPREL32));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TElfExeOutputMIPS.CreatePICStub(objsym:TObjSymbol);
|
||||
var
|
||||
textsec,newsec:TObjSection;
|
||||
@ -722,6 +757,9 @@ implementation
|
||||
local_got_relocs.add(objreloc);
|
||||
end;
|
||||
end;
|
||||
|
||||
R_MIPS_TLS_GOTTPREL:
|
||||
inherited AllocGOTSlot(objreloc.symbol);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -918,6 +956,34 @@ implementation
|
||||
//TODO: check overflow
|
||||
address:=(address and $FFFF0000) or ((((SmallInt(address) shl 2)+relocval-curloc) shr 2) and $FFFF);
|
||||
|
||||
R_MIPS_GPREL32:
|
||||
address:=address+relocval+TElfObjData(objsec.objdata).gp_value-gotsymbol.address;
|
||||
|
||||
R_MIPS_TLS_GOTTPREL:
|
||||
begin
|
||||
if IsSharedLibrary then
|
||||
relocval:=relocval-tlsseg.MemPos
|
||||
else
|
||||
relocval:=relocval-(tlsseg.MemPos+TP_OFFSET);
|
||||
MaybeWriteTLSIEGotEntry(relocval,objreloc.symbol);
|
||||
relocval:=-(gotsymbol.offset-(objreloc.symbol.exesymbol.gotoffset-sizeof(pint)));
|
||||
// TODO: check overflow
|
||||
address:=(address and $FFFF0000) or (relocval and $FFFF);
|
||||
end;
|
||||
|
||||
R_MIPS_TLS_TPREL_HI16:
|
||||
begin
|
||||
tmp:=SmallInt(address)+relocval-(tlsseg.MemPos+TP_OFFSET);
|
||||
tmp:=(tmp+$8000) shr 16;
|
||||
address:=(address and $FFFF0000) or (tmp and $FFFF);
|
||||
end;
|
||||
|
||||
R_MIPS_TLS_TPREL_LO16:
|
||||
begin
|
||||
tmp:=SmallInt(address)+relocval-(tlsseg.MemPos+TP_OFFSET);
|
||||
address:=(address and $FFFF0000) or (tmp and $FFFF);
|
||||
end;
|
||||
|
||||
R_MIPS_JALR: {optimization hint, ignore for now }
|
||||
;
|
||||
else
|
||||
|
@ -76,6 +76,9 @@ interface
|
||||
public
|
||||
ident: TElfIdent;
|
||||
flags: longword;
|
||||
{$ifdef mips}
|
||||
gp_value: longword;
|
||||
{$endif mips}
|
||||
constructor create(const n:string);override;
|
||||
function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
|
||||
procedure CreateDebugSections;override;
|
||||
@ -148,6 +151,7 @@ interface
|
||||
class function CanReadObjData(AReader:TObjectreader):boolean;override;
|
||||
function CreateSection(const shdr:TElfsechdr;index:longint;objdata:TObjData;
|
||||
out secname:string):TElfObjSection;
|
||||
function ReadBytes(offs:longint;out buf;len:longint):boolean;
|
||||
end;
|
||||
|
||||
TElfVersionDef = class(TFPHashObject)
|
||||
@ -1474,6 +1478,13 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function TElfObjInput.ReadBytes(offs:longint;out buf;len:longint):boolean;
|
||||
begin
|
||||
FReader.Seek(offs);
|
||||
result:=FReader.Read(buf,len);
|
||||
end;
|
||||
|
||||
|
||||
procedure TElfObjInput.LoadSection(const shdr:TElfsechdr;index:longint;objdata:tobjdata);
|
||||
var
|
||||
sec: TElfObjSection;
|
||||
|
Loading…
Reference in New Issue
Block a user