}
uint16_t getSizeOfOptionalHeader() const {
if (COFFHeader)
- return COFFHeader->SizeOfOptionalHeader;
+ return COFFHeader->isImportLibrary() ? 0
+ : COFFHeader->SizeOfOptionalHeader;
// bigobj doesn't have this field.
if (COFFBigObjHeader)
return 0;
}
uint16_t getCharacteristics() const {
if (COFFHeader)
- return COFFHeader->Characteristics;
+ return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics;
// bigobj doesn't have characteristics to speak of,
// editbin will silently lie to you if you attempt to set any.
if (COFFBigObjHeader)
}
uint32_t getNumberOfSections() const {
if (COFFHeader)
- return COFFHeader->NumberOfSections;
+ return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections;
if (COFFBigObjHeader)
return COFFBigObjHeader->NumberOfSections;
llvm_unreachable("no COFF header!");
}
uint32_t getPointerToSymbolTable() const {
if (COFFHeader)
- return COFFHeader->PointerToSymbolTable;
+ return COFFHeader->isImportLibrary() ? 0
+ : COFFHeader->PointerToSymbolTable;
if (COFFBigObjHeader)
return COFFBigObjHeader->PointerToSymbolTable;
llvm_unreachable("no COFF header!");
}
uint32_t getNumberOfSymbols() const {
if (COFFHeader)
- return COFFHeader->NumberOfSymbols;
+ return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols;
if (COFFBigObjHeader)
return COFFBigObjHeader->NumberOfSymbols;
llvm_unreachable("no COFF header!");
return EC;
return COFFSymbolRef(Symb);
}
- llvm_unreachable("no symbol table pointer!");
+ return object_error::parse_failed;
}
template <typename T>
std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
template <typename T>
static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
const void *Ptr,
- const size_t Size = sizeof(T)) {
+ const uint64_t Size = sizeof(T)) {
uintptr_t Addr = uintptr_t(Ptr);
if (std::error_code EC = checkOffset(M, Addr, Size))
return EC;
const coff_symbol_type *Addr =
reinterpret_cast<const coff_symbol_type *>(Ref.p);
+ assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr)));
#ifndef NDEBUG
// Verify that the symbol points to a valid entry in the symbol table.
uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base());
- if (Offset < getPointerToSymbolTable() ||
- Offset >= getPointerToSymbolTable() +
- (getNumberOfSymbols() * sizeof(coff_symbol_type)))
- report_fatal_error("Symbol was outside of symbol table.");
assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
"Symbol did not point to the beginning of a symbol");
}
void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const {
+ auto End = reinterpret_cast<uintptr_t>(StringTable);
if (SymbolTable16) {
const coff_symbol16 *Symb = toSymb<coff_symbol16>(Ref);
Symb += 1 + Symb->NumberOfAuxSymbols;
- Ref.p = reinterpret_cast<uintptr_t>(Symb);
+ Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
} else if (SymbolTable32) {
const coff_symbol32 *Symb = toSymb<coff_symbol32>(Ref);
Symb += 1 + Symb->NumberOfAuxSymbols;
- Ref.p = reinterpret_cast<uintptr_t>(Symb);
+ Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);
} else {
llvm_unreachable("no symbol table pointer!");
}
}
bool COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Ref) const {
- // FIXME: Unimplemented
- return true;
+ // Sections marked 'Info', 'Remove', or 'Discardable' aren't required for
+ // execution.
+ const coff_section *Sec = toSec(Ref);
+ return !(Sec->Characteristics &
+ (COFF::IMAGE_SCN_LNK_INFO | COFF::IMAGE_SCN_LNK_REMOVE |
+ COFF::IMAGE_SCN_MEM_DISCARDABLE));
}
bool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const {
}
bool COFFObjectFile::isSectionZeroInit(DataRefImpl Ref) const {
- // FIXME: Unimplemented.
- return false;
+ const coff_section *Sec = toSec(Ref);
+ return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
}
bool COFFObjectFile::isSectionReadOnlyData(DataRefImpl Ref) const {
- // FIXME: Unimplemented.
- return false;
+ const coff_section *Sec = toSec(Ref);
+ // Check if it's any sort of data section.
+ if (!(Sec->Characteristics & (COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)))
+ return false;
+ // If it's writable or executable or contains code, it isn't read-only data.
+ if (Sec->Characteristics &
+ (COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE |
+ COFF::IMAGE_SCN_MEM_WRITE))
+ return false;
+ return true;
}
bool COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
// Initialize the pointer to the symbol table.
std::error_code COFFObjectFile::initSymbolTablePtr() {
if (COFFHeader)
- if (std::error_code EC =
- getObject(SymbolTable16, Data, base() + getPointerToSymbolTable(),
- getNumberOfSymbols() * getSymbolTableEntrySize()))
+ if (std::error_code EC = getObject(
+ SymbolTable16, Data, base() + getPointerToSymbolTable(),
+ (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
return EC;
if (COFFBigObjHeader)
- if (std::error_code EC =
- getObject(SymbolTable32, Data, base() + getPointerToSymbolTable(),
- getNumberOfSymbols() * getSymbolTableEntrySize()))
+ if (std::error_code EC = getObject(
+ SymbolTable32, Data, base() + getPointerToSymbolTable(),
+ (uint64_t)getNumberOfSymbols() * getSymbolTableEntrySize()))
return EC;
// Find string table. The first four byte of the string table contains the
}
if ((EC = getObject(SectionTable, Data, base() + CurPtr,
- getNumberOfSections() * sizeof(coff_section))))
+ (uint64_t)getNumberOfSections() * sizeof(coff_section))))
return;
// Initialize the pointer to the symbol table.
- if (getPointerToSymbolTable() != 0)
+ if (getPointerToSymbolTable() != 0) {
if ((EC = initSymbolTablePtr()))
return;
+ } 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;
+ }
+ }
// Initialize the pointer to the beginning of the import table.
if ((EC = initImportTablePtr()))
std::error_code COFFObjectFile::getSection(int32_t Index,
const coff_section *&Result) const {
- // Check for special index values.
+ Result = nullptr;
if (COFF::isReservedSectionNumber(Index))
- Result = nullptr;
- else if (Index > 0 && static_cast<uint32_t>(Index) <= getNumberOfSections())
+ return object_error::success;
+ if (static_cast<uint32_t>(Index) <= getNumberOfSections()) {
// We already verified the section table data, so no need to check again.
Result = SectionTable + (Index - 1);
- else
- return object_error::parse_failed;
- return object_error::success;
+ return object_error::success;
+ }
+ return object_error::parse_failed;
}
std::error_code COFFObjectFile::getString(uint32_t Offset,
symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
const coff_relocation *R = toRel(Rel);
DataRefImpl Ref;
+ if (R->SymbolTableIndex >= getNumberOfSymbols())
+ return symbol_end();
if (SymbolTable16)
Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex);
else if (SymbolTable32)
void COFFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); }
-static StringRef getSectionName(const llvm::object::COFFObjectFile *Obj,
- COFFSymbolRef Symbol,
- const coff_section *Section) {
+static ErrorOr<StringRef>
+getSectionName(const llvm::object::COFFObjectFile *Obj, int32_t SectionNumber,
+ const coff_section *Section) {
if (Section) {
StringRef SectionName;
- Obj->getSectionName(Section, SectionName);
+ if (std::error_code EC = Obj->getSectionName(Section, SectionName))
+ return EC;
return SectionName;
}
- int32_t SectionNumber = Symbol.getSectionNumber();
if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
- return "IMAGE_SYM_DEBUG";
+ return StringRef("IMAGE_SYM_DEBUG");
if (SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE)
- return "IMAGE_SYM_ABSOLUTE";
+ return StringRef("IMAGE_SYM_ABSOLUTE");
if (SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED)
- return "IMAGE_SYM_UNDEFINED";
- return "";
+ return StringRef("IMAGE_SYM_UNDEFINED");
+ return StringRef("");
}
void COFFDumper::printSymbol(const SymbolRef &Sym) {
if (Obj->getSymbolName(Symbol, SymbolName))
SymbolName = "";
- StringRef SectionName = getSectionName(Obj, Symbol, Section);
+ StringRef SectionName = "";
+ ErrorOr<StringRef> Res =
+ getSectionName(Obj, Symbol.getSectionNumber(), Section);
+ if (Res)
+ SectionName = *Res;
W.printString("Name", SymbolName);
W.printNumber("Value", Symbol.getValue());
if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT
&& Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
const coff_section *Assoc;
- StringRef AssocName;
- std::error_code EC;
- if ((EC = Obj->getSection(AuxNumber, Assoc)) ||
- (EC = Obj->getSectionName(Assoc, AssocName))) {
+ StringRef AssocName = "";
+ std::error_code EC = Obj->getSection(AuxNumber, Assoc);
+ ErrorOr<StringRef> Res = getSectionName(Obj, AuxNumber, Assoc);
+ if (Res)
+ AssocName = *Res;
+ if (!EC)
+ EC = Res.getError();
+ if (EC) {
AssocName = "";
error(EC);
}