Skip to content

Commit

Permalink
1. For ARM, add br as a branch instruction category and blr as a call…
Browse files Browse the repository at this point in the history
… instruction category. 2. Need to skip the first two PLT entry sizes on ARM 3. Only invoke new jump table parsing on x86. On power, we use the old heuristics. On ARM, we currently give up
  • Loading branch information
mxz297 committed May 27, 2016
1 parent 0f86fb4 commit 85cebd3
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 18 deletions.
2 changes: 2 additions & 0 deletions instructionAPI/src/InstructionCategories.C
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ namespace Dyninst
return c_ReturnInsn;
case e_call:
case aarch64_op_bl:
case aarch64_op_blr:
return c_CallInsn;
case e_jmp:
case e_jb:
Expand Down Expand Up @@ -76,6 +77,7 @@ namespace Dyninst
case aarch64_op_tbnz:
case aarch64_op_cbz:
case aarch64_op_cbnz:
case aarch64_op_br:
return c_BranchInsn;
case e_cmp:
case e_cmppd:
Expand Down
17 changes: 3 additions & 14 deletions parseAPI/src/IA_IAPI.C
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
#include "util.h"
#include "common/src/Types.h"
#include "dyntypes.h"
#include "IndirectAnalyzer.h"

#include <deque>
#include <map>
Expand Down Expand Up @@ -953,21 +952,11 @@ bool IA_IAPI::parseJumpTable(Dyninst::ParseAPI::Function * currFunc,
Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges) const
{
/*

// Call platform specific jump table parser
IA_platformDetails* jumpTableParser = makePlatformDetails(_isrc->getArch(), this);
bool ret = jumpTableParser->parseJumpTable(currBlk, outEdges);
bool ret = jumpTableParser->parseJumpTable(currFunc, currBlk, outEdges);
delete jumpTableParser;
*/


IndirectControlFlowAnalyzer icfa(currFunc, currBlk);
bool ret = icfa.NewJumpTableAnalysis(outEdges);

parsing_printf("Jump table parser returned %d, %d edges\n", ret, outEdges.size());
for (auto oit = outEdges.begin(); oit != outEdges.end(); ++oit) parsing_printf("edge target at %lx\n", oit->first);
// Update statistics
currBlk->obj()->cs()->incrementCounter(PARSE_JUMPTABLE_COUNT);
if (!ret) currBlk->obj()->cs()->incrementCounter(PARSE_JUMPTABLE_FAIL);

return ret;
}
Expand Down
9 changes: 9 additions & 0 deletions parseAPI/src/IA_aarch64Details.C
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,12 @@ bool IA_aarch64Details::parseJumpTable(Block* /*currBlk*/,
assert(0);
return true;
}

bool IA_aarch64Details::parseJumpTable(Dyninst::ParseAPI::Function* currFunc,
Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges)
{
parsing_printf("Jump table parsing not implmemented on ARM 64 yet\n");
return false;
}

4 changes: 4 additions & 0 deletions parseAPI/src/IA_aarch64Details.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ namespace Dyninst
virtual ~IA_aarch64Details() {}
virtual bool parseJumpTable(Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges);
virtual bool parseJumpTable(Dyninst::ParseAPI::Function* currFunc,
Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges);

private:
bool findTableAddrNoTOC(const IA_IAPI* blockToCheck);
bool parseRelativeTableIdiom();
Expand Down
4 changes: 4 additions & 0 deletions parseAPI/src/IA_platformDetails.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ namespace Dyninst
virtual ~IA_platformDetails() {}
virtual bool parseJumpTable(Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges) = 0;
virtual bool parseJumpTable(Dyninst::ParseAPI::Function * currFunc,
Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges) = 0;

protected:
const IA_IAPI* currentBlock;

Expand Down
7 changes: 7 additions & 0 deletions parseAPI/src/IA_powerDetails.C
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,13 @@ bool IA_powerDetails::findTableBase(IA_IAPI::allInsns_t::const_iterator start,
return true;
}

bool IA_powerDetails::parseJumpTable(Function *,
Block* currBlk,
std::vector<std::pair< Address, EdgeTypeEnum> >& outEdges)
{
return parseJumpTable(currBlk, outEdges);
}



// This should only be called on a known indirect branch...
Expand Down
4 changes: 4 additions & 0 deletions parseAPI/src/IA_powerDetails.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ namespace Dyninst
virtual ~IA_powerDetails() {}
virtual bool parseJumpTable(Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges);
virtual bool parseJumpTable(Dyninst::ParseAPI::Function* currFunc,
Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges);

private:
bool findTableAddrNoTOC(const IA_IAPI* blockToCheck);
bool parseRelativeTableIdiom();
Expand Down
21 changes: 20 additions & 1 deletion parseAPI/src/IA_x86Details.C
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

#include <deque>
#include <boost/bind.hpp>
#include "IndirectAnalyzer.h"

using namespace Dyninst;
using namespace InstructionAPI;
Expand Down Expand Up @@ -595,7 +596,7 @@ void IA_x86Details::findThunkInBlock(Block* curBlock)
return;
}

void processPredecessor(Edge* e, std::set<Block*>& visited, std::deque<Block*>& worklist)
void processPredecessor(ParseAPI::Edge* e, std::set<Block*>& visited, std::deque<Block*>& worklist)
{
parsing_printf("\t\tblock %x, edge type %s\n",
e->src()->start(),
Expand Down Expand Up @@ -992,3 +993,21 @@ bool IA_x86Details::computeTableBounds(Instruction::Ptr maxSwitchInsn,
return true;
}

bool IA_x86Details::parseJumpTable(Dyninst::ParseAPI::Function * currFunc,
Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges)
{

IndirectControlFlowAnalyzer icfa(currFunc, currBlk);
bool ret = icfa.NewJumpTableAnalysis(outEdges);

parsing_printf("Jump table parser returned %d, %d edges\n", ret, outEdges.size());
for (auto oit = outEdges.begin(); oit != outEdges.end(); ++oit) parsing_printf("edge target at %lx\n", oit->first);
// Update statistics
currBlk->obj()->cs()->incrementCounter(PARSE_JUMPTABLE_COUNT);
if (!ret) currBlk->obj()->cs()->incrementCounter(PARSE_JUMPTABLE_FAIL);

return ret;
}


4 changes: 4 additions & 0 deletions parseAPI/src/IA_x86Details.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ namespace Dyninst
virtual ~IA_x86Details() {}
virtual bool parseJumpTable(Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges);
virtual bool parseJumpTable(Dyninst::ParseAPI::Function* currFunc,
Dyninst::ParseAPI::Block* currBlk,
std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges);

private:
bool isMovAPSTable(std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges);
void findThunkAndOffset(Dyninst::ParseAPI::Block * start);
Expand Down
4 changes: 2 additions & 2 deletions parseAPI/src/Parser.C
Original file line number Diff line number Diff line change
Expand Up @@ -1270,8 +1270,8 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) {
ParseCallback::insn_details insn_det;
insn_det.insn = &ah;

parsing_printf("[%s:%d] curAddr 0x%lx \n",
FILE__,__LINE__,curAddr);
parsing_printf("[%s:%d] curAddr 0x%lx: %s \n",
FILE__,__LINE__,curAddr, insn_det.insn->getInstruction()->format().c_str() );

if (func->_is_leaf_function) {
Address ret_addr;
Expand Down
6 changes: 5 additions & 1 deletion symtabAPI/src/Object-elf.C
Original file line number Diff line number Diff line change
Expand Up @@ -1368,7 +1368,11 @@ bool Object::get_relocation_entries( Elf_X_Shdr *&rel_plt_scnp,
// 1st plt entry is special.
next_plt_entry_addr += plt_entry_size_;

#else
#elif defined(arch_aarch64)
// For ARM, the first entry should be skipped,
// but the first entry is in double size
next_plt_entry_addr += 2 * plt_entry_size_;
#else
next_plt_entry_addr += 4*(plt_entry_size_); //1st 4 entries are special
#endif

Expand Down

0 comments on commit 85cebd3

Please sign in to comment.