diff options
author | Stephen Hines <srhines@google.com> | 2014-04-23 16:57:46 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-04-24 15:53:16 -0700 |
commit | 36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch) | |
tree | e6cfb69fbbd937f450eeb83bfb83b9da3b01275a /lib/Object/MachOObjectFile.cpp | |
parent | 69a8640022b04415ae9fac62f8ab090601d8f889 (diff) | |
download | external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2 |
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'lib/Object/MachOObjectFile.cpp')
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 232 |
1 files changed, 108 insertions, 124 deletions
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index d2cb8bd..12132a4 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Object/MachO.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Format.h" @@ -214,6 +215,14 @@ void SwapStruct(MachO::linker_options_command &C) { } template<> +void SwapStruct(MachO::version_min_command&C) { + SwapValue(C.cmd); + SwapValue(C.cmdsize); + SwapValue(C.version); + SwapValue(C.reserved); +} + +template<> void SwapStruct(MachO::data_in_code_entry &C) { SwapValue(C.offset); SwapValue(C.length); @@ -275,18 +284,9 @@ static StringRef parseSegmentOrSectionName(const char *P) { // Helper to advance a section or symbol iterator multiple increments at a time. template<class T> -static error_code advance(T &it, size_t Val) { - error_code ec; - while (Val--) { - it.increment(ec); - } - return ec; -} - -template<class T> -static void advanceTo(T &it, size_t Val) { - if (error_code ec = advance(it, Val)) - report_fatal_error(ec.message()); +static void advance(T &it, size_t Val) { + while (Val--) + ++it; } static unsigned getCPUType(const MachOObjectFile *O) { @@ -305,18 +305,16 @@ static void printRelocationTargetName(const MachOObjectFile *O, if (IsScattered) { uint32_t Val = O->getPlainRelocationSymbolNum(RE); - error_code ec; - for (symbol_iterator SI = O->begin_symbols(), SE = O->end_symbols(); - SI != SE; SI.increment(ec)) { - if (ec) report_fatal_error(ec.message()); - + for (const SymbolRef &Symbol : O->symbols()) { + error_code ec; uint64_t Addr; StringRef Name; - if ((ec = SI->getAddress(Addr))) + if ((ec = Symbol.getAddress(Addr))) report_fatal_error(ec.message()); - if (Addr != Val) continue; - if ((ec = SI->getName(Name))) + if (Addr != Val) + continue; + if ((ec = Symbol.getName(Name))) report_fatal_error(ec.message()); fmt << Name; return; @@ -324,17 +322,16 @@ static void printRelocationTargetName(const MachOObjectFile *O, // If we couldn't find a symbol that this relocation refers to, try // to find a section beginning instead. - for (section_iterator SI = O->begin_sections(), SE = O->end_sections(); - SI != SE; SI.increment(ec)) { - if (ec) report_fatal_error(ec.message()); - + for (const SectionRef &Section : O->sections()) { + error_code ec; uint64_t Addr; StringRef Name; - if ((ec = SI->getAddress(Addr))) + if ((ec = Section.getAddress(Addr))) report_fatal_error(ec.message()); - if (Addr != Val) continue; - if ((ec = SI->getName(Name))) + if (Addr != Val) + continue; + if ((ec = Section.getName(Name))) report_fatal_error(ec.message()); fmt << Name; return; @@ -349,13 +346,13 @@ static void printRelocationTargetName(const MachOObjectFile *O, uint64_t Val = O->getPlainRelocationSymbolNum(RE); if (isExtern) { - symbol_iterator SI = O->begin_symbols(); - advanceTo(SI, Val); + symbol_iterator SI = O->symbol_begin(); + advance(SI, Val); SI->getName(S); } else { - section_iterator SI = O->begin_sections(); + section_iterator SI = O->section_begin(); // Adjust for the fact that sections are 1-indexed. - advanceTo(SI, Val - 1); + advance(SI, Val - 1); SI->getName(S); } @@ -419,10 +416,10 @@ static uint32_t getSectionFlags(const MachOObjectFile *O, return Sect.flags; } -MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, - bool IsLittleEndian, bool Is64bits, - error_code &ec) - : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), +MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, + bool Is64bits, error_code &EC, + bool BufferOwned) + : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object, BufferOwned), SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL), DataInCodeLoadCmd(NULL) { uint32_t LoadCommandCount = this->getHeader().ncmds; MachO::LoadCommandType SegmentLoadType = is64Bit() ? @@ -454,14 +451,11 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, } } -error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb, - SymbolRef &Res) const { +void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const { unsigned SymbolTableEntrySize = is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); Symb.p += SymbolTableEntrySize; - Res = SymbolRef(Symb, this); - return object_error::success; } error_code MachOObjectFile::getSymbolName(DataRefImpl Symb, @@ -485,33 +479,9 @@ error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb, return object_error::success; } -error_code -MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb, - uint64_t &Res) const { - nlist_base Entry = getSymbolTableEntryBase(this, Symb); - getSymbolAddress(Symb, Res); - if (Entry.n_sect) { - uint64_t Delta; - DataRefImpl SecRel; - SecRel.d.a = Entry.n_sect-1; - if (is64Bit()) { - MachO::section_64 Sec = getSection64(SecRel); - Delta = Sec.offset - Sec.addr; - } else { - MachO::section Sec = getSection(SecRel); - Delta = Sec.offset - Sec.addr; - } - - Res += Delta; - } - - return object_error::success; -} - error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI, uint32_t &Result) const { - uint32_t flags; - this->getSymbolFlags(DRI, flags); + uint32_t flags = getSymbolFlags(DRI); if (flags & SymbolRef::SF_Common) { nlist_base Entry = getSymbolTableEntryBase(this, DRI); Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc); @@ -535,8 +505,7 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, SectionIndex = Entry.n_sect; if (!SectionIndex) { - uint32_t flags = SymbolRef::SF_None; - this->getSymbolFlags(DRI, flags); + uint32_t flags = getSymbolFlags(DRI); if (flags & SymbolRef::SF_Common) Result = Value; else @@ -545,10 +514,8 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, } // Unfortunately symbols are unsorted so we need to touch all // symbols from load command - error_code ec; - for (symbol_iterator I = begin_symbols(), E = end_symbols(); I != E; - I.increment(ec)) { - DataRefImpl DRI = I->getRawDataRefImpl(); + for (const SymbolRef &Symbol : symbols()) { + DataRefImpl DRI = Symbol.getRawDataRefImpl(); Entry = getSymbolTableEntryBase(this, DRI); getSymbolAddress(DRI, Value); if (Entry.n_sect == SectionIndex && Value > BeginOffset) @@ -591,15 +558,13 @@ error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, return object_error::success; } -error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, - uint32_t &Result) const { +uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const { nlist_base Entry = getSymbolTableEntryBase(this, DRI); uint8_t MachOType = Entry.n_type; uint16_t MachOFlags = Entry.n_desc; - // TODO: Correctly set SF_ThreadLocal - Result = SymbolRef::SF_None; + uint32_t Result = SymbolRef::SF_None; if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) Result |= SymbolRef::SF_Undefined; @@ -623,7 +588,7 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, if ((MachOType & MachO::N_TYPE) == MachO::N_ABS) Result |= SymbolRef::SF_Absolute; - return object_error::success; + return Result; } error_code @@ -633,7 +598,7 @@ MachOObjectFile::getSymbolSection(DataRefImpl Symb, uint8_t index = Entry.n_sect; if (index == 0) { - Res = end_sections(); + Res = section_end(); } else { DataRefImpl DRI; DRI.d.a = index - 1; @@ -643,16 +608,8 @@ MachOObjectFile::getSymbolSection(DataRefImpl Symb, return object_error::success; } -error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb, - uint64_t &Val) const { - report_fatal_error("getSymbolValue unimplemented in MachOObjectFile"); -} - -error_code MachOObjectFile::getSectionNext(DataRefImpl Sec, - SectionRef &Res) const { +void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; - Res = SectionRef(Sec, this); - return object_error::success; } error_code @@ -834,13 +791,20 @@ MachOObjectFile::section_rel_end(DataRefImpl Sec) const { return relocation_iterator(RelocationRef(Ret, this)); } -error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, - RelocationRef &Res) const { +bool MachOObjectFile::section_rel_empty(DataRefImpl Sec) const { + if (is64Bit()) { + MachO::section_64 Sect = getSection64(Sec); + return Sect.nreloc == 0; + } else { + MachO::section Sect = getSection(Sec); + return Sect.nreloc == 0; + } +} + +void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const { const MachO::any_relocation_info *P = reinterpret_cast<const MachO::any_relocation_info *>(Rel.p); Rel.p = reinterpret_cast<uintptr_t>(P + 1); - Res = RelocationRef(Rel, this); - return object_error::success; } error_code @@ -861,7 +825,7 @@ MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const { uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); bool isExtern = getPlainRelocationExternal(RE); if (!isExtern) - return end_symbols(); + return symbol_end(); MachO::symtab_command S = getSymtabLoadCommand(); unsigned SymbolTableEntrySize = is64Bit() ? @@ -899,7 +863,7 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, "GENERIC_RELOC_LOCAL_SECTDIFF", "GENERIC_RELOC_TLV" }; - if (RType > 6) + if (RType > 5) res = "Unknown"; else res = Table[RType]; @@ -943,6 +907,23 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, res = Table[RType]; break; } + case Triple::arm64: + case Triple::aarch64: { + static const char *const Table[] = { + "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR", + "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21", + "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21", + "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT", + "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12", + "ARM64_RELOC_ADDEND" + }; + + if (RType >= array_lengthof(Table)) + res = "Unknown"; + else + res = Table[RType]; + break; + } case Triple::ppc: { static const char *const Table[] = { "PPC_RELOC_VANILLA", @@ -962,7 +943,10 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, "PPC_RELOC_LO14_SECTDIFF", "PPC_RELOC_LOCAL_SECTDIFF" }; - res = Table[RType]; + if (RType > 15) + res = "Unknown"; + else + res = Table[RType]; break; } case Triple::UnknownArch: @@ -1187,20 +1171,20 @@ error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData, report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); } -symbol_iterator MachOObjectFile::begin_symbols() const { +basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const { DataRefImpl DRI; if (!SymtabLoadCmd) - return symbol_iterator(SymbolRef(DRI, this)); + return basic_symbol_iterator(SymbolRef(DRI, this)); MachO::symtab_command Symtab = getSymtabLoadCommand(); DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff)); - return symbol_iterator(SymbolRef(DRI, this)); + return basic_symbol_iterator(SymbolRef(DRI, this)); } -symbol_iterator MachOObjectFile::end_symbols() const { +basic_symbol_iterator MachOObjectFile::symbol_end_impl() const { DataRefImpl DRI; if (!SymtabLoadCmd) - return symbol_iterator(SymbolRef(DRI, this)); + return basic_symbol_iterator(SymbolRef(DRI, this)); MachO::symtab_command Symtab = getSymtabLoadCommand(); unsigned SymbolTableEntrySize = is64Bit() ? @@ -1209,36 +1193,26 @@ symbol_iterator MachOObjectFile::end_symbols() const { unsigned Offset = Symtab.symoff + Symtab.nsyms * SymbolTableEntrySize; DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); - return symbol_iterator(SymbolRef(DRI, this)); -} - -symbol_iterator MachOObjectFile::begin_dynamic_symbols() const { - // TODO: implement - report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile"); -} - -symbol_iterator MachOObjectFile::end_dynamic_symbols() const { - // TODO: implement - report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile"); + return basic_symbol_iterator(SymbolRef(DRI, this)); } -section_iterator MachOObjectFile::begin_sections() const { +section_iterator MachOObjectFile::section_begin() const { DataRefImpl DRI; return section_iterator(SectionRef(DRI, this)); } -section_iterator MachOObjectFile::end_sections() const { +section_iterator MachOObjectFile::section_end() const { DataRefImpl DRI; DRI.d.a = Sections.size(); return section_iterator(SectionRef(DRI, this)); } -library_iterator MachOObjectFile::begin_libraries_needed() const { +library_iterator MachOObjectFile::needed_library_begin() const { // TODO: implement report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); } -library_iterator MachOObjectFile::end_libraries_needed() const { +library_iterator MachOObjectFile::needed_library_end() const { // TODO: implement report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); } @@ -1272,6 +1246,8 @@ StringRef MachOObjectFile::getFileFormatName() const { switch (CPUType) { case llvm::MachO::CPU_TYPE_X86_64: return "Mach-O 64-bit x86-64"; + case llvm::MachO::CPU_TYPE_ARM64: + return "Mach-O arm64"; case llvm::MachO::CPU_TYPE_POWERPC64: return "Mach-O 64-bit ppc64"; default: @@ -1287,6 +1263,8 @@ Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { return Triple::x86_64; case llvm::MachO::CPU_TYPE_ARM: return Triple::arm; + case llvm::MachO::CPU_TYPE_ARM64: + return Triple::arm64; case llvm::MachO::CPU_TYPE_POWERPC: return Triple::ppc; case llvm::MachO::CPU_TYPE_POWERPC64: @@ -1423,7 +1401,7 @@ SectionRef MachOObjectFile::getRelocationSection( const MachO::any_relocation_info &RE) const { if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) - return *end_sections(); + return *section_end(); unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1; DataRefImpl DRI; DRI.d.a = SecNum; @@ -1501,6 +1479,11 @@ MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const { return getStruct<MachO::linker_options_command>(this, L.Ptr); } +MachO::version_min_command +MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const { + return getStruct<MachO::version_min_command>(this, L.Ptr); +} + MachO::any_relocation_info MachOObjectFile::getRelocation(DataRefImpl Rel) const { const char *P = reinterpret_cast<const char *>(Rel.p); @@ -1579,26 +1562,27 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index, } } -ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { +ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer, + bool BufferOwned) { StringRef Magic = Buffer->getBuffer().slice(0, 4); - error_code ec; - OwningPtr<ObjectFile> Ret; + error_code EC; + std::unique_ptr<MachOObjectFile> Ret; if (Magic == "\xFE\xED\xFA\xCE") - Ret.reset(new MachOObjectFile(Buffer, false, false, ec)); + Ret.reset(new MachOObjectFile(Buffer, false, false, EC, BufferOwned)); else if (Magic == "\xCE\xFA\xED\xFE") - Ret.reset(new MachOObjectFile(Buffer, true, false, ec)); + Ret.reset(new MachOObjectFile(Buffer, true, false, EC, BufferOwned)); else if (Magic == "\xFE\xED\xFA\xCF") - Ret.reset(new MachOObjectFile(Buffer, false, true, ec)); + Ret.reset(new MachOObjectFile(Buffer, false, true, EC, BufferOwned)); else if (Magic == "\xCF\xFA\xED\xFE") - Ret.reset(new MachOObjectFile(Buffer, true, true, ec)); + Ret.reset(new MachOObjectFile(Buffer, true, true, EC, BufferOwned)); else { delete Buffer; - return NULL; + return object_error::parse_failed; } - if (ec) - return NULL; - return Ret.take(); + if (EC) + return EC; + return Ret.release(); } } // end namespace object |