Index: include/llvm/Object/COFF.h =================================================================== --- include/llvm/Object/COFF.h +++ include/llvm/Object/COFF.h @@ -397,6 +397,7 @@ uint64_t &Res) const override; error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + section_iterator getRelocationSection(DataRefImpl Rel) const override; error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override; error_code getRelocationTypeName(DataRefImpl Rel, Index: include/llvm/Object/ELFObjectFile.h =================================================================== --- include/llvm/Object/ELFObjectFile.h +++ include/llvm/Object/ELFObjectFile.h @@ -96,6 +96,7 @@ uint64_t &Res) const override; error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + section_iterator getRelocationSection(DataRefImpl Rel) const override; error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override; error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl &Result) const override; @@ -552,6 +553,12 @@ return symbol_iterator(SymbolRef(SymbolData, this)); } +// ELF relocations can not target sections +template +section_iterator ELFObjectFile::getRelocationSection(DataRefImpl Rel) const { + return section_end(); +} + template error_code ELFObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Result) const { Index: include/llvm/Object/MachO.h =================================================================== --- include/llvm/Object/MachO.h +++ include/llvm/Object/MachO.h @@ -94,12 +94,14 @@ uint64_t &Res) const override; error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + section_iterator getRelocationSection(DataRefImpl Rel) const override; error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override; error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl &Result) const override; error_code getRelocationValueString(DataRefImpl Rel, SmallVectorImpl &Result) const override; error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const override; + error_code getRelocationLength(DataRefImpl Rel, uint8_t &Res) const; error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const override; Index: include/llvm/Object/ObjectFile.h =================================================================== --- include/llvm/Object/ObjectFile.h +++ include/llvm/Object/ObjectFile.h @@ -30,6 +30,8 @@ class SymbolRef; class symbol_iterator; +class SectionRef; +typedef content_iterator section_iterator; /// RelocationRef - This is a value type class that represents a single /// relocation in the list of relocations in the object file. @@ -49,6 +51,7 @@ error_code getAddress(uint64_t &Result) const; error_code getOffset(uint64_t &Result) const; symbol_iterator getSymbol() const; + section_iterator getSection() const; error_code getType(uint64_t &Result) const; /// @brief Indicates whether this relocation should hidden when listing @@ -74,8 +77,6 @@ /// SectionRef - This is a value type class that represents a single section in /// the list of sections in the object file. -class SectionRef; -typedef content_iterator section_iterator; class SectionRef { friend class SymbolRef; DataRefImpl SectionPimpl; @@ -264,6 +265,7 @@ virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const =0; virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0; + virtual section_iterator getRelocationSection(DataRefImpl Rel) const = 0; virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const = 0; virtual error_code getRelocationTypeName(DataRefImpl Rel, @@ -486,6 +488,10 @@ return OwningObject->getRelocationSymbol(RelocationPimpl); } +inline section_iterator RelocationRef::getSection() const { + return OwningObject->getRelocationSection(RelocationPimpl); +} + inline error_code RelocationRef::getType(uint64_t &Result) const { return OwningObject->getRelocationType(RelocationPimpl, Result); } Index: include/llvm/Object/RelocVisitor.h =================================================================== --- include/llvm/Object/RelocVisitor.h +++ include/llvm/Object/RelocVisitor.h @@ -18,9 +18,11 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/MachO.h" #include "llvm/Support/raw_ostream.h" namespace llvm { @@ -46,7 +48,7 @@ // 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, + RelocToApply visit(uint32_t RelocType, SectionRef Sec, RelocationRef R, uint64_t SecAddr = 0, uint64_t Value = 0) { if (FileFormat == "ELF64-x86-64") { switch (RelocType) { @@ -161,6 +163,14 @@ case llvm::ELF::R_ARM_ABS32: return visitELF_ARM_ABS32(R, Value); } + } else if (FileFormat == "Mach-O 64-bit x86-64") { + switch (RelocType) { + case llvm::MachO::X86_64_RELOC_UNSIGNED: + return visitMACHO_X86_64_UNSIGNED(Sec, R, Value); + default: + HasError = true; + return RelocToApply(); + } } HasError = true; return RelocToApply(); @@ -203,6 +213,24 @@ Obj->getRelocationAddend(DRI, Addend); return Addend; } + + uint8_t getLengthMachO64(RelocationRef R) { + const MachOObjectFile *Obj = cast(R.getObjectFile()); + DataRefImpl DRI = R.getRawDataRefImpl(); + uint8_t Length; + Obj->getRelocationLength(DRI, Length); + return Length; + } + + uint64_t getValueMachO64(SectionRef Sec, RelocationRef R, uint8_t Length) { + uint64_t Offset, Value; + R.getOffset(Offset); + StringRef Contents; + Sec.getContents(Contents); + assert(Offset < Contents.size()); + memcpy(&Value, Contents.data()+Offset, Length); + return Value; + } /// Operations /// 386-ELF @@ -338,6 +366,13 @@ return RelocToApply(Value + Addend, 4); } + RelocToApply visitMACHO_X86_64_UNSIGNED(SectionRef Sec, RelocationRef R, uint64_t Value) { + uint8_t Length = getLengthMachO64(R); + Length = 1<isELF()) { + if (Obj->isELF() || Obj->isMachO()) { object::symbol_iterator Sym = Reloc.getSymbol(); - Sym->getAddress(SymAddr); + if (Sym != Obj->symbol_end()) + Sym->getAddress(SymAddr); + else { + object::section_iterator RSec = Reloc.getSection(); + if (RSec != Obj->section_end()) + RSec->getAddress(SymAddr); + } } + DEBUG(dbgs() << "Sym Addr " << format("%p", SymAddr) << "\n"); + object::RelocVisitor V(Obj->getFileFormatName()); // The section address is always 0 for debug sections. - object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr)); + object::RelocToApply R(V.visit(Type, *RelocatedSection, Reloc, 0, SymAddr)); if (V.error()) { SmallString<32> Name; error_code ec(Reloc.getTypeName(Name)); Index: lib/Object/COFFObjectFile.cpp =================================================================== --- lib/Object/COFFObjectFile.cpp +++ lib/Object/COFFObjectFile.cpp @@ -864,6 +864,11 @@ return symbol_iterator(SymbolRef(Ref, this)); } +section_iterator COFFObjectFile::getRelocationSection(DataRefImpl Rel) const { + // TODO: Somebody check whether this is correct + return section_end(); +} + error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, uint64_t &Res) const { const coff_relocation* R = toRel(Rel); Index: lib/Object/MachOObjectFile.cpp =================================================================== --- lib/Object/MachOObjectFile.cpp +++ lib/Object/MachOObjectFile.cpp @@ -846,6 +846,12 @@ return symbol_iterator(SymbolRef(Sym, this)); } +section_iterator +MachOObjectFile::getRelocationSection(DataRefImpl Rel) const { + return section_iterator(getRelocationSection(getRelocation(Rel))); +} + + error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, uint64_t &Res) const { MachO::any_relocation_info RE = getRelocation(Rel); @@ -1170,6 +1176,13 @@ return object_error::success; } +error_code +MachOObjectFile::getRelocationLength(DataRefImpl Rel, uint8_t &Res) const { + MachO::any_relocation_info RE = getRelocation(Rel); + Res = getAnyRelocationLength(RE); + return object_error::success; +} + error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const { report_fatal_error("Needed libraries unimplemented in MachOObjectFile");