aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Object
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-08-22 19:00:43 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-11-13 20:39:49 +0000
commitfe6060f10f634930ff71b7c50291ddc610da2475 (patch)
tree1483580c790bd4d27b6500a7542b5ee00534d3cc /contrib/llvm-project/llvm/lib/Object
parentb61bce17f346d79cecfd8f195a64b10f77be43b1 (diff)
parent344a3780b2e33f6ca763666c380202b18aab72a3 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object')
-rw-r--r--contrib/llvm-project/llvm/lib/Object/Archive.cpp147
-rw-r--r--contrib/llvm-project/llvm/lib/Object/Binary.cpp3
-rw-r--r--contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp9
-rw-r--r--contrib/llvm-project/llvm/lib/Object/ELF.cpp117
-rw-r--r--contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp9
-rw-r--r--contrib/llvm-project/llvm/lib/Object/FaultMapParser.cpp66
-rw-r--r--contrib/llvm-project/llvm/lib/Object/IRSymtab.cpp34
-rw-r--r--contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp12
-rw-r--r--contrib/llvm-project/llvm/lib/Object/MachOUniversalWriter.cpp15
-rw-r--r--contrib/llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp16
-rw-r--r--contrib/llvm-project/llvm/lib/Object/ObjectFile.cpp5
-rw-r--r--contrib/llvm-project/llvm/lib/Object/RecordStreamer.cpp7
-rw-r--r--contrib/llvm-project/llvm/lib/Object/RecordStreamer.h4
-rw-r--r--contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp32
-rw-r--r--contrib/llvm-project/llvm/lib/Object/SymbolSize.cpp6
-rw-r--r--contrib/llvm-project/llvm/lib/Object/SymbolicFile.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/Object/TapiFile.cpp7
-rw-r--r--contrib/llvm-project/llvm/lib/Object/TapiUniversal.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp208
-rw-r--r--contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp418
20 files changed, 680 insertions, 439 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/Archive.cpp b/contrib/llvm-project/llvm/lib/Object/Archive.cpp
index 11c9de4455dd..6ff896cf347e 100644
--- a/contrib/llvm-project/llvm/lib/Object/Archive.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/Archive.cpp
@@ -43,8 +43,7 @@ const char ThinMagic[] = "!<thin>\n";
void Archive::anchor() {}
-static Error
-malformedError(Twine Msg) {
+static Error malformedError(Twine Msg) {
std::string StringMsg = "truncated or malformed archive (" + Msg.str() + ")";
return make_error<GenericBinaryError>(std::move(StringMsg),
object_error::parse_failed);
@@ -77,8 +76,8 @@ ArchiveMemberHeader::ArchiveMemberHeader(const Archive *Parent,
if (Err) {
std::string Buf;
raw_string_ostream OS(Buf);
- OS.write_escaped(StringRef(ArMemHdr->Terminator,
- sizeof(ArMemHdr->Terminator)));
+ OS.write_escaped(
+ StringRef(ArMemHdr->Terminator, sizeof(ArMemHdr->Terminator)));
OS.flush();
std::string Msg("terminator characters in archive member \"" + Buf +
"\" not the correct \"`\\n\" values for the archive "
@@ -102,14 +101,14 @@ Expected<StringRef> ArchiveMemberHeader::getRawName() const {
auto Kind = Parent->kind();
if (Kind == Archive::K_BSD || Kind == Archive::K_DARWIN64) {
if (ArMemHdr->Name[0] == ' ') {
- uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
+ uint64_t Offset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
return malformedError("name contains a leading space for archive member "
- "header at offset " + Twine(Offset));
+ "header at offset " +
+ Twine(Offset));
}
EndCond = ' ';
- }
- else if (ArMemHdr->Name[0] == '/' || ArMemHdr->Name[0] == '#')
+ } else if (ArMemHdr->Name[0] == '/' || ArMemHdr->Name[0] == '#')
EndCond = ' ';
else
EndCond = '/';
@@ -131,8 +130,8 @@ Expected<StringRef> ArchiveMemberHeader::getName(uint64_t Size) const {
// archive header is truncated to produce an error message with the name.
// Make sure the name field is not truncated.
if (Size < offsetof(ArMemHdrType, Name) + sizeof(ArMemHdr->Name)) {
- uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
+ uint64_t ArchiveOffset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
return malformedError("archive header truncated before the name field "
"for archive member header at offset " +
Twine(ArchiveOffset));
@@ -158,21 +157,22 @@ Expected<StringRef> ArchiveMemberHeader::getName(uint64_t Size) const {
raw_string_ostream OS(Buf);
OS.write_escaped(Name.substr(1).rtrim(' '));
OS.flush();
- uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
+ uint64_t ArchiveOffset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
return malformedError("long name offset characters after the '/' are "
- "not all decimal numbers: '" + Buf + "' for "
- "archive member header at offset " +
+ "not all decimal numbers: '" +
+ Buf + "' for archive member header at offset " +
Twine(ArchiveOffset));
}
// Verify it.
if (StringOffset >= Parent->getStringTable().size()) {
- uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
- return malformedError("long name offset " + Twine(StringOffset) + " past "
- "the end of the string table for archive member "
- "header at offset " + Twine(ArchiveOffset));
+ uint64_t ArchiveOffset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
+ return malformedError("long name offset " + Twine(StringOffset) +
+ " past the end of the string table for archive "
+ "member header at offset " +
+ Twine(ArchiveOffset));
}
// GNU long file names end with a "/\n".
@@ -196,23 +196,24 @@ Expected<StringRef> ArchiveMemberHeader::getName(uint64_t Size) const {
raw_string_ostream OS(Buf);
OS.write_escaped(Name.substr(3).rtrim(' '));
OS.flush();
- uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
+ uint64_t ArchiveOffset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
return malformedError("long name length characters after the #1/ are "
- "not all decimal numbers: '" + Buf + "' for "
- "archive member header at offset " +
+ "not all decimal numbers: '" +
+ Buf + "' for archive member header at offset " +
Twine(ArchiveOffset));
}
if (getSizeOf() + NameLength > Size) {
- uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
+ uint64_t ArchiveOffset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
return malformedError("long name length: " + Twine(NameLength) +
" extends past the end of the member or archive "
"for archive member header at offset " +
Twine(ArchiveOffset));
}
return StringRef(reinterpret_cast<const char *>(ArMemHdr) + getSizeOf(),
- NameLength).rtrim('\0');
+ NameLength)
+ .rtrim('\0');
}
// It is not a long name so trim the blanks at the end of the name.
@@ -225,36 +226,43 @@ Expected<StringRef> ArchiveMemberHeader::getName(uint64_t Size) const {
Expected<uint64_t> ArchiveMemberHeader::getSize() const {
uint64_t Ret;
- if (StringRef(ArMemHdr->Size,
- sizeof(ArMemHdr->Size)).rtrim(" ").getAsInteger(10, Ret)) {
+ if (StringRef(ArMemHdr->Size, sizeof(ArMemHdr->Size))
+ .rtrim(" ")
+ .getAsInteger(10, Ret)) {
std::string Buf;
raw_string_ostream OS(Buf);
- OS.write_escaped(StringRef(ArMemHdr->Size,
- sizeof(ArMemHdr->Size)).rtrim(" "));
+ OS.write_escaped(
+ StringRef(ArMemHdr->Size, sizeof(ArMemHdr->Size)).rtrim(" "));
OS.flush();
- uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
+ uint64_t Offset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
return malformedError("characters in size field in archive header are not "
- "all decimal numbers: '" + Buf + "' for archive "
- "member header at offset " + Twine(Offset));
+ "all decimal numbers: '" +
+ Buf +
+ "' for archive "
+ "member header at offset " +
+ Twine(Offset));
}
return Ret;
}
Expected<sys::fs::perms> ArchiveMemberHeader::getAccessMode() const {
unsigned Ret;
- if (StringRef(ArMemHdr->AccessMode,
- sizeof(ArMemHdr->AccessMode)).rtrim(' ').getAsInteger(8, Ret)) {
+ if (StringRef(ArMemHdr->AccessMode, sizeof(ArMemHdr->AccessMode))
+ .rtrim(' ')
+ .getAsInteger(8, Ret)) {
std::string Buf;
raw_string_ostream OS(Buf);
- OS.write_escaped(StringRef(ArMemHdr->AccessMode,
- sizeof(ArMemHdr->AccessMode)).rtrim(" "));
+ OS.write_escaped(
+ StringRef(ArMemHdr->AccessMode, sizeof(ArMemHdr->AccessMode))
+ .rtrim(" "));
OS.flush();
- uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
+ uint64_t Offset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
return malformedError("characters in AccessMode field in archive header "
- "are not all decimal numbers: '" + Buf + "' for the "
- "archive member header at offset " + Twine(Offset));
+ "are not all decimal numbers: '" +
+ Buf + "' for the archive member header at offset " +
+ Twine(Offset));
}
return static_cast<sys::fs::perms>(Ret);
}
@@ -262,19 +270,21 @@ Expected<sys::fs::perms> ArchiveMemberHeader::getAccessMode() const {
Expected<sys::TimePoint<std::chrono::seconds>>
ArchiveMemberHeader::getLastModified() const {
unsigned Seconds;
- if (StringRef(ArMemHdr->LastModified,
- sizeof(ArMemHdr->LastModified)).rtrim(' ')
+ if (StringRef(ArMemHdr->LastModified, sizeof(ArMemHdr->LastModified))
+ .rtrim(' ')
.getAsInteger(10, Seconds)) {
std::string Buf;
raw_string_ostream OS(Buf);
- OS.write_escaped(StringRef(ArMemHdr->LastModified,
- sizeof(ArMemHdr->LastModified)).rtrim(" "));
+ OS.write_escaped(
+ StringRef(ArMemHdr->LastModified, sizeof(ArMemHdr->LastModified))
+ .rtrim(" "));
OS.flush();
- uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
+ uint64_t Offset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
return malformedError("characters in LastModified field in archive header "
- "are not all decimal numbers: '" + Buf + "' for the "
- "archive member header at offset " + Twine(Offset));
+ "are not all decimal numbers: '" +
+ Buf + "' for the archive member header at offset " +
+ Twine(Offset));
}
return sys::toTimePoint(Seconds);
@@ -290,11 +300,12 @@ Expected<unsigned> ArchiveMemberHeader::getUID() const {
raw_string_ostream OS(Buf);
OS.write_escaped(User);
OS.flush();
- uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
+ uint64_t Offset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
return malformedError("characters in UID field in archive header "
- "are not all decimal numbers: '" + Buf + "' for the "
- "archive member header at offset " + Twine(Offset));
+ "are not all decimal numbers: '" +
+ Buf + "' for the archive member header at offset " +
+ Twine(Offset));
}
return Ret;
}
@@ -309,11 +320,12 @@ Expected<unsigned> ArchiveMemberHeader::getGID() const {
raw_string_ostream OS(Buf);
OS.write_escaped(Group);
OS.flush();
- uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
- Parent->getData().data();
+ uint64_t Offset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
return malformedError("characters in GID field in archive header "
- "are not all decimal numbers: '" + Buf + "' for the "
- "archive member header at offset " + Twine(Offset));
+ "are not all decimal numbers: '" +
+ Buf + "' for the archive member header at offset " +
+ Twine(Offset));
}
return Ret;
}
@@ -321,15 +333,15 @@ Expected<unsigned> ArchiveMemberHeader::getGID() const {
Archive::Child::Child(const Archive *Parent, StringRef Data,
uint16_t StartOfFile)
: Parent(Parent), Header(Parent, Data.data(), Data.size(), nullptr),
- Data(Data), StartOfFile(StartOfFile) {
-}
+ Data(Data), StartOfFile(StartOfFile) {}
Archive::Child::Child(const Archive *Parent, const char *Start, Error *Err)
: Parent(Parent),
Header(Parent, Start,
Parent
- ? Parent->getData().size() - (Start - Parent->getData().data())
- : 0, Err) {
+ ? Parent->getData().size() - (Start - Parent->getData().data())
+ : 0,
+ Err) {
if (!Start)
return;
@@ -368,7 +380,7 @@ Archive::Child::Child(const Archive *Parent, const char *Start, Error *Err)
StartOfFile = Header.getSizeOf();
// Don't include attached name.
Expected<StringRef> NameOrErr = getRawName();
- if (!NameOrErr){
+ if (!NameOrErr) {
*Err = NameOrErr.takeError();
return;
}
@@ -382,8 +394,8 @@ Archive::Child::Child(const Archive *Parent, const char *Start, Error *Err)
OS.flush();
uint64_t Offset = Start - Parent->getData().data();
*Err = malformedError("long name length characters after the #1/ are "
- "not all decimal numbers: '" + Buf + "' for "
- "archive member header at offset " +
+ "not all decimal numbers: '" +
+ Buf + "' for archive member header at offset " +
Twine(Offset));
return;
}
@@ -646,8 +658,7 @@ Archive::Archive(MemoryBufferRef Source, Error &Err)
SymbolTable = BufOrErr.get();
if (Increment())
return;
- }
- else if (Name == "__.SYMDEF_64 SORTED" || Name == "__.SYMDEF_64") {
+ } else if (Name == "__.SYMDEF_64 SORTED" || Name == "__.SYMDEF_64") {
Format = K_DARWIN64;
// We know that the symbol table is not an external file, but we still
// must check any Expected<> return value.
diff --git a/contrib/llvm-project/llvm/lib/Object/Binary.cpp b/contrib/llvm-project/llvm/lib/Object/Binary.cpp
index e741cbba2882..143554344256 100644
--- a/contrib/llvm-project/llvm/lib/Object/Binary.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/Binary.cpp
@@ -56,6 +56,7 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
case file_magic::elf_executable:
case file_magic::elf_shared_object:
case file_magic::elf_core:
+ case file_magic::goff_object:
case file_magic::macho_object:
case file_magic::macho_executable:
case file_magic::macho_fixed_virtual_memory_shared_lib:
@@ -97,7 +98,7 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
Expected<OwningBinary<Binary>>
object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
- MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1,
+ MemoryBuffer::getFileOrSTDIN(Path, /*IsText=*/false,
/*RequiresNullTerminator=*/false);
if (std::error_code EC = FileOrErr.getError())
return errorCodeToError(EC);
diff --git a/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
index 6e9a8eb35dcf..354b3c0d5577 100644
--- a/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
@@ -328,7 +328,14 @@ bool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const {
// The .debug sections are the only debug sections for COFF
// (\see MCObjectFileInfo.cpp).
-bool COFFObjectFile::isDebugSection(StringRef SectionName) const {
+bool COFFObjectFile::isDebugSection(DataRefImpl Ref) const {
+ Expected<StringRef> SectionNameOrErr = getSectionName(Ref);
+ if (!SectionNameOrErr) {
+ // TODO: Report the error message properly.
+ consumeError(SectionNameOrErr.takeError());
+ return false;
+ }
+ StringRef SectionName = SectionNameOrErr.get();
return SectionName.startswith(".debug");
}
diff --git a/contrib/llvm-project/llvm/lib/Object/ELF.cpp b/contrib/llvm-project/llvm/lib/Object/ELF.cpp
index 264f115ddbb5..ca2ed4449120 100644
--- a/contrib/llvm-project/llvm/lib/Object/ELF.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/ELF.cpp
@@ -8,7 +8,7 @@
#include "llvm/Object/ELF.h"
#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/Support/LEB128.h"
+#include "llvm/Support/DataExtractor.h"
using namespace llvm;
using namespace object;
@@ -22,6 +22,13 @@ using namespace object;
StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
uint32_t Type) {
switch (Machine) {
+ case ELF::EM_68K:
+ switch (Type) {
+#include "llvm/BinaryFormat/ELFRelocs/M68k.def"
+ default:
+ break;
+ }
+ break;
case ELF::EM_X86_64:
switch (Type) {
#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
@@ -373,39 +380,31 @@ ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {
Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
if (!ContentsOrErr)
return ContentsOrErr.takeError();
- const uint8_t *Cur = ContentsOrErr->begin();
- const uint8_t *End = ContentsOrErr->end();
- if (ContentsOrErr->size() < 4 || Cur[0] != 'A' || Cur[1] != 'P' ||
- Cur[2] != 'S' || Cur[3] != '2')
+ ArrayRef<uint8_t> Content = *ContentsOrErr;
+ if (Content.size() < 4 || Content[0] != 'A' || Content[1] != 'P' ||
+ Content[2] != 'S' || Content[3] != '2')
return createError("invalid packed relocation header");
- Cur += 4;
-
- const char *ErrStr = nullptr;
- auto ReadSLEB = [&]() -> int64_t {
- if (ErrStr)
- return 0;
- unsigned Len;
- int64_t Result = decodeSLEB128(Cur, &Len, End, &ErrStr);
- Cur += Len;
- return Result;
- };
+ DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4);
+ DataExtractor::Cursor Cur(/*Offset=*/4);
- uint64_t NumRelocs = ReadSLEB();
- uint64_t Offset = ReadSLEB();
+ uint64_t NumRelocs = Data.getSLEB128(Cur);
+ uint64_t Offset = Data.getSLEB128(Cur);
uint64_t Addend = 0;
- if (ErrStr)
- return createError(ErrStr);
+ if (!Cur)
+ return std::move(Cur.takeError());
std::vector<Elf_Rela> Relocs;
Relocs.reserve(NumRelocs);
while (NumRelocs) {
- uint64_t NumRelocsInGroup = ReadSLEB();
+ uint64_t NumRelocsInGroup = Data.getSLEB128(Cur);
+ if (!Cur)
+ return std::move(Cur.takeError());
if (NumRelocsInGroup > NumRelocs)
return createError("relocation group unexpectedly large");
NumRelocs -= NumRelocsInGroup;
- uint64_t GroupFlags = ReadSLEB();
+ uint64_t GroupFlags = Data.getSLEB128(Cur);
bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
@@ -413,34 +412,30 @@ ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {
uint64_t GroupOffsetDelta;
if (GroupedByOffsetDelta)
- GroupOffsetDelta = ReadSLEB();
+ GroupOffsetDelta = Data.getSLEB128(Cur);
uint64_t GroupRInfo;
if (GroupedByInfo)
- GroupRInfo = ReadSLEB();
+ GroupRInfo = Data.getSLEB128(Cur);
if (GroupedByAddend && GroupHasAddend)
- Addend += ReadSLEB();
+ Addend += Data.getSLEB128(Cur);
if (!GroupHasAddend)
Addend = 0;
- for (uint64_t I = 0; I != NumRelocsInGroup; ++I) {
+ for (uint64_t I = 0; Cur && I != NumRelocsInGroup; ++I) {
Elf_Rela R;
- Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB();
+ Offset += GroupedByOffsetDelta ? GroupOffsetDelta : Data.getSLEB128(Cur);
R.r_offset = Offset;
- R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB();
+ R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(Cur);
if (GroupHasAddend && !GroupedByAddend)
- Addend += ReadSLEB();
+ Addend += Data.getSLEB128(Cur);
R.r_addend = Addend;
Relocs.push_back(R);
-
- if (ErrStr)
- return createError(ErrStr);
}
-
- if (ErrStr)
- return createError(ErrStr);
+ if (!Cur)
+ return std::move(Cur.takeError());
}
return Relocs;
@@ -617,6 +612,58 @@ ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const {
return base() + Offset;
}
+template <class ELFT>
+Expected<std::vector<typename ELFT::BBAddrMap>>
+ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec) const {
+ Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
+ if (!ContentsOrErr)
+ return ContentsOrErr.takeError();
+ ArrayRef<uint8_t> Content = *ContentsOrErr;
+ DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4);
+ std::vector<Elf_BBAddrMap> FunctionEntries;
+
+ 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.
+ // Also returns zero if ULEBSizeErr is already in an error state.
+ auto ReadULEB128AsUInt32 = [&Data, &Cur, &ULEBSizeErr]() -> uint32_t {
+ // Bail out and do not extract data if ULEBSizeErr is already set.
+ if (ULEBSizeErr)
+ return 0;
+ uint64_t Offset = Cur.tell();
+ uint64_t Value = Data.getULEB128(Cur);
+ if (Value > UINT32_MAX) {
+ ULEBSizeErr = createError(
+ "ULEB128 value at offset 0x" + Twine::utohexstr(Offset) +
+ " exceeds UINT32_MAX (0x" + Twine::utohexstr(Value) + ")");
+ return 0;
+ }
+ return static_cast<uint32_t>(Value);
+ };
+
+ while (!ULEBSizeErr && Cur && Cur.tell() < Content.size()) {
+ uintX_t Address = static_cast<uintX_t>(Data.getAddress(Cur));
+ uint32_t NumBlocks = ReadULEB128AsUInt32();
+ std::vector<typename Elf_BBAddrMap::BBEntry> BBEntries;
+ for (uint32_t BlockID = 0; !ULEBSizeErr && Cur && (BlockID < NumBlocks);
+ ++BlockID) {
+ uint32_t Offset = ReadULEB128AsUInt32();
+ uint32_t Size = ReadULEB128AsUInt32();
+ uint32_t Metadata = ReadULEB128AsUInt32();
+ BBEntries.push_back({Offset, Size, Metadata});
+ }
+ FunctionEntries.push_back({Address, BBEntries});
+ }
+ // Either Cur is in the error state, or ULEBSizeError is set (not both), but
+ // we join the two errors here to be safe.
+ if (!Cur || ULEBSizeErr)
+ return joinErrors(Cur.takeError(), std::move(ULEBSizeErr));
+ return FunctionEntries;
+}
+
template class llvm::object::ELFFile<ELF32LE>;
template class llvm::object::ELFFile<ELF32BE>;
template class llvm::object::ELFFile<ELF64LE>;
diff --git a/contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp
index 91871a6255dc..6613d79ab3d0 100644
--- a/contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/ELFObjectFile.cpp
@@ -457,6 +457,8 @@ StringRef ELFObjectFileBase::getAMDGPUCPUName() const {
return "gfx908";
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909:
return "gfx909";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90A:
+ return "gfx90a";
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C:
return "gfx90c";
@@ -467,6 +469,8 @@ StringRef ELFObjectFileBase::getAMDGPUCPUName() const {
return "gfx1011";
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012:
return "gfx1012";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1013:
+ return "gfx1013";
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030:
return "gfx1030";
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031:
@@ -475,6 +479,10 @@ StringRef ELFObjectFileBase::getAMDGPUCPUName() const {
return "gfx1032";
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033:
return "gfx1033";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1034:
+ return "gfx1034";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1035:
+ return "gfx1035";
default:
llvm_unreachable("Unknown EF_AMDGPU_MACH value");
}
@@ -581,6 +589,7 @@ ELFObjectFileBase::getPltAddresses() const {
JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT;
break;
case Triple::aarch64:
+ case Triple::aarch64_be:
JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;
break;
default:
diff --git a/contrib/llvm-project/llvm/lib/Object/FaultMapParser.cpp b/contrib/llvm-project/llvm/lib/Object/FaultMapParser.cpp
new file mode 100644
index 000000000000..9e83bc1de79d
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/Object/FaultMapParser.cpp
@@ -0,0 +1,66 @@
+//===----------------------- FaultMapParser.cpp ---------------------------===//
+//
+// 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/FaultMapParser.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+void printFaultType(FaultMapParser::FaultKind FT, raw_ostream &OS) {
+ switch (FT) {
+ default:
+ llvm_unreachable("unhandled fault type!");
+ case FaultMapParser::FaultingLoad:
+ OS << "FaultingLoad";
+ break;
+ case FaultMapParser::FaultingLoadStore:
+ OS << "FaultingLoadStore";
+ break;
+ case FaultMapParser::FaultingStore:
+ OS << "FaultingStore";
+ break;
+ }
+}
+
+raw_ostream &
+llvm::operator<<(raw_ostream &OS,
+ const FaultMapParser::FunctionFaultInfoAccessor &FFI) {
+ OS << "Fault kind: ";
+ printFaultType((FaultMapParser::FaultKind)FFI.getFaultKind(), OS);
+ OS << ", faulting PC offset: " << FFI.getFaultingPCOffset()
+ << ", handling PC offset: " << FFI.getHandlerPCOffset();
+ return OS;
+}
+
+raw_ostream &llvm::operator<<(raw_ostream &OS,
+ const FaultMapParser::FunctionInfoAccessor &FI) {
+ OS << "FunctionAddress: " << format_hex(FI.getFunctionAddr(), 8)
+ << ", NumFaultingPCs: " << FI.getNumFaultingPCs() << "\n";
+ for (unsigned I = 0, E = FI.getNumFaultingPCs(); I != E; ++I)
+ OS << FI.getFunctionFaultInfoAt(I) << "\n";
+ return OS;
+}
+
+raw_ostream &llvm::operator<<(raw_ostream &OS, const FaultMapParser &FMP) {
+ OS << "Version: " << format_hex(FMP.getFaultMapVersion(), 2) << "\n";
+ OS << "NumFunctions: " << FMP.getNumFunctions() << "\n";
+
+ if (FMP.getNumFunctions() == 0)
+ return OS;
+
+ FaultMapParser::FunctionInfoAccessor FI;
+
+ for (unsigned I = 0, E = FMP.getNumFunctions(); I != E; ++I) {
+ FI = (I == 0) ? FMP.getFirstFunctionInfo() : FI.getNextFunctionInfo();
+ OS << FI;
+ }
+
+ return OS;
+}
diff --git a/contrib/llvm-project/llvm/lib/Object/IRSymtab.cpp b/contrib/llvm-project/llvm/lib/Object/IRSymtab.cpp
index e39cb732add1..746b00867157 100644
--- a/contrib/llvm-project/llvm/lib/Object/IRSymtab.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/IRSymtab.cpp
@@ -108,7 +108,7 @@ struct Builder {
Error addModule(Module *M);
Error addSymbol(const ModuleSymbolTable &Msymtab,
- const SmallPtrSet<GlobalValue *, 8> &Used,
+ const SmallPtrSet<GlobalValue *, 4> &Used,
ModuleSymbolTable::Symbol Sym);
Error build(ArrayRef<Module *> Mods);
@@ -119,8 +119,21 @@ Error Builder::addModule(Module *M) {
return make_error<StringError>("input module has no datalayout",
inconvertibleErrorCode());
- SmallPtrSet<GlobalValue *, 8> Used;
- collectUsedGlobalVariables(*M, Used, /*CompilerUsed*/ false);
+ // Symbols in the llvm.used list will get the FB_Used bit and will not be
+ // internalized. We do this for llvm.compiler.used as well:
+ //
+ // IR symbol table tracks module-level asm symbol references but not inline
+ // asm. A symbol only referenced by inline asm is not in the IR symbol table,
+ // so we may not know that the definition (in another translation unit) is
+ // referenced. That definition may have __attribute__((used)) (which lowers to
+ // llvm.compiler.used on ELF targets) to communicate to the compiler that it
+ // may be used by inline asm. The usage is perfectly fine, so we treat
+ // llvm.compiler.used conservatively as llvm.used to work around our own
+ // limitation.
+ SmallVector<GlobalValue *, 4> UsedV;
+ collectUsedGlobalVariables(*M, UsedV, /*CompilerUsed=*/false);
+ collectUsedGlobalVariables(*M, UsedV, /*CompilerUsed=*/true);
+ SmallPtrSet<GlobalValue *, 4> Used(UsedV.begin(), UsedV.end());
ModuleSymbolTable Msymtab;
Msymtab.addModule(M);
@@ -186,6 +199,7 @@ Expected<int> Builder::getComdatIndex(const Comdat *C, const Module *M) {
storage::Comdat Comdat;
setStr(Comdat.Name, Saver.save(Name));
+ Comdat.SelectionKind = C->getSelectionKind();
Comdats.push_back(Comdat);
}
@@ -193,7 +207,7 @@ Expected<int> Builder::getComdatIndex(const Comdat *C, const Module *M) {
}
Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
- const SmallPtrSet<GlobalValue *, 8> &Used,
+ const SmallPtrSet<GlobalValue *, 4> &Used,
ModuleSymbolTable::Symbol Msym) {
Syms.emplace_back();
storage::Symbol &Sym = Syms.back();
@@ -217,7 +231,7 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
raw_svector_ostream OS(Name);
Msymtab.printSymbolName(OS, Msym);
}
- setStr(Sym.Name, Saver.save(StringRef(Name)));
+ setStr(Sym.Name, Saver.save(Name.str()));
auto Flags = Msymtab.getSymbolFlags(Msym);
if (Flags & object::BasicSymbolRef::SF_Undefined)
@@ -247,11 +261,7 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
setStr(Sym.IRName, GV->getName());
- bool IsBuiltinFunc = false;
-
- for (const char *LibcallName : LibcallRoutineNames)
- if (GV->getName() == LibcallName)
- IsBuiltinFunc = true;
+ bool IsBuiltinFunc = llvm::is_contained(LibcallRoutineNames, GV->getName());
if (Used.count(GV) || IsBuiltinFunc)
Sym.Flags |= 1 << storage::Symbol::FB_used;
@@ -268,8 +278,8 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
if (!GVar)
return make_error<StringError>("Only variables can have common linkage!",
inconvertibleErrorCode());
- Uncommon().CommonSize = GV->getParent()->getDataLayout().getTypeAllocSize(
- GV->getType()->getElementType());
+ Uncommon().CommonSize =
+ GV->getParent()->getDataLayout().getTypeAllocSize(GV->getValueType());
Uncommon().CommonAlign = GVar->getAlignment();
}
diff --git a/contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp
index 302255926289..177314a9a790 100644
--- a/contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/MachOObjectFile.cpp
@@ -42,7 +42,6 @@
#include <limits>
#include <list>
#include <memory>
-#include <string>
#include <system_error>
using namespace llvm;
@@ -1836,6 +1835,8 @@ MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
if (!SecOrError)
return SecOrError.takeError();
section_iterator Sec = *SecOrError;
+ if (Sec == section_end())
+ return SymbolRef::ST_Other;
if (Sec->isData() || Sec->isBSS())
return SymbolRef::ST_Data;
return SymbolRef::ST_Function;
@@ -2033,7 +2034,14 @@ bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
SectionType == MachO::S_GB_ZEROFILL);
}
-bool MachOObjectFile::isDebugSection(StringRef SectionName) const {
+bool MachOObjectFile::isDebugSection(DataRefImpl Sec) const {
+ Expected<StringRef> SectionNameOrErr = getSectionName(Sec);
+ if (!SectionNameOrErr) {
+ // TODO: Report the error message properly.
+ consumeError(SectionNameOrErr.takeError());
+ return false;
+ }
+ StringRef SectionName = SectionNameOrErr.get();
return SectionName.startswith("__debug") ||
SectionName.startswith("__zdebug") ||
SectionName.startswith("__apple") || SectionName == "__gdb_index" ||
diff --git a/contrib/llvm-project/llvm/lib/Object/MachOUniversalWriter.cpp b/contrib/llvm-project/llvm/lib/Object/MachOUniversalWriter.cpp
index 4bb467e56a6f..9673c97a10f0 100644
--- a/contrib/llvm-project/llvm/lib/Object/MachOUniversalWriter.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/MachOUniversalWriter.cpp
@@ -263,8 +263,8 @@ buildFatArchList(ArrayRef<Slice> Slices) {
return FatArchList;
}
-static Error writeUniversalBinaryToStream(ArrayRef<Slice> Slices,
- raw_ostream &Out) {
+Error object::writeUniversalBinaryToStream(ArrayRef<Slice> Slices,
+ raw_ostream &Out) {
MachO::fat_header FatHeader;
FatHeader.magic = MachO::FAT_MAGIC;
FatHeader.nfat_arch = Slices.size();
@@ -324,14 +324,3 @@ Error object::writeUniversalBinary(ArrayRef<Slice> Slices,
}
return Temp->keep(OutputFileName);
}
-
-Expected<std::unique_ptr<MemoryBuffer>>
-object::writeUniversalBinaryToBuffer(ArrayRef<Slice> Slices) {
- SmallVector<char, 0> Buffer;
- raw_svector_ostream Out(Buffer);
-
- if (Error E = writeUniversalBinaryToStream(Slices, Out))
- return std::move(E);
-
- return std::make_unique<SmallVectorMemoryBuffer>(std::move(Buffer));
-}
diff --git a/contrib/llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp b/contrib/llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp
index 7f3055b5dcfa..9a79de77af16 100644
--- a/contrib/llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -99,16 +99,18 @@ initializeRecordStreamer(const Module &M,
if (!MCII)
return;
- MCObjectFileInfo MOFI;
- MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
- MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx);
- MOFI.setSDKVersion(M.getSDKVersion());
- RecordStreamer Streamer(MCCtx, M);
- T->createNullTargetStreamer(Streamer);
-
std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
SourceMgr SrcMgr;
SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
+
+ MCContext MCCtx(TT, MAI.get(), MRI.get(), STI.get(), &SrcMgr);
+ std::unique_ptr<MCObjectFileInfo> MOFI(
+ T->createMCObjectFileInfo(MCCtx, /*PIC=*/false));
+ MOFI->setSDKVersion(M.getSDKVersion());
+ MCCtx.setObjectFileInfo(MOFI.get());
+ RecordStreamer Streamer(MCCtx, M);
+ T->createNullTargetStreamer(Streamer);
+
std::unique_ptr<MCAsmParser> Parser(
createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI));
diff --git a/contrib/llvm-project/llvm/lib/Object/ObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/ObjectFile.cpp
index cf09a66d9c7d..5c894439ff67 100644
--- a/contrib/llvm-project/llvm/lib/Object/ObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/ObjectFile.cpp
@@ -94,9 +94,7 @@ bool ObjectFile::isBerkeleyData(DataRefImpl Sec) const {
return isSectionData(Sec);
}
-bool ObjectFile::isDebugSection(StringRef SectionName) const {
- return false;
-}
+bool ObjectFile::isDebugSection(DataRefImpl Sec) const { return false; }
Expected<section_iterator>
ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
@@ -147,6 +145,7 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
case file_magic::windows_resource:
case file_magic::pdb:
case file_magic::minidump:
+ case file_magic::goff_object:
return errorCodeToError(object_error::invalid_file_type);
case file_magic::tapi_file:
return errorCodeToError(object_error::invalid_file_type);
diff --git a/contrib/llvm-project/llvm/lib/Object/RecordStreamer.cpp b/contrib/llvm-project/llvm/lib/Object/RecordStreamer.cpp
index b2f973eff361..2d07d34bbf97 100644
--- a/contrib/llvm-project/llvm/lib/Object/RecordStreamer.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/RecordStreamer.cpp
@@ -123,9 +123,10 @@ RecordStreamer::State RecordStreamer::getSymbolState(const MCSymbol *Sym) {
return SI->second;
}
-void RecordStreamer::emitELFSymverDirective(StringRef AliasName,
- const MCSymbol *Aliasee) {
- SymverAliasMap[Aliasee].push_back(AliasName);
+void RecordStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
+ StringRef Name,
+ bool KeepOriginalSym) {
+ SymverAliasMap[OriginalSym].push_back(Name);
}
iterator_range<RecordStreamer::const_symver_iterator>
diff --git a/contrib/llvm-project/llvm/lib/Object/RecordStreamer.h b/contrib/llvm-project/llvm/lib/Object/RecordStreamer.h
index 99d15f790a15..957d80f33bf4 100644
--- a/contrib/llvm-project/llvm/lib/Object/RecordStreamer.h
+++ b/contrib/llvm-project/llvm/lib/Object/RecordStreamer.h
@@ -63,8 +63,8 @@ public:
void EndCOFFSymbolDef() override {}
/// Record .symver aliases for later processing.
- void emitELFSymverDirective(StringRef AliasName,
- const MCSymbol *Aliasee) override;
+ void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name,
+ bool KeepOriginalSym) override;
// Emit ELF .symver aliases and ensure they have the same binding as the
// defined symbol they alias with.
diff --git a/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp b/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
index 204577af7239..ab98a2dd2ac1 100644
--- a/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
@@ -89,8 +89,8 @@ static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,
static bool supportsBPF(uint64_t Type) {
switch (Type) {
- case ELF::R_BPF_64_32:
- case ELF::R_BPF_64_64:
+ case ELF::R_BPF_64_ABS32:
+ case ELF::R_BPF_64_ABS64:
return true;
default:
return false;
@@ -100,9 +100,9 @@ static bool supportsBPF(uint64_t Type) {
static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S,
uint64_t LocData, int64_t /*Addend*/) {
switch (Type) {
- case ELF::R_BPF_64_32:
+ case ELF::R_BPF_64_ABS32:
return (S + LocData) & 0xFFFFFFFF;
- case ELF::R_BPF_64_64:
+ case ELF::R_BPF_64_ABS64:
return S + LocData;
default:
llvm_unreachable("Invalid relocation type");
@@ -312,12 +312,17 @@ static bool supportsARM(uint64_t Type) {
}
static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
- uint64_t LocData, int64_t /*Addend*/) {
+ uint64_t LocData, int64_t Addend) {
+ // Support both RELA and REL relocations. The caller is responsible
+ // for supplying the correct values for LocData and Addend, i.e.
+ // Addend == 0 for REL and LocData == 0 for RELA.
+ assert((LocData == 0 || Addend == 0) &&
+ "one of LocData and Addend must be 0");
switch (Type) {
case ELF::R_ARM_ABS32:
- return (S + LocData) & 0xFFFFFFFF;
+ return (S + LocData + Addend) & 0xFFFFFFFF;
case ELF::R_ARM_REL32:
- return (S + LocData - Offset) & 0xFFFFFFFF;
+ return (S + LocData + Addend - Offset) & 0xFFFFFFFF;
}
llvm_unreachable("Invalid relocation type");
}
@@ -572,9 +577,10 @@ static bool supportsWasm32(uint64_t Type) {
case wasm::R_WASM_GLOBAL_INDEX_LEB:
case wasm::R_WASM_FUNCTION_OFFSET_I32:
case wasm::R_WASM_SECTION_OFFSET_I32:
- case wasm::R_WASM_EVENT_INDEX_LEB:
+ case wasm::R_WASM_TAG_INDEX_LEB:
case wasm::R_WASM_GLOBAL_INDEX_I32:
case wasm::R_WASM_TABLE_NUMBER_LEB:
+ case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
return true;
default:
return false;
@@ -608,9 +614,10 @@ static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
case wasm::R_WASM_GLOBAL_INDEX_LEB:
case wasm::R_WASM_FUNCTION_OFFSET_I32:
case wasm::R_WASM_SECTION_OFFSET_I32:
- case wasm::R_WASM_EVENT_INDEX_LEB:
+ case wasm::R_WASM_TAG_INDEX_LEB:
case wasm::R_WASM_GLOBAL_INDEX_I32:
case wasm::R_WASM_TABLE_NUMBER_LEB:
+ case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
// For wasm section, its offset at 0 -- ignoring Value
return LocData;
default:
@@ -742,8 +749,13 @@ uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
};
- if (GetRelSectionType() == ELF::SHT_RELA)
+ if (GetRelSectionType() == ELF::SHT_RELA) {
Addend = getELFAddend(R);
+ // RISCV relocations use both LocData and Addend.
+ if (Obj->getArch() != Triple::riscv32 &&
+ Obj->getArch() != Triple::riscv64)
+ LocData = 0;
+ }
}
return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
diff --git a/contrib/llvm-project/llvm/lib/Object/SymbolSize.cpp b/contrib/llvm-project/llvm/lib/Object/SymbolSize.cpp
index 97baabec084b..e42dbe6f47ab 100644
--- a/contrib/llvm-project/llvm/lib/Object/SymbolSize.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/SymbolSize.cpp
@@ -12,6 +12,7 @@
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/Wasm.h"
+#include "llvm/Object/XCOFFObjectFile.h"
using namespace llvm;
using namespace object;
@@ -30,7 +31,8 @@ static unsigned getSectionID(const ObjectFile &O, SectionRef Sec) {
return M->getSectionID(Sec);
if (isa<WasmObjectFile>(&O))
return Sec.getIndex();
-
+ if (isa<XCOFFObjectFile>(&O))
+ return Sec.getIndex();
return cast<COFFObjectFile>(O).getSectionID(Sec);
}
@@ -39,6 +41,8 @@ static unsigned getSymbolSectionID(const ObjectFile &O, SymbolRef Sym) {
return M->getSymbolSectionID(Sym);
if (const auto *M = dyn_cast<WasmObjectFile>(&O))
return M->getSymbolSectionId(Sym);
+ if (const auto *M = dyn_cast<XCOFFObjectFile>(&O))
+ return M->getSymbolSectionID(Sym);
return cast<COFFObjectFile>(O).getSymbolSectionID(Sym);
}
diff --git a/contrib/llvm-project/llvm/lib/Object/SymbolicFile.cpp b/contrib/llvm-project/llvm/lib/Object/SymbolicFile.cpp
index 34a2c5e1c125..58db5b672914 100644
--- a/contrib/llvm-project/llvm/lib/Object/SymbolicFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/SymbolicFile.cpp
@@ -53,6 +53,7 @@ SymbolicFile::createSymbolicFile(MemoryBufferRef Object, file_magic Type,
case file_magic::elf_executable:
case file_magic::elf_shared_object:
case file_magic::elf_core:
+ case file_magic::goff_object:
case file_magic::macho_executable:
case file_magic::macho_fixed_virtual_memory_shared_lib:
case file_magic::macho_core:
@@ -102,6 +103,7 @@ bool SymbolicFile::isSymbolicFile(file_magic Type, const LLVMContext *Context) {
case file_magic::elf_executable:
case file_magic::elf_shared_object:
case file_magic::elf_core:
+ case file_magic::goff_object:
case file_magic::macho_executable:
case file_magic::macho_fixed_virtual_memory_shared_lib:
case file_magic::macho_core:
diff --git a/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp b/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp
index 7a361990ba5d..6b576260bdb1 100644
--- a/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp
@@ -14,17 +14,12 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/TextAPI/Symbol.h"
using namespace llvm;
using namespace MachO;
using namespace object;
-static constexpr StringLiteral ObjC1ClassNamePrefix = ".objc_class_name_";
-static constexpr StringLiteral ObjC2ClassNamePrefix = "_OBJC_CLASS_$_";
-static constexpr StringLiteral ObjC2MetaClassNamePrefix = "_OBJC_METACLASS_$_";
-static constexpr StringLiteral ObjC2EHTypePrefix = "_OBJC_EHTYPE_$_";
-static constexpr StringLiteral ObjC2IVarPrefix = "_OBJC_IVAR_$_";
-
static uint32_t getFlags(const Symbol *Sym) {
uint32_t Flags = BasicSymbolRef::SF_Global;
if (Sym->isUndefined())
diff --git a/contrib/llvm-project/llvm/lib/Object/TapiUniversal.cpp b/contrib/llvm-project/llvm/lib/Object/TapiUniversal.cpp
index 48cb949cb6f4..d73d93f6bd53 100644
--- a/contrib/llvm-project/llvm/lib/Object/TapiUniversal.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/TapiUniversal.cpp
@@ -14,7 +14,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/TextAPI/MachO/TextAPIReader.h"
+#include "llvm/TextAPI/TextAPIReader.h"
using namespace llvm;
using namespace MachO;
diff --git a/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp
index 40f468881edd..a08c648358c0 100644
--- a/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp
@@ -39,8 +39,8 @@ using namespace object;
void WasmSymbol::print(raw_ostream &Out) const {
Out << "Name=" << Info.Name
- << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind))
- << ", Flags=" << Info.Flags;
+ << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) << ", Flags=0x"
+ << Twine::utohexstr(Info.Flags);
if (!isTypeData()) {
Out << ", ElemIndex=" << Info.ElementIndex;
} else if (isDefined()) {
@@ -208,7 +208,7 @@ static Error readInitExpr(wasm::WasmInitExpr &Expr,
static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) {
wasm::WasmLimits Result;
Result.Flags = readVaruint32(Ctx);
- Result.Initial = readVaruint64(Ctx);
+ Result.Minimum = readVaruint64(Ctx);
if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
Result.Maximum = readVaruint64(Ctx);
return Result;
@@ -316,8 +316,8 @@ Error WasmObjectFile::parseSection(WasmSection &Sec) {
return parseTableSection(Ctx);
case wasm::WASM_SEC_MEMORY:
return parseMemorySection(Ctx);
- case wasm::WASM_SEC_EVENT:
- return parseEventSection(Ctx);
+ case wasm::WASM_SEC_TAG:
+ return parseTagSection(Ctx);
case wasm::WASM_SEC_GLOBAL:
return parseGlobalSection(Ctx);
case wasm::WASM_SEC_EXPORT:
@@ -462,7 +462,7 @@ Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
for (uint32_t I = 0; I < Count; I++) {
DataSegments[I].Data.Name = readString(Ctx);
DataSegments[I].Data.Alignment = readVaruint32(Ctx);
- DataSegments[I].Data.LinkerFlags = readVaruint32(Ctx);
+ DataSegments[I].Data.LinkingFlags = readVaruint32(Ctx);
}
break;
}
@@ -507,19 +507,19 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
std::vector<wasm::WasmImport *> ImportedGlobals;
std::vector<wasm::WasmImport *> ImportedFunctions;
- std::vector<wasm::WasmImport *> ImportedEvents;
+ std::vector<wasm::WasmImport *> ImportedTags;
std::vector<wasm::WasmImport *> ImportedTables;
ImportedGlobals.reserve(Imports.size());
ImportedFunctions.reserve(Imports.size());
- ImportedEvents.reserve(Imports.size());
+ ImportedTags.reserve(Imports.size());
ImportedTables.reserve(Imports.size());
for (auto &I : Imports) {
if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
ImportedFunctions.emplace_back(&I);
else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
ImportedGlobals.emplace_back(&I);
- else if (I.Kind == wasm::WASM_EXTERNAL_EVENT)
- ImportedEvents.emplace_back(&I);
+ else if (I.Kind == wasm::WASM_EXTERNAL_TAG)
+ ImportedTags.emplace_back(&I);
else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
ImportedTables.emplace_back(&I);
}
@@ -529,7 +529,7 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
const wasm::WasmSignature *Signature = nullptr;
const wasm::WasmGlobalType *GlobalType = nullptr;
const wasm::WasmTableType *TableType = nullptr;
- const wasm::WasmEventType *EventType = nullptr;
+ const wasm::WasmTagType *TagType = nullptr;
Info.Kind = readUint8(Ctx);
Info.Flags = readVaruint32(Ctx);
@@ -598,8 +598,8 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
case wasm::WASM_SYMBOL_TYPE_TABLE:
Info.ElementIndex = readVaruint32(Ctx);
- if (!isValidTableIndex(Info.ElementIndex) ||
- IsDefined != isDefinedTableIndex(Info.ElementIndex))
+ if (!isValidTableNumber(Info.ElementIndex) ||
+ IsDefined != isDefinedTableNumber(Info.ElementIndex))
return make_error<GenericBinaryError>("invalid table symbol index",
object_error::parse_failed);
if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
@@ -608,8 +608,8 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
object_error::parse_failed);
if (IsDefined) {
Info.Name = readString(Ctx);
- unsigned TableIndex = Info.ElementIndex - NumImportedTables;
- wasm::WasmTable &Table = Tables[TableIndex];
+ unsigned TableNumber = Info.ElementIndex - NumImportedTables;
+ wasm::WasmTable &Table = Tables[TableNumber];
TableType = &Table.Type;
if (Table.SymbolName.empty())
Table.SymbolName = Info.Name;
@@ -637,9 +637,12 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
object_error::parse_failed);
auto Offset = readVaruint64(Ctx);
auto Size = readVaruint64(Ctx);
- if (Offset + Size > DataSegments[Index].Data.Content.size())
- return make_error<GenericBinaryError>("invalid data symbol offset",
- object_error::parse_failed);
+ size_t SegmentSize = DataSegments[Index].Data.Content.size();
+ if (Offset > SegmentSize)
+ return make_error<GenericBinaryError>(
+ "invalid data symbol offset: `" + Info.Name + "` (offset: " +
+ Twine(Offset) + " segment size: " + Twine(SegmentSize) + ")",
+ object_error::parse_failed);
Info.DataRef = wasm::WasmDataReference{Index, Offset, Size};
}
break;
@@ -657,11 +660,11 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
break;
}
- case wasm::WASM_SYMBOL_TYPE_EVENT: {
+ case wasm::WASM_SYMBOL_TYPE_TAG: {
Info.ElementIndex = readVaruint32(Ctx);
- if (!isValidEventIndex(Info.ElementIndex) ||
- IsDefined != isDefinedEventIndex(Info.ElementIndex))
- return make_error<GenericBinaryError>("invalid event symbol index",
+ if (!isValidTagIndex(Info.ElementIndex) ||
+ IsDefined != isDefinedTagIndex(Info.ElementIndex))
+ return make_error<GenericBinaryError>("invalid tag symbol index",
object_error::parse_failed);
if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
wasm::WASM_SYMBOL_BINDING_WEAK)
@@ -669,23 +672,23 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
object_error::parse_failed);
if (IsDefined) {
Info.Name = readString(Ctx);
- unsigned EventIndex = Info.ElementIndex - NumImportedEvents;
- wasm::WasmEvent &Event = Events[EventIndex];
- Signature = &Signatures[Event.Type.SigIndex];
- EventType = &Event.Type;
- if (Event.SymbolName.empty())
- Event.SymbolName = Info.Name;
+ unsigned TagIndex = Info.ElementIndex - NumImportedTags;
+ wasm::WasmTag &Tag = Tags[TagIndex];
+ Signature = &Signatures[Tag.Type.SigIndex];
+ TagType = &Tag.Type;
+ if (Tag.SymbolName.empty())
+ Tag.SymbolName = Info.Name;
} else {
- wasm::WasmImport &Import = *ImportedEvents[Info.ElementIndex];
+ wasm::WasmImport &Import = *ImportedTags[Info.ElementIndex];
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
Info.Name = readString(Ctx);
Info.ImportName = Import.Field;
} else {
Info.Name = Import.Field;
}
- EventType = &Import.Event;
- Signature = &Signatures[EventType->SigIndex];
+ TagType = &Import.Tag;
+ Signature = &Signatures[TagType->SigIndex];
if (!Import.Module.empty()) {
Info.ImportModule = Import.Module;
}
@@ -707,7 +710,7 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
object_error::parse_failed);
LinkingData.SymbolTable.emplace_back(Info);
Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType,
- EventType, Signature);
+ TagType, Signature);
LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
}
@@ -867,6 +870,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
case wasm::R_WASM_TABLE_INDEX_I32:
case wasm::R_WASM_TABLE_INDEX_I64:
case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
+ case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
if (!isValidFunctionSymbol(Reloc.Index))
return make_error<GenericBinaryError>(
"invalid relocation function index", object_error::parse_failed);
@@ -895,9 +899,9 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
return make_error<GenericBinaryError>("invalid relocation global index",
object_error::parse_failed);
break;
- case wasm::R_WASM_EVENT_INDEX_LEB:
- if (!isValidEventSymbol(Reloc.Index))
- return make_error<GenericBinaryError>("invalid relocation event index",
+ case wasm::R_WASM_TAG_INDEX_LEB:
+ if (!isValidTagSymbol(Reloc.Index))
+ return make_error<GenericBinaryError>("invalid relocation tag index",
object_error::parse_failed);
break;
case wasm::R_WASM_MEMORY_ADDR_LEB:
@@ -905,6 +909,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
case wasm::R_WASM_MEMORY_ADDR_I32:
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
+ case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
if (!isValidDataSymbol(Reloc.Index))
return make_error<GenericBinaryError>("invalid relocation data index",
object_error::parse_failed);
@@ -914,6 +919,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
case wasm::R_WASM_MEMORY_ADDR_SLEB64:
case wasm::R_WASM_MEMORY_ADDR_I64:
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
+ case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64:
if (!isValidDataSymbol(Reloc.Index))
return make_error<GenericBinaryError>("invalid relocation data index",
object_error::parse_failed);
@@ -953,6 +959,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
Size = 10;
if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 ||
Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
+ Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||
Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
@@ -1058,10 +1065,10 @@ Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
object_error::parse_failed);
break;
}
- case wasm::WASM_EXTERNAL_EVENT:
- NumImportedEvents++;
- Im.Event.Attribute = readVarint32(Ctx);
- Im.Event.SigIndex = readVarint32(Ctx);
+ case wasm::WASM_EXTERNAL_TAG:
+ NumImportedTags++;
+ Im.Tag.Attribute = readUint8(Ctx);
+ Im.Tag.SigIndex = readVarint32(Ctx);
break;
default:
return make_error<GenericBinaryError>("unexpected import kind",
@@ -1130,20 +1137,20 @@ Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
return Error::success();
}
-Error WasmObjectFile::parseEventSection(ReadContext &Ctx) {
- EventSection = Sections.size();
- uint32_t Count = readVarint32(Ctx);
- Events.reserve(Count);
+Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {
+ TagSection = Sections.size();
+ uint32_t Count = readVaruint32(Ctx);
+ Tags.reserve(Count);
while (Count--) {
- wasm::WasmEvent Event;
- Event.Index = NumImportedEvents + Events.size();
- Event.Type.Attribute = readVaruint32(Ctx);
- Event.Type.SigIndex = readVarint32(Ctx);
- Events.push_back(Event);
+ wasm::WasmTag Tag;
+ Tag.Index = NumImportedTags + Tags.size();
+ Tag.Type.Attribute = readUint8(Ctx);
+ Tag.Type.SigIndex = readVaruint32(Ctx);
+ Tags.push_back(Tag);
}
if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("event section ended prematurely",
+ return make_error<GenericBinaryError>("tag section ended prematurely",
object_error::parse_failed);
return Error::success();
}
@@ -1188,9 +1195,9 @@ Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
return make_error<GenericBinaryError>("invalid global export",
object_error::parse_failed);
break;
- case wasm::WASM_EXTERNAL_EVENT:
- if (!isValidEventIndex(Ex.Index))
- return make_error<GenericBinaryError>("invalid event export",
+ case wasm::WASM_EXTERNAL_TAG:
+ if (!isValidTagIndex(Ex.Index))
+ return make_error<GenericBinaryError>("invalid tag export",
object_error::parse_failed);
break;
case wasm::WASM_EXTERNAL_MEMORY:
@@ -1220,7 +1227,7 @@ bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
return Index < NumImportedGlobals + Globals.size();
}
-bool WasmObjectFile::isValidTableIndex(uint32_t Index) const {
+bool WasmObjectFile::isValidTableNumber(uint32_t Index) const {
return Index < NumImportedTables + Tables.size();
}
@@ -1228,16 +1235,16 @@ bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
}
-bool WasmObjectFile::isDefinedTableIndex(uint32_t Index) const {
- return Index >= NumImportedTables && isValidTableIndex(Index);
+bool WasmObjectFile::isDefinedTableNumber(uint32_t Index) const {
+ return Index >= NumImportedTables && isValidTableNumber(Index);
}
-bool WasmObjectFile::isValidEventIndex(uint32_t Index) const {
- return Index < NumImportedEvents + Events.size();
+bool WasmObjectFile::isValidTagIndex(uint32_t Index) const {
+ return Index < NumImportedTags + Tags.size();
}
-bool WasmObjectFile::isDefinedEventIndex(uint32_t Index) const {
- return Index >= NumImportedEvents && isValidEventIndex(Index);
+bool WasmObjectFile::isDefinedTagIndex(uint32_t Index) const {
+ return Index >= NumImportedTags && isValidTagIndex(Index);
}
bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
@@ -1252,8 +1259,8 @@ bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
}
-bool WasmObjectFile::isValidEventSymbol(uint32_t Index) const {
- return Index < Symbols.size() && Symbols[Index].isTypeEvent();
+bool WasmObjectFile::isValidTagSymbol(uint32_t Index) const {
+ return Index < Symbols.size() && Symbols[Index].isTypeTag();
}
bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
@@ -1280,9 +1287,9 @@ wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
return Globals[Index - NumImportedGlobals];
}
-wasm::WasmEvent &WasmObjectFile::getDefinedEvent(uint32_t Index) {
- assert(isDefinedEventIndex(Index));
- return Events[Index - NumImportedEvents];
+wasm::WasmTag &WasmObjectFile::getDefinedTag(uint32_t Index) {
+ assert(isDefinedTagIndex(Index));
+ return Tags[Index - NumImportedTags];
}
Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
@@ -1340,13 +1347,54 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
ElemSegments.reserve(Count);
while (Count--) {
wasm::WasmElemSegment Segment;
- Segment.TableIndex = readVaruint32(Ctx);
- if (Segment.TableIndex != 0) {
- return make_error<GenericBinaryError>("invalid TableIndex",
+ Segment.Flags = readVaruint32(Ctx);
+
+ uint32_t SupportedFlags = wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER |
+ wasm::WASM_ELEM_SEGMENT_IS_PASSIVE |
+ wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS;
+ if (Segment.Flags & ~SupportedFlags)
+ return make_error<GenericBinaryError>(
+ "Unsupported flags for element segment", object_error::parse_failed);
+
+ if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER)
+ Segment.TableNumber = readVaruint32(Ctx);
+ else
+ Segment.TableNumber = 0;
+ if (!isValidTableNumber(Segment.TableNumber))
+ return make_error<GenericBinaryError>("invalid TableNumber",
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;
+ } else {
+ if (Error Err = readInitExpr(Segment.Offset, Ctx))
+ return Err;
}
- if (Error Err = readInitExpr(Segment.Offset, Ctx))
- return Err;
+
+ if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND) {
+ Segment.ElemKind = readUint8(Ctx);
+ if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS) {
+ if (Segment.ElemKind != uint8_t(wasm::ValType::FUNCREF) &&
+ Segment.ElemKind != uint8_t(wasm::ValType::EXTERNREF)) {
+ return make_error<GenericBinaryError>("invalid reference type",
+ object_error::parse_failed);
+ }
+ } else {
+ if (Segment.ElemKind != 0)
+ return make_error<GenericBinaryError>("invalid elemtype",
+ object_error::parse_failed);
+ Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
+ }
+ } else {
+ Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
+ }
+
+ if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS)
+ return make_error<GenericBinaryError>(
+ "elem segment init expressions not yet implemented",
+ object_error::parse_failed);
+
uint32_t NumElems = readVaruint32(Ctx);
while (NumElems--) {
Segment.Functions.push_back(readVaruint32(Ctx));
@@ -1388,7 +1436,7 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
// The rest of these Data fields are set later, when reading in the linking
// metadata section.
Segment.Data.Alignment = 0;
- Segment.Data.LinkerFlags = 0;
+ Segment.Data.LinkingFlags = 0;
Segment.Data.Comdat = UINT32_MAX;
Segment.SectionOffset = Ctx.Ptr - Ctx.Start;
Ctx.Ptr += Size;
@@ -1468,7 +1516,7 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const {
switch (Sym.Info.Kind) {
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
- case wasm::WASM_SYMBOL_TYPE_EVENT:
+ case wasm::WASM_SYMBOL_TYPE_TAG:
case wasm::WASM_SYMBOL_TYPE_TABLE:
return Sym.Info.ElementIndex;
case wasm::WASM_SYMBOL_TYPE_DATA: {
@@ -1517,7 +1565,7 @@ WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
return SymbolRef::ST_Data;
case wasm::WASM_SYMBOL_TYPE_SECTION:
return SymbolRef::ST_Debug;
- case wasm::WASM_SYMBOL_TYPE_EVENT:
+ case wasm::WASM_SYMBOL_TYPE_TAG:
return SymbolRef::ST_Other;
case wasm::WASM_SYMBOL_TYPE_TABLE:
return SymbolRef::ST_Other;
@@ -1553,8 +1601,8 @@ uint32_t WasmObjectFile::getSymbolSectionIdImpl(const WasmSymbol &Sym) const {
return DataSection;
case wasm::WASM_SYMBOL_TYPE_SECTION:
return Sym.Info.ElementIndex;
- case wasm::WASM_SYMBOL_TYPE_EVENT:
- return EventSection;
+ case wasm::WASM_SYMBOL_TYPE_TAG:
+ return TagSection;
case wasm::WASM_SYMBOL_TYPE_TABLE:
return TableSection;
default:
@@ -1576,7 +1624,7 @@ Expected<StringRef> WasmObjectFile::getSectionName(DataRefImpl Sec) const {
ECase(TABLE);
ECase(MEMORY);
ECase(GLOBAL);
- ECase(EVENT);
+ ECase(TAG);
ECase(EXPORT);
ECase(START);
ECase(ELEM);
@@ -1775,8 +1823,8 @@ int WasmSectionOrderChecker::getSectionOrder(unsigned ID,
return WASM_SEC_ORDER_DATA;
case wasm::WASM_SEC_DATACOUNT:
return WASM_SEC_ORDER_DATACOUNT;
- case wasm::WASM_SEC_EVENT:
- return WASM_SEC_ORDER_EVENT;
+ case wasm::WASM_SEC_TAG:
+ return WASM_SEC_ORDER_TAG;
default:
return WASM_SEC_ORDER_NONE;
}
@@ -1798,9 +1846,9 @@ int WasmSectionOrderChecker::DisallowedPredecessors
// WASM_SEC_ORDER_TABLE
{WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY},
// WASM_SEC_ORDER_MEMORY
- {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_EVENT},
- // WASM_SEC_ORDER_EVENT
- {WASM_SEC_ORDER_EVENT, WASM_SEC_ORDER_GLOBAL},
+ {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG},
+ // WASM_SEC_ORDER_TAG
+ {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL},
// WASM_SEC_ORDER_GLOBAL
{WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},
// WASM_SEC_ORDER_EXPORT
diff --git a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
index a16a458168d4..53447d0c97b2 100644
--- a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/XCOFFObjectFile.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/DataExtractor.h"
#include <cstddef>
@@ -23,8 +24,8 @@ using namespace XCOFF;
namespace object {
static const uint8_t FunctionSym = 0x20;
-static const uint8_t SymTypeMask = 0x07;
static const uint16_t NoRelMask = 0x0001;
+static const size_t SymbolAuxTypeOffset = 17;
// Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
// 'M'. Returns a pointer to the underlying object on success.
@@ -82,6 +83,19 @@ uint8_t XCOFFRelocation32::getRelocatedLength() const {
return (Info & XR_BIASED_LENGTH_MASK) + 1;
}
+uintptr_t
+XCOFFObjectFile::getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
+ uint32_t Distance) {
+ return getWithOffset(CurrentAddress, Distance * XCOFF::SymbolTableEntrySize);
+}
+
+const XCOFF::SymbolAuxType *
+XCOFFObjectFile::getSymbolAuxType(uintptr_t AuxEntryAddress) const {
+ assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
+ return viewAs<XCOFF::SymbolAuxType>(
+ getWithOffset(AuxEntryAddress, SymbolAuxTypeOffset));
+}
+
void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
uintptr_t TableAddress) const {
if (Addr < TableAddress)
@@ -114,14 +128,12 @@ XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
return viewAs<XCOFFSectionHeader64>(Ref.p);
}
-const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
+XCOFFSymbolRef XCOFFObjectFile::toSymbolRef(DataRefImpl Ref) const {
assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
#ifndef NDEBUG
checkSymbolEntryPointer(Ref.p);
#endif
- auto SymEntPtr = viewAs<XCOFFSymbolEntry>(Ref.p);
- return SymEntPtr;
+ return XCOFFSymbolRef(Ref, this);
}
const XCOFFFileHeader32 *XCOFFObjectFile::fileHeader32() const {
@@ -147,15 +159,15 @@ XCOFFObjectFile::sectionHeaderTable64() const {
}
void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
- const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
- SymEntPtr += SymEntPtr->NumberOfAuxEntries + 1;
+ uintptr_t NextSymbolAddr = getAdvancedSymbolEntryAddress(
+ Symb.p, toSymbolRef(Symb).getNumberOfAuxEntries() + 1);
#ifndef NDEBUG
// This function is used by basic_symbol_iterator, which allows to
// point to the end-of-symbol-table address.
- if (reinterpret_cast<uintptr_t>(SymEntPtr) != getEndOfSymbolTableAddress())
- checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(SymEntPtr));
+ if (NextSymbolAddr != getEndOfSymbolTableAddress())
+ checkSymbolEntryPointer(NextSymbolAddr);
#endif
- Symb.p = reinterpret_cast<uintptr_t>(SymEntPtr);
+ Symb.p = NextSymbolAddr;
}
Expected<StringRef>
@@ -175,36 +187,27 @@ XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
object_error::parse_failed);
}
+StringRef XCOFFObjectFile::getStringTable() const {
+ return StringRef(StringTable.Data, StringTable.Size);
+}
+
Expected<StringRef>
XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const {
- if (CFileEntPtr->NameInStrTbl.Magic !=
- XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
+ if (CFileEntPtr->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
return generateXCOFFFixedNameStringRef(CFileEntPtr->Name);
return getStringTableEntry(CFileEntPtr->NameInStrTbl.Offset);
}
Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
- const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
-
- // A storage class value with the high-order bit on indicates that the name is
- // a symbolic debugger stabstring.
- if (SymEntPtr->StorageClass & 0x80)
- return StringRef("Unimplemented Debug Name");
-
- if (SymEntPtr->NameInStrTbl.Magic != XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
- return generateXCOFFFixedNameStringRef(SymEntPtr->SymbolName);
-
- return getStringTableEntry(SymEntPtr->NameInStrTbl.Offset);
+ return toSymbolRef(Symb).getName();
}
Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
- return toSymbolEntry(Symb)->Value;
+ return toSymbolRef(Symb).getValue();
}
uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
- return toSymbolEntry(Symb)->Value;
+ return toSymbolRef(Symb).getValue();
}
uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
@@ -215,14 +218,13 @@ uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
Expected<SymbolRef::Type>
XCOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
- llvm_unreachable("Not yet implemented!");
+ // TODO: Return the correct symbol type.
return SymbolRef::ST_Other;
}
Expected<section_iterator>
XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
- const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
- int16_t SectNum = SymEntPtr->SectionNumber;
+ const int16_t SectNum = toSymbolRef(Symb).getSectionNumber();
if (isReservedSectionNumber(SectNum))
return section_end();
@@ -296,9 +298,7 @@ uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
}
bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
- bool Result = false;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ return false;
}
bool XCOFFObjectFile::isSectionText(DataRefImpl Sec) const {
@@ -315,6 +315,11 @@ bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const {
return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS);
}
+bool XCOFFObjectFile::isDebugSection(DataRefImpl Sec) const {
+ uint32_t Flags = getSectionFlags(Sec);
+ return Flags & (XCOFF::STYP_DEBUG | XCOFF::STYP_DWARF);
+}
+
bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const {
return is64Bit() ? toSection64(Sec)->FileOffsetToRawData == 0
: toSection32(Sec)->FileOffsetToRawData == 0;
@@ -377,7 +382,7 @@ symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
return symbol_end();
DataRefImpl SymDRI;
- SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
+ SymDRI.p = getSymbolEntryAddressByIndex(Index);
return symbol_iterator(SymbolRef(SymDRI, this));
}
@@ -398,24 +403,20 @@ void XCOFFObjectFile::getRelocationTypeName(
Expected<uint32_t> XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
uint32_t Result = 0;
- llvm_unreachable("Not yet implemented!");
+ // TODO: Return correct symbol flags.
return Result;
}
basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
- if (is64Bit())
- report_fatal_error("64-bit support not implemented yet");
DataRefImpl SymDRI;
SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
return basic_symbol_iterator(SymbolRef(SymDRI, this));
}
basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
- if (is64Bit())
- report_fatal_error("64-bit support not implemented yet");
DataRefImpl SymDRI;
- SymDRI.p = reinterpret_cast<uintptr_t>(
- SymbolTblPtr + getLogicalNumberOfSymbolTableEntries32());
+ const uint32_t NumberOfSymbolTableEntries = getNumberOfSymbolTableEntries();
+ SymDRI.p = getSymbolEntryAddressByIndex(NumberOfSymbolTableEntries);
return basic_symbol_iterator(SymbolRef(SymDRI, this));
}
@@ -448,7 +449,7 @@ SubtargetFeatures XCOFFObjectFile::getFeatures() const {
bool XCOFFObjectFile::isRelocatableObject() const {
if (is64Bit())
- report_fatal_error("64-bit support not implemented yet");
+ return !(fileHeader64()->Flags & NoRelMask);
return !(fileHeader32()->Flags & NoRelMask);
}
@@ -458,6 +459,22 @@ Expected<uint64_t> XCOFFObjectFile::getStartAddress() const {
return 0;
}
+StringRef XCOFFObjectFile::mapDebugSectionName(StringRef Name) const {
+ return StringSwitch<StringRef>(Name)
+ .Case("dwinfo", "debug_info")
+ .Case("dwline", "debug_line")
+ .Case("dwpbnms", "debug_pubnames")
+ .Case("dwpbtyp", "debug_pubtypes")
+ .Case("dwarnge", "debug_aranges")
+ .Case("dwabrev", "debug_abbrev")
+ .Case("dwstr", "debug_str")
+ .Case("dwrnges", "debug_ranges")
+ .Case("dwloc", "debug_loc")
+ .Case("dwframe", "debug_frame")
+ .Case("dwmac", "debug_macinfo")
+ .Default(Name);
+}
+
size_t XCOFFObjectFile::getFileHeaderSize() const {
return is64Bit() ? sizeof(XCOFFFileHeader64) : sizeof(XCOFFFileHeader32);
}
@@ -486,9 +503,8 @@ Expected<DataRefImpl> XCOFFObjectFile::getSectionByNum(int16_t Num) const {
}
Expected<StringRef>
-XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
- int16_t SectionNum = SymEntPtr->SectionNumber;
+XCOFFObjectFile::getSymbolSectionName(XCOFFSymbolRef SymEntPtr) const {
+ const int16_t SectionNum = SymEntPtr.getSectionNumber();
switch (SectionNum) {
case XCOFF::N_DEBUG:
@@ -506,6 +522,11 @@ XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
}
}
+unsigned XCOFFObjectFile::getSymbolSectionID(SymbolRef Sym) const {
+ XCOFFSymbolRef XCOFFSymRef(Sym.getRawDataRefImpl(), this);
+ return XCOFFSymRef.getSectionNumber();
+}
+
bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
return (SectionNumber <= 0 && SectionNumber >= -2);
}
@@ -549,10 +570,13 @@ uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
return fileHeader64()->NumberOfSymTableEntries;
}
+uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
+ return is64Bit() ? getNumberOfSymbolTableEntries64()
+ : getLogicalNumberOfSymbolTableEntries32();
+}
+
uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
- uint32_t NumberOfSymTableEntries =
- is64Bit() ? getNumberOfSymbolTableEntries64()
- : getLogicalNumberOfSymbolTableEntries32();
+ const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
}
@@ -578,16 +602,20 @@ uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
XCOFF::SymbolTableEntrySize;
}
+uintptr_t XCOFFObjectFile::getSymbolEntryAddressByIndex(uint32_t Index) const {
+ return getAdvancedSymbolEntryAddress(
+ reinterpret_cast<uintptr_t>(getPointerToSymbolTable()), Index);
+}
+
Expected<StringRef>
XCOFFObjectFile::getSymbolNameByIndex(uint32_t Index) const {
- if (is64Bit())
- report_fatal_error("64-bit symbol table support not implemented yet.");
+ const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
- if (Index >= getLogicalNumberOfSymbolTableEntries32())
+ if (Index >= NumberOfSymTableEntries)
return errorCodeToError(object_error::invalid_symbol_index);
DataRefImpl SymDRI;
- SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
+ SymDRI.p = getSymbolEntryAddressByIndex(Index);
return getSymbolName(SymDRI);
}
@@ -730,20 +758,21 @@ XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
Obj->SectionHeaderTable = SecHeadersOrErr.get();
}
- // 64-bit object supports only file header and section headers for now.
- if (Obj->is64Bit())
- return std::move(Obj);
+ const uint32_t NumberOfSymbolTableEntries =
+ Obj->getNumberOfSymbolTableEntries();
// If there is no symbol table we are done parsing the memory buffer.
- if (Obj->getLogicalNumberOfSymbolTableEntries32() == 0)
+ if (NumberOfSymbolTableEntries == 0)
return std::move(Obj);
// Parse symbol table.
- CurOffset = Obj->fileHeader32()->SymbolTableOffset;
- uint64_t SymbolTableSize = (uint64_t)(sizeof(XCOFFSymbolEntry)) *
- Obj->getLogicalNumberOfSymbolTableEntries32();
+ CurOffset = Obj->is64Bit() ? Obj->getSymbolTableOffset64()
+ : Obj->getSymbolTableOffset32();
+ const uint64_t SymbolTableSize =
+ static_cast<uint64_t>(XCOFF::SymbolTableEntrySize) *
+ NumberOfSymbolTableEntries;
auto SymTableOrErr =
- getObject<XCOFFSymbolEntry>(Data, Base + CurOffset, SymbolTableSize);
+ getObject<void *>(Data, Base + CurOffset, SymbolTableSize);
if (Error E = SymTableOrErr.takeError())
return std::move(E);
Obj->SymbolTblPtr = SymTableOrErr.get();
@@ -765,74 +794,103 @@ ObjectFile::createXCOFFObjectFile(MemoryBufferRef MemBufRef,
return XCOFFObjectFile::create(FileType, MemBufRef);
}
-XCOFF::StorageClass XCOFFSymbolRef::getStorageClass() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->StorageClass;
-}
+bool XCOFFSymbolRef::isFunction() const {
+ if (!isCsectSymbol())
+ return false;
-uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
-}
+ if (getSymbolType() & FunctionSym)
+ return true;
-// TODO: The function needs to return an error if there is no csect auxiliary
-// entry.
-const XCOFFCsectAuxEnt32 *XCOFFSymbolRef::getXCOFFCsectAuxEnt32() const {
- assert(!OwningObjectPtr->is64Bit() &&
- "32-bit interface called on 64-bit object file.");
- assert(hasCsectAuxEnt() && "No Csect Auxiliary Entry is found.");
+ Expected<XCOFFCsectAuxRef> ExpCsectAuxEnt = getXCOFFCsectAuxRef();
+ if (!ExpCsectAuxEnt)
+ return false;
- // In XCOFF32, the csect auxilliary entry is always the last auxiliary
- // entry for the symbol.
- uintptr_t AuxAddr = getWithOffset(
- SymEntDataRef.p, XCOFF::SymbolTableEntrySize * getNumberOfAuxEntries());
+ const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();
-#ifndef NDEBUG
- OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
-#endif
+ // A function definition should be a label definition.
+ // FIXME: This is not necessarily the case when -ffunction-sections is
+ // enabled.
+ if (!CsectAuxRef.isLabel())
+ return false;
- return reinterpret_cast<const XCOFFCsectAuxEnt32 *>(AuxAddr);
-}
+ if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR)
+ return false;
-uint16_t XCOFFSymbolRef::getType() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SymbolType;
-}
+ const int16_t SectNum = getSectionNumber();
+ Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
+ if (!SI) {
+ // If we could not get the section, then this symbol should not be
+ // a function. So consume the error and return `false` to move on.
+ consumeError(SI.takeError());
+ return false;
+ }
-int16_t XCOFFSymbolRef::getSectionNumber() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber;
+ return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
}
-// TODO: The function name needs to be changed to express the purpose of the
-// function.
-bool XCOFFSymbolRef::hasCsectAuxEnt() const {
+bool XCOFFSymbolRef::isCsectSymbol() const {
XCOFF::StorageClass SC = getStorageClass();
return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||
SC == XCOFF::C_HIDEXT);
}
-bool XCOFFSymbolRef::isFunction() const {
- if (OwningObjectPtr->is64Bit())
- report_fatal_error("64-bit support is unimplemented yet.");
+Expected<XCOFFCsectAuxRef> XCOFFSymbolRef::getXCOFFCsectAuxRef() const {
+ assert(isCsectSymbol() &&
+ "Calling csect symbol interface with a non-csect symbol.");
- if (getType() & FunctionSym)
- return true;
+ uint8_t NumberOfAuxEntries = getNumberOfAuxEntries();
- if (!hasCsectAuxEnt())
- return false;
+ Expected<StringRef> NameOrErr = getName();
+ if (auto Err = NameOrErr.takeError())
+ return std::move(Err);
- const XCOFFCsectAuxEnt32 *CsectAuxEnt = getXCOFFCsectAuxEnt32();
+ if (!NumberOfAuxEntries) {
+ return createStringError(object_error::parse_failed,
+ "csect symbol \"" + *NameOrErr +
+ "\" contains no auxiliary entry");
+ }
- // A function definition should be a label definition.
- if ((CsectAuxEnt->SymbolAlignmentAndType & SymTypeMask) != XCOFF::XTY_LD)
- return false;
+ if (!OwningObjectPtr->is64Bit()) {
+ // In XCOFF32, the csect auxilliary entry is always the last auxiliary
+ // entry for the symbol.
+ uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+ getEntryAddress(), NumberOfAuxEntries);
+ return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt32>(AuxAddr));
+ }
- if (CsectAuxEnt->StorageMappingClass != XCOFF::XMC_PR)
- return false;
+ // XCOFF64 uses SymbolAuxType to identify the auxiliary entry type.
+ // We need to iterate through all the auxiliary entries to find it.
+ for (uint8_t Index = NumberOfAuxEntries; Index > 0; --Index) {
+ uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+ getEntryAddress(), Index);
+ if (*OwningObjectPtr->getSymbolAuxType(AuxAddr) ==
+ XCOFF::SymbolAuxType::AUX_CSECT) {
+#ifndef NDEBUG
+ OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
+#endif
+ return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt64>(AuxAddr));
+ }
+ }
- int16_t SectNum = getSectionNumber();
- Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
- if (!SI)
- return false;
+ return createStringError(
+ object_error::parse_failed,
+ "a csect auxiliary entry is not found for symbol \"" + *NameOrErr + "\"");
+}
- return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
+Expected<StringRef> XCOFFSymbolRef::getName() const {
+ // A storage class value with the high-order bit on indicates that the name is
+ // a symbolic debugger stabstring.
+ if (getStorageClass() & 0x80)
+ return StringRef("Unimplemented Debug Name");
+
+ if (Entry32) {
+ if (Entry32->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
+ return generateXCOFFFixedNameStringRef(Entry32->SymbolName);
+
+ return OwningObjectPtr->getStringTableEntry(Entry32->NameInStrTbl.Offset);
+ }
+
+ return OwningObjectPtr->getStringTableEntry(Entry64->Offset);
}
// Explictly instantiate template classes.
@@ -846,15 +904,34 @@ bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
return support::endian::read32be(Bytes.data()) == 0;
}
-TBVectorExt::TBVectorExt(StringRef TBvectorStrRef) {
+#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
+#define GETVALUEWITHMASKSHIFT(X, S) \
+ ((Data & (TracebackTable::X)) >> (TracebackTable::S))
+
+Expected<TBVectorExt> TBVectorExt::create(StringRef TBvectorStrRef) {
+ Error Err = Error::success();
+ TBVectorExt TBTVecExt(TBvectorStrRef, Err);
+ if (Err)
+ return std::move(Err);
+ return TBTVecExt;
+}
+
+TBVectorExt::TBVectorExt(StringRef TBvectorStrRef, Error &Err) {
const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
Data = support::endian::read16be(Ptr);
- VecParmsInfo = support::endian::read32be(Ptr + 2);
+ uint32_t VecParmsTypeValue = support::endian::read32be(Ptr + 2);
+ unsigned ParmsNum =
+ GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask, NumberOfVectorParmsShift);
+
+ ErrorAsOutParameter EAO(&Err);
+ Expected<SmallString<32>> VecParmsTypeOrError =
+ parseVectorParmsType(VecParmsTypeValue, ParmsNum);
+ if (!VecParmsTypeOrError)
+ Err = VecParmsTypeOrError.takeError();
+ else
+ VecParmsInfo = VecParmsTypeOrError.get();
}
-#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
-#define GETVALUEWITHMASKSHIFT(X, S) \
- ((Data & (TracebackTable::X)) >> (TracebackTable::S))
uint8_t TBVectorExt::getNumberOfVRSaved() const {
return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
}
@@ -866,6 +943,7 @@ bool TBVectorExt::isVRSavedOnStack() const {
bool TBVectorExt::hasVarArgs() const {
return GETVALUEWITHMASK(HasVarArgsMask);
}
+
uint8_t TBVectorExt::getNumberOfVectorParms() const {
return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
NumberOfVectorParmsShift);
@@ -877,72 +955,6 @@ bool TBVectorExt::hasVMXInstruction() const {
#undef GETVALUEWITHMASK
#undef GETVALUEWITHMASKSHIFT
-SmallString<32> TBVectorExt::getVectorParmsInfoString() const {
- SmallString<32> ParmsType;
- uint32_t Value = VecParmsInfo;
- for (uint8_t I = 0; I < getNumberOfVectorParms(); ++I) {
- if (I != 0)
- ParmsType += ", ";
- switch (Value & TracebackTable::ParmTypeMask) {
- case TracebackTable::ParmTypeIsVectorCharBit:
- ParmsType += "vc";
- break;
-
- case TracebackTable::ParmTypeIsVectorShortBit:
- ParmsType += "vs";
- break;
-
- case TracebackTable::ParmTypeIsVectorIntBit:
- ParmsType += "vi";
- break;
-
- case TracebackTable::ParmTypeIsVectorFloatBit:
- ParmsType += "vf";
- break;
- }
- Value <<= 2;
- }
- return ParmsType;
-}
-
-static SmallString<32> parseParmsTypeWithVecInfo(uint32_t Value,
- unsigned int ParmsNum) {
- SmallString<32> ParmsType;
- unsigned I = 0;
- bool Begin = false;
- while (I < ParmsNum || Value) {
- if (Begin)
- ParmsType += ", ";
- else
- Begin = true;
-
- switch (Value & TracebackTable::ParmTypeMask) {
- case TracebackTable::ParmTypeIsFixedBits:
- ParmsType += "i";
- ++I;
- break;
- case TracebackTable::ParmTypeIsVectorBits:
- ParmsType += "v";
- break;
- case TracebackTable::ParmTypeIsFloatingBits:
- ParmsType += "f";
- ++I;
- break;
- case TracebackTable::ParmTypeIsDoubleBits:
- ParmsType += "d";
- ++I;
- break;
- default:
- assert(false && "Unrecognized bits in ParmsType.");
- }
- Value <<= 2;
- }
- assert(I == ParmsNum &&
- "The total parameters number of fixed-point or floating-point "
- "parameters not equal to the number in the parameter type!");
- return ParmsType;
-}
-
Expected<XCOFFTracebackTable> XCOFFTracebackTable::create(const uint8_t *Ptr,
uint64_t &Size) {
Error Err = Error::success();
@@ -963,21 +975,13 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
// Skip 8 bytes of mandatory fields.
DE.getU64(Cur);
+ unsigned FixedParmsNum = getNumberOfFixedParms();
+ unsigned FloatingParmsNum = getNumberOfFPParms();
+ uint32_t ParamsTypeValue = 0;
+
// Begin to parse optional fields.
- if (Cur) {
- unsigned ParmNum = getNumberOfFixedParms() + getNumberOfFPParms();
-
- // As long as there are no "fixed-point" or floating-point parameters, this
- // field remains not present even when hasVectorInfo gives true and
- // indicates the presence of vector parameters.
- if (ParmNum > 0) {
- uint32_t ParamsTypeValue = DE.getU32(Cur);
- if (Cur)
- ParmsType = hasVectorInfo()
- ? parseParmsTypeWithVecInfo(ParamsTypeValue, ParmNum)
- : parseParmsType(ParamsTypeValue, ParmNum);
- }
- }
+ if (Cur && (FixedParmsNum + FloatingParmsNum) > 0)
+ ParamsTypeValue = DE.getU32(Cur);
if (Cur && hasTraceBackTableOffset())
TraceBackTableOffset = DE.getU32(Cur);
@@ -1006,10 +1010,35 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
if (Cur && isAllocaUsed())
AllocaRegister = DE.getU8(Cur);
+ unsigned VectorParmsNum = 0;
if (Cur && hasVectorInfo()) {
StringRef VectorExtRef = DE.getBytes(Cur, 6);
- if (Cur)
- VecExt = TBVectorExt(VectorExtRef);
+ if (Cur) {
+ Expected<TBVectorExt> TBVecExtOrErr = TBVectorExt::create(VectorExtRef);
+ if (!TBVecExtOrErr) {
+ Err = TBVecExtOrErr.takeError();
+ return;
+ }
+ VecExt = TBVecExtOrErr.get();
+ VectorParmsNum = VecExt.getValue().getNumberOfVectorParms();
+ }
+ }
+
+ // As long as there is no fixed-point or floating-point parameter, this
+ // field remains not present even when hasVectorInfo gives true and
+ // indicates the presence of vector parameters.
+ if (Cur && (FixedParmsNum + FloatingParmsNum) > 0) {
+ Expected<SmallString<32>> ParmsTypeOrError =
+ hasVectorInfo()
+ ? parseParmsTypeWithVecInfo(ParamsTypeValue, FixedParmsNum,
+ FloatingParmsNum, VectorParmsNum)
+ : parseParmsType(ParamsTypeValue, FixedParmsNum, FloatingParmsNum);
+
+ if (!ParmsTypeOrError) {
+ Err = ParmsTypeOrError.takeError();
+ return;
+ }
+ ParmsType = ParmsTypeOrError.get();
}
if (Cur && hasExtensionTable())
@@ -1017,6 +1046,7 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
if (!Cur)
Err = Cur.takeError();
+
Size = Cur.tell();
}