diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 56d7f7c6c5..ba80e5ae50 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2011-10-12 Jan Kratochvil + + Fix empty DWARF expressions DATA vs. SIZE conditionals. + * dwarf2loc.c (dwarf2_find_location_expression): Clear *LOCEXPR_LENGTH. + (dwarf_expr_frame_base_1): Indicate unavailability via zero *LENGTH. + (locexpr_tracepoint_var_ref): Check only zero SIZE, not zero DATA. + (loclist_read_variable, loclist_tracepoint_var_ref): Do not check for + zero DATA. + * dwarf2loc.h (struct dwarf2_locexpr_baton): Comment DATA vs. SIZE + validity. + * dwarf2read.c (struct dwarf_block): Comment DATA validity. + (dwarf2_fetch_die_location_block, dwarf2_symbol_mark_computed): Do not + clear DATA on zero SIZE. + 2011-10-12 Doug Evans * dwarf2read.c (partial_read_comp_unit_head): Set header->offset, diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 7eb8d8ac7e..8a7d7e9ef9 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -112,7 +112,10 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton, /* An end-of-list entry. */ if (low == 0 && high == 0) - return NULL; + { + *locexpr_length = 0; + return NULL; + } /* Otherwise, a location expression entry. */ low += base_address; @@ -215,7 +218,7 @@ dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc, const gdb_byte **start, size_t *length) { if (SYMBOL_LOCATION_BATON (framefunc) == NULL) - *start = NULL; + *length = 0; else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs) { struct dwarf2_loclist_baton *symbaton; @@ -234,10 +237,10 @@ dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc, *start = symbaton->data; } else - *start = NULL; + *length = 0; } - if (*start == NULL) + if (*length == 0) error (_("Could not find the frame base for \"%s\"."), SYMBOL_NATURAL_NAME (framefunc)); } @@ -3716,7 +3719,7 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu); - if (dlbaton->data == NULL || dlbaton->size == 0) + if (dlbaton->size == 0) value->optimized_out = 1; else dwarf2_compile_expr_to_ax (ax, value, gdbarch, addr_size, @@ -3750,11 +3753,8 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame) CORE_ADDR pc = frame ? get_frame_address_in_block (frame) : 0; data = dwarf2_find_location_expression (dlbaton, &size, pc); - if (data == NULL) - val = allocate_optimized_out_value (SYMBOL_TYPE (symbol)); - else - val = dwarf2_evaluate_loc_desc (SYMBOL_TYPE (symbol), frame, data, size, - dlbaton->per_cu); + val = dwarf2_evaluate_loc_desc (SYMBOL_TYPE (symbol), frame, data, size, + dlbaton->per_cu); return val; } @@ -3893,7 +3893,7 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu); data = dwarf2_find_location_expression (dlbaton, &size, ax->scope); - if (data == NULL || size == 0) + if (size == 0) value->optimized_out = 1; else dwarf2_compile_expr_to_ax (ax, value, gdbarch, addr_size, data, data + size, diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h index 32aa0af3df..819679191e 100644 --- a/gdb/dwarf2loc.h +++ b/gdb/dwarf2loc.h @@ -87,10 +87,12 @@ struct value *dwarf2_evaluate_loc_desc (struct type *type, struct dwarf2_locexpr_baton { - /* Pointer to the start of the location expression. */ + /* Pointer to the start of the location expression. Valid only if SIZE is + not zero. */ const gdb_byte *data; - /* Length of the location expression. */ + /* Length of the location expression. For optimized out expressions it is + zero. */ unsigned long size; /* The compilation unit containing the symbol whose location diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 0b16ef8ec5..5fa6c5b387 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -722,6 +722,8 @@ struct function_range struct dwarf_block { unsigned int size; + + /* Valid only if SIZE is not zero. */ gdb_byte *data; }; @@ -14217,7 +14219,6 @@ dwarf2_fetch_die_location_block (unsigned int offset, { /* DWARF: "If there is no such attribute, then there is no effect.". */ - retval.data = NULL; retval.size = 0; } else if (attr_form_is_section_offset (attr)) @@ -15495,7 +15496,6 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, dwarf2_invalid_attrib_class_complaint ("location description", SYMBOL_NATURAL_NAME (sym)); baton->size = 0; - baton->data = NULL; } SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 285f8424e5..b06f8704be 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2011-10-12 Jan Kratochvil + + Fix empty DWARF expressions DATA vs. SIZE conditionals. + * gdb.dwarf2/dw2-op-call.S (arraycallnoloc, arraynoloc): New DIEs. + (loclist): New. + (4): New abbrev. + * gdb.dwarf2/dw2-op-call.exp: Remove variable srcfile and executable. + Use prepare_for_testing, remove clean_restart. + (p arraynoloc, p arraycallnoloc): New tests. + 2011-10-12 Jan Kratochvil * gdb.cp/namespace-enum.exp (executable): New variable. diff --git a/gdb/testsuite/gdb.dwarf2/dw2-op-call.S b/gdb/testsuite/gdb.dwarf2/dw2-op-call.S index 9a0efcafea..0db493e86b 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-op-call.S +++ b/gdb/testsuite/gdb.dwarf2/dw2-op-call.S @@ -72,10 +72,30 @@ array3: .2byte 3 .uleb128 array3-array1 /* */ 2: + .uleb128 3 /* Abbrev: DW_TAG_variable */ + .ascii "arraycallnoloc\0" /* DW_AT_name */ + .4byte .L2byte_type-.Lcu1_begin /* DW_AT_type */ + .byte 2f - 1f /* DW_AT_location */ +1: .byte 0x99 /* DW_OP_call4 */ + .4byte .Larraynoloc-.Lcu1_begin /* */ +2: + +.Larraynoloc: + .uleb128 4 /* Abbrev: DW_TAG_variable-loclist */ + .ascii "arraynoloc\0" /* DW_AT_name */ + .4byte .L2byte_type-.Lcu1_begin /* DW_AT_type */ + .4byte loclist /* DW_AT_location */ + .byte 0 /* End of children of CU */ .Lcu1_end: +/* Location list. */ + .section .debug_loc +loclist: + /* Location list end. */ + .4byte 0, 0 + /* Abbrev table */ .section .debug_abbrev .Labbrev1_begin: @@ -115,5 +135,17 @@ array3: .2byte 3 .byte 0x0 /* Terminator */ .byte 0x0 /* Terminator */ + .uleb128 4 /* Abbrev code */ + .uleb128 0x34 /* DW_TAG_variable-loclist */ + .byte 0 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x2 /* DW_AT_location */ + .uleb128 0x06 /* DW_FORM_data4 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ .byte 0x0 /* Terminator */ diff --git a/gdb/testsuite/gdb.dwarf2/dw2-op-call.exp b/gdb/testsuite/gdb.dwarf2/dw2-op-call.exp index 3319133378..416eef45fa 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-op-call.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-op-call.exp @@ -22,18 +22,20 @@ if {![dwarf2_support]} { } set testfile "dw2-op-call" -set srcfile ${testfile}.S -set executable ${testfile}.x - -if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${executable}" object {nodebug}] != "" } { +if { [prepare_for_testing ${testfile}.exp ${testfile} [list ${testfile}.S main.c] {nodebug}] } { return -1 } -clean_restart $executable - # Additional test to verify the referenced CU is not aged out. gdb_test_no_output "maintenance set dwarf2 max-cache-age 0" gdb_test "p array1" " = 1" gdb_test "p array2" " = 2" "array2 using DW_OP_call2" gdb_test "p array3" " = 3" "array3 using DW_OP_call4" + +# Location lists need PC. +if ![runto_main] { + return -1 +} +gdb_test "p arraynoloc" " = " +gdb_test "p arraycallnoloc" {Asked for position 0 of stack, stack only has 0 elements on it\.}