Skip to content
This repository was archived by the owner on Apr 4, 2025. It is now read-only.

Commit ed10e60

Browse files
committed
Add a second jump table slicing patch to dyninst to fix a failed
assert in the first patch.
1 parent 032dab1 commit ed10e60

File tree

2 files changed

+149
-1
lines changed

2 files changed

+149
-1
lines changed

symtabAPI/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ else
2929
# table multi slices branch.
3030

3131
FETCH_TARFILE = dyninst-lite-9.3.2.tar.bz2
32-
EXTRA_PATCH_FILES = jump-table-slices
32+
EXTRA_PATCH_FILES = jump-table-slices jump-table-slices-2
3333

3434
endif
3535

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
This patch is the diff between Xiaozhu's jump table slicing branch on
2+
June 2 (ba1b3348ab) and June 21 (ed29383c09). Apply this patch after
3+
the jump-table-slices patch (which brings 9.3.2 up to the June 2
4+
commit).
5+
6+
This has a small improvement in the jump table analysis and reduces
7+
some gaps. But more importantly, it fixes a failed assert over a
8+
shared pointer in JumpTableFormatPred.C.
9+
10+
commit ed29383c09bae75ba9daa41c8bfac3f3038f82ff (jump_table_multi_slices)
11+
Author: Xiaozhu Meng <xmeng@cs.wisc.edu>
12+
Date: Wed Jun 21 16:13:00 2017 -0500
13+
14+
It is not a good idea to stop scanning jump table when an entry
15+
leads to an address in another function. The reason is that the
16+
another function can have an overapproximated jump table scan,
17+
causing wrong function boundary.
18+
19+
New heurisitics:
20+
if the indirect jump is in a function with a hint, and the
21+
indirect jump jumps to an adderss outside the range speicified by
22+
the hint, we stop.
23+
24+
25+
diff --git a/parseAPI/h/CodeSource.h b/parseAPI/h/CodeSource.h
26+
index e7e7651..ed2066d 100644
27+
--- a/parseAPI/h/CodeSource.h
28+
+++ b/parseAPI/h/CodeSource.h
29+
@@ -92,11 +92,12 @@ template <typename OS>
30+
31+
/* A starting point for parsing */
32+
struct Hint {
33+
- Hint() : _addr(0), _reg(NULL), _name("") { }
34+
- Hint(Address a, CodeRegion * r, std::string s) :
35+
- _addr(a), _reg(r), _name(s) { }
36+
+ Hint() : _addr(0), _size(0), _reg(NULL), _name("") { }
37+
+ Hint(Address a, int size, CodeRegion * r, std::string s) :
38+
+ _addr(a), _size(size), _reg(r), _name(s) { }
39+
40+
Address _addr;
41+
+ int _size;
42+
CodeRegion * _reg;
43+
std::string _name;
44+
45+
diff --git a/parseAPI/src/IndirectAnalyzer.C b/parseAPI/src/IndirectAnalyzer.C
46+
index 139d6f4..740bffc 100644
47+
--- a/parseAPI/src/IndirectAnalyzer.C
48+
+++ b/parseAPI/src/IndirectAnalyzer.C
49+
@@ -60,7 +60,7 @@ bool IndirectControlFlowAnalyzer::NewJumpTableAnalysis(std::vector<std::pair< Ad
50+
parsing_printf("Apply indirect control flow analysis at %lx\n", block->last());
51+
parsing_printf("Looking for thunk\n");
52+
53+
-// if (block->last() == 0xa8d7c9) dyn_debug_parsing=1; else dyn_debug_parsing=0;
54+
+// if (block->last() == 0x549cf9) dyn_debug_parsing=1; else dyn_debug_parsing=0;
55+
56+
// Find all blocks that reach the block containing the indirect jump
57+
// This is a prerequisit for finding thunks
58+
@@ -241,7 +241,7 @@ void IndirectControlFlowAnalyzer::ReadTable(AST::Ptr jumpTargetExpr,
59+
JumpTableReadVisitor jtrv(index, v, cs, false, memoryReadSize);
60+
jumpTargetExpr->accept(&jtrv);
61+
if (jtrv.valid && cs->isCode(jtrv.targetAddress)) {
62+
- bool overlap = false;
63+
+ bool stop = false;
64+
set<Block*> blocks;
65+
block->obj()->findCurrentBlocks(block->region(), jtrv.targetAddress, blocks);
66+
for (auto bit = blocks.begin(); bit != blocks.end(); ++bit) {
67+
@@ -249,21 +249,28 @@ void IndirectControlFlowAnalyzer::ReadTable(AST::Ptr jumpTargetExpr,
68+
Block::Insns insns;
69+
(*bit)->getInsns(insns);
70+
if (insns.find(jtrv.targetAddress) == insns.end()) {
71+
- overlap = true;
72+
+ stop = true;
73+
parsing_printf("WARNING: resolving jump tables leads to address %lx, which causes overlapping instructions in basic blocks [%lx,%lx)\n", jtrv.targetAddress, (*bit)->start(), (*bit)->end());
74+
break;
75+
}
76+
}
77+
}
78+
- set<Function*> funcs;
79+
- block->obj()->findCurrentFuncs(block->region(), jtrv.targetAddress, funcs);
80+
- for (auto fit = funcs.begin(); fit != funcs.end(); ++fit) {
81+
- if (*fit != func) {
82+
- overlap = true;
83+
- parsing_printf("WARNING: resolving jump tables leads to address %lx in another function at %lx\n", jtrv.targetAddress, (*fit)->addr());
84+
+ // Assume that indirect jump should not jump beyond the function range.
85+
+ // This assumption is shaky in terms of non-contiguous functions.
86+
+ // But non-contiguous blocks tend not be reach by indirect jumps
87+
+ if (func->src() == HINT) {
88+
+ Hint h(func->addr(), 0 , NULL, "");
89+
+ auto range = equal_range(cs->hints().begin(), cs->hints().end(), h);
90+
+ if (range.first != range.second && range.first != cs->hints().end()) {
91+
+ Address startAddr = range.first->_addr;
92+
+ int size = range.first->_size;
93+
+ if (jtrv.targetAddress < startAddr || jtrv.targetAddress >= startAddr + size) {
94+
+ stop = true;
95+
+ parsing_printf("WARNING: resolving jump tables leads to address %lx, which is not in the function range specified in the symbol table\n", jtrv.targetAddress);
96+
+ }
97+
}
98+
}
99+
- if (overlap) break;
100+
+ if (stop) break;
101+
jumpTargets.insert(jtrv.targetAddress);
102+
} else {
103+
// We have a bad entry. We stop here, as we have wrong information
104+
diff --git a/parseAPI/src/JumpTableFormatPred.C b/parseAPI/src/JumpTableFormatPred.C
105+
index 608d91b..876af5e 100644
106+
--- a/parseAPI/src/JumpTableFormatPred.C
107+
+++ b/parseAPI/src/JumpTableFormatPred.C
108+
@@ -323,6 +323,7 @@ static Assignment::Ptr SearchForWrite(SliceNode::Ptr n, AbsRegion &src, Slicer::
109+
if (!(*oit).writesMemory() && !(*oit).readsMemory()) {
110+
std::set<RegisterAST::Ptr> regsRead;
111+
oit->getReadSet(regsRead);
112+
+ if (regsRead.empty()) continue;
113+
src = AbsRegion(Absloc( (*regsRead.begin())->getID() ));
114+
parsing_printf("\t\tContinue to slice on %s\n", src.format().c_str());
115+
break;
116+
diff --git a/parseAPI/src/SymbolicExpression.C b/parseAPI/src/SymbolicExpression.C
117+
index b03d1ea..7e1a4ce 100644
118+
--- a/parseAPI/src/SymbolicExpression.C
119+
+++ b/parseAPI/src/SymbolicExpression.C
120+
@@ -77,6 +77,7 @@ AST::Ptr SymbolicExpression::SimplifyRoot(AST::Ptr ast, Address addr) {
121+
}
122+
}
123+
break;
124+
+/*
125+
case ROSEOperation::sMultOp:
126+
case ROSEOperation::uMultOp:
127+
if (roseAST->child(0)->getID() == AST::V_ConstantAST) {
128+
@@ -89,7 +90,7 @@ AST::Ptr SymbolicExpression::SimplifyRoot(AST::Ptr ast, Address addr) {
129+
if (child1->val().val == 1) return roseAST->child(0);
130+
}
131+
break;
132+
-
133+
+*/
134+
case ROSEOperation::xorOp:
135+
if (roseAST->child(0)->getID() == AST::V_VariableAST && roseAST->child(1)->getID() == AST::V_VariableAST) {
136+
VariableAST::Ptr child0 = boost::static_pointer_cast<VariableAST>(roseAST->child(0));
137+
diff --git a/parseAPI/src/SymtabCodeSource.C b/parseAPI/src/SymtabCodeSource.C
138+
index 1310f32..b8cb12a 100644
139+
--- a/parseAPI/src/SymtabCodeSource.C
140+
+++ b/parseAPI/src/SymtabCodeSource.C
141+
@@ -505,6 +505,7 @@ SymtabCodeSource::init_hints(dyn_hash_map<void*, CodeRegion*> & rmap,
142+
sr->getMemOffset()+sr->getDiskSize());
143+
} else {
144+
_hints.push_back( Hint((*fsit)->getOffset(),
145+
+ (*fsit)->getSize(),
146+
cr,
147+
(*fsit)->getFirstSymbol()->getPrettyName()) );
148+
parsing_printf("\t<%lx,%s,[%lx,%lx)>\n",

0 commit comments

Comments
 (0)