diff --git a/bolt/BinaryFunction.cpp b/bolt/BinaryFunction.cpp index 480c154084fb..71445f4d37ad 100644 --- a/bolt/BinaryFunction.cpp +++ b/bolt/BinaryFunction.cpp @@ -13,6 +13,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" #include "llvm/Object/ObjectFile.h" @@ -166,9 +167,9 @@ bool BinaryFunction::disassemble(ArrayRef FunctionData) { break; } + uint64_t AbsoluteInstrAddr = getAddress() + Offset; if (MIA->isBranch(Instruction) || MIA->isCall(Instruction)) { uint64_t InstructionTarget = 0; - uint64_t AbsoluteInstrAddr = getAddress() + Offset; if (MIA->evaluateBranch(Instruction, AbsoluteInstrAddr, Size, @@ -242,15 +243,45 @@ bool BinaryFunction::disassemble(ArrayRef FunctionData) { } else { // Indirect call + DEBUG(dbgs() << "FLO: indirect call detected (not yet supported)\n"); IsSimple = false; break; } } else { if (MIA->hasRIPOperand(Instruction)) { - DEBUG(dbgs() << "FLO: rip-relative instruction found " - "(not supported yet)\n"); - IsSimple = false; - break; + uint64_t TargetAddress{0}; + MCSymbol *TargetSymbol{nullptr}; + if (!MIA->evaluateRIPOperand(Instruction, AbsoluteInstrAddr, + Size, TargetAddress)) { + DEBUG( + dbgs() << "FLO: rip-relative operand could not be evaluated:\n"; + BC.InstPrinter->printInst(&Instruction, dbgs(), "", *BC.STI); + dbgs() << '\n'; + Instruction.dump_pretty(dbgs(), BC.InstPrinter.get()); + dbgs() << '\n'; + ); + IsSimple = false; + break; + } + std::string Name; + auto NI = BC.GlobalAddresses.find(TargetAddress); + if (NI != BC.GlobalAddresses.end()) { + Name = NI->second; + } else { + // Register new "data" symbol at the destination. + Name = (Twine("DATAat0x") + Twine::utohexstr(TargetAddress)).str(); + BC.GlobalAddresses.emplace(std::make_pair(TargetAddress, + Name)); + } + TargetSymbol = Ctx->getOrCreateSymbol(Name); + BC.GlobalSymbols[Name] = TargetAddress; + + MIA->replaceRIPOperandDisp( + Instruction, + MCOperand::createExpr( + MCSymbolRefExpr::create(TargetSymbol, + MCSymbolRefExpr::VK_None, + *Ctx))); } } diff --git a/bolt/llvm-flo.cpp b/bolt/llvm-flo.cpp index 3196b85c9db0..ebcb1be73372 100644 --- a/bolt/llvm-flo.cpp +++ b/bolt/llvm-flo.cpp @@ -312,13 +312,19 @@ static void OptimizeFile(ELFObjectFileBase *File) { FileSymRefs[Address] = Symbol; + // There's nothing horribly wrong with anonymous symbols, but let's + // ignore them for now. + if (Name->empty()) + continue; + + BC->GlobalAddresses.emplace(std::make_pair(Address, *Name)); + // Only consider ST_Function symbols for functions. Although this // assumption could be broken by assembly functions for which the type - // could be wrong. - if (Symbol.getType() != SymbolRef::ST_Function) { - // FIXME: add it to the address map. + // could be wrong, we skip such entries till the support for + // assembly is implemented. + if (Symbol.getType() != SymbolRef::ST_Function) continue; - } // TODO: populate address map with PLT entries for better readability. @@ -327,11 +333,6 @@ static void OptimizeFile(ELFObjectFileBase *File) { if (SymbolSize == 0) continue; - // There's nothing horribly wrong with anonymous symbols, but let's - // ignore them for now. - if (Name->empty()) - continue; - ErrorOr SectionOrErr = Symbol.getSection(); error(SectionOrErr.getError()); section_iterator Section = *SectionOrErr;