dwarf stack: save expression and add is_exp_equal() to compare

expressions
This commit is contained in:
2020-01-25 17:24:36 +04:00
parent e48cfddeb0
commit 4f94a9e1c2
2 changed files with 45 additions and 3 deletions
+22
View File
@@ -1078,6 +1078,25 @@ const dwarf_op_map* find_op_map(int op)
return NULL; 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) bool __dwarf_stack::get_value(uint64_t& value)
{ {
if(!Size()) { if(!Size()) {
@@ -1114,6 +1133,9 @@ bool __dwarf_stack::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribu
return false; 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(); dwarf_value* v = get();
// dereference register location there if it is not last in stack // dereference register location there if it is not last in stack
if(v && (v->type & DWARF_TYPE_REGISTER_LOC)) { if(v && (v->type & DWARF_TYPE_REGISTER_LOC)) {
+22 -2
View File
@@ -3,6 +3,17 @@
#include <elfutils/libdwfl.h> #include <elfutils/libdwfl.h>
#include "common.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 { typedef enum {
DWARF_TYPE_INVALID = 0, // no type DWARF_TYPE_INVALID = 0, // no type
@@ -62,11 +73,17 @@ typedef struct __dwarf_value : public SC_ListNode {
} dwarf_value; } dwarf_value;
typedef struct __dwarf_stack : public SC_ListHead { typedef struct __dwarf_stack : public SC_ListHead {
__dwarf_stack(pst_context* c) : ctx(c) __dwarf_stack(pst_context* c) : ctx(c) {
{
attr = NULL; 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() { void clear() {
for(dwarf_value* v = (dwarf_value*)First(); v; v = (dwarf_value*)First()) { for(dwarf_value* v = (dwarf_value*)First(); v; v = (dwarf_value*)First()) {
Remove(v); 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) { void push(void* v, uint32_t s, int t) {
dwarf_value* value = new dwarf_value((char*)v, s, t); dwarf_value* value = new dwarf_value((char*)v, s, t);
InsertFirst(value); InsertFirst(value);
@@ -105,6 +124,7 @@ typedef struct __dwarf_stack : public SC_ListHead {
bool get_value(uint64_t& value); bool get_value(uint64_t& value);
Dwarf_Attribute* attr; // attribute which expression currently processed Dwarf_Attribute* attr; // attribute which expression currently processed
SC_ListHead expr; // DWARF expression
pst_context* ctx; pst_context* ctx;
} dwarf_stack; } dwarf_stack;