summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter')
-rw-r--r--lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp5
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFile.h2
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp73
3 files changed, 61 insertions, 19 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
index 4ef1b625c4c..4d2304a73d8 100644
--- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
@@ -11,6 +11,7 @@
#include "ArchHandler.h"
#include "File.h"
+#include "MachONormalizedFile.h"
#include "MachOPasses.h"
#include "lld/Core/PassManager.h"
@@ -125,6 +126,10 @@ uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
llvm_unreachable("Unknown arch type");
}
+bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
+ return mach_o::normalized::isThinObjectFile(path, arch);
+}
+
MachOLinkingContext::MachOLinkingContext()
: _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
_doNothing(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
index c6e2a3a9b75..441bf45299a 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
@@ -252,6 +252,8 @@ struct NormalizedFile {
BumpPtrAllocator ownedAllocations;
};
+/// Tests if a file is a non-fat mach-o object file.
+bool isThinObjectFile(StringRef path, MachOLinkingContext::Arch &arch);
/// Reads a mach-o file and produces an in-memory normalized view.
ErrorOr<std::unique_ptr<NormalizedFile>>
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