diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 13:13:10 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 13:13:10 +0000 |
commit | 7d523365ff1a3cc95bc058b33102500f61e8166d (patch) | |
tree | b466a4817f79516eb1df8eae92bccf62ecc84003 /contrib/llvm/lib/Object | |
parent | e3b65fde506060bec5cd110fcf03b440bd0eea1d (diff) | |
parent | dd58ef019b700900793a1eb48b52123db01b654e (diff) |
Update llvm to trunk r256633.
Notes
Notes:
svn path=/projects/clang380-import/; revision=292941
Diffstat (limited to 'contrib/llvm/lib/Object')
-rw-r--r-- | contrib/llvm/lib/Object/Archive.cpp | 208 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/ArchiveWriter.cpp | 117 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/COFFObjectFile.cpp | 56 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/COFFYAML.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/ELF.cpp | 1 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/ELFYAML.cpp | 33 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/Error.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/FunctionIndexObjectFile.cpp | 143 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/IRObjectFile.cpp | 8 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/MachOObjectFile.cpp | 175 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/MachOUniversal.cpp | 16 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/Object.cpp | 4 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/ObjectFile.cpp | 6 | ||||
-rw-r--r-- | contrib/llvm/lib/Object/SymbolicFile.cpp | 5 |
14 files changed, 553 insertions, 223 deletions
diff --git a/contrib/llvm/lib/Object/Archive.cpp b/contrib/llvm/lib/Object/Archive.cpp index d4821196a6cf..99b0650c8b7e 100644 --- a/contrib/llvm/lib/Object/Archive.cpp +++ b/contrib/llvm/lib/Object/Archive.cpp @@ -43,10 +43,10 @@ StringRef ArchiveMemberHeader::getName() const { return llvm::StringRef(Name, end); } -uint32_t ArchiveMemberHeader::getSize() const { +ErrorOr<uint32_t> ArchiveMemberHeader::getSize() const { uint32_t Ret; if (llvm::StringRef(Size, sizeof(Size)).rtrim(" ").getAsInteger(10, Ret)) - llvm_unreachable("Size is not a decimal number."); + return object_error::parse_failed; // Size is not a decimal number. return Ret; } @@ -82,22 +82,30 @@ unsigned ArchiveMemberHeader::getGID() const { return Ret; } -Archive::Child::Child(const Archive *Parent, const char *Start) +Archive::Child::Child(const Archive *Parent, StringRef Data, + uint16_t StartOfFile) + : Parent(Parent), Data(Data), StartOfFile(StartOfFile) {} + +Archive::Child::Child(const Archive *Parent, const char *Start, + std::error_code *EC) : Parent(Parent) { if (!Start) return; - const ArchiveMemberHeader *Header = - reinterpret_cast<const ArchiveMemberHeader *>(Start); uint64_t Size = sizeof(ArchiveMemberHeader); - if (!Parent->IsThin || Header->getName() == "/" || Header->getName() == "//") - Size += Header->getSize(); Data = StringRef(Start, Size); + if (!isThinMember()) { + ErrorOr<uint64_t> MemberSize = getRawSize(); + if ((*EC = MemberSize.getError())) + return; + Size += MemberSize.get(); + Data = StringRef(Start, Size); + } // Setup StartOfFile and PaddingBytes. StartOfFile = sizeof(ArchiveMemberHeader); // Don't include attached name. - StringRef Name = Header->getName(); + StringRef Name = getRawName(); if (Name.startswith("#1/")) { uint64_t NameSize; if (Name.substr(3).rtrim(" ").getAsInteger(10, NameSize)) @@ -106,25 +114,40 @@ Archive::Child::Child(const Archive *Parent, const char *Start) } } -uint64_t Archive::Child::getSize() const { - if (Parent->IsThin) - return getHeader()->getSize(); +ErrorOr<uint64_t> Archive::Child::getSize() const { + if (Parent->IsThin) { + ErrorOr<uint32_t> Size = getHeader()->getSize(); + if (std::error_code EC = Size.getError()) + return EC; + return Size.get(); + } return Data.size() - StartOfFile; } -uint64_t Archive::Child::getRawSize() const { - return getHeader()->getSize(); +ErrorOr<uint64_t> Archive::Child::getRawSize() const { + ErrorOr<uint32_t> Size = getHeader()->getSize(); + if (std::error_code EC = Size.getError()) + return EC; + return Size.get(); +} + +bool Archive::Child::isThinMember() const { + StringRef Name = getHeader()->getName(); + return Parent->IsThin && Name != "/" && Name != "//"; } ErrorOr<StringRef> Archive::Child::getBuffer() const { - if (!Parent->IsThin) - return StringRef(Data.data() + StartOfFile, getSize()); + if (!isThinMember()) { + ErrorOr<uint32_t> Size = getSize(); + if (std::error_code EC = Size.getError()) + return EC; + return StringRef(Data.data() + StartOfFile, Size.get()); + } ErrorOr<StringRef> Name = getName(); if (std::error_code EC = Name.getError()) return EC; - SmallString<128> FullName = - Parent->getMemoryBufferRef().getBufferIdentifier(); - sys::path::remove_filename(FullName); + SmallString<128> FullName = sys::path::parent_path( + Parent->getMemoryBufferRef().getBufferIdentifier()); sys::path::append(FullName, *Name); ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFile(FullName); if (std::error_code EC = Buf.getError()) @@ -133,7 +156,7 @@ ErrorOr<StringRef> Archive::Child::getBuffer() const { return Parent->ThinBuffers.back()->getBuffer(); } -Archive::Child Archive::Child::getNext() const { +ErrorOr<Archive::Child> Archive::Child::getNext() const { size_t SpaceToSkip = Data.size(); // If it's odd, add 1 to make it even. if (SpaceToSkip & 1) @@ -141,11 +164,19 @@ Archive::Child Archive::Child::getNext() const { const char *NextLoc = Data.data() + SpaceToSkip; + // Check to see if this is at the end of the archive. + if (NextLoc == Parent->Data.getBufferEnd()) + return Child(Parent, nullptr, nullptr); + // Check to see if this is past the end of the archive. - if (NextLoc >= Parent->Data.getBufferEnd()) - return Child(Parent, nullptr); + if (NextLoc > Parent->Data.getBufferEnd()) + return object_error::parse_failed; - return Child(Parent, NextLoc); + std::error_code EC; + Child Ret(Parent, NextLoc, &EC); + if (EC) + return EC; + return Ret; } uint64_t Archive::Child::getChildOffset() const { @@ -168,17 +199,11 @@ ErrorOr<StringRef> Archive::Child::getName() const { std::size_t offset; if (name.substr(1).rtrim(" ").getAsInteger(10, offset)) llvm_unreachable("Long name offset is not an integer"); - const char *addr = Parent->StringTable->Data.begin() - + sizeof(ArchiveMemberHeader) - + offset; + // Verify it. - if (Parent->StringTable == Parent->child_end() - || addr < (Parent->StringTable->Data.begin() - + sizeof(ArchiveMemberHeader)) - || addr > (Parent->StringTable->Data.begin() - + sizeof(ArchiveMemberHeader) - + Parent->StringTable->getSize())) + if (offset >= Parent->StringTable.size()) return object_error::parse_failed; + const char *addr = Parent->StringTable.begin() + offset; // GNU long file names end with a "/\n". if (Parent->kind() == K_GNU || Parent->kind() == K_MIPS64) { @@ -227,9 +252,13 @@ ErrorOr<std::unique_ptr<Archive>> Archive::create(MemoryBufferRef Source) { return std::move(Ret); } +void Archive::setFirstRegular(const Child &C) { + FirstRegularData = C.Data; + FirstRegularStartOfFile = C.StartOfFile; +} + Archive::Archive(MemoryBufferRef Source, std::error_code &ec) - : Binary(Binary::ID_Archive, Source), SymbolTable(child_end()), - StringTable(child_end()), FirstRegular(child_end()) { + : Binary(Binary::ID_Archive, Source) { StringRef Buffer = Data.getBuffer(); // Check for sufficient magic. if (Buffer.startswith(ThinMagic)) { @@ -242,15 +271,26 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec) } // Get the special members. - child_iterator i = child_begin(false); - child_iterator e = child_end(); + child_iterator I = child_begin(false); + if ((ec = I->getError())) + return; + child_iterator E = child_end(); - if (i == e) { + if (I == E) { ec = std::error_code(); return; } + const Child *C = &**I; - StringRef Name = i->getRawName(); + auto Increment = [&]() { + ++I; + if ((ec = I->getError())) + return true; + C = &**I; + return false; + }; + + StringRef Name = C->getRawName(); // Below is the pattern that is used to figure out the archive format // GNU archive format @@ -273,9 +313,13 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec) if (Name == "__.SYMDEF") { Format = K_BSD; - SymbolTable = i; - ++i; - FirstRegular = i; + // We know that the symbol table is not an external file, so we just assert + // there is no error. + SymbolTable = *C->getBuffer(); + if (Increment()) + return; + setFirstRegular(*C); + ec = std::error_code(); return; } @@ -283,16 +327,19 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec) if (Name.startswith("#1/")) { Format = K_BSD; // We know this is BSD, so getName will work since there is no string table. - ErrorOr<StringRef> NameOrErr = i->getName(); + ErrorOr<StringRef> NameOrErr = C->getName(); ec = NameOrErr.getError(); if (ec) return; Name = NameOrErr.get(); if (Name == "__.SYMDEF SORTED" || Name == "__.SYMDEF") { - SymbolTable = i; - ++i; + // We know that the symbol table is not an external file, so we just + // assert there is no error. + SymbolTable = *C->getBuffer(); + if (Increment()) + return; } - FirstRegular = i; + setFirstRegular(*C); return; } @@ -303,30 +350,36 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec) bool has64SymTable = false; if (Name == "/" || Name == "/SYM64/") { - SymbolTable = i; + // We know that the symbol table is not an external file, so we just assert + // there is no error. + SymbolTable = *C->getBuffer(); if (Name == "/SYM64/") has64SymTable = true; - ++i; - if (i == e) { + if (Increment()) + return; + if (I == E) { ec = std::error_code(); return; } - Name = i->getRawName(); + Name = C->getRawName(); } if (Name == "//") { Format = has64SymTable ? K_MIPS64 : K_GNU; - StringTable = i; - ++i; - FirstRegular = i; + // The string table is never an external member, so we just assert on the + // ErrorOr. + StringTable = *C->getBuffer(); + if (Increment()) + return; + setFirstRegular(*C); ec = std::error_code(); return; } if (Name[0] != '/') { Format = has64SymTable ? K_MIPS64 : K_GNU; - FirstRegular = i; + setFirstRegular(*C); ec = std::error_code(); return; } @@ -337,23 +390,30 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec) } Format = K_COFF; - SymbolTable = i; + // We know that the symbol table is not an external file, so we just assert + // there is no error. + SymbolTable = *C->getBuffer(); - ++i; - if (i == e) { - FirstRegular = i; + if (Increment()) + return; + + if (I == E) { + setFirstRegular(*C); ec = std::error_code(); return; } - Name = i->getRawName(); + Name = C->getRawName(); if (Name == "//") { - StringTable = i; - ++i; + // The string table is never an external member, so we just assert on the + // ErrorOr. + StringTable = *C->getBuffer(); + if (Increment()) + return; } - FirstRegular = i; + setFirstRegular(*C); ec = std::error_code(); } @@ -362,22 +422,25 @@ Archive::child_iterator Archive::child_begin(bool SkipInternal) const { return child_end(); if (SkipInternal) - return FirstRegular; + return Child(this, FirstRegularData, FirstRegularStartOfFile); const char *Loc = Data.getBufferStart() + strlen(Magic); - Child c(this, Loc); - return c; + std::error_code EC; + Child c(this, Loc, &EC); + if (EC) + return child_iterator(EC); + return child_iterator(c); } Archive::child_iterator Archive::child_end() const { - return Child(this, nullptr); + return Child(this, nullptr, nullptr); } StringRef Archive::Symbol::getName() const { return Parent->getSymbolTable().begin() + StringIndex; } -ErrorOr<Archive::child_iterator> Archive::Symbol::getMember() const { +ErrorOr<Archive::Child> Archive::Symbol::getMember() const { const char *Buf = Parent->getSymbolTable().begin(); const char *Offsets = Buf; if (Parent->kind() == K_MIPS64) @@ -422,8 +485,11 @@ ErrorOr<Archive::child_iterator> Archive::Symbol::getMember() const { } const char *Loc = Parent->getData().begin() + Offset; - child_iterator Iter(Child(Parent, Loc)); - return Iter; + std::error_code EC; + Child C(Parent, Loc, &EC); + if (EC) + return EC; + return C; } Archive::Symbol Archive::Symbol::getNext() const { @@ -506,12 +572,12 @@ 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 { + if (!hasSymbolTable()) + return 0; const char *buf = getSymbolTable().begin(); if (kind() == K_GNU) return read32be(buf); @@ -542,6 +608,4 @@ Archive::child_iterator Archive::findSym(StringRef name) const { return child_end(); } -bool Archive::hasSymbolTable() const { - return SymbolTable != child_end(); -} +bool Archive::hasSymbolTable() const { return !SymbolTable.empty(); } diff --git a/contrib/llvm/lib/Object/ArchiveWriter.cpp b/contrib/llvm/lib/Object/ArchiveWriter.cpp index a40901c924ea..c7343fdc171d 100644 --- a/contrib/llvm/lib/Object/ArchiveWriter.cpp +++ b/contrib/llvm/lib/Object/ArchiveWriter.cpp @@ -34,32 +34,32 @@ using namespace llvm; -NewArchiveIterator::NewArchiveIterator(object::Archive::child_iterator I, +NewArchiveIterator::NewArchiveIterator(const object::Archive::Child &OldMember, StringRef Name) - : IsNewMember(false), Name(Name), OldI(I) {} + : IsNewMember(false), Name(Name), OldMember(OldMember) {} -NewArchiveIterator::NewArchiveIterator(StringRef NewFilename, StringRef Name) - : IsNewMember(true), Name(Name), NewFilename(NewFilename) {} +NewArchiveIterator::NewArchiveIterator(StringRef FileName) + : IsNewMember(true), Name(FileName), OldMember(nullptr, nullptr, nullptr) {} StringRef NewArchiveIterator::getName() const { return Name; } bool NewArchiveIterator::isNewMember() const { return IsNewMember; } -object::Archive::child_iterator NewArchiveIterator::getOld() const { +const object::Archive::Child &NewArchiveIterator::getOld() const { assert(!IsNewMember); - return OldI; + return OldMember; } StringRef NewArchiveIterator::getNew() const { assert(IsNewMember); - return NewFilename; + return Name; } llvm::ErrorOr<int> NewArchiveIterator::getFD(sys::fs::file_status &NewStatus) const { assert(IsNewMember); int NewFD; - if (auto EC = sys::fs::openFileForRead(NewFilename, NewFD)) + if (auto EC = sys::fs::openFileForRead(Name, NewFD)) return EC; assert(NewFD != -1); @@ -77,7 +77,7 @@ NewArchiveIterator::getFD(sys::fs::file_status &NewStatus) const { template <typename T> static void printWithSpacePadding(raw_fd_ostream &OS, T Data, unsigned Size, - bool MayTruncate = false) { + bool MayTruncate = false) { uint64_t OldPos = OS.tell(); OS << Data; unsigned SizeSoFar = OS.tell() - OldPos; @@ -135,30 +135,56 @@ static void printBSDMemberHeader(raw_fd_ostream &Out, StringRef Name, Out.write(uint8_t(0)); } +static bool useStringTable(bool Thin, StringRef Name) { + return Thin || Name.size() >= 16; +} + static void -printMemberHeader(raw_fd_ostream &Out, object::Archive::Kind Kind, +printMemberHeader(raw_fd_ostream &Out, object::Archive::Kind Kind, bool Thin, StringRef Name, std::vector<unsigned>::iterator &StringMapIndexIter, const sys::TimeValue &ModTime, unsigned UID, unsigned GID, unsigned Perms, unsigned Size) { if (Kind == object::Archive::K_BSD) return printBSDMemberHeader(Out, Name, ModTime, UID, GID, Perms, Size); - if (Name.size() < 16) + if (!useStringTable(Thin, Name)) return printGNUSmallMemberHeader(Out, Name, ModTime, UID, GID, Perms, Size); Out << '/'; printWithSpacePadding(Out, *StringMapIndexIter++, 15); printRestOfMemberHeader(Out, ModTime, UID, GID, Perms, Size); } -static void writeStringTable(raw_fd_ostream &Out, +// Compute the relative path from From to To. +static std::string computeRelativePath(StringRef From, StringRef To) { + if (sys::path::is_absolute(From) || sys::path::is_absolute(To)) + return To; + + StringRef DirFrom = sys::path::parent_path(From); + auto FromI = sys::path::begin(DirFrom); + auto ToI = sys::path::begin(To); + while (*FromI == *ToI) { + ++FromI; + ++ToI; + } + + SmallString<128> Relative; + for (auto FromE = sys::path::end(DirFrom); FromI != FromE; ++FromI) + sys::path::append(Relative, ".."); + + for (auto ToE = sys::path::end(To); ToI != ToE; ++ToI) + sys::path::append(Relative, *ToI); + + return Relative.str(); +} + +static void writeStringTable(raw_fd_ostream &Out, StringRef ArcName, ArrayRef<NewArchiveIterator> Members, - std::vector<unsigned> &StringMapIndexes) { + std::vector<unsigned> &StringMapIndexes, + bool Thin) { unsigned StartOffset = 0; - for (ArrayRef<NewArchiveIterator>::iterator I = Members.begin(), - E = Members.end(); - I != E; ++I) { - StringRef Name = I->getName(); - if (Name.size() < 16) + for (const NewArchiveIterator &I : Members) { + StringRef Name = sys::path::filename(I.getName()); + if (!useStringTable(Thin, Name)) continue; if (StartOffset == 0) { printWithSpacePadding(Out, "//", 58); @@ -166,7 +192,13 @@ static void writeStringTable(raw_fd_ostream &Out, StartOffset = Out.tell(); } StringMapIndexes.push_back(Out.tell() - StartOffset); - Out << Name << "/\n"; + + if (Thin) + Out << computeRelativePath(ArcName, I.getName()); + else + Out << Name; + + Out << "/\n"; } if (StartOffset == 0) return; @@ -268,9 +300,11 @@ writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind, return BodyStartOffset + 4; } -std::pair<StringRef, std::error_code> llvm::writeArchive( - StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers, - bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic) { +std::pair<StringRef, std::error_code> +llvm::writeArchive(StringRef ArcName, + std::vector<NewArchiveIterator> &NewMembers, + bool WriteSymtab, object::Archive::Kind Kind, + bool Deterministic, bool Thin) { SmallString<128> TmpArchive; int TmpArchiveFD; if (auto EC = sys::fs::createUniqueFile(ArcName + ".temp-archive-%%%%%%%.a", @@ -279,7 +313,10 @@ std::pair<StringRef, std::error_code> llvm::writeArchive( tool_output_file Output(TmpArchive, TmpArchiveFD); raw_fd_ostream &Out = Output.os(); - Out << "!<arch>\n"; + if (Thin) + Out << "!<thin>\n"; + else + Out << "!<arch>\n"; std::vector<unsigned> MemberOffsetRefs; @@ -309,9 +346,11 @@ std::pair<StringRef, std::error_code> llvm::writeArchive( Buffers.push_back(std::move(MemberBufferOrErr.get())); MemberRef = Buffers.back()->getMemBufferRef(); } else { - object::Archive::child_iterator OldMember = Member.getOld(); + const object::Archive::Child &OldMember = Member.getOld(); + assert((!Thin || OldMember.getParent()->isThin()) && + "Thin archives cannot refers to member of other archives"); ErrorOr<MemoryBufferRef> MemberBufferOrErr = - OldMember->getMemoryBufferRef(); + OldMember.getMemoryBufferRef(); if (auto EC = MemberBufferOrErr.getError()) return std::make_pair("", EC); MemberRef = MemberBufferOrErr.get(); @@ -330,7 +369,7 @@ std::pair<StringRef, std::error_code> llvm::writeArchive( std::vector<unsigned> StringMapIndexes; if (Kind != object::Archive::K_BSD) - writeStringTable(Out, NewMembers, StringMapIndexes); + writeStringTable(Out, ArcName, NewMembers, StringMapIndexes, Thin); unsigned MemberNum = 0; unsigned NewMemberNum = 0; @@ -358,26 +397,32 @@ std::pair<StringRef, std::error_code> llvm::writeArchive( GID = Status.getGroup(); Perms = Status.permissions(); } else { - object::Archive::child_iterator OldMember = I.getOld(); - ModTime = OldMember->getLastModified(); - UID = OldMember->getUID(); - GID = OldMember->getGID(); - Perms = OldMember->getAccessMode(); + const object::Archive::Child &OldMember = I.getOld(); + ModTime = OldMember.getLastModified(); + UID = OldMember.getUID(); + GID = OldMember.getGID(); + Perms = OldMember.getAccessMode(); } if (I.isNewMember()) { StringRef FileName = I.getNew(); const sys::fs::file_status &Status = NewMemberStatus[NewMemberNum++]; - printMemberHeader(Out, Kind, sys::path::filename(FileName), + printMemberHeader(Out, Kind, Thin, sys::path::filename(FileName), StringMapIndexIter, ModTime, UID, GID, Perms, Status.getSize()); } else { - object::Archive::child_iterator OldMember = I.getOld(); - printMemberHeader(Out, Kind, I.getName(), StringMapIndexIter, ModTime, - UID, GID, Perms, OldMember->getSize()); + const object::Archive::Child &OldMember = I.getOld(); + ErrorOr<uint32_t> Size = OldMember.getSize(); + if (std::error_code EC = Size.getError()) + return std::make_pair("", EC); + StringRef FileName = I.getName(); + printMemberHeader(Out, Kind, Thin, sys::path::filename(FileName), + StringMapIndexIter, ModTime, UID, GID, Perms, + Size.get()); } - Out << File.getBuffer(); + if (!Thin) + Out << File.getBuffer(); if (Out.tell() % 2) Out << '\n'; diff --git a/contrib/llvm/lib/Object/COFFObjectFile.cpp b/contrib/llvm/lib/Object/COFFObjectFile.cpp index bcca9839b475..1f2111759a0e 100644 --- a/contrib/llvm/lib/Object/COFFObjectFile.cpp +++ b/contrib/llvm/lib/Object/COFFObjectFile.cpp @@ -171,6 +171,11 @@ ErrorOr<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const { if (std::error_code EC = getSection(SectionNumber, Section)) return EC; Result += Section->VirtualAddress; + + // The section VirtualAddress does not include ImageBase, and we want to + // return virtual addresses. + Result += getImageBase(); + return Result; } @@ -178,10 +183,10 @@ SymbolRef::Type COFFObjectFile::getSymbolType(DataRefImpl Ref) const { COFFSymbolRef Symb = getCOFFSymbol(Ref); int32_t SectionNumber = Symb.getSectionNumber(); + if (Symb.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) + return SymbolRef::ST_Function; if (Symb.isAnyUndefined()) return SymbolRef::ST_Unknown; - if (Symb.isFunctionDefinition()) - return SymbolRef::ST_Function; if (Symb.isCommon()) return SymbolRef::ST_Data; if (Symb.isFileRecord()) @@ -230,21 +235,17 @@ uint64_t COFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Ref) const { return Symb.getValue(); } -std::error_code -COFFObjectFile::getSymbolSection(DataRefImpl Ref, - section_iterator &Result) const { +ErrorOr<section_iterator> +COFFObjectFile::getSymbolSection(DataRefImpl Ref) const { COFFSymbolRef Symb = getCOFFSymbol(Ref); - if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) { - Result = section_end(); - } else { - const coff_section *Sec = nullptr; - if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec)) - return EC; - DataRefImpl Ref; - Ref.p = reinterpret_cast<uintptr_t>(Sec); - Result = section_iterator(SectionRef(Ref, this)); - } - return std::error_code(); + if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) + return section_end(); + const coff_section *Sec = nullptr; + if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec)) + return EC; + DataRefImpl Ret; + Ret.p = reinterpret_cast<uintptr_t>(Sec); + return section_iterator(SectionRef(Ret, this)); } unsigned COFFObjectFile::getSymbolSectionID(SymbolRef Sym) const { @@ -266,7 +267,12 @@ std::error_code COFFObjectFile::getSectionName(DataRefImpl Ref, uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const { const coff_section *Sec = toSec(Ref); - return Sec->VirtualAddress; + uint64_t Result = Sec->VirtualAddress; + + // The section VirtualAddress does not include ImageBase, and we want to + // return virtual addresses. + Result += getImageBase(); + return Result; } uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const { @@ -412,10 +418,18 @@ std::error_code COFFObjectFile::initSymbolTablePtr() { return std::error_code(); } +uint64_t COFFObjectFile::getImageBase() const { + if (PE32Header) + return PE32Header->ImageBase; + else if (PE32PlusHeader) + return PE32PlusHeader->ImageBase; + // This actually comes up in practice. + return 0; +} + // Returns the file offset for the given VA. std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const { - uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase - : (uint64_t)PE32PlusHeader->ImageBase; + uint64_t ImageBase = getImageBase(); uint64_t Rva = Addr - ImageBase; assert(Rva <= UINT32_MAX); return getRvaPtr((uint32_t)Rva, Res); @@ -744,6 +758,8 @@ StringRef COFFObjectFile::getFileFormatName() const { return "COFF-x86-64"; case COFF::IMAGE_FILE_MACHINE_ARMNT: return "COFF-ARM"; + case COFF::IMAGE_FILE_MACHINE_ARM64: + return "COFF-ARM64"; default: return "COFF-<unknown arch>"; } @@ -757,6 +773,8 @@ unsigned COFFObjectFile::getArch() const { return Triple::x86_64; case COFF::IMAGE_FILE_MACHINE_ARMNT: return Triple::thumb; + case COFF::IMAGE_FILE_MACHINE_ARM64: + return Triple::aarch64; default: return Triple::UnknownArch; } diff --git a/contrib/llvm/lib/Object/COFFYAML.cpp b/contrib/llvm/lib/Object/COFFYAML.cpp index 9a24b531da9e..4c1fca19bf1b 100644 --- a/contrib/llvm/lib/Object/COFFYAML.cpp +++ b/contrib/llvm/lib/Object/COFFYAML.cpp @@ -56,6 +56,7 @@ void ScalarEnumerationTraits<COFF::MachineTypes>::enumeration( ECase(IMAGE_FILE_MACHINE_AMD64); ECase(IMAGE_FILE_MACHINE_ARM); ECase(IMAGE_FILE_MACHINE_ARMNT); + ECase(IMAGE_FILE_MACHINE_ARM64); ECase(IMAGE_FILE_MACHINE_EBC); ECase(IMAGE_FILE_MACHINE_I386); ECase(IMAGE_FILE_MACHINE_IA64); @@ -210,6 +211,7 @@ void ScalarBitSetTraits<COFF::Characteristics>::bitset( void ScalarBitSetTraits<COFF::SectionCharacteristics>::bitset( IO &IO, COFF::SectionCharacteristics &Value) { + BCase(IMAGE_SCN_TYPE_NOLOAD); BCase(IMAGE_SCN_TYPE_NO_PAD); BCase(IMAGE_SCN_CNT_CODE); BCase(IMAGE_SCN_CNT_INITIALIZED_DATA); diff --git a/contrib/llvm/lib/Object/ELF.cpp b/contrib/llvm/lib/Object/ELF.cpp index 398e9e412994..62c27cc427a6 100644 --- a/contrib/llvm/lib/Object/ELF.cpp +++ b/contrib/llvm/lib/Object/ELF.cpp @@ -26,6 +26,7 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) { } break; case ELF::EM_386: + case ELF::EM_IAMCU: switch (Type) { #include "llvm/Support/ELFRelocs/i386.def" default: diff --git a/contrib/llvm/lib/Object/ELFYAML.cpp b/contrib/llvm/lib/Object/ELFYAML.cpp index 72c232c32870..4a4b2276f46b 100644 --- a/contrib/llvm/lib/Object/ELFYAML.cpp +++ b/contrib/llvm/lib/Object/ELFYAML.cpp @@ -193,6 +193,7 @@ ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(IO &IO, ECase(EM_VIDEOCORE5) ECase(EM_78KOR) ECase(EM_56800EX) + ECase(EM_AMDGPU) #undef ECase } @@ -316,6 +317,25 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO, BCase(EF_HEXAGON_ISA_V4) BCase(EF_HEXAGON_ISA_V5) break; + case ELF::EM_AVR: + BCase(EF_AVR_ARCH_AVR1) + BCase(EF_AVR_ARCH_AVR2) + BCase(EF_AVR_ARCH_AVR25) + BCase(EF_AVR_ARCH_AVR3) + BCase(EF_AVR_ARCH_AVR31) + BCase(EF_AVR_ARCH_AVR35) + BCase(EF_AVR_ARCH_AVR4) + BCase(EF_AVR_ARCH_AVR51) + BCase(EF_AVR_ARCH_AVR6) + BCase(EF_AVR_ARCH_AVRTINY) + BCase(EF_AVR_ARCH_XMEGA1) + BCase(EF_AVR_ARCH_XMEGA2) + BCase(EF_AVR_ARCH_XMEGA3) + BCase(EF_AVR_ARCH_XMEGA4) + BCase(EF_AVR_ARCH_XMEGA5) + BCase(EF_AVR_ARCH_XMEGA6) + BCase(EF_AVR_ARCH_XMEGA7) + break; default: llvm_unreachable("Unsupported architecture"); } @@ -382,6 +402,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration( void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO, ELFYAML::ELF_SHF &Value) { + const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); #define BCase(X) IO.bitSetCase(Value, #X, ELF::X); BCase(SHF_WRITE) BCase(SHF_ALLOC) @@ -394,6 +415,17 @@ void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO, BCase(SHF_OS_NONCONFORMING) BCase(SHF_GROUP) BCase(SHF_TLS) + switch(Object->Header.Machine) { + case ELF::EM_AMDGPU: + BCase(SHF_AMDGPU_HSA_GLOBAL) + BCase(SHF_AMDGPU_HSA_READONLY) + BCase(SHF_AMDGPU_HSA_CODE) + BCase(SHF_AMDGPU_HSA_AGENT) + break; + default: + // Nothing to do. + break; + } #undef BCase } @@ -466,6 +498,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration( #include "llvm/Support/ELFRelocs/Hexagon.def" break; case ELF::EM_386: + case ELF::EM_IAMCU: #include "llvm/Support/ELFRelocs/i386.def" break; case ELF::EM_AARCH64: diff --git a/contrib/llvm/lib/Object/Error.cpp b/contrib/llvm/lib/Object/Error.cpp index 7ca2f12f0924..7ecc3a19af9d 100644 --- a/contrib/llvm/lib/Object/Error.cpp +++ b/contrib/llvm/lib/Object/Error.cpp @@ -47,6 +47,8 @@ std::string _object_error_category::message(int EV) const { return "Invalid section index"; case object_error::bitcode_section_not_found: return "Bitcode section not found in object file"; + case object_error::elf_invalid_dynamic_table_size: + return "Invalid dynamic table size"; case object_error::macho_small_load_command: return "Mach-O load command with size < 8 bytes"; case object_error::macho_load_segment_too_many_sections: diff --git a/contrib/llvm/lib/Object/FunctionIndexObjectFile.cpp b/contrib/llvm/lib/Object/FunctionIndexObjectFile.cpp new file mode 100644 index 000000000000..fe111de1a9c8 --- /dev/null +++ b/contrib/llvm/lib/Object/FunctionIndexObjectFile.cpp @@ -0,0 +1,143 @@ +//===- FunctionIndexObjectFile.cpp - Function index file implementation ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Part of the FunctionIndexObjectFile class implementation. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/FunctionIndexObjectFile.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/IR/FunctionInfo.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; +using namespace object; + +FunctionIndexObjectFile::FunctionIndexObjectFile( + MemoryBufferRef Object, std::unique_ptr<FunctionInfoIndex> I) + : SymbolicFile(Binary::ID_FunctionIndex, Object), Index(std::move(I)) {} + +FunctionIndexObjectFile::~FunctionIndexObjectFile() {} + +std::unique_ptr<FunctionInfoIndex> FunctionIndexObjectFile::takeIndex() { + return std::move(Index); +} + +ErrorOr<MemoryBufferRef> +FunctionIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) { + for (const SectionRef &Sec : Obj.sections()) { + StringRef SecName; + if (std::error_code EC = Sec.getName(SecName)) + return EC; + if (SecName == ".llvmbc") { + StringRef SecContents; + if (std::error_code EC = Sec.getContents(SecContents)) + return EC; + return MemoryBufferRef(SecContents, Obj.getFileName()); + } + } + + return object_error::bitcode_section_not_found; +} + +ErrorOr<MemoryBufferRef> +FunctionIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { + sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); + switch (Type) { + case sys::fs::file_magic::bitcode: + return Object; + case sys::fs::file_magic::elf_relocatable: + case sys::fs::file_magic::macho_object: + case sys::fs::file_magic::coff_object: { + ErrorOr<std::unique_ptr<ObjectFile>> ObjFile = + ObjectFile::createObjectFile(Object, Type); + if (!ObjFile) + return ObjFile.getError(); + return findBitcodeInObject(*ObjFile->get()); + } + default: + return object_error::invalid_file_type; + } +} + +// Looks for function index in the given memory buffer. +// returns true if found, else false. +bool FunctionIndexObjectFile::hasFunctionSummaryInMemBuffer( + MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler) { + ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); + if (!BCOrErr) + return false; + + return hasFunctionSummary(BCOrErr.get(), DiagnosticHandler); +} + +// Parse function index in the given memory buffer. +// Return new FunctionIndexObjectFile instance containing parsed +// function summary/index. +ErrorOr<std::unique_ptr<FunctionIndexObjectFile>> +FunctionIndexObjectFile::create(MemoryBufferRef Object, + DiagnosticHandlerFunction DiagnosticHandler, + bool IsLazy) { + std::unique_ptr<FunctionInfoIndex> Index; + + ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); + if (!BCOrErr) + return BCOrErr.getError(); + + ErrorOr<std::unique_ptr<FunctionInfoIndex>> IOrErr = getFunctionInfoIndex( + BCOrErr.get(), DiagnosticHandler, IsLazy); + + if (std::error_code EC = IOrErr.getError()) + return EC; + + Index = std::move(IOrErr.get()); + + return llvm::make_unique<FunctionIndexObjectFile>(Object, std::move(Index)); +} + +// Parse the function summary information for function with the +// given name out of the given buffer. Parsed information is +// stored on the index object saved in this object. +std::error_code FunctionIndexObjectFile::findFunctionSummaryInMemBuffer( + MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler, + StringRef FunctionName) { + sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); + switch (Type) { + case sys::fs::file_magic::bitcode: { + return readFunctionSummary(Object, DiagnosticHandler, FunctionName, + std::move(Index)); + } + default: + return object_error::invalid_file_type; + } +} + +// Parse the function index out of an IR file and return the function +// index object if found, or nullptr if not. +ErrorOr<std::unique_ptr<FunctionInfoIndex>> +llvm::getFunctionIndexForFile(StringRef Path, + DiagnosticHandlerFunction DiagnosticHandler) { + ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = + MemoryBuffer::getFileOrSTDIN(Path); + std::error_code EC = FileOrErr.getError(); + if (EC) + return EC; + MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef(); + ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr = + object::FunctionIndexObjectFile::create(BufferRef, DiagnosticHandler); + EC = ObjOrErr.getError(); + if (EC) + return EC; + + object::FunctionIndexObjectFile &Obj = **ObjOrErr; + return Obj.takeIndex(); +} diff --git a/contrib/llvm/lib/Object/IRObjectFile.cpp b/contrib/llvm/lib/Object/IRObjectFile.cpp index 9f5132e9062c..c35c413b3c3b 100644 --- a/contrib/llvm/lib/Object/IRObjectFile.cpp +++ b/contrib/llvm/lib/Object/IRObjectFile.cpp @@ -219,6 +219,12 @@ uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { uint32_t Res = BasicSymbolRef::SF_None; if (GV->isDeclarationForLinker()) Res |= BasicSymbolRef::SF_Undefined; + else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) + Res |= BasicSymbolRef::SF_Hidden; + if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { + if (GVar->isConstant()) + Res |= BasicSymbolRef::SF_Const; + } if (GV->hasPrivateLinkage()) Res |= BasicSymbolRef::SF_FormatSpecific; if (!GV->hasLocalLinkage()) @@ -303,7 +309,7 @@ llvm::object::IRObjectFile::create(MemoryBufferRef Object, MemoryBuffer::getMemBuffer(BCOrErr.get(), false)); ErrorOr<std::unique_ptr<Module>> MOrErr = - getLazyBitcodeModule(std::move(Buff), Context, nullptr, + getLazyBitcodeModule(std::move(Buff), Context, /*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 05900630c75c..d1f79b225ee4 100644 --- a/contrib/llvm/lib/Object/MachOObjectFile.cpp +++ b/contrib/llvm/lib/Object/MachOObjectFile.cpp @@ -278,7 +278,7 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, return; } LinkOptHintsLoadCmd = Load.Ptr; - } else if (Load.C.cmd == MachO::LC_DYLD_INFO || + } else if (Load.C.cmd == MachO::LC_DYLD_INFO || Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) { // Multiple dyldinfo load commands if (DyldInfoLoadCmd) { @@ -401,6 +401,9 @@ SymbolRef::Type MachOObjectFile::getSymbolType(DataRefImpl Symb) const { case MachO::N_UNDF : return SymbolRef::ST_Unknown; case MachO::N_SECT : + section_iterator Sec = *getSymbolSection(Symb); + if (Sec->isData() || Sec->isBSS()) + return SymbolRef::ST_Data; return SymbolRef::ST_Function; } return SymbolRef::ST_Other; @@ -445,22 +448,18 @@ uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const { return Result; } -std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const { +ErrorOr<section_iterator> +MachOObjectFile::getSymbolSection(DataRefImpl Symb) const { MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb); uint8_t index = Entry.n_sect; - if (index == 0) { - Res = section_end(); - } 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)); - } - - return std::error_code(); + if (index == 0) + return section_end(); + DataRefImpl DRI; + DRI.d.a = index - 1; + if (DRI.d.a >= Sections.size()) + report_fatal_error("getSymbolSection: Invalid section index."); + return section_iterator(SectionRef(DRI, this)); } unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const { @@ -487,9 +486,32 @@ uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const { } uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const { - if (is64Bit()) - return getSection64(Sec).size; - return getSection(Sec).size; + // In the case if a malformed Mach-O file where the section offset is past + // the end of the file or some part of the section size is past the end of + // the file return a size of zero or a size that covers the rest of the file + // but does not extend past the end of the file. + uint32_t SectOffset, SectType; + uint64_t SectSize; + + if (is64Bit()) { + MachO::section_64 Sect = getSection64(Sec); + SectOffset = Sect.offset; + SectSize = Sect.size; + SectType = Sect.flags & MachO::SECTION_TYPE; + } else { + MachO::section Sect = getSection(Sec); + SectOffset = Sect.offset; + SectSize = Sect.size; + SectType = Sect.flags & MachO::SECTION_TYPE; + } + if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL) + return SectSize; + uint64_t FileSize = getData().size(); + if (SectOffset > FileSize) + return 0; + if (FileSize - SectOffset < SectSize) + return FileSize - SectOffset; + return SectSize; } std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec, @@ -1136,8 +1158,7 @@ Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType, } Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType, - const char **McpuDefault, - Triple *ThumbTriple) { + const char **McpuDefault, Triple *ThumbTriple) { Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault); *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType, McpuDefault); @@ -1212,8 +1233,8 @@ dice_iterator MachOObjectFile::end_dices() const { return dice_iterator(DiceRef(DRI, this)); } -ExportEntry::ExportEntry(ArrayRef<uint8_t> T) - : Trie(T), Malformed(false), Done(false) { } +ExportEntry::ExportEntry(ArrayRef<uint8_t> T) + : Trie(T), Malformed(false), Done(false) {} void ExportEntry::moveToFirst() { pushNode(0); @@ -1226,7 +1247,7 @@ void ExportEntry::moveToEnd() { } bool ExportEntry::operator==(const ExportEntry &Other) const { - // Common case, one at end, other iterating from begin. + // Common case, one at end, other iterating from begin. if (Done || Other.Done) return (Done == Other.Done); // Not equal if different stack sizes. @@ -1240,7 +1261,7 @@ bool ExportEntry::operator==(const ExportEntry &Other) const { if (Stack[i].Start != Other.Stack[i].Start) return false; } - return true; + return true; } uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) { @@ -1281,11 +1302,10 @@ uint32_t ExportEntry::nodeOffset() const { return Stack.back().Start - Trie.begin(); } -ExportEntry::NodeState::NodeState(const uint8_t *Ptr) - : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0), - ImportName(nullptr), ChildCount(0), NextChildIndex(0), - ParentStringLength(0), IsExportNode(false) { -} +ExportEntry::NodeState::NodeState(const uint8_t *Ptr) + : Start(Ptr), Current(Ptr), Flags(0), Address(0), Other(0), + ImportName(nullptr), ChildCount(0), NextChildIndex(0), + ParentStringLength(0), IsExportNode(false) {} void ExportEntry::pushNode(uint64_t offset) { const uint8_t *Ptr = Trie.begin() + offset; @@ -1302,7 +1322,7 @@ void ExportEntry::pushNode(uint64_t offset) { } else { State.Address = readULEB128(State.Current); if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) - State.Other = readULEB128(State.Current); + State.Other = readULEB128(State.Current); } } State.ChildCount = *Children; @@ -1339,7 +1359,7 @@ void ExportEntry::pushDownUntilBottom() { // // There is one "export" node for each exported symbol. But because some // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export -// node may have child nodes too. +// node may have child nodes too. // // The algorithm for moveNext() is to keep moving down the leftmost unvisited // child until hitting a node with no children (which is an export node or @@ -1372,7 +1392,7 @@ void ExportEntry::moveNext() { Done = true; } -iterator_range<export_iterator> +iterator_range<export_iterator> MachOObjectFile::exports(ArrayRef<uint8_t> Trie) { ExportEntry Start(Trie); if (Trie.size() == 0) @@ -1383,15 +1403,13 @@ MachOObjectFile::exports(ArrayRef<uint8_t> Trie) { ExportEntry Finish(Trie); Finish.moveToEnd(); - return iterator_range<export_iterator>(export_iterator(Start), - export_iterator(Finish)); + return make_range(export_iterator(Start), export_iterator(Finish)); } iterator_range<export_iterator> MachOObjectFile::exports() const { return exports(getDyldInfoExportsTrie()); } - MachORebaseEntry::MachORebaseEntry(ArrayRef<uint8_t> Bytes, bool is64Bit) : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0), RemainingLoopCount(0), AdvanceAmount(0), RebaseType(0), @@ -1555,17 +1573,14 @@ MachOObjectFile::rebaseTable(ArrayRef<uint8_t> Opcodes, bool is64) { MachORebaseEntry Finish(Opcodes, is64); Finish.moveToEnd(); - return iterator_range<rebase_iterator>(rebase_iterator(Start), - rebase_iterator(Finish)); + return make_range(rebase_iterator(Start), rebase_iterator(Finish)); } iterator_range<rebase_iterator> MachOObjectFile::rebaseTable() const { return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit()); } - -MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, - Kind BK) +MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK) : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0), Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0), BindType(0), PointerSize(is64Bit ? 8 : 4), @@ -1769,7 +1784,6 @@ int64_t MachOBindEntry::readSLEB128() { return Result; } - uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; } uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; } @@ -1810,8 +1824,7 @@ MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64, MachOBindEntry Finish(Opcodes, is64, BKind); Finish.moveToEnd(); - return iterator_range<bind_iterator>(bind_iterator(Start), - bind_iterator(Finish)); + return make_range(bind_iterator(Start), bind_iterator(Finish)); } iterator_range<bind_iterator> MachOObjectFile::bindTable() const { @@ -1841,8 +1854,7 @@ MachOObjectFile::end_load_commands() const { iterator_range<MachOObjectFile::load_command_iterator> MachOObjectFile::load_commands() const { - return iterator_range<load_command_iterator>(begin_load_commands(), - end_load_commands()); + return make_range(begin_load_commands(), end_load_commands()); } StringRef @@ -2207,66 +2219,66 @@ MachOObjectFile::getLinkOptHintsLoadCommand() const { } ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const { - if (!DyldInfoLoadCmd) - return ArrayRef<uint8_t>(); + if (!DyldInfoLoadCmd) + return None; - MachO::dyld_info_command DyldInfo - = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); - const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( - getPtr(this, DyldInfo.rebase_off)); - return ArrayRef<uint8_t>(Ptr, DyldInfo.rebase_size); + MachO::dyld_info_command DyldInfo = + getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); + const uint8_t *Ptr = + reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.rebase_off)); + return makeArrayRef(Ptr, DyldInfo.rebase_size); } ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const { - if (!DyldInfoLoadCmd) - return ArrayRef<uint8_t>(); + if (!DyldInfoLoadCmd) + return None; - MachO::dyld_info_command DyldInfo - = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); - const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( - getPtr(this, DyldInfo.bind_off)); - return ArrayRef<uint8_t>(Ptr, DyldInfo.bind_size); + MachO::dyld_info_command DyldInfo = + getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); + const uint8_t *Ptr = + reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.bind_off)); + return makeArrayRef(Ptr, DyldInfo.bind_size); } ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const { - if (!DyldInfoLoadCmd) - return ArrayRef<uint8_t>(); + if (!DyldInfoLoadCmd) + return None; - MachO::dyld_info_command DyldInfo - = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); - const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( - getPtr(this, DyldInfo.weak_bind_off)); - return ArrayRef<uint8_t>(Ptr, DyldInfo.weak_bind_size); + MachO::dyld_info_command DyldInfo = + getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); + const uint8_t *Ptr = + reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.weak_bind_off)); + return makeArrayRef(Ptr, DyldInfo.weak_bind_size); } ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const { - if (!DyldInfoLoadCmd) - return ArrayRef<uint8_t>(); + if (!DyldInfoLoadCmd) + return None; - MachO::dyld_info_command DyldInfo - = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); - const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( - getPtr(this, DyldInfo.lazy_bind_off)); - return ArrayRef<uint8_t>(Ptr, DyldInfo.lazy_bind_size); + MachO::dyld_info_command DyldInfo = + getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); + const uint8_t *Ptr = + reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.lazy_bind_off)); + return makeArrayRef(Ptr, DyldInfo.lazy_bind_size); } ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const { - if (!DyldInfoLoadCmd) - return ArrayRef<uint8_t>(); + if (!DyldInfoLoadCmd) + return None; - MachO::dyld_info_command DyldInfo - = getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); - const uint8_t *Ptr = reinterpret_cast<const uint8_t*>( - getPtr(this, DyldInfo.export_off)); - return ArrayRef<uint8_t>(Ptr, DyldInfo.export_size); + MachO::dyld_info_command DyldInfo = + getStruct<MachO::dyld_info_command>(this, DyldInfoLoadCmd); + const uint8_t *Ptr = + reinterpret_cast<const uint8_t *>(getPtr(this, DyldInfo.export_off)); + return makeArrayRef(Ptr, DyldInfo.export_size); } ArrayRef<uint8_t> MachOObjectFile::getUuid() const { if (!UuidLoadCmd) - return ArrayRef<uint8_t>(); + return None; // Returning a pointer is fine as uuid doesn't need endian swapping. const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid); - return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Ptr), 16); + return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16); } StringRef MachOObjectFile::getStringTableData() const { @@ -2315,4 +2327,3 @@ ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) { return EC; return std::move(Ret); } - diff --git a/contrib/llvm/lib/Object/MachOUniversal.cpp b/contrib/llvm/lib/Object/MachOUniversal.cpp index 1d0e69e4622d..a1c83b9b7f86 100644 --- a/contrib/llvm/lib/Object/MachOUniversal.cpp +++ b/contrib/llvm/lib/Object/MachOUniversal.cpp @@ -69,14 +69,14 @@ MachOUniversalBinary::ObjectForArch::ObjectForArch( ErrorOr<std::unique_ptr<MachOObjectFile>> MachOUniversalBinary::ObjectForArch::getAsObjectFile() const { - if (Parent) { - StringRef ParentData = Parent->getData(); - StringRef ObjectData = ParentData.substr(Header.offset, Header.size); - StringRef ObjectName = Parent->getFileName(); - MemoryBufferRef ObjBuffer(ObjectData, ObjectName); - return ObjectFile::createMachOObjectFile(ObjBuffer); - } - return object_error::parse_failed; + if (!Parent) + return object_error::parse_failed; + + StringRef ParentData = Parent->getData(); + StringRef ObjectData = ParentData.substr(Header.offset, Header.size); + StringRef ObjectName = Parent->getFileName(); + MemoryBufferRef ObjBuffer(ObjectData, ObjectName); + return ObjectFile::createMachOObjectFile(ObjBuffer); } ErrorOr<std::unique_ptr<Archive>> diff --git a/contrib/llvm/lib/Object/Object.cpp b/contrib/llvm/lib/Object/Object.cpp index 5c4b7a67b2ad..b44c1a16fd08 100644 --- a/contrib/llvm/lib/Object/Object.cpp +++ b/contrib/llvm/lib/Object/Object.cpp @@ -98,8 +98,10 @@ void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, LLVMSymbolIteratorRef Sym) { - if (std::error_code ec = (*unwrap(Sym))->getSection(*unwrap(Sect))) + ErrorOr<section_iterator> SecOrErr = (*unwrap(Sym))->getSection(); + if (std::error_code ec = SecOrErr.getError()) report_fatal_error(ec.message()); + *unwrap(Sect) = *SecOrErr; } // ObjectFile Symbol iterators diff --git a/contrib/llvm/lib/Object/ObjectFile.cpp b/contrib/llvm/lib/Object/ObjectFile.cpp index f82edae89bc6..d12dc411361c 100644 --- a/contrib/llvm/lib/Object/ObjectFile.cpp +++ b/contrib/llvm/lib/Object/ObjectFile.cpp @@ -29,10 +29,10 @@ ObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source) : SymbolicFile(Type, Source) {} bool SectionRef::containsSymbol(SymbolRef S) const { - section_iterator SymSec = getObject()->section_end(); - if (S.getSection(SymSec)) + ErrorOr<section_iterator> SymSec = S.getSection(); + if (!SymSec) return false; - return *this == *SymSec; + return *this == **SymSec; } uint64_t ObjectFile::getSymbolValue(DataRefImpl Ref) const { diff --git a/contrib/llvm/lib/Object/SymbolicFile.cpp b/contrib/llvm/lib/Object/SymbolicFile.cpp index 854e68e40f4d..bf79dfb8da62 100644 --- a/contrib/llvm/lib/Object/SymbolicFile.cpp +++ b/contrib/llvm/lib/Object/SymbolicFile.cpp @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Object/COFF.h" +#include "llvm/Object/COFFImportFile.h" #include "llvm/Object/IRObjectFile.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Object/SymbolicFile.h" @@ -54,9 +56,10 @@ ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile( 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); + case sys::fs::file_magic::coff_import_library: + return std::unique_ptr<SymbolicFile>(new COFFImportFile(Object)); case sys::fs::file_magic::elf_relocatable: case sys::fs::file_magic::macho_object: case sys::fs::file_magic::coff_object: { |