[BOLT] Add interface to extract values from static addresses

(cherry picked from FBD14858028)
This commit is contained in:
Maksim Panchenko
2019-04-09 12:29:40 -07:00
parent 7d89b113d8
commit a8e05d067d
7 changed files with 50 additions and 31 deletions

View File

@@ -1079,17 +1079,35 @@ BinarySection &BinaryContext::absoluteSection() {
}
ErrorOr<uint64_t>
BinaryContext::extractPointerAtAddress(uint64_t Address) const {
auto Section = getSectionForAddress(Address);
BinaryContext::getUnsignedValueAtAddress(uint64_t Address,
size_t Size) const {
const auto Section = getSectionForAddress(Address);
if (!Section)
return std::make_error_code(std::errc::bad_address);
StringRef SectionContents = Section->getContents();
DataExtractor DE(SectionContents,
AsmInfo->isLittleEndian(),
if (Section->isVirtual())
return 0;
DataExtractor DE(Section->getContents(), AsmInfo->isLittleEndian(),
AsmInfo->getCodePointerSize());
uint32_t SectionOffset = Address - Section->getAddress();
return DE.getAddress(&SectionOffset);
auto ValueOffset = static_cast<uint32_t>(Address - Section->getAddress());
return DE.getUnsigned(&ValueOffset, Size);
}
ErrorOr<uint64_t>
BinaryContext::getSignedValueAtAddress(uint64_t Address,
size_t Size) const {
const auto Section = getSectionForAddress(Address);
if (!Section)
return std::make_error_code(std::errc::bad_address);
if (Section->isVirtual())
return 0;
DataExtractor DE(Section->getContents(), AsmInfo->isLittleEndian(),
AsmInfo->getCodePointerSize());
auto ValueOffset = static_cast<uint32_t>(Address - Section->getAddress());
return DE.getSigned(&ValueOffset, Size);
}
void BinaryContext::addRelocation(uint64_t Address,

View File

@@ -731,10 +731,20 @@ public:
return std::make_error_code(std::errc::bad_address);
}
/// Given \p Address in the binary, extract and return a pointer value at that
/// address. The address has to be a valid statically allocated address for
/// the binary.
ErrorOr<uint64_t> extractPointerAtAddress(uint64_t Address) const;
/// Return an unsigned value of \p Size stored at \p Address. The address has
/// to be a valid statically allocated address for the binary.
ErrorOr<uint64_t> getUnsignedValueAtAddress(uint64_t Address,
size_t Size) const;
/// Return a signed value of \p Size stored at \p Address. The address has
/// to be a valid statically allocated address for the binary.
ErrorOr<uint64_t> getSignedValueAtAddress(uint64_t Address,
size_t Size) const;
/// Special case of getUnsignedValueAtAddress() that uses a pointer size.
ErrorOr<uint64_t> getPointerAtAddress(uint64_t Address) const {
return getUnsignedValueAtAddress(Address, AsmInfo->getCodePointerSize());
}
/// Replaces all references to \p ChildBF with \p ParentBF. \p ChildBF is then
/// removed from the list of functions \p BFs. The profile data of \p ChildBF

View File

@@ -266,7 +266,7 @@ void BinaryFunction::parseLSDA(ArrayRef<uint8_t> LSDASectionData,
return;
}
if (TTypeEncoding & DW_EH_PE_indirect) {
auto PointerOrErr = BC.extractPointerAtAddress(TypeAddress);
auto PointerOrErr = BC.getPointerAtAddress(TypeAddress);
assert(PointerOrErr && "failed to decode indirect address");
TypeAddress = *PointerOrErr;
}
@@ -349,9 +349,8 @@ void BinaryFunction::parseLSDA(ArrayRef<uint8_t> LSDASectionData,
if ((TTypeEncoding & DW_EH_PE_pcrel) && (TypeAddress == TTEntryAddress)) {
TypeAddress = 0;
}
if (TypeAddress &&
(TTypeEncoding & DW_EH_PE_indirect)) {
auto PointerOrErr = BC.extractPointerAtAddress(TypeAddress);
if (TypeAddress && (TTypeEncoding & DW_EH_PE_indirect)) {
auto PointerOrErr = BC.getPointerAtAddress(TypeAddress);
assert(PointerOrErr && "failed to decode indirect address");
TypeAddress = *PointerOrErr;
}

View File

@@ -647,7 +647,7 @@ IndirectCallPromotion::maybeGetVtableSyms(
<< "+" << MethodOffset << "/" << MI.Count
<< "\n");
if (auto MethodAddr = BC.extractPointerAtAddress(Address)) {
if (auto MethodAddr = BC.getPointerAtAddress(Address)) {
auto *MethodBD = BC.getBinaryDataAtAddress(MethodAddr.get());
if (!MethodBD) // skip unknown methods
continue;

View File

@@ -1838,7 +1838,6 @@ int64_t getRelocationAddend(const ELFObjectFileBase *Obj,
} // anonymous namespace
bool RewriteInstance::analyzeRelocation(const RelocationRef &Rel,
SectionRef RelocatedSection,
std::string &SymbolName,
bool &IsSectionRelocation,
uint64_t &SymbolAddress,
@@ -1849,16 +1848,11 @@ bool RewriteInstance::analyzeRelocation(const RelocationRef &Rel,
const bool IsAArch64 = BC->isAArch64();
// Extract the value.
StringRef RelocatedSectionContents;
RelocatedSection.getContents(RelocatedSectionContents);
DataExtractor DE(RelocatedSectionContents,
BC->AsmInfo->isLittleEndian(),
BC->AsmInfo->getCodePointerSize());
uint32_t RelocationOffset = Rel.getOffset() - RelocatedSection.getAddress();
const auto RelSize = Relocation::getSizeForType(Rel.getType());
ExtractedValue = static_cast<uint64_t>(DE.getSigned(&RelocationOffset,
RelSize));
auto Value = BC->getUnsignedValueAtAddress(Rel.getOffset(), RelSize);
assert(Value && "failed to extract relocated value");
ExtractedValue = *Value;
if (IsAArch64) {
ExtractedValue = Relocation::extractValue(Rel.getType(),
ExtractedValue,
@@ -1867,7 +1861,7 @@ bool RewriteInstance::analyzeRelocation(const RelocationRef &Rel,
Addend = getRelocationAddend(InputFile, Rel);
const bool IsPCRelative = Relocation::isPCRelative(Rel.getType());
const auto IsPCRelative = Relocation::isPCRelative(Rel.getType());
const auto PCRelOffset = IsPCRelative && !IsAArch64 ? Rel.getOffset() : 0;
bool SkipVerification = false;
auto SymbolIter = Rel.getSymbol();
@@ -2026,7 +2020,6 @@ void RewriteInstance::readRelocations(const SectionRef &Section) {
uint64_t ExtractedValue;
bool IsSectionRelocation;
if (!analyzeRelocation(Rel,
RelocatedSection,
SymbolName,
IsSectionRelocation,
SymbolAddress,

View File

@@ -163,12 +163,11 @@ private:
/// Make .eh_frame section relocatable.
void relocateEHFrameSection();
/// Analyze relocation \p Rel contained in section \p RelocatedSection.
/// Analyze relocation \p Rel.
/// Return true if the relocation was successfully processed, false otherwise.
/// The \p SymbolName, \p SymbolAddress, \p Addend and \p ExtractedValue
/// parameters will be set on success.
bool analyzeRelocation(const RelocationRef &Rel,
SectionRef RelocatedSection,
std::string &SymbolName,
bool &IsSectionRelocation,
uint64_t &SymbolAddress,

View File

@@ -1893,7 +1893,7 @@ public:
assert(Offset + I.DataSize <= ConstantData.size() &&
"invalid offset for given constant data");
int64_t ImmVal =
DataExtractor(ConstantData, true, 64).getSigned(&Offset, I.DataSize);
DataExtractor(ConstantData, true, 8).getSigned(&Offset, I.DataSize);
// Compute the new opcode.
unsigned NewOpcode = 0;