X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FObject%2FMachOUniversal.cpp;h=a1c83b9b7f86ac85e87bd53ded0e009248a2e21d;hb=f9ae1a7e779c55005c79d964617b10d7cee8272a;hp=98f7198bdb1b6a8787a2f2d016b863420889eb29;hpb=9c22f87b1374b06dc6c07f6e8047890e390bbe2d;p=oota-llvm.git diff --git a/lib/Object/MachOUniversal.cpp b/lib/Object/MachOUniversal.cpp index 98f7198bdb1..a1c83b9b7f8 100644 --- a/lib/Object/MachOUniversal.cpp +++ b/lib/Object/MachOUniversal.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Object/MachOUniversal.h" - +#include "llvm/Object/Archive.h" #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Casting.h" @@ -22,27 +22,22 @@ using namespace llvm; using namespace object; -template -static void SwapValue(T &Value) { - Value = sys::SwapByteOrder(Value); -} - template static void SwapStruct(T &Value); template<> -void SwapStruct(macho::FatHeader &H) { - SwapValue(H.Magic); - SwapValue(H.NumFatArch); +void SwapStruct(MachO::fat_header &H) { + sys::swapByteOrder(H.magic); + sys::swapByteOrder(H.nfat_arch); } template<> -void SwapStruct(macho::FatArchHeader &H) { - SwapValue(H.CPUType); - SwapValue(H.CPUSubtype); - SwapValue(H.Offset); - SwapValue(H.Size); - SwapValue(H.Align); +void SwapStruct(MachO::fat_arch &H) { + sys::swapByteOrder(H.cputype); + sys::swapByteOrder(H.cpusubtype); + sys::swapByteOrder(H.offset); + sys::swapByteOrder(H.size); + sys::swapByteOrder(H.align); } template @@ -58,82 +53,84 @@ static T getUniversalBinaryStruct(const char *Ptr) { MachOUniversalBinary::ObjectForArch::ObjectForArch( const MachOUniversalBinary *Parent, uint32_t Index) : Parent(Parent), Index(Index) { - if (Parent == 0 || Index > Parent->getNumberOfObjects()) { + if (!Parent || Index >= Parent->getNumberOfObjects()) { clear(); } else { // Parse object header. StringRef ParentData = Parent->getData(); - const char *HeaderPos = ParentData.begin() + macho::FatHeaderSize + - Index * macho::FatArchHeaderSize; - Header = getUniversalBinaryStruct(HeaderPos); - if (ParentData.size() < Header.Offset + Header.Size) { + const char *HeaderPos = ParentData.begin() + sizeof(MachO::fat_header) + + Index * sizeof(MachO::fat_arch); + Header = getUniversalBinaryStruct(HeaderPos); + if (ParentData.size() < Header.offset + Header.size) { clear(); } } } -error_code MachOUniversalBinary::ObjectForArch::getAsObjectFile( - OwningPtr &Result) const { - if (Parent) { - StringRef ParentData = Parent->getData(); - StringRef ObjectData = ParentData.substr(Header.Offset, Header.Size); - Twine ObjectName = - Twine(Parent->getFileName()) + ":" + - Triple::getArchTypeName(MachOObjectFile::getArch(Header.CPUType)); - MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer( - ObjectData, ObjectName.str(), false); - if (ObjectFile *Obj = ObjectFile::createMachOObjectFile(ObjBuffer)) { - Result.reset(Obj); - return object_error::success; - } - } - return object_error::parse_failed; +ErrorOr> +MachOUniversalBinary::ObjectForArch::getAsObjectFile() const { + if (!Parent) + return object_error::parse_failed; + + StringRef ParentData = Parent->getData(); + StringRef ObjectData = ParentData.substr(Header.offset, Header.size); + StringRef ObjectName = Parent->getFileName(); + MemoryBufferRef ObjBuffer(ObjectData, ObjectName); + return ObjectFile::createMachOObjectFile(ObjBuffer); +} + +ErrorOr> +MachOUniversalBinary::ObjectForArch::getAsArchive() const { + if (!Parent) + return object_error::parse_failed; + + StringRef ParentData = Parent->getData(); + StringRef ObjectData = ParentData.substr(Header.offset, Header.size); + StringRef ObjectName = Parent->getFileName(); + MemoryBufferRef ObjBuffer(ObjectData, ObjectName); + return Archive::create(ObjBuffer); } void MachOUniversalBinary::anchor() { } -MachOUniversalBinary::MachOUniversalBinary(MemoryBuffer *Source, - error_code &ec) - : Binary(Binary::ID_MachOUniversalBinary, Source), - NumberOfObjects(0) { - if (Source->getBufferSize() < macho::FatHeaderSize) { +ErrorOr> +MachOUniversalBinary::create(MemoryBufferRef Source) { + std::error_code EC; + std::unique_ptr Ret( + new MachOUniversalBinary(Source, EC)); + if (EC) + return EC; + return std::move(Ret); +} + +MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source, + std::error_code &ec) + : Binary(Binary::ID_MachOUniversalBinary, Source), NumberOfObjects(0) { + if (Data.getBufferSize() < sizeof(MachO::fat_header)) { ec = object_error::invalid_file_type; return; } // Check for magic value and sufficient header size. StringRef Buf = getData(); - macho::FatHeader H = getUniversalBinaryStruct(Buf.begin()); - NumberOfObjects = H.NumFatArch; - uint32_t MinSize = macho::FatHeaderSize + - macho::FatArchHeaderSize * NumberOfObjects; - if (H.Magic != macho::HM_Universal || Buf.size() < MinSize) { + MachO::fat_header H= getUniversalBinaryStruct(Buf.begin()); + NumberOfObjects = H.nfat_arch; + uint32_t MinSize = sizeof(MachO::fat_header) + + sizeof(MachO::fat_arch) * NumberOfObjects; + if (H.magic != MachO::FAT_MAGIC || Buf.size() < MinSize) { ec = object_error::parse_failed; return; } - ec = object_error::success; + ec = std::error_code(); } -static bool getCTMForArch(Triple::ArchType Arch, mach::CPUTypeMachine &CTM) { - switch (Arch) { - case Triple::x86: CTM = mach::CTM_i386; return true; - case Triple::x86_64: CTM = mach::CTM_x86_64; return true; - case Triple::arm: CTM = mach::CTM_ARM; return true; - case Triple::sparc: CTM = mach::CTM_SPARC; return true; - case Triple::ppc: CTM = mach::CTM_PowerPC; return true; - case Triple::ppc64: CTM = mach::CTM_PowerPC64; return true; - default: return false; - } -} - -error_code -MachOUniversalBinary::getObjectForArch(Triple::ArchType Arch, - OwningPtr &Result) const { - mach::CPUTypeMachine CTM; - if (!getCTMForArch(Arch, CTM)) +ErrorOr> +MachOUniversalBinary::getObjectForArch(StringRef ArchName) const { + if (Triple(ArchName).getArch() == Triple::ArchType::UnknownArch) return object_error::arch_not_found; + for (object_iterator I = begin_objects(), E = end_objects(); I != E; ++I) { - if (I->getCPUType() == static_cast(CTM)) - return I->getAsObjectFile(Result); + if (I->getArchTypeName() == ArchName) + return I->getAsObjectFile(); } return object_error::arch_not_found; }