mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
5bbb04ae53
The Mach-O command line flag like "-arch armv7m" does not match the arch name part of its llvm Triple which is "thumbv7m-apple-darwin”. I think the best way to fix this is to have llvm::object::MachOObjectFile::getArchTriple() optionally return the name of the Mach-O arch flag that would be used with -arch that matches the CPUType and CPUSubType. Then change llvm::object::MachOUniversalBinary::ObjectForArch::getArchTypeName() to use that and change it to getArchFlagName() as the type name is really part of the Triple and the -arch flag name is a Mach-O thing for a specific Triple with a specific Mcpu value. rdar://29663637 llvm-svn: 290001
169 lines
4.9 KiB
C++
169 lines
4.9 KiB
C++
//===- MachOUniversal.h - Mach-O universal binaries -------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file declares Mach-O fat/universal binaries.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
|
|
#define LLVM_OBJECT_MACHOUNIVERSAL_H
|
|
|
|
#include "llvm/ADT/Triple.h"
|
|
#include "llvm/ADT/iterator_range.h"
|
|
#include "llvm/Object/Archive.h"
|
|
#include "llvm/Object/Binary.h"
|
|
#include "llvm/Object/MachO.h"
|
|
#include "llvm/Support/MachO.h"
|
|
|
|
namespace llvm {
|
|
class StringRef;
|
|
|
|
namespace object {
|
|
|
|
class MachOUniversalBinary : public Binary {
|
|
virtual void anchor();
|
|
|
|
uint32_t Magic;
|
|
uint32_t NumberOfObjects;
|
|
public:
|
|
class ObjectForArch {
|
|
const MachOUniversalBinary *Parent;
|
|
/// \brief Index of object in the universal binary.
|
|
uint32_t Index;
|
|
/// \brief Descriptor of the object.
|
|
MachO::fat_arch Header;
|
|
MachO::fat_arch_64 Header64;
|
|
|
|
public:
|
|
ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
|
|
|
|
void clear() {
|
|
Parent = nullptr;
|
|
Index = 0;
|
|
}
|
|
|
|
bool operator==(const ObjectForArch &Other) const {
|
|
return (Parent == Other.Parent) && (Index == Other.Index);
|
|
}
|
|
|
|
ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
|
|
uint32_t getCPUType() const {
|
|
if (Parent->getMagic() == MachO::FAT_MAGIC)
|
|
return Header.cputype;
|
|
else // Parent->getMagic() == MachO::FAT_MAGIC_64
|
|
return Header64.cputype;
|
|
}
|
|
uint32_t getCPUSubType() const {
|
|
if (Parent->getMagic() == MachO::FAT_MAGIC)
|
|
return Header.cpusubtype;
|
|
else // Parent->getMagic() == MachO::FAT_MAGIC_64
|
|
return Header64.cpusubtype;
|
|
}
|
|
uint32_t getOffset() const {
|
|
if (Parent->getMagic() == MachO::FAT_MAGIC)
|
|
return Header.offset;
|
|
else // Parent->getMagic() == MachO::FAT_MAGIC_64
|
|
return Header64.offset;
|
|
}
|
|
uint32_t getSize() const {
|
|
if (Parent->getMagic() == MachO::FAT_MAGIC)
|
|
return Header.size;
|
|
else // Parent->getMagic() == MachO::FAT_MAGIC_64
|
|
return Header64.size;
|
|
}
|
|
uint32_t getAlign() const {
|
|
if (Parent->getMagic() == MachO::FAT_MAGIC)
|
|
return Header.align;
|
|
else // Parent->getMagic() == MachO::FAT_MAGIC_64
|
|
return Header64.align;
|
|
}
|
|
uint32_t getReserved() const {
|
|
if (Parent->getMagic() == MachO::FAT_MAGIC)
|
|
return 0;
|
|
else // Parent->getMagic() == MachO::FAT_MAGIC_64
|
|
return Header64.reserved;
|
|
}
|
|
std::string getArchFlagName() const {
|
|
const char *McpuDefault, *ArchFlag;
|
|
if (Parent->getMagic() == MachO::FAT_MAGIC) {
|
|
Triple T =
|
|
MachOObjectFile::getArchTriple(Header.cputype, Header.cpusubtype,
|
|
&McpuDefault, &ArchFlag);
|
|
} else { // Parent->getMagic() == MachO::FAT_MAGIC_64
|
|
Triple T =
|
|
MachOObjectFile::getArchTriple(Header64.cputype,
|
|
Header64.cpusubtype,
|
|
&McpuDefault, &ArchFlag);
|
|
}
|
|
if (ArchFlag) {
|
|
std::string ArchFlagName(ArchFlag);
|
|
return ArchFlagName;
|
|
} else {
|
|
std::string ArchFlagName("");
|
|
return ArchFlagName;
|
|
}
|
|
}
|
|
|
|
Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
|
|
|
|
Expected<std::unique_ptr<Archive>> getAsArchive() const;
|
|
};
|
|
|
|
class object_iterator {
|
|
ObjectForArch Obj;
|
|
public:
|
|
object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
|
|
const ObjectForArch *operator->() const { return &Obj; }
|
|
const ObjectForArch &operator*() const { return Obj; }
|
|
|
|
bool operator==(const object_iterator &Other) const {
|
|
return Obj == Other.Obj;
|
|
}
|
|
bool operator!=(const object_iterator &Other) const {
|
|
return !(*this == Other);
|
|
}
|
|
|
|
object_iterator& operator++() { // Preincrement
|
|
Obj = Obj.getNext();
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
MachOUniversalBinary(MemoryBufferRef Souce, Error &Err);
|
|
static Expected<std::unique_ptr<MachOUniversalBinary>>
|
|
create(MemoryBufferRef Source);
|
|
|
|
object_iterator begin_objects() const {
|
|
return ObjectForArch(this, 0);
|
|
}
|
|
object_iterator end_objects() const {
|
|
return ObjectForArch(nullptr, 0);
|
|
}
|
|
|
|
iterator_range<object_iterator> objects() const {
|
|
return make_range(begin_objects(), end_objects());
|
|
}
|
|
|
|
uint32_t getMagic() const { return Magic; }
|
|
uint32_t getNumberOfObjects() const { return NumberOfObjects; }
|
|
|
|
// Cast methods.
|
|
static inline bool classof(Binary const *V) {
|
|
return V->isMachOUniversalBinary();
|
|
}
|
|
|
|
Expected<std::unique_ptr<MachOObjectFile>>
|
|
getObjectForArch(StringRef ArchName) const;
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
#endif
|