X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FObject%2FMachOObjectFile.cpp;h=5bcb4bae8ea383d56025c31e0fc250a37b0a5239;hb=78c0b35bf7e5d9093c94f811a7e8c72f0a6357df;hp=4919114d2349752607514bc2fbe5c070ee31de3d;hpb=5b003bb869bb79cbec59f76c2ffe6461c8a8efea;p=oota-llvm.git diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 4919114d234..5bcb4bae8ea 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -14,6 +14,7 @@ #include "llvm/Object/MachO.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Format.h" @@ -27,220 +28,19 @@ using namespace llvm; using namespace object; -namespace llvm { - -namespace object { - -struct nlist_base { - uint32_t n_strx; - uint8_t n_type; - uint8_t n_sect; - uint16_t n_desc; -}; - -struct section_base { - char sectname[16]; - char segname[16]; -}; - -template -static void SwapStruct(T &Value); - -template<> -void SwapStruct(MachO::any_relocation_info &H) { - sys::swapByteOrder(H.r_word0); - sys::swapByteOrder(H.r_word1); -} - -template<> -void SwapStruct(MachO::load_command &L) { - sys::swapByteOrder(L.cmd); - sys::swapByteOrder(L.cmdsize); -} - -template<> -void SwapStruct(nlist_base &S) { - sys::swapByteOrder(S.n_strx); - sys::swapByteOrder(S.n_desc); -} - -template<> -void SwapStruct(MachO::section &S) { - sys::swapByteOrder(S.addr); - sys::swapByteOrder(S.size); - sys::swapByteOrder(S.offset); - sys::swapByteOrder(S.align); - sys::swapByteOrder(S.reloff); - sys::swapByteOrder(S.nreloc); - sys::swapByteOrder(S.flags); - sys::swapByteOrder(S.reserved1); - sys::swapByteOrder(S.reserved2); -} - -template<> -void SwapStruct(MachO::section_64 &S) { - sys::swapByteOrder(S.addr); - sys::swapByteOrder(S.size); - sys::swapByteOrder(S.offset); - sys::swapByteOrder(S.align); - sys::swapByteOrder(S.reloff); - sys::swapByteOrder(S.nreloc); - sys::swapByteOrder(S.flags); - sys::swapByteOrder(S.reserved1); - sys::swapByteOrder(S.reserved2); - sys::swapByteOrder(S.reserved3); -} - -template<> -void SwapStruct(MachO::nlist &S) { - sys::swapByteOrder(S.n_strx); - sys::swapByteOrder(S.n_desc); - sys::swapByteOrder(S.n_value); -} - -template<> -void SwapStruct(MachO::nlist_64 &S) { - sys::swapByteOrder(S.n_strx); - sys::swapByteOrder(S.n_desc); - sys::swapByteOrder(S.n_value); -} - -template<> -void SwapStruct(MachO::mach_header &H) { - sys::swapByteOrder(H.magic); - sys::swapByteOrder(H.cputype); - sys::swapByteOrder(H.cpusubtype); - sys::swapByteOrder(H.filetype); - sys::swapByteOrder(H.ncmds); - sys::swapByteOrder(H.sizeofcmds); - sys::swapByteOrder(H.flags); -} - -template<> -void SwapStruct(MachO::mach_header_64 &H) { - sys::swapByteOrder(H.magic); - sys::swapByteOrder(H.cputype); - sys::swapByteOrder(H.cpusubtype); - sys::swapByteOrder(H.filetype); - sys::swapByteOrder(H.ncmds); - sys::swapByteOrder(H.sizeofcmds); - sys::swapByteOrder(H.flags); - sys::swapByteOrder(H.reserved); -} - -template<> -void SwapStruct(MachO::symtab_command &C) { - sys::swapByteOrder(C.cmd); - sys::swapByteOrder(C.cmdsize); - sys::swapByteOrder(C.symoff); - sys::swapByteOrder(C.nsyms); - sys::swapByteOrder(C.stroff); - sys::swapByteOrder(C.strsize); -} - -template<> -void SwapStruct(MachO::dysymtab_command &C) { - sys::swapByteOrder(C.cmd); - sys::swapByteOrder(C.cmdsize); - sys::swapByteOrder(C.ilocalsym); - sys::swapByteOrder(C.nlocalsym); - sys::swapByteOrder(C.iextdefsym); - sys::swapByteOrder(C.nextdefsym); - sys::swapByteOrder(C.iundefsym); - sys::swapByteOrder(C.nundefsym); - sys::swapByteOrder(C.tocoff); - sys::swapByteOrder(C.ntoc); - sys::swapByteOrder(C.modtaboff); - sys::swapByteOrder(C.nmodtab); - sys::swapByteOrder(C.extrefsymoff); - sys::swapByteOrder(C.nextrefsyms); - sys::swapByteOrder(C.indirectsymoff); - sys::swapByteOrder(C.nindirectsyms); - sys::swapByteOrder(C.extreloff); - sys::swapByteOrder(C.nextrel); - sys::swapByteOrder(C.locreloff); - sys::swapByteOrder(C.nlocrel); -} - -template<> -void SwapStruct(MachO::linkedit_data_command &C) { - sys::swapByteOrder(C.cmd); - sys::swapByteOrder(C.cmdsize); - sys::swapByteOrder(C.dataoff); - sys::swapByteOrder(C.datasize); -} - -template<> -void SwapStruct(MachO::segment_command &C) { - sys::swapByteOrder(C.cmd); - sys::swapByteOrder(C.cmdsize); - sys::swapByteOrder(C.vmaddr); - sys::swapByteOrder(C.vmsize); - sys::swapByteOrder(C.fileoff); - sys::swapByteOrder(C.filesize); - sys::swapByteOrder(C.maxprot); - sys::swapByteOrder(C.initprot); - sys::swapByteOrder(C.nsects); - sys::swapByteOrder(C.flags); -} - -template<> -void SwapStruct(MachO::segment_command_64 &C) { - sys::swapByteOrder(C.cmd); - sys::swapByteOrder(C.cmdsize); - sys::swapByteOrder(C.vmaddr); - sys::swapByteOrder(C.vmsize); - sys::swapByteOrder(C.fileoff); - sys::swapByteOrder(C.filesize); - sys::swapByteOrder(C.maxprot); - sys::swapByteOrder(C.initprot); - sys::swapByteOrder(C.nsects); - sys::swapByteOrder(C.flags); -} - -template<> -void SwapStruct(uint32_t &C) { - sys::swapByteOrder(C); -} - -template<> -void SwapStruct(MachO::linker_options_command &C) { - sys::swapByteOrder(C.cmd); - sys::swapByteOrder(C.cmdsize); - sys::swapByteOrder(C.count); -} - -template<> -void SwapStruct(MachO::version_min_command&C) { - sys::swapByteOrder(C.cmd); - sys::swapByteOrder(C.cmdsize); - sys::swapByteOrder(C.version); - sys::swapByteOrder(C.reserved); -} - -template<> -void SwapStruct(MachO::dylib_command&C) { - sys::swapByteOrder(C.cmd); - sys::swapByteOrder(C.cmdsize); - sys::swapByteOrder(C.dylib.name); - sys::swapByteOrder(C.dylib.timestamp); - sys::swapByteOrder(C.dylib.current_version); - sys::swapByteOrder(C.dylib.compatibility_version); -} - -template<> -void SwapStruct(MachO::data_in_code_entry &C) { - sys::swapByteOrder(C.offset); - sys::swapByteOrder(C.length); - sys::swapByteOrder(C.kind); +namespace { + struct section_base { + char sectname[16]; + char segname[16]; + }; } template -T getStruct(const MachOObjectFile *O, const char *P) { +static T getStruct(const MachOObjectFile *O, const char *P) { T Cmd; memcpy(&Cmd, P, sizeof(T)); if (O->isLittleEndian() != sys::IsLittleEndianHost) - SwapStruct(Cmd); + MachO::swapStruct(Cmd); return Cmd; } @@ -274,10 +74,10 @@ static const char *getPtr(const MachOObjectFile *O, size_t Offset) { return O->getData().substr(Offset, 1).data(); } -static nlist_base +static MachO::nlist_base getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) { const char *P = reinterpret_cast(DRI.p); - return getStruct(O, P); + return getStruct(O, P); } static StringRef parseSegmentOrSectionName(const char *P) { @@ -474,7 +274,7 @@ void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const { std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb, StringRef &Res) const { StringRef StringTable = getStringTableData(); - nlist_base Entry = getSymbolTableEntryBase(this, Symb); + MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); const char *Start = &StringTable.data()[Entry.n_strx]; Res = StringRef(Start); return object_error::success; @@ -528,7 +328,7 @@ std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI, uint32_t &Result) const { uint32_t flags = getSymbolFlags(DRI); if (flags & SymbolRef::SF_Common) { - nlist_base Entry = getSymbolTableEntryBase(this, DRI); + MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc); } else { Result = 0; @@ -542,7 +342,7 @@ std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, uint64_t EndOffset = 0; uint8_t SectionIndex; - nlist_base Entry = getSymbolTableEntryBase(this, DRI); + MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); uint64_t Value; getSymbolAddress(DRI, Value); if (Value == UnknownAddressOrSize) { @@ -587,7 +387,7 @@ std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const { - nlist_base Entry = getSymbolTableEntryBase(this, Symb); + MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); uint8_t n_type = Entry.n_type; Res = SymbolRef::ST_Other; @@ -610,7 +410,7 @@ std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, } uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const { - nlist_base Entry = getSymbolTableEntryBase(this, DRI); + MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI); uint8_t MachOType = Entry.n_type; uint16_t MachOFlags = Entry.n_desc; @@ -639,6 +439,9 @@ uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const { if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) Result |= SymbolRef::SF_Weak; + if (MachOFlags & (MachO::N_ARM_THUMB_DEF)) + Result |= SymbolRef::SF_Thumb; + if ((MachOType & MachO::N_TYPE) == MachO::N_ABS) Result |= SymbolRef::SF_Absolute; @@ -647,7 +450,7 @@ uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const { std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, section_iterator &Res) const { - nlist_base Entry = getSymbolTableEntryBase(this, Symb); + MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); uint8_t index = Entry.n_sect; if (index == 0) { @@ -956,7 +759,6 @@ 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", @@ -1210,16 +1012,6 @@ std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel, return object_error::success; } -std::error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData, - LibraryRef &Res) const { - report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); -} - -std::error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData, - StringRef &Res) const { - report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); -} - // // guessLibraryShortName() is passed a name of a dynamic library and returns a // guess on what the short name is. Then name is returned as a substring of the @@ -1447,16 +1239,6 @@ section_iterator MachOObjectFile::section_end() const { return section_iterator(SectionRef(DRI, this)); } -library_iterator MachOObjectFile::needed_library_begin() const { - // TODO: implement - report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); -} - -library_iterator MachOObjectFile::needed_library_end() const { - // TODO: implement - report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); -} - uint8_t MachOObjectFile::getBytesInAddress() const { return is64Bit() ? 8 : 4; } @@ -1504,7 +1286,7 @@ Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { case llvm::MachO::CPU_TYPE_ARM: return Triple::arm; case llvm::MachO::CPU_TYPE_ARM64: - return Triple::arm64; + return Triple::aarch64; case llvm::MachO::CPU_TYPE_POWERPC: return Triple::ppc; case llvm::MachO::CPU_TYPE_POWERPC64: @@ -1514,7 +1296,11 @@ Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { } } -Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) { +Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType, + const char **McpuDefault) { + if (McpuDefault) + *McpuDefault = nullptr; + switch (CPUType) { case MachO::CPU_TYPE_I386: switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { @@ -1538,15 +1324,25 @@ Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) { return Triple("armv4t-apple-darwin"); case MachO::CPU_SUBTYPE_ARM_V5TEJ: return Triple("armv5e-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_XSCALE: + return Triple("xscale-apple-darwin"); case MachO::CPU_SUBTYPE_ARM_V6: return Triple("armv6-apple-darwin"); case MachO::CPU_SUBTYPE_ARM_V6M: + if (McpuDefault) + *McpuDefault = "cortex-m0"; return Triple("armv6m-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_V7: + return Triple("armv7-apple-darwin"); case MachO::CPU_SUBTYPE_ARM_V7EM: + if (McpuDefault) + *McpuDefault = "cortex-m4"; return Triple("armv7em-apple-darwin"); case MachO::CPU_SUBTYPE_ARM_V7K: return Triple("armv7k-apple-darwin"); case MachO::CPU_SUBTYPE_ARM_V7M: + if (McpuDefault) + *McpuDefault = "cortex-m3"; return Triple("armv7m-apple-darwin"); case MachO::CPU_SUBTYPE_ARM_V7S: return Triple("armv7s-apple-darwin"); @@ -1579,50 +1375,102 @@ Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) { } } +Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType, + const char **McpuDefault) { + if (McpuDefault) + *McpuDefault = nullptr; + + switch (CPUType) { + case MachO::CPU_TYPE_ARM: + switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { + case MachO::CPU_SUBTYPE_ARM_V4T: + return Triple("thumbv4t-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_V5TEJ: + return Triple("thumbv5e-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_XSCALE: + return Triple("xscale-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_V6: + return Triple("thumbv6-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_V6M: + if (McpuDefault) + *McpuDefault = "cortex-m0"; + return Triple("thumbv6m-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_V7: + return Triple("thumbv7-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_V7EM: + if (McpuDefault) + *McpuDefault = "cortex-m4"; + return Triple("thumbv7em-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_V7K: + return Triple("thumbv7k-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_V7M: + if (McpuDefault) + *McpuDefault = "cortex-m3"; + return Triple("thumbv7m-apple-darwin"); + case MachO::CPU_SUBTYPE_ARM_V7S: + return Triple("thumbv7s-apple-darwin"); + default: + return Triple(); + } + default: + return Triple(); + } +} + +Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType, + const char **McpuDefault, + Triple *ThumbTriple) { + Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault); + *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType, + McpuDefault); + return T; +} + Triple MachOObjectFile::getHostArch() { return Triple(sys::getDefaultTargetTriple()); } -Triple MachOObjectFile::getArch(StringRef ArchFlag) { - if (ArchFlag == "i386") - return Triple("i386-apple-darwin"); - else if (ArchFlag == "x86_64") - return Triple("x86_64-apple-darwin"); - else if (ArchFlag == "x86_64h") - return Triple("x86_64h-apple-darwin"); - else if (ArchFlag == "armv4t" || ArchFlag == "arm") - return Triple("armv4t-apple-darwin"); - else if (ArchFlag == "armv5e") - return Triple("armv5e-apple-darwin"); - else if (ArchFlag == "armv6") - return Triple("armv6-apple-darwin"); - else if (ArchFlag == "armv6m") - return Triple("armv6m-apple-darwin"); - else if (ArchFlag == "armv7em") - return Triple("armv7em-apple-darwin"); - else if (ArchFlag == "armv7k") - return Triple("armv7k-apple-darwin"); - else if (ArchFlag == "armv7k") - return Triple("armv7m-apple-darwin"); - else if (ArchFlag == "armv7s") - return Triple("armv7s-apple-darwin"); - else if (ArchFlag == "arm64") - return Triple("arm64-apple-darwin"); - else if (ArchFlag == "ppc") - return Triple("ppc-apple-darwin"); - else if (ArchFlag == "ppc64") - return Triple("ppc64-apple-darwin"); - else - return Triple(); +bool MachOObjectFile::isValidArch(StringRef ArchFlag) { + return StringSwitch(ArchFlag) + .Case("i386", true) + .Case("x86_64", true) + .Case("x86_64h", true) + .Case("armv4t", true) + .Case("arm", true) + .Case("armv5e", true) + .Case("armv6", true) + .Case("armv6m", true) + .Case("armv7em", true) + .Case("armv7k", true) + .Case("armv7m", true) + .Case("armv7s", true) + .Case("arm64", true) + .Case("ppc", true) + .Case("ppc64", true) + .Default(false); } unsigned MachOObjectFile::getArch() const { return getArch(getCPUType(this)); } -StringRef MachOObjectFile::getLoadName() const { - // TODO: Implement - report_fatal_error("get_load_name() unimplemented in MachOObjectFile"); +Triple MachOObjectFile::getArch(const char **McpuDefault, + Triple *ThumbTriple) const { + Triple T; + if (is64Bit()) { + MachO::mach_header_64 H_64; + H_64 = getHeader64(); + T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype, McpuDefault); + *ThumbTriple = MachOObjectFile::getThumbArch(H_64.cputype, H_64.cpusubtype, + McpuDefault); + } else { + MachO::mach_header H; + H = getHeader(); + T = MachOObjectFile::getArch(H.cputype, H.cpusubtype, McpuDefault); + *ThumbTriple = MachOObjectFile::getThumbArch(H.cputype, H.cpusubtype, + McpuDefault); + } + return T; } relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const { @@ -1908,7 +1756,7 @@ StringRef MachOObjectFile::getStringTableData() const { bool MachOObjectFile::is64Bit() const { return getType() == getMachOType(false, true) || - getType() == getMachOType(true, true); + getType() == getMachOType(true, true); } void MachOObjectFile::ReadULEB128s(uint64_t Index, @@ -1923,11 +1771,11 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index, } } -const char *MachOObjectFile::getSectionPointer(DataRefImpl Rel) const { - return Sections[Rel.d.a]; +bool MachOObjectFile::isRelocatableObject() const { + return getHeader().filetype == MachO::MH_OBJECT; } -ErrorOr +ErrorOr> ObjectFile::createMachOObjectFile(std::unique_ptr &Buffer) { StringRef Magic = Buffer->getBuffer().slice(0, 4); std::error_code EC; @@ -1945,8 +1793,6 @@ ObjectFile::createMachOObjectFile(std::unique_ptr &Buffer) { if (EC) return EC; - return Ret.release(); + return std::move(Ret); } -} // end namespace object -} // end namespace llvm