dwarf stack: save expression and add is_exp_equal() to compare
expressions
This commit is contained in:
@@ -1078,6 +1078,25 @@ const dwarf_op_map* find_op_map(int op)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool __dwarf_stack::is_expr_equal(__dwarf_stack* rhs)
|
||||
{
|
||||
if(rhs->expr.Size() != expr.Size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pst_dwarf_op* rop = (pst_dwarf_op*)rhs->expr.First();
|
||||
pst_dwarf_op* lop = (pst_dwarf_op*)expr.First();
|
||||
while(lop != NULL && rop != NULL) {
|
||||
if(lop->operation != rop->operation || lop->arg1 != rop->arg1 || lop->arg2 != rop->arg2) {
|
||||
return false;
|
||||
}
|
||||
lop = (pst_dwarf_op*)expr.Next(lop);
|
||||
rop = (pst_dwarf_op*)rhs->expr.Next(rop);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __dwarf_stack::get_value(uint64_t& value)
|
||||
{
|
||||
if(!Size()) {
|
||||
@@ -1114,6 +1133,9 @@ bool __dwarf_stack::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribu
|
||||
return false;
|
||||
}
|
||||
|
||||
pst_dwarf_op* op = new pst_dwarf_op(exprs[i].atom, exprs[i].number, exprs[i].number2);
|
||||
expr.InsertLast(op);
|
||||
|
||||
dwarf_value* v = get();
|
||||
// dereference register location there if it is not last in stack
|
||||
if(v && (v->type & DWARF_TYPE_REGISTER_LOC)) {
|
||||
|
||||
@@ -3,6 +3,17 @@
|
||||
#include <elfutils/libdwfl.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "linkedlist.h"
|
||||
|
||||
// DWARF operation (represents our own DW_OP_XXX)
|
||||
typedef struct __pst_dwarf_op : public SC_ListNode {
|
||||
__pst_dwarf_op(uint8_t op, uint64_t a1, uint64_t a2) {
|
||||
operation = op; arg1 = a1; arg2 = a2;
|
||||
}
|
||||
uint8_t operation;
|
||||
uint64_t arg1;
|
||||
uint64_t arg2;
|
||||
} pst_dwarf_op;
|
||||
|
||||
typedef enum {
|
||||
DWARF_TYPE_INVALID = 0, // no type
|
||||
@@ -62,11 +73,17 @@ typedef struct __dwarf_value : public SC_ListNode {
|
||||
} dwarf_value;
|
||||
|
||||
typedef struct __dwarf_stack : public SC_ListHead {
|
||||
__dwarf_stack(pst_context* c) : ctx(c)
|
||||
{
|
||||
__dwarf_stack(pst_context* c) : ctx(c) {
|
||||
attr = NULL;
|
||||
}
|
||||
|
||||
~__dwarf_stack() {
|
||||
for(pst_dwarf_op* op = (pst_dwarf_op*)expr.First(); op; op = (pst_dwarf_op*)expr.First()) {
|
||||
expr.Remove(op);
|
||||
delete op;
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for(dwarf_value* v = (dwarf_value*)First(); v; v = (dwarf_value*)First()) {
|
||||
Remove(v);
|
||||
@@ -74,6 +91,8 @@ typedef struct __dwarf_stack : public SC_ListHead {
|
||||
}
|
||||
}
|
||||
|
||||
bool is_expr_equal(__dwarf_stack* rhs);
|
||||
|
||||
void push(void* v, uint32_t s, int t) {
|
||||
dwarf_value* value = new dwarf_value((char*)v, s, t);
|
||||
InsertFirst(value);
|
||||
@@ -105,6 +124,7 @@ typedef struct __dwarf_stack : public SC_ListHead {
|
||||
bool get_value(uint64_t& value);
|
||||
|
||||
Dwarf_Attribute* attr; // attribute which expression currently processed
|
||||
SC_ListHead expr; // DWARF expression
|
||||
pst_context* ctx;
|
||||
} dwarf_stack;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user