diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2010-06-07 19:55:33 +0000 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2010-06-07 19:55:33 +0000 |
commit | 5c631832c12b23cae13bde49a3d393e8bf94f599 (patch) | |
tree | 98209d93e18f835b6343c45693d1dc75fc882afe /gdb/dwarf2read.c | |
parent | 17ea53c331199c560a28089d4c5757caa1517d33 (diff) | |
download | gdb-5c631832c12b23cae13bde49a3d393e8bf94f599.zip gdb-5c631832c12b23cae13bde49a3d393e8bf94f599.tar.gz gdb-5c631832c12b23cae13bde49a3d393e8bf94f599.tar.bz2 |
gdb/
Fix PR 10640.
* dwarf2-frame.c (no_dwarf_call): New function.
(execute_stack_op): Set CTX->DWARF_CALL.
* dwarf2expr.c (execute_stack_op) <DW_OP_call2, DW_OP_call4>: New.
* dwarf2expr.h (struct dwarf_expr_context) <dwarf_call>: New.
(struct dwarf_expr_context) <get_subr>: Remove the #if0-ed field.
* dwarf2loc.c (per_cu_dwarf_call, dwarf_expr_dwarf_call): New functions.
(dwarf2_evaluate_loc_desc): Initialize CTX->DWARF_CALL.
(needs_frame_dwarf_call): New function.
(dwarf2_loc_desc_needs_frame): Initialize CTX->DWARF_CALL.
* dwarf2read.c (follow_die_offset): Based on former follow_die_ref.
Update the comment. Move variables die, offset and error call to ...
(follow_die_ref): ... a new function.
(dwarf2_fetch_die_location_block): New function.
* dwarf2loc.h (dwarf2_fetch_die_location_block): New prototype.
gdb/testsuite/
Test PR 10640.
* gdb.dwarf2/dw2-op-call.exp, gdb.dwarf2/dw2-op-call.S: New.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 79 |
1 files changed, 63 insertions, 16 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 6a6f1cb..05fbd09 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -10736,30 +10736,25 @@ follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr, return die; } -/* Follow reference attribute ATTR of SRC_DIE. - On entry *REF_CU is the CU of SRC_DIE. +/* Follow reference OFFSET. + On entry *REF_CU is the CU of source DIE referencing OFFSET. On exit *REF_CU is the CU of the result. */ static struct die_info * -follow_die_ref (struct die_info *src_die, struct attribute *attr, - struct dwarf2_cu **ref_cu) +follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu) { - struct die_info *die; - unsigned int offset; struct die_info temp_die; struct dwarf2_cu *target_cu, *cu = *ref_cu; gdb_assert (cu->per_cu != NULL); - offset = dwarf2_get_ref_die_offset (attr); - if (cu->per_cu->from_debug_types) { /* .debug_types CUs cannot reference anything outside their CU. If they need to, they have to reference a signatured type via DW_FORM_sig8. */ if (! offset_in_cu_p (&cu->header, offset)) - goto not_found; + return NULL; target_cu = cu; } else if (! offset_in_cu_p (&cu->header, offset)) @@ -10779,15 +10774,67 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr, *ref_cu = target_cu; temp_die.offset = offset; - die = htab_find_with_hash (target_cu->die_hash, &temp_die, offset); - if (die) - return die; + return htab_find_with_hash (target_cu->die_hash, &temp_die, offset); +} - not_found: +/* Follow reference attribute ATTR of SRC_DIE. + On entry *REF_CU is the CU of SRC_DIE. + On exit *REF_CU is the CU of the result. */ - error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE " - "at 0x%x [in module %s]"), - offset, src_die->offset, cu->objfile->name); +static struct die_info * +follow_die_ref (struct die_info *src_die, struct attribute *attr, + struct dwarf2_cu **ref_cu) +{ + unsigned int offset = dwarf2_get_ref_die_offset (attr); + struct dwarf2_cu *cu = *ref_cu; + struct die_info *die; + + die = follow_die_offset (offset, ref_cu); + if (!die) + error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE " + "at 0x%x [in module %s]"), + offset, src_die->offset, cu->objfile->name); + + return die; +} + +/* Return DWARF block and its CU referenced by OFFSET at PER_CU. Returned + value is intended for DW_OP_call*. */ + +struct dwarf2_locexpr_baton +dwarf2_fetch_die_location_block (unsigned int offset, + struct dwarf2_per_cu_data *per_cu) +{ + struct dwarf2_cu *cu = per_cu->cu; + struct die_info *die; + struct attribute *attr; + struct dwarf2_locexpr_baton retval; + + die = follow_die_offset (offset, &cu); + if (!die) + error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"), + offset, per_cu->cu->objfile->name); + + attr = dwarf2_attr (die, DW_AT_location, cu); + if (!attr) + { + /* DWARF: "If there is no such attribute, then there is no effect.". */ + + retval.data = NULL; + retval.size = 0; + } + else + { + if (!attr_form_is_block (attr)) + error (_("Dwarf Error: DIE at 0x%x referenced in module %s " + "is neither DW_FORM_block* nor DW_FORM_exprloc"), + offset, per_cu->cu->objfile->name); + + retval.data = DW_BLOCK (attr)->data; + retval.size = DW_BLOCK (attr)->size; + } + retval.per_cu = cu->per_cu; + return retval; } /* Follow the signature attribute ATTR in SRC_DIE. |