From a7e7d97da692c9723bef01271f6764c25c8b7ca6 Mon Sep 17 00:00:00 2001 From: sergei Date: Mon, 19 Nov 2012 09:07:45 +0000 Subject: [PATCH] * ELF linker: fixed written values of STT_TLS symbols, they must be relative to PT_TLS segment address. * Made name of dynamic interpreter variable, it is now set correctly for each target. - Removed setting header flags for ARM. This functionality belongs to CPU-specific unit anyway, and probably must be implemented using object attributes in modern ABIs. git-svn-id: trunk@23032 - --- compiler/ogelf.pas | 53 +++++++++++++++--------------------- compiler/systems/t_linux.pas | 2 ++ 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/compiler/ogelf.pas b/compiler/ogelf.pas index be8a352abe..ac7a3a0ab2 100644 --- a/compiler/ogelf.pas +++ b/compiler/ogelf.pas @@ -58,6 +58,7 @@ interface kind: TElfSymtabKind; fstrsec: TObjSection; symidx: longint; + tlsbase: aword; constructor create(aObjData:TObjData;aKind:TElfSymtabKind);reintroduce; procedure writeSymbol(objsym:TObjSymbol;nameidx:longword=0); procedure writeInternalSymbol(avalue:aword;astridx:longword;ainfo:byte;ashndx:word); @@ -184,6 +185,7 @@ interface dynsymnames: Plongword; dynsymtable: TElfSymtab; interpobjsec: TObjSection; + FInterpreter: pshortstring; dynamicsec, hashobjsec: TElfObjSection; neededlist: TFPHashList; @@ -239,6 +241,7 @@ interface procedure DataPos_ExeSection(const aname:string);override; function writeData:boolean;override; procedure GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);override; + property interpreter:pshortstring read FInterpreter write FInterpreter; end; var @@ -1159,10 +1162,10 @@ implementation else elfsym.st_name:=nameidx; elfsym.st_size:=objsym.size; + elfsym.st_value:=objsym.address; case objsym.bind of AB_LOCAL : begin - elfsym.st_value:=objsym.address; elfsym.st_info:=STB_LOCAL shl 4; inc(shinfo); end; @@ -1175,19 +1178,13 @@ implementation AB_EXTERNAL : elfsym.st_info:=STB_GLOBAL shl 4; AB_WEAK_EXTERNAL : - begin - elfsym.st_info:=STB_WEAK shl 4; - elfsym.st_value:=objsym.address; - end; + elfsym.st_info:=STB_WEAK shl 4; AB_GLOBAL : - begin - elfsym.st_value:=objsym.address; - elfsym.st_info:=STB_GLOBAL shl 4; - end; + elfsym.st_info:=STB_GLOBAL shl 4; + else + InternalError(2012111801); end; - if (objsym.bind<>AB_EXTERNAL) {and - not(assigned(objsym.objsection) and - not(oso_data in objsym.objsection.secoptions))} then + if (objsym.bind<>AB_EXTERNAL) then begin case objsym.typ of AT_FUNCTION : @@ -1198,6 +1195,7 @@ implementation elfsym.st_info:=elfsym.st_info or STT_TLS; AT_GNU_IFUNC: elfsym.st_info:=elfsym.st_info or STT_GNU_IFUNC; + { other types are implicitly mapped to STT_NOTYPE } end; end; if objsym.bind<>AB_COMMON then @@ -1206,7 +1204,9 @@ implementation begin if assigned(objsym.objsection) and assigned(objsym.objsection.ExeSection) then begin - if (oso_plt in objsym.objsection.SecOptions) then + if (objsym.typ=AT_TLS) then + elfsym.st_value:=elfsym.st_value-tlsbase + else if (oso_plt in objsym.objsection.SecOptions) then elfsym.st_value:=0 else elfsym.st_shndx:=TElfExeSection(objsym.objsection.ExeSection).secshidx; @@ -1302,9 +1302,7 @@ implementation begin with data do begin - { filename entry } - symtabsect.writeInternalSymbol(0,1,STT_FILE,SHN_ABS); - { section } + { section symbols } ObjSectionList.ForEachCall(@section_write_symbol,nil); { First the Local Symbols, this is required by ELF. The localsyms count stored in shinfo is used to skip the local symbols @@ -1414,8 +1412,9 @@ implementation if (target_info.system in systems_linux) and not(cs_executable_stack in current_settings.moduleswitches) then TElfObjSection.create_ext(data,'.note.GNU-stack',SHT_PROGBITS,0,1,0); - { insert filename as first in strtab } + { symbol for filename } symtabsect.fstrsec.writestr(ExtractFileName(current_module.mainsource)); + symtabsect.writeInternalSymbol(0,1,STT_FILE,SHN_ABS); { calc amount of sections we have } nsections:=1; { also create the index in the section header table } @@ -1453,10 +1452,6 @@ implementation header.e_ident[EI_VERSION]:=1; header.e_type:=ET_REL; header.e_machine:=ELFMACHINE; -{$ifdef arm} - if (current_settings.fputype=fpu_soft) then - header.e_flags:=$600; -{$endif arm} header.e_version:=1; header.e_shoff:=shoffset; header.e_shstrndx:=shstrtabsect.index; @@ -2117,6 +2112,7 @@ implementation dynreloclist.Free; if assigned(dynsymnames) then FreeMem(dynsymnames); + stringdispose(FInterpreter); inherited Destroy; end; @@ -2159,10 +2155,6 @@ implementation else header.e_type:=ET_EXEC; header.e_machine:=ELFMACHINE; -{$ifdef arm} - if (current_settings.fputype=fpu_soft) then - header.e_flags:=$600; -{$endif arm} header.e_version:=1; header.e_phoff:=sizeof(TElfHeader); header.e_shoff:=shoffset; @@ -2232,6 +2224,8 @@ implementation sec: TElfExeSection; exesym: TExeSymbol; begin + if assigned(tlsseg) then + symtab.tlsbase:=tlsseg.MemPos; for i:=0 to ExeSectionList.Count-1 do begin sec:=TElfExeSection(ExeSectionList[i]); @@ -2680,6 +2674,8 @@ implementation begin dynrelocsec.size:=0; { write actual .dynsym content (needs valid symbol addresses) } + if assigned(tlsseg) then + dynsymtable.tlsbase:=tlsseg.MemPos; dynsymtable.size:=sizeof(TElfsymbol); for i:=0 to dynsymlist.count-1 do dynsymtable.writeSymbol(TExeSymbol(dynsymlist[i]).objsymbol,dynsymnames[i]); @@ -2828,12 +2824,7 @@ implementation if not IsSharedLibrary then begin interpobjsec:=internalObjData.createsection('.interp',1,[oso_data,oso_load,oso_keep]); - { TODO: supply target-specific default } -{$ifdef x86_64} - interpobjsec.writestr('/lib64/ld-linux-x86-64.so.2'); -{$else} - interpobjsec.writestr('/lib/ld-linux.so.2'); -{$endif x86_64} + interpobjsec.writestr(interpreter^); end; hashobjsec:=TElfObjSection.create_ext(internalObjData,'.hash', diff --git a/compiler/systems/t_linux.pas b/compiler/systems/t_linux.pas index 1543aa5a2b..75c57dd855 100644 --- a/compiler/systems/t_linux.pas +++ b/compiler/systems/t_linux.pas @@ -1216,6 +1216,8 @@ begin AddSharedLibrary('c'); end; + TElfExeOutput(exeoutput).interpreter:=stringdup(dynlinker); + { add objectfiles, start with prt0 always } if not (target_info.system in systems_internal_sysinit) and (prtobj<>'') then LinkScript.Concat('READOBJECT '+ maybequoted(FindObjectFile(prtobj,'',false)));