summaryrefslogtreecommitdiff
path: root/compiler/ogelf.pas
diff options
context:
space:
mode:
authorsergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2>2012-12-01 13:38:28 +0000
committersergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2>2012-12-01 13:38:28 +0000
commit71263025e1ebfeee8ea80cb7107245746c9e18c7 (patch)
treea0d7a0209f4a7e147aad16f927455ddf1420dd8d /compiler/ogelf.pas
parent0bbc6eb29199695fed610d04d5726b3d44b47878 (diff)
downloadfpc-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.pas20
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;