diff options
author | Roland McGrath <roland@redhat.com> | 2009-09-24 13:05:41 -0700 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2009-09-24 13:06:31 -0700 |
commit | 2e2a5d82cfd03db7be2e9ff1457b5ea50e46bc3a (patch) | |
tree | e11572dbb27ac79da1acb29507b5b99b2d58991d /loc2c.c | |
parent | a1c1924486c8a29451898a9fe0cb83c8b472a78e (diff) | |
download | systemtap-steved-2e2a5d82cfd03db7be2e9ff1457b5ea50e46bc3a.tar.gz systemtap-steved-2e2a5d82cfd03db7be2e9ff1457b5ea50e46bc3a.tar.xz systemtap-steved-2e2a5d82cfd03db7be2e9ff1457b5ea50e46bc3a.zip |
Support DW_AT_const_value cases in loc2c and loc2c-test.
* loc2c.c (c_translate_constant): New function.
* loc2c.h: Declare it.
* loc2c-test.c (main): Use it for DW_AT_const_value cases.
Diffstat (limited to 'loc2c.c')
-rw-r--r-- | loc2c.c | 103 |
1 files changed, 101 insertions, 2 deletions
@@ -1152,6 +1152,105 @@ c_translate_location (struct obstack *pool, return NULL; } +/* Translate a DW_AT_const_value attribute as if it were a location of + constant-value flavor. */ + +struct location * +c_translate_constant (struct obstack *pool, + void (*fail) (void *arg, + const char *fmt, ...) + __attribute__ ((noreturn, + format (printf, 2, 3))), + void *fail_arg, + void (*emit_address) (void *fail_arg, + struct obstack *, + Dwarf_Addr), + int indent, Dwarf_Addr dwbias, Dwarf_Attribute *attr) +{ + indent += 2; + + struct location *loc = obstack_alloc (pool, sizeof *loc); + loc->fail = fail; + loc->fail_arg = fail_arg; + loc->emit_address = emit_address ?: &default_emit_address; + loc->byte_size = 0; + loc->frame_base = NULL; + loc->address.stack_depth = 0; + loc->address.declare = NULL; + loc->address.used_deref = false; + + switch (dwarf_whatform (attr)) + { + case DW_FORM_addr: + { + Dwarf_Addr addr; + if (dwarf_formaddr (attr, &addr) != 0) + { + FAIL (loc, N_("cannot get constant address: %s"), + dwarf_errmsg (-1)); + return NULL; + } + loc->type = loc_value; + obstack_printf (pool, "%*saddr = ", indent * 2, ""); + (*loc->emit_address) (loc->fail_arg, pool, dwbias + addr); + obstack_grow (pool, ";\n", 3); + loc->address.program = obstack_finish (pool); + break; + } + + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + { + Dwarf_Block block; + if (dwarf_formblock (attr, &block) != 0) + { + FAIL (loc, N_("cannot get constant block: %s"), dwarf_errmsg (-1)); + return NULL; + } + loc->type = loc_constant; + loc->byte_size = block.length; + loc->constant_block = block.data; + break; + } + + case DW_FORM_string: + case DW_FORM_strp: + { + const char *string = dwarf_formstring (attr); + if (string == NULL) + { + FAIL (loc, N_("cannot get string constant: %s"), dwarf_errmsg (-1)); + return NULL; + } + loc->type = loc_constant; + loc->byte_size = strlen (string) + 1; + loc->constant_block = string; + break; + } + + default: + { + Dwarf_Sword value; + if (dwarf_formsdata (attr, &value) != 0) + { + FAIL (loc, N_("cannot get constant value: %s"), dwarf_errmsg (-1)); + return NULL; + } + loc->type = loc_value; + obstack_printf (pool, "%*saddr = %" PRId64 "L\n;", + indent * 2, "", value); + obstack_1grow (pool, '\0'); + loc->address.program = obstack_finish (pool); + break; + } + } + + return loc; +} + + /* Translate a C fragment for a direct argument VALUE. On errors, call FAIL, which should not return. Any later errors will use FAIL and FAIL_ARG from this translate call. On success, return the fragment created. */ @@ -1166,7 +1265,7 @@ c_translate_argument (struct obstack *pool, { indent += 2; - obstack_printf(pool, "%*saddr = %s;\n", indent * 2, "", value); + obstack_printf (pool, "%*saddr = %s;\n", indent * 2, "", value); obstack_1grow (pool, '\0'); char *program = obstack_finish (pool); @@ -1174,7 +1273,7 @@ c_translate_argument (struct obstack *pool, loc->next = NULL; loc->fail = fail; loc->fail_arg = fail_arg; - loc->emit_address = emit_address; + loc->emit_address = emit_address ?: &default_emit_address; loc->ops = NULL; loc->nops = 0; loc->byte_size = 0; |