1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[RelocationResolver] Support R_PPC_REL32 & R_PPC64_REL{32,64}

This suppresses `failed to compute relocation: R_PPC_REL32, Invalid data was encountered while parsing the file`
and its 64-bit variants when running llvm-dwarfdump on a PowerPC object file with .eh_frame

Unfortunately it is difficult to test the computation:
DWARFDataExtractor::getEncodedPointer does not use the relocated value
and even if it does, we need to teach llvm-dwarfdump --eh-frame to do
some linker job to report a reasonable address.
This commit is contained in:
Fangrui Song 2020-07-17 23:29:50 -07:00
parent 1fa6761405
commit 07079947f8
2 changed files with 57 additions and 2 deletions

View File

@ -152,6 +152,8 @@ static bool supportsPPC64(uint64_t Type) {
switch (Type) {
case ELF::R_PPC64_ADDR32:
case ELF::R_PPC64_ADDR64:
case ELF::R_PPC64_REL32:
case ELF::R_PPC64_REL64:
return true;
default:
return false;
@ -164,6 +166,10 @@ static uint64_t resolvePPC64(RelocationRef R, uint64_t S, uint64_t A) {
return (S + getELFAddend(R)) & 0xFFFFFFFF;
case ELF::R_PPC64_ADDR64:
return S + getELFAddend(R);
case ELF::R_PPC64_REL32:
return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF;
case ELF::R_PPC64_REL64:
return S + getELFAddend(R) - R.getOffset();
default:
llvm_unreachable("Invalid relocation type");
}
@ -259,12 +265,22 @@ static uint64_t resolveX86(RelocationRef R, uint64_t S, uint64_t A) {
}
static bool supportsPPC32(uint64_t Type) {
return Type == ELF::R_PPC_ADDR32;
switch (Type) {
case ELF::R_PPC_ADDR32:
case ELF::R_PPC_REL32:
return true;
default:
return false;
}
}
static uint64_t resolvePPC32(RelocationRef R, uint64_t S, uint64_t A) {
if (R.getType() == ELF::R_PPC_ADDR32)
switch (R.getType()) {
case ELF::R_PPC_ADDR32:
return (S + getELFAddend(R)) & 0xFFFFFFFF;
case ELF::R_PPC_REL32:
return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF;
}
llvm_unreachable("Invalid relocation type");
}

View File

@ -0,0 +1,39 @@
; RUN: llc -filetype=obj -mtriple=powerpc %s -o %t32.o
; RUN: llvm-readobj -r %t32.o | FileCheck %s --check-prefix=PPC_REL
; RUN: llvm-dwarfdump --eh-frame %t32.o 2>&1 | FileCheck %s --check-prefix=PPC
; PPC_REL: R_PPC_REL32 .text 0x0
; PPC_REL-NEXT: R_PPC_REL32 .text 0x4
; PPC-NOT: warning:
; PPC: FDE cie=00000000 pc=00000000...00000004
;; TODO Take relocation into consideration
; PPC: FDE cie=00000000 pc=00000000...00000004
; RUN: llc -filetype=obj -mtriple=ppc64 %s -o %t64.o
; RUN: llvm-readobj -r %t64.o | FileCheck %s --check-prefix=PPC64_REL
; RUN: llvm-dwarfdump --eh-frame %t64.o 2>&1 | FileCheck %s --check-prefix=PPC64
; PPC64_REL: R_PPC64_REL32 .text 0x0
; PPC64_REL-NEXT: R_PPC64_REL32 .text 0x10
; PPC64-NOT: warning:
; PPC64: FDE cie=00000000 pc=00000000...00000010
; PPC64: FDE cie=00000000 pc=00000000...00000010
; RUN: llc -filetype=obj -mtriple=ppc64le -code-model=large %s -o %t64l.o
; RUN: llvm-readobj -r %t64l.o | FileCheck %s --check-prefix=PPC64L_REL
; RUN: llvm-dwarfdump --eh-frame %t64l.o 2>&1 | FileCheck %s --check-prefix=PPC64
; PPC64L_REL: R_PPC64_REL64 .text 0x0
; PPC64L_REL-NEXT: R_PPC64_REL64 .text 0x10
define void @foo() {
entry:
ret void
}
define void @bar() {
entry:
ret void
}