Files
archived-llvm/include/llvm/Object/MachOUniversal.h
Kevin Enderby c827f2cd76 Finish cleaning up most of the error handling in libObject’s MachOUniversalBinary
and its clients to use the new llvm::Error model for error handling.

Changed getAsArchive() from ErrorOr<...> to Expected<...> so now all
interfaces there use the new llvm::Error model for return values.

In the two places it had if (!Parent) this is actually a program error so changed
from returning errorCodeToError(object_error::parse_failed) to calling
report_fatal_error() with a message.

In getObjectForArch() added error messages to its two llvm::Error return values
instead of returning errorCodeToError(object_error::arch_not_found) with no
error message.

For the llvm-obdump, llvm-nm and llvm-size clients since the only binary files in
Mach-O Universal Binaries that are supported are Mach-O files or archives with
Mach-O objects, updated their logic to generate an error when a slice contains
something like an ELF binary instead of ignoring it. And added a test case for
that.

The last error stuff to be cleaned up for libObject’s MachOUniversalBinary is
the use of errorOrToExpected(Archive::create(ObjBuffer)) which needs
Archive::create() to be changed from ErrorOr<...> to Expected<...> first,
which I’ll work on next. 


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274079 91177308-0d34-0410-b5e6-96231b3b80d8
2016-06-28 23:16:13 +00:00

161 lines
4.6 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 getArchTypeName() const {
if (Parent->getMagic() == MachO::FAT_MAGIC) {
Triple T =
MachOObjectFile::getArchTriple(Header.cputype, Header.cpusubtype);
return T.getArchName();
} else { // Parent->getMagic() == MachO::FAT_MAGIC_64
Triple T =
MachOObjectFile::getArchTriple(Header64.cputype,
Header64.cpusubtype);
return T.getArchName();
}
}
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