Refactor RelocVisitor to take an object. This removes some

string comparisons and makes it a bit easier to check individual
targets.

Patch by Charlie Turner.

llvm-svn: 219108
This commit is contained in:
Eric Christopher 2014-10-06 06:55:55 +00:00
parent 1452c8e640
commit 47e079d45e
3 changed files with 116 additions and 98 deletions

View File

@ -924,6 +924,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
default: default:
report_fatal_error("Invalid ELFCLASS!"); report_fatal_error("Invalid ELFCLASS!");
} }
case ELF::EM_PPC:
return Triple::ppc;
case ELF::EM_PPC64: case ELF::EM_PPC64:
return IsLittleEndian ? Triple::ppc64le : Triple::ppc64; return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
case ELF::EM_S390: case ELF::EM_S390:

View File

@ -40,16 +40,18 @@ struct RelocToApply {
/// @brief Base class for object file relocation visitors. /// @brief Base class for object file relocation visitors.
class RelocVisitor { class RelocVisitor {
public: public:
explicit RelocVisitor(StringRef FileFormat) explicit RelocVisitor(ObjectFile &Obj)
: FileFormat(FileFormat), HasError(false) {} : ObjToVisit(Obj), HasError(false) {}
// TODO: Should handle multiple applied relocations via either passing in the // TODO: Should handle multiple applied relocations via either passing in the
// previously computed value or just count paired relocations as a single // previously computed value or just count paired relocations as a single
// visit. // visit.
RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0, RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0,
uint64_t Value = 0) { uint64_t Value = 0) {
if (FileFormat == "ELF64-x86-64") { if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file
switch (RelocType) { switch (ObjToVisit.getArch()) {
case Triple::x86_64:
switch (RelocType) {
case llvm::ELF::R_X86_64_NONE: case llvm::ELF::R_X86_64_NONE:
return visitELF_X86_64_NONE(R); return visitELF_X86_64_NONE(R);
case llvm::ELF::R_X86_64_64: case llvm::ELF::R_X86_64_64:
@ -63,113 +65,127 @@ public:
default: default:
HasError = true; HasError = true;
return RelocToApply(); return RelocToApply();
} }
} else if (FileFormat == "ELF32-i386") { case Triple::aarch64:
switch (RelocType) { switch (RelocType) {
case llvm::ELF::R_386_NONE: case llvm::ELF::R_AARCH64_ABS32:
return visitELF_386_NONE(R); return visitELF_AARCH64_ABS32(R, Value);
case llvm::ELF::R_386_32: case llvm::ELF::R_AARCH64_ABS64:
return visitELF_386_32(R, Value); return visitELF_AARCH64_ABS64(R, Value);
case llvm::ELF::R_386_PC32: default:
return visitELF_386_PC32(R, Value, SecAddr); 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: default:
HasError = true; HasError = true;
return RelocToApply(); return RelocToApply();
} }
} else if (FileFormat == "ELF64-ppc64") { } else if (ObjToVisit.getBytesInAddress() == 4) { // 32-bit object file
switch (RelocType) { switch (ObjToVisit.getArch()) {
case llvm::ELF::R_PPC64_ADDR32: case Triple::x86:
return visitELF_PPC64_ADDR32(R, Value); switch (RelocType) {
case llvm::ELF::R_PPC64_ADDR64: case llvm::ELF::R_386_NONE:
return visitELF_PPC64_ADDR64(R, Value); 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::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: default:
HasError = true; HasError = true;
return RelocToApply(); return RelocToApply();
} }
} else if (FileFormat == "ELF32-ppc") { } else {
switch (RelocType) { report_fatal_error("Invalid word size in object file");
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);
}
} }
HasError = true;
return RelocToApply();
} }
bool error() { return HasError; } bool error() { return HasError; }
private: private:
StringRef FileFormat; ObjectFile &ObjToVisit;
bool HasError; bool HasError;
int64_t getAddend32LE(RelocationRef R) { int64_t getAddend32LE(RelocationRef R) {

View File

@ -626,7 +626,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile &Obj)
Sym->getAddress(SymAddr); Sym->getAddress(SymAddr);
} }
object::RelocVisitor V(Obj.getFileFormatName()); object::RelocVisitor V(Obj);
// The section address is always 0 for debug sections. // The section address is always 0 for debug sections.
object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr)); object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
if (V.error()) { if (V.error()) {