aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Object
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object')
-rw-r--r--contrib/llvm-project/llvm/lib/Object/Archive.cpp18
-rw-r--r--contrib/llvm-project/llvm/lib/Object/ArchiveWriter.cpp234
-rw-r--r--contrib/llvm-project/llvm/lib/Object/Binary.cpp7
-rw-r--r--contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp4
-rw-r--r--contrib/llvm-project/llvm/lib/Object/COFFModuleDefinition.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp161
-rw-r--r--contrib/llvm-project/llvm/lib/Object/DXContainer.cpp111
-rw-r--r--contrib/llvm-project/llvm/lib/Object/Decompressor.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/Object/ELF.cpp27
-rw-r--r--contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp87
-rw-r--r--contrib/llvm-project/llvm/lib/Object/Error.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/Object/IRObjectFile.cpp16
-rw-r--r--contrib/llvm-project/llvm/lib/Object/IRSymtab.cpp1
-rw-r--r--contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp229
-rw-r--r--contrib/llvm-project/llvm/lib/Object/MachOUniversal.cpp6
-rw-r--r--contrib/llvm-project/llvm/lib/Object/MachOUniversalWriter.cpp12
-rw-r--r--contrib/llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp3
-rw-r--r--contrib/llvm-project/llvm/lib/Object/Object.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/Object/ObjectFile.cpp15
-rw-r--r--contrib/llvm-project/llvm/lib/Object/OffloadBinary.cpp164
-rw-r--r--contrib/llvm-project/llvm/lib/Object/RecordStreamer.h8
-rw-r--r--contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp45
-rw-r--r--contrib/llvm-project/llvm/lib/Object/SymbolicFile.cpp9
-rw-r--r--contrib/llvm-project/llvm/lib/Object/TapiFile.cpp6
-rw-r--r--contrib/llvm-project/llvm/lib/Object/TapiUniversal.cpp5
-rw-r--r--contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp123
-rw-r--r--contrib/llvm-project/llvm/lib/Object/WindowsResource.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp27
28 files changed, 1123 insertions, 205 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/Archive.cpp b/contrib/llvm-project/llvm/lib/Object/Archive.cpp
index 9a4ef055faa4..ad03f9cae9f8 100644
--- a/contrib/llvm-project/llvm/lib/Object/Archive.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/Archive.cpp
@@ -22,6 +22,7 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
@@ -30,7 +31,6 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
-#include <cstring>
#include <memory>
#include <string>
#include <system_error>
@@ -257,6 +257,14 @@ Expected<StringRef> ArchiveMemberHeader::getName(uint64_t Size) const {
return Name;
if (Name.size() == 2 && Name[1] == '/') // String table.
return Name;
+ // System libraries from the Windows SDK for Windows 11 contain this symbol.
+ // It looks like a CFG guard: we just skip it for now.
+ if (Name.equals("/<XFGHASHMAP>/"))
+ return Name;
+ // Some libraries (e.g., arm64rt.lib) from the Windows WDK
+ // (version 10.0.22000.0) contain this undocumented special member.
+ if (Name.equals("/<ECSYMBOLS>/"))
+ return Name;
// It's a long name.
// Get the string table offset.
std::size_t StringOffset;
@@ -922,6 +930,14 @@ Archive::Archive(MemoryBufferRef Source, Error &Err)
Err = Error::success();
}
+object::Archive::Kind Archive::getDefaultKindForHost() {
+ Triple HostTriple(sys::getProcessTriple());
+ return HostTriple.isOSDarwin()
+ ? object::Archive::K_DARWIN
+ : (HostTriple.isOSAIX() ? object::Archive::K_AIXBIG
+ : object::Archive::K_GNU);
+}
+
Archive::child_iterator Archive::child_begin(Error &Err,
bool SkipInternal) const {
if (isEmpty())
diff --git a/contrib/llvm-project/llvm/lib/Object/ArchiveWriter.cpp b/contrib/llvm-project/llvm/lib/Object/ArchiveWriter.cpp
index 053b3dafed95..dbf5052cdac0 100644
--- a/contrib/llvm-project/llvm/lib/Object/ArchiveWriter.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/ArchiveWriter.cpp
@@ -18,16 +18,19 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/Error.h"
+#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/Support/Alignment.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SmallVectorMemoryBuffer.h"
-#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
@@ -44,6 +47,40 @@ NewArchiveMember::NewArchiveMember(MemoryBufferRef BufRef)
: Buf(MemoryBuffer::getMemBuffer(BufRef, false)),
MemberName(BufRef.getBufferIdentifier()) {}
+object::Archive::Kind NewArchiveMember::detectKindFromObject() const {
+ auto MemBufferRef = this->Buf->getMemBufferRef();
+ Expected<std::unique_ptr<object::ObjectFile>> OptionalObject =
+ object::ObjectFile::createObjectFile(MemBufferRef);
+
+ if (OptionalObject)
+ return isa<object::MachOObjectFile>(**OptionalObject)
+ ? object::Archive::K_DARWIN
+ : (isa<object::XCOFFObjectFile>(**OptionalObject)
+ ? object::Archive::K_AIXBIG
+ : object::Archive::K_GNU);
+
+ // Squelch the error in case we had a non-object file.
+ consumeError(OptionalObject.takeError());
+
+ // If we're adding a bitcode file to the archive, detect the Archive kind
+ // based on the target triple.
+ LLVMContext Context;
+ if (identify_magic(MemBufferRef.getBuffer()) == file_magic::bitcode) {
+ if (auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
+ MemBufferRef, file_magic::bitcode, &Context)) {
+ auto &IRObject = cast<object::IRObjectFile>(**ObjOrErr);
+ return Triple(IRObject.getTargetTriple()).isOSDarwin()
+ ? object::Archive::K_DARWIN
+ : object::Archive::K_GNU;
+ } else {
+ // Squelch the error in case this was not a SymbolicFile.
+ consumeError(ObjOrErr.takeError());
+ }
+ }
+
+ return object::Archive::getDefaultKindForHost();
+}
+
Expected<NewArchiveMember>
NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
bool Deterministic) {
@@ -128,16 +165,20 @@ static bool isDarwin(object::Archive::Kind Kind) {
Kind == object::Archive::K_DARWIN64;
}
+static bool isAIXBigArchive(object::Archive::Kind Kind) {
+ return Kind == object::Archive::K_AIXBIG;
+}
+
static bool isBSDLike(object::Archive::Kind Kind) {
switch (Kind) {
case object::Archive::K_GNU:
case object::Archive::K_GNU64:
+ case object::Archive::K_AIXBIG:
return false;
case object::Archive::K_BSD:
case object::Archive::K_DARWIN:
case object::Archive::K_DARWIN64:
return true;
- case object::Archive::K_AIXBIG:
case object::Archive::K_COFF:
break;
}
@@ -190,6 +231,31 @@ printBSDMemberHeader(raw_ostream &Out, uint64_t Pos, StringRef Name,
Out.write(uint8_t(0));
}
+static void
+printBigArchiveMemberHeader(raw_ostream &Out, StringRef Name,
+ const sys::TimePoint<std::chrono::seconds> &ModTime,
+ unsigned UID, unsigned GID, unsigned Perms,
+ uint64_t Size, unsigned PrevOffset,
+ unsigned NextOffset) {
+ unsigned NameLen = Name.size();
+
+ printWithSpacePadding(Out, Size, 20); // File member size
+ printWithSpacePadding(Out, NextOffset, 20); // Next member header offset
+ printWithSpacePadding(Out, PrevOffset, 20); // Previous member header offset
+ printWithSpacePadding(Out, sys::toTimeT(ModTime), 12); // File member date
+ // The big archive format has 12 chars for uid and gid.
+ printWithSpacePadding(Out, UID % 1000000000000, 12); // UID
+ printWithSpacePadding(Out, GID % 1000000000000, 12); // GID
+ printWithSpacePadding(Out, format("%o", Perms), 12); // Permission
+ printWithSpacePadding(Out, NameLen, 4); // Name length
+ if (NameLen) {
+ printWithSpacePadding(Out, Name, NameLen); // Name
+ if (NameLen % 2)
+ Out.write(uint8_t(0)); // Null byte padding
+ }
+ Out << "`\n"; // Terminator
+}
+
static bool useStringTable(bool Thin, StringRef Name) {
return Thin || Name.size() >= 16 || Name.contains('/');
}
@@ -200,8 +266,8 @@ static bool is64BitKind(object::Archive::Kind Kind) {
case object::Archive::K_BSD:
case object::Archive::K_DARWIN:
case object::Archive::K_COFF:
- case object::Archive::K_AIXBIG:
return false;
+ case object::Archive::K_AIXBIG:
case object::Archive::K_DARWIN64:
case object::Archive::K_GNU64:
return true;
@@ -305,7 +371,11 @@ static uint64_t computeSymbolTableSize(object::Archive::Kind Kind,
// least 4-byte aligned for 32-bit content. Opt for the larger encoding
// uniformly.
// We do this for all bsd formats because it simplifies aligning members.
- uint32_t Pad = offsetToAlignment(Size, Align(isBSDLike(Kind) ? 8 : 2));
+ // For the big archive format, the symbol table is the last member, so there
+ // is no need to align.
+ uint32_t Pad = isAIXBigArchive(Kind)
+ ? 0
+ : offsetToAlignment(Size, Align(isBSDLike(Kind) ? 8 : 2));
Size += Pad;
if (Padding)
*Padding = Pad;
@@ -313,11 +383,15 @@ static uint64_t computeSymbolTableSize(object::Archive::Kind Kind,
}
static void writeSymbolTableHeader(raw_ostream &Out, object::Archive::Kind Kind,
- bool Deterministic, uint64_t Size) {
+ bool Deterministic, uint64_t Size,
+ uint64_t PrevMemberOffset = 0) {
if (isBSDLike(Kind)) {
const char *Name = is64BitKind(Kind) ? "__.SYMDEF_64" : "__.SYMDEF";
printBSDMemberHeader(Out, Out.tell(), Name, now(Deterministic), 0, 0, 0,
Size);
+ } else if (isAIXBigArchive(Kind)) {
+ printBigArchiveMemberHeader(Out, "", now(Deterministic), 0, 0,
+ 0, Size, PrevMemberOffset, 0);
} else {
const char *Name = is64BitKind(Kind) ? "/SYM64" : "";
printGNUSmallMemberHeader(Out, Name, now(Deterministic), 0, 0, 0, Size);
@@ -326,7 +400,8 @@ static void writeSymbolTableHeader(raw_ostream &Out, object::Archive::Kind Kind,
static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind,
bool Deterministic, ArrayRef<MemberData> Members,
- StringRef StringTable) {
+ StringRef StringTable,
+ uint64_t PrevMemberOffset = 0) {
// We don't write a symbol table on an archive with no members -- except on
// Darwin, where the linker will abort unless the archive has a symbol table.
if (StringTable.empty() && !isDarwin(Kind))
@@ -339,9 +414,10 @@ static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind,
uint64_t OffsetSize = is64BitKind(Kind) ? 8 : 4;
uint32_t Pad;
uint64_t Size = computeSymbolTableSize(Kind, NumSyms, OffsetSize, StringTable, &Pad);
- writeSymbolTableHeader(Out, Kind, Deterministic, Size);
+ writeSymbolTableHeader(Out, Kind, Deterministic, Size, PrevMemberOffset);
- uint64_t Pos = Out.tell() + Size;
+ uint64_t Pos = isAIXBigArchive(Kind) ? sizeof(object::BigArchive::FixLenHdr)
+ : Out.tell() + Size;
if (isBSDLike(Kind))
printNBits(Out, Kind, NumSyms * 2 * OffsetSize);
@@ -410,9 +486,8 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
bool NeedSymbols, ArrayRef<NewArchiveMember> NewMembers) {
static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};
- // This ignores the symbol table, but we only need the value mod 8 and the
- // symbol table is aligned to be a multiple of 8 bytes
- uint64_t Pos = 0;
+ uint64_t Pos =
+ isAIXBigArchive(Kind) ? sizeof(object::BigArchive::FixLenHdr) : 0;
std::vector<MemberData> Ret;
bool HasObject = false;
@@ -472,6 +547,9 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
Entry.second = Entry.second > 1 ? 1 : 0;
}
+ // The big archive format needs to know the offset of the previous member
+ // header.
+ unsigned PrevOffset = 0;
for (const NewArchiveMember &M : NewMembers) {
std::string Header;
raw_string_ostream Out(Header);
@@ -504,8 +582,16 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
std::move(StringMsg), object::object_error::parse_failed);
}
- printMemberHeader(Out, Pos, StringTable, MemberNames, Kind, Thin, M,
- ModTime, Size);
+ if (isAIXBigArchive(Kind)) {
+ unsigned NextOffset = Pos + sizeof(object::BigArMemHdrType) +
+ alignTo(M.MemberName.size(), 2) + alignTo(Size, 2);
+ printBigArchiveMemberHeader(Out, M.MemberName, ModTime, M.UID, M.GID,
+ M.Perms, Size, PrevOffset, NextOffset);
+ PrevOffset = Pos;
+ } else {
+ printMemberHeader(Out, Pos, StringTable, MemberNames, Kind, Thin, M,
+ ModTime, Size);
+ }
Out.flush();
std::vector<unsigned> Symbols;
@@ -589,22 +675,25 @@ static Error writeArchiveToStream(raw_ostream &Out,
return E;
std::vector<MemberData> &Data = *DataOrErr;
- if (!StringTableBuf.empty())
+ if (!StringTableBuf.empty() && !isAIXBigArchive(Kind))
Data.insert(Data.begin(), computeStringTable(StringTableBuf));
// We would like to detect if we need to switch to a 64-bit symbol table.
- if (WriteSymtab) {
- uint64_t MaxOffset = 8; // For the file signature.
- uint64_t LastOffset = MaxOffset;
- uint64_t NumSyms = 0;
- for (const auto &M : Data) {
- // Record the start of the member's offset
- LastOffset = MaxOffset;
- // Account for the size of each part associated with the member.
- MaxOffset += M.Header.size() + M.Data.size() + M.Padding.size();
- NumSyms += M.Symbols.size();
- }
+ uint64_t LastMemberEndOffset =
+ isAIXBigArchive(Kind) ? sizeof(object::BigArchive::FixLenHdr) : 8;
+ uint64_t LastMemberHeaderOffset = LastMemberEndOffset;
+ uint64_t NumSyms = 0;
+ for (const auto &M : Data) {
+ // Record the start of the member's offset
+ LastMemberHeaderOffset = LastMemberEndOffset;
+ // Account for the size of each part associated with the member.
+ LastMemberEndOffset += M.Header.size() + M.Data.size() + M.Padding.size();
+ NumSyms += M.Symbols.size();
+ }
+ // The symbol table is put at the end of the big archive file. The symbol
+ // table is at the start of the archive file for other archive formats.
+ if (WriteSymtab && !isAIXBigArchive(Kind)) {
// We assume 32-bit offsets to see if 32-bit symbols are possible or not.
uint64_t SymtabSize = computeSymbolTableSize(Kind, NumSyms, 4, SymNamesBuf);
auto computeSymbolTableHeaderSize =
@@ -614,7 +703,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
writeSymbolTableHeader(Tmp, Kind, Deterministic, SymtabSize);
return TmpBuf.size();
};
- LastOffset += computeSymbolTableHeaderSize() + SymtabSize;
+ LastMemberHeaderOffset += computeSymbolTableHeaderSize() + SymtabSize;
// The SYM64 format is used when an archive's member offsets are larger than
// 32-bits can hold. The need for this shift in format is detected by
@@ -628,10 +717,10 @@ static Error writeArchiveToStream(raw_ostream &Out,
if (Sym64Env)
StringRef(Sym64Env).getAsInteger(10, Sym64Threshold);
- // If LastOffset isn't going to fit in a 32-bit varible we need to switch
- // to 64-bit. Note that the file can be larger than 4GB as long as the last
- // member starts before the 4GB offset.
- if (LastOffset >= Sym64Threshold) {
+ // If LastMemberHeaderOffset isn't going to fit in a 32-bit varible we need
+ // to switch to 64-bit. Note that the file can be larger than 4GB as long as
+ // the last member starts before the 4GB offset.
+ if (LastMemberHeaderOffset >= Sym64Threshold) {
if (Kind == object::Archive::K_DARWIN)
Kind = object::Archive::K_DARWIN64;
else
@@ -641,15 +730,92 @@ static Error writeArchiveToStream(raw_ostream &Out,
if (Thin)
Out << "!<thin>\n";
+ else if (isAIXBigArchive(Kind))
+ Out << "<bigaf>\n";
else
Out << "!<arch>\n";
- if (WriteSymtab)
- writeSymbolTable(Out, Kind, Deterministic, Data, SymNamesBuf);
+ if (!isAIXBigArchive(Kind)) {
+ if (WriteSymtab)
+ writeSymbolTable(Out, Kind, Deterministic, Data, SymNamesBuf);
+ for (const MemberData &M : Data)
+ Out << M.Header << M.Data << M.Padding;
+ } else {
+ // For the big archive (AIX) format, compute a table of member names and
+ // offsets, used in the member table.
+ uint64_t MemberTableNameStrTblSize = 0;
+ std::vector<size_t> MemberOffsets;
+ std::vector<StringRef> MemberNames;
+ // Loop across object to find offset and names.
+ uint64_t MemberEndOffset = sizeof(object::BigArchive::FixLenHdr);
+ for (size_t I = 0, Size = NewMembers.size(); I != Size; ++I) {
+ const NewArchiveMember &Member = NewMembers[I];
+ MemberTableNameStrTblSize += Member.MemberName.size() + 1;
+ MemberOffsets.push_back(MemberEndOffset);
+ MemberNames.push_back(Member.MemberName);
+ // File member name ended with "`\n". The length is included in
+ // BigArMemHdrType.
+ MemberEndOffset += sizeof(object::BigArMemHdrType) +
+ alignTo(Data[I].Data.size(), 2) +
+ alignTo(Member.MemberName.size(), 2);
+ }
- for (const MemberData &M : Data)
- Out << M.Header << M.Data << M.Padding;
+ // AIX member table size.
+ unsigned MemberTableSize = 20 + // Number of members field
+ 20 * MemberOffsets.size() +
+ MemberTableNameStrTblSize;
+
+ unsigned GlobalSymbolOffset =
+ (WriteSymtab && NumSyms > 0)
+ ? LastMemberEndOffset +
+ alignTo(sizeof(object::BigArMemHdrType) + MemberTableSize, 2)
+ : 0;
+
+ // Fixed Sized Header.
+ printWithSpacePadding(Out, NewMembers.size() ? LastMemberEndOffset : 0,
+ 20); // Offset to member table
+ // If there are no file members in the archive, there will be no global
+ // symbol table.
+ printWithSpacePadding(Out, NewMembers.size() ? GlobalSymbolOffset : 0, 20);
+ printWithSpacePadding(
+ Out, 0,
+ 20); // Offset to 64 bits global symbol table - Not supported yet
+ printWithSpacePadding(
+ Out, NewMembers.size() ? sizeof(object::BigArchive::FixLenHdr) : 0,
+ 20); // Offset to first archive member
+ printWithSpacePadding(Out, NewMembers.size() ? LastMemberHeaderOffset : 0,
+ 20); // Offset to last archive member
+ printWithSpacePadding(
+ Out, 0,
+ 20); // Offset to first member of free list - Not supported yet
+
+ for (const MemberData &M : Data) {
+ Out << M.Header << M.Data;
+ if (M.Data.size() % 2)
+ Out << '\0';
+ }
+ if (NewMembers.size()) {
+ // Member table.
+ printBigArchiveMemberHeader(Out, "", sys::toTimePoint(0), 0, 0, 0,
+ MemberTableSize, LastMemberHeaderOffset,
+ GlobalSymbolOffset);
+ printWithSpacePadding(Out, MemberOffsets.size(), 20); // Number of members
+ for (uint64_t MemberOffset : MemberOffsets)
+ printWithSpacePadding(Out, MemberOffset,
+ 20); // Offset to member file header.
+ for (StringRef MemberName : MemberNames)
+ Out << MemberName << '\0'; // Member file name, null byte padding.
+
+ if (MemberTableNameStrTblSize % 2)
+ Out << '\0'; // Name table must be tail padded to an even number of
+ // bytes.
+
+ if (WriteSymtab && NumSyms > 0)
+ writeSymbolTable(Out, Kind, Deterministic, Data, SymNamesBuf,
+ LastMemberEndOffset);
+ }
+ }
Out.flush();
return Error::success();
}
diff --git a/contrib/llvm-project/llvm/lib/Object/Binary.cpp b/contrib/llvm-project/llvm/lib/Object/Binary.cpp
index 143554344256..8065e3eb1d85 100644
--- a/contrib/llvm-project/llvm/lib/Object/Binary.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/Binary.cpp
@@ -18,14 +18,13 @@
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/Minidump.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/OffloadBinary.h"
#include "llvm/Object/TapiUniversal.h"
#include "llvm/Object/WindowsResource.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
-#include <algorithm>
#include <memory>
#include <system_error>
@@ -84,9 +83,13 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
// PDB does not support the Binary interface.
return errorCodeToError(object_error::invalid_file_type);
case file_magic::unknown:
+ case file_magic::cuda_fatbinary:
case file_magic::coff_cl_gl_object:
+ case file_magic::dxcontainer_object:
// Unrecognized object file format.
return errorCodeToError(object_error::invalid_file_type);
+ case file_magic::offload_binary:
+ return OffloadBinary::create(Buffer);
case file_magic::minidump:
return MinidumpFile::create(Buffer);
case file_magic::tapi_file:
diff --git a/contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp b/contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp
index 69bbf70b43a1..91ecea11511d 100644
--- a/contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp
@@ -12,10 +12,14 @@
#include "llvm/Object/COFFImportFile.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ArchiveWriter.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Path.h"
#include <cstdint>
diff --git a/contrib/llvm-project/llvm/lib/Object/COFFModuleDefinition.cpp b/contrib/llvm-project/llvm/lib/Object/COFFModuleDefinition.cpp
index 55ddd3baca2b..0666970d5c60 100644
--- a/contrib/llvm-project/llvm/lib/Object/COFFModuleDefinition.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/COFFModuleDefinition.cpp
@@ -17,12 +17,10 @@
#include "llvm/Object/COFFModuleDefinition.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Object/COFF.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
using namespace llvm::COFF;
using namespace llvm;
diff --git a/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
index 354b3c0d5577..1a4bb329201a 100644
--- a/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
@@ -25,7 +25,7 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/MemoryBufferRef.h"
#include <algorithm>
#include <cassert>
#include <cinttypes>
@@ -447,7 +447,8 @@ Error COFFObjectFile::initSymbolTablePtr() {
// Check that the string table is null terminated if has any in it.
if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
- return errorCodeToError(object_error::parse_failed);
+ return createStringError(object_error::parse_failed,
+ "string table missing null terminator");
return Error::success();
}
@@ -469,23 +470,43 @@ Error COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
}
// Returns the file offset for the given RVA.
-Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
+Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res,
+ const char *ErrorContext) const {
for (const SectionRef &S : sections()) {
const coff_section *Section = getCOFFSection(S);
uint32_t SectionStart = Section->VirtualAddress;
uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
if (SectionStart <= Addr && Addr < SectionEnd) {
+ // A table/directory entry can be pointing to somewhere in a stripped
+ // section, in an object that went through `objcopy --only-keep-debug`.
+ // In this case we don't want to cause the parsing of the object file to
+ // fail, otherwise it will be impossible to use this object as debug info
+ // in LLDB. Return SectionStrippedError here so that
+ // COFFObjectFile::initialize can ignore the error.
+ // Somewhat common binaries may have RVAs pointing outside of the
+ // provided raw data. Instead of rejecting the binaries, just
+ // treat the section as stripped for these purposes.
+ if (Section->SizeOfRawData < Section->VirtualSize &&
+ Addr >= SectionStart + Section->SizeOfRawData) {
+ return make_error<SectionStrippedError>();
+ }
uint32_t Offset = Addr - SectionStart;
Res = reinterpret_cast<uintptr_t>(base()) + Section->PointerToRawData +
Offset;
return Error::success();
}
}
- return errorCodeToError(object_error::parse_failed);
+ if (ErrorContext)
+ return createStringError(object_error::parse_failed,
+ "RVA 0x%" PRIx32 " for %s not found", Addr,
+ ErrorContext);
+ return createStringError(object_error::parse_failed,
+ "RVA 0x%" PRIx32 " not found", Addr);
}
Error COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
- ArrayRef<uint8_t> &Contents) const {
+ ArrayRef<uint8_t> &Contents,
+ const char *ErrorContext) const {
for (const SectionRef &S : sections()) {
const coff_section *Section = getCOFFSection(S);
uint32_t SectionStart = Section->VirtualAddress;
@@ -501,7 +522,12 @@ Error COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
return Error::success();
}
}
- return errorCodeToError(object_error::parse_failed);
+ if (ErrorContext)
+ return createStringError(object_error::parse_failed,
+ "RVA 0x%" PRIx32 " for %s not found", RVA,
+ ErrorContext);
+ return createStringError(object_error::parse_failed,
+ "RVA 0x%" PRIx32 " not found", RVA);
}
// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
@@ -521,11 +547,12 @@ Error COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir,
const codeview::DebugInfo *&PDBInfo,
StringRef &PDBFileName) const {
ArrayRef<uint8_t> InfoBytes;
- if (Error E = getRvaAndSizeAsBytes(
- DebugDir->AddressOfRawData, DebugDir->SizeOfData, InfoBytes))
+ if (Error E =
+ getRvaAndSizeAsBytes(DebugDir->AddressOfRawData, DebugDir->SizeOfData,
+ InfoBytes, "PDB info"))
return E;
if (InfoBytes.size() < sizeof(*PDBInfo) + 1)
- return errorCodeToError(object_error::parse_failed);
+ return createStringError(object_error::parse_failed, "PDB info too small");
PDBInfo = reinterpret_cast<const codeview::DebugInfo *>(InfoBytes.data());
InfoBytes = InfoBytes.drop_front(sizeof(*PDBInfo));
PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()),
@@ -563,7 +590,7 @@ Error COFFObjectFile::initImportTablePtr() {
// Find the section that contains the RVA. This is needed because the RVA is
// the import table's memory address which is different from its file offset.
uintptr_t IntPtr = 0;
- if (Error E = getRvaPtr(ImportTableRva, IntPtr))
+ if (Error E = getRvaPtr(ImportTableRva, IntPtr, "import table"))
return E;
if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
return E;
@@ -586,8 +613,11 @@ Error COFFObjectFile::initDelayImportTablePtr() {
sizeof(delay_import_directory_table_entry) - 1;
uintptr_t IntPtr = 0;
- if (Error E = getRvaPtr(RVA, IntPtr))
+ if (Error E = getRvaPtr(RVA, IntPtr, "delay import table"))
return E;
+ if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
+ return E;
+
DelayImportDirectory = reinterpret_cast<
const delay_import_directory_table_entry *>(IntPtr);
return Error::success();
@@ -607,8 +637,11 @@ Error COFFObjectFile::initExportTablePtr() {
uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
uintptr_t IntPtr = 0;
- if (Error E = getRvaPtr(ExportTableRva, IntPtr))
+ if (Error E = getRvaPtr(ExportTableRva, IntPtr, "export table"))
return E;
+ if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
+ return E;
+
ExportDirectory =
reinterpret_cast<const export_directory_table_entry *>(IntPtr);
return Error::success();
@@ -623,8 +656,12 @@ Error COFFObjectFile::initBaseRelocPtr() {
return Error::success();
uintptr_t IntPtr = 0;
- if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+ if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr,
+ "base reloc table"))
+ return E;
+ if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
return E;
+
BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
IntPtr);
BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
@@ -646,11 +683,16 @@ Error COFFObjectFile::initDebugDirectoryPtr() {
// Check that the size is a multiple of the entry size.
if (DataEntry->Size % sizeof(debug_directory) != 0)
- return errorCodeToError(object_error::parse_failed);
+ return createStringError(object_error::parse_failed,
+ "debug directory has uneven size");
uintptr_t IntPtr = 0;
- if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+ if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr,
+ "debug directory"))
+ return E;
+ if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
return E;
+
DebugDirectoryBegin = reinterpret_cast<const debug_directory *>(IntPtr);
DebugDirectoryEnd = reinterpret_cast<const debug_directory *>(
IntPtr + DataEntry->Size);
@@ -680,7 +722,10 @@ Error COFFObjectFile::initTLSDirectoryPtr() {
static_cast<uint32_t>(DataEntry->Size), DirSize);
uintptr_t IntPtr = 0;
- if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+ if (Error E =
+ getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr, "TLS directory"))
+ return E;
+ if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
return E;
if (is64())
@@ -701,7 +746,10 @@ Error COFFObjectFile::initLoadConfigPtr() {
if (DataEntry->RelativeVirtualAddress == 0)
return Error::success();
uintptr_t IntPtr = 0;
- if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+ if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr,
+ "load config table"))
+ return E;
+ if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
return E;
LoadConfig = (const void *)IntPtr;
@@ -727,6 +775,14 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object)
DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr),
TLSDirectory32(nullptr), TLSDirectory64(nullptr) {}
+static Error ignoreStrippedErrors(Error E) {
+ if (E.isA<SectionStrippedError>()) {
+ consumeError(std::move(E));
+ return Error::success();
+ }
+ return E;
+}
+
Error COFFObjectFile::initialize() {
// Check that we at least have enough room for a header.
std::error_code EC;
@@ -749,7 +805,8 @@ Error COFFObjectFile::initialize() {
CurPtr = DH->AddressOfNewExeHeader;
// Check the PE magic bytes. ("PE\0\0")
if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) {
- return errorCodeToError(object_error::parse_failed);
+ return createStringError(object_error::parse_failed,
+ "incorrect PE magic");
}
CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
HasPEHeader = true;
@@ -805,7 +862,8 @@ Error COFFObjectFile::initialize() {
DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
} else {
// It's neither PE32 nor PE32+.
- return errorCodeToError(object_error::parse_failed);
+ return createStringError(object_error::parse_failed,
+ "incorrect PE magic");
}
if (Error E = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))
return E;
@@ -834,33 +892,34 @@ Error COFFObjectFile::initialize() {
} else {
// We had better not have any symbols if we don't have a symbol table.
if (getNumberOfSymbols() != 0) {
- return errorCodeToError(object_error::parse_failed);
+ return createStringError(object_error::parse_failed,
+ "symbol table missing");
}
}
// Initialize the pointer to the beginning of the import table.
- if (Error E = initImportTablePtr())
+ if (Error E = ignoreStrippedErrors(initImportTablePtr()))
return E;
- if (Error E = initDelayImportTablePtr())
+ if (Error E = ignoreStrippedErrors(initDelayImportTablePtr()))
return E;
// Initialize the pointer to the export table.
- if (Error E = initExportTablePtr())
+ if (Error E = ignoreStrippedErrors(initExportTablePtr()))
return E;
// Initialize the pointer to the base relocation table.
- if (Error E = initBaseRelocPtr())
+ if (Error E = ignoreStrippedErrors(initBaseRelocPtr()))
return E;
// Initialize the pointer to the debug directory.
- if (Error E = initDebugDirectoryPtr())
+ if (Error E = ignoreStrippedErrors(initDebugDirectoryPtr()))
return E;
// Initialize the pointer to the TLS directory.
- if (Error E = initTLSDirectoryPtr())
+ if (Error E = ignoreStrippedErrors(initTLSDirectoryPtr()))
return E;
- if (Error E = initLoadConfigPtr())
+ if (Error E = ignoreStrippedErrors(initLoadConfigPtr()))
return E;
return Error::success();
@@ -1021,13 +1080,14 @@ Expected<const coff_section *> COFFObjectFile::getSection(int32_t Index) const {
// We already verified the section table data, so no need to check again.
return SectionTable + (Index - 1);
}
- return errorCodeToError(object_error::parse_failed);
+ return createStringError(object_error::parse_failed,
+ "section index out of bounds");
}
Expected<StringRef> COFFObjectFile::getString(uint32_t Offset) const {
if (StringTableSize <= 4)
// Tried to get a string from an empty string table.
- return errorCodeToError(object_error::parse_failed);
+ return createStringError(object_error::parse_failed, "string table empty");
if (Offset >= StringTableSize)
return errorCodeToError(object_error::unexpected_eof);
return StringRef(StringTable + Offset);
@@ -1086,13 +1146,7 @@ uint32_t COFFObjectFile::getSymbolIndex(COFFSymbolRef Symbol) const {
Expected<StringRef>
COFFObjectFile::getSectionName(const coff_section *Sec) const {
- StringRef Name;
- if (Sec->Name[COFF::NameSize - 1] == 0)
- // Null terminated, let ::strlen figure out the length.
- Name = Sec->Name;
- else
- // Not null terminated, use all 8 bytes.
- Name = StringRef(Sec->Name, COFF::NameSize);
+ StringRef Name = StringRef(Sec->Name, COFF::NameSize).split('\0').first;
// Check for string table entry. First byte is '/'.
if (Name.startswith("/")) {
@@ -1414,7 +1468,8 @@ ImportDirectoryEntryRef::lookup_table_symbols() const {
Error ImportDirectoryEntryRef::getName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (Error E = OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
+ if (Error E = OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr,
+ "import directory name"))
return E;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return Error::success();
@@ -1460,7 +1515,8 @@ DelayImportDirectoryEntryRef::imported_symbols() const {
Error DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (Error E = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
+ if (Error E = OwningObject->getRvaPtr(Table[Index].Name, IntPtr,
+ "delay import directory name"))
return E;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return Error::success();
@@ -1477,7 +1533,7 @@ Error DelayImportDirectoryEntryRef::getImportAddress(int AddrIndex,
uint32_t RVA = Table[Index].DelayImportAddressTable +
AddrIndex * (OwningObject->is64() ? 8 : 4);
uintptr_t IntPtr = 0;
- if (Error E = OwningObject->getRvaPtr(RVA, IntPtr))
+ if (Error E = OwningObject->getRvaPtr(RVA, IntPtr, "import address"))
return E;
if (OwningObject->is64())
Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
@@ -1499,7 +1555,8 @@ void ExportDirectoryEntryRef::moveNext() {
// by ordinal, the empty string is set as a result.
Error ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (Error E = OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
+ if (Error E =
+ OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr, "dll name"))
return E;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return Error::success();
@@ -1520,8 +1577,8 @@ Error ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
// Returns the address of the current export symbol.
Error ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
uintptr_t IntPtr = 0;
- if (Error EC =
- OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
+ if (Error EC = OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA,
+ IntPtr, "export address"))
return EC;
const export_address_table_entry *entry =
reinterpret_cast<const export_address_table_entry *>(IntPtr);
@@ -1534,8 +1591,8 @@ Error ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
Error
ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (Error EC =
- OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr))
+ if (Error EC = OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr,
+ "export ordinal table"))
return EC;
const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
@@ -1545,11 +1602,12 @@ ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
I < E; ++I, ++Offset) {
if (*I != Index)
continue;
- if (Error EC =
- OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr))
+ if (Error EC = OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr,
+ "export table entry"))
return EC;
const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
- if (Error EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
+ if (Error EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr,
+ "export symbol name"))
return EC;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return Error::success();
@@ -1562,7 +1620,8 @@ Error ExportDirectoryEntryRef::isForwarder(bool &Result) const {
const data_directory *DataEntry =
OwningObject->getDataDirectory(COFF::EXPORT_TABLE);
if (!DataEntry)
- return errorCodeToError(object_error::parse_failed);
+ return createStringError(object_error::parse_failed,
+ "export table missing");
uint32_t RVA;
if (auto EC = getExportRVA(RVA))
return EC;
@@ -1577,7 +1636,7 @@ Error ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
if (auto EC = getExportRVA(RVA))
return EC;
uintptr_t IntPtr = 0;
- if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr))
+ if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr, "export forward target"))
return EC;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return Error::success();
@@ -1606,7 +1665,7 @@ Error ImportedSymbolRef::getSymbolName(StringRef &Result) const {
RVA = Entry64[Index].getHintNameRVA();
}
uintptr_t IntPtr = 0;
- if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr))
+ if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr, "import symbol name"))
return EC;
// +2 because the first two bytes is hint.
Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
@@ -1645,7 +1704,7 @@ Error ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
RVA = Entry64[Index].getHintNameRVA();
}
uintptr_t IntPtr = 0;
- if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr))
+ if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr, "import symbol ordinal"))
return EC;
Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
return Error::success();
diff --git a/contrib/llvm-project/llvm/lib/Object/DXContainer.cpp b/contrib/llvm-project/llvm/lib/Object/DXContainer.cpp
new file mode 100644
index 000000000000..ca859c1f69ae
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/Object/DXContainer.cpp
@@ -0,0 +1,111 @@
+//===- DXContainer.cpp - DXContainer object file implementation -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/DXContainer.h"
+#include "llvm/BinaryFormat/DXContainer.h"
+#include "llvm/Object/Error.h"
+
+using namespace llvm;
+using namespace llvm::object;
+
+static Error parseFailed(const Twine &Msg) {
+ return make_error<GenericBinaryError>(Msg.str(), object_error::parse_failed);
+}
+
+template <typename T>
+static Error readStruct(StringRef Buffer, const char *Src, T &Struct) {
+ // Don't read before the beginning or past the end of the file
+ if (Src < Buffer.begin() || Src + sizeof(T) > Buffer.end())
+ return parseFailed("Reading structure out of file bounds");
+
+ memcpy(&Struct, Src, sizeof(T));
+ // DXContainer is always little endian
+ if (sys::IsBigEndianHost)
+ Struct.swapBytes();
+ return Error::success();
+}
+
+template <typename T>
+static Error readInteger(StringRef Buffer, const char *Src, T &Val) {
+ static_assert(std::is_integral<T>::value,
+ "Cannot call readInteger on non-integral type.");
+ assert(reinterpret_cast<uintptr_t>(Src) % alignof(T) == 0 &&
+ "Unaligned read of value from buffer!");
+ // Don't read before the beginning or past the end of the file
+ if (Src < Buffer.begin() || Src + sizeof(T) > Buffer.end())
+ return parseFailed("Reading structure out of file bounds");
+
+ Val = *reinterpret_cast<const T *>(Src);
+ // DXContainer is always little endian
+ if (sys::IsBigEndianHost)
+ sys::swapByteOrder(Val);
+ return Error::success();
+}
+
+DXContainer::DXContainer(MemoryBufferRef O) : Data(O) {}
+
+Error DXContainer::parseHeader() {
+ return readStruct(Data.getBuffer(), Data.getBuffer().data(), Header);
+}
+
+Error DXContainer::parseDXILHeader(uint32_t Offset) {
+ if (DXIL)
+ return parseFailed("More than one DXIL part is present in the file");
+ const char *Current = Data.getBuffer().data() + Offset;
+ dxbc::ProgramHeader Header;
+ if (Error Err = readStruct(Data.getBuffer(), Current, Header))
+ return Err;
+ Current += offsetof(dxbc::ProgramHeader, Bitcode) + Header.Bitcode.Offset;
+ DXIL.emplace(std::make_pair(Header, Current));
+ return Error::success();
+}
+
+Error DXContainer::parsePartOffsets() {
+ const char *Current = Data.getBuffer().data() + sizeof(dxbc::Header);
+ for (uint32_t Part = 0; Part < Header.PartCount; ++Part) {
+ uint32_t PartOffset;
+ if (Error Err = readInteger(Data.getBuffer(), Current, PartOffset))
+ return Err;
+ Current += sizeof(uint32_t);
+ // We need to ensure that each part offset leaves enough space for a part
+ // header. To prevent overflow, we subtract the part header size from the
+ // buffer size, rather than adding to the offset. Since the file header is
+ // larger than the part header we can't reach this code unless the buffer
+ // is larger than the part header, so this can't underflow.
+ if (PartOffset > Data.getBufferSize() - sizeof(dxbc::PartHeader))
+ return parseFailed("Part offset points beyond boundary of the file");
+ PartOffsets.push_back(PartOffset);
+
+ // If this isn't a dxil part stop here...
+ if (Data.getBuffer().substr(PartOffset, 4) != "DXIL")
+ continue;
+ if (Error Err = parseDXILHeader(PartOffset + sizeof(dxbc::PartHeader)))
+ return Err;
+ }
+ return Error::success();
+}
+
+Expected<DXContainer> DXContainer::create(MemoryBufferRef Object) {
+ DXContainer Container(Object);
+ if (Error Err = Container.parseHeader())
+ return std::move(Err);
+ if (Error Err = Container.parsePartOffsets())
+ return std::move(Err);
+ return Container;
+}
+
+void DXContainer::PartIterator::updateIteratorImpl(const uint32_t Offset) {
+ StringRef Buffer = Container.Data.getBuffer();
+ const char *Current = Buffer.data() + Offset;
+ // Offsets are validated during parsing, so all offsets in the container are
+ // valid and contain enough readable data to read a header.
+ cantFail(readStruct(Buffer, Current, IteratorState.Part));
+ IteratorState.Data =
+ StringRef(Current + sizeof(dxbc::PartHeader), IteratorState.Part.Size);
+ IteratorState.Offset = Offset;
+}
diff --git a/contrib/llvm-project/llvm/lib/Object/Decompressor.cpp b/contrib/llvm-project/llvm/lib/Object/Decompressor.cpp
index 11efd857d1a1..de067ed59ac5 100644
--- a/contrib/llvm-project/llvm/lib/Object/Decompressor.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/Decompressor.cpp
@@ -8,7 +8,7 @@
#include "llvm/Object/Decompressor.h"
#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Endian.h"
diff --git a/contrib/llvm-project/llvm/lib/Object/ELF.cpp b/contrib/llvm-project/llvm/lib/Object/ELF.cpp
index 56a426211755..6acf4543be5a 100644
--- a/contrib/llvm-project/llvm/lib/Object/ELF.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/ELF.cpp
@@ -166,6 +166,13 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
break;
}
break;
+ case ELF::EM_LOONGARCH:
+ switch (Type) {
+#include "llvm/BinaryFormat/ELFRelocs/LoongArch.def"
+ default:
+ break;
+ }
+ break;
default:
break;
}
@@ -288,6 +295,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART);
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR);
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR);
+ STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP_V0);
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP);
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
@@ -633,7 +641,6 @@ ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec) const {
DataExtractor::Cursor Cur(0);
Error ULEBSizeErr = Error::success();
-
// Helper to extract and decode the next ULEB128 value as uint32_t.
// Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the uint32_t
// limit.
@@ -653,18 +660,34 @@ ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec) const {
return static_cast<uint32_t>(Value);
};
+ uint8_t Version = 0;
while (!ULEBSizeErr && Cur && Cur.tell() < Content.size()) {
+ if (Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
+ Version = Data.getU8(Cur);
+ if (!Cur)
+ break;
+ if (Version > 1)
+ return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +
+ Twine(static_cast<int>(Version)));
+ Data.getU8(Cur); // Feature byte
+ }
uintX_t Address = static_cast<uintX_t>(Data.getAddress(Cur));
uint32_t NumBlocks = ReadULEB128AsUInt32();
std::vector<BBAddrMap::BBEntry> BBEntries;
+ uint32_t PrevBBEndOffset = 0;
for (uint32_t BlockID = 0; !ULEBSizeErr && Cur && (BlockID < NumBlocks);
++BlockID) {
uint32_t Offset = ReadULEB128AsUInt32();
uint32_t Size = ReadULEB128AsUInt32();
uint32_t Metadata = ReadULEB128AsUInt32();
+ if (Version >= 1) {
+ // Offset is calculated relative to the end of the previous BB.
+ Offset += PrevBBEndOffset;
+ PrevBBEndOffset = Offset + Size;
+ }
BBEntries.push_back({Offset, Size, Metadata});
}
- FunctionEntries.push_back({Address, BBEntries});
+ FunctionEntries.push_back({Address, std::move(BBEntries)});
}
// Either Cur is in the error state, or ULEBSizeError is set (not both), but
// we join the two errors here to be safe.
diff --git a/contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp
index cf1f12d9a9a7..38de669f1d3d 100644
--- a/contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp
@@ -21,7 +21,6 @@
#include "llvm/Object/Error.h"
#include "llvm/Support/ARMAttributeParser.h"
#include "llvm/Support/ARMBuildAttributes.h"
-#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/RISCVAttributeParser.h"
@@ -31,7 +30,6 @@
#include <cstdint>
#include <memory>
#include <string>
-#include <system_error>
#include <utility>
using namespace llvm;
@@ -169,11 +167,11 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
bool isV7 = false;
Optional<unsigned> Attr =
Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
- if (Attr.hasValue())
+ if (Attr)
isV7 = Attr.getValue() == ARMBuildAttrs::v7;
Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
- if (Attr.hasValue()) {
+ if (Attr) {
switch (Attr.getValue()) {
case ARMBuildAttrs::ApplicationProfile:
Features.AddFeature("aclass");
@@ -192,7 +190,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);
- if (Attr.hasValue()) {
+ if (Attr) {
switch (Attr.getValue()) {
default:
break;
@@ -207,7 +205,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch);
- if (Attr.hasValue()) {
+ if (Attr) {
switch (Attr.getValue()) {
default:
break;
@@ -231,7 +229,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch);
- if (Attr.hasValue()) {
+ if (Attr) {
switch (Attr.getValue()) {
default:
break;
@@ -250,7 +248,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch);
- if (Attr.hasValue()) {
+ if (Attr) {
switch (Attr.getValue()) {
default:
break;
@@ -269,7 +267,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use);
- if (Attr.hasValue()) {
+ if (Attr) {
switch (Attr.getValue()) {
default:
break;
@@ -305,11 +303,11 @@ SubtargetFeatures ELFObjectFileBase::getRISCVFeatures() const {
}
Optional<StringRef> Attr = Attributes.getAttributeString(RISCVAttrs::ARCH);
- if (Attr.hasValue()) {
+ if (Attr) {
// The Arch pattern is [rv32|rv64][i|e]version(_[m|a|f|d|c]version)*
// Version string pattern is (major)p(minor). Major and minor are optional.
// For example, a version number could be 2p0, 2, or p92.
- StringRef Arch = Attr.getValue();
+ StringRef Arch = *Attr;
if (Arch.consume_front("rv32"))
Features.AddFeature("64bit", false);
else if (Arch.consume_front("rv64"))
@@ -360,6 +358,8 @@ Optional<StringRef> ELFObjectFileBase::tryGetCPUName() const {
switch (getEMachine()) {
case ELF::EM_AMDGPU:
return getAMDGPUCPUName();
+ case ELF::EM_PPC64:
+ return StringRef("future");
default:
return None;
}
@@ -461,6 +461,8 @@ StringRef ELFObjectFileBase::getAMDGPUCPUName() const {
return "gfx90a";
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C:
return "gfx90c";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX940:
+ return "gfx940";
// AMDGCN GFX10.
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010:
@@ -483,6 +485,18 @@ StringRef ELFObjectFileBase::getAMDGPUCPUName() const {
return "gfx1034";
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1035:
return "gfx1035";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1036:
+ return "gfx1036";
+
+ // AMDGCN GFX11.
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1100:
+ return "gfx1100";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1101:
+ return "gfx1101";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1102:
+ return "gfx1102";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1103:
+ return "gfx1103";
default:
llvm_unreachable("Unknown EF_AMDGPU_MACH value");
}
@@ -509,7 +523,7 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
Optional<unsigned> Attr =
Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
- if (Attr.hasValue()) {
+ if (Attr) {
switch (Attr.getValue()) {
case ARMBuildAttrs::v4:
Triple += "v4";
@@ -541,7 +555,7 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
case ARMBuildAttrs::v7: {
Optional<unsigned> ArchProfileAttr =
Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
- if (ArchProfileAttr.hasValue() &&
+ if (ArchProfileAttr &&
ArchProfileAttr.getValue() == ARMBuildAttrs::MicroControllerProfile)
Triple += "v7m";
else
@@ -572,6 +586,9 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
case ARMBuildAttrs::v8_1_M_Main:
Triple += "v8.1m.main";
break;
+ case ARMBuildAttrs::v9_A:
+ Triple += "v9a";
+ break;
}
}
if (!isLittleEndian())
@@ -656,6 +673,36 @@ ELFObjectFileBase::getPltAddresses() const {
}
template <class ELFT>
+Expected<std::vector<BBAddrMap>>
+readBBAddrMapImpl(const ELFFile<ELFT> &EF,
+ Optional<unsigned> TextSectionIndex) {
+ using Elf_Shdr = typename ELFT::Shdr;
+ std::vector<BBAddrMap> BBAddrMaps;
+ const auto &Sections = cantFail(EF.sections());
+ for (const Elf_Shdr &Sec : Sections) {
+ if (Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP &&
+ Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP_V0)
+ continue;
+ if (TextSectionIndex) {
+ Expected<const Elf_Shdr *> TextSecOrErr = EF.getSection(Sec.sh_link);
+ if (!TextSecOrErr)
+ return createError("unable to get the linked-to section for " +
+ describe(EF, Sec) + ": " +
+ toString(TextSecOrErr.takeError()));
+ if (*TextSectionIndex != std::distance(Sections.begin(), *TextSecOrErr))
+ continue;
+ }
+ Expected<std::vector<BBAddrMap>> BBAddrMapOrErr = EF.decodeBBAddrMap(Sec);
+ if (!BBAddrMapOrErr)
+ return createError("unable to read " + describe(EF, Sec) + ": " +
+ toString(BBAddrMapOrErr.takeError()));
+ std::move(BBAddrMapOrErr->begin(), BBAddrMapOrErr->end(),
+ std::back_inserter(BBAddrMaps));
+ }
+ return BBAddrMaps;
+}
+
+template <class ELFT>
static Expected<std::vector<VersionEntry>>
readDynsymVersionsImpl(const ELFFile<ELFT> &EF,
ELFObjectFileBase::elf_symbol_iterator_range Symbols) {
@@ -723,3 +770,17 @@ ELFObjectFileBase::readDynsymVersions() const {
return readDynsymVersionsImpl(cast<ELF64BEObjectFile>(this)->getELFFile(),
Symbols);
}
+
+Expected<std::vector<BBAddrMap>>
+ELFObjectFileBase::readBBAddrMap(Optional<unsigned> TextSectionIndex) const {
+ if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))
+ return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex);
+ if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))
+ return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex);
+ if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))
+ return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex);
+ if (const auto *Obj = cast<ELF64BEObjectFile>(this))
+ return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex);
+ else
+ llvm_unreachable("Unsupported binary format");
+}
diff --git a/contrib/llvm-project/llvm/lib/Object/Error.cpp b/contrib/llvm-project/llvm/lib/Object/Error.cpp
index bc75bc6c0445..6d1e3f2a59d0 100644
--- a/contrib/llvm-project/llvm/lib/Object/Error.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/Error.cpp
@@ -52,6 +52,8 @@ std::string _object_error_category::message(int EV) const {
return "Bitcode section not found in object file";
case object_error::invalid_symbol_index:
return "Invalid symbol index";
+ case object_error::section_stripped:
+ return "Section has been stripped from the object file";
}
llvm_unreachable("An enumerator of object_error does not have a message "
"defined.");
diff --git a/contrib/llvm-project/llvm/lib/Object/IRObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/IRObjectFile.cpp
index c653262791cc..091930988bd0 100644
--- a/contrib/llvm-project/llvm/lib/Object/IRObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/IRObjectFile.cpp
@@ -11,20 +11,20 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/IRObjectFile.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/IR/GVMaterializer.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
-#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace object;
+namespace llvm {
+class LLVMContext;
+class raw_ostream;
+} // namespace llvm
+
IRObjectFile::IRObjectFile(MemoryBufferRef Object,
std::vector<std::unique_ptr<Module>> Mods)
: SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) {
@@ -32,7 +32,7 @@ IRObjectFile::IRObjectFile(MemoryBufferRef Object,
SymTab.addModule(M.get());
}
-IRObjectFile::~IRObjectFile() {}
+IRObjectFile::~IRObjectFile() = default;
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) {
return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p);
diff --git a/contrib/llvm-project/llvm/lib/Object/IRSymtab.cpp b/contrib/llvm-project/llvm/lib/Object/IRSymtab.cpp
index dea3d90d3560..5a7ecdb1fc25 100644
--- a/contrib/llvm-project/llvm/lib/Object/IRSymtab.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/IRSymtab.cpp
@@ -24,7 +24,6 @@
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/StringTableBuilder.h"
-#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/ModuleSymbolTable.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/Allocator.h"
diff --git a/contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp
index 3d95b18f4672..2f463a1bd458 100644
--- a/contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp
@@ -34,7 +34,7 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/LEB128.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/MemoryBufferRef.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/raw_ostream.h"
@@ -1303,7 +1303,6 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
}
const char *DyldIdLoadCmd = nullptr;
- const char *FuncStartsLoadCmd = nullptr;
const char *SplitInfoLoadCmd = nullptr;
const char *CodeSignDrsLoadCmd = nullptr;
const char *CodeSignLoadCmd = nullptr;
@@ -1381,6 +1380,11 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd,
"LC_DYLD_INFO_ONLY", Elements)))
return;
+ } else if (Load.C.cmd == MachO::LC_DYLD_CHAINED_FIXUPS) {
+ if ((Err = checkLinkeditDataCommand(
+ *this, Load, I, &DyldChainedFixupsLoadCmd,
+ "LC_DYLD_CHAINED_FIXUPS", Elements, "chained fixups")))
+ return;
} else if (Load.C.cmd == MachO::LC_UUID) {
if (Load.C.cmdsize != sizeof(MachO::uuid_command)) {
Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect "
@@ -1596,9 +1600,9 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
return;
// Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported.
} else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
- if ((Err = checkTwoLevelHintsCommand(*this, Load, I,
- &TwoLevelHintsLoadCmd, Elements)))
- return;
+ if ((Err = checkTwoLevelHintsCommand(*this, Load, I,
+ &TwoLevelHintsLoadCmd, Elements)))
+ return;
} else if (Load.C.cmd == MachO::LC_IDENT) {
// Note: LC_IDENT is ignored.
continue;
@@ -2993,7 +2997,9 @@ void ExportEntry::pushNode(uint64_t offset) {
return;
}
if (O != nullptr) {
- if (State.Other > O->getLibraryCount()) {
+ // Only positive numbers represent library ordinals. Zero and negative
+ // numbers have special meaning (see BindSpecialDylib).
+ if ((int64_t)State.Other > 0 && State.Other > O->getLibraryCount()) {
*E = malformedError(
"bad library ordinal: " + Twine((int)State.Other) + " (max " +
Twine((int)O->getLibraryCount()) +
@@ -3186,6 +3192,106 @@ iterator_range<export_iterator> MachOObjectFile::exports(Error &Err) const {
return exports(Err, getDyldInfoExportsTrie(), this);
}
+MachOAbstractFixupEntry::MachOAbstractFixupEntry(Error *E,
+ const MachOObjectFile *O)
+ : E(E), O(O) {
+ // Cache the vmaddress of __TEXT
+ for (const auto &Command : O->load_commands()) {
+ if (Command.C.cmd == MachO::LC_SEGMENT) {
+ MachO::segment_command SLC = O->getSegmentLoadCommand(Command);
+ if (StringRef(SLC.segname) == StringRef("__TEXT")) {
+ TextAddress = SLC.vmaddr;
+ break;
+ }
+ } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
+ MachO::segment_command_64 SLC_64 = O->getSegment64LoadCommand(Command);
+ if (StringRef(SLC_64.segname) == StringRef("__TEXT")) {
+ TextAddress = SLC_64.vmaddr;
+ break;
+ }
+ }
+ }
+}
+
+int32_t MachOAbstractFixupEntry::segmentIndex() const { return SegmentIndex; }
+
+uint64_t MachOAbstractFixupEntry::segmentOffset() const {
+ return SegmentOffset;
+}
+
+uint64_t MachOAbstractFixupEntry::segmentAddress() const {
+ return O->BindRebaseAddress(SegmentIndex, 0);
+}
+
+StringRef MachOAbstractFixupEntry::segmentName() const {
+ return O->BindRebaseSegmentName(SegmentIndex);
+}
+
+StringRef MachOAbstractFixupEntry::sectionName() const {
+ return O->BindRebaseSectionName(SegmentIndex, SegmentOffset);
+}
+
+uint64_t MachOAbstractFixupEntry::address() const {
+ return O->BindRebaseAddress(SegmentIndex, SegmentOffset);
+}
+
+StringRef MachOAbstractFixupEntry::symbolName() const { return SymbolName; }
+
+int64_t MachOAbstractFixupEntry::addend() const { return Addend; }
+
+uint32_t MachOAbstractFixupEntry::flags() const { return Flags; }
+
+int MachOAbstractFixupEntry::ordinal() const { return Ordinal; }
+
+StringRef MachOAbstractFixupEntry::typeName() const { return "unknown"; }
+
+void MachOAbstractFixupEntry::moveToFirst() {
+ SegmentOffset = 0;
+ SegmentIndex = -1;
+ Ordinal = 0;
+ Flags = 0;
+ Addend = 0;
+ Done = false;
+}
+
+void MachOAbstractFixupEntry::moveToEnd() { Done = true; }
+
+MachOChainedFixupEntry::MachOChainedFixupEntry(Error *E,
+ const MachOObjectFile *O,
+ bool Parse)
+ : MachOAbstractFixupEntry(E, O) {
+ ErrorAsOutParameter e(E);
+ if (!Parse)
+ return;
+ if (auto FixupTargetsOrErr = O->getDyldChainedFixupTargets())
+ FixupTargets = *FixupTargetsOrErr;
+ else {
+ *E = FixupTargetsOrErr.takeError();
+ return;
+ }
+}
+
+void MachOChainedFixupEntry::moveToFirst() {
+ MachOAbstractFixupEntry::moveToFirst();
+ FixupIndex = 0;
+ moveNext();
+}
+
+void MachOChainedFixupEntry::moveToEnd() {
+ MachOAbstractFixupEntry::moveToEnd();
+}
+
+void MachOChainedFixupEntry::moveNext() { Done = true; }
+
+bool MachOChainedFixupEntry::operator==(
+ const MachOChainedFixupEntry &Other) const {
+ if (Done == Other.Done)
+ return true;
+ if ((FixupIndex == Other.FixupIndex))
+ return true;
+ return false;
+}
+
MachORebaseEntry::MachORebaseEntry(Error *E, const MachOObjectFile *O,
ArrayRef<uint8_t> Bytes, bool is64Bit)
: E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()),
@@ -4194,6 +4300,16 @@ iterator_range<bind_iterator> MachOObjectFile::weakBindTable(Error &Err) {
MachOBindEntry::Kind::Weak);
}
+iterator_range<fixup_iterator> MachOObjectFile::fixupTable(Error &Err) {
+ MachOChainedFixupEntry Start(&Err, this, true);
+ Start.moveToFirst();
+
+ MachOChainedFixupEntry Finish(&Err, this, false);
+ Finish.moveToEnd();
+
+ return make_range(fixup_iterator(Start), fixup_iterator(Finish));
+}
+
MachOObjectFile::load_command_iterator
MachOObjectFile::begin_load_commands() const {
return LoadCommands.begin();
@@ -4649,6 +4765,72 @@ ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const {
return makeArrayRef(Ptr, DyldInfo.lazy_bind_size);
}
+Expected<Optional<MachO::dyld_chained_fixups_header>>
+MachOObjectFile::getChainedFixupsHeader() const {
+ // Load the dyld chained fixups load command.
+ if (!DyldChainedFixupsLoadCmd)
+ return llvm::None;
+ auto DyldChainedFixupsOrErr = getStructOrErr<MachO::linkedit_data_command>(
+ *this, DyldChainedFixupsLoadCmd);
+ if (!DyldChainedFixupsOrErr)
+ return DyldChainedFixupsOrErr.takeError();
+ MachO::linkedit_data_command DyldChainedFixups = DyldChainedFixupsOrErr.get();
+
+ // If the load command is present but the data offset has been zeroed out,
+ // as is the case for dylib stubs, return None (no error).
+ uint64_t CFHeaderOffset = DyldChainedFixups.dataoff;
+ if (CFHeaderOffset == 0)
+ return DyldChainedFixupsOrErr.takeError();
+
+ // Load the dyld chained fixups header.
+ const char *CFHeaderPtr = getPtr(*this, CFHeaderOffset);
+ auto CFHeaderOrErr =
+ getStructOrErr<MachO::dyld_chained_fixups_header>(*this, CFHeaderPtr);
+ if (!CFHeaderOrErr)
+ return CFHeaderOrErr.takeError();
+ MachO::dyld_chained_fixups_header CFHeader = CFHeaderOrErr.get();
+
+ // Reject unknown chained fixup formats.
+ if (CFHeader.fixups_version != 0)
+ return malformedError(Twine("bad chained fixups: unknown version: ") +
+ Twine(CFHeader.fixups_version));
+ if (CFHeader.imports_format < 1 || CFHeader.imports_format > 3)
+ return malformedError(
+ Twine("bad chained fixups: unknown imports format: ") +
+ Twine(CFHeader.imports_format));
+
+ // Validate the image format.
+ //
+ // Load the image starts.
+ uint64_t CFImageStartsOffset = (CFHeaderOffset + CFHeader.starts_offset);
+ if (CFHeader.starts_offset < sizeof(MachO::dyld_chained_fixups_header)) {
+ return malformedError(Twine("bad chained fixups: image starts offset ") +
+ Twine(CFHeader.starts_offset) +
+ " overlaps with chained fixups header");
+ }
+ uint32_t EndOffset = DyldChainedFixups.dataoff + DyldChainedFixups.datasize;
+ if (CFImageStartsOffset + sizeof(MachO::dyld_chained_starts_in_image) >
+ EndOffset) {
+ return malformedError(Twine("bad chained fixups: image starts end ") +
+ Twine(CFImageStartsOffset +
+ sizeof(MachO::dyld_chained_starts_in_image)) +
+ " extends past end " + Twine(EndOffset));
+ }
+
+ return CFHeader;
+}
+
+Expected<std::vector<ChainedFixupTarget>>
+MachOObjectFile::getDyldChainedFixupTargets() const {
+ auto CFHeaderOrErr = getChainedFixupsHeader();
+ if (!CFHeaderOrErr)
+ return CFHeaderOrErr.takeError();
+ std::vector<ChainedFixupTarget> Targets;
+ if (!(*CFHeaderOrErr))
+ return Targets;
+ return Targets;
+}
+
ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
if (!DyldInfoLoadCmd)
return None;
@@ -4663,6 +4845,21 @@ ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const {
return makeArrayRef(Ptr, DyldInfo.export_size);
}
+SmallVector<uint64_t> MachOObjectFile::getFunctionStarts() const {
+ if (!FuncStartsLoadCmd)
+ return {};
+
+ auto InfoOrErr =
+ getStructOrErr<MachO::linkedit_data_command>(*this, FuncStartsLoadCmd);
+ if (!InfoOrErr)
+ return {};
+
+ MachO::linkedit_data_command Info = InfoOrErr.get();
+ SmallVector<uint64_t, 8> FunctionStarts;
+ this->ReadULEB128s(Info.dataoff, FunctionStarts);
+ return std::move(FunctionStarts);
+}
+
ArrayRef<uint8_t> MachOObjectFile::getUuid() const {
if (!UuidLoadCmd)
return None;
@@ -4778,3 +4975,23 @@ MachOObjectFile::mapReflectionSectionNameToEnumValue(
.Default(llvm::binaryformat::Swift5ReflectionSectionKind::unknown);
#undef HANDLE_SWIFT_SECTION
}
+
+bool MachOObjectFile::isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) {
+ switch (Arch) {
+ case Triple::x86:
+ return RelocType == MachO::GENERIC_RELOC_SECTDIFF ||
+ RelocType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF;
+ case Triple::x86_64:
+ return RelocType == MachO::X86_64_RELOC_SUBTRACTOR;
+ case Triple::arm:
+ case Triple::thumb:
+ return RelocType == MachO::ARM_RELOC_SECTDIFF ||
+ RelocType == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
+ RelocType == MachO::ARM_RELOC_HALF ||
+ RelocType == MachO::ARM_RELOC_HALF_SECTDIFF;
+ case Triple::aarch64:
+ return RelocType == MachO::ARM64_RELOC_SUBTRACTOR;
+ default:
+ return false;
+ }
+}
diff --git a/contrib/llvm-project/llvm/lib/Object/MachOUniversal.cpp b/contrib/llvm-project/llvm/lib/Object/MachOUniversal.cpp
index f3ce005e6ef9..c2c2b67814dc 100644
--- a/contrib/llvm-project/llvm/lib/Object/MachOUniversal.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/MachOUniversal.cpp
@@ -15,9 +15,9 @@
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include "llvm/Support/type_traits.h"
using namespace llvm;
using namespace object;
diff --git a/contrib/llvm-project/llvm/lib/Object/MachOUniversalWriter.cpp b/contrib/llvm-project/llvm/lib/Object/MachOUniversalWriter.cpp
index ae1ff09a4f8f..333706baf8c1 100644
--- a/contrib/llvm-project/llvm/lib/Object/MachOUniversalWriter.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/MachOUniversalWriter.cpp
@@ -12,13 +12,21 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/MachOUniversalWriter.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/Binary.h"
-#include "llvm/Object/Error.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBufferRef.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace object;
@@ -205,7 +213,7 @@ Expected<Slice> Slice::create(const Archive &A, LLVMContext *LLVMCtx) {
.c_str());
if (MFO) {
- Slice ArchiveSlice(*(MFO.get()), MFO->is64Bit() ? 3 : 2);
+ Slice ArchiveSlice(*(MFO), MFO->is64Bit() ? 3 : 2);
ArchiveSlice.B = &A;
return ArchiveSlice;
}
diff --git a/contrib/llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp b/contrib/llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp
index 954d1f09f4e9..11274a7fcc16 100644
--- a/contrib/llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -15,7 +15,6 @@
#include "llvm/Object/ModuleSymbolTable.h"
#include "RecordStreamer.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
@@ -27,7 +26,6 @@
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
@@ -39,7 +37,6 @@
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/CodeGen.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SMLoc.h"
diff --git a/contrib/llvm-project/llvm/lib/Object/Object.cpp b/contrib/llvm-project/llvm/lib/Object/Object.cpp
index 576eb8d069d6..d5e67160dfa3 100644
--- a/contrib/llvm-project/llvm/lib/Object/Object.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/Object.cpp
@@ -120,6 +120,8 @@ LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR) {
return LLVMBinaryTypeMachO64L;
case ID_MachO64B:
return LLVMBinaryTypeMachO64B;
+ case ID_Offload:
+ return LLVMBinaryTypeOffload;
case ID_Wasm:
return LLVMBinaryTypeWasm;
case ID_StartObjects:
diff --git a/contrib/llvm-project/llvm/lib/Object/ObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/ObjectFile.cpp
index 6fd02f3b9592..1be8f11751be 100644
--- a/contrib/llvm-project/llvm/lib/Object/ObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/ObjectFile.cpp
@@ -21,10 +21,9 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
#include <cstdint>
#include <memory>
#include <system_error>
@@ -147,6 +146,9 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
case file_magic::pdb:
case file_magic::minidump:
case file_magic::goff_object:
+ case file_magic::cuda_fatbinary:
+ case file_magic::offload_binary:
+ case file_magic::dxcontainer_object:
return errorCodeToError(object_error::invalid_file_type);
case file_magic::tapi_file:
return errorCodeToError(object_error::invalid_file_type);
@@ -198,3 +200,12 @@ ObjectFile::createObjectFile(StringRef ObjectPath) {
return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer));
}
+
+bool ObjectFile::isReflectionSectionStrippable(
+ llvm::binaryformat::Swift5ReflectionSectionKind ReflectionSectionKind)
+ const {
+ using llvm::binaryformat::Swift5ReflectionSectionKind;
+ return ReflectionSectionKind == Swift5ReflectionSectionKind::fieldmd ||
+ ReflectionSectionKind == Swift5ReflectionSectionKind::reflstr ||
+ ReflectionSectionKind == Swift5ReflectionSectionKind::assocty;
+}
diff --git a/contrib/llvm-project/llvm/lib/Object/OffloadBinary.cpp b/contrib/llvm-project/llvm/lib/Object/OffloadBinary.cpp
new file mode 100644
index 000000000000..21946ec2d6fb
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/Object/OffloadBinary.cpp
@@ -0,0 +1,164 @@
+//===- Offloading.cpp - Utilities for handling offloading code -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/OffloadBinary.h"
+
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/Alignment.h"
+#include "llvm/Support/FileOutputBuffer.h"
+
+using namespace llvm;
+using namespace llvm::object;
+
+Expected<std::unique_ptr<OffloadBinary>>
+OffloadBinary::create(MemoryBufferRef Buf) {
+ if (Buf.getBufferSize() < sizeof(Header) + sizeof(Entry))
+ return errorCodeToError(object_error::parse_failed);
+
+ // Check for 0x10FF1OAD magic bytes.
+ if (identify_magic(Buf.getBuffer()) != file_magic::offload_binary)
+ return errorCodeToError(object_error::parse_failed);
+
+ // Make sure that the data has sufficient alignment.
+ if (!isAddrAligned(Align(getAlignment()), Buf.getBufferStart()))
+ return errorCodeToError(object_error::parse_failed);
+
+ const char *Start = Buf.getBufferStart();
+ const Header *TheHeader = reinterpret_cast<const Header *>(Start);
+ if (TheHeader->Version != OffloadBinary::Version)
+ return errorCodeToError(object_error::parse_failed);
+
+ if (TheHeader->Size > Buf.getBufferSize() ||
+ TheHeader->EntryOffset > TheHeader->Size - sizeof(Entry) ||
+ TheHeader->EntrySize > TheHeader->Size - sizeof(Header))
+ return errorCodeToError(object_error::unexpected_eof);
+
+ const Entry *TheEntry =
+ reinterpret_cast<const Entry *>(&Start[TheHeader->EntryOffset]);
+
+ if (TheEntry->ImageOffset > Buf.getBufferSize() ||
+ TheEntry->StringOffset > Buf.getBufferSize())
+ return errorCodeToError(object_error::unexpected_eof);
+
+ return std::unique_ptr<OffloadBinary>(
+ new OffloadBinary(Buf, TheHeader, TheEntry));
+}
+
+std::unique_ptr<MemoryBuffer>
+OffloadBinary::write(const OffloadingImage &OffloadingData) {
+ // Create a null-terminated string table with all the used strings.
+ StringTableBuilder StrTab(StringTableBuilder::ELF);
+ for (auto &KeyAndValue : OffloadingData.StringData) {
+ StrTab.add(KeyAndValue.getKey());
+ StrTab.add(KeyAndValue.getValue());
+ }
+ StrTab.finalize();
+
+ uint64_t StringEntrySize =
+ sizeof(StringEntry) * OffloadingData.StringData.size();
+
+ // Make sure the image we're wrapping around is aligned as well.
+ uint64_t BinaryDataSize = alignTo(sizeof(Header) + sizeof(Entry) +
+ StringEntrySize + StrTab.getSize(),
+ getAlignment());
+
+ // Create the header and fill in the offsets. The entry will be directly
+ // placed after the header in memory. Align the size to the alignment of the
+ // header so this can be placed contiguously in a single section.
+ Header TheHeader;
+ TheHeader.Size = alignTo(
+ BinaryDataSize + OffloadingData.Image->getBufferSize(), getAlignment());
+ TheHeader.EntryOffset = sizeof(Header);
+ TheHeader.EntrySize = sizeof(Entry);
+
+ // Create the entry using the string table offsets. The string table will be
+ // placed directly after the entry in memory, and the image after that.
+ Entry TheEntry;
+ TheEntry.TheImageKind = OffloadingData.TheImageKind;
+ TheEntry.TheOffloadKind = OffloadingData.TheOffloadKind;
+ TheEntry.Flags = OffloadingData.Flags;
+ TheEntry.StringOffset = sizeof(Header) + sizeof(Entry);
+ TheEntry.NumStrings = OffloadingData.StringData.size();
+
+ TheEntry.ImageOffset = BinaryDataSize;
+ TheEntry.ImageSize = OffloadingData.Image->getBufferSize();
+
+ SmallVector<char> Data;
+ Data.reserve(TheHeader.Size);
+ raw_svector_ostream OS(Data);
+ OS << StringRef(reinterpret_cast<char *>(&TheHeader), sizeof(Header));
+ OS << StringRef(reinterpret_cast<char *>(&TheEntry), sizeof(Entry));
+ for (auto &KeyAndValue : OffloadingData.StringData) {
+ uint64_t Offset = sizeof(Header) + sizeof(Entry) + StringEntrySize;
+ StringEntry Map{Offset + StrTab.getOffset(KeyAndValue.getKey()),
+ Offset + StrTab.getOffset(KeyAndValue.getValue())};
+ OS << StringRef(reinterpret_cast<char *>(&Map), sizeof(StringEntry));
+ }
+ StrTab.write(OS);
+ // Add padding to required image alignment.
+ OS.write_zeros(TheEntry.ImageOffset - OS.tell());
+ OS << OffloadingData.Image->getBuffer();
+
+ // Add final padding to required alignment.
+ assert(TheHeader.Size >= OS.tell() && "Too much data written?");
+ OS.write_zeros(TheHeader.Size - OS.tell());
+ assert(TheHeader.Size == OS.tell() && "Size mismatch");
+
+ return MemoryBuffer::getMemBufferCopy(OS.str());
+}
+
+OffloadKind object::getOffloadKind(StringRef Name) {
+ return llvm::StringSwitch<OffloadKind>(Name)
+ .Case("openmp", OFK_OpenMP)
+ .Case("cuda", OFK_Cuda)
+ .Case("hip", OFK_HIP)
+ .Default(OFK_None);
+}
+
+StringRef object::getOffloadKindName(OffloadKind Kind) {
+ switch (Kind) {
+ case OFK_OpenMP:
+ return "openmp";
+ case OFK_Cuda:
+ return "cuda";
+ case OFK_HIP:
+ return "hip";
+ default:
+ return "none";
+ }
+}
+
+ImageKind object::getImageKind(StringRef Name) {
+ return llvm::StringSwitch<ImageKind>(Name)
+ .Case("o", IMG_Object)
+ .Case("bc", IMG_Bitcode)
+ .Case("cubin", IMG_Cubin)
+ .Case("fatbin", IMG_Fatbinary)
+ .Case("s", IMG_PTX)
+ .Default(IMG_None);
+}
+
+StringRef object::getImageKindName(ImageKind Kind) {
+ switch (Kind) {
+ case IMG_Object:
+ return "o";
+ case IMG_Bitcode:
+ return "bc";
+ case IMG_Cubin:
+ return "cubin";
+ case IMG_Fatbinary:
+ return "fatbin";
+ case IMG_PTX:
+ return "s";
+ default:
+ return "";
+ }
+}
diff --git a/contrib/llvm-project/llvm/lib/Object/RecordStreamer.h b/contrib/llvm-project/llvm/lib/Object/RecordStreamer.h
index 957d80f33bf4..5c6541e5052d 100644
--- a/contrib/llvm-project/llvm/lib/Object/RecordStreamer.h
+++ b/contrib/llvm-project/llvm/lib/Object/RecordStreamer.h
@@ -57,10 +57,10 @@ public:
// Ignore COFF-specific directives; we do not need any information from them,
// but the default implementation of these methods crashes, so we override
// them with versions that do nothing.
- void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {}
- void EmitCOFFSymbolStorageClass(int StorageClass) override {}
- void EmitCOFFSymbolType(int Type) override {}
- void EndCOFFSymbolDef() override {}
+ void beginCOFFSymbolDef(const MCSymbol *Symbol) override {}
+ void emitCOFFSymbolStorageClass(int StorageClass) override {}
+ void emitCOFFSymbolType(int Type) override {}
+ void endCOFFSymbolDef() override {}
/// Record .symver aliases for later processing.
void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name,
diff --git a/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp b/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
index 00a45e2c5d4e..e14301663df3 100644
--- a/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
@@ -11,6 +11,21 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/RelocationResolver.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <vector>
namespace llvm {
namespace object {
@@ -63,6 +78,7 @@ static bool supportsAArch64(uint64_t Type) {
switch (Type) {
case ELF::R_AARCH64_ABS32:
case ELF::R_AARCH64_ABS64:
+ case ELF::R_AARCH64_PREL16:
case ELF::R_AARCH64_PREL32:
case ELF::R_AARCH64_PREL64:
return true;
@@ -78,6 +94,8 @@ static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,
return (S + Addend) & 0xFFFFFFFF;
case ELF::R_AARCH64_ABS64:
return S + Addend;
+ case ELF::R_AARCH64_PREL16:
+ return (S + Addend - Offset) & 0xFFFF;
case ELF::R_AARCH64_PREL32:
return (S + Addend - Offset) & 0xFFFFFFFF;
case ELF::R_AARCH64_PREL64:
@@ -468,6 +486,31 @@ static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S,
}
}
+static bool supportsCSKY(uint64_t Type) {
+ switch (Type) {
+ case ELF::R_CKCORE_NONE:
+ case ELF::R_CKCORE_ADDR32:
+ case ELF::R_CKCORE_PCREL32:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static uint64_t resolveCSKY(uint64_t Type, uint64_t Offset, uint64_t S,
+ uint64_t LocData, int64_t Addend) {
+ switch (Type) {
+ case ELF::R_CKCORE_NONE:
+ return LocData;
+ case ELF::R_CKCORE_ADDR32:
+ return (S + Addend) & 0xFFFFFFFF;
+ case ELF::R_CKCORE_PCREL32:
+ return (S + Addend - Offset) & 0xFFFFFFFF;
+ default:
+ llvm_unreachable("Invalid relocation type");
+ }
+}
+
static bool supportsCOFFX86(uint64_t Type) {
switch (Type) {
case COFF::IMAGE_REL_I386_SECREL:
@@ -715,6 +758,8 @@ getRelocationResolver(const ObjectFile &Obj) {
return {supportsHexagon, resolveHexagon};
case Triple::riscv32:
return {supportsRISCV, resolveRISCV};
+ case Triple::csky:
+ return {supportsCSKY, resolveCSKY};
default:
return {nullptr, nullptr};
}
diff --git a/contrib/llvm-project/llvm/lib/Object/SymbolicFile.cpp b/contrib/llvm-project/llvm/lib/Object/SymbolicFile.cpp
index 58db5b672914..05f47cfbf2ff 100644
--- a/contrib/llvm-project/llvm/lib/Object/SymbolicFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/SymbolicFile.cpp
@@ -17,18 +17,17 @@
#include "llvm/Object/Error.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <algorithm>
#include <memory>
using namespace llvm;
using namespace object;
+namespace llvm {
+class LLVMContext;
+}
+
SymbolicFile::SymbolicFile(unsigned int Type, MemoryBufferRef Source)
: Binary(Type, Source) {}
diff --git a/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp b/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp
index 83568e8d823a..596445a09e85 100644
--- a/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp
@@ -12,8 +12,12 @@
#include "llvm/Object/TapiFile.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Object/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/MemoryBufferRef.h"
+#include "llvm/TextAPI/ArchitectureSet.h"
+#include "llvm/TextAPI/InterfaceFile.h"
+#include "llvm/TextAPI/Platform.h"
#include "llvm/TextAPI/Symbol.h"
using namespace llvm;
diff --git a/contrib/llvm-project/llvm/lib/Object/TapiUniversal.cpp b/contrib/llvm-project/llvm/lib/Object/TapiUniversal.cpp
index d73d93f6bd53..bf96b57f0321 100644
--- a/contrib/llvm-project/llvm/lib/Object/TapiUniversal.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/TapiUniversal.cpp
@@ -13,7 +13,8 @@
#include "llvm/Object/TapiUniversal.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Object/TapiFile.h"
+#include "llvm/TextAPI/ArchitectureSet.h"
#include "llvm/TextAPI/TextAPIReader.h"
using namespace llvm;
@@ -47,7 +48,7 @@ TapiUniversal::~TapiUniversal() = default;
Expected<std::unique_ptr<TapiFile>>
TapiUniversal::ObjectForArch::getAsObjectFile() const {
return std::unique_ptr<TapiFile>(new TapiFile(Parent->getMemoryBufferRef(),
- *Parent->ParsedFile.get(),
+ *Parent->ParsedFile,
Parent->Libraries[Index].Arch));
}
diff --git a/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp
index 6a19b159f3d5..ce816b097691 100644
--- a/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp
@@ -8,7 +8,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
@@ -30,7 +29,6 @@
#include <cassert>
#include <cstdint>
#include <cstring>
-#include <system_error>
#define DEBUG_TYPE "wasm-object"
@@ -166,23 +164,25 @@ static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) {
static Error readInitExpr(wasm::WasmInitExpr &Expr,
WasmObjectFile::ReadContext &Ctx) {
- Expr.Opcode = readOpcode(Ctx);
+ auto Start = Ctx.Ptr;
- switch (Expr.Opcode) {
+ Expr.Extended = false;
+ Expr.Inst.Opcode = readOpcode(Ctx);
+ switch (Expr.Inst.Opcode) {
case wasm::WASM_OPCODE_I32_CONST:
- Expr.Value.Int32 = readVarint32(Ctx);
+ Expr.Inst.Value.Int32 = readVarint32(Ctx);
break;
case wasm::WASM_OPCODE_I64_CONST:
- Expr.Value.Int64 = readVarint64(Ctx);
+ Expr.Inst.Value.Int64 = readVarint64(Ctx);
break;
case wasm::WASM_OPCODE_F32_CONST:
- Expr.Value.Float32 = readFloat32(Ctx);
+ Expr.Inst.Value.Float32 = readFloat32(Ctx);
break;
case wasm::WASM_OPCODE_F64_CONST:
- Expr.Value.Float64 = readFloat64(Ctx);
+ Expr.Inst.Value.Float64 = readFloat64(Ctx);
break;
case wasm::WASM_OPCODE_GLOBAL_GET:
- Expr.Value.Global = readULEB128(Ctx);
+ Expr.Inst.Value.Global = readULEB128(Ctx);
break;
case wasm::WASM_OPCODE_REF_NULL: {
wasm::ValType Ty = static_cast<wasm::ValType>(readULEB128(Ctx));
@@ -193,15 +193,46 @@ static Error readInitExpr(wasm::WasmInitExpr &Expr,
break;
}
default:
- return make_error<GenericBinaryError>("invalid opcode in init_expr",
- object_error::parse_failed);
+ Expr.Extended = true;
}
- uint8_t EndOpcode = readOpcode(Ctx);
- if (EndOpcode != wasm::WASM_OPCODE_END) {
- return make_error<GenericBinaryError>("invalid init_expr",
- object_error::parse_failed);
+ if (!Expr.Extended) {
+ uint8_t EndOpcode = readOpcode(Ctx);
+ if (EndOpcode != wasm::WASM_OPCODE_END)
+ Expr.Extended = true;
+ }
+
+ if (Expr.Extended) {
+ Ctx.Ptr = Start;
+ while (1) {
+ uint8_t Opcode = readOpcode(Ctx);
+ switch (Opcode) {
+ case wasm::WASM_OPCODE_I32_CONST:
+ case wasm::WASM_OPCODE_GLOBAL_GET:
+ case wasm::WASM_OPCODE_REF_NULL:
+ case wasm::WASM_OPCODE_I64_CONST:
+ case wasm::WASM_OPCODE_F32_CONST:
+ case wasm::WASM_OPCODE_F64_CONST:
+ readULEB128(Ctx);
+ break;
+ case wasm::WASM_OPCODE_I32_ADD:
+ case wasm::WASM_OPCODE_I32_SUB:
+ case wasm::WASM_OPCODE_I32_MUL:
+ case wasm::WASM_OPCODE_I64_ADD:
+ case wasm::WASM_OPCODE_I64_SUB:
+ case wasm::WASM_OPCODE_I64_MUL:
+ break;
+ case wasm::WASM_OPCODE_END:
+ Expr.Body = ArrayRef<uint8_t>(Start, Ctx.Ptr - Start);
+ return Error::success();
+ default:
+ return make_error<GenericBinaryError>(
+ Twine("invalid opcode in init_expr: ") + Twine(unsigned(Opcode)),
+ object_error::parse_failed);
+ }
+ }
}
+
return Error::success();
}
@@ -420,10 +451,6 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
llvm::DenseSet<uint64_t> SeenFunctions;
llvm::DenseSet<uint64_t> SeenGlobals;
llvm::DenseSet<uint64_t> SeenSegments;
- if (Functions.size() && !SeenCodeSection) {
- return make_error<GenericBinaryError>("names must come after code section",
- object_error::parse_failed);
- }
while (Ctx.Ptr < Ctx.End) {
uint8_t Type = readUint8(Ctx);
@@ -443,7 +470,7 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
return make_error<GenericBinaryError>(
"function named more than once", object_error::parse_failed);
if (!isValidFunctionIndex(Index) || Name.empty())
- return make_error<GenericBinaryError>("invalid name entry",
+ return make_error<GenericBinaryError>("invalid function name entry",
object_error::parse_failed);
if (isDefinedFunctionIndex(Index))
@@ -454,7 +481,7 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
return make_error<GenericBinaryError>("global named more than once",
object_error::parse_failed);
if (!isValidGlobalIndex(Index) || Name.empty())
- return make_error<GenericBinaryError>("invalid name entry",
+ return make_error<GenericBinaryError>("invalid global name entry",
object_error::parse_failed);
} else {
nameType = wasm::NameType::DATA_SEGMENT;
@@ -462,7 +489,7 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
return make_error<GenericBinaryError>(
"segment named more than once", object_error::parse_failed);
if (Index > DataSegments.size())
- return make_error<GenericBinaryError>("invalid named data segment",
+ return make_error<GenericBinaryError>("invalid data segment name entry",
object_error::parse_failed);
}
DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
@@ -488,11 +515,6 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
HasLinkingSection = true;
- if (Functions.size() && !SeenCodeSection) {
- return make_error<GenericBinaryError>(
- "linking data must come after code section",
- object_error::parse_failed);
- }
LinkingData.Version = readVaruint32(Ctx);
if (LinkingData.Version != wasm::WasmMetadataVersion) {
@@ -1379,7 +1401,6 @@ Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
}
Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
- SeenCodeSection = true;
CodeSection = Sections.size();
uint32_t FunctionCount = readVaruint32(Ctx);
if (FunctionCount != Functions.size()) {
@@ -1443,8 +1464,9 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
object_error::parse_failed);
if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_IS_PASSIVE) {
- Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST;
- Segment.Offset.Value.Int32 = 0;
+ Segment.Offset.Extended = false;
+ Segment.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST;
+ Segment.Offset.Inst.Value.Int32 = 0;
} else {
if (Error Err = readInitExpr(Segment.Offset, Ctx))
return Err;
@@ -1488,7 +1510,7 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
DataSection = Sections.size();
uint32_t Count = readVaruint32(Ctx);
- if (DataCount && Count != DataCount.getValue())
+ if (DataCount && Count != *DataCount)
return make_error<GenericBinaryError>(
"number of data segments does not match DataCount section");
DataSegments.reserve(Count);
@@ -1503,8 +1525,9 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
if (Error Err = readInitExpr(Segment.Data.Offset, Ctx))
return Err;
} else {
- Segment.Data.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST;
- Segment.Data.Offset.Value.Int32 = 0;
+ Segment.Data.Offset.Extended = false;
+ Segment.Data.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST;
+ Segment.Data.Offset.Inst.Value.Int32 = 0;
}
uint32_t Size = readVaruint32(Ctx);
if (Size > (size_t)(Ctx.End - Ctx.Ptr))
@@ -1602,10 +1625,12 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const {
// offset within the segment.
uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
- if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST) {
- return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
- } else if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I64_CONST) {
- return Segment.Offset.Value.Int64 + Sym.Info.DataRef.Offset;
+ if (Segment.Offset.Extended) {
+ llvm_unreachable("extended init exprs not supported");
+ } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I32_CONST) {
+ return Segment.Offset.Inst.Value.Int32 + Sym.Info.DataRef.Offset;
+ } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I64_CONST) {
+ return Segment.Offset.Inst.Value.Int64 + Sym.Info.DataRef.Offset;
} else {
llvm_unreachable("unknown init expr opcode");
}
@@ -1692,29 +1717,11 @@ void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
Expected<StringRef> WasmObjectFile::getSectionName(DataRefImpl Sec) const {
const WasmSection &S = Sections[Sec.d.a];
-#define ECase(X) \
- case wasm::WASM_SEC_##X: \
- return #X;
- switch (S.Type) {
- ECase(TYPE);
- ECase(IMPORT);
- ECase(FUNCTION);
- ECase(TABLE);
- ECase(MEMORY);
- ECase(GLOBAL);
- ECase(TAG);
- ECase(EXPORT);
- ECase(START);
- ECase(ELEM);
- ECase(CODE);
- ECase(DATA);
- ECase(DATACOUNT);
- case wasm::WASM_SEC_CUSTOM:
+ if (S.Type == wasm::WASM_SEC_CUSTOM)
return S.Name;
- default:
+ if (S.Type > wasm::WASM_SEC_LAST_KNOWN)
return createStringError(object_error::invalid_section_index, "");
- }
-#undef ECase
+ return wasm::sectionTypeToString(S.Type);
}
uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; }
diff --git a/contrib/llvm-project/llvm/lib/Object/WindowsResource.cpp b/contrib/llvm-project/llvm/lib/Object/WindowsResource.cpp
index 2a69c6c46b59..d50f149629c3 100644
--- a/contrib/llvm-project/llvm/lib/Object/WindowsResource.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/WindowsResource.cpp
@@ -12,13 +12,11 @@
#include "llvm/Object/WindowsResource.h"
#include "llvm/Object/COFF.h"
-#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ScopedPrinter.h"
#include <ctime>
#include <queue>
-#include <system_error>
using namespace llvm;
using namespace object;
diff --git a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
index f2f6d700ddd8..ff39fe1794c0 100644
--- a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -615,6 +615,16 @@ Expected<uint32_t> XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
if (XCOFFSym.getSectionNumber() == XCOFF::N_UNDEF)
Result |= SymbolRef::SF_Undefined;
+ // There is no visibility in old 32 bit XCOFF object file interpret.
+ if (is64Bit() || (auxiliaryHeader32() && (auxiliaryHeader32()->getVersion() ==
+ NEW_XCOFF_INTERPRET))) {
+ uint16_t SymType = XCOFFSym.getSymbolType();
+ if ((SymType & VISIBILITY_MASK) == SYM_V_HIDDEN)
+ Result |= SymbolRef::SF_Hidden;
+
+ if ((SymType & VISIBILITY_MASK) == SYM_V_EXPORTED)
+ Result |= SymbolRef::SF_Exported;
+ }
return Result;
}
@@ -699,6 +709,19 @@ bool XCOFFObjectFile::is64Bit() const {
return Binary::ID_XCOFF64 == getType();
}
+Expected<StringRef> XCOFFObjectFile::getRawData(const char *Start,
+ uint64_t Size,
+ StringRef Name) const {
+ uintptr_t StartPtr = reinterpret_cast<uintptr_t>(Start);
+ // TODO: this path is untested.
+ if (Error E = Binary::checkOffset(Data, StartPtr, Size))
+ return createError(toString(std::move(E)) + ": " + Name.data() +
+ " data with offset 0x" + Twine::utohexstr(StartPtr) +
+ " and size 0x" + Twine::utohexstr(Size) +
+ " goes past the end of the file");
+ return StringRef(Start, Size);
+}
+
uint16_t XCOFFObjectFile::getMagic() const {
return is64Bit() ? fileHeader64()->Magic : fileHeader32()->Magic;
}
@@ -1319,7 +1342,7 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
NumOfCtlAnchors = DE.getU32(Cur);
if (Cur && NumOfCtlAnchors) {
SmallVector<uint32_t, 8> Disp;
- Disp.reserve(NumOfCtlAnchors.getValue());
+ Disp.reserve(*NumOfCtlAnchors);
for (uint32_t I = 0; I < NumOfCtlAnchors && Cur; ++I)
Disp.push_back(DE.getU32(Cur));
if (Cur)
@@ -1346,7 +1369,7 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
return;
}
VecExt = TBVecExtOrErr.get();
- VectorParmsNum = VecExt.getValue().getNumberOfVectorParms();
+ VectorParmsNum = VecExt->getNumberOfVectorParms();
}
}