summaryrefslogtreecommitdiff
path: root/llvm/lib/Object
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /llvm/lib/Object
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'llvm/lib/Object')
-rw-r--r--llvm/lib/Object/Archive.cpp14
-rw-r--r--llvm/lib/Object/ArchiveWriter.cpp14
-rw-r--r--llvm/lib/Object/COFFImportFile.cpp2
-rw-r--r--llvm/lib/Object/COFFModuleDefinition.cpp8
-rw-r--r--llvm/lib/Object/COFFObjectFile.cpp573
-rw-r--r--llvm/lib/Object/ELF.cpp30
-rw-r--r--llvm/lib/Object/ELFObjectFile.cpp101
-rw-r--r--llvm/lib/Object/Error.cpp6
-rw-r--r--llvm/lib/Object/IRObjectFile.cpp3
-rw-r--r--llvm/lib/Object/IRSymtab.cpp8
-rw-r--r--llvm/lib/Object/MachOObjectFile.cpp41
-rw-r--r--llvm/lib/Object/ModuleSymbolTable.cpp8
-rw-r--r--llvm/lib/Object/ObjectFile.cpp30
-rw-r--r--llvm/lib/Object/RecordStreamer.cpp22
-rw-r--r--llvm/lib/Object/RecordStreamer.h15
-rw-r--r--llvm/lib/Object/RelocationResolver.cpp50
-rw-r--r--llvm/lib/Object/SymbolSize.cpp13
-rw-r--r--llvm/lib/Object/TapiFile.cpp22
-rw-r--r--llvm/lib/Object/TapiUniversal.cpp17
-rw-r--r--llvm/lib/Object/WasmObjectFile.cpp229
-rw-r--r--llvm/lib/Object/WindowsResource.cpp10
-rw-r--r--llvm/lib/Object/XCOFFObjectFile.cpp110
22 files changed, 787 insertions, 539 deletions
diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp
index 148c011d9cd4c..c18dd11a72ccd 100644
--- a/llvm/lib/Object/Archive.cpp
+++ b/llvm/lib/Object/Archive.cpp
@@ -392,12 +392,8 @@ Archive::Child::Child(const Archive *Parent, const char *Start, Error *Err)
}
Expected<uint64_t> Archive::Child::getSize() const {
- if (Parent->IsThin) {
- Expected<uint32_t> Size = Header.getSize();
- if (!Size)
- return Size.takeError();
- return Size.get();
- }
+ if (Parent->IsThin)
+ return Header.getSize();
return Data.size() - StartOfFile;
}
@@ -423,12 +419,12 @@ Expected<std::string> Archive::Child::getFullName() const {
return NameOrErr.takeError();
StringRef Name = *NameOrErr;
if (sys::path::is_absolute(Name))
- return Name;
+ return std::string(Name);
SmallString<128> FullName = sys::path::parent_path(
Parent->getMemoryBufferRef().getBufferIdentifier());
sys::path::append(FullName, Name);
- return StringRef(FullName);
+ return std::string(FullName.str());
}
Expected<StringRef> Archive::Child::getBuffer() const {
@@ -437,7 +433,7 @@ Expected<StringRef> Archive::Child::getBuffer() const {
return isThinOrErr.takeError();
bool isThin = isThinOrErr.get();
if (!isThin) {
- Expected<uint32_t> Size = getSize();
+ Expected<uint64_t> Size = getSize();
if (!Size)
return Size.takeError();
return StringRef(Data.data() + StartOfFile, Size.get());
diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp
index 5234b0e18233b..6f92c547164ba 100644
--- a/llvm/lib/Object/ArchiveWriter.cpp
+++ b/llvm/lib/Object/ArchiveWriter.cpp
@@ -12,6 +12,7 @@
#include "llvm/Object/ArchiveWriter.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/IR/LLVMContext.h"
@@ -263,12 +264,15 @@ static sys::TimePoint<std::chrono::seconds> now(bool Deterministic) {
}
static bool isArchiveSymbol(const object::BasicSymbolRef &S) {
- uint32_t Symflags = S.getFlags();
- if (Symflags & object::SymbolRef::SF_FormatSpecific)
+ Expected<uint32_t> SymFlagsOrErr = S.getFlags();
+ if (!SymFlagsOrErr)
+ // TODO: Actually report errors helpfully.
+ report_fatal_error(SymFlagsOrErr.takeError());
+ if (*SymFlagsOrErr & object::SymbolRef::SF_FormatSpecific)
return false;
- if (!(Symflags & object::SymbolRef::SF_Global))
+ if (!(*SymFlagsOrErr & object::SymbolRef::SF_Global))
return false;
- if (Symflags & object::SymbolRef::SF_Undefined)
+ if (*SymFlagsOrErr & object::SymbolRef::SF_Undefined)
return false;
return true;
}
@@ -545,7 +549,7 @@ Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) {
for (auto ToE = sys::path::end(PathTo); ToI != ToE; ++ToI)
sys::path::append(Relative, sys::path::Style::posix, *ToI);
- return Relative.str();
+ return std::string(Relative.str());
}
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp
index ff4a799be60c7..69bbf70b43a15 100644
--- a/llvm/lib/Object/COFFImportFile.cpp
+++ b/llvm/lib/Object/COFFImportFile.cpp
@@ -600,7 +600,7 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
: getNameType(SymbolName, E.Name,
Machine, MinGW);
Expected<std::string> Name = E.ExtName.empty()
- ? SymbolName
+ ? std::string(SymbolName)
: replace(SymbolName, E.Name, E.ExtName);
if (!Name)
diff --git a/llvm/lib/Object/COFFModuleDefinition.cpp b/llvm/lib/Object/COFFModuleDefinition.cpp
index 64d4cf0efda2d..8f29f7a658fdd 100644
--- a/llvm/lib/Object/COFFModuleDefinition.cpp
+++ b/llvm/lib/Object/COFFModuleDefinition.cpp
@@ -229,14 +229,14 @@ private:
Error parseExport() {
COFFShortExport E;
- E.Name = Tok.Value;
+ E.Name = std::string(Tok.Value);
read();
if (Tok.K == Equal) {
read();
if (Tok.K != Identifier)
return createError("identifier expected, but got " + Tok.Value);
E.ExtName = E.Name;
- E.Name = Tok.Value;
+ E.Name = std::string(Tok.Value);
} else {
unget();
}
@@ -285,7 +285,7 @@ private:
}
if (Tok.K == EqualEqual) {
read();
- E.AliasTarget = Tok.Value;
+ E.AliasTarget = std::string(Tok.Value);
if (Machine == IMAGE_FILE_MACHINE_I386 && !isDecorated(E.AliasTarget, MingwDef))
E.AliasTarget = std::string("_").append(E.AliasTarget);
continue;
@@ -315,7 +315,7 @@ private:
Error parseName(std::string *Out, uint64_t *Baseaddr) {
read();
if (Tok.K == Identifier) {
- *Out = Tok.Value;
+ *Out = std::string(Tok.Value);
} else {
*Out = "";
unget();
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 2c0f6dc2b1e9b..c26d7721b3fe9 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/COFF.h"
@@ -54,14 +55,13 @@ static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
// Returns unexpected_eof if error.
template <typename T>
-static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
- const void *Ptr,
- const uint64_t Size = sizeof(T)) {
+static Error getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr,
+ const uint64_t Size = sizeof(T)) {
uintptr_t Addr = uintptr_t(Ptr);
- if (std::error_code EC = Binary::checkOffset(M, Addr, Size))
- return EC;
+ if (Error E = Binary::checkOffset(M, Addr, Size))
+ return E;
Obj = reinterpret_cast<const T *>(Addr);
- return std::error_code();
+ return Error::success();
}
// Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
@@ -147,11 +147,7 @@ void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const {
}
Expected<StringRef> COFFObjectFile::getSymbolName(DataRefImpl Ref) const {
- COFFSymbolRef Symb = getCOFFSymbol(Ref);
- StringRef Result;
- if (std::error_code EC = getSymbolName(Symb, Result))
- return errorCodeToError(EC);
- return Result;
+ return getSymbolName(getCOFFSymbol(Ref));
}
uint64_t COFFObjectFile::getSymbolValueImpl(DataRefImpl Ref) const {
@@ -166,7 +162,7 @@ uint32_t COFFObjectFile::getSymbolAlignment(DataRefImpl Ref) const {
}
Expected<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
- uint64_t Result = getSymbolValue(Ref);
+ uint64_t Result = cantFail(getSymbolValue(Ref));
COFFSymbolRef Symb = getCOFFSymbol(Ref);
int32_t SectionNumber = Symb.getSectionNumber();
@@ -174,10 +170,10 @@ Expected<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
COFF::isReservedSectionNumber(SectionNumber))
return Result;
- const coff_section *Section = nullptr;
- if (std::error_code EC = getSection(SectionNumber, Section))
- return errorCodeToError(EC);
- Result += Section->VirtualAddress;
+ Expected<const coff_section *> Section = getSection(SectionNumber);
+ if (!Section)
+ return Section.takeError();
+ Result += (*Section)->VirtualAddress;
// The section VirtualAddress does not include ImageBase, and we want to
// return virtual addresses.
@@ -209,7 +205,7 @@ Expected<SymbolRef::Type> COFFObjectFile::getSymbolType(DataRefImpl Ref) const {
return SymbolRef::ST_Other;
}
-uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const {
+Expected<uint32_t> COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
uint32_t Result = SymbolRef::SF_None;
@@ -250,11 +246,11 @@ COFFObjectFile::getSymbolSection(DataRefImpl Ref) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
if (COFF::isReservedSectionNumber(Symb.getSectionNumber()))
return section_end();
- const coff_section *Sec = nullptr;
- if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec))
- return errorCodeToError(EC);
+ Expected<const coff_section *> Sec = getSection(Symb.getSectionNumber());
+ if (!Sec)
+ return Sec.takeError();
DataRefImpl Ret;
- Ret.p = reinterpret_cast<uintptr_t>(Sec);
+ Ret.p = reinterpret_cast<uintptr_t>(*Sec);
return section_iterator(SectionRef(Ret, this));
}
@@ -328,6 +324,12 @@ bool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const {
return (Sec->Characteristics & BssFlags) == BssFlags;
}
+// The .debug sections are the only debug sections for COFF
+// (\see MCObjectFileInfo.cpp).
+bool COFFObjectFile::isDebugSection(StringRef SectionName) const {
+ return SectionName.startswith(".debug");
+}
+
unsigned COFFObjectFile::getSectionID(SectionRef Sec) const {
uintptr_t Offset =
uintptr_t(Sec.getRawDataRefImpl().p) - uintptr_t(SectionTable);
@@ -350,9 +352,12 @@ static uint32_t getNumberOfRelocations(const coff_section *Sec,
// VirtualAddress field in the first relocation entry.
if (Sec->hasExtendedRelocations()) {
const coff_relocation *FirstReloc;
- if (getObject(FirstReloc, M, reinterpret_cast<const coff_relocation*>(
- base + Sec->PointerToRelocations)))
+ if (Error E = getObject(FirstReloc, M,
+ reinterpret_cast<const coff_relocation *>(
+ base + Sec->PointerToRelocations))) {
+ consumeError(std::move(E));
return 0;
+ }
// -1 to exclude this first relocation entry.
return FirstReloc->VirtualAddress - 1;
}
@@ -371,9 +376,11 @@ getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) {
// relocations.
begin++;
}
- if (Binary::checkOffset(M, uintptr_t(begin),
- sizeof(coff_relocation) * NumRelocs))
+ if (auto E = Binary::checkOffset(M, uintptr_t(begin),
+ sizeof(coff_relocation) * NumRelocs)) {
+ consumeError(std::move(E));
return nullptr;
+ }
return begin;
}
@@ -398,18 +405,18 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
}
// Initialize the pointer to the symbol table.
-std::error_code COFFObjectFile::initSymbolTablePtr() {
+Error COFFObjectFile::initSymbolTablePtr() {
if (COFFHeader)
- if (std::error_code EC = getObject(
+ if (Error E = getObject(
SymbolTable16, Data, base() + getPointerToSymbolTable(),
(uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
- return EC;
+ return E;
if (COFFBigObjHeader)
- if (std::error_code EC = getObject(
+ if (Error E = getObject(
SymbolTable32, Data, base() + getPointerToSymbolTable(),
(uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
- return EC;
+ return E;
// Find string table. The first four byte of the string table contains the
// total size of the string table, including the size field itself. If the
@@ -418,22 +425,21 @@ std::error_code COFFObjectFile::initSymbolTablePtr() {
getNumberOfSymbols() * getSymbolTableEntrySize();
const uint8_t *StringTableAddr = base() + StringTableOffset;
const ulittle32_t *StringTableSizePtr;
- if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
- return EC;
+ if (Error E = getObject(StringTableSizePtr, Data, StringTableAddr))
+ return E;
StringTableSize = *StringTableSizePtr;
- if (std::error_code EC =
- getObject(StringTable, Data, StringTableAddr, StringTableSize))
- return EC;
+ if (Error E = getObject(StringTable, Data, StringTableAddr, StringTableSize))
+ return E;
// Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
// tools like cvtres write a size of 0 for an empty table instead of 4.
if (StringTableSize < 4)
- StringTableSize = 4;
+ StringTableSize = 4;
// Check that the string table is null terminated if has any in it.
if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
- return object_error::parse_failed;
- return std::error_code();
+ return errorCodeToError(object_error::parse_failed);
+ return Error::success();
}
uint64_t COFFObjectFile::getImageBase() const {
@@ -446,7 +452,7 @@ uint64_t COFFObjectFile::getImageBase() const {
}
// Returns the file offset for the given VA.
-std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
+Error COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
uint64_t ImageBase = getImageBase();
uint64_t Rva = Addr - ImageBase;
assert(Rva <= UINT32_MAX);
@@ -454,7 +460,7 @@ std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
}
// Returns the file offset for the given RVA.
-std::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
+Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
for (const SectionRef &S : sections()) {
const coff_section *Section = getCOFFSection(S);
uint32_t SectionStart = Section->VirtualAddress;
@@ -462,15 +468,14 @@ std::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
if (SectionStart <= Addr && Addr < SectionEnd) {
uint32_t Offset = Addr - SectionStart;
Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
- return std::error_code();
+ return Error::success();
}
}
- return object_error::parse_failed;
+ return errorCodeToError(object_error::parse_failed);
}
-std::error_code
-COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
- ArrayRef<uint8_t> &Contents) const {
+Error COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
+ ArrayRef<uint8_t> &Contents) const {
for (const SectionRef &S : sections()) {
const coff_section *Section = getCOFFSection(S);
uint32_t SectionStart = Section->VirtualAddress;
@@ -483,196 +488,207 @@ COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
uintptr_t(base()) + Section->PointerToRawData + OffsetIntoSection;
Contents =
ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Begin), Size);
- return std::error_code();
+ return Error::success();
}
}
- return object_error::parse_failed;
+ return errorCodeToError(object_error::parse_failed);
}
// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
// table entry.
-std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
- StringRef &Name) const {
+Error COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
+ StringRef &Name) const {
uintptr_t IntPtr = 0;
- if (std::error_code EC = getRvaPtr(Rva, IntPtr))
- return EC;
+ if (Error E = getRvaPtr(Rva, IntPtr))
+ return E;
const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
- return std::error_code();
+ return Error::success();
}
-std::error_code
-COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir,
- const codeview::DebugInfo *&PDBInfo,
- StringRef &PDBFileName) const {
+Error COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir,
+ const codeview::DebugInfo *&PDBInfo,
+ StringRef &PDBFileName) const {
ArrayRef<uint8_t> InfoBytes;
- if (std::error_code EC = getRvaAndSizeAsBytes(
+ if (Error E = getRvaAndSizeAsBytes(
DebugDir->AddressOfRawData, DebugDir->SizeOfData, InfoBytes))
- return EC;
+ return E;
if (InfoBytes.size() < sizeof(*PDBInfo) + 1)
- return object_error::parse_failed;
+ return errorCodeToError(object_error::parse_failed);
PDBInfo = reinterpret_cast<const codeview::DebugInfo *>(InfoBytes.data());
InfoBytes = InfoBytes.drop_front(sizeof(*PDBInfo));
PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()),
InfoBytes.size());
// Truncate the name at the first null byte. Ignore any padding.
PDBFileName = PDBFileName.split('\0').first;
- return std::error_code();
+ return Error::success();
}
-std::error_code
-COFFObjectFile::getDebugPDBInfo(const codeview::DebugInfo *&PDBInfo,
- StringRef &PDBFileName) const {
+Error COFFObjectFile::getDebugPDBInfo(const codeview::DebugInfo *&PDBInfo,
+ StringRef &PDBFileName) const {
for (const debug_directory &D : debug_directories())
if (D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW)
return getDebugPDBInfo(&D, PDBInfo, PDBFileName);
// If we get here, there is no PDB info to return.
PDBInfo = nullptr;
PDBFileName = StringRef();
- return std::error_code();
+ return Error::success();
}
// Find the import table.
-std::error_code COFFObjectFile::initImportTablePtr() {
+Error COFFObjectFile::initImportTablePtr() {
// First, we get the RVA of the import table. If the file lacks a pointer to
// the import table, do nothing.
- const data_directory *DataEntry;
- if (getDataDirectory(COFF::IMPORT_TABLE, DataEntry))
- return std::error_code();
+ const data_directory *DataEntry = getDataDirectory(COFF::IMPORT_TABLE);
+ if (!DataEntry)
+ return Error::success();
// Do nothing if the pointer to import table is NULL.
if (DataEntry->RelativeVirtualAddress == 0)
- return std::error_code();
+ return Error::success();
uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
// 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 (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
- return EC;
- if (std::error_code EC = checkOffset(Data, IntPtr, DataEntry->Size))
- return EC;
+ if (Error E = getRvaPtr(ImportTableRva, IntPtr))
+ return E;
+ if (Error E = checkOffset(Data, IntPtr, DataEntry->Size))
+ return E;
ImportDirectory = reinterpret_cast<
const coff_import_directory_table_entry *>(IntPtr);
- return std::error_code();
+ return Error::success();
}
// Initializes DelayImportDirectory and NumberOfDelayImportDirectory.
-std::error_code COFFObjectFile::initDelayImportTablePtr() {
- const data_directory *DataEntry;
- if (getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR, DataEntry))
- return std::error_code();
+Error COFFObjectFile::initDelayImportTablePtr() {
+ const data_directory *DataEntry =
+ getDataDirectory(COFF::DELAY_IMPORT_DESCRIPTOR);
+ if (!DataEntry)
+ return Error::success();
if (DataEntry->RelativeVirtualAddress == 0)
- return std::error_code();
+ return Error::success();
uint32_t RVA = DataEntry->RelativeVirtualAddress;
NumberOfDelayImportDirectory = DataEntry->Size /
sizeof(delay_import_directory_table_entry) - 1;
uintptr_t IntPtr = 0;
- if (std::error_code EC = getRvaPtr(RVA, IntPtr))
- return EC;
+ if (Error E = getRvaPtr(RVA, IntPtr))
+ return E;
DelayImportDirectory = reinterpret_cast<
const delay_import_directory_table_entry *>(IntPtr);
- return std::error_code();
+ return Error::success();
}
// Find the export table.
-std::error_code COFFObjectFile::initExportTablePtr() {
+Error COFFObjectFile::initExportTablePtr() {
// First, we get the RVA of the export table. If the file lacks a pointer to
// the export table, do nothing.
- const data_directory *DataEntry;
- if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
- return std::error_code();
+ const data_directory *DataEntry = getDataDirectory(COFF::EXPORT_TABLE);
+ if (!DataEntry)
+ return Error::success();
// Do nothing if the pointer to export table is NULL.
if (DataEntry->RelativeVirtualAddress == 0)
- return std::error_code();
+ return Error::success();
uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
uintptr_t IntPtr = 0;
- if (std::error_code EC = getRvaPtr(ExportTableRva, IntPtr))
- return EC;
+ if (Error E = getRvaPtr(ExportTableRva, IntPtr))
+ return E;
ExportDirectory =
reinterpret_cast<const export_directory_table_entry *>(IntPtr);
- return std::error_code();
+ return Error::success();
}
-std::error_code COFFObjectFile::initBaseRelocPtr() {
- const data_directory *DataEntry;
- if (getDataDirectory(COFF::BASE_RELOCATION_TABLE, DataEntry))
- return std::error_code();
+Error COFFObjectFile::initBaseRelocPtr() {
+ const data_directory *DataEntry =
+ getDataDirectory(COFF::BASE_RELOCATION_TABLE);
+ if (!DataEntry)
+ return Error::success();
if (DataEntry->RelativeVirtualAddress == 0)
- return std::error_code();
+ return Error::success();
uintptr_t IntPtr = 0;
- if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
- return EC;
+ if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+ return E;
BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(
IntPtr);
BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(
IntPtr + DataEntry->Size);
// FIXME: Verify the section containing BaseRelocHeader has at least
// DataEntry->Size bytes after DataEntry->RelativeVirtualAddress.
- return std::error_code();
+ return Error::success();
}
-std::error_code COFFObjectFile::initDebugDirectoryPtr() {
+Error COFFObjectFile::initDebugDirectoryPtr() {
// Get the RVA of the debug directory. Do nothing if it does not exist.
- const data_directory *DataEntry;
- if (getDataDirectory(COFF::DEBUG_DIRECTORY, DataEntry))
- return std::error_code();
+ const data_directory *DataEntry = getDataDirectory(COFF::DEBUG_DIRECTORY);
+ if (!DataEntry)
+ return Error::success();
// Do nothing if the RVA is NULL.
if (DataEntry->RelativeVirtualAddress == 0)
- return std::error_code();
+ return Error::success();
// Check that the size is a multiple of the entry size.
if (DataEntry->Size % sizeof(debug_directory) != 0)
- return object_error::parse_failed;
+ return errorCodeToError(object_error::parse_failed);
uintptr_t IntPtr = 0;
- if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
- return EC;
+ if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+ return E;
DebugDirectoryBegin = reinterpret_cast<const debug_directory *>(IntPtr);
DebugDirectoryEnd = reinterpret_cast<const debug_directory *>(
IntPtr + DataEntry->Size);
// FIXME: Verify the section containing DebugDirectoryBegin has at least
// DataEntry->Size bytes after DataEntry->RelativeVirtualAddress.
- return std::error_code();
+ return Error::success();
}
-std::error_code COFFObjectFile::initLoadConfigPtr() {
+Error COFFObjectFile::initLoadConfigPtr() {
// Get the RVA of the debug directory. Do nothing if it does not exist.
- const data_directory *DataEntry;
- if (getDataDirectory(COFF::LOAD_CONFIG_TABLE, DataEntry))
- return std::error_code();
+ const data_directory *DataEntry = getDataDirectory(COFF::LOAD_CONFIG_TABLE);
+ if (!DataEntry)
+ return Error::success();
// Do nothing if the RVA is NULL.
if (DataEntry->RelativeVirtualAddress == 0)
- return std::error_code();
+ return Error::success();
uintptr_t IntPtr = 0;
- if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
- return EC;
+ if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+ return E;
LoadConfig = (const void *)IntPtr;
- return std::error_code();
+ return Error::success();
+}
+
+Expected<std::unique_ptr<COFFObjectFile>>
+COFFObjectFile::create(MemoryBufferRef Object) {
+ std::unique_ptr<COFFObjectFile> Obj(new COFFObjectFile(std::move(Object)));
+ if (Error E = Obj->initialize())
+ return std::move(E);
+ return std::move(Obj);
}
-COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
+COFFObjectFile::COFFObjectFile(MemoryBufferRef Object)
: ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
- ImportDirectory(nullptr),
- DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0),
- ExportDirectory(nullptr), BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
- DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {
+ ImportDirectory(nullptr), DelayImportDirectory(nullptr),
+ NumberOfDelayImportDirectory(0), ExportDirectory(nullptr),
+ BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
+ DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {}
+
+Error COFFObjectFile::initialize() {
// Check that we at least have enough room for a header.
+ std::error_code EC;
if (!checkSize(Data, EC, sizeof(coff_file_header)))
- return;
+ return errorCodeToError(EC);
// The current location in the file where we are looking at.
uint64_t CurPtr = 0;
@@ -690,24 +706,23 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
CurPtr = DH->AddressOfNewExeHeader;
// Check the PE magic bytes. ("PE\0\0")
if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) {
- EC = object_error::parse_failed;
- return;
+ return errorCodeToError(object_error::parse_failed);
}
CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
HasPEHeader = true;
}
}
- if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
- return;
+ if (Error E = getObject(COFFHeader, Data, base() + CurPtr))
+ return E;
// It might be a bigobj file, let's check. Note that COFF bigobj and COFF
// import libraries share a common prefix but bigobj is more restrictive.
if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN &&
COFFHeader->NumberOfSections == uint16_t(0xffff) &&
checkSize(Data, EC, sizeof(coff_bigobj_file_header))) {
- if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr)))
- return;
+ if (Error E = getObject(COFFBigObjHeader, Data, base() + CurPtr))
+ return E;
// Verify that we are dealing with bigobj.
if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion &&
@@ -727,13 +742,13 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
CurPtr += sizeof(coff_file_header);
if (COFFHeader->isImportLibrary())
- return;
+ return errorCodeToError(EC);
}
if (HasPEHeader) {
const pe32_header *Header;
- if ((EC = getObject(Header, Data, base() + CurPtr)))
- return;
+ if (Error E = getObject(Header, Data, base() + CurPtr))
+ return E;
const uint8_t *DataDirAddr;
uint64_t DataDirSize;
@@ -747,23 +762,27 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
} else {
// It's neither PE32 nor PE32+.
- EC = object_error::parse_failed;
- return;
+ return errorCodeToError(object_error::parse_failed);
}
- if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
- return;
+ if (Error E = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))
+ return E;
}
if (COFFHeader)
CurPtr += COFFHeader->SizeOfOptionalHeader;
- if ((EC = getObject(SectionTable, Data, base() + CurPtr,
- (uint64_t)getNumberOfSections() * sizeof(coff_section))))
- return;
+ assert(COFFHeader || COFFBigObjHeader);
+
+ if (Error E =
+ getObject(SectionTable, Data, base() + CurPtr,
+ (uint64_t)getNumberOfSections() * sizeof(coff_section)))
+ return E;
// Initialize the pointer to the symbol table.
if (getPointerToSymbolTable() != 0) {
- if ((EC = initSymbolTablePtr())) {
+ if (Error E = initSymbolTablePtr()) {
+ // Recover from errors reading the symbol table.
+ consumeError(std::move(E));
SymbolTable16 = nullptr;
SymbolTable32 = nullptr;
StringTable = nullptr;
@@ -772,33 +791,32 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
} else {
// We had better not have any symbols if we don't have a symbol table.
if (getNumberOfSymbols() != 0) {
- EC = object_error::parse_failed;
- return;
+ return errorCodeToError(object_error::parse_failed);
}
}
// Initialize the pointer to the beginning of the import table.
- if ((EC = initImportTablePtr()))
- return;
- if ((EC = initDelayImportTablePtr()))
- return;
+ if (Error E = initImportTablePtr())
+ return E;
+ if (Error E = initDelayImportTablePtr())
+ return E;
// Initialize the pointer to the export table.
- if ((EC = initExportTablePtr()))
- return;
+ if (Error E = initExportTablePtr())
+ return E;
// Initialize the pointer to the base relocation table.
- if ((EC = initBaseRelocPtr()))
- return;
+ if (Error E = initBaseRelocPtr())
+ return E;
// Initialize the pointer to the export table.
- if ((EC = initDebugDirectoryPtr()))
- return;
+ if (Error E = initDebugDirectoryPtr())
+ return E;
- if ((EC = initLoadConfigPtr()))
- return;
+ if (Error E = initLoadConfigPtr())
+ return E;
- EC = std::error_code();
+ return Error::success();
}
basic_symbol_iterator COFFObjectFile::symbol_begin() const {
@@ -936,86 +954,54 @@ iterator_range<base_reloc_iterator> COFFObjectFile::base_relocs() const {
return make_range(base_reloc_begin(), base_reloc_end());
}
-std::error_code
-COFFObjectFile::getDataDirectory(uint32_t Index,
- const data_directory *&Res) const {
- // Error if there's no data directory or the index is out of range.
- if (!DataDirectory) {
- Res = nullptr;
- return object_error::parse_failed;
- }
+const data_directory *COFFObjectFile::getDataDirectory(uint32_t Index) const {
+ if (!DataDirectory)
+ return nullptr;
assert(PE32Header || PE32PlusHeader);
uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize
: PE32PlusHeader->NumberOfRvaAndSize;
- if (Index >= NumEnt) {
- Res = nullptr;
- return object_error::parse_failed;
- }
- Res = &DataDirectory[Index];
- return std::error_code();
+ if (Index >= NumEnt)
+ return nullptr;
+ return &DataDirectory[Index];
}
-std::error_code COFFObjectFile::getSection(int32_t Index,
- const coff_section *&Result) const {
- Result = nullptr;
+Expected<const coff_section *> COFFObjectFile::getSection(int32_t Index) const {
+ // Perhaps getting the section of a reserved section index should be an error,
+ // but callers rely on this to return null.
if (COFF::isReservedSectionNumber(Index))
- return std::error_code();
+ return (const coff_section *)nullptr;
if (static_cast<uint32_t>(Index) <= getNumberOfSections()) {
// We already verified the section table data, so no need to check again.
- Result = SectionTable + (Index - 1);
- return std::error_code();
- }
- return object_error::parse_failed;
-}
-
-std::error_code COFFObjectFile::getSection(StringRef SectionName,
- const coff_section *&Result) const {
- Result = nullptr;
- for (const SectionRef &Section : sections()) {
- auto NameOrErr = Section.getName();
- if (!NameOrErr)
- return errorToErrorCode(NameOrErr.takeError());
-
- if (*NameOrErr == SectionName) {
- Result = getCOFFSection(Section);
- return std::error_code();
- }
+ return SectionTable + (Index - 1);
}
- return object_error::parse_failed;
+ return errorCodeToError(object_error::parse_failed);
}
-std::error_code COFFObjectFile::getString(uint32_t Offset,
- StringRef &Result) const {
+Expected<StringRef> COFFObjectFile::getString(uint32_t Offset) const {
if (StringTableSize <= 4)
// Tried to get a string from an empty string table.
- return object_error::parse_failed;
+ return errorCodeToError(object_error::parse_failed);
if (Offset >= StringTableSize)
- return object_error::unexpected_eof;
- Result = StringRef(StringTable + Offset);
- return std::error_code();
+ return errorCodeToError(object_error::unexpected_eof);
+ return StringRef(StringTable + Offset);
}
-std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol,
- StringRef &Res) const {
- return getSymbolName(Symbol.getGeneric(), Res);
+Expected<StringRef> COFFObjectFile::getSymbolName(COFFSymbolRef Symbol) const {
+ return getSymbolName(Symbol.getGeneric());
}
-std::error_code COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol,
- StringRef &Res) const {
+Expected<StringRef>
+COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol) const {
// Check for string table entry. First 4 bytes are 0.
- if (Symbol->Name.Offset.Zeroes == 0) {
- if (std::error_code EC = getString(Symbol->Name.Offset.Offset, Res))
- return EC;
- return std::error_code();
- }
+ if (Symbol->Name.Offset.Zeroes == 0)
+ return getString(Symbol->Name.Offset.Offset);
+ // Null terminated, let ::strlen figure out the length.
if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0)
- // Null terminated, let ::strlen figure out the length.
- Res = StringRef(Symbol->Name.ShortName);
- else
- // Not null terminated, use all 8 bytes.
- Res = StringRef(Symbol->Name.ShortName, COFF::NameSize);
- return std::error_code();
+ return StringRef(Symbol->Name.ShortName);
+
+ // Not null terminated, use all 8 bytes.
+ return StringRef(Symbol->Name.ShortName, COFF::NameSize);
}
ArrayRef<uint8_t>
@@ -1067,14 +1053,13 @@ COFFObjectFile::getSectionName(const coff_section *Sec) const {
if (Name.startswith("//")) {
if (decodeBase64StringEntry(Name.substr(2), Offset))
return createStringError(object_error::parse_failed,
- "inalid section name");
+ "invalid section name");
} else {
if (Name.substr(1).getAsInteger(10, Offset))
return createStringError(object_error::parse_failed,
"invalid section name");
}
- if (std::error_code EC = getString(Offset, Name))
- return errorCodeToError(EC);
+ return getString(Offset);
}
return Name;
@@ -1107,8 +1092,8 @@ Error COFFObjectFile::getSectionContents(const coff_section *Sec,
// data, as there's nothing that says that is not allowed.
uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
uint32_t SectionSize = getSectionSize(Sec);
- if (checkOffset(Data, ConStart, SectionSize))
- return make_error<BinaryError>();
+ if (Error E = checkOffset(Data, ConStart, SectionSize))
+ return E;
Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);
return Error::success();
}
@@ -1304,7 +1289,7 @@ void ImportDirectoryEntryRef::moveNext() {
}
}
-std::error_code ImportDirectoryEntryRef::getImportTableEntry(
+Error ImportDirectoryEntryRef::getImportTableEntry(
const coff_import_directory_table_entry *&Result) const {
return getObject(Result, OwningObject->Data, ImportTable + Index);
}
@@ -1323,14 +1308,16 @@ makeImportedSymbolIterator(const COFFObjectFile *Object,
static imported_symbol_iterator
importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object) {
uintptr_t IntPtr = 0;
- Object->getRvaPtr(RVA, IntPtr);
+ // FIXME: Handle errors.
+ cantFail(Object->getRvaPtr(RVA, IntPtr));
return makeImportedSymbolIterator(Object, IntPtr, 0);
}
static imported_symbol_iterator
importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object) {
uintptr_t IntPtr = 0;
- Object->getRvaPtr(RVA, IntPtr);
+ // FIXME: Handle errors.
+ cantFail(Object->getRvaPtr(RVA, IntPtr));
// Forward the pointer to the last entry which is null.
int Index = 0;
if (Object->getBytesInAddress() == 4) {
@@ -1377,25 +1364,24 @@ ImportDirectoryEntryRef::lookup_table_symbols() const {
return make_range(lookup_table_begin(), lookup_table_end());
}
-std::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const {
+Error ImportDirectoryEntryRef::getName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (std::error_code EC =
- OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
- return EC;
+ if (Error E = OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr))
+ return E;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
- return std::error_code();
+ return Error::success();
}
-std::error_code
+Error
ImportDirectoryEntryRef::getImportLookupTableRVA(uint32_t &Result) const {
Result = ImportTable[Index].ImportLookupTableRVA;
- return std::error_code();
+ return Error::success();
}
-std::error_code
-ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const {
+Error ImportDirectoryEntryRef::getImportAddressTableRVA(
+ uint32_t &Result) const {
Result = ImportTable[Index].ImportAddressTableRVA;
- return std::error_code();
+ return Error::success();
}
bool DelayImportDirectoryEntryRef::
@@ -1424,32 +1410,32 @@ DelayImportDirectoryEntryRef::imported_symbols() const {
return make_range(imported_symbol_begin(), imported_symbol_end());
}
-std::error_code DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
+Error DelayImportDirectoryEntryRef::getName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (std::error_code EC = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
- return EC;
+ if (Error E = OwningObject->getRvaPtr(Table[Index].Name, IntPtr))
+ return E;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
- return std::error_code();
+ return Error::success();
}
-std::error_code DelayImportDirectoryEntryRef::
-getDelayImportTable(const delay_import_directory_table_entry *&Result) const {
+Error DelayImportDirectoryEntryRef::getDelayImportTable(
+ const delay_import_directory_table_entry *&Result) const {
Result = &Table[Index];
- return std::error_code();
+ return Error::success();
}
-std::error_code DelayImportDirectoryEntryRef::
-getImportAddress(int AddrIndex, uint64_t &Result) const {
+Error DelayImportDirectoryEntryRef::getImportAddress(int AddrIndex,
+ uint64_t &Result) const {
uint32_t RVA = Table[Index].DelayImportAddressTable +
AddrIndex * (OwningObject->is64() ? 8 : 4);
uintptr_t IntPtr = 0;
- if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
- return EC;
+ if (Error E = OwningObject->getRvaPtr(RVA, IntPtr))
+ return E;
if (OwningObject->is64())
Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);
else
Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);
- return std::error_code();
+ return Error::success();
}
bool ExportDirectoryEntryRef::
@@ -1463,46 +1449,44 @@ void ExportDirectoryEntryRef::moveNext() {
// Returns the name of the current export symbol. If the symbol is exported only
// by ordinal, the empty string is set as a result.
-std::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
+Error ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (std::error_code EC =
- OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
- return EC;
+ if (Error E = OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
+ return E;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
- return std::error_code();
+ return Error::success();
}
// Returns the starting ordinal number.
-std::error_code
-ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
+Error ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
Result = ExportTable->OrdinalBase;
- return std::error_code();
+ return Error::success();
}
// Returns the export ordinal of the current export symbol.
-std::error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
+Error ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
Result = ExportTable->OrdinalBase + Index;
- return std::error_code();
+ return Error::success();
}
// Returns the address of the current export symbol.
-std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
+Error ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
uintptr_t IntPtr = 0;
- if (std::error_code EC =
+ if (Error EC =
OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
return EC;
const export_address_table_entry *entry =
reinterpret_cast<const export_address_table_entry *>(IntPtr);
Result = entry[Index].ExportRVA;
- return std::error_code();
+ return Error::success();
}
// Returns the name of the current export symbol. If the symbol is exported only
// by ordinal, the empty string is set as a result.
-std::error_code
+Error
ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (std::error_code EC =
+ if (Error EC =
OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr))
return EC;
const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
@@ -1513,33 +1497,34 @@ ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
I < E; ++I, ++Offset) {
if (*I != Index)
continue;
- if (std::error_code EC =
+ if (Error EC =
OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr))
return EC;
const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
- if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
+ if (Error EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
return EC;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
- return std::error_code();
+ return Error::success();
}
Result = "";
- return std::error_code();
+ return Error::success();
}
-std::error_code ExportDirectoryEntryRef::isForwarder(bool &Result) const {
- const data_directory *DataEntry;
- if (auto EC = OwningObject->getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
- return EC;
+Error ExportDirectoryEntryRef::isForwarder(bool &Result) const {
+ const data_directory *DataEntry =
+ OwningObject->getDataDirectory(COFF::EXPORT_TABLE);
+ if (!DataEntry)
+ return errorCodeToError(object_error::parse_failed);
uint32_t RVA;
if (auto EC = getExportRVA(RVA))
return EC;
uint32_t Begin = DataEntry->RelativeVirtualAddress;
uint32_t End = DataEntry->RelativeVirtualAddress + DataEntry->Size;
Result = (Begin <= RVA && RVA < End);
- return std::error_code();
+ return Error::success();
}
-std::error_code ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
+Error ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
uint32_t RVA;
if (auto EC = getExportRVA(RVA))
return EC;
@@ -1547,7 +1532,7 @@ std::error_code ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr))
return EC;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
- return std::error_code();
+ return Error::success();
}
bool ImportedSymbolRef::
@@ -1560,72 +1545,67 @@ void ImportedSymbolRef::moveNext() {
++Index;
}
-std::error_code
-ImportedSymbolRef::getSymbolName(StringRef &Result) const {
+Error ImportedSymbolRef::getSymbolName(StringRef &Result) const {
uint32_t RVA;
if (Entry32) {
// If a symbol is imported only by ordinal, it has no name.
if (Entry32[Index].isOrdinal())
- return std::error_code();
+ return Error::success();
RVA = Entry32[Index].getHintNameRVA();
} else {
if (Entry64[Index].isOrdinal())
- return std::error_code();
+ return Error::success();
RVA = Entry64[Index].getHintNameRVA();
}
uintptr_t IntPtr = 0;
- if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
+ if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr))
return EC;
// +2 because the first two bytes is hint.
Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));
- return std::error_code();
+ return Error::success();
}
-std::error_code ImportedSymbolRef::isOrdinal(bool &Result) const {
+Error ImportedSymbolRef::isOrdinal(bool &Result) const {
if (Entry32)
Result = Entry32[Index].isOrdinal();
else
Result = Entry64[Index].isOrdinal();
- return std::error_code();
+ return Error::success();
}
-std::error_code ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
+Error ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
if (Entry32)
Result = Entry32[Index].getHintNameRVA();
else
Result = Entry64[Index].getHintNameRVA();
- return std::error_code();
+ return Error::success();
}
-std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
+Error ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
uint32_t RVA;
if (Entry32) {
if (Entry32[Index].isOrdinal()) {
Result = Entry32[Index].getOrdinal();
- return std::error_code();
+ return Error::success();
}
RVA = Entry32[Index].getHintNameRVA();
} else {
if (Entry64[Index].isOrdinal()) {
Result = Entry64[Index].getOrdinal();
- return std::error_code();
+ return Error::success();
}
RVA = Entry64[Index].getHintNameRVA();
}
uintptr_t IntPtr = 0;
- if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
+ if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr))
return EC;
Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);
- return std::error_code();
+ return Error::success();
}
Expected<std::unique_ptr<COFFObjectFile>>
ObjectFile::createCOFFObjectFile(MemoryBufferRef Object) {
- std::error_code EC;
- std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC));
- if (EC)
- return errorCodeToError(EC);
- return std::move(Ret);
+ return COFFObjectFile::create(Object);
}
bool BaseRelocRef::operator==(const BaseRelocRef &Other) const {
@@ -1650,16 +1630,16 @@ void BaseRelocRef::moveNext() {
}
}
-std::error_code BaseRelocRef::getType(uint8_t &Type) const {
+Error BaseRelocRef::getType(uint8_t &Type) const {
auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
Type = Entry[Index].getType();
- return std::error_code();
+ return Error::success();
}
-std::error_code BaseRelocRef::getRVA(uint32_t &Result) const {
+Error BaseRelocRef::getRVA(uint32_t &Result) const {
auto *Entry = reinterpret_cast<const coff_base_reloc_block_entry *>(Header + 1);
Result = Header->PageRVA + Entry[Index].getOffset();
- return std::error_code();
+ return Error::success();
}
#define RETURN_IF_ERROR(Expr) \
@@ -1823,15 +1803,16 @@ ResourceSectionRef::getContents(const coff_resource_data_entry &Entry) {
Expected<COFFSymbolRef> Sym = Obj->getSymbol(R.SymbolTableIndex);
if (!Sym)
return Sym.takeError();
- const coff_section *Section = nullptr;
// And the symbol's section
- if (std::error_code EC = Obj->getSection(Sym->getSectionNumber(), Section))
- return errorCodeToError(EC);
+ Expected<const coff_section *> Section =
+ Obj->getSection(Sym->getSectionNumber());
+ if (!Section)
+ return Section.takeError();
// Add the initial value of DataRVA to the symbol's offset to find the
// data it points at.
uint64_t Offset = Entry.DataRVA + Sym->getValue();
ArrayRef<uint8_t> Contents;
- if (Error E = Obj->getSectionContents(Section, Contents))
+ if (Error E = Obj->getSectionContents(*Section, Contents))
return std::move(E);
if (Offset + Entry.DataSize > Contents.size())
return createStringError(object_error::parse_failed,
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index f17a6da23d7d3..2515695095a1c 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -145,6 +145,13 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
break;
}
break;
+ case ELF::EM_VE:
+ switch (Type) {
+#include "llvm/BinaryFormat/ELFRelocs/VE.def"
+ default:
+ break;
+ }
+ break;
default:
break;
}
@@ -223,6 +230,9 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
}
break;
+ case ELF::EM_RISCV:
+ switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_RISCV_ATTRIBUTES); }
+ break;
default:
break;
}
@@ -499,7 +509,6 @@ std::string ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const {
template <class ELFT>
Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
ArrayRef<Elf_Dyn> Dyn;
- size_t DynSecSize = 0;
auto ProgramHeadersOrError = program_headers();
if (!ProgramHeadersOrError)
@@ -510,7 +519,6 @@ Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
Dyn = makeArrayRef(
reinterpret_cast<const Elf_Dyn *>(base() + Phdr.p_offset),
Phdr.p_filesz / sizeof(Elf_Dyn));
- DynSecSize = Phdr.p_filesz;
break;
}
}
@@ -529,7 +537,6 @@ Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
if (!DynOrError)
return DynOrError.takeError();
Dyn = *DynOrError;
- DynSecSize = Sec.sh_size;
break;
}
}
@@ -542,10 +549,6 @@ Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
// TODO: this error is untested.
return createError("invalid empty dynamic section");
- if (DynSecSize % sizeof(Elf_Dyn) != 0)
- // TODO: this error is untested.
- return createError("malformed dynamic section");
-
if (Dyn.back().d_tag != ELF::DT_NULL)
// TODO: this error is untested.
return createError("dynamic sections must be DT_NULL terminated");
@@ -580,7 +583,18 @@ Expected<const uint8_t *> ELFFile<ELFT>::toMappedAddr(uint64_t VAddr) const {
if (Delta >= Phdr.p_filesz)
return createError("virtual address is not in any segment: 0x" +
Twine::utohexstr(VAddr));
- return base() + Phdr.p_offset + Delta;
+
+ uint64_t Offset = Phdr.p_offset + Delta;
+ if (Offset >= getBufSize())
+ return createError("can't map virtual address 0x" +
+ Twine::utohexstr(VAddr) + " to the segment with index " +
+ Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +
+ ": the segment ends at 0x" +
+ Twine::utohexstr(Phdr.p_offset + Phdr.p_filesz) +
+ ", which is greater than the file size (0x" +
+ Twine::utohexstr(getBufSize()) + ")");
+
+ return base() + Offset;
}
template class llvm::object::ELFFile<ELF32LE>;
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index bf6ffd6c37b95..c919d25855d24 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -23,6 +23,8 @@
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/RISCVAttributeParser.h"
+#include "llvm/Support/RISCVAttributes.h"
#include "llvm/Support/TargetRegistry.h"
#include <algorithm>
#include <cstddef>
@@ -157,17 +159,21 @@ SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const {
SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
SubtargetFeatures Features;
ARMAttributeParser Attributes;
- if (Error E = getBuildAttributes(Attributes))
+ if (Error E = getBuildAttributes(Attributes)) {
+ consumeError(std::move(E));
return SubtargetFeatures();
+ }
// both ARMv7-M and R have to support thumb hardware div
bool isV7 = false;
- if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
- isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)
- == ARMBuildAttrs::v7;
-
- if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch_profile)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile)) {
+ Optional<unsigned> Attr =
+ Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
+ if (Attr.hasValue())
+ isV7 = Attr.getValue() == ARMBuildAttrs::v7;
+
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
case ARMBuildAttrs::ApplicationProfile:
Features.AddFeature("aclass");
break;
@@ -184,8 +190,9 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
default:
break;
case ARMBuildAttrs::Not_Allowed:
@@ -198,8 +205,9 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
default:
break;
case ARMBuildAttrs::Not_Allowed:
@@ -221,8 +229,9 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- if (Attributes.hasAttribute(ARMBuildAttrs::Advanced_SIMD_arch)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
default:
break;
case ARMBuildAttrs::Not_Allowed:
@@ -239,8 +248,9 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- if (Attributes.hasAttribute(ARMBuildAttrs::MVE_arch)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
default:
break;
case ARMBuildAttrs::Not_Allowed:
@@ -257,8 +267,9 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {
+ Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
default:
break;
case ARMBuildAttrs::DisallowDIV:
@@ -283,6 +294,51 @@ SubtargetFeatures ELFObjectFileBase::getRISCVFeatures() const {
Features.AddFeature("c");
}
+ // Add features according to the ELF attribute section.
+ // If there are any unrecognized features, ignore them.
+ RISCVAttributeParser Attributes;
+ if (Error E = getBuildAttributes(Attributes)) {
+ // TODO Propagate Error.
+ consumeError(std::move(E));
+ return Features; // Keep "c" feature if there is one in PlatformFlags.
+ }
+
+ Optional<StringRef> Attr = Attributes.getAttributeString(RISCVAttrs::ARCH);
+ if (Attr.hasValue()) {
+ // 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();
+ if (Arch.consume_front("rv32"))
+ Features.AddFeature("64bit", false);
+ else if (Arch.consume_front("rv64"))
+ Features.AddFeature("64bit");
+
+ while (!Arch.empty()) {
+ switch (Arch[0]) {
+ default:
+ break; // Ignore unexpected features.
+ case 'i':
+ Features.AddFeature("e", false);
+ break;
+ case 'd':
+ Features.AddFeature("f"); // D-ext will imply F-ext.
+ LLVM_FALLTHROUGH;
+ case 'e':
+ case 'm':
+ case 'a':
+ case 'f':
+ case 'c':
+ Features.AddFeature(Arch.take_front());
+ break;
+ }
+
+ // FIXME: Handle version numbers.
+ Arch = Arch.drop_until([](char c) { return c == '_' || c == '\0'; });
+ Arch = Arch.drop_while([](char c) { return c == '_'; });
+ }
+ }
+
return Features;
}
@@ -305,8 +361,11 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
return;
ARMAttributeParser Attributes;
- if (Error E = getBuildAttributes(Attributes))
+ if (Error E = getBuildAttributes(Attributes)) {
+ // TODO Propagate Error.
+ consumeError(std::move(E));
return;
+ }
std::string Triple;
// Default to ARM, but use the triple if it's been set.
@@ -315,8 +374,10 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
else
Triple = "arm";
- if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
- switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
+ Optional<unsigned> Attr =
+ Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
+ if (Attr.hasValue()) {
+ switch (Attr.getValue()) {
case ARMBuildAttrs::v4:
Triple += "v4";
break;
diff --git a/llvm/lib/Object/Error.cpp b/llvm/lib/Object/Error.cpp
index 010c5b42dac25..bc75bc6c0445c 100644
--- a/llvm/lib/Object/Error.cpp
+++ b/llvm/lib/Object/Error.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/Error.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
@@ -60,9 +61,10 @@ void BinaryError::anchor() {}
char BinaryError::ID = 0;
char GenericBinaryError::ID = 0;
-GenericBinaryError::GenericBinaryError(Twine Msg) : Msg(Msg.str()) {}
+GenericBinaryError::GenericBinaryError(const Twine &Msg) : Msg(Msg.str()) {}
-GenericBinaryError::GenericBinaryError(Twine Msg, object_error ECOverride)
+GenericBinaryError::GenericBinaryError(const Twine &Msg,
+ object_error ECOverride)
: Msg(Msg.str()) {
setErrorCode(make_error_code(ECOverride));
}
diff --git a/llvm/lib/Object/IRObjectFile.cpp b/llvm/lib/Object/IRObjectFile.cpp
index 636f1521262fd..befba5d57127b 100644
--- a/llvm/lib/Object/IRObjectFile.cpp
+++ b/llvm/lib/Object/IRObjectFile.cpp
@@ -47,7 +47,7 @@ Error IRObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const {
return Error::success();
}
-uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
+Expected<uint32_t> IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
return SymTab.getSymbolFlags(getSym(Symb));
}
@@ -94,6 +94,7 @@ IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
return Object;
case file_magic::elf_relocatable:
case file_magic::macho_object:
+ case file_magic::wasm_object:
case file_magic::coff_object: {
Expected<std::unique_ptr<ObjectFile>> ObjFile =
ObjectFile::createObjectFile(Object, Type);
diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp
index e4282b9d6bd32..e39cb732add10 100644
--- a/llvm/lib/Object/IRSymtab.cpp
+++ b/llvm/lib/Object/IRSymtab.cpp
@@ -181,7 +181,7 @@ Expected<int> Builder::getComdatIndex(const Comdat *C, const Module *M) {
llvm::raw_string_ostream OS(Name);
Mang.getNameWithPrefix(OS, GV, false);
} else {
- Name = C->getName();
+ Name = std::string(C->getName());
}
storage::Comdat Comdat;
@@ -264,9 +264,13 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
Sym.Flags |= unsigned(GV->getVisibility()) << storage::Symbol::FB_visibility;
if (Flags & object::BasicSymbolRef::SF_Common) {
+ auto *GVar = dyn_cast<GlobalVariable>(GV);
+ if (!GVar)
+ return make_error<StringError>("Only variables can have common linkage!",
+ inconvertibleErrorCode());
Uncommon().CommonSize = GV->getParent()->getDataLayout().getTypeAllocSize(
GV->getType()->getElementType());
- Uncommon().CommonAlign = GV->getAlignment();
+ Uncommon().CommonAlign = GVar->getAlignment();
}
const GlobalObject *Base = GV->getBaseObject();
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index 8540b7ab03cdf..4d85e6f40ec41 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -1804,8 +1804,8 @@ Expected<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
}
uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const {
- uint32_t flags = getSymbolFlags(DRI);
- if (flags & SymbolRef::SF_Common) {
+ uint32_t Flags = cantFail(getSymbolFlags(DRI));
+ if (Flags & SymbolRef::SF_Common) {
MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
}
@@ -1840,7 +1840,7 @@ MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
return SymbolRef::ST_Other;
}
-uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
+Expected<uint32_t> MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI);
uint8_t MachOType = Entry.n_type;
@@ -2030,6 +2030,11 @@ bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const {
SectionType == MachO::S_GB_ZEROFILL);
}
+bool MachOObjectFile::isDebugSection(StringRef SectionName) const {
+ return SectionName.startswith("__debug") ||
+ SectionName.startswith("__zdebug") || SectionName == "__gdb_index";
+}
+
unsigned MachOObjectFile::getSectionID(SectionRef Sec) const {
return Sec.getRawDataRefImpl().d.a;
}
@@ -3214,6 +3219,7 @@ void MachORebaseEntry::moveNext() {
SegmentOffset) << "\n");
break;
case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
+ SegmentOffset += ImmValue * PointerSize;
error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
PointerSize);
if (error) {
@@ -3223,18 +3229,6 @@ void MachORebaseEntry::moveNext() {
moveToEnd();
return;
}
- SegmentOffset += ImmValue * PointerSize;
- error = O->RebaseEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
- PointerSize);
- if (error) {
- *E =
- malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED "
- " (after adding immediate times the pointer size) " +
- Twine(error) + " for opcode at: 0x" +
- Twine::utohexstr(OpcodeStart - Opcodes.begin()));
- moveToEnd();
- return;
- }
DEBUG_WITH_TYPE("mach-o-rebase",
dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: "
<< format("SegmentOffset=0x%06X",
@@ -3803,15 +3797,6 @@ void MachOBindEntry::moveNext() {
moveToEnd();
return;
}
- error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset,
- PointerSize);
- if (error) {
- *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
- Twine(error) + " for opcode at: 0x" +
- Twine::utohexstr(OpcodeStart - Opcodes.begin()));
- moveToEnd();
- return;
- }
if (SymbolName == StringRef()) {
*E = malformedError(
"for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
@@ -3835,11 +3820,9 @@ void MachOBindEntry::moveNext() {
error = O->BindEntryCheckSegAndOffsets(SegmentIndex, SegmentOffset +
AdvanceAmount, PointerSize);
if (error) {
- *E =
- malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED "
- " (after adding immediate times the pointer size) " +
- Twine(error) + " for opcode at: 0x" +
- Twine::utohexstr(OpcodeStart - Opcodes.begin()));
+ *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " +
+ Twine(error) + " for opcode at: 0x" +
+ Twine::utohexstr(OpcodeStart - Opcodes.begin()));
moveToEnd();
return;
}
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp
index 17ac4afda2d64..7f3055b5dcfab 100644
--- a/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -23,6 +23,7 @@
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
@@ -63,7 +64,8 @@ void ModuleSymbolTable::addModule(Module *M) {
SymTab.push_back(&GV);
CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) {
- SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags));
+ SymTab.push_back(new (AsmSymbols.Allocate())
+ AsmSymbol(std::string(Name), Flags));
});
}
@@ -115,6 +117,10 @@ initializeRecordStreamer(const Module &M,
if (!TAP)
return;
+ // Module-level inline asm is assumed to use At&t syntax (see
+ // AsmPrinter::doInitialization()).
+ Parser->setAssemblerDialect(InlineAsm::AD_ATT);
+
Parser->setTargetParser(*TAP);
if (Parser->Run(false))
return;
diff --git a/llvm/lib/Object/ObjectFile.cpp b/llvm/lib/Object/ObjectFile.cpp
index 098b3d8f8dd05..61b36ea0f448a 100644
--- a/llvm/lib/Object/ObjectFile.cpp
+++ b/llvm/lib/Object/ObjectFile.cpp
@@ -54,12 +54,15 @@ bool SectionRef::containsSymbol(SymbolRef S) const {
return *this == **SymSec;
}
-uint64_t ObjectFile::getSymbolValue(DataRefImpl Ref) const {
- uint32_t Flags = getSymbolFlags(Ref);
- if (Flags & SymbolRef::SF_Undefined)
- return 0;
- if (Flags & SymbolRef::SF_Common)
- return getCommonSymbolSize(Ref);
+Expected<uint64_t> ObjectFile::getSymbolValue(DataRefImpl Ref) const {
+ if (Expected<uint32_t> FlagsOrErr = getSymbolFlags(Ref)) {
+ if (*FlagsOrErr & SymbolRef::SF_Undefined)
+ return 0;
+ if (*FlagsOrErr & SymbolRef::SF_Common)
+ return getCommonSymbolSize(Ref);
+ } else
+ // TODO: Test this error.
+ return FlagsOrErr.takeError();
return getSymbolValueImpl(Ref);
}
@@ -91,6 +94,10 @@ bool ObjectFile::isBerkeleyData(DataRefImpl Sec) const {
return isSectionData(Sec);
}
+bool ObjectFile::isDebugSection(StringRef SectionName) const {
+ return false;
+}
+
Expected<section_iterator>
ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
return section_iterator(SectionRef(Sec, this));
@@ -108,14 +115,17 @@ Triple ObjectFile::makeTriple() const {
setARMSubArch(TheTriple);
// TheTriple defaults to ELF, and COFF doesn't have an environment:
- // the best we can do here is indicate that it is mach-o.
- if (isMachO())
+ // something we can do here is indicate that it is mach-o.
+ if (isMachO()) {
TheTriple.setObjectFormat(Triple::MachO);
-
- if (isCOFF()) {
+ } else if (isCOFF()) {
const auto COFFObj = cast<COFFObjectFile>(this);
if (COFFObj->getArch() == Triple::thumb)
TheTriple.setTriple("thumbv7-windows");
+ } else if (isXCOFF()) {
+ // XCOFF implies AIX.
+ TheTriple.setOS(Triple::AIX);
+ TheTriple.setObjectFormat(Triple::XCOFF);
}
return TheTriple;
diff --git a/llvm/lib/Object/RecordStreamer.cpp b/llvm/lib/Object/RecordStreamer.cpp
index f39a6c28ed50c..b2f973eff3614 100644
--- a/llvm/lib/Object/RecordStreamer.cpp
+++ b/llvm/lib/Object/RecordStreamer.cpp
@@ -81,22 +81,22 @@ RecordStreamer::const_iterator RecordStreamer::begin() {
RecordStreamer::const_iterator RecordStreamer::end() { return Symbols.end(); }
-void RecordStreamer::EmitInstruction(const MCInst &Inst,
+void RecordStreamer::emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) {
- MCStreamer::EmitInstruction(Inst, STI);
+ MCStreamer::emitInstruction(Inst, STI);
}
-void RecordStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
- MCStreamer::EmitLabel(Symbol);
+void RecordStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCStreamer::emitLabel(Symbol);
markDefined(*Symbol);
}
-void RecordStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
+void RecordStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
markDefined(*Symbol);
- MCStreamer::EmitAssignment(Symbol, Value);
+ MCStreamer::emitAssignment(Symbol, Value);
}
-bool RecordStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
+bool RecordStreamer::emitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) {
if (Attribute == MCSA_Global || Attribute == MCSA_Weak)
markGlobal(*Symbol, Attribute);
@@ -105,13 +105,13 @@ bool RecordStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
return true;
}
-void RecordStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
+void RecordStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment,
SMLoc Loc) {
markDefined(*Symbol);
}
-void RecordStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+void RecordStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
markDefined(*Symbol);
}
@@ -224,9 +224,9 @@ void RecordStreamer::flushSymverDirectives() {
if (IsDefined)
markDefined(*Alias);
// Don't use EmitAssignment override as it always marks alias as defined.
- MCStreamer::EmitAssignment(Alias, Value);
+ MCStreamer::emitAssignment(Alias, Value);
if (Attr != MCSA_Invalid)
- EmitSymbolAttribute(Alias, Attr);
+ emitSymbolAttribute(Alias, Attr);
}
}
}
diff --git a/llvm/lib/Object/RecordStreamer.h b/llvm/lib/Object/RecordStreamer.h
index c8b75bcc6d1df..99d15f790a156 100644
--- a/llvm/lib/Object/RecordStreamer.h
+++ b/llvm/lib/Object/RecordStreamer.h
@@ -13,13 +13,12 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/SMLoc.h"
#include <vector>
namespace llvm {
-class GlobalValue;
+class MCSymbol;
class Module;
class RecordStreamer : public MCStreamer {
@@ -46,13 +45,13 @@ private:
public:
RecordStreamer(MCContext &Context, const Module &M);
- void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
- void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
- void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
- bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
- void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+ void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+ void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment, SMLoc Loc = SMLoc()) override;
- void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
// Ignore COFF-specific directives; we do not need any information from them,
diff --git a/llvm/lib/Object/RelocationResolver.cpp b/llvm/lib/Object/RelocationResolver.cpp
index 31478be7899ed..3f3f79b0f4ff7 100644
--- a/llvm/lib/Object/RelocationResolver.cpp
+++ b/llvm/lib/Object/RelocationResolver.cpp
@@ -127,6 +127,27 @@ static uint64_t resolveMips64(RelocationRef R, uint64_t S, uint64_t A) {
}
}
+static bool supportsMSP430(uint64_t Type) {
+ switch (Type) {
+ case ELF::R_MSP430_32:
+ case ELF::R_MSP430_16_BYTE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static uint64_t resolveMSP430(RelocationRef R, uint64_t S, uint64_t A) {
+ switch (R.getType()) {
+ case ELF::R_MSP430_32:
+ return (S + getELFAddend(R)) & 0xFFFFFFFF;
+ case ELF::R_MSP430_16_BYTE:
+ return (S + getELFAddend(R)) & 0xFFFF;
+ default:
+ llvm_unreachable("Invalid relocation type");
+ }
+}
+
static bool supportsPPC64(uint64_t Type) {
switch (Type) {
case ELF::R_PPC64_ADDR32:
@@ -498,12 +519,24 @@ static bool supportsWasm32(uint64_t Type) {
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_GLOBAL_INDEX_I32:
return true;
default:
return false;
}
}
+static bool supportsWasm64(uint64_t Type) {
+ switch (Type) {
+ case wasm::R_WASM_MEMORY_ADDR_LEB64:
+ case wasm::R_WASM_MEMORY_ADDR_SLEB64:
+ case wasm::R_WASM_MEMORY_ADDR_I64:
+ return true;
+ default:
+ return supportsWasm32(Type);
+ }
+}
+
static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
switch (R.getType()) {
case wasm::R_WASM_FUNCTION_INDEX_LEB:
@@ -517,6 +550,7 @@ static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
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_GLOBAL_INDEX_I32:
// For wasm section, its offset at 0 -- ignoring Value
return A;
default:
@@ -524,6 +558,18 @@ static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
}
}
+static uint64_t resolveWasm64(RelocationRef R, uint64_t S, uint64_t A) {
+ switch (R.getType()) {
+ case wasm::R_WASM_MEMORY_ADDR_LEB64:
+ case wasm::R_WASM_MEMORY_ADDR_SLEB64:
+ case wasm::R_WASM_MEMORY_ADDR_I64:
+ // For wasm section, its offset at 0 -- ignoring Value
+ return A;
+ default:
+ return resolveWasm32(R, S, A);
+ }
+}
+
std::pair<bool (*)(uint64_t), RelocationResolver>
getRelocationResolver(const ObjectFile &Obj) {
if (Obj.isCOFF()) {
@@ -589,6 +635,8 @@ getRelocationResolver(const ObjectFile &Obj) {
case Triple::mipsel:
case Triple::mips:
return {supportsMips32, resolveMips32};
+ case Triple::msp430:
+ return {supportsMSP430, resolveMSP430};
case Triple::sparc:
return {supportsSparc32, resolveSparc32};
case Triple::hexagon:
@@ -605,6 +653,8 @@ getRelocationResolver(const ObjectFile &Obj) {
} else if (Obj.isWasm()) {
if (Obj.getArch() == Triple::wasm32)
return {supportsWasm32, resolveWasm32};
+ if (Obj.getArch() == Triple::wasm64)
+ return {supportsWasm64, resolveWasm64};
return {nullptr, nullptr};
}
diff --git a/llvm/lib/Object/SymbolSize.cpp b/llvm/lib/Object/SymbolSize.cpp
index bdf4dc55cf3cc..84eed4d169d3a 100644
--- a/llvm/lib/Object/SymbolSize.cpp
+++ b/llvm/lib/Object/SymbolSize.cpp
@@ -11,6 +11,7 @@
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachO.h"
+#include "llvm/Object/Wasm.h"
using namespace llvm;
using namespace object;
@@ -27,12 +28,17 @@ int llvm::object::compareAddress(const SymEntry *A, const SymEntry *B) {
static unsigned getSectionID(const ObjectFile &O, SectionRef Sec) {
if (auto *M = dyn_cast<MachOObjectFile>(&O))
return M->getSectionID(Sec);
+ if (isa<WasmObjectFile>(&O))
+ return Sec.getIndex();
+
return cast<COFFObjectFile>(O).getSectionID(Sec);
}
static unsigned getSymbolSectionID(const ObjectFile &O, SymbolRef Sym) {
if (auto *M = dyn_cast<MachOObjectFile>(&O))
return M->getSymbolSectionID(Sym);
+ if (const auto *M = dyn_cast<WasmObjectFile>(&O))
+ return M->getSymbolSectionId(Sym);
return cast<COFFObjectFile>(O).getSymbolSectionID(Sym);
}
@@ -55,8 +61,11 @@ llvm::object::computeSymbolSizes(const ObjectFile &O) {
unsigned SymNum = 0;
for (symbol_iterator I = O.symbol_begin(), E = O.symbol_end(); I != E; ++I) {
SymbolRef Sym = *I;
- uint64_t Value = Sym.getValue();
- Addresses.push_back({I, Value, SymNum, getSymbolSectionID(O, Sym)});
+ Expected<uint64_t> ValueOrErr = Sym.getValue();
+ if (!ValueOrErr)
+ // TODO: Actually report errors helpfully.
+ report_fatal_error(ValueOrErr.takeError());
+ Addresses.push_back({I, *ValueOrErr, SymNum, getSymbolSectionID(O, Sym)});
++SymNum;
}
for (SectionRef Sec : O.sections()) {
diff --git a/llvm/lib/Object/TapiFile.cpp b/llvm/lib/Object/TapiFile.cpp
index c409bd8e59951..7a361990ba5d2 100644
--- a/llvm/lib/Object/TapiFile.cpp
+++ b/llvm/lib/Object/TapiFile.cpp
@@ -40,7 +40,7 @@ static uint32_t getFlags(const Symbol *Sym) {
TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface,
Architecture Arch)
- : SymbolicFile(ID_TapiFile, Source) {
+ : SymbolicFile(ID_TapiFile, Source), Arch(Arch) {
for (const auto *Symbol : interface.symbols()) {
if (!Symbol->getArchitectures().has(Arch))
continue;
@@ -75,30 +75,28 @@ TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface,
TapiFile::~TapiFile() = default;
-void TapiFile::moveSymbolNext(DataRefImpl &DRI) const {
- const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p);
- DRI.p = reinterpret_cast<uintptr_t>(++Sym);
-}
+void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; }
Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const {
- const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p);
- OS << Sym->Prefix << Sym->Name;
+ assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");
+ const Symbol &Sym = Symbols[DRI.d.a];
+ OS << Sym.Prefix << Sym.Name;
return Error::success();
}
-uint32_t TapiFile::getSymbolFlags(DataRefImpl DRI) const {
- const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p);
- return Sym->Flags;
+Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const {
+ assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");
+ return Symbols[DRI.d.a].Flags;
}
basic_symbol_iterator TapiFile::symbol_begin() const {
DataRefImpl DRI;
- DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.begin());
+ DRI.d.a = 0;
return BasicSymbolRef{DRI, this};
}
basic_symbol_iterator TapiFile::symbol_end() const {
DataRefImpl DRI;
- DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.end());
+ DRI.d.a = Symbols.size();
return BasicSymbolRef{DRI, this};
}
diff --git a/llvm/lib/Object/TapiUniversal.cpp b/llvm/lib/Object/TapiUniversal.cpp
index b3273e345a61d..48cb949cb6f4d 100644
--- a/llvm/lib/Object/TapiUniversal.cpp
+++ b/llvm/lib/Object/TapiUniversal.cpp
@@ -22,7 +22,7 @@ using namespace object;
TapiUniversal::TapiUniversal(MemoryBufferRef Source, Error &Err)
: Binary(ID_TapiUniversal, Source) {
- auto Result = TextAPIReader::get(Source);
+ Expected<std::unique_ptr<InterfaceFile>> Result = TextAPIReader::get(Source);
ErrorAsOutParameter ErrAsOuParam(&Err);
if (!Result) {
Err = Result.takeError();
@@ -30,9 +30,16 @@ TapiUniversal::TapiUniversal(MemoryBufferRef Source, Error &Err)
}
ParsedFile = std::move(Result.get());
- auto Archs = ParsedFile->getArchitectures();
- for (auto Arch : Archs)
- Architectures.emplace_back(Arch);
+ auto FlattenObjectInfo = [this](const auto &File) {
+ StringRef Name = File->getInstallName();
+ for (const Architecture Arch : File->getArchitectures())
+ Libraries.emplace_back(Library({Name, Arch}));
+ };
+
+ FlattenObjectInfo(ParsedFile);
+ // Get inlined documents from tapi file.
+ for (const std::shared_ptr<InterfaceFile> &File : ParsedFile->documents())
+ FlattenObjectInfo(File);
}
TapiUniversal::~TapiUniversal() = default;
@@ -41,7 +48,7 @@ Expected<std::unique_ptr<TapiFile>>
TapiUniversal::ObjectForArch::getAsObjectFile() const {
return std::unique_ptr<TapiFile>(new TapiFile(Parent->getMemoryBufferRef(),
*Parent->ParsedFile.get(),
- Parent->Architectures[Index]));
+ Parent->Libraries[Index].Arch));
}
Expected<std::unique_ptr<TapiUniversal>>
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index ab8918ce1919c..bb2e81d64047f 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/MC/SubtargetFeature.h"
@@ -155,6 +156,10 @@ static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx) {
return readLEB128(Ctx);
}
+static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx) {
+ return readULEB128(Ctx);
+}
+
static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) {
return readUint8(Ctx);
}
@@ -179,6 +184,14 @@ static Error readInitExpr(wasm::WasmInitExpr &Expr,
case wasm::WASM_OPCODE_GLOBAL_GET:
Expr.Value.Global = readULEB128(Ctx);
break;
+ case wasm::WASM_OPCODE_REF_NULL: {
+ wasm::ValType Ty = static_cast<wasm::ValType>(readULEB128(Ctx));
+ if (Ty != wasm::ValType::EXTERNREF) {
+ return make_error<GenericBinaryError>("Invalid type for ref.null",
+ object_error::parse_failed);
+ }
+ break;
+ }
default:
return make_error<GenericBinaryError>("Invalid opcode in init_expr",
object_error::parse_failed);
@@ -195,9 +208,9 @@ static Error readInitExpr(wasm::WasmInitExpr &Expr,
static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) {
wasm::WasmLimits Result;
Result.Flags = readVaruint32(Ctx);
- Result.Initial = readVaruint32(Ctx);
+ Result.Initial = readVaruint64(Ctx);
if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
- Result.Maximum = readVaruint32(Ctx);
+ Result.Maximum = readVaruint64(Ctx);
return Result;
}
@@ -302,10 +315,10 @@ Error WasmObjectFile::parseSection(WasmSection &Sec) {
return parseTableSection(Ctx);
case wasm::WASM_SEC_MEMORY:
return parseMemorySection(Ctx);
- case wasm::WASM_SEC_GLOBAL:
- return parseGlobalSection(Ctx);
case wasm::WASM_SEC_EVENT:
return parseEventSection(Ctx);
+ case wasm::WASM_SEC_GLOBAL:
+ return parseGlobalSection(Ctx);
case wasm::WASM_SEC_EXPORT:
return parseExportSection(Ctx);
case wasm::WASM_SEC_START:
@@ -508,13 +521,16 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
Function.SymbolName = Info.Name;
} else {
wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
- if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
Info.Name = readString(Ctx);
- else
+ Info.ImportName = Import.Field;
+ } else {
Info.Name = Import.Field;
+ }
Signature = &Signatures[Import.SigIndex];
- Info.ImportName = Import.Field;
- Info.ImportModule = Import.Module;
+ if (!Import.Module.empty()) {
+ Info.ImportModule = Import.Module;
+ }
}
break;
@@ -537,25 +553,29 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
Global.SymbolName = Info.Name;
} else {
wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
- if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
Info.Name = readString(Ctx);
- else
+ Info.ImportName = Import.Field;
+ } else {
Info.Name = Import.Field;
+ }
GlobalType = &Import.Global;
Info.ImportName = Import.Field;
- Info.ImportModule = Import.Module;
+ if (!Import.Module.empty()) {
+ Info.ImportModule = Import.Module;
+ }
}
break;
case wasm::WASM_SYMBOL_TYPE_DATA:
Info.Name = readString(Ctx);
if (IsDefined) {
- uint32_t Index = readVaruint32(Ctx);
+ auto Index = readVaruint32(Ctx);
if (Index >= DataSegments.size())
return make_error<GenericBinaryError>("invalid data symbol index",
object_error::parse_failed);
- uint32_t Offset = readVaruint32(Ctx);
- uint32_t Size = readVaruint32(Ctx);
+ 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);
@@ -597,14 +617,17 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
} else {
wasm::WasmImport &Import = *ImportedEvents[Info.ElementIndex];
- if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
Info.Name = readString(Ctx);
- else
+ Info.ImportName = Import.Field;
+ } else {
Info.Name = Import.Field;
+ }
EventType = &Import.Event;
Signature = &Signatures[EventType->SigIndex];
- Info.ImportName = Import.Field;
- Info.ImportModule = Import.Module;
+ if (!Import.Module.empty()) {
+ Info.ImportModule = Import.Module;
+ }
}
break;
}
@@ -708,7 +731,7 @@ Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
"Producers section contains repeated producer",
object_error::parse_failed);
}
- ProducerVec->emplace_back(Name, Version);
+ ProducerVec->emplace_back(std::string(Name), std::string(Version));
}
}
if (Ctx.Ptr != Ctx.End)
@@ -732,7 +755,7 @@ Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
return make_error<GenericBinaryError>("Unknown feature policy prefix",
object_error::parse_failed);
}
- Feature.Name = readString(Ctx);
+ Feature.Name = std::string(readString(Ctx));
if (!FeaturesSeen.insert(Feature.Name).second)
return make_error<GenericBinaryError>(
"Target features section contains repeated feature \"" +
@@ -788,6 +811,11 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
return make_error<GenericBinaryError>("Bad relocation global index",
object_error::parse_failed);
break;
+ case wasm::R_WASM_GLOBAL_INDEX_I32:
+ if (!isValidGlobalSymbol(Reloc.Index))
+ return make_error<GenericBinaryError>("Bad relocation global index",
+ object_error::parse_failed);
+ break;
case wasm::R_WASM_EVENT_INDEX_LEB:
if (!isValidEventSymbol(Reloc.Index))
return make_error<GenericBinaryError>("Bad relocation event index",
@@ -802,6 +830,15 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
object_error::parse_failed);
Reloc.Addend = readVarint32(Ctx);
break;
+ case wasm::R_WASM_MEMORY_ADDR_LEB64:
+ case wasm::R_WASM_MEMORY_ADDR_SLEB64:
+ case wasm::R_WASM_MEMORY_ADDR_I64:
+ case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
+ if (!isValidDataSymbol(Reloc.Index))
+ return make_error<GenericBinaryError>("Bad relocation data index",
+ object_error::parse_failed);
+ Reloc.Addend = readVarint64(Ctx);
+ break;
case wasm::R_WASM_FUNCTION_OFFSET_I32:
if (!isValidFunctionSymbol(Reloc.Index))
return make_error<GenericBinaryError>("Bad relocation function index",
@@ -824,11 +861,18 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
// also shouldn't overlap a function/element boundary, but we don't bother
// to check that.
uint64_t Size = 5;
+ if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LEB64 ||
+ Reloc.Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 ||
+ Reloc.Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64)
+ Size = 10;
if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 ||
Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
- Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32)
+ Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
+ Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
Size = 4;
+ if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64)
+ Size = 8;
if (Reloc.Offset + Size > EndOffset)
return make_error<GenericBinaryError>("Bad relocation offset",
object_error::parse_failed);
@@ -983,6 +1027,24 @@ Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
return Error::success();
}
+Error WasmObjectFile::parseEventSection(ReadContext &Ctx) {
+ EventSection = Sections.size();
+ uint32_t Count = readVarint32(Ctx);
+ Events.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);
+ }
+
+ if (Ctx.Ptr != Ctx.End)
+ return make_error<GenericBinaryError>("Event section ended prematurely",
+ object_error::parse_failed);
+ return Error::success();
+}
+
Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
GlobalSection = Sections.size();
uint32_t Count = readVaruint32(Ctx);
@@ -1002,24 +1064,6 @@ Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
return Error::success();
}
-Error WasmObjectFile::parseEventSection(ReadContext &Ctx) {
- EventSection = Sections.size();
- uint32_t Count = readVarint32(Ctx);
- Events.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);
- }
-
- if (Ctx.Ptr != Ctx.End)
- return make_error<GenericBinaryError>("Event section ended prematurely",
- object_error::parse_failed);
- return Error::success();
-}
-
Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
uint32_t Count = readVaruint32(Ctx);
Exports.reserve(Count);
@@ -1250,7 +1294,7 @@ const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const {
void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.b++; }
-uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const {
+Expected<uint32_t> WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const {
uint32_t Result = SymbolRef::SF_None;
const WasmSymbol &Sym = getWasmSymbol(Symb);
@@ -1314,8 +1358,13 @@ 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;
- assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST);
- return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
+ 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;
+ } else {
+ llvm_unreachable("unknown init expr opcode");
+ }
}
case wasm::WASM_SYMBOL_TYPE_SECTION:
return 0;
@@ -1365,26 +1414,30 @@ WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
return section_end();
DataRefImpl Ref;
+ Ref.d.a = getSymbolSectionIdImpl(Sym);
+ return section_iterator(SectionRef(Ref, this));
+}
+
+uint32_t WasmObjectFile::getSymbolSectionId(SymbolRef Symb) const {
+ const WasmSymbol &Sym = getWasmSymbol(Symb);
+ return getSymbolSectionIdImpl(Sym);
+}
+
+uint32_t WasmObjectFile::getSymbolSectionIdImpl(const WasmSymbol &Sym) const {
switch (Sym.Info.Kind) {
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
- Ref.d.a = CodeSection;
- break;
+ return CodeSection;
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
- Ref.d.a = GlobalSection;
- break;
+ return GlobalSection;
case wasm::WASM_SYMBOL_TYPE_DATA:
- Ref.d.a = DataSection;
- break;
+ return DataSection;
case wasm::WASM_SYMBOL_TYPE_SECTION:
- Ref.d.a = Sym.Info.ElementIndex;
- break;
+ return Sym.Info.ElementIndex;
case wasm::WASM_SYMBOL_TYPE_EVENT:
- Ref.d.a = EventSection;
- break;
+ return EventSection;
default:
llvm_unreachable("Unknown WasmSymbol::SymbolType");
}
- return section_iterator(SectionRef(Ref, this));
}
void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
@@ -1455,8 +1508,6 @@ bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
-bool WasmObjectFile::isSectionBitcode(DataRefImpl Sec) const { return false; }
-
relocation_iterator WasmObjectFile::section_rel_begin(DataRefImpl Ref) const {
DataRefImpl RelocRef;
RelocRef.d.a = Ref.d.a;
@@ -1608,30 +1659,50 @@ int WasmSectionOrderChecker::getSectionOrder(unsigned ID,
// Represents the edges in a directed graph where any node B reachable from node
// A is not allowed to appear before A in the section ordering, but may appear
// afterward.
-int WasmSectionOrderChecker::DisallowedPredecessors[WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {
- {}, // WASM_SEC_ORDER_NONE
- {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT}, // WASM_SEC_ORDER_TYPE,
- {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION}, // WASM_SEC_ORDER_IMPORT,
- {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE}, // WASM_SEC_ORDER_FUNCTION,
- {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY}, // WASM_SEC_ORDER_TABLE,
- {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_GLOBAL}, // WASM_SEC_ORDER_MEMORY,
- {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EVENT}, // WASM_SEC_ORDER_GLOBAL,
- {WASM_SEC_ORDER_EVENT, WASM_SEC_ORDER_EXPORT}, // WASM_SEC_ORDER_EVENT,
- {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START}, // WASM_SEC_ORDER_EXPORT,
- {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM}, // WASM_SEC_ORDER_START,
- {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT}, // WASM_SEC_ORDER_ELEM,
- {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE}, // WASM_SEC_ORDER_DATACOUNT,
- {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA}, // WASM_SEC_ORDER_CODE,
- {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING}, // WASM_SEC_ORDER_DATA,
-
- // Custom Sections
- {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE}, // WASM_SEC_ORDER_DYLINK,
- {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME}, // WASM_SEC_ORDER_LINKING,
- {}, // WASM_SEC_ORDER_RELOC (can be repeated),
- {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS}, // WASM_SEC_ORDER_NAME,
- {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES}, // WASM_SEC_ORDER_PRODUCERS,
- {WASM_SEC_ORDER_TARGET_FEATURES} // WASM_SEC_ORDER_TARGET_FEATURES
-};
+int WasmSectionOrderChecker::DisallowedPredecessors
+ [WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {
+ // WASM_SEC_ORDER_NONE
+ {},
+ // WASM_SEC_ORDER_TYPE
+ {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT},
+ // WASM_SEC_ORDER_IMPORT
+ {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION},
+ // WASM_SEC_ORDER_FUNCTION
+ {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE},
+ // 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_GLOBAL
+ {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},
+ // WASM_SEC_ORDER_EXPORT
+ {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START},
+ // WASM_SEC_ORDER_START
+ {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM},
+ // WASM_SEC_ORDER_ELEM
+ {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT},
+ // WASM_SEC_ORDER_DATACOUNT
+ {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE},
+ // WASM_SEC_ORDER_CODE
+ {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA},
+ // WASM_SEC_ORDER_DATA
+ {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING},
+
+ // Custom Sections
+ // WASM_SEC_ORDER_DYLINK
+ {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE},
+ // WASM_SEC_ORDER_LINKING
+ {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME},
+ // WASM_SEC_ORDER_RELOC (can be repeated)
+ {},
+ // WASM_SEC_ORDER_NAME
+ {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS},
+ // WASM_SEC_ORDER_PRODUCERS
+ {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES},
+ // WASM_SEC_ORDER_TARGET_FEATURES
+ {WASM_SEC_ORDER_TARGET_FEATURES}};
bool WasmSectionOrderChecker::isValidSectionOrder(unsigned ID,
StringRef CustomSectionName) {
diff --git a/llvm/lib/Object/WindowsResource.cpp b/llvm/lib/Object/WindowsResource.cpp
index 10717718b2019..2a69c6c46b590 100644
--- a/llvm/lib/Object/WindowsResource.cpp
+++ b/llvm/lib/Object/WindowsResource.cpp
@@ -346,7 +346,7 @@ Error WindowsResourceParser::parse(WindowsResource *WR,
ResourceEntryRef Entry = EntryOrErr.get();
uint32_t Origin = InputFilenames.size();
- InputFilenames.push_back(WR->getFileName());
+ InputFilenames.push_back(std::string(WR->getFileName()));
bool End = false;
while (!End) {
@@ -368,7 +368,7 @@ Error WindowsResourceParser::parse(ResourceSectionRef &RSR, StringRef Filename,
std::vector<std::string> &Duplicates) {
UNWRAP_REF_OR_RETURN(BaseTable, RSR.getBaseTable());
uint32_t Origin = InputFilenames.size();
- InputFilenames.push_back(Filename);
+ InputFilenames.push_back(std::string(Filename));
std::vector<StringOrID> Context;
return addChildren(Root, RSR, BaseTable, Origin, Context, Duplicates);
}
@@ -721,8 +721,10 @@ WindowsResourceCOFFWriter::write(uint32_t TimeDateStamp) {
// it's okay to *not* copy the trailing zero.
static void coffnamecpy(char (&Dest)[COFF::NameSize], StringRef Src) {
assert(Src.size() <= COFF::NameSize &&
- "Src is not larger than COFF::NameSize");
- strncpy(Dest, Src.data(), (size_t)COFF::NameSize);
+ "Src is larger than COFF::NameSize");
+ assert((Src.size() == COFF::NameSize || Dest[Src.size()] == '\0') &&
+ "Dest not zeroed upon initialization");
+ memcpy(Dest, Src.data(), Src.size());
}
void WindowsResourceCOFFWriter::writeCOFFHeader(uint32_t TimeDateStamp) {
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index f98cd69a0d379..533361666cf21 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -11,13 +11,16 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/XCOFFObjectFile.h"
+#include "llvm/MC/SubtargetFeature.h"
#include <cstddef>
#include <cstring>
namespace llvm {
namespace object {
-enum { FUNCTION_SYM = 0x20, SYM_TYPE_MASK = 0x07, RELOC_OVERFLOW = 65535 };
+static const uint8_t FunctionSym = 0x20;
+static const uint8_t SymTypeMask = 0x07;
+static const uint16_t NoRelMask = 0x0001;
// Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
// 'M'. Returns a pointer to the underlying object on success.
@@ -25,8 +28,8 @@ template <typename T>
static Expected<const T *> getObject(MemoryBufferRef M, const void *Ptr,
const uint64_t Size = sizeof(T)) {
uintptr_t Addr = uintptr_t(Ptr);
- if (std::error_code EC = Binary::checkOffset(M, Addr, Size))
- return errorCodeToError(EC);
+ if (Error E = Binary::checkOffset(M, Addr, Size))
+ return std::move(E);
return reinterpret_cast<const T *>(Addr);
}
@@ -314,58 +317,98 @@ bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const {
}
relocation_iterator XCOFFObjectFile::section_rel_begin(DataRefImpl Sec) const {
- llvm_unreachable("Not yet implemented!");
- return relocation_iterator(RelocationRef());
+ if (is64Bit())
+ report_fatal_error("64-bit support not implemented yet");
+ const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec);
+ auto RelocationsOrErr = relocations(*SectionEntPtr);
+ if (Error E = RelocationsOrErr.takeError())
+ return relocation_iterator(RelocationRef());
+ DataRefImpl Ret;
+ Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin());
+ return relocation_iterator(RelocationRef(Ret, this));
}
relocation_iterator XCOFFObjectFile::section_rel_end(DataRefImpl Sec) const {
- llvm_unreachable("Not yet implemented!");
- return relocation_iterator(RelocationRef());
+ if (is64Bit())
+ report_fatal_error("64-bit support not implemented yet");
+ const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec);
+ auto RelocationsOrErr = relocations(*SectionEntPtr);
+ if (Error E = RelocationsOrErr.takeError())
+ return relocation_iterator(RelocationRef());
+ DataRefImpl Ret;
+ Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end());
+ return relocation_iterator(RelocationRef(Ret, this));
}
void XCOFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
- llvm_unreachable("Not yet implemented!");
- return;
+ Rel.p = reinterpret_cast<uintptr_t>(viewAs<XCOFFRelocation32>(Rel.p) + 1);
}
uint64_t XCOFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
- llvm_unreachable("Not yet implemented!");
- uint64_t Result = 0;
- return Result;
+ if (is64Bit())
+ report_fatal_error("64-bit support not implemented yet");
+ const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
+ const XCOFFSectionHeader32 *Sec32 = sectionHeaderTable32();
+ const uint32_t RelocAddress = Reloc->VirtualAddress;
+ const uint16_t NumberOfSections = getNumberOfSections();
+ for (uint16_t i = 0; i < NumberOfSections; ++i) {
+ // Find which section this relocation is belonging to, and get the
+ // relocation offset relative to the start of the section.
+ if (Sec32->VirtualAddress <= RelocAddress &&
+ RelocAddress < Sec32->VirtualAddress + Sec32->SectionSize) {
+ return RelocAddress - Sec32->VirtualAddress;
+ }
+ ++Sec32;
+ }
+ return InvalidRelocOffset;
}
symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
- llvm_unreachable("Not yet implemented!");
- return symbol_iterator(SymbolRef());
+ if (is64Bit())
+ report_fatal_error("64-bit support not implemented yet");
+ const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
+ const uint32_t Index = Reloc->SymbolIndex;
+
+ if (Index >= getLogicalNumberOfSymbolTableEntries32())
+ return symbol_end();
+
+ DataRefImpl SymDRI;
+ SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
+ return symbol_iterator(SymbolRef(SymDRI, this));
}
uint64_t XCOFFObjectFile::getRelocationType(DataRefImpl Rel) const {
- llvm_unreachable("Not yet implemented!");
- uint64_t Result = 0;
- return Result;
+ if (is64Bit())
+ report_fatal_error("64-bit support not implemented yet");
+ return viewAs<XCOFFRelocation32>(Rel.p)->Type;
}
void XCOFFObjectFile::getRelocationTypeName(
DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
- llvm_unreachable("Not yet implemented!");
- return;
+ if (is64Bit())
+ report_fatal_error("64-bit support not implemented yet");
+ const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
+ StringRef Res = XCOFF::getRelocationTypeString(Reloc->Type);
+ Result.append(Res.begin(), Res.end());
}
-uint32_t XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
+Expected<uint32_t> XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
uint32_t Result = 0;
llvm_unreachable("Not yet implemented!");
return Result;
}
basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
- assert(!is64Bit() && "64-bit support not implemented yet.");
+ 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 {
- assert(!is64Bit() && "64-bit support not implemented yet.");
+ if (is64Bit())
+ report_fatal_error("64-bit support not implemented yet");
DataRefImpl SymDRI;
SymDRI.p = reinterpret_cast<uintptr_t>(
SymbolTblPtr + getLogicalNumberOfSymbolTableEntries32());
@@ -400,9 +443,9 @@ SubtargetFeatures XCOFFObjectFile::getFeatures() const {
}
bool XCOFFObjectFile::isRelocatableObject() const {
- bool Result = false;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ if (is64Bit())
+ report_fatal_error("64-bit support not implemented yet");
+ return !(fileHeader32()->Flags & NoRelMask);
}
Expected<uint64_t> XCOFFObjectFile::getStartAddress() const {
@@ -588,7 +631,7 @@ Expected<uint32_t> XCOFFObjectFile::getLogicalNumberOfRelocationEntries(
uint16_t SectionIndex = &Sec - sectionHeaderTable32() + 1;
- if (Sec.NumberOfRelocations < RELOC_OVERFLOW)
+ if (Sec.NumberOfRelocations < XCOFF::RelocOverflow)
return Sec.NumberOfRelocations;
for (const auto &Sec : sections32()) {
if (Sec.Flags == XCOFF::STYP_OVRFLO &&
@@ -608,6 +651,7 @@ XCOFFObjectFile::relocations(const XCOFFSectionHeader32 &Sec) const {
uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
+ assert(sizeof(XCOFFRelocation32) == XCOFF::RelocationSerializationSize32);
auto RelocationOrErr =
getObject<XCOFFRelocation32>(Data, reinterpret_cast<void *>(RelocAddr),
NumRelocEntries * sizeof(XCOFFRelocation32));
@@ -623,9 +667,11 @@ Expected<XCOFFStringTable>
XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
// If there is a string table, then the buffer must contain at least 4 bytes
// for the string table's size. Not having a string table is not an error.
- if (auto EC = Binary::checkOffset(
- Obj->Data, reinterpret_cast<uintptr_t>(Obj->base() + Offset), 4))
+ if (Error E = Binary::checkOffset(
+ Obj->Data, reinterpret_cast<uintptr_t>(Obj->base() + Offset), 4)) {
+ consumeError(std::move(E));
return XCOFFStringTable{0, nullptr};
+ }
// Read the size out of the buffer.
uint32_t Size = support::endian::read32be(Obj->base() + Offset);
@@ -722,6 +768,8 @@ uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
}
+// 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.");
@@ -747,6 +795,8 @@ int16_t XCOFFSymbolRef::getSectionNumber() const {
return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber;
}
+// TODO: The function name needs to be changed to express the purpose of the
+// function.
bool XCOFFSymbolRef::hasCsectAuxEnt() const {
XCOFF::StorageClass SC = getStorageClass();
return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||
@@ -757,7 +807,7 @@ bool XCOFFSymbolRef::isFunction() const {
if (OwningObjectPtr->is64Bit())
report_fatal_error("64-bit support is unimplemented yet.");
- if (getType() & FUNCTION_SYM)
+ if (getType() & FunctionSym)
return true;
if (!hasCsectAuxEnt())
@@ -766,7 +816,7 @@ bool XCOFFSymbolRef::isFunction() const {
const XCOFFCsectAuxEnt32 *CsectAuxEnt = getXCOFFCsectAuxEnt32();
// A function definition should be a label definition.
- if ((CsectAuxEnt->SymbolAlignmentAndType & SYM_TYPE_MASK) != XCOFF::XTY_LD)
+ if ((CsectAuxEnt->SymbolAlignmentAndType & SymTypeMask) != XCOFF::XTY_LD)
return false;
if (CsectAuxEnt->StorageMappingClass != XCOFF::XMC_PR)