FLO: added support for rip-relative operands.

Summary: Detect and replace rip-relative operands with relocations.

(cherry picked from FBD2529818)
This commit is contained in:
Maksim Panchenko
2015-10-09 21:47:18 -07:00
parent f166c4ab2b
commit ffcc2be7fa
2 changed files with 46 additions and 14 deletions

View File

@@ -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<uint8_t> 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<uint8_t> 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)));
}
}

View File

@@ -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<section_iterator> SectionOrErr = Symbol.getSection();
error(SectionOrErr.getError());
section_iterator Section = *SectionOrErr;