summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorKevin Enderby <enderby@apple.com>2016-06-20 22:16:18 +0000
committerKevin Enderby <enderby@apple.com>2016-06-20 22:16:18 +0000
commiteb6d110c1d0d0089c4da4b4ca9cd64460aa142f3 (patch)
tree5bb2189d83eb75d2cbe1f53e793f58dea9a65e3f /llvm/lib
parent94eb31a7a91e5c9e8b004d3bea1176a9642ef1ed (diff)
downloadbcm5719-llvm-eb6d110c1d0d0089c4da4b4ca9cd64460aa142f3.tar.gz
bcm5719-llvm-eb6d110c1d0d0089c4da4b4ca9cd64460aa142f3.zip
Add support for Darwin’s 64-bit universal files with 64-bit offsets and sizes for the objects.
Darwin added support in its Xcode 8.0 tools (released in the beta) for universal files where offsets and sizes for the objects are 64-bits to allow support for objects contained in universal files to be larger then 4gb. The change is very straight forward. There is a new magic number that differs by one bit, much like the 64-bit Mach-O files. Then there is a new structure that follow the fat_header that has the same layout but with the offset and size fields using 64-bit values instead of 32-bit values. rdar://26899493 llvm-svn: 273207
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Object/MachOUniversal.cpp58
-rw-r--r--llvm/lib/Support/Path.cpp2
2 files changed, 48 insertions, 12 deletions
diff --git a/llvm/lib/Object/MachOUniversal.cpp b/llvm/lib/Object/MachOUniversal.cpp
index 2d0ddd93f0b..8ccf4de50e0 100644
--- a/llvm/lib/Object/MachOUniversal.cpp
+++ b/llvm/lib/Object/MachOUniversal.cpp
@@ -40,6 +40,16 @@ void SwapStruct(MachO::fat_arch &H) {
sys::swapByteOrder(H.align);
}
+template<>
+void SwapStruct(MachO::fat_arch_64 &H) {
+ sys::swapByteOrder(H.cputype);
+ sys::swapByteOrder(H.cpusubtype);
+ sys::swapByteOrder(H.offset);
+ sys::swapByteOrder(H.size);
+ sys::swapByteOrder(H.align);
+ sys::swapByteOrder(H.reserved);
+}
+
template<typename T>
static T getUniversalBinaryStruct(const char *Ptr) {
T Res;
@@ -58,11 +68,20 @@ MachOUniversalBinary::ObjectForArch::ObjectForArch(
} else {
// Parse object header.
StringRef ParentData = Parent->getData();
- const char *HeaderPos = ParentData.begin() + sizeof(MachO::fat_header) +
- Index * sizeof(MachO::fat_arch);
- Header = getUniversalBinaryStruct<MachO::fat_arch>(HeaderPos);
- if (ParentData.size() < Header.offset + Header.size) {
- clear();
+ if (Parent->getMagic() == MachO::FAT_MAGIC) {
+ const char *HeaderPos = ParentData.begin() + sizeof(MachO::fat_header) +
+ Index * sizeof(MachO::fat_arch);
+ Header = getUniversalBinaryStruct<MachO::fat_arch>(HeaderPos);
+ if (ParentData.size() < Header.offset + Header.size) {
+ clear();
+ }
+ } else { // Parent->getMagic() == MachO::FAT_MAGIC_64
+ const char *HeaderPos = ParentData.begin() + sizeof(MachO::fat_header) +
+ Index * sizeof(MachO::fat_arch_64);
+ Header64 = getUniversalBinaryStruct<MachO::fat_arch_64>(HeaderPos);
+ if (ParentData.size() < Header64.offset + Header64.size) {
+ clear();
+ }
}
}
}
@@ -73,7 +92,11 @@ MachOUniversalBinary::ObjectForArch::getAsObjectFile() const {
return errorCodeToError(object_error::parse_failed);
StringRef ParentData = Parent->getData();
- StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
+ StringRef ObjectData;
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ ObjectData = ParentData.substr(Header.offset, Header.size);
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ ObjectData = ParentData.substr(Header64.offset, Header64.size);
StringRef ObjectName = Parent->getFileName();
MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
return ObjectFile::createMachOObjectFile(ObjBuffer);
@@ -85,7 +108,11 @@ MachOUniversalBinary::ObjectForArch::getAsArchive() const {
return object_error::parse_failed;
StringRef ParentData = Parent->getData();
- StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
+ StringRef ObjectData;
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ ObjectData = ParentData.substr(Header.offset, Header.size);
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ ObjectData = ParentData.substr(Header64.offset, Header64.size);
StringRef ObjectName = Parent->getFileName();
MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
return Archive::create(ObjBuffer);
@@ -105,7 +132,8 @@ MachOUniversalBinary::create(MemoryBufferRef Source) {
MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source,
std::error_code &ec)
- : Binary(Binary::ID_MachOUniversalBinary, Source), NumberOfObjects(0) {
+ : Binary(Binary::ID_MachOUniversalBinary, Source), Magic(0),
+ NumberOfObjects(0) {
if (Data.getBufferSize() < sizeof(MachO::fat_header)) {
ec = object_error::invalid_file_type;
return;
@@ -113,10 +141,18 @@ MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source,
// Check for magic value and sufficient header size.
StringRef Buf = getData();
MachO::fat_header H= getUniversalBinaryStruct<MachO::fat_header>(Buf.begin());
+ Magic = H.magic;
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) {
+ uint32_t MinSize = sizeof(MachO::fat_header);
+ if (Magic == MachO::FAT_MAGIC)
+ MinSize += sizeof(MachO::fat_arch) * NumberOfObjects;
+ else if (Magic == MachO::FAT_MAGIC_64)
+ MinSize += sizeof(MachO::fat_arch_64) * NumberOfObjects;
+ else {
+ ec = object_error::parse_failed;
+ return;
+ }
+ if (Buf.size() < MinSize) {
ec = object_error::parse_failed;
return;
}
diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp
index 406a37b2cc0..f6355d1df80 100644
--- a/llvm/lib/Support/Path.cpp
+++ b/llvm/lib/Support/Path.cpp
@@ -1049,7 +1049,7 @@ file_magic identify_magic(StringRef Magic) {
case 0xCA:
if (Magic[1] == char(0xFE) && Magic[2] == char(0xBA) &&
- Magic[3] == char(0xBE)) {
+ (Magic[3] == char(0xBE) || Magic[3] == char(0xBF))) {
// This is complicated by an overlap with Java class files.
// See the Mach-O section in /usr/share/file/magic for details.
if (Magic.size() >= 8 && Magic[7] < 43)
OpenPOWER on IntegriCloud