From 86598ebfa13479b4ba3b6b7a9de25c3e497ff57e Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 16 Sep 2009 12:22:04 +0200 Subject: Clean up dwflpp::translate_location workaround for DW_AT_data_member_location. Do the same workaround as loc2c-test.c does. Just treat a constant member location offset as a DW_OP_plus_uconst and call c_translate_location for it. Also Remove c_translate_add_offset. * dwflpp.cxx (dwflpp::translate_location): Check elfutils version and only do workaround for elfutils < 0.142. * loc2c.h (c_translate_add_offset): Removed. * loc2c.c (c_translate_add_offset): Likewise. --- loc2c.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) (limited to 'loc2c.c') diff --git a/loc2c.c b/loc2c.c index d4cb4666..5cf59691 100644 --- a/loc2c.c +++ b/loc2c.c @@ -1711,40 +1711,6 @@ c_translate_pointer_store (struct obstack *pool, int indent, // XXX: what about multiple-location lvalues? } - -/* Translate a fragment to add an offset to the currently calculated - address of the input location. Used for struct fields. Only works - when location is already an actual base address. -*/ - -void -c_translate_add_offset (struct obstack *pool, int indent, const char *comment, - Dwarf_Sword off, struct location **input) -{ - indent++; - if (comment == NULL || comment[0] == '\0') - comment = "field offset"; - switch ((*input)->type) - { - case loc_address: - obstack_printf (pool, "%*saddr += " SFORMAT "; // %s\n", - indent * 2 + 2, "", off, comment); - *input = (*input)->next = new_synthetic_loc (pool, *input, false); - break; - - case loc_register: - FAIL (*input, N_("cannot add offset of object in register")); - break; - case loc_noncontiguous: - FAIL (*input, N_("cannot add offset of noncontiguous object")); - break; - - default: - abort (); - break; - } -} - /* Determine the element stride of an array type. */ static Dwarf_Word array_stride (Dwarf_Die *typedie, struct location *origin) -- cgit From 45d7e32572c4aafde1428b305541330aaf2692f3 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 16 Sep 2009 15:22:45 -0700 Subject: * loc2c.c: Handle DW_OP_stack_value. Untested and probably unfinished. --- loc2c.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'loc2c.c') diff --git a/loc2c.c b/loc2c.c index 5cf59691..c5859df4 100644 --- a/loc2c.c +++ b/loc2c.c @@ -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; -- cgit From 24c7957b4dbddc8545d0e0c734377746a5ae6e60 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 17 Sep 2009 15:06:57 +0200 Subject: PR10417 Pass around attributes for supporting DW_OP_{implicit,stack}_value. Preparation for retrieving the Dwarf_Block that holds the value of an DW_OP_implicit_value. We need the Dwarf_Attribute that is associated with the location expression operants. Depends on new elfutils 0.143 functionality. Recognizes, but does not yet handle the new operants DW_OP_{implicit,stack}_value. * loc2c.h (c_translate_location): Take an Dwarf_Attribute. * loc2c.c (c_translate_location): Likewise and pass it on. (location_relative): Likewise. (location_from_address): Likewise. (translate): Likewise and capture Dwarf_Block. * loc2c-test.c (handle_variable): Pass in Dwarf_Attribute. * dwflpp.cxx (translate_location): Likewise. (literal_stmt_for_return): Pass in NULL to indicate no attribute. --- loc2c.c | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) (limited to 'loc2c.c') diff --git a/loc2c.c b/loc2c.c index 5cf59691..4bc6aa6e 100644 --- a/loc2c.c +++ b/loc2c.c @@ -151,7 +151,7 @@ lose (struct location *loc, static const char * translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, - const Dwarf_Op *expr, const size_t len, + Dwarf_Attribute *attr, const Dwarf_Op *expr, const size_t len, struct location *input, bool *need_fb, size_t *loser, struct location *loc) @@ -525,6 +525,28 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, } break; + case DW_OP_stack_value: + DIE ("DW_OP_stack_value not supported"); + break; + + case DW_OP_implicit_value: + { + if (attr == NULL) + DIE ("No Dwarf_Attribute given, but DW_OP_implicit_value used"); + else + { +#if ! _ELFUTILS_PREREQ(0,142) + Dwarf_Block block; + Dwarf_Op *op = (Dwarf_Op *) &expr[i]; + if (dwarf_getlocation_implicit_value (attr, op, &block) != 0) + DIE("DW_OP_implicit_value, dwarf_getlocation_implicit_value failed"); + else +#endif + DIE ("DW_OP_implicit_value not supported"); + } + 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. @@ -576,6 +598,7 @@ location_from_address (struct obstack *pool, void (*emit_address) (void *fail_arg, struct obstack *, Dwarf_Addr), int indent, Dwarf_Addr dwbias, + Dwarf_Attribute *attr, const Dwarf_Op *expr, size_t len, Dwarf_Addr address, struct location **input, Dwarf_Attribute *fb_attr, const Dwarf_Op *cfa_ops) @@ -589,7 +612,7 @@ location_from_address (struct obstack *pool, bool need_fb = false; size_t loser; - const char *failure = translate (pool, indent + 1, dwbias, expr, len, + const char *failure = translate (pool, indent + 1, dwbias, attr, expr, len, *input, &need_fb, &loser, loc); if (failure != NULL) return lose (loc, failure, expr, loser); @@ -637,7 +660,7 @@ location_from_address (struct obstack *pool, fb_ops = fb_expr; loc->frame_base = alloc_location (pool, loc); - failure = translate (pool, indent + 1, dwbias, fb_ops, fb_len, NULL, + failure = translate (pool, indent + 1, dwbias, attr, fb_ops, fb_len, NULL, NULL, &loser, loc->frame_base); if (failure != NULL) return lose (loc, failure, fb_expr, loser); @@ -653,11 +676,11 @@ location_from_address (struct obstack *pool, /* Translate a location starting from a non-address "on the top of the stack". The *INPUT location is a register name or noncontiguous object specification, and this expression wants to find the "address" - of an object relative to that "address". */ + of an object (or the actual value) relative to that "address". */ static struct location * location_relative (struct obstack *pool, - int indent, Dwarf_Addr dwbias, + int indent, Dwarf_Addr dwbias, Dwarf_Attribute *attr, const Dwarf_Op *expr, size_t len, Dwarf_Addr address, struct location **input, Dwarf_Attribute *fb_attr, const Dwarf_Op *cfa_ops) @@ -790,7 +813,7 @@ location_relative (struct obstack *pool, /* This started from a register, but now it's following a pointer. So we can do the translation starting from address here. */ return location_from_address (pool, NULL, NULL, NULL, indent, dwbias, - expr, len, address, input, fb_attr, + attr, expr, len, address, input, fb_attr, cfa_ops); @@ -948,7 +971,7 @@ location_relative (struct obstack *pool, computations now have an address to start with. So we can punt to the address computation generator. */ loc = location_from_address (pool, NULL, NULL, NULL, - indent, dwbias, + indent, dwbias, attr, &expr[i + 1], len - i - 1, address, input, fb_attr, cfa_ops); @@ -1033,6 +1056,7 @@ c_translate_location (struct obstack *pool, void (*emit_address) (void *fail_arg, struct obstack *, Dwarf_Addr), int indent, Dwarf_Addr dwbias, Dwarf_Addr pc_address, + Dwarf_Attribute *attr, const Dwarf_Op *expr, size_t len, struct location **input, Dwarf_Attribute *fb_attr, const Dwarf_Op *cfa_ops) @@ -1046,15 +1070,16 @@ 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, pc_address, + indent, dwbias, attr, expr, len, pc_address, input, fb_attr, cfa_ops); 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, pc_address, - input, fb_attr, cfa_ops); + register or implicit value. We can only handle limited + computations from here. */ + return location_relative (pool, indent, dwbias, attr, expr, len, + pc_address, input, fb_attr, cfa_ops); default: abort (); -- cgit From 6ce6af84113edf73e293fe7655ed93f22109020f Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 17 Sep 2009 22:01:04 +0200 Subject: dwarf_getlocation_implicit_value() was/will be introduced in elfutils 0.143. * loc2c.c (translate): _ELFUTILS_PREREQ(0,143). Clarify attr == NULL DIE message. --- loc2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'loc2c.c') diff --git a/loc2c.c b/loc2c.c index 4bc6aa6e..3eae22e2 100644 --- a/loc2c.c +++ b/loc2c.c @@ -532,10 +532,10 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, case DW_OP_implicit_value: { if (attr == NULL) - DIE ("No Dwarf_Attribute given, but DW_OP_implicit_value used"); + DIE ("DW_OP_implicit_value used in invalid context (no dwarf attribute, ABI return value location?)"); else { -#if ! _ELFUTILS_PREREQ(0,142) +#if ! _ELFUTILS_PREREQ(0,143) Dwarf_Block block; Dwarf_Op *op = (Dwarf_Op *) &expr[i]; if (dwarf_getlocation_implicit_value (attr, op, &block) != 0) -- cgit From 0c254456b929440f2065d9af397e57b0de79a919 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 17 Sep 2009 13:13:29 -0700 Subject: Unfinished nits in loc_value code. --- loc2c.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'loc2c.c') diff --git a/loc2c.c b/loc2c.c index c5859df4..8fc4685a 100644 --- a/loc2c.c +++ b/loc2c.c @@ -194,6 +194,8 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, tos_register = -1; } + bool tos_value = false; + if (input != NULL) switch (input->type) { @@ -201,6 +203,11 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, push ("addr"); break; + case loc_value: + push ("addr"); + tos_value = true; + break; + case loc_register: tos_register = input->reg.regno; break; @@ -212,7 +219,6 @@ 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) { @@ -1924,7 +1930,7 @@ static void emit_loc_address (FILE *out, struct location *loc, unsigned int indent, const char *target) { - assert (loc->type == loc_address); + assert (loc->type == loc_address || loc->type == loc_value); if (loc->address.stack_depth == 0) /* Synthetic program. */ @@ -1966,6 +1972,7 @@ emit_loc_value (FILE *out, struct location *loc, unsigned int indent, break; case loc_address: + case loc_value: emit_loc_address (out, loc, indent, target); break; } @@ -1988,6 +1995,7 @@ c_emit_location (FILE *out, struct location *loc, int indent) break; case loc_address: + case loc_value: if (declared_addr) break; declared_addr = true; @@ -2017,6 +2025,7 @@ c_emit_location (FILE *out, struct location *loc, int indent) switch (loc->type) { case loc_address: + case loc_value: /* Emit the program fragment to calculate the address. */ emit_loc_value (out, loc, indent + 1, "addr", false); deref = deref || loc->address.used_deref; -- cgit From 707e2bec52a319441497f684b1a62d7ed97e3eff Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 17 Sep 2009 14:36:48 -0700 Subject: Support DW_OP_implicit_value. * loc2c.c (struct location): Add loc_constant variant, with constant_block field. (translate): Handle DW_OP_implicit_value to make loc_constant pieces. (c_translate_location): Handle loc_constant. (discontiguify): Likewise. (location_relative): Likewise. (declare_noncontig_union): Likewise. (translate_base_fetch): Likewise. (c_translate_array): Likewise. (c_emit_location): Likewise. (emit_base_store): Refuse loc_constant. (c_translate_addressof): Likewise. --- loc2c.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 31 deletions(-) (limited to 'loc2c.c') diff --git a/loc2c.c b/loc2c.c index 1b510543..ce5979b9 100644 --- a/loc2c.c +++ b/loc2c.c @@ -52,7 +52,7 @@ struct location enum { loc_address, loc_register, loc_noncontiguous, loc_value, - loc_decl, loc_fragment, loc_final + loc_constant, loc_decl, loc_fragment, loc_final } type; struct location *frame_base; union @@ -70,6 +70,7 @@ struct location Dwarf_Word offset; } reg; struct location *pieces; /* loc_noncontiguous */ + const void *constant_block; /* loc_constant */ }; }; @@ -195,6 +196,7 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, } bool tos_value = false; + Dwarf_Block implicit_value = { 0, NULL }; if (input != NULL) switch (input->type) @@ -228,13 +230,23 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, { obstack_1grow (pool, '\0'); char *program = obstack_finish (pool); - 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; + if (implicit_value.data == NULL) + { + 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; + } + else + { + piece->type = loc_constant; + piece->byte_size = implicit_value.length; + piece->constant_block = implicit_value.data; + } used_deref = false; tos_value = false; + implicit_value.data = NULL; } else if (tos_register == -1) DIE ("stack underflow"); @@ -258,12 +270,19 @@ 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) + inline bool more_ops (void) + { + return (expr[i].atom != DW_OP_nop + && expr[i].atom != DW_OP_piece + && expr[i].atom != DW_OP_bit_piece); + } + + if (tos_value && more_ops ()) DIE ("operations follow DW_OP_stack_value"); + if (implicit_value.data != NULL && more_ops ()) + DIE ("operations follow DW_OP_implicit_value"); + switch (expr[i].atom) { /* Basic stack operations. */ @@ -555,18 +574,23 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias, case DW_OP_implicit_value: if (attr == NULL) - DIE ("DW_OP_implicit_value used in invalid context (no DWARF attribute, ABI return value location?)"); + DIE ("DW_OP_implicit_value used in invalid context" + " (no DWARF attribute, ABI return value location?)"); + + /* It's supposed to appear by itself, except for DW_OP_piece. */ + if (stack_depth != 0) + DIE ("DW_OP_implicit_value follows stack operations"); #if _ELFUTILS_PREREQ (0, 143) - { - Dwarf_Block block; - Dwarf_Op *op = (Dwarf_Op *) &expr[i]; - if (dwarf_getlocation_implicit_value (attr, op, &block) != 0) - DIE ("dwarf_getlocation_implicit_value failed"); + if (dwarf_getlocation_implicit_value (attr, (Dwarf_Op *) &expr[i], + &implicit_value) != 0) + DIE ("dwarf_getlocation_implicit_value failed"); - /* XXX insert real support here */ - } + /* Fake top of stack: implicit_value being set marks it. */ + PUSH; + break; #endif + DIE ("DW_OP_implicit_value not supported"); break; @@ -1011,6 +1035,18 @@ location_relative (struct obstack *pool, (*input)->reg.offset += value; return head ?: *input; + case loc_constant: + /* This piece has a constant value. */ + if (value >= (*input)->byte_size) + DIE ("offset outside available constant block"); + (*input)->constant_block += value; + (*input)->byte_size -= value; + return head ?: *input; + + case loc_value: + /* The piece we want is part of a computed value! */ + /* XXX implement me! */ + default: abort (); } @@ -1099,6 +1135,7 @@ c_translate_location (struct obstack *pool, case loc_noncontiguous: case loc_register: case loc_value: + case loc_constant: /* The starting point is not an address computation, but a register or implicit value. We can only handle limited computations from here. */ @@ -1226,6 +1263,10 @@ emit_base_store (struct obstack *pool, Dwarf_Word byte_size, FAIL (loc, N_("location is computed value, cannot store")); break; + case loc_constant: + FAIL (loc, N_("location is constant value, cannot store")); + break; + default: abort (); break; @@ -1302,6 +1343,27 @@ discontiguify (struct obstack *pool, int indent, struct location *loc, break; } + case loc_constant: + { + Dwarf_Word offset = 0; + while (total_bytes - offset > 0) + { + Dwarf_Word size = total_bytes - offset; + if (size > max_piece_bytes) + size = max_piece_bytes; + + struct location *piece = alloc_location (pool, loc); + piece->next = NULL; + piece->type = loc_constant; + piece->byte_size = size; + piece->constant_block = loc->constant_block + offset; + + add (piece); + } + + break; + } + case loc_value: FAIL (loc, N_("stack value too big for fetch ???")); break; @@ -1345,17 +1407,20 @@ declare_noncontig_union (struct obstack *pool, int indent, obstack_printf (pool, "%*sstruct {\n", indent++ * 2, ""); - Dwarf_Word offset = 0; - struct location *p; - for (p = loc->pieces; p != NULL; p = p->next) + if (loc->type == loc_noncontiguous) { - obstack_printf (pool, "%*suint%" PRIu64 "_t p%" PRIu64 ";\n", - indent * 2, "", p->byte_size * 8, offset); - offset += p->byte_size; - } + Dwarf_Word offset = 0; + struct location *p; + for (p = loc->pieces; p != NULL; p = p->next) + { + obstack_printf (pool, "%*suint%" PRIu64 "_t p%" PRIu64 ";\n", + indent * 2, "", p->byte_size * 8, offset); + offset += p->byte_size; + } - obstack_printf (pool, "%*s} pieces __attribute__ ((packed));\n", - --indent * 2, ""); + obstack_printf (pool, "%*s} pieces __attribute__ ((packed));\n", + --indent * 2, ""); + } obstack_printf (pool, "%*suint%" PRIu64 "_t whole;\n", indent * 2, "", loc->byte_size * 8); @@ -1429,8 +1494,9 @@ get_bitfield (struct location *loc, /* Translate a fragment to fetch the base-type value of BYTE_SIZE bytes at the *INPUT location and store it in lvalue TARGET. */ static void -translate_base_fetch (struct obstack *pool, int indent, Dwarf_Word byte_size, - bool signed_p, struct location **input, const char *target) +translate_base_fetch (struct obstack *pool, int indent, + Dwarf_Word byte_size, bool signed_p, + struct location **input, const char *target) { bool deref = false; @@ -1459,6 +1525,20 @@ translate_base_fetch (struct obstack *pool, int indent, Dwarf_Word byte_size, p = p->next; } + obstack_printf (pool, "%*s%s = u.whole;\n", indent * 2, "", target); + } + else if ((*input)->type == loc_constant) + { + const unsigned char *constant_block = (*input)->constant_block; + const size_t byte_size = (*input)->byte_size; + size_t i; + + declare_noncontig_union (pool, indent, input, *input); + + for (i = 0; i < byte_size; ++i) + obstack_printf (pool, "%*su.bytes[%zu] = %#x;\n", indent * 2, "", + i, constant_block[i]); + obstack_printf (pool, "%*s%s = u.whole;\n", indent * 2, "", target); } else @@ -1522,8 +1602,7 @@ c_translate_fetch (struct obstack *pool, int indent, if (dwarf_attr_integrate (die, DW_AT_encoding, &encoding_attr) == NULL || dwarf_formudata (&encoding_attr, &encoding) != 0) encoding = base_encoding (typedie, *input); - bool signed_p = (encoding == DW_ATE_signed - || encoding == DW_ATE_signed_char); + bool signed_p = encoding == DW_ATE_signed || encoding == DW_ATE_signed_char; *input = discontiguify (pool, indent, *input, byte_size, max_fetch_size (*input, die)); @@ -1739,6 +1818,9 @@ c_translate_addressof (struct obstack *pool, int indent, case loc_value: FAIL (*input, N_("cannot take address of computed value")); break; + case loc_constant: + FAIL (*input, N_("cannot take address of constant value")); + break; default: abort(); @@ -1886,6 +1968,19 @@ c_translate_array (struct obstack *pool, int indent, } break; + case loc_constant: + if (idx != NULL) + FAIL (*input, N_("cannot index into constant value")); + else if (const_idx > loc->byte_size / stride) + FAIL (*input, N_("constant index is outside constant array value")); + else + { + loc->byte_size = stride; + loc->constant_block += const_idx * stride; + return; + }; + break; + case loc_value: FAIL (*input, N_("cannot index into computed value")); break; @@ -2059,6 +2154,7 @@ c_emit_location (FILE *out, struct location *loc, int indent) case loc_decl: case loc_register: case loc_noncontiguous: + case loc_constant: /* These don't produce any code directly. The next address/final record incorporates the value. */ break; -- cgit