summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp')
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp73
1 files changed, 54 insertions, 19 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
index 6fcee3bf059..9997ca0245c 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
@@ -117,6 +117,59 @@ template <typename T> static T readBigEndian(T t) {
return t;
}
+
+static bool isMachOHeader(const mach_header *mh, bool &is64, bool &swap) {
+ switch (mh->magic) {
+ case llvm::MachO::MH_MAGIC:
+ is64 = false;
+ swap = false;
+ return true;
+ case llvm::MachO::MH_MAGIC_64:
+ is64 = true;
+ swap = false;
+ return true;
+ case llvm::MachO::MH_CIGAM:
+ is64 = false;
+ swap = true;
+ return true;
+ case llvm::MachO::MH_CIGAM_64:
+ is64 = true;
+ swap = true;
+ return true;
+ default:
+ return false;
+ }
+}
+
+
+bool isThinObjectFile(StringRef path, MachOLinkingContext::Arch &arch) {
+ // Try opening and mapping file at path.
+ ErrorOr<std::unique_ptr<MemoryBuffer>> b = MemoryBuffer::getFileOrSTDIN(path);
+ if (b.getError())
+ return false;
+
+ // If file length < 32 it is too small to be mach-o object file.
+ StringRef fileBuffer = b->get()->getBuffer();
+ if (fileBuffer.size() < 32)
+ return false;
+
+ // If file buffer does not start with MH_MAGIC (and variants), not obj file.
+ const mach_header *mh = reinterpret_cast<const mach_header *>(
+ fileBuffer.begin());
+ bool is64, swap;
+ if (!isMachOHeader(mh, is64, swap))
+ return false;
+
+ // If not MH_OBJECT, not object file.
+ if (read32(swap, mh->filetype) != MH_OBJECT)
+ return false;
+
+ // Lookup up arch from cpu/subtype pair.
+ arch = MachOLinkingContext::archFromCpuType(read32(swap, mh->cputype),
+ read32(swap, mh->cpusubtype));
+ return true;
+}
+
/// Reads a mach-o file and produces an in-memory normalized view.
ErrorOr<std::unique_ptr<NormalizedFile>>
readBinary(std::unique_ptr<MemoryBuffer> &mb,
@@ -162,26 +215,8 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb,
}
bool is64, swap;
- switch (mh->magic) {
- case llvm::MachO::MH_MAGIC:
- is64 = false;
- swap = false;
- break;
- case llvm::MachO::MH_MAGIC_64:
- is64 = true;
- swap = false;
- break;
- case llvm::MachO::MH_CIGAM:
- is64 = false;
- swap = true;
- break;
- case llvm::MachO::MH_CIGAM_64:
- is64 = true;
- swap = true;
- break;
- default:
+ if (!isMachOHeader(mh, is64, swap))
return make_error_code(llvm::errc::executable_format_error);
- }
// Endian swap header, if needed.
mach_header headerCopy;
OpenPOWER on IntegriCloud