summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Object
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-05-27 20:26:41 +0000
committerdim <dim@FreeBSD.org>2015-05-27 20:26:41 +0000
commit5ef8fd3549d38e883a31881636be3dc2a275de20 (patch)
treebd13a22d9db57ccf3eddbc07b32c18109521d050 /contrib/llvm/lib/Object
parent77794ebe2d5718eb502c93ec32f8ccae4d8a0b7b (diff)
parent782067d0278612ee75d024b9b135c221c327e9e8 (diff)
downloadFreeBSD-src-5ef8fd3549d38e883a31881636be3dc2a275de20.zip
FreeBSD-src-5ef8fd3549d38e883a31881636be3dc2a275de20.tar.gz
Merge llvm trunk r238337 from ^/vendor/llvm/dist, resolve conflicts, and
preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/lib/Object')
-rw-r--r--contrib/llvm/lib/Object/Archive.cpp110
-rw-r--r--contrib/llvm/lib/Object/Binary.cpp1
-rw-r--r--contrib/llvm/lib/Object/COFFObjectFile.cpp81
-rw-r--r--contrib/llvm/lib/Object/ELFYAML.cpp214
-rw-r--r--contrib/llvm/lib/Object/IRObjectFile.cpp16
-rw-r--r--contrib/llvm/lib/Object/MachOObjectFile.cpp136
-rw-r--r--contrib/llvm/lib/Object/ObjectFile.cpp1
-rw-r--r--contrib/llvm/lib/Object/RecordStreamer.cpp2
-rw-r--r--contrib/llvm/lib/Object/RecordStreamer.h2
-rw-r--r--contrib/llvm/lib/Object/SymbolicFile.cpp1
10 files changed, 396 insertions, 168 deletions
diff --git a/contrib/llvm/lib/Object/Archive.cpp b/contrib/llvm/lib/Object/Archive.cpp
index 5aada91..fb91eed 100644
--- a/contrib/llvm/lib/Object/Archive.cpp
+++ b/contrib/llvm/lib/Object/Archive.cpp
@@ -20,6 +20,7 @@
using namespace llvm;
using namespace object;
+using namespace llvm::support::endian;
static const char *const Magic = "!<arch>\n";
static const char *const ThinMagic = "!<thin>\n";
@@ -110,6 +111,10 @@ uint64_t Archive::Child::getSize() const {
return Data.size() - StartOfFile;
}
+uint64_t Archive::Child::getRawSize() const {
+ return getHeader()->getSize();
+}
+
Archive::Child Archive::Child::getNext() const {
size_t SpaceToSkip = Data.size();
// If it's odd, add 1 to make it even.
@@ -125,6 +130,13 @@ Archive::Child Archive::Child::getNext() const {
return Child(Parent, NextLoc);
}
+uint64_t Archive::Child::getChildOffset() const {
+ const char *a = Parent->Data.getBuffer().data();
+ const char *c = Data.data();
+ uint64_t offset = c - a;
+ return offset;
+}
+
ErrorOr<StringRef> Archive::Child::getName() const {
StringRef name = getRawName();
// Check if it's a special name.
@@ -151,7 +163,7 @@ ErrorOr<StringRef> Archive::Child::getName() const {
return object_error::parse_failed;
// GNU long file names end with a /.
- if (Parent->kind() == K_GNU) {
+ if (Parent->kind() == K_GNU || Parent->kind() == K_MIPS64) {
StringRef::size_type End = StringRef(addr).find('/');
return StringRef(addr, End);
}
@@ -262,8 +274,16 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
return;
}
- if (Name == "/") {
+ // MIPS 64-bit ELF archives use a special format of a symbol table.
+ // This format is marked by `ar_name` field equals to "/SYM64/".
+ // For detailed description see page 96 in the following document:
+ // http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
+
+ bool has64SymTable = false;
+ if (Name == "/" || Name == "/SYM64/") {
SymbolTable = i;
+ if (Name == "/SYM64/")
+ has64SymTable = true;
++i;
if (i == e) {
@@ -274,7 +294,7 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
}
if (Name == "//") {
- Format = K_GNU;
+ Format = has64SymTable ? K_MIPS64 : K_GNU;
StringTable = i;
++i;
FirstRegular = i;
@@ -283,7 +303,7 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
}
if (Name[0] != '/') {
- Format = K_GNU;
+ Format = has64SymTable ? K_MIPS64 : K_GNU;
FirstRegular = i;
ec = object_error::success;
return;
@@ -337,11 +357,16 @@ StringRef Archive::Symbol::getName() const {
ErrorOr<Archive::child_iterator> Archive::Symbol::getMember() const {
const char *Buf = Parent->SymbolTable->getBuffer().begin();
- const char *Offsets = Buf + 4;
+ const char *Offsets = Buf;
+ if (Parent->kind() == K_MIPS64)
+ Offsets += sizeof(uint64_t);
+ else
+ Offsets += sizeof(uint32_t);
uint32_t Offset = 0;
if (Parent->kind() == K_GNU) {
- Offset = *(reinterpret_cast<const support::ubig32_t*>(Offsets)
- + SymbolIndex);
+ Offset = read32be(Offsets + SymbolIndex * 4);
+ } else if (Parent->kind() == K_MIPS64) {
+ Offset = read64be(Offsets + SymbolIndex * 8);
} else if (Parent->kind() == K_BSD) {
// The SymbolIndex is an index into the ranlib structs that start at
// Offsets (the first uint32_t is the number of bytes of the ranlib
@@ -349,36 +374,29 @@ ErrorOr<Archive::child_iterator> Archive::Symbol::getMember() const {
// being a string table offset and the second being the offset into
// the archive of the member that defines the symbol. Which is what
// is needed here.
- Offset = *(reinterpret_cast<const support::ulittle32_t *>(Offsets) +
- (SymbolIndex * 2) + 1);
+ Offset = read32le(Offsets + SymbolIndex * 8 + 4);
} else {
- uint32_t MemberCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
-
// Skip offsets.
- Buf += sizeof(support::ulittle32_t)
- + (MemberCount * sizeof(support::ulittle32_t));
-
- uint32_t SymbolCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
+ uint32_t MemberCount = read32le(Buf);
+ Buf += MemberCount * 4 + 4;
+ uint32_t SymbolCount = read32le(Buf);
if (SymbolIndex >= SymbolCount)
return object_error::parse_failed;
// Skip SymbolCount to get to the indices table.
- const char *Indices = Buf + sizeof(support::ulittle32_t);
+ const char *Indices = Buf + 4;
// Get the index of the offset in the file member offset table for this
// symbol.
- uint16_t OffsetIndex =
- *(reinterpret_cast<const support::ulittle16_t*>(Indices)
- + SymbolIndex);
+ uint16_t OffsetIndex = read16le(Indices + SymbolIndex * 2);
// Subtract 1 since OffsetIndex is 1 based.
--OffsetIndex;
if (OffsetIndex >= MemberCount)
return object_error::parse_failed;
- Offset = *(reinterpret_cast<const support::ulittle32_t*>(Offsets)
- + OffsetIndex);
+ Offset = read32le(Offsets + OffsetIndex * 4);
}
const char *Loc = Parent->getData().begin() + Offset;
@@ -404,8 +422,7 @@ Archive::Symbol Archive::Symbol::getNext() const {
// the string table followed by the string table.
const char *Buf = Parent->SymbolTable->getBuffer().begin();
uint32_t RanlibCount = 0;
- RanlibCount = (*reinterpret_cast<const support::ulittle32_t *>(Buf)) /
- (sizeof(uint32_t) * 2);
+ RanlibCount = read32le(Buf) / 8;
// If t.SymbolIndex + 1 will be past the count of symbols (the RanlibCount)
// don't change the t.StringIndex as we don't want to reference a ranlib
// past RanlibCount.
@@ -413,10 +430,8 @@ Archive::Symbol Archive::Symbol::getNext() const {
const char *Ranlibs = Buf + 4;
uint32_t CurRanStrx = 0;
uint32_t NextRanStrx = 0;
- CurRanStrx = *(reinterpret_cast<const support::ulittle32_t *>(Ranlibs) +
- (t.SymbolIndex * 2));
- NextRanStrx = *(reinterpret_cast<const support::ulittle32_t *>(Ranlibs) +
- ((t.SymbolIndex + 1) * 2));
+ CurRanStrx = read32le(Ranlibs + t.SymbolIndex * 8);
+ NextRanStrx = read32le(Ranlibs + (t.SymbolIndex + 1) * 8);
t.StringIndex -= CurRanStrx;
t.StringIndex += NextRanStrx;
}
@@ -436,8 +451,11 @@ Archive::symbol_iterator Archive::symbol_begin() const {
const char *buf = SymbolTable->getBuffer().begin();
if (kind() == K_GNU) {
uint32_t symbol_count = 0;
- symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
+ symbol_count = read32be(buf);
buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
+ } else if (kind() == K_MIPS64) {
+ uint64_t symbol_count = read64be(buf);
+ buf += sizeof(uint64_t) + (symbol_count * (sizeof(uint64_t)));
} else if (kind() == K_BSD) {
// The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
// which is the number of bytes of ranlib structs that follow. The ranlib
@@ -446,11 +464,10 @@ Archive::symbol_iterator Archive::symbol_begin() const {
// define the symbol. After that the next uint32_t is the byte count of
// the string table followed by the string table.
uint32_t ranlib_count = 0;
- ranlib_count = (*reinterpret_cast<const support::ulittle32_t *>(buf)) /
- (sizeof(uint32_t) * 2);
+ ranlib_count = read32le(buf) / 8;
const char *ranlibs = buf + 4;
uint32_t ran_strx = 0;
- ran_strx = *(reinterpret_cast<const support::ulittle32_t *>(ranlibs));
+ ran_strx = read32le(ranlibs);
buf += sizeof(uint32_t) + (ranlib_count * (2 * (sizeof(uint32_t))));
// Skip the byte count of the string table.
buf += sizeof(uint32_t);
@@ -458,9 +475,9 @@ Archive::symbol_iterator Archive::symbol_begin() const {
} else {
uint32_t member_count = 0;
uint32_t symbol_count = 0;
- member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+ member_count = read32le(buf);
buf += 4 + (member_count * 4); // Skip offsets.
- symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+ symbol_count = read32le(buf);
buf += 4 + (symbol_count * 2); // Skip indices.
}
uint32_t string_start_offset = buf - SymbolTable->getBuffer().begin();
@@ -470,22 +487,21 @@ Archive::symbol_iterator Archive::symbol_begin() const {
Archive::symbol_iterator Archive::symbol_end() const {
if (!hasSymbolTable())
return symbol_iterator(Symbol(this, 0, 0));
+ return symbol_iterator(Symbol(this, getNumberOfSymbols(), 0));
+}
+uint32_t Archive::getNumberOfSymbols() const {
const char *buf = SymbolTable->getBuffer().begin();
- uint32_t symbol_count = 0;
- if (kind() == K_GNU) {
- symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
- } else if (kind() == K_BSD) {
- symbol_count = (*reinterpret_cast<const support::ulittle32_t *>(buf)) /
- (sizeof(uint32_t) * 2);
- } else {
- uint32_t member_count = 0;
- member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
- buf += 4 + (member_count * 4); // Skip offsets.
- symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
- }
- return symbol_iterator(
- Symbol(this, symbol_count, 0));
+ if (kind() == K_GNU)
+ return read32be(buf);
+ if (kind() == K_MIPS64)
+ return read64be(buf);
+ if (kind() == K_BSD)
+ return read32le(buf) / 8;
+ uint32_t member_count = 0;
+ member_count = read32le(buf);
+ buf += 4 + (member_count * 4); // Skip offsets.
+ return read32le(buf);
}
Archive::child_iterator Archive::findSym(StringRef name) const {
diff --git a/contrib/llvm/lib/Object/Binary.cpp b/contrib/llvm/lib/Object/Binary.cpp
index c56eeb1..a2b167a 100644
--- a/contrib/llvm/lib/Object/Binary.cpp
+++ b/contrib/llvm/lib/Object/Binary.cpp
@@ -58,6 +58,7 @@ ErrorOr<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
case sys::fs::file_magic::macho_bundle:
case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
case sys::fs::file_magic::macho_dsym_companion:
+ case sys::fs::file_magic::macho_kext_bundle:
case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
diff --git a/contrib/llvm/lib/Object/COFFObjectFile.cpp b/contrib/llvm/lib/Object/COFFObjectFile.cpp
index cde6fdc..74709c8 100644
--- a/contrib/llvm/lib/Object/COFFObjectFile.cpp
+++ b/contrib/llvm/lib/Object/COFFObjectFile.cpp
@@ -190,7 +190,9 @@ std::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
Result = SymbolRef::ST_Data;
} else if (Symb.isFileRecord()) {
Result = SymbolRef::ST_File;
- } else if (SectionNumber == COFF::IMAGE_SYM_DEBUG) {
+ } else if (SectionNumber == COFF::IMAGE_SYM_DEBUG ||
+ Symb.isSectionDefinition()) {
+ // TODO: perhaps we need a new symbol type ST_Section.
Result = SymbolRef::ST_Debug;
} else if (!COFF::isReservedSectionNumber(SectionNumber)) {
const coff_section *Section = nullptr;
@@ -238,59 +240,10 @@ std::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref,
uint64_t &Result) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
- if (Symb.isAnyUndefined()) {
- Result = UnknownAddressOrSize;
- return object_error::success;
- }
- if (Symb.isCommon()) {
+ if (Symb.isCommon())
Result = Symb.getValue();
- return object_error::success;
- }
-
- // Let's attempt to get the size of the symbol by looking at the address of
- // the symbol after the symbol in question.
- uint64_t SymbAddr;
- if (std::error_code EC = getSymbolAddress(Ref, SymbAddr))
- return EC;
- int32_t SectionNumber = Symb.getSectionNumber();
- if (COFF::isReservedSectionNumber(SectionNumber)) {
- // Absolute and debug symbols aren't sorted in any interesting way.
- Result = 0;
- return object_error::success;
- }
- const section_iterator SecEnd = section_end();
- uint64_t AfterAddr = UnknownAddressOrSize;
- for (const symbol_iterator &SymbI : symbols()) {
- section_iterator SecI = SecEnd;
- if (std::error_code EC = SymbI->getSection(SecI))
- return EC;
- // Check the symbol's section, skip it if it's in the wrong section.
- // First, make sure it is in any section.
- if (SecI == SecEnd)
- continue;
- // Second, make sure it is in the same section as the symbol in question.
- if (!sectionContainsSymbol(SecI->getRawDataRefImpl(), Ref))
- continue;
- uint64_t Addr;
- if (std::error_code EC = SymbI->getAddress(Addr))
- return EC;
- // We want to compare our symbol in question with the closest possible
- // symbol that comes after.
- if (AfterAddr > Addr && Addr > SymbAddr)
- AfterAddr = Addr;
- }
- if (AfterAddr == UnknownAddressOrSize) {
- // No symbol comes after this one, assume that everything after our symbol
- // is part of it.
- const coff_section *Section = nullptr;
- if (std::error_code EC = getSection(SectionNumber, Section))
- return EC;
- Result = Section->SizeOfRawData - Symb.getValue();
- } else {
- // Take the difference between our symbol and the symbol that comes after
- // our symbol.
- Result = AfterAddr - SymbAddr;
- }
+ else
+ Result = UnknownAddressOrSize;
return object_error::success;
}
@@ -359,12 +312,17 @@ bool COFFObjectFile::isSectionData(DataRefImpl Ref) const {
bool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const {
const coff_section *Sec = toSec(Ref);
- return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
+ const uint32_t BssFlags = COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ |
+ COFF::IMAGE_SCN_MEM_WRITE;
+ return (Sec->Characteristics & BssFlags) == BssFlags;
}
bool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const {
const coff_section *Sec = toSec(Ref);
- return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
+ // In COFF, a virtual section won't have any in-file
+ // content, so the file pointer to the content will be zero.
+ return Sec->PointerToRawData == 0;
}
bool COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
@@ -1037,6 +995,19 @@ symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
return symbol_iterator(SymbolRef(Ref, this));
}
+section_iterator COFFObjectFile::getRelocationSection(DataRefImpl Rel) const {
+ symbol_iterator Sym = getRelocationSymbol(Rel);
+ if (Sym == symbol_end())
+ return section_end();
+ COFFSymbolRef Symb = getCOFFSymbol(*Sym);
+ if (!Symb.isSection())
+ return section_end();
+ section_iterator Res(section_end());
+ if (getSymbolSection(Sym->getRawDataRefImpl(),Res))
+ return section_end();
+ return Res;
+}
+
std::error_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
uint64_t &Res) const {
const coff_relocation* R = toRel(Rel);
diff --git a/contrib/llvm/lib/Object/ELFYAML.cpp b/contrib/llvm/lib/Object/ELFYAML.cpp
index 7e35fb5..78087d6 100644
--- a/contrib/llvm/lib/Object/ELFYAML.cpp
+++ b/contrib/llvm/lib/Object/ELFYAML.cpp
@@ -13,6 +13,7 @@
#include "llvm/Object/ELFYAML.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/MipsABIFlags.h"
namespace llvm {
@@ -30,6 +31,7 @@ ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration(IO &IO,
ECase(ET_DYN)
ECase(ET_CORE)
#undef ECase
+ IO.enumFallback<Hex16>(Value);
}
void
@@ -234,6 +236,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
ECase(ELFOSABI_NSK)
ECase(ELFOSABI_AROS)
ECase(ELFOSABI_FENIXOS)
+ ECase(ELFOSABI_CLOUDABI)
ECase(ELFOSABI_C6000_ELFABI)
ECase(ELFOSABI_C6000_LINUX)
ECase(ELFOSABI_ARM)
@@ -264,10 +267,33 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
BCase(EF_MIPS_CPIC)
BCase(EF_MIPS_ABI2)
BCase(EF_MIPS_32BITMODE)
+ BCase(EF_MIPS_FP64)
BCase(EF_MIPS_NAN2008)
- BCase(EF_MIPS_ABI_O32)
BCase(EF_MIPS_MICROMIPS)
BCase(EF_MIPS_ARCH_ASE_M16)
+ BCase(EF_MIPS_ARCH_ASE_MDMX)
+ BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI)
+ BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI)
+ BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI)
+ BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI)
+ BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH)
+ BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH)
BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH)
BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH)
BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH)
@@ -414,6 +440,16 @@ void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO,
#undef BCaseMask
}
+void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration(
+ IO &IO, ELFYAML::ELF_RSS &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X);
+ ECase(RSS_UNDEF)
+ ECase(RSS_GP)
+ ECase(RSS_GP0)
+ ECase(RSS_LOC)
+#undef ECase
+}
+
void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
IO &IO, ELFYAML::ELF_REL &Value) {
const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
@@ -444,6 +480,93 @@ void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
#undef ELF_RELOC
}
+void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration(
+ IO &IO, ELFYAML::MIPS_AFL_REG &Value) {
+#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X);
+ ECase(REG_NONE)
+ ECase(REG_32)
+ ECase(REG_64)
+ ECase(REG_128)
+#undef ECase
+}
+
+void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration(
+ IO &IO, ELFYAML::MIPS_ABI_FP &Value) {
+#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X);
+ ECase(FP_ANY)
+ ECase(FP_DOUBLE)
+ ECase(FP_SINGLE)
+ ECase(FP_SOFT)
+ ECase(FP_OLD_64)
+ ECase(FP_XX)
+ ECase(FP_64)
+ ECase(FP_64A)
+#undef ECase
+}
+
+void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration(
+ IO &IO, ELFYAML::MIPS_AFL_EXT &Value) {
+#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X);
+ ECase(EXT_NONE)
+ ECase(EXT_XLR)
+ ECase(EXT_OCTEON2)
+ ECase(EXT_OCTEONP)
+ ECase(EXT_LOONGSON_3A)
+ ECase(EXT_OCTEON)
+ ECase(EXT_5900)
+ ECase(EXT_4650)
+ ECase(EXT_4010)
+ ECase(EXT_4100)
+ ECase(EXT_3900)
+ ECase(EXT_10000)
+ ECase(EXT_SB1)
+ ECase(EXT_4111)
+ ECase(EXT_4120)
+ ECase(EXT_5400)
+ ECase(EXT_5500)
+ ECase(EXT_LOONGSON_2E)
+ ECase(EXT_LOONGSON_2F)
+ ECase(EXT_OCTEON3)
+#undef ECase
+}
+
+void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration(
+ IO &IO, ELFYAML::MIPS_ISA &Value) {
+ IO.enumCase(Value, "MIPS1", 1);
+ IO.enumCase(Value, "MIPS2", 2);
+ IO.enumCase(Value, "MIPS3", 3);
+ IO.enumCase(Value, "MIPS4", 4);
+ IO.enumCase(Value, "MIPS5", 5);
+ IO.enumCase(Value, "MIPS32", 32);
+ IO.enumCase(Value, "MIPS64", 64);
+}
+
+void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset(
+ IO &IO, ELFYAML::MIPS_AFL_ASE &Value) {
+#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X);
+ BCase(DSP)
+ BCase(DSPR2)
+ BCase(EVA)
+ BCase(MCU)
+ BCase(MDMX)
+ BCase(MIPS3D)
+ BCase(MT)
+ BCase(SMARTMIPS)
+ BCase(VIRT)
+ BCase(MSA)
+ BCase(MIPS16)
+ BCase(MICROMIPS)
+ BCase(XPA)
+#undef BCase
+}
+
+void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset(
+ IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) {
+#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X);
+ BCase(ODDSPREG)
+#undef BCase
+}
+
void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
ELFYAML::FileHeader &FileHdr) {
IO.mapRequired("Class", FileHdr.Class);
@@ -495,6 +618,7 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
IO.mapOptional("Address", Section.Address, Hex64(0));
IO.mapOptional("Link", Section.Link, StringRef());
IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
+ IO.mapOptional("Info", Section.Info, StringRef());
}
static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
@@ -505,10 +629,39 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
commonSectionMapping(IO, Section);
- IO.mapOptional("Info", Section.Info, StringRef());
IO.mapOptional("Relocations", Section.Relocations);
}
+static void groupSectionMapping(IO &IO, ELFYAML::Group &group) {
+ commonSectionMapping(IO, group);
+ IO.mapRequired("Members", group.Members);
+}
+
+void MappingTraits<ELFYAML::SectionOrType>::mapping(
+ IO &IO, ELFYAML::SectionOrType &sectionOrType) {
+ IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
+}
+
+static void sectionMapping(IO &IO, ELFYAML::MipsABIFlags &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Version", Section.Version, Hex16(0));
+ IO.mapRequired("ISA", Section.ISALevel);
+ IO.mapOptional("ISARevision", Section.ISARevision, Hex8(0));
+ IO.mapOptional("ISAExtension", Section.ISAExtension,
+ ELFYAML::MIPS_AFL_EXT(Mips::AFL_EXT_NONE));
+ IO.mapOptional("ASEs", Section.ASEs, ELFYAML::MIPS_AFL_ASE(0));
+ IO.mapOptional("FpABI", Section.FpABI,
+ ELFYAML::MIPS_ABI_FP(Mips::Val_GNU_MIPS_ABI_FP_ANY));
+ IO.mapOptional("GPRSize", Section.GPRSize,
+ ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
+ IO.mapOptional("CPR1Size", Section.CPR1Size,
+ ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
+ IO.mapOptional("CPR2Size", Section.CPR2Size,
+ ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
+ IO.mapOptional("Flags1", Section.Flags1, ELFYAML::MIPS_AFL_FLAGS1(0));
+ IO.mapOptional("Flags2", Section.Flags2, Hex32(0));
+}
+
void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
IO &IO, std::unique_ptr<ELFYAML::Section> &Section) {
ELFYAML::ELF_SHT sectionType;
@@ -524,6 +677,16 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
Section.reset(new ELFYAML::RelocationSection());
sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
break;
+ case ELF::SHT_GROUP:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::Group());
+ groupSectionMapping(IO, *cast<ELFYAML::Group>(Section.get()));
+ break;
+ case ELF::SHT_MIPS_ABIFLAGS:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::MipsABIFlags());
+ sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
+ break;
default:
if (!IO.outputting())
Section.reset(new ELFYAML::RawContentSection());
@@ -539,12 +702,49 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate(
return "Section size must be greater or equal to the content size";
}
+namespace {
+struct NormalizedMips64RelType {
+ NormalizedMips64RelType(IO &)
+ : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
+ Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
+ Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
+ SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {}
+ NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original)
+ : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF),
+ Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {}
+
+ ELFYAML::ELF_REL denormalize(IO &) {
+ ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24;
+ return Res;
+ }
+
+ ELFYAML::ELF_REL Type;
+ ELFYAML::ELF_REL Type2;
+ ELFYAML::ELF_REL Type3;
+ ELFYAML::ELF_RSS SpecSym;
+};
+}
+
void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
ELFYAML::Relocation &Rel) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+
IO.mapRequired("Offset", Rel.Offset);
IO.mapRequired("Symbol", Rel.Symbol);
- IO.mapRequired("Type", Rel.Type);
- IO.mapOptional("Addend", Rel.Addend);
+
+ if (Object->Header.Machine == ELFYAML::ELF_EM(ELF::EM_MIPS) &&
+ Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) {
+ MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key(
+ IO, Rel.Type);
+ IO.mapRequired("Type", Key->Type);
+ IO.mapOptional("Type2", Key->Type2, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
+ IO.mapOptional("Type3", Key->Type3, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
+ IO.mapOptional("SpecSym", Key->SpecSym, ELFYAML::ELF_RSS(ELF::RSS_UNDEF));
+ } else
+ IO.mapRequired("Type", Rel.Type);
+
+ IO.mapOptional("Addend", Rel.Addend, (int64_t)0);
}
void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
@@ -556,5 +756,11 @@ void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
IO.setContext(nullptr);
}
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
+
} // end namespace yaml
} // end namespace llvm
diff --git a/contrib/llvm/lib/Object/IRObjectFile.cpp b/contrib/llvm/lib/Object/IRObjectFile.cpp
index 423ed9e..c12c5d4 100644
--- a/contrib/llvm/lib/Object/IRObjectFile.cpp
+++ b/contrib/llvm/lib/Object/IRObjectFile.cpp
@@ -13,6 +13,7 @@
#include "llvm/Object/IRObjectFile.h"
#include "RecordStreamer.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/LLVMContext.h"
@@ -24,6 +25,7 @@
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -35,12 +37,9 @@ using namespace object;
IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
: SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) {
- // If we have a DataLayout, setup a mangler.
- const DataLayout *DL = M->getDataLayout();
- if (!DL)
- return;
-
- Mang.reset(new Mangler(DL));
+ // Setup a mangler with the DataLayout.
+ const DataLayout &DL = M->getDataLayout();
+ Mang.reset(new Mangler(&DL));
const std::string &InlineAsm = M->getModuleInlineAsm();
if (InlineAsm.empty())
@@ -73,6 +72,7 @@ IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx);
std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx));
+ T->createNullTargetStreamer(*Streamer);
std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
SourceMgr SrcMgr;
@@ -301,7 +301,9 @@ llvm::object::IRObjectFile::create(MemoryBufferRef Object,
std::unique_ptr<MemoryBuffer> Buff(
MemoryBuffer::getMemBuffer(BCOrErr.get(), false));
- ErrorOr<Module *> MOrErr = getLazyBitcodeModule(std::move(Buff), Context);
+ ErrorOr<Module *> MOrErr =
+ getLazyBitcodeModule(std::move(Buff), Context, nullptr,
+ /*ShouldLazyLoadMetadata*/ true);
if (std::error_code EC = MOrErr.getError())
return EC;
diff --git a/contrib/llvm/lib/Object/MachOObjectFile.cpp b/contrib/llvm/lib/Object/MachOObjectFile.cpp
index e476976..79f8100 100644
--- a/contrib/llvm/lib/Object/MachOObjectFile.cpp
+++ b/contrib/llvm/lib/Object/MachOObjectFile.cpp
@@ -38,8 +38,12 @@ namespace {
};
}
-template<typename T>
+template <typename T>
static T getStruct(const MachOObjectFile *O, const char *P) {
+ // Don't read before the beginning or past the end of the file
+ if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
+ report_fatal_error("Malformed MachO file.");
+
T Cmd;
memcpy(&Cmd, P, sizeof(T));
if (O->isLittleEndian() != sys::IsLittleEndianHost)
@@ -47,15 +51,26 @@ static T getStruct(const MachOObjectFile *O, const char *P) {
return Cmd;
}
+template <typename SegmentCmd>
+static uint32_t getSegmentLoadCommandNumSections(const SegmentCmd &S,
+ uint32_t Cmdsize) {
+ const unsigned SectionSize = sizeof(SegmentCmd);
+ if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
+ S.nsects * SectionSize > Cmdsize - sizeof(S))
+ report_fatal_error(
+ "Number of sections too large for size of load command.");
+ return S.nsects;
+}
+
static uint32_t
getSegmentLoadCommandNumSections(const MachOObjectFile *O,
const MachOObjectFile::LoadCommandInfo &L) {
- if (O->is64Bit()) {
- MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
- return S.nsects;
- }
- MachO::segment_command S = O->getSegmentLoadCommand(L);
- return S.nsects;
+ if (O->is64Bit())
+ return getSegmentLoadCommandNumSections(O->getSegment64LoadCommand(L),
+ L.C.cmdsize);
+
+ return getSegmentLoadCommandNumSections(O->getSegmentLoadCommand(L),
+ L.C.cmdsize);
}
static bool isPageZeroSegment(const MachOObjectFile *O,
@@ -233,8 +248,9 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
bool Is64bits, std::error_code &EC)
: ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
- DataInCodeLoadCmd(nullptr), DyldInfoLoadCmd(nullptr),
- UuidLoadCmd(nullptr), HasPageZeroSegment(false) {
+ DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
+ DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
+ HasPageZeroSegment(false) {
uint32_t LoadCommandCount = this->getHeader().ncmds;
if (LoadCommandCount == 0)
return;
@@ -265,6 +281,13 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
return;
}
DataInCodeLoadCmd = Load.Ptr;
+ } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
+ // Multiple linker optimization hint tables
+ if (LinkOptHintsLoadCmd) {
+ EC = object_error::parse_failed;
+ return;
+ }
+ LinkOptHintsLoadCmd = Load.Ptr;
} else if (Load.C.cmd == MachO::LC_DYLD_INFO ||
Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
// Multiple dyldinfo load commands
@@ -281,6 +304,12 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
}
UuidLoadCmd = Load.Ptr;
} else if (Load.C.cmd == SegmentLoadType) {
+ const unsigned SegmentLoadSize = this->is64Bit()
+ ? sizeof(MachO::segment_command_64)
+ : sizeof(MachO::segment_command);
+ if (Load.C.cmdsize < SegmentLoadSize)
+ report_fatal_error("Segment load command size is too small.");
+
uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
for (unsigned J = 0; J < NumSections; ++J) {
const char *Sec = getSectionPtr(this, Load, J);
@@ -315,6 +344,9 @@ std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
StringRef StringTable = getStringTableData();
MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
const char *Start = &StringTable.data()[Entry.n_strx];
+ if (Start < getData().begin() || Start >= getData().end())
+ report_fatal_error(
+ "Symbol name entry points before beginning or past end of file.");
Res = StringRef(Start);
return object_error::success;
}
@@ -383,49 +415,13 @@ std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
uint64_t &Result) const {
- uint64_t BeginOffset;
- uint64_t EndOffset = 0;
- uint8_t SectionIndex;
-
- MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
uint64_t Value;
getSymbolAddress(DRI, Value);
- if (Value == UnknownAddressOrSize) {
+ uint32_t flags = getSymbolFlags(DRI);
+ if (flags & SymbolRef::SF_Common)
+ Result = Value;
+ else
Result = UnknownAddressOrSize;
- return object_error::success;
- }
-
- BeginOffset = Value;
-
- SectionIndex = Entry.n_sect;
- if (!SectionIndex) {
- uint32_t flags = getSymbolFlags(DRI);
- if (flags & SymbolRef::SF_Common)
- Result = Value;
- else
- Result = UnknownAddressOrSize;
- return object_error::success;
- }
- // Unfortunately symbols are unsorted so we need to touch all
- // symbols from load command
- for (const SymbolRef &Symbol : symbols()) {
- DataRefImpl DRI = Symbol.getRawDataRefImpl();
- Entry = getSymbolTableEntryBase(this, DRI);
- getSymbolAddress(DRI, Value);
- if (Value == UnknownAddressOrSize)
- continue;
- if (Entry.n_sect == SectionIndex && Value > BeginOffset)
- if (!EndOffset || Value < EndOffset)
- EndOffset = Value;
- }
- if (!EndOffset) {
- DataRefImpl Sec;
- Sec.d.a = SectionIndex-1;
- uint64_t Size = getSectionSize(Sec);
- EndOffset = getSectionAddress(Sec);
- EndOffset += Size;
- }
- Result = EndOffset - BeginOffset;
return object_error::success;
}
@@ -478,6 +474,9 @@ uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
if (Value && Value != UnknownAddressOrSize)
Result |= SymbolRef::SF_Common;
}
+
+ if (!(MachOType & MachO::N_PEXT))
+ Result |= SymbolRef::SF_Exported;
}
if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
@@ -502,6 +501,8 @@ std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
} else {
DataRefImpl DRI;
DRI.d.a = index - 1;
+ if (DRI.d.a >= Sections.size())
+ report_fatal_error("getSymbolSection: Invalid section index.");
Res = section_iterator(SectionRef(DRI, this));
}
@@ -675,6 +676,11 @@ MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
return symbol_iterator(SymbolRef(Sym, this));
}
+section_iterator
+MachOObjectFile::getRelocationSection(DataRefImpl Rel) const {
+ return section_iterator(getAnyRelocationSection(getRelocation(Rel)));
+}
+
std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
uint64_t &Res) const {
MachO::any_relocation_info RE = getRelocation(Rel);
@@ -1201,7 +1207,8 @@ basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
return basic_symbol_iterator(SymbolRef(DRI, this));
MachO::symtab_command Symtab = getSymtabLoadCommand();
- assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
+ if (Index >= Symtab.nsyms)
+ report_fatal_error("Requested symbol index is out of range.");
unsigned SymbolTableEntrySize =
is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
@@ -1501,7 +1508,7 @@ bool ExportEntry::operator==(const ExportEntry &Other) const {
if (Stack.size() != Other.Stack.size())
return false;
// Not equal if different cumulative strings.
- if (!CumulativeString.str().equals(Other.CumulativeString.str()))
+ if (!CumulativeString.equals(Other.CumulativeString))
return false;
// Equal if all nodes in both stacks match.
for (unsigned i=0; i < Stack.size(); ++i) {
@@ -1523,7 +1530,7 @@ uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) {
}
StringRef ExportEntry::name() const {
- return CumulativeString.str();
+ return CumulativeString;
}
uint64_t ExportEntry::flags() const {
@@ -2105,6 +2112,7 @@ MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
ArrayRef<char>
MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
+ assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
const section_base *Base =
reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
return makeArrayRef(Base->sectname);
@@ -2112,6 +2120,7 @@ MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
ArrayRef<char>
MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
+ assert(Sec.d.a < Sections.size() && "Should have detected this earlier");
const section_base *Base =
reinterpret_cast<const section_base *>(Sections[Sec.d.a]);
return makeArrayRef(Base->segname);
@@ -2184,7 +2193,7 @@ MachOObjectFile::getAnyRelocationType(
}
SectionRef
-MachOObjectFile::getRelocationSection(
+MachOObjectFile::getAnyRelocationSection(
const MachO::any_relocation_info &RE) const {
if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
return *section_end();
@@ -2202,6 +2211,8 @@ MachOObjectFile::getFirstLoadCommandInfo() const {
sizeof(MachO::mach_header);
Load.Ptr = getPtr(this, HeaderSize);
Load.C = getStruct<MachO::load_command>(this, Load.Ptr);
+ if (Load.C.cmdsize < 8)
+ report_fatal_error("Load command with size < 8 bytes.");
return Load;
}
@@ -2210,14 +2221,18 @@ MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
MachOObjectFile::LoadCommandInfo Next;
Next.Ptr = L.Ptr + L.C.cmdsize;
Next.C = getStruct<MachO::load_command>(this, Next.Ptr);
+ if (Next.C.cmdsize < 8)
+ report_fatal_error("Load command with size < 8 bytes.");
return Next;
}
MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
+ assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
return getStruct<MachO::section>(this, Sections[DRI.d.a]);
}
MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
+ assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
}
@@ -2455,6 +2470,21 @@ MachOObjectFile::getDataInCodeLoadCommand() const {
return Cmd;
}
+MachO::linkedit_data_command
+MachOObjectFile::getLinkOptHintsLoadCommand() const {
+ if (LinkOptHintsLoadCmd)
+ return getStruct<MachO::linkedit_data_command>(this, LinkOptHintsLoadCmd);
+
+ // If there is no LinkOptHintsLoadCmd return a load command with zero'ed
+ // fields.
+ MachO::linkedit_data_command Cmd;
+ Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT;
+ Cmd.cmdsize = sizeof(MachO::linkedit_data_command);
+ Cmd.dataoff = 0;
+ Cmd.datasize = 0;
+ return Cmd;
+}
+
ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const {
if (!DyldInfoLoadCmd)
return ArrayRef<uint8_t>();
diff --git a/contrib/llvm/lib/Object/ObjectFile.cpp b/contrib/llvm/lib/Object/ObjectFile.cpp
index fd78271..01b7654 100644
--- a/contrib/llvm/lib/Object/ObjectFile.cpp
+++ b/contrib/llvm/lib/Object/ObjectFile.cpp
@@ -76,6 +76,7 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type) {
case sys::fs::file_magic::macho_bundle:
case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
case sys::fs::file_magic::macho_dsym_companion:
+ case sys::fs::file_magic::macho_kext_bundle:
return createMachOObjectFile(Object);
case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library:
diff --git a/contrib/llvm/lib/Object/RecordStreamer.cpp b/contrib/llvm/lib/Object/RecordStreamer.cpp
index 081fadd..42dbd3e 100644
--- a/contrib/llvm/lib/Object/RecordStreamer.cpp
+++ b/contrib/llvm/lib/Object/RecordStreamer.cpp
@@ -89,7 +89,7 @@ bool RecordStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
return true;
}
-void RecordStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
+void RecordStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
markDefined(*Symbol);
}
diff --git a/contrib/llvm/lib/Object/RecordStreamer.h b/contrib/llvm/lib/Object/RecordStreamer.h
index 7dacbdf..d861061 100644
--- a/contrib/llvm/lib/Object/RecordStreamer.h
+++ b/contrib/llvm/lib/Object/RecordStreamer.h
@@ -33,7 +33,7 @@ public:
void EmitLabel(MCSymbol *Symbol) override;
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
- void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
diff --git a/contrib/llvm/lib/Object/SymbolicFile.cpp b/contrib/llvm/lib/Object/SymbolicFile.cpp
index de98a12..854e68e 100644
--- a/contrib/llvm/lib/Object/SymbolicFile.cpp
+++ b/contrib/llvm/lib/Object/SymbolicFile.cpp
@@ -53,6 +53,7 @@ ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile(
case sys::fs::file_magic::macho_bundle:
case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
case sys::fs::file_magic::macho_dsym_companion:
+ case sys::fs::file_magic::macho_kext_bundle:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
return ObjectFile::createObjectFile(Object, Type);
OpenPOWER on IntegriCloud