diff options
Diffstat (limited to 'gdb/dwarf2/read.c')
-rw-r--r-- | gdb/dwarf2/read.c | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 37cabe5..59a6500 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -10987,20 +10987,19 @@ dwarf2_ranges_read_low_addrs (unsigned offset, struct dwarf2_cu *cu, }); } -/* Get low and high pc attributes from a die. See enum pc_bounds_kind - definition for the return value. *LOWPC and *HIGHPC are set iff - neither PC_BOUNDS_NOT_PRESENT nor PC_BOUNDS_INVALID are returned. */ +/* Determine the low and high pc using the DW_AT_low_pc and DW_AT_high_pc or + DW_AT_ranges attributes of a DIE. */ -static enum pc_bounds_kind -dwarf2_get_pc_bounds (struct die_info *die, unrelocated_addr *lowpc, - unrelocated_addr *highpc, struct dwarf2_cu *cu, - addrmap *map, void *datum) +static pc_bounds_kind +dwarf_get_pc_bounds_ranges_or_highlow_pc (die_info *die, unrelocated_addr *low, + unrelocated_addr *high, dwarf2_cu *cu, + addrmap *map, void *datum) { - dwarf2_per_objfile *per_objfile = cu->per_objfile; + gdb_assert (low != nullptr); + gdb_assert (high != nullptr); + struct attribute *attr; struct attribute *attr_high; - unrelocated_addr low = {}; - unrelocated_addr high = {}; enum pc_bounds_kind ret; attr_high = dwarf2_attr (die, DW_AT_high_pc, cu); @@ -11009,17 +11008,19 @@ dwarf2_get_pc_bounds (struct die_info *die, unrelocated_addr *lowpc, attr = dwarf2_attr (die, DW_AT_low_pc, cu); if (attr != nullptr) { - low = attr->as_address (); - high = attr_high->as_address (); + *low = attr->as_address (); + *high = attr_high->as_address (); if (cu->header.version >= 4 && attr_high->form_is_constant ()) - high = (unrelocated_addr) ((ULONGEST) high + (ULONGEST) low); + *high = (unrelocated_addr) ((ULONGEST) *high + (ULONGEST) *low); + + /* Found consecutive range of addresses. */ + ret = PC_BOUNDS_HIGH_LOW; } else - /* Found high w/o low attribute. */ - return PC_BOUNDS_INVALID; - - /* Found consecutive range of addresses. */ - ret = PC_BOUNDS_HIGH_LOW; + { + /* Found high w/o low attribute. */ + ret = PC_BOUNDS_INVALID; + } } else { @@ -11037,16 +11038,44 @@ dwarf2_get_pc_bounds (struct die_info *die, unrelocated_addr *lowpc, /* Value of the DW_AT_ranges attribute is the offset in the .debug_ranges section. */ - if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, + if (!dwarf2_ranges_read (ranges_offset, low, high, cu, map, datum, die->tag)) return PC_BOUNDS_INVALID; /* Found discontinuous range of addresses. */ ret = PC_BOUNDS_RANGES; } else - return PC_BOUNDS_NOT_PRESENT; + { + /* Could not find high_pc or ranges attributed and thus no bounds + pair. */ + ret = PC_BOUNDS_NOT_PRESENT; + } } + return ret; +} + +/* Get low and high pc attributes from a die. See enum pc_bounds_kind + definition for the return value. *LOWPC and *HIGHPC are set iff + neither PC_BOUNDS_NOT_PRESENT nor PC_BOUNDS_INVALID are returned. */ + +static enum pc_bounds_kind +dwarf2_get_pc_bounds (struct die_info *die, unrelocated_addr *lowpc, + unrelocated_addr *highpc, struct dwarf2_cu *cu, + addrmap *map, void *datum) +{ + dwarf2_per_objfile *per_objfile = cu->per_objfile; + + unrelocated_addr low = {}; + unrelocated_addr high = {}; + enum pc_bounds_kind ret; + + ret = dwarf_get_pc_bounds_ranges_or_highlow_pc (die, &low, &high, cu, map, + datum); + + if (ret == PC_BOUNDS_NOT_PRESENT || ret == PC_BOUNDS_INVALID) + return ret; + /* partial_die_info::read has also the strict LOW < HIGH requirement. */ if (high <= low) return PC_BOUNDS_INVALID; @@ -11064,7 +11093,7 @@ dwarf2_get_pc_bounds (struct die_info *die, unrelocated_addr *lowpc, return PC_BOUNDS_INVALID; *lowpc = low; - if (highpc) + if (highpc != nullptr) *highpc = high; return ret; } |