From ec1a0212430fbb2a6e51111b6bfcdb0a5a75c98d Mon Sep 17 00:00:00 2001 From: Doug Moore Date: Tue, 16 May 2017 22:00:38 -0500 Subject: [PATCH] Move the ret_addr_column field from dwarf_reg_cache_entry to dwarf_reg_state, so that it will get saved and restored with the register state. Initialize the rs_state version of ret_addr_column at the some time the dwarf_cursor version is initialized, and don't bother copying ret_addr_column explicitly from cursor to cache since it's copied implicitly as part of reg_state. Use the reg_state version in apply_reg_state, instead of the cursor version. Which brings up the question: why do we have ret_addr_column in the dwarf_cursor? We call find_reg_state before calling apply_reg_state, so the value of ret_addr_column in the cursor when dwarf_step gets called gets overwritten before it is used. So it's initial value doesn't matter. But some architectures do funky things with cursor->ret_addr_column, even though I don't see how they matter. So I'm not deleting dwarf_cursor->ret_addr_column, even though I suspect this patch makes it useless. --- include/dwarf.h | 2 +- src/dwarf/Gparser.c | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/include/dwarf.h b/include/dwarf.h index f552e6f9..759883c0 100644 --- a/include/dwarf.h +++ b/include/dwarf.h @@ -251,6 +251,7 @@ dwarf_where_t; typedef struct dwarf_reg_state { + unw_word_t ret_addr_column; /* which column in rule table represents return address */ char where[DWARF_NUM_PRESERVED_REGS + 2]; /* how is the register saved? */ unw_word_t val[DWARF_NUM_PRESERVED_REGS + 2]; /* where it's saved */ } @@ -269,7 +270,6 @@ typedef struct dwarf_reg_cache_entry unsigned short lru_chain; /* used for least-recently-used chain */ unsigned short coll_chain; /* used for hash collisions */ unsigned short hint; /* hint for next rs to try (or -1) */ - unw_word_t ret_addr_column; /* indicates which column in the rule table represents return address */ unsigned short valid : 1; /* optional machine-dependent signal info */ unsigned short signal_frame : 1; /* optional machine-dependent signal info */ } diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c index 411c3822..2600ce39 100644 --- a/src/dwarf/Gparser.c +++ b/src/dwarf/Gparser.c @@ -488,10 +488,6 @@ static int parse_dynamic (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr) { Debug (1, "Not yet implemented\n"); -#if 0 - /* Don't forget to set the ret_addr_column! */ - c->ret_addr_column = XXX; -#endif return -UNW_ENOINFO; } @@ -521,6 +517,7 @@ setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr) struct dwarf_cie_info *dci = c->pi.unwind_info; c->ret_addr_column = dci->ret_addr_column; + sr->rs_current.ret_addr_column = dci->ret_addr_column; unw_word_t addr = dci->cie_instr_start; unw_word_t curr_ip = 0; dwarf_stackable_reg_state_t *rs_stack = NULL; @@ -715,7 +712,6 @@ rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c) cache->links[head].ip = c->ip; cache->links[head].valid = 1; - cache->links[head].ret_addr_column = c->ret_addr_column; cache->links[head].signal_frame = tdep_cache_frame(c); return cache->buckets + head; } @@ -860,11 +856,11 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) c->cfa = cfa; /* DWARF spec says undefined return address location means end of stack. */ - if (DWARF_IS_NULL_LOC (c->loc[c->ret_addr_column])) + if (DWARF_IS_NULL_LOC (c->loc[rs->ret_addr_column])) c->ip = 0; else { - ret = dwarf_get (c, c->loc[c->ret_addr_column], &ip); + ret = dwarf_get (c, c->loc[rs->ret_addr_column], &ip); if (ret < 0) return ret; c->ip = ip; @@ -898,7 +894,6 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr) { /* update hint; no locking needed: single-word writes are atomic */ unsigned short index = rs - cache->buckets; - c->ret_addr_column = cache->links[index].ret_addr_column; c->use_prev_instr = ! cache->links[index].signal_frame; memcpy (&sr->rs_current, rs, sizeof (*rs)); } @@ -982,10 +977,6 @@ dwarf_reg_states_dynamic_iterate(struct dwarf_cursor *c, void *token) { Debug (1, "Not yet implemented\n"); -#if 0 - /* Don't forget to set the ret_addr_column! */ - c->ret_addr_column = XXX; -#endif return -UNW_ENOINFO; }