}
}
-std::error_code COFFObjectFile::getSymbolName(DataRefImpl Ref,
- StringRef &Result) const {
+ErrorOr<StringRef> COFFObjectFile::getSymbolName(DataRefImpl Ref) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
- return getSymbolName(Symb, Result);
+ StringRef Result;
+ std::error_code EC = getSymbolName(Symb, Result);
+ if (EC)
+ return EC;
+ return Result;
}
-uint64_t COFFObjectFile::getSymbolValue(DataRefImpl Ref) const {
- COFFSymbolRef Sym = getCOFFSymbol(Ref);
-
- if (Sym.isAnyUndefined() || Sym.isCommon())
- return UnknownAddress;
-
- return Sym.getValue();
+uint64_t COFFObjectFile::getSymbolValueImpl(DataRefImpl Ref) const {
+ return getCOFFSymbol(Ref).getValue();
}
-std::error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref,
- uint64_t &Result) const {
- Result = getSymbolValue(Ref);
+ErrorOr<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
+ uint64_t Result = getSymbolValue(Ref);
COFFSymbolRef Symb = getCOFFSymbol(Ref);
int32_t SectionNumber = Symb.getSectionNumber();
if (Symb.isAnyUndefined() || Symb.isCommon() ||
COFF::isReservedSectionNumber(SectionNumber))
- return std::error_code();
+ return Result;
const coff_section *Section = nullptr;
if (std::error_code EC = getSection(SectionNumber, Section))
return EC;
Result += Section->VirtualAddress;
- return std::error_code();
+
+ // The section VirtualAddress does not include ImageBase, and we want to
+ // return virtual addresses.
+ Result += getImageBase();
+
+ return Result;
}
SymbolRef::Type COFFObjectFile::getSymbolType(DataRefImpl Ref) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
int32_t SectionNumber = Symb.getSectionNumber();
+ if (Symb.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION)
+ return SymbolRef::ST_Function;
if (Symb.isAnyUndefined())
return SymbolRef::ST_Unknown;
- if (Symb.isFunctionDefinition())
- return SymbolRef::ST_Function;
if (Symb.isCommon())
return SymbolRef::ST_Data;
if (Symb.isFileRecord())
return Symb.getValue();
}
-std::error_code
-COFFObjectFile::getSymbolSection(DataRefImpl Ref,
- section_iterator &Result) const {
+ErrorOr<section_iterator>
+COFFObjectFile::getSymbolSection(DataRefImpl Ref) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
- if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) {
- Result = section_end();
- } else {
- const coff_section *Sec = nullptr;
- if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec))
- return EC;
- DataRefImpl Ref;
- Ref.p = reinterpret_cast<uintptr_t>(Sec);
- Result = section_iterator(SectionRef(Ref, this));
- }
- return std::error_code();
+ if (COFF::isReservedSectionNumber(Symb.getSectionNumber()))
+ return section_end();
+ const coff_section *Sec = nullptr;
+ if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec))
+ return EC;
+ DataRefImpl Ret;
+ Ret.p = reinterpret_cast<uintptr_t>(Sec);
+ return section_iterator(SectionRef(Ret, this));
}
unsigned COFFObjectFile::getSymbolSectionID(SymbolRef Sym) const {
uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Ref) const {
const coff_section *Sec = toSec(Ref);
- return Sec->VirtualAddress;
+ uint64_t Result = Sec->VirtualAddress;
+
+ // The section VirtualAddress does not include ImageBase, and we want to
+ // return virtual addresses.
+ Result += getImageBase();
+ return Result;
}
uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const {
return Sec->PointerToRawData == 0;
}
-bool COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
- DataRefImpl SymbRef) const {
- const coff_section *Sec = toSec(SecRef);
- COFFSymbolRef Symb = getCOFFSymbol(SymbRef);
- int32_t SecNumber = (Sec - SectionTable) + 1;
- return SecNumber == Symb.getSectionNumber();
-}
-
static uint32_t getNumberOfRelocations(const coff_section *Sec,
MemoryBufferRef M, const uint8_t *base) {
// The field for the number of relocations in COFF section table is only
relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const {
const coff_section *Sec = toSec(Ref);
const coff_relocation *begin = getFirstReloc(Sec, Data, base());
+ if (begin && Sec->VirtualAddress != 0)
+ report_fatal_error("Sections with relocations should have an address of 0");
DataRefImpl Ret;
Ret.p = reinterpret_cast<uintptr_t>(begin);
return relocation_iterator(RelocationRef(Ret, this));
return std::error_code();
}
+uint64_t COFFObjectFile::getImageBase() const {
+ if (PE32Header)
+ return PE32Header->ImageBase;
+ else if (PE32PlusHeader)
+ return PE32PlusHeader->ImageBase;
+ // This actually comes up in practice.
+ return 0;
+}
+
// Returns the file offset for the given VA.
std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
- uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase
- : (uint64_t)PE32PlusHeader->ImageBase;
+ uint64_t ImageBase = getImageBase();
uint64_t Rva = Addr - ImageBase;
assert(Rva <= UINT32_MAX);
return getRvaPtr((uint32_t)Rva, Res);
return "COFF-x86-64";
case COFF::IMAGE_FILE_MACHINE_ARMNT:
return "COFF-ARM";
+ case COFF::IMAGE_FILE_MACHINE_ARM64:
+ return "COFF-ARM64";
default:
return "COFF-<unknown arch>";
}
return Triple::x86_64;
case COFF::IMAGE_FILE_MACHINE_ARMNT:
return Triple::thumb;
+ case COFF::IMAGE_FILE_MACHINE_ARM64:
+ return Triple::aarch64;
default:
return Triple::UnknownArch;
}
std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol,
StringRef &Res) const {
+ return getSymbolName(Symbol.getGeneric(), Res);
+}
+
+std::error_code COFFObjectFile::getSymbolName(const coff_symbol_generic *Symbol,
+ StringRef &Res) const {
// Check for string table entry. First 4 bytes are 0.
- if (Symbol.getStringTableOffset().Zeroes == 0) {
- uint32_t Offset = Symbol.getStringTableOffset().Offset;
- if (std::error_code EC = getString(Offset, Res))
+ 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.getShortName()[COFF::NameSize - 1] == 0)
+ if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0)
// Null terminated, let ::strlen figure out the length.
- Res = StringRef(Symbol.getShortName());
+ Res = StringRef(Symbol->Name.ShortName);
else
// Not null terminated, use all 8 bytes.
- Res = StringRef(Symbol.getShortName(), COFF::NameSize);
+ Res = StringRef(Symbol->Name.ShortName, COFF::NameSize);
return std::error_code();
}
// whether or not we have an executable image.
//
// For object files, SizeOfRawData contains the size of section's data;
- // VirtualSize is always zero.
+ // VirtualSize should be zero but isn't due to buggy COFF writers.
//
// For executables, SizeOfRawData *must* be a multiple of FileAlignment; the
// actual section size is in VirtualSize. It is possible for VirtualSize to
// be greater than SizeOfRawData; the contents past that point should be
// considered to be zero.
- uint32_t SectionSize;
- if (Sec->VirtualSize)
- SectionSize = std::min(Sec->VirtualSize, Sec->SizeOfRawData);
- else
- SectionSize = Sec->SizeOfRawData;
-
- return SectionSize;
+ if (getDOSHeader())
+ return std::min(Sec->VirtualSize, Sec->SizeOfRawData);
+ return Sec->SizeOfRawData;
}
std::error_code
reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
}
-std::error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel,
- uint64_t &Res) const {
- report_fatal_error("getRelocationAddress not implemented in COFFObjectFile");
-}
-
-std::error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
- uint64_t &Res) const {
+uint64_t COFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
const coff_relocation *R = toRel(Rel);
- const support::ulittle32_t *VirtualAddressPtr;
- if (std::error_code EC =
- getObject(VirtualAddressPtr, Data, &R->VirtualAddress))
- return EC;
- Res = *VirtualAddressPtr;
- return std::error_code();
+ return R->VirtualAddress;
}
symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
return symbol_iterator(SymbolRef(Ref, this));
}
-std::error_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
- uint64_t &Res) const {
+uint64_t COFFObjectFile::getRelocationType(DataRefImpl Rel) const {
const coff_relocation* R = toRel(Rel);
- Res = R->Type;
- return std::error_code();
+ return R->Type;
}
const coff_section *
Res = #reloc_type; \
break;
-std::error_code
-COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const {
+void COFFObjectFile::getRelocationTypeName(
+ DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
const coff_relocation *Reloc = toRel(Rel);
StringRef Res;
switch (getMachine()) {
Res = "Unknown";
}
Result.append(Res.begin(), Res.end());
- return std::error_code();
}
#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME