diff options
author | sergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2012-12-01 13:38:28 +0000 |
---|---|---|
committer | sergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2012-12-01 13:38:28 +0000 |
commit | 71263025e1ebfeee8ea80cb7107245746c9e18c7 (patch) | |
tree | a0d7a0209f4a7e147aad16f927455ddf1420dd8d /compiler/ogelf.pas | |
parent | 0bbc6eb29199695fed610d04d5726b3d44b47878 (diff) | |
download | fpc-71263025e1ebfeee8ea80cb7107245746c9e18c7.tar.gz |
+ Allow TObjRelocation to be created without a symbol, such relocations are being used to tag specific positions on non-x86 targets.
* Write relocation format dependent dynamic tags based on actual sh_type of dynamic relocation sections, instead of global relocs_use_addend flag.
* Don't write DT_REL[A]COUNT tag if .rel[a].dyn section is not present.
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@23083 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/ogelf.pas')
-rw-r--r-- | compiler/ogelf.pas | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/compiler/ogelf.pas b/compiler/ogelf.pas index 12fb241f86..b7503f0c7a 100644 --- a/compiler/ogelf.pas +++ b/compiler/ogelf.pas @@ -1536,10 +1536,11 @@ implementation if relsym>=syms then InternalError(2012060204); p:=TObjSymbol(FSymTbl[relsym]); - if assigned(p) then + { Some relocations (e.g. R_ARM_V4BX) don't use a symbol at all } + if assigned(p) or (relsym=0) then begin objrel:=TObjRelocation.CreateRaw(rel.address-secrec.sec.mempos,p,reltyp); - if relocs_use_addend then + if (secrec.relentsize=3*sizeof(pint)) then objrel.orgsize:=rel.addend; { perform target-specific actions } ElfTarget.loadreloc(objrel); @@ -3036,6 +3037,8 @@ implementation relcnttags: array[boolean] of longword=(DT_RELCOUNT,DT_RELACOUNT); procedure TElfExeOutput.FinishDynamicTags; + var + rela: boolean; begin if assigned(dynsymtable) then writeDynTag(DT_STRSZ,dynsymtable.fstrsec.size); @@ -3046,18 +3049,19 @@ implementation if Assigned(pltrelocsec) and (pltrelocsec.size>0) then begin writeDynTag(DT_PLTRELSZ,pltrelocsec.Size); - writeDynTag(DT_PLTREL,pltreltags[relocs_use_addend]); + writeDynTag(DT_PLTREL,pltreltags[pltrelocsec.shtype=SHT_RELA]); writeDynTag(DT_JMPREL,pltrelocsec); end; if Assigned(dynrelocsec) and (dynrelocsec.size>0) then begin - writeDynTag(pltreltags[relocs_use_addend],dynrelocsec); - writeDynTag(relsztags[relocs_use_addend],dynrelocsec.Size); - writeDynTag(relenttags[relocs_use_addend],dynrelocsec.shentsize); + rela:=(dynrelocsec.shtype=SHT_RELA); + writeDynTag(pltreltags[rela],dynrelocsec); + writeDynTag(relsztags[rela],dynrelocsec.Size); + writeDynTag(relenttags[rela],dynrelocsec.shentsize); + if (relative_reloc_count>0) then + writeDynTag(relcnttags[rela],relative_reloc_count); end; - if (relative_reloc_count>0) then - writeDynTag(relcnttags[relocs_use_addend],relative_reloc_count); writeDynTag(DT_NULL,0); end; |