Skip to content

Commit

Permalink
Improve PIC thunk handling.
Browse files Browse the repository at this point in the history
Copy the PC to the target register for common thunk forms.
  • Loading branch information
morehouse committed Oct 27, 2016
1 parent a8252fd commit 23e0691
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
4 changes: 2 additions & 2 deletions dataflowAPI/h/stackanalysis.h
Expand Up @@ -71,7 +71,6 @@ namespace Dyninst {
class Expression;
};


class StackAnalysis {
public:
typedef boost::shared_ptr<InstructionAPI::Instruction> InstructionPtr;
Expand Down Expand Up @@ -389,7 +388,8 @@ class StackAnalysis {
bool isJump(InstructionPtr insn);
bool handleNormalCall(InstructionPtr insn, ParseAPI::Block *block,
Offset off, TransferFuncs &xferFuncs, TransferSet &funcSummary);
bool handleThunkCall(InstructionPtr insn, TransferFuncs &xferFuncs);
bool handleThunkCall(InstructionPtr insn, ParseAPI::Block *block,
const Offset off, TransferFuncs &xferFuncs);
bool handleJump(InstructionPtr insn, ParseAPI::Block *block,
Offset off, TransferFuncs &xferFuncs, TransferSet &funcSummary);
void handlePushPop(InstructionPtr insn, ParseAPI::Block *block,
Expand Down
21 changes: 17 additions & 4 deletions dataflowAPI/src/stackanalysis.C
Expand Up @@ -548,7 +548,7 @@ void StackAnalysis::computeInsnEffects(ParseAPI::Block *block,
// Cases we handle
if (isCall(insn)) {
if (handleNormalCall(insn, block, off, xferFuncs, funcSummary)) return;
else if (handleThunkCall(insn, xferFuncs)) return;
else if (handleThunkCall(insn, block, off, xferFuncs)) return;
else return handleDefault(insn, block, off, xferFuncs);
}

Expand Down Expand Up @@ -2511,8 +2511,8 @@ bool StackAnalysis::handleJump(Instruction::Ptr insn, Block *block, Offset off,
return true;
}

bool StackAnalysis::handleThunkCall(Instruction::Ptr insn,
TransferFuncs &xferFuncs) {
bool StackAnalysis::handleThunkCall(Instruction::Ptr insn, Block *block,
const Offset off, TransferFuncs &xferFuncs) {

// We know that we're not a normal call, so it depends on whether the CFT is
// "next instruction" or not.
Expand All @@ -2529,10 +2529,23 @@ bool StackAnalysis::handleThunkCall(Instruction::Ptr insn,
Absloc sploc(sp());
xferFuncs.push_back(TransferFunc::deltaFunc(sploc, -1 * word_size));
copyBaseSubReg(sp(), xferFuncs);
return true;
}
// Else we're calling a mov, ret thunk that has no effect on the stack
// pointer

// Check the next instruction to see which register is holding the PC.
// Assumes next instruction is add thunk_reg, offset.
const Address pc = off + insn->size();
Instruction::Ptr thunkAddInsn = block->getInsn(pc);
if (thunkAddInsn == Instruction::Ptr()) return true;
if (thunkAddInsn->getOperation().getID() != e_add) return true;
std::set<RegisterAST::Ptr> writtenRegs;
thunkAddInsn->getOperand(0).getWriteSet(writtenRegs);
if (writtenRegs.size() != 1) return true;
const MachRegister &thunkTarget = (*writtenRegs.begin())->getID();

xferFuncs.push_back(TransferFunc::absFunc(Absloc(thunkTarget), pc));
copyBaseSubReg(thunkTarget, xferFuncs);
return true;
}

Expand Down

0 comments on commit 23e0691

Please sign in to comment.