diff options
-rw-r--r-- | loc2c-test.c | 42 | ||||
-rw-r--r-- | loc2c.c | 32 | ||||
-rw-r--r-- | loc2c.h | 5 | ||||
-rw-r--r-- | tapsets.cxx | 42 |
4 files changed, 80 insertions, 41 deletions
diff --git a/loc2c-test.c b/loc2c-test.c index 2967b9ed..4376b578 100644 --- a/loc2c-test.c +++ b/loc2c-test.c @@ -44,6 +44,34 @@ fail (void *arg __attribute__ ((unused)), const char *fmt, ...) exit (2); } +static const Dwarf_Op * +get_location (Dwarf_Addr dwbias, Dwarf_Addr pc, Dwarf_Attribute *loc_attr, + size_t *len) +{ + Dwarf_Op *expr; + + switch (dwarf_getlocation_addr (loc_attr, pc - dwbias, &expr, len, 1)) + { + case 1: /* Should always happen. */ + if (*len == 0) + goto inaccessible; + break; + + default: /* Shouldn't happen. */ + case -1: + fail (NULL, _("dwarf_addrloclists (form %#x): %s"), + dwarf_whatform (loc_attr), dwarf_errmsg (-1)); + return NULL; + + case 0: /* Shouldn't happen. */ + inaccessible: + fail (NULL, _("not accessible at this address")); + return NULL; + } + + return expr; +} + static void handle_variable (Dwarf_Die *scopes, int nscopes, int out, Dwarf_Addr cubias, Dwarf_Die *vardie, Dwarf_Addr pc, @@ -86,9 +114,12 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out, #define FIELD "addr" #define emit(fmt, ...) printf (" addr = " fmt "\n", ## __VA_ARGS__) + size_t locexpr_len; + const Dwarf_Op *locexpr = get_location (cubias, pc, &attr_mem, &locexpr_len); + struct location *head, *tail = NULL; head = c_translate_location (&pool, &fail, NULL, NULL, - 1, cubias, &attr_mem, pc, + 1, cubias, pc, locexpr, locexpr_len, &tail, fb_attr); if (dwarf_attr_integrate (vardie, DW_AT_type, &attr_mem) == NULL) @@ -181,9 +212,12 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out, *fields, dwarf_errmsg (-1)); } else - c_translate_location (&pool, NULL, NULL, NULL, - 1, cubias, &attr_mem, pc, - &tail, NULL); + { + locexpr = get_location (cubias, pc, &attr_mem, &locexpr_len); + c_translate_location (&pool, NULL, NULL, NULL, + 1, cubias, pc, locexpr, locexpr_len, + &tail, NULL); + } ++fields; break; @@ -965,34 +965,12 @@ c_translate_location (struct obstack *pool, void *fail_arg, void (*emit_address) (void *fail_arg, struct obstack *, Dwarf_Addr), - int indent, Dwarf_Addr dwbias, - Dwarf_Attribute *loc_attr, Dwarf_Addr address, + int indent, Dwarf_Addr dwbias, Dwarf_Addr pc_address, + const Dwarf_Op *expr, size_t len, struct location **input, Dwarf_Attribute *fb_attr) { - ++indent; - - Dwarf_Op *expr; - size_t len; - switch (dwarf_getlocation_addr (loc_attr, address - dwbias, &expr, &len, 1)) - { - case 1: /* Should always happen. */ - if (len == 0) - goto inaccessible; - break; - - default: /* Shouldn't happen. */ - case -1: - (*fail) (fail_arg, N_("dwarf_addrloclists (form %#x): %s"), - dwarf_whatform (fb_attr), dwarf_errmsg (-1)); - return NULL; + indent += 2; - case 0: /* Shouldn't happen. */ - inaccessible: - (*fail) (fail_arg, N_("not accessible at this address")); - return NULL; - } - - ++indent; switch (*input == NULL ? loc_address : (*input)->type) { case loc_address: @@ -1000,14 +978,14 @@ c_translate_location (struct obstack *pool, This expression will compute starting with that on the stack. */ return location_from_address (pool, fail, fail_arg, emit_address ?: &default_emit_address, - indent, dwbias, expr, len, address, + indent, dwbias, expr, len, pc_address, input, fb_attr); case loc_noncontiguous: case loc_register: /* The starting point is not an address computation, but a register. We can only handle limited computations from here. */ - return location_relative (pool, indent, dwbias, expr, len, address, + return location_relative (pool, indent, dwbias, expr, len, pc_address, input, fb_attr); default: @@ -26,8 +26,9 @@ struct location *c_translate_location (struct obstack *, Dwarf_Addr), int indent, Dwarf_Addr bias, - Dwarf_Attribute *loc_attr, - Dwarf_Addr address, + Dwarf_Addr pc_address, + const Dwarf_Op *locexpr, + size_t locexprlen, struct location **input, Dwarf_Attribute *fb_attr); diff --git a/tapsets.cxx b/tapsets.cxx index 5e6497f4..fdf1b999 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -934,6 +934,37 @@ dwflpp } + struct location * + translate_location(struct obstack *pool, + Dwarf_Attribute *attr, Dwarf_Addr pc, + Dwarf_Attribute *fb_attr, + struct location **tail) + { + Dwarf_Op *expr; + size_t len; + + switch (dwarf_getlocation_addr (attr, pc - module_bias, &expr, &len, 1)) + { + case 1: /* Should always happen. */ + if (len > 0) + break; + /* Fall through. */ + + case 0: /* Shouldn't happen. */ + throw semantic_error ("not accessible at this address"); + + default: /* Shouldn't happen. */ + case -1: + throw semantic_error (string ("dwarf_getlocation_addr failed") + + string (dwarf_errmsg (-1))); + } + + return c_translate_location (pool, &loc2c_error, this, + &loc2c_emit_address, + 1, module_bias, + pc, expr, len, tail, fb_attr); + } + Dwarf_Die * translate_components(struct obstack *pool, struct location **tail, @@ -1015,9 +1046,7 @@ dwflpp + " :" + string(dwarf_errmsg (-1))); } else - c_translate_location (pool, NULL, NULL, NULL, 1, - module_bias, attr_mem, pc, - tail, NULL); + translate_location (pool, attr_mem, pc, NULL, tail); ++i; break; @@ -1195,11 +1224,8 @@ dwflpp /* Given $foo->bar->baz[NN], translate the location of foo. */ - struct location *head = c_translate_location (&pool, &loc2c_error, this, - &loc2c_emit_address, - 1, module_bias, - &attr_mem, pc, - &tail, fb_attr); + struct location *head = translate_location (&pool, + &attr_mem, pc, fb_attr, &tail); if (dwarf_attr_integrate (&vardie, DW_AT_type, &attr_mem) == NULL) throw semantic_error("failed to retrieve type " |