mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 19:11:03 +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
@ -49,6 +49,7 @@ implementation
|
|||||||
stubcount: longint;
|
stubcount: longint;
|
||||||
trampolinesection: TObjSection;
|
trampolinesection: TObjSection;
|
||||||
procedure MaybeWriteGOTEntry(relocval:aint;objsym:TObjSymbol);
|
procedure MaybeWriteGOTEntry(relocval:aint;objsym:TObjSymbol);
|
||||||
|
procedure MaybeWriteTLSIEGotEntry(relocval:aint;objsym:TObjSymbol);
|
||||||
procedure CreatePICStub(objsym:TObjSymbol);
|
procedure CreatePICStub(objsym:TObjSymbol);
|
||||||
protected
|
protected
|
||||||
procedure PrepareGOT;override;
|
procedure PrepareGOT;override;
|
||||||
@ -225,9 +226,18 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
function elf_mips_loadsection(objinput:TElfObjInput;objdata:TObjData;const shdr:TElfsechdr;shindex:longint):boolean;
|
function elf_mips_loadsection(objinput:TElfObjInput;objdata:TObjData;const shdr:TElfsechdr;shindex:longint):boolean;
|
||||||
|
var
|
||||||
|
ri: TElfReginfo;
|
||||||
begin
|
begin
|
||||||
case shdr.sh_type of
|
case shdr.sh_type of
|
||||||
SHT_MIPS_REGINFO:
|
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;
|
result:=true;
|
||||||
else
|
else
|
||||||
writeln('elf_mips_loadsection: ',hexstr(shdr.sh_type,8),' ',objdata.name);
|
writeln('elf_mips_loadsection: ',hexstr(shdr.sh_type,8),' ',objdata.name);
|
||||||
@ -555,6 +565,31 @@ implementation
|
|||||||
end;
|
end;
|
||||||
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);
|
procedure TElfExeOutputMIPS.CreatePICStub(objsym:TObjSymbol);
|
||||||
var
|
var
|
||||||
textsec,newsec:TObjSection;
|
textsec,newsec:TObjSection;
|
||||||
@ -722,6 +757,9 @@ implementation
|
|||||||
local_got_relocs.add(objreloc);
|
local_got_relocs.add(objreloc);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
R_MIPS_TLS_GOTTPREL:
|
||||||
|
inherited AllocGOTSlot(objreloc.symbol);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -918,6 +956,34 @@ implementation
|
|||||||
//TODO: check overflow
|
//TODO: check overflow
|
||||||
address:=(address and $FFFF0000) or ((((SmallInt(address) shl 2)+relocval-curloc) shr 2) and $FFFF);
|
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 }
|
R_MIPS_JALR: {optimization hint, ignore for now }
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
|
@ -76,6 +76,9 @@ interface
|
|||||||
public
|
public
|
||||||
ident: TElfIdent;
|
ident: TElfIdent;
|
||||||
flags: longword;
|
flags: longword;
|
||||||
|
{$ifdef mips}
|
||||||
|
gp_value: longword;
|
||||||
|
{$endif mips}
|
||||||
constructor create(const n:string);override;
|
constructor create(const n:string);override;
|
||||||
function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
|
function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
|
||||||
procedure CreateDebugSections;override;
|
procedure CreateDebugSections;override;
|
||||||
@ -148,6 +151,7 @@ interface
|
|||||||
class function CanReadObjData(AReader:TObjectreader):boolean;override;
|
class function CanReadObjData(AReader:TObjectreader):boolean;override;
|
||||||
function CreateSection(const shdr:TElfsechdr;index:longint;objdata:TObjData;
|
function CreateSection(const shdr:TElfsechdr;index:longint;objdata:TObjData;
|
||||||
out secname:string):TElfObjSection;
|
out secname:string):TElfObjSection;
|
||||||
|
function ReadBytes(offs:longint;out buf;len:longint):boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TElfVersionDef = class(TFPHashObject)
|
TElfVersionDef = class(TFPHashObject)
|
||||||
@ -1474,6 +1478,13 @@ implementation
|
|||||||
end;
|
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);
|
procedure TElfObjInput.LoadSection(const shdr:TElfsechdr;index:longint;objdata:tobjdata);
|
||||||
var
|
var
|
||||||
sec: TElfObjSection;
|
sec: TElfObjSection;
|
||||||
|
Loading…
Reference in New Issue
Block a user