mirror of
https://github.com/intel/llvm.git
synced 2026-01-14 03:50:17 +08:00
[BOLT] Add interface to extract values from static addresses
(cherry picked from FBD14858028)
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user