mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 14:10:41 +00:00
Refactor the RelocVisitor::visit method
This change replaces the brittle if/else chain of string comparisons with a switch statement on the detected target triple, removing the need for testing arbitrary architecture names returned from getFileFormatName, whose primary purpose seems to be for display (user-interface) purposes. The visitor now takes a reference to the object file, rather than its arbitrary file format name to figure out whether the file is a 32 or 64-bit object file and what the detected target triple is. A set of tests have been added to help show that the refactoring processes relocations for the same targets as the original code. Patch by Charlie Turner. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218388 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cfc42962c8
commit
faac033f73
@ -924,6 +924,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
|
||||
default:
|
||||
report_fatal_error("Invalid ELFCLASS!");
|
||||
}
|
||||
case ELF::EM_PPC:
|
||||
return Triple::ppc;
|
||||
case ELF::EM_PPC64:
|
||||
return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
|
||||
case ELF::EM_S390:
|
||||
|
@ -40,16 +40,18 @@ struct RelocToApply {
|
||||
/// @brief Base class for object file relocation visitors.
|
||||
class RelocVisitor {
|
||||
public:
|
||||
explicit RelocVisitor(StringRef FileFormat)
|
||||
: FileFormat(FileFormat), HasError(false) {}
|
||||
explicit RelocVisitor(ObjectFile &Obj)
|
||||
: ObjToVisit(Obj), HasError(false) {}
|
||||
|
||||
// TODO: Should handle multiple applied relocations via either passing in the
|
||||
// previously computed value or just count paired relocations as a single
|
||||
// visit.
|
||||
RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0,
|
||||
uint64_t Value = 0) {
|
||||
if (FileFormat == "ELF64-x86-64") {
|
||||
switch (RelocType) {
|
||||
if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file
|
||||
switch (ObjToVisit.getArch()) {
|
||||
case Triple::x86_64:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_X86_64_NONE:
|
||||
return visitELF_X86_64_NONE(R);
|
||||
case llvm::ELF::R_X86_64_64:
|
||||
@ -63,113 +65,129 @@ public:
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF32-i386") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_386_NONE:
|
||||
return visitELF_386_NONE(R);
|
||||
case llvm::ELF::R_386_32:
|
||||
return visitELF_386_32(R, Value);
|
||||
case llvm::ELF::R_386_PC32:
|
||||
return visitELF_386_PC32(R, Value, SecAddr);
|
||||
}
|
||||
case Triple::aarch64:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_AARCH64_ABS32:
|
||||
return visitELF_AARCH64_ABS32(R, Value);
|
||||
case llvm::ELF::R_AARCH64_ABS64:
|
||||
return visitELF_AARCH64_ABS64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
case Triple::mips64el:
|
||||
case Triple::mips64:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_MIPS_32:
|
||||
return visitELF_MIPS_32(R, Value);
|
||||
case llvm::ELF::R_MIPS_64:
|
||||
return visitELF_MIPS_64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
case Triple::ppc64le:
|
||||
case Triple::ppc64:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_PPC64_ADDR32:
|
||||
return visitELF_PPC64_ADDR32(R, Value);
|
||||
case llvm::ELF::R_PPC64_ADDR64:
|
||||
return visitELF_PPC64_ADDR64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
case Triple::systemz:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_390_32:
|
||||
return visitELF_390_32(R, Value);
|
||||
case llvm::ELF::R_390_64:
|
||||
return visitELF_390_64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
case Triple::sparcv9:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_SPARC_32:
|
||||
case llvm::ELF::R_SPARC_UA32:
|
||||
return visitELF_SPARCV9_32(R, Value);
|
||||
case llvm::ELF::R_SPARC_64:
|
||||
case llvm::ELF::R_SPARC_UA64:
|
||||
return visitELF_SPARCV9_64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF64-ppc64") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_PPC64_ADDR32:
|
||||
return visitELF_PPC64_ADDR32(R, Value);
|
||||
case llvm::ELF::R_PPC64_ADDR64:
|
||||
return visitELF_PPC64_ADDR64(R, Value);
|
||||
} else if (ObjToVisit.getBytesInAddress() == 4) { // 32-bit object file
|
||||
switch (ObjToVisit.getArch()) {
|
||||
case Triple::x86:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_386_NONE:
|
||||
return visitELF_386_NONE(R);
|
||||
case llvm::ELF::R_386_32:
|
||||
return visitELF_386_32(R, Value);
|
||||
case llvm::ELF::R_386_PC32:
|
||||
return visitELF_386_PC32(R, Value, SecAddr);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
case Triple::ppc:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_PPC_ADDR32:
|
||||
return visitELF_PPC_ADDR32(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
case Triple::arm:
|
||||
case Triple::armeb:
|
||||
switch (RelocType) {
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
case llvm::ELF::R_ARM_ABS32:
|
||||
return visitELF_ARM_ABS32(R, Value);
|
||||
}
|
||||
case Triple::hexagon:
|
||||
llvm_unreachable("Unimplemented");
|
||||
case Triple::mipsel:
|
||||
case Triple::mips:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_MIPS_32:
|
||||
return visitELF_MIPS_32(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
case Triple::sparc:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_SPARC_32:
|
||||
case llvm::ELF::R_SPARC_UA32:
|
||||
return visitELF_SPARC_32(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF32-ppc") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_PPC_ADDR32:
|
||||
return visitELF_PPC_ADDR32(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF32-mips") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_MIPS_32:
|
||||
return visitELF_MIPS_32(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF64-mips") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_MIPS_32:
|
||||
return visitELF_MIPS_32(R, Value);
|
||||
case llvm::ELF::R_MIPS_64:
|
||||
return visitELF_MIPS_64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF64-aarch64") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_AARCH64_ABS32:
|
||||
return visitELF_AARCH64_ABS32(R, Value);
|
||||
case llvm::ELF::R_AARCH64_ABS64:
|
||||
return visitELF_AARCH64_ABS64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF64-s390") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_390_32:
|
||||
return visitELF_390_32(R, Value);
|
||||
case llvm::ELF::R_390_64:
|
||||
return visitELF_390_64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF32-sparc") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_SPARC_32:
|
||||
case llvm::ELF::R_SPARC_UA32:
|
||||
return visitELF_SPARC_32(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF64-sparc") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_SPARC_32:
|
||||
case llvm::ELF::R_SPARC_UA32:
|
||||
return visitELF_SPARCV9_32(R, Value);
|
||||
case llvm::ELF::R_SPARC_64:
|
||||
case llvm::ELF::R_SPARC_UA64:
|
||||
return visitELF_SPARCV9_64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF32-arm") {
|
||||
switch (RelocType) {
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
case llvm::ELF::R_ARM_ABS32:
|
||||
return visitELF_ARM_ABS32(R, Value);
|
||||
}
|
||||
} else {
|
||||
report_fatal_error("Invalid word size in object file");
|
||||
}
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
|
||||
bool error() { return HasError; }
|
||||
|
||||
private:
|
||||
StringRef FileFormat;
|
||||
ObjectFile &ObjToVisit;
|
||||
bool HasError;
|
||||
|
||||
int64_t getAddend32LE(RelocationRef R) {
|
||||
|
@ -667,7 +667,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile &Obj)
|
||||
Sym->getAddress(SymAddr);
|
||||
}
|
||||
|
||||
object::RelocVisitor V(Obj.getFileFormatName());
|
||||
object::RelocVisitor V(Obj);
|
||||
// The section address is always 0 for debug sections.
|
||||
object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
|
||||
if (V.error()) {
|
||||
|
26
test/DebugInfo/processes-relocations.ll
Normal file
26
test/DebugInfo/processes-relocations.ll
Normal file
@ -0,0 +1,26 @@
|
||||
; Make sure that for each supported architecture in RelocVisitor::visit,
|
||||
; the visitor does compute the relocation.
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple x86_64-none-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple i386-none-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple powerpc64-unknown-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple powerpc-unknown-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple mips-unknown-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple mips64-unknown-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple arm-unknown-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple aarch64-unknown-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple s390x-unknown-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple sparc-unknown-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple sparcv9-unknown-linux-eabi | llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK-NOT: failed to compute relocation
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!3, !4}
|
||||
!llvm.ident = !{!5}
|
||||
|
||||
!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.6.0 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !2, metadata !2, metadata !2, metadata !"", i32 1} ; [ DW_TAG_compile_unit ] [/a/empty.c] [DW_LANG_C99]
|
||||
!1 = metadata !{metadata !"empty.c", metadata !"/a"}
|
||||
!2 = metadata !{}
|
||||
!3 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
|
||||
!4 = metadata !{i32 2, metadata !"Debug Info Version", i32 1}
|
||||
!5 = metadata !{metadata !"clang version 3.6.0 "}
|
Loading…
Reference in New Issue
Block a user