diff options
author | Roland McGrath <roland@redhat.com> | 2009-09-16 15:22:45 -0700 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2009-09-16 15:22:45 -0700 |
commit | 45d7e32572c4aafde1428b305541330aaf2692f3 (patch) | |
tree | 6a26dc199f8f37f0d055889ce29a569bf4e0b896 /loc2c.c | |
parent | 6be6402d1514d149e6e6adf66a5c50b80b8bbb0f (diff) | |
download | systemtap-steved-45d7e32572c4aafde1428b305541330aaf2692f3.tar.gz systemtap-steved-45d7e32572c4aafde1428b305541330aaf2692f3.tar.xz systemtap-steved-45d7e32572c4aafde1428b305541330aaf2692f3.zip |
* loc2c.c: Handle DW_OP_stack_value. Untested and probably unfinished.
Diffstat (limited to 'loc2c.c')
-rw-r--r-- | loc2c.c | 48 |
1 files changed, 45 insertions, 3 deletions
@@ -51,13 +51,13 @@ struct location enum { - loc_address, loc_register, loc_noncontiguous, + loc_address, loc_register, loc_noncontiguous, loc_value, loc_decl, loc_fragment, loc_final } type; struct location *frame_base; union { - struct /* loc_address, loc_fragment, loc_final */ + struct /* loc_address, loc_value, loc_fragment, loc_final */ { const char *declare; /* Temporary that needs declared. */ char *program; /* C fragment, leaves address in s0. */ @@ -212,6 +212,7 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, size_t i; + bool tos_value = false; bool used_deref = false; inline const char *finish (struct location *piece) { @@ -221,12 +222,13 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, { obstack_1grow (pool, '\0'); char *program = obstack_finish (pool); - piece->type = loc_address; + piece->type = tos_value ? loc_value : loc_address; piece->address.declare = NULL; piece->address.program = program; piece->address.stack_depth = max_stack; piece->address.used_deref = used_deref; used_deref = false; + tos_value = false; } else if (tos_register == -1) DIE ("stack underflow"); @@ -250,6 +252,12 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, uint_fast8_t sp; Dwarf_Word value; + if (tos_value + && expr[i].atom != DW_OP_nop + && expr[i].atom != DW_OP_piece + && expr[i].atom != DW_OP_bit_piece) + DIE ("operations follow DW_OP_stack_value"); + switch (expr[i].atom) { /* Basic stack operations. */ @@ -525,6 +533,20 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, } break; + case DW_OP_stack_value: + if (stack_depth > 1) + DIE ("DW_OP_stack_value left multiple values on stack"); + else + { + /* Fetch a register to top of stack, or check for underflow. + Then mark the TOS as being a value. */ + POP (tos); + assert (tos == 0); + PUSH; + tos_value = true; + } + break; + case DW_OP_call_frame_cfa: // We pick this out when processing DW_AT_frame_base in // so it really shouldn't turn up here. @@ -1051,6 +1073,7 @@ c_translate_location (struct obstack *pool, case loc_noncontiguous: case loc_register: + case loc_value: /* 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, pc_address, @@ -1115,6 +1138,10 @@ emit_base_fetch (struct obstack *pool, Dwarf_Word byte_size, switch (loc->type) { + case loc_value: + obstack_printf (pool, "addr;"); + break; + case loc_address: if (byte_size != 0 && byte_size != (Dwarf_Word) -1) obstack_printf (pool, "deref (%" PRIu64 ", addr);", byte_size); @@ -1169,6 +1196,10 @@ emit_base_store (struct obstack *pool, Dwarf_Word byte_size, FAIL (loc, N_("noncontiguous location for base store")); break; + case loc_value: + FAIL (loc, N_("location is computed value, cannot store")); + break; + default: abort (); break; @@ -1245,6 +1276,10 @@ discontiguify (struct obstack *pool, int indent, struct location *loc, break; } + case loc_value: + FAIL (loc, N_("stack value too big for fetch ???")); + break; + case loc_register: FAIL (loc, N_("single register too big for fetch/store ???")); break; @@ -1675,6 +1710,9 @@ c_translate_addressof (struct obstack *pool, int indent, case loc_noncontiguous: FAIL (*input, N_("cannot take address of noncontiguous object")); break; + case loc_value: + FAIL (*input, N_("cannot take address of computed value")); + break; default: abort(); @@ -1822,6 +1860,10 @@ c_translate_array (struct obstack *pool, int indent, } break; + case loc_value: + FAIL (*input, N_("cannot index into computed value")); + break; + default: abort(); break; |