mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-01 08:45:58 +02:00
+ Support dynamic copy relocations.
* For unresolved weak symbols, provide dynamic binding only if they are referenced via GOT or PLT (ld-compatible behavior). * Made more TElfExeOutput properties/methods usable by descendant classes. * x86_64/cpuelf.pas: some refactoring, handle DTPOFF relocations, prohibit TPOFF relocations in shared objects. * i386/cpuelf.pas: set symref_from_text flags for copy relocations to work correctly. git-svn-id: trunk@23375 -
This commit is contained in:
parent
a1503b51f2
commit
af4935e346
@ -210,6 +210,20 @@ implementation
|
|||||||
objsym.refs:=objsym.refs or symref_plt;
|
objsym.refs:=objsym.refs or symref_plt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
R_386_32:
|
||||||
|
if (oso_executable in objsec.SecOptions) or
|
||||||
|
not (oso_write in objsec.SecOptions) then
|
||||||
|
begin
|
||||||
|
if assigned(objreloc.symbol) and assigned(objreloc.symbol.exesymbol) then
|
||||||
|
begin
|
||||||
|
objsym:=objreloc.symbol.exesymbol.ObjSymbol;
|
||||||
|
objsym.refs:=objsym.refs or symref_from_text;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
case reltyp of
|
||||||
|
|
||||||
R_386_TLS_IE:
|
R_386_TLS_IE:
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
@ -228,7 +228,6 @@ interface
|
|||||||
shoffset: aword;
|
shoffset: aword;
|
||||||
gotwritten: boolean;
|
gotwritten: boolean;
|
||||||
{ dynamic linking }
|
{ dynamic linking }
|
||||||
dynamiclink: boolean;
|
|
||||||
dynsymnames: Plongword;
|
dynsymnames: Plongword;
|
||||||
dynsymtable: TElfSymtab;
|
dynsymtable: TElfSymtab;
|
||||||
interpobjsec: TObjSection;
|
interpobjsec: TObjSection;
|
||||||
@ -241,7 +240,7 @@ interface
|
|||||||
dynamicsec,
|
dynamicsec,
|
||||||
hashobjsec: TElfObjSection;
|
hashobjsec: TElfObjSection;
|
||||||
neededlist: TFPHashList;
|
neededlist: TFPHashList;
|
||||||
gotsize: aword;
|
dyncopysyms: TFPObjectList;
|
||||||
dynrelsize: aword;
|
dynrelsize: aword;
|
||||||
|
|
||||||
function AttachSection(objsec:TObjSection):TElfExeSection;
|
function AttachSection(objsec:TObjSection):TElfExeSection;
|
||||||
@ -257,12 +256,13 @@ interface
|
|||||||
procedure MapSectionsToSegments;
|
procedure MapSectionsToSegments;
|
||||||
procedure WriteStaticSymtable;
|
procedure WriteStaticSymtable;
|
||||||
procedure InitDynlink;
|
procedure InitDynlink;
|
||||||
procedure PrepareGOT;
|
|
||||||
protected
|
protected
|
||||||
|
dynamiclink: boolean;
|
||||||
hastextrelocs: boolean;
|
hastextrelocs: boolean;
|
||||||
gotsymbol: TObjSymbol;
|
gotsymbol: TObjSymbol;
|
||||||
dynsymlist: TFPObjectList;
|
dynsymlist: TFPObjectList;
|
||||||
gotobjsec: TObjSection;
|
gotobjsec: TObjSection;
|
||||||
|
dynbssobjsec,
|
||||||
pltobjsec,
|
pltobjsec,
|
||||||
gotpltobjsec,
|
gotpltobjsec,
|
||||||
pltrelocsec,
|
pltrelocsec,
|
||||||
@ -271,7 +271,9 @@ interface
|
|||||||
dynreloclist: TFPObjectList;
|
dynreloclist: TFPObjectList;
|
||||||
tlsseg: TElfSegment;
|
tlsseg: TElfSegment;
|
||||||
relative_reloc_count: longint;
|
relative_reloc_count: longint;
|
||||||
function AllocGOTSlot(objsym: TObjSymbol):boolean;
|
gotsize: aword;
|
||||||
|
procedure PrepareGOT;virtual;
|
||||||
|
function AllocGOTSlot(objsym: TObjSymbol):boolean;virtual;
|
||||||
procedure CreateGOTSection;virtual;
|
procedure CreateGOTSection;virtual;
|
||||||
procedure make_dynamic_if_undefweak(exesym:TExeSymbol);
|
procedure make_dynamic_if_undefweak(exesym:TExeSymbol);
|
||||||
procedure WriteDynRelocEntry(dataofs:aword;typ:byte;symidx:aword;addend:aword);
|
procedure WriteDynRelocEntry(dataofs:aword;typ:byte;symidx:aword;addend:aword);
|
||||||
@ -1821,12 +1823,6 @@ implementation
|
|||||||
if dynndx=0 then
|
if dynndx=0 then
|
||||||
InternalError(2012071401);
|
InternalError(2012071401);
|
||||||
|
|
||||||
{ for DSO, we aren't interested in actual sections, but need to a dummy one
|
|
||||||
to maintain integrity. }
|
|
||||||
objsec:=TElfObjSection.create_ext(objdata,'*DSO*',SHT_PROGBITS,0,0,0);
|
|
||||||
for i:=1 to nsects-1 do
|
|
||||||
FSecTbl[i].sec:=objsec;
|
|
||||||
|
|
||||||
{ load the symtable }
|
{ load the symtable }
|
||||||
FReader.Seek(symtaboffset+sizeof(TElfSymbol));
|
FReader.Seek(symtaboffset+sizeof(TElfSymbol));
|
||||||
LoadSymbols(objdata,syms,localsyms);
|
LoadSymbols(objdata,syms,localsyms);
|
||||||
@ -1941,6 +1937,7 @@ implementation
|
|||||||
|
|
||||||
destructor TElfExeOutput.Destroy;
|
destructor TElfExeOutput.Destroy;
|
||||||
begin
|
begin
|
||||||
|
dyncopysyms.Free;
|
||||||
neededlist.Free;
|
neededlist.Free;
|
||||||
segmentlist.Free;
|
segmentlist.Free;
|
||||||
dynsymlist.Free;
|
dynsymlist.Free;
|
||||||
@ -2180,6 +2177,7 @@ implementation
|
|||||||
exit;
|
exit;
|
||||||
gotobjsec.alloc(sizeof(pint));
|
gotobjsec.alloc(sizeof(pint));
|
||||||
exesym.GotOffset:=gotobjsec.size;
|
exesym.GotOffset:=gotobjsec.size;
|
||||||
|
make_dynamic_if_undefweak(exesym);
|
||||||
{ In shared library, every GOT entry needs a RELATIVE dynamic reloc,
|
{ In shared library, every GOT entry needs a RELATIVE dynamic reloc,
|
||||||
imported/exported symbols need GLOB_DAT instead. For executables,
|
imported/exported symbols need GLOB_DAT instead. For executables,
|
||||||
only the latter applies. }
|
only the latter applies. }
|
||||||
@ -2266,6 +2264,15 @@ implementation
|
|||||||
begin
|
begin
|
||||||
exesym.State:=symstate_defined;
|
exesym.State:=symstate_defined;
|
||||||
exesym.dynindex:=dynsymlist.Add(exesym)+1;
|
exesym.dynindex:=dynsymlist.Add(exesym)+1;
|
||||||
|
{ The original binding, value and section of external symbol
|
||||||
|
must be preserved, therefore resolving directly to .so symbol
|
||||||
|
hurts more than it helps. Copy type and size, and store .so
|
||||||
|
symbol in objsym.indsymbol for later use. }
|
||||||
|
exesym.ObjSymbol.typ:=objsym.typ;
|
||||||
|
if objsym.typ<>AT_FUNCTION then
|
||||||
|
exesym.ObjSymbol.size:=objsym.size;
|
||||||
|
exesym.ObjSymbol.indsymbol:=objsym;
|
||||||
|
objsym.ExeSymbol:=exesym;
|
||||||
needed:=true;
|
needed:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2368,8 +2375,10 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if exesym.dynindex<>0 then
|
if exesym.dynindex<>0 then
|
||||||
InternalError(2012062301);
|
InternalError(2012062301);
|
||||||
exesym.dynindex:=dynsymlist.add(exesym)+1;
|
{ Weak-referenced symbols are changed into dynamic ones
|
||||||
exesym.state:=symstate_defined;
|
only if referenced through GOT or PLT (this is BFD-compatible) }
|
||||||
|
if exesym.state<>symstate_undefweak then
|
||||||
|
exesym.dynindex:=dynsymlist.add(exesym)+1;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
UnresolvedExeSymbols[i]:=nil;
|
UnresolvedExeSymbols[i]:=nil;
|
||||||
@ -2386,21 +2395,44 @@ implementation
|
|||||||
if assigned(exesym.ObjSymbol.objsection) then // an exported symbol
|
if assigned(exesym.ObjSymbol.objsection) then // an exported symbol
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
{ if there's no PLT references to symbol, then PLT entry isn't needed }
|
if ((exesym.ObjSymbol.refs and symref_plt)<>0) or
|
||||||
{ !! Does not work correctly yet !! }
|
((exesym.ObjSymbol.typ=AT_FUNCTION) and (not IsSharedLibrary)) then
|
||||||
// if (exesym.objsymbol.refs and symref_plt)=0 then
|
begin
|
||||||
// continue;
|
make_dynamic_if_undefweak(exesym);
|
||||||
|
|
||||||
{ This symbol has a valid address to which relocations are resolved,
|
{ This symbol has a valid address to which relocations are resolved,
|
||||||
but it remains (weak)external when written to dynamic symtable. }
|
but it remains (weak)external when written to dynamic symtable. }
|
||||||
objsym:=internalobjdata.CreateSymbol(exesym.name);
|
objsym:=internalobjdata.CreateSymbol(exesym.name);
|
||||||
objsym.typ:=AT_FUNCTION;
|
objsym.typ:=AT_FUNCTION;
|
||||||
objsym.bind:=exesym.ObjSymbol.bind; { AB_EXTERNAL or AB_WEAK_EXTERNAL }
|
objsym.bind:=exesym.ObjSymbol.bind; { AB_EXTERNAL or AB_WEAK_EXTERNAL }
|
||||||
objsym.offset:=pltobjsec.size;
|
objsym.indsymbol:=exesym.ObjSymbol.indsymbol;
|
||||||
objsym.objsection:=pltobjsec;
|
objsym.offset:=pltobjsec.size;
|
||||||
exesym.ObjSymbol:=objsym;
|
objsym.objsection:=pltobjsec;
|
||||||
|
objsym.exesymbol:=exesym;
|
||||||
|
exesym.ObjSymbol:=objsym;
|
||||||
|
|
||||||
WritePLTEntry(exesym);
|
WritePLTEntry(exesym);
|
||||||
|
end
|
||||||
|
else if ((exesym.ObjSymbol.refs and symref_from_text)<>0) and
|
||||||
|
(exesym.ObjSymbol.typ<>AT_FUNCTION) and (not IsSharedLibrary) and
|
||||||
|
(exesym.state<>symstate_undefweak) then
|
||||||
|
begin
|
||||||
|
if exesym.ObjSymbol.size=0 then
|
||||||
|
Comment(v_error,'Dynamic variable '+exesym.name+' has zero size');
|
||||||
|
internalobjdata.setSection(dynbssobjsec);
|
||||||
|
internalobjdata.allocalign(var_align(exesym.ObjSymbol.size));
|
||||||
|
objsym:=internalobjdata.SymbolDefine(exesym.name,AB_GLOBAL,AT_DATA);
|
||||||
|
objsym.size:=exesym.ObjSymbol.size;
|
||||||
|
objsym.indsymbol:=exesym.ObjSymbol.indsymbol;
|
||||||
|
exesym.ObjSymbol:=objsym;
|
||||||
|
objsym.exesymbol:=exesym;
|
||||||
|
dynbssobjsec.alloc(objsym.size);
|
||||||
|
{ allocate space for R_xx_COPY relocation for this symbol;
|
||||||
|
we'll create it later, to be consistent with "-z combreloc" semantics }
|
||||||
|
dyncopysyms.add(objsym);
|
||||||
|
dynrelocsec.alloc(dynrelocsec.shentsize);
|
||||||
|
inc(dynrelsize,dynrelocsec.shentsize);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Handle indirect symbols }
|
{ Handle indirect symbols }
|
||||||
@ -2439,7 +2471,8 @@ implementation
|
|||||||
(.got, .rel[a].dyn, .rel[a].plt (includes .rel[a].iplt) and .hash }
|
(.got, .rel[a].dyn, .rel[a].plt (includes .rel[a].iplt) and .hash }
|
||||||
if gotobjsec.size<>0 then
|
if gotobjsec.size<>0 then
|
||||||
Exclude(gotobjsec.ExeSection.SecOptions,oso_disabled);
|
Exclude(gotobjsec.ExeSection.SecOptions,oso_disabled);
|
||||||
if assigned(dynrelocsec) and (dynrelocsec.size<>0) then
|
if assigned(dynrelocsec) and
|
||||||
|
((dynrelocsec.size<>0) or (dyncopysyms.count<>0)) then
|
||||||
Exclude(dynrelocsec.ExeSection.SecOptions,oso_disabled);
|
Exclude(dynrelocsec.ExeSection.SecOptions,oso_disabled);
|
||||||
if assigned(pltrelocsec) and (pltrelocsec.size>0) then
|
if assigned(pltrelocsec) and (pltrelocsec.size>0) then
|
||||||
Exclude(pltrelocsec.ExeSection.SecOptions,oso_disabled);
|
Exclude(pltrelocsec.ExeSection.SecOptions,oso_disabled);
|
||||||
@ -2568,9 +2601,10 @@ implementation
|
|||||||
|
|
||||||
if (not gotwritten) then
|
if (not gotwritten) then
|
||||||
begin
|
begin
|
||||||
{ reset size of .got and .rel[a].dyn, they will be refilled while fixing up relocations }
|
{ Reset size of .got and .rel[a].dyn, they will be refilled while fixing up relocations.
|
||||||
|
For .got, consider already written reserved entries. }
|
||||||
if assigned(gotobjsec) then
|
if assigned(gotobjsec) then
|
||||||
gotobjsec.size:=0;
|
gotobjsec.size:=gotobjsec.data.size;
|
||||||
if assigned(dynrelocsec) then
|
if assigned(dynrelocsec) then
|
||||||
begin
|
begin
|
||||||
dynrelocsec.size:=0;
|
dynrelocsec.size:=0;
|
||||||
@ -2615,6 +2649,7 @@ implementation
|
|||||||
exesec: TExeSection;
|
exesec: TExeSection;
|
||||||
seg: TElfSegment;
|
seg: TElfSegment;
|
||||||
objreloc: TObjRelocation;
|
objreloc: TObjRelocation;
|
||||||
|
objsym: TObjSymbol;
|
||||||
begin
|
begin
|
||||||
gotwritten:=true;
|
gotwritten:=true;
|
||||||
{ If target does not support sorted relocations, it is expected to write the
|
{ If target does not support sorted relocations, it is expected to write the
|
||||||
@ -2623,6 +2658,14 @@ implementation
|
|||||||
should remain. }
|
should remain. }
|
||||||
if assigned(dynrelocsec) then
|
if assigned(dynrelocsec) then
|
||||||
begin
|
begin
|
||||||
|
{ Append R_xx_COPY relocations }
|
||||||
|
for i:=0 to dyncopysyms.count-1 do
|
||||||
|
begin
|
||||||
|
objsym:=TObjSymbol(dyncopysyms[i]);
|
||||||
|
dynreloclist.Add(TObjRelocation.CreateRaw(objsym.address,objsym,ElfTarget.dyn_reloc_codes[dr_copy]));
|
||||||
|
end;
|
||||||
|
dyncopysyms.Clear;
|
||||||
|
|
||||||
if (dynrelocsec.size+(dynreloclist.count*dynrelocsec.shentsize)<>dynrelsize) then
|
if (dynrelocsec.size+(dynreloclist.count*dynrelocsec.shentsize)<>dynrelsize) then
|
||||||
InternalError(2012110601);
|
InternalError(2012110601);
|
||||||
{ Write out non-RELATIVE dynamic relocations
|
{ Write out non-RELATIVE dynamic relocations
|
||||||
@ -2742,6 +2785,10 @@ implementation
|
|||||||
dynrelocsec:=TElfObjSection.create_reloc(internalObjData,'.dyn',true);
|
dynrelocsec:=TElfObjSection.create_reloc(internalObjData,'.dyn',true);
|
||||||
dynrelocsec.SecOptions:=[oso_keep];
|
dynrelocsec.SecOptions:=[oso_keep];
|
||||||
|
|
||||||
|
dynbssobjsec:=TElfObjSection.create_ext(internalObjData,'.dynbss',
|
||||||
|
SHT_NOBITS,SHF_ALLOC or SHF_WRITE,sizeof(pint){16??},0);
|
||||||
|
dynbssobjsec.SecOptions:=[oso_keep];
|
||||||
|
|
||||||
dynreloclist:=TFPObjectList.Create(true);
|
dynreloclist:=TFPObjectList.Create(true);
|
||||||
|
|
||||||
symversec:=TElfObjSection.create_ext(internalObjData,'.gnu.version',
|
symversec:=TElfObjSection.create_ext(internalObjData,'.gnu.version',
|
||||||
@ -2753,6 +2800,7 @@ implementation
|
|||||||
verneedsec:=TElfObjSection.create_ext(internalObjData,'.gnu.version_r',
|
verneedsec:=TElfObjSection.create_ext(internalObjData,'.gnu.version_r',
|
||||||
SHT_GNU_VERNEED,SHF_ALLOC,sizeof(pint),0);
|
SHT_GNU_VERNEED,SHF_ALLOC,sizeof(pint),0);
|
||||||
verneedsec.SecOptions:=[oso_keep];
|
verneedsec.SecOptions:=[oso_keep];
|
||||||
|
dyncopysyms:=TFPObjectList.Create(False);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1457,6 +1457,7 @@ begin
|
|||||||
Concat(' PROVIDE edata');
|
Concat(' PROVIDE edata');
|
||||||
Concat('ENDEXESECTION');
|
Concat('ENDEXESECTION');
|
||||||
Concat('EXESECTION .bss');
|
Concat('EXESECTION .bss');
|
||||||
|
Concat(' OBJSECTION .dynbss');
|
||||||
Concat(' OBJSECTION .bss*');
|
Concat(' OBJSECTION .bss*');
|
||||||
Concat(' OBJSECTION fpc.reshandles');
|
Concat(' OBJSECTION fpc.reshandles');
|
||||||
Concat(' PROVIDE end');
|
Concat(' PROVIDE end');
|
||||||
|
@ -199,6 +199,7 @@ implementation
|
|||||||
objsym:TObjSymbol;
|
objsym:TObjSymbol;
|
||||||
objreloc:TObjRelocation;
|
objreloc:TObjRelocation;
|
||||||
reltyp:byte;
|
reltyp:byte;
|
||||||
|
externsym,fromtext:boolean;
|
||||||
begin
|
begin
|
||||||
objreloc:=TObjRelocation(objsec.ObjRelocations[idx]);
|
objreloc:=TObjRelocation(objsec.ObjRelocations[idx]);
|
||||||
if (ObjReloc.flags and rf_raw)=0 then
|
if (ObjReloc.flags and rf_raw)=0 then
|
||||||
@ -249,6 +250,7 @@ implementation
|
|||||||
//R_X86_64_TLSGD,
|
//R_X86_64_TLSGD,
|
||||||
//R_X86_64_TLSLD: { TODO: allocate two GOT slots }
|
//R_X86_64_TLSLD: { TODO: allocate two GOT slots }
|
||||||
|
|
||||||
|
R_X86_64_TPOFF32,
|
||||||
{ R_X86_64_32S cannot be used in DSOs at all }
|
{ R_X86_64_32S cannot be used in DSOs at all }
|
||||||
R_X86_64_32S:
|
R_X86_64_32S:
|
||||||
if IsSharedLibrary then
|
if IsSharedLibrary then
|
||||||
@ -275,17 +277,40 @@ implementation
|
|||||||
|
|
||||||
R_X86_64_64:
|
R_X86_64_64:
|
||||||
begin
|
begin
|
||||||
|
fromtext:=(oso_executable in objsec.SecOptions) or
|
||||||
|
not (oso_write in objsec.SecOptions);
|
||||||
|
externsym:=assigned(objreloc.symbol) and
|
||||||
|
assigned(objreloc.symbol.exesymbol) and
|
||||||
|
(objreloc.symbol.exesymbol.dynindex<>0);
|
||||||
|
|
||||||
if IsSharedLibrary then
|
if IsSharedLibrary then
|
||||||
begin
|
begin
|
||||||
if (oso_executable in objsec.SecOptions) or
|
if fromtext then
|
||||||
not (oso_write in objsec.SecOptions) then
|
|
||||||
hastextrelocs:=True;
|
hastextrelocs:=True;
|
||||||
dynrelocsec.alloc(dynrelocsec.shentsize);
|
dynrelocsec.alloc(dynrelocsec.shentsize);
|
||||||
objreloc.flags:=objreloc.flags or rf_dynamic;
|
objreloc.flags:=objreloc.flags or rf_dynamic;
|
||||||
if (objreloc.symbol=nil) or
|
if (not externsym) then
|
||||||
(objreloc.symbol.exesymbol=nil) or
|
|
||||||
(objreloc.symbol.exesymbol.dynindex=0) then
|
|
||||||
Inc(relative_reloc_count);
|
Inc(relative_reloc_count);
|
||||||
|
end
|
||||||
|
else if externsym then
|
||||||
|
// TODO: R_X86_64_32 and R_X86_64_32S here?
|
||||||
|
begin
|
||||||
|
objsym:=objreloc.symbol.ExeSymbol.ObjSymbol;
|
||||||
|
{ If symbol has non-GOT references from readonly sections, then it needs a
|
||||||
|
copy reloc, which eliminates any dynamic relocations to this symbol from
|
||||||
|
writable sections as well. OTOH if it is referenced *only* from writable
|
||||||
|
sections, then it's better not to generate a copy reloc and keep dynamic
|
||||||
|
relocations. The following code is based on assumption that all readonly
|
||||||
|
sections are processed before writable ones (which is true for current
|
||||||
|
segment mapping).
|
||||||
|
For arbitrary segment mapping, this will probably require a separate pass. }
|
||||||
|
if fromtext then
|
||||||
|
objsym.refs:=objsym.refs or symref_from_text
|
||||||
|
else if (objsym.refs and symref_from_text)=0 then
|
||||||
|
begin
|
||||||
|
dynrelocsec.alloc(dynrelocsec.shentsize);
|
||||||
|
objreloc.flags:=objreloc.flags or rf_dynamic;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -403,9 +428,20 @@ implementation
|
|||||||
address:=address+relocval-PC;
|
address:=address+relocval-PC;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
//R_X86_64_DTPOFF64 is possible in data??
|
||||||
|
R_X86_64_DTPOFF32:
|
||||||
|
begin
|
||||||
|
{ In executable it behaves as TPOFF32, but data expressions
|
||||||
|
like ".long foo@dtpoff" resolve to positive offset }
|
||||||
|
if IsSharedLibrary or not (oso_executable in objsec.SecOptions) then
|
||||||
|
address:=address+relocval-tlsseg.MemPos
|
||||||
|
else
|
||||||
|
address:=address+relocval-(tlsseg.MemPos+tlsseg.MemSize);
|
||||||
|
end;
|
||||||
|
|
||||||
R_X86_64_TPOFF32,
|
R_X86_64_TPOFF32,
|
||||||
R_X86_64_TPOFF64:
|
R_X86_64_TPOFF64:
|
||||||
address:=relocval-(tlsseg.MemPos+tlsseg.MemSize);
|
address:=address+relocval-(tlsseg.MemPos+tlsseg.MemSize);
|
||||||
|
|
||||||
R_X86_64_GOTTPOFF,
|
R_X86_64_GOTTPOFF,
|
||||||
R_X86_64_GOTPCREL,
|
R_X86_64_GOTPCREL,
|
||||||
|
Loading…
Reference in New Issue
Block a user