diff options
Diffstat (limited to 'gdb/dwarf2/loc.c')
-rw-r--r-- | gdb/dwarf2/loc.c | 183 |
1 files changed, 108 insertions, 75 deletions
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index 5fea668..37c85d8 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -1,6 +1,6 @@ /* DWARF 2 location expression support for GDB. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 Free Software Foundation, Inc. Contributed by Daniel Jacobowitz, MontaVista Software, Inc. @@ -41,16 +41,15 @@ #include "dwarf2/frame.h" #include "dwarf2/leb.h" #include "compile/compile.h" -#include "gdbsupport/selftest.h" #include <algorithm> #include <vector> -#include <unordered_set> #include "gdbsupport/underlying.h" #include "gdbsupport/byte-vector.h" +#include "extract-store-integer.h" static struct value *dwarf2_evaluate_loc_desc_full (struct type *type, const frame_info_ptr &frame, const gdb_byte *data, - size_t size, dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile, + size_t size, dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile, struct type *subobj_type, LONGEST subobj_byte_offset, bool as_lval = true); /* Until these have formal names, we define these here. @@ -154,7 +153,7 @@ decode_debug_loc_addresses (const gdb_byte *loc_ptr, const gdb_byte *buf_end, The result indicates the kind of entry found. */ static enum debug_loc_kind -decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu, +decode_debug_loclists_addresses (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile, const gdb_byte *loc_ptr, const gdb_byte *buf_end, @@ -289,7 +288,7 @@ decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu, The result indicates the kind of entry found. */ static enum debug_loc_kind -decode_debug_loc_dwo_addresses (dwarf2_per_cu_data *per_cu, +decode_debug_loc_dwo_addresses (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile, const gdb_byte *loc_ptr, const gdb_byte *buf_end, @@ -389,12 +388,12 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton, enum debug_loc_kind kind; const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */ - if (baton->per_cu->version () < 5 && baton->from_dwo) + if (baton->dwarf_version < 5 && baton->from_dwo) kind = decode_debug_loc_dwo_addresses (baton->per_cu, baton->per_objfile, loc_ptr, buf_end, &new_ptr, &low, &high, byte_order); - else if (baton->per_cu->version () < 5) + else if (baton->dwarf_version < 5) kind = decode_debug_loc_addresses (loc_ptr, buf_end, &new_ptr, &low, &high, byte_order, addr_size, @@ -445,7 +444,7 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton, high = (unrelocated_addr) ((CORE_ADDR) high + (CORE_ADDR) base_address); } - if (baton->per_cu->version () < 5) + if (baton->dwarf_version < 5) { length = extract_unsigned_integer (loc_ptr, 2, byte_order); loc_ptr += 2; @@ -667,9 +666,8 @@ call_site_target::iterate_over_addresses (gdbarch *call_site_gdbarch, dwarf_block = m_loc.dwarf_block; if (dwarf_block == NULL) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol_by_pc (call_site->pc () - 1); + bound_minimal_symbol msym + = lookup_minimal_symbol_by_pc (call_site->pc () - 1); throw_error (NO_ENTRY_VALUE_ERROR, _("DW_AT_call_target is not specified at %s in %s"), paddress (call_site_gdbarch, call_site->pc ()), @@ -679,9 +677,8 @@ call_site_target::iterate_over_addresses (gdbarch *call_site_gdbarch, } if (caller_frame == NULL) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol_by_pc (call_site->pc () - 1); + bound_minimal_symbol msym + = lookup_minimal_symbol_by_pc (call_site->pc () - 1); throw_error (NO_ENTRY_VALUE_ERROR, _("DW_AT_call_target DWARF block resolving " "requires known frame which is currently not " @@ -708,12 +705,12 @@ call_site_target::iterate_over_addresses (gdbarch *call_site_gdbarch, case call_site_target::PHYSNAME: { const char *physname; - struct bound_minimal_symbol msym; physname = m_loc.physname; /* Handle both the mangled and demangled PHYSNAME. */ - msym = lookup_minimal_symbol (physname, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, physname); if (msym.minsym == NULL) { msym = lookup_minimal_symbol_by_pc (call_site->pc () - 1); @@ -782,7 +779,7 @@ func_addr_to_tail_call_list (struct gdbarch *gdbarch, CORE_ADDR addr) via its tail calls (incl. transitively). Throw NO_ENTRY_VALUE_ERROR if it can call itself via tail calls. - If a funtion can tail call itself its entry value based parameters are + If a function can tail call itself its entry value based parameters are unreliable. There is no verification whether the value of some/all parameters is unchanged through the self tail call, we expect if there is a self tail call all the parameters can be modified. */ @@ -797,7 +794,7 @@ func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr) std::vector<CORE_ADDR> todo; /* Track here CORE_ADDRs which were already visited. */ - std::unordered_set<CORE_ADDR> addr_hash; + gdb::unordered_set<CORE_ADDR> addr_hash; todo.push_back (verify_addr); while (!todo.empty ()) @@ -820,9 +817,8 @@ func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr) { if (target_addr == verify_addr) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol_by_pc (verify_addr); + bound_minimal_symbol msym + = lookup_minimal_symbol_by_pc (verify_addr); throw_error (NO_ENTRY_VALUE_ERROR, _("DW_OP_entry_value resolving has found " "function \"%s\" at %s can call itself via tail " @@ -846,7 +842,7 @@ static void tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site) { CORE_ADDR addr = call_site->pc (); - struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1); gdb_printf (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr), (msym.minsym == NULL ? "???" @@ -967,7 +963,7 @@ call_site_find_chain_2 (struct gdbarch *gdbarch, gdb::unique_xmalloc_ptr<struct call_site_chain> *resultp, std::vector<struct call_site *> &chain, - std::unordered_set<CORE_ADDR> &addr_hash, + gdb::unordered_set<CORE_ADDR> &addr_hash, struct call_site *call_site, CORE_ADDR callee_pc) { @@ -1050,7 +1046,7 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc, paddress (gdbarch, save_callee_pc)); /* Mark CALL_SITEs so we do not visit the same ones twice. */ - std::unordered_set<CORE_ADDR> addr_hash; + gdb::unordered_set<CORE_ADDR> addr_hash; /* Do not push CALL_SITE to CHAIN. Push there only the first tail call site at the target's function. All the possible tail call sites in the @@ -1064,10 +1060,10 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc, if (retval == NULL) { - struct bound_minimal_symbol msym_caller, msym_callee; - - msym_caller = lookup_minimal_symbol_by_pc (caller_pc); - msym_callee = lookup_minimal_symbol_by_pc (callee_pc); + bound_minimal_symbol msym_caller + = lookup_minimal_symbol_by_pc (caller_pc); + bound_minimal_symbol msym_callee + = lookup_minimal_symbol_by_pc (callee_pc); throw_error (NO_ENTRY_VALUE_ERROR, _("There are no unambiguously determinable intermediate " "callers or callees between caller function \"%s\" at %s " @@ -1141,7 +1137,7 @@ struct call_site_parameter * dwarf_expr_reg_to_entry_parameter (const frame_info_ptr &initial_frame, call_site_parameter_kind kind, call_site_parameter_u kind_u, - dwarf2_per_cu_data **per_cu_return, + dwarf2_per_cu **per_cu_return, dwarf2_per_objfile **per_objfile_return) { CORE_ADDR func_addr, caller_pc; @@ -1165,8 +1161,7 @@ dwarf_expr_reg_to_entry_parameter (const frame_info_ptr &initial_frame, caller_frame = get_prev_frame (frame); if (gdbarch != frame_unwind_arch (frame)) { - struct bound_minimal_symbol msym - = lookup_minimal_symbol_by_pc (func_addr); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (func_addr); struct gdbarch *caller_gdbarch = frame_unwind_arch (frame); throw_error (NO_ENTRY_VALUE_ERROR, @@ -1181,8 +1176,7 @@ dwarf_expr_reg_to_entry_parameter (const frame_info_ptr &initial_frame, if (caller_frame == NULL) { - struct bound_minimal_symbol msym - = lookup_minimal_symbol_by_pc (func_addr); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (func_addr); throw_error (NO_ENTRY_VALUE_ERROR, _("DW_OP_entry_value resolving " "requires caller of %s (%s)"), @@ -1265,7 +1259,7 @@ static struct value * dwarf_entry_parameter_to_value (struct call_site_parameter *parameter, CORE_ADDR deref_size, struct type *type, const frame_info_ptr &caller_frame, - dwarf2_per_cu_data *per_cu, + dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile) { const gdb_byte *data_src; @@ -1349,7 +1343,7 @@ value_of_dwarf_reg_entry (struct type *type, const frame_info_ptr &frame, frame_info_ptr caller_frame = get_prev_frame (frame); struct value *outer_val, *target_val, *val; struct call_site_parameter *parameter; - dwarf2_per_cu_data *caller_per_cu; + dwarf2_per_cu *caller_per_cu; dwarf2_per_objfile *caller_per_objfile; parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u, @@ -1422,7 +1416,7 @@ value_of_dwarf_block_entry (struct type *type, const frame_info_ptr &frame, static struct value * fetch_const_value_from_synthetic_pointer (sect_offset die, LONGEST byte_offset, - dwarf2_per_cu_data *per_cu, + dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile, struct type *type) { @@ -1455,7 +1449,7 @@ fetch_const_value_from_synthetic_pointer (sect_offset die, LONGEST byte_offset, struct value * indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset, - dwarf2_per_cu_data *per_cu, + dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile, const frame_info_ptr &frame, struct type *type, bool resolve_abstract_p) @@ -1499,7 +1493,7 @@ indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset, static struct value * dwarf2_evaluate_loc_desc_full (struct type *type, const frame_info_ptr &frame, const gdb_byte *data, size_t size, - dwarf2_per_cu_data *per_cu, + dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile, struct type *subobj_type, LONGEST subobj_byte_offset, @@ -1564,7 +1558,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, const frame_info_ptr &frame, struct value * dwarf2_evaluate_loc_desc (struct type *type, const frame_info_ptr &frame, const gdb_byte *data, size_t size, - dwarf2_per_cu_data *per_cu, + dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile, bool as_lval) { return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, @@ -1595,7 +1589,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, return 0; dwarf2_per_objfile *per_objfile = dlbaton->per_objfile; - dwarf2_per_cu_data *per_cu = dlbaton->per_cu; + dwarf2_per_cu *per_cu = dlbaton->per_cu; dwarf_expr_context ctx (per_objfile, per_cu->addr_size ()); value *result; @@ -1738,11 +1732,10 @@ dwarf2_evaluate_property (const dynamic_prop *prop, *value = prop->const_val (); return true; - case PROP_ADDR_OFFSET: + case PROP_FIELD: { const dwarf2_property_baton *baton = prop->baton (); const struct property_addr_info *pinfo; - struct value *val; for (pinfo = addr_stack; pinfo != NULL; pinfo = pinfo->next) { @@ -1753,14 +1746,40 @@ dwarf2_evaluate_property (const dynamic_prop *prop, } if (pinfo == NULL) error (_("cannot find reference address for offset property")); - if (pinfo->valaddr.data () != NULL) - val = value_from_contents - (baton->offset_info.type, - pinfo->valaddr.data () + baton->offset_info.offset); - else - val = value_at (baton->offset_info.type, - pinfo->addr + baton->offset_info.offset); - *value = value_as_address (val); + + struct field resolved_field = baton->field; + resolve_dynamic_field (resolved_field, pinfo, initial_frame); + + /* Storage for memory if we need to read it. */ + gdb::byte_vector memory; + const gdb_byte *bytes = pinfo->valaddr.data (); + if (bytes == nullptr) + { + int bitpos = resolved_field.loc_bitpos (); + int bitsize = resolved_field.bitsize (); + if (bitsize == 0) + bitsize = check_typedef (resolved_field.type ())->length () * 8; + + /* Read just the minimum number of bytes needed to satisfy + unpack_field_as_long. So, update the resolved field's + starting offset to remove any unnecessary leading + bytes. */ + int byte_offset = bitpos / 8; + + bitpos %= 8; + resolved_field.set_loc_bitpos (bitpos); + + /* Make sure to include any remaining bit offset in the + size computation, in case the value straddles a + byte. */ + int byte_length = align_up (bitsize + bitpos, 8) / 8; + memory.resize (byte_length); + + read_memory (pinfo->addr + byte_offset, memory.data (), + byte_length); + bytes = memory.data (); + } + *value = unpack_field_as_long (bytes, &resolved_field); return true; } @@ -1790,10 +1809,11 @@ dwarf2_compile_property_to_c (string_file *stream, CORE_ADDR pc, struct symbol *sym) { +#if defined (HAVE_COMPILE) const dwarf2_property_baton *baton = prop->baton (); const gdb_byte *data; size_t size; - dwarf2_per_cu_data *per_cu; + dwarf2_per_cu *per_cu; dwarf2_per_objfile *per_objfile; if (prop->kind () == PROP_LOCEXPR) @@ -1816,6 +1836,9 @@ dwarf2_compile_property_to_c (string_file *stream, gdbarch, registers_used, per_cu->addr_size (), data, data + size, per_cu, per_objfile); +#else + gdb_assert_not_reached ("Compile support was disabled"); +#endif } /* Compute the correct symbol_needs_kind value for the location @@ -1826,7 +1849,7 @@ dwarf2_compile_property_to_c (string_file *stream, static enum symbol_needs_kind dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr, - dwarf2_per_cu_data *per_cu, + dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile, bfd_endian byte_order, int addr_size, @@ -1846,7 +1869,7 @@ dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr, std::vector<const gdb_byte *> ops_to_visit; /* Operations already visited. */ - std::unordered_set<const gdb_byte *> visited_ops; + gdb::unordered_set<const gdb_byte *> visited_ops; /* Insert OP in OPS_TO_VISIT if it is within the expression's range and hasn't been visited yet. */ @@ -1973,6 +1996,7 @@ dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr, case DW_OP_GNU_reinterpret: case DW_OP_addrx: case DW_OP_GNU_addr_index: + case DW_OP_constx: case DW_OP_GNU_const_index: case DW_OP_constu: case DW_OP_plus_uconst: @@ -2253,7 +2277,7 @@ dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr, /* A helper function that throws an unimplemented error mentioning a given DWARF operator. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void unimplemented (unsigned int op) { const char *name = get_DW_OP_name (op); @@ -2376,8 +2400,7 @@ access_memory (struct gdbarch *arch, struct agent_expr *expr, ULONGEST nbits) static void dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, unsigned int addr_size, const gdb_byte *op_ptr, - const gdb_byte *op_end, - dwarf2_per_cu_data *per_cu, + const gdb_byte *op_end, dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile) { gdbarch *arch = expr->gdbarch; @@ -3139,7 +3162,7 @@ locexpr_regname (struct gdbarch *gdbarch, int dwarf_regnum) static const gdb_byte * locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, - CORE_ADDR addr, dwarf2_per_cu_data *per_cu, + CORE_ADDR addr, dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile, const gdb_byte *data, const gdb_byte *end, unsigned int addr_size) @@ -3271,10 +3294,13 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, /* With -gsplit-dwarf a TLS variable can also look like this: DW_AT_location : 3 byte block: fc 4 e0 (DW_OP_GNU_const_index: 4; - DW_OP_GNU_push_tls_address) */ + DW_OP_GNU_push_tls_address) | + 3 byte block a2 4 e0 + (DW_OP_constx: 4; + DW_OP_form_tls_address) */ else if (data + 3 <= end && data + 1 + (leb128_size = skip_leb128 (data + 1, end)) < end - && data[0] == DW_OP_GNU_const_index + && (data[0] == DW_OP_constx || data[0] == DW_OP_GNU_const_index) && leb128_size > 0 && (data[1 + leb128_size] == DW_OP_GNU_push_tls_address || data[1 + leb128_size] == DW_OP_form_tls_address) @@ -3316,7 +3342,7 @@ disassemble_dwarf_expression (struct ui_file *stream, int offset_size, const gdb_byte *start, const gdb_byte *data, const gdb_byte *end, int indent, int all, - dwarf2_per_cu_data *per_cu, + dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile) { while (data < end @@ -3681,6 +3707,7 @@ disassemble_dwarf_expression (struct ui_file *stream, gdb_printf (stream, " 0x%s", phex_nz (ul, addr_size)); break; + case DW_OP_constx: case DW_OP_GNU_const_index: data = safe_read_uleb128 (data, end, &ul); ul = (uint64_t) dwarf2_read_addr_index (per_cu, per_objfile, ul); @@ -3721,7 +3748,7 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr, struct ui_file *stream, const gdb_byte *data, size_t size, unsigned int addr_size, - int offset_size, dwarf2_per_cu_data *per_cu, + int offset_size, dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile) { const gdb_byte *end = data + size; @@ -3854,6 +3881,7 @@ locexpr_generate_c_location (struct symbol *sym, string_file *stream, std::vector<bool> ®isters_used, CORE_ADDR pc, const char *result_name) { +#if defined (HAVE_COMPILE) struct dwarf2_locexpr_baton *dlbaton = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (sym); unsigned int addr_size = dlbaton->per_cu->addr_size (); @@ -3865,6 +3893,9 @@ locexpr_generate_c_location (struct symbol *sym, string_file *stream, sym, pc, gdbarch, registers_used, addr_size, dlbaton->data, dlbaton->data + dlbaton->size, dlbaton->per_cu, dlbaton->per_objfile); +#else + gdb_assert_not_reached ("Compile support was disabled"); +#endif } /* The set of location functions used with the DWARF-2 expression @@ -3978,12 +4009,12 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr, enum debug_loc_kind kind; const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */ - if (dlbaton->per_cu->version () < 5 && dlbaton->from_dwo) + if (dlbaton->dwarf_version < 5 && dlbaton->from_dwo) kind = decode_debug_loc_dwo_addresses (dlbaton->per_cu, per_objfile, loc_ptr, buf_end, &new_ptr, &low, &high, byte_order); - else if (dlbaton->per_cu->version () < 5) + else if (dlbaton->dwarf_version < 5) kind = decode_debug_loc_addresses (loc_ptr, buf_end, &new_ptr, &low, &high, byte_order, addr_size, @@ -4033,7 +4064,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr, CORE_ADDR low_reloc = per_objfile->relocate (low); CORE_ADDR high_reloc = per_objfile->relocate (high); - if (dlbaton->per_cu->version () < 5) + if (dlbaton->dwarf_version < 5) { length = extract_unsigned_integer (loc_ptr, 2, byte_order); loc_ptr += 2; @@ -4090,6 +4121,7 @@ loclist_generate_c_location (struct symbol *sym, string_file *stream, std::vector<bool> ®isters_used, CORE_ADDR pc, const char *result_name) { +#if defined (HAVE_COMPILE) struct dwarf2_loclist_baton *dlbaton = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (sym); unsigned int addr_size = dlbaton->per_cu->addr_size (); @@ -4105,6 +4137,9 @@ loclist_generate_c_location (struct symbol *sym, string_file *stream, data, data + size, dlbaton->per_cu, dlbaton->per_objfile); +#else + gdb_assert_not_reached ("Compile support was disabled"); +#endif } /* The set of location functions used with the DWARF-2 expression @@ -4119,19 +4154,17 @@ const struct symbol_computed_ops dwarf2_loclist_funcs = { loclist_generate_c_location }; -void _initialize_dwarf2loc (); -void -_initialize_dwarf2loc () +INIT_GDB_FILE (dwarf2loc) { add_setshow_zuinteger_cmd ("entry-values", class_maintenance, &entry_values_debug, - _("Set entry values and tail call frames " - "debugging."), - _("Show entry values and tail call frames " - "debugging."), - _("When non-zero, the process of determining " - "parameter values from function entry point " - "and tail call frames will be printed."), + _("\ +Set entry values and tail call frames debugging."), + _("\ +Show entry values and tail call frames debugging."), + _("\ +When non-zero, the process of determining parameter values from\n\ +function entry point and tail call frames will be printed."), NULL, show_entry_values_debug, &setdebuglist, &showdebuglist); |