#include "bolt/Core/BinaryContext.h"
#include "bolt/Core/BinaryEmitter.h"
#include "bolt/Core/BinaryFunction.h"
#include "bolt/Utils/CommandLineOpts.h"
#include "bolt/Utils/Utils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Regex.h"
#include <algorithm>
#include <functional>
#include <iterator>
#include <unordered_set>
usingnamespacellvm;
#undef DEBUG_TYPE
#define DEBUG_TYPE …
namespace opts {
cl::opt<bool> NoHugePages("no-huge-pages",
cl::desc("use regular size pages for code alignment"),
cl::Hidden, cl::cat(BoltCategory));
static cl::opt<bool>
PrintDebugInfo("print-debug-info",
cl::desc("print debug info when printing functions"),
cl::Hidden,
cl::ZeroOrMore,
cl::cat(BoltCategory));
cl::opt<bool> PrintRelocations(
"print-relocations",
cl::desc("print relocations when printing functions/objects"), cl::Hidden,
cl::cat(BoltCategory));
static cl::opt<bool>
PrintMemData("print-mem-data",
cl::desc("print memory data annotations when printing functions"),
cl::Hidden,
cl::ZeroOrMore,
cl::cat(BoltCategory));
cl::opt<std::string> CompDirOverride(
"comp-dir-override",
cl::desc("overrides DW_AT_comp_dir, and provides an alternative base "
"location, which is used with DW_AT_dwo_name to construct a path "
"to *.dwo files."),
cl::Hidden, cl::init(""), cl::cat(BoltCategory));
}
namespace llvm {
namespace bolt {
char BOLTError::ID = …;
BOLTError::BOLTError(bool IsFatal, const Twine &S)
: … { … }
void BOLTError::log(raw_ostream &OS) const { … }
std::error_code BOLTError::convertToErrorCode() const { … }
Error createNonFatalBOLTError(const Twine &S) { … }
Error createFatalBOLTError(const Twine &S) { … }
void BinaryContext::logBOLTErrorsAndQuitOnFatal(Error E) { … }
BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
std::unique_ptr<DWARFContext> DwCtx,
std::unique_ptr<Triple> TheTriple,
const Target *TheTarget, std::string TripleName,
std::unique_ptr<MCCodeEmitter> MCE,
std::unique_ptr<MCObjectFileInfo> MOFI,
std::unique_ptr<const MCAsmInfo> AsmInfo,
std::unique_ptr<const MCInstrInfo> MII,
std::unique_ptr<const MCSubtargetInfo> STI,
std::unique_ptr<MCInstPrinter> InstPrinter,
std::unique_ptr<const MCInstrAnalysis> MIA,
std::unique_ptr<MCPlusBuilder> MIB,
std::unique_ptr<const MCRegisterInfo> MRI,
std::unique_ptr<MCDisassembler> DisAsm,
JournalingStreams Logger)
: … { … }
BinaryContext::~BinaryContext() { … }
Expected<std::unique_ptr<BinaryContext>> BinaryContext::createBinaryContext(
Triple TheTriple, StringRef InputFileName, SubtargetFeatures *Features,
bool IsPIC, std::unique_ptr<DWARFContext> DwCtx, JournalingStreams Logger) { … }
bool BinaryContext::forceSymbolRelocations(StringRef SymbolName) const { … }
std::unique_ptr<MCObjectWriter>
BinaryContext::createObjectWriter(raw_pwrite_stream &OS) { … }
bool BinaryContext::validateObjectNesting() const { … }
bool BinaryContext::validateHoles() const { … }
void BinaryContext::updateObjectNesting(BinaryDataMapType::iterator GAI) { … }
iterator_range<BinaryContext::binary_data_iterator>
BinaryContext::getSubBinaryData(BinaryData *BD) { … }
std::pair<const MCSymbol *, uint64_t>
BinaryContext::handleAddressRef(uint64_t Address, BinaryFunction &BF,
bool IsPCRel) { … }
MemoryContentsType BinaryContext::analyzeMemoryAt(uint64_t Address,
BinaryFunction &BF) { … }
bool BinaryContext::analyzeJumpTable(const uint64_t Address,
const JumpTable::JumpTableType Type,
const BinaryFunction &BF,
const uint64_t NextJTAddress,
JumpTable::AddressesType *EntriesAsAddress,
bool *HasEntryInFragment) const { … }
void BinaryContext::populateJumpTables() { … }
void BinaryContext::skipMarkedFragments() { … }
MCSymbol *BinaryContext::getOrCreateGlobalSymbol(uint64_t Address, Twine Prefix,
uint64_t Size,
uint16_t Alignment,
unsigned Flags) { … }
MCSymbol *BinaryContext::getOrCreateUndefinedGlobalSymbol(StringRef Name) { … }
BinaryFunction *BinaryContext::createBinaryFunction(
const std::string &Name, BinarySection &Section, uint64_t Address,
uint64_t Size, uint64_t SymbolSize, uint16_t Alignment) { … }
const MCSymbol *
BinaryContext::getOrCreateJumpTable(BinaryFunction &Function, uint64_t Address,
JumpTable::JumpTableType Type) { … }
std::pair<uint64_t, const MCSymbol *>
BinaryContext::duplicateJumpTable(BinaryFunction &Function, JumpTable *JT,
const MCSymbol *OldLabel) { … }
std::string BinaryContext::generateJumpTableName(const BinaryFunction &BF,
uint64_t Address) { … }
bool BinaryContext::hasValidCodePadding(const BinaryFunction &BF) { … }
void BinaryContext::adjustCodePadding() { … }
MCSymbol *BinaryContext::registerNameAtAddress(StringRef Name, uint64_t Address,
uint64_t Size,
uint16_t Alignment,
unsigned Flags) { … }
const BinaryData *
BinaryContext::getBinaryDataContainingAddressImpl(uint64_t Address) const { … }
BinaryData *BinaryContext::getGOTSymbol() { … }
bool BinaryContext::setBinaryDataSize(uint64_t Address, uint64_t Size) { … }
void BinaryContext::generateSymbolHashes() { … }
bool BinaryContext::registerFragment(BinaryFunction &TargetFunction,
BinaryFunction &Function) { … }
void BinaryContext::addAdrpAddRelocAArch64(BinaryFunction &BF,
MCInst &LoadLowBits,
MCInst &LoadHiBits,
uint64_t Target) { … }
bool BinaryContext::handleAArch64Veneer(uint64_t Address, bool MatchOnly) { … }
void BinaryContext::processInterproceduralReferences() { … }
void BinaryContext::postProcessSymbolTable() { … }
void BinaryContext::foldFunction(BinaryFunction &ChildBF,
BinaryFunction &ParentBF) { … }
void BinaryContext::fixBinaryDataHoles() { … }
void BinaryContext::printGlobalSymbols(raw_ostream &OS) const { … }
Expected<unsigned> BinaryContext::getDwarfFile(
StringRef Directory, StringRef FileName, unsigned FileNumber,
std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
unsigned CUID, unsigned DWARFVersion) { … }
unsigned BinaryContext::addDebugFilenameToUnit(const uint32_t DestCUID,
const uint32_t SrcCUID,
unsigned FileIndex) { … }
std::vector<BinaryFunction *> BinaryContext::getSortedFunctions() { … }
std::vector<BinaryFunction *> BinaryContext::getAllBinaryFunctions() { … }
std::optional<DWARFUnit *> BinaryContext::getDWOCU(uint64_t DWOId) { … }
DWARFContext *BinaryContext::getDWOContext() const { … }
void BinaryContext::preprocessDWODebugInfo() { … }
void BinaryContext::preprocessDebugInfo() { … }
bool BinaryContext::shouldEmit(const BinaryFunction &Function) const { … }
void BinaryContext::dump(const MCInst &Inst) const { … }
void BinaryContext::printCFI(raw_ostream &OS, const MCCFIInstruction &Inst) { … }
MarkerSymType BinaryContext::getMarkerType(const SymbolRef &Symbol) const { … }
bool BinaryContext::isMarker(const SymbolRef &Symbol) const { … }
static void printDebugInfo(raw_ostream &OS, const MCInst &Instruction,
const BinaryFunction *Function,
DWARFContext *DwCtx) { … }
void BinaryContext::printInstruction(raw_ostream &OS, const MCInst &Instruction,
uint64_t Offset,
const BinaryFunction *Function,
bool PrintMCInst, bool PrintMemData,
bool PrintRelocations,
StringRef Endl) const { … }
std::optional<uint64_t>
BinaryContext::getBaseAddressForMapping(uint64_t MMapAddress,
uint64_t FileOffset) const { … }
ErrorOr<BinarySection &> BinaryContext::getSectionForAddress(uint64_t Address) { … }
ErrorOr<StringRef>
BinaryContext::getSectionNameForAddress(uint64_t Address) const { … }
BinarySection &BinaryContext::registerSection(BinarySection *Section) { … }
BinarySection &BinaryContext::registerSection(SectionRef Section) { … }
BinarySection &
BinaryContext::registerSection(const Twine &SectionName,
const BinarySection &OriginalSection) { … }
BinarySection &
BinaryContext::registerOrUpdateSection(const Twine &Name, unsigned ELFType,
unsigned ELFFlags, uint8_t *Data,
uint64_t Size, unsigned Alignment) { … }
void BinaryContext::deregisterSectionName(const BinarySection &Section) { … }
void BinaryContext::deregisterUnusedSections() { … }
bool BinaryContext::deregisterSection(BinarySection &Section) { … }
void BinaryContext::renameSection(BinarySection &Section,
const Twine &NewName) { … }
void BinaryContext::printSections(raw_ostream &OS) const { … }
BinarySection &BinaryContext::absoluteSection() { … }
ErrorOr<uint64_t> BinaryContext::getUnsignedValueAtAddress(uint64_t Address,
size_t Size) const { … }
ErrorOr<int64_t> BinaryContext::getSignedValueAtAddress(uint64_t Address,
size_t Size) const { … }
void BinaryContext::addRelocation(uint64_t Address, MCSymbol *Symbol,
uint64_t Type, uint64_t Addend,
uint64_t Value) { … }
void BinaryContext::addDynamicRelocation(uint64_t Address, MCSymbol *Symbol,
uint64_t Type, uint64_t Addend,
uint64_t Value) { … }
bool BinaryContext::removeRelocationAt(uint64_t Address) { … }
const Relocation *BinaryContext::getRelocationAt(uint64_t Address) const { … }
const Relocation *
BinaryContext::getDynamicRelocationAt(uint64_t Address) const { … }
void BinaryContext::markAmbiguousRelocations(BinaryData &BD,
const uint64_t Address) { … }
BinaryFunction *BinaryContext::getFunctionForSymbol(const MCSymbol *Symbol,
uint64_t *EntryDesc) { … }
std::string
BinaryContext::generateBugReportMessage(StringRef Message,
const BinaryFunction &Function) const { … }
BinaryFunction *
BinaryContext::createInjectedBinaryFunction(const std::string &Name,
bool IsSimple) { … }
std::pair<size_t, size_t>
BinaryContext::calculateEmittedSize(BinaryFunction &BF, bool FixBranches) { … }
bool BinaryContext::validateInstructionEncoding(
ArrayRef<uint8_t> InputSequence) const { … }
uint64_t BinaryContext::getHotThreshold() const { … }
BinaryFunction *BinaryContext::getBinaryFunctionContainingAddress(
uint64_t Address, bool CheckPastEnd, bool UseMaxSize) { … }
BinaryFunction *BinaryContext::getBinaryFunctionAtAddress(uint64_t Address) { … }
void BinaryContext::deleteJumpTable(uint64_t Address) { … }
DebugAddressRangesVector BinaryContext::translateModuleAddressRanges(
const DWARFAddressRangesVector &InputRanges) const { … }
}
}