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();
}
ErrorOr<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
if (std::error_code EC = getSection(SectionNumber, Section))
return EC;
Result += Section->VirtualAddress;
+
+ // The section VirtualAddress does not include ImageBase, and we want to
+ // return virtual addresses.
+ Result += getImageBase();
+
return Result;
}
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 {
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;
}
reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
}
-ErrorOr<uint64_t> COFFObjectFile::getRelocationAddress(DataRefImpl Rel) const {
- report_fatal_error("getRelocationAddress not implemented in COFFObjectFile");
-}
-
uint64_t COFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
const coff_relocation *R = toRel(Rel);
return R->VirtualAddress;