libbacktrace: gather address ranges from skeleton units
authorIan Lance Taylor <iant@golang.org>
Thu, 17 Feb 2022 04:18:45 +0000 (20:18 -0800)
committerIan Lance Taylor <iant@golang.org>
Thu, 17 Feb 2022 04:21:48 +0000 (20:21 -0800)
* dwarf.c (find_address_ranges): Handle skeleton units.
(read_function_entry): Likewise.

libbacktrace/dwarf.c

index 2158bc1..45cc9e7 100644 (file)
@@ -1989,14 +1989,16 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
              break;
 
            case DW_AT_stmt_list:
-             if (abbrev->tag == DW_TAG_compile_unit
+             if ((abbrev->tag == DW_TAG_compile_unit
+                  || abbrev->tag == DW_TAG_skeleton_unit)
                  && (val.encoding == ATTR_VAL_UINT
                      || val.encoding == ATTR_VAL_REF_SECTION))
                u->lineoff = val.u.uint;
              break;
 
            case DW_AT_name:
-             if (abbrev->tag == DW_TAG_compile_unit)
+             if (abbrev->tag == DW_TAG_compile_unit
+                 || abbrev->tag == DW_TAG_skeleton_unit)
                {
                  name_val = val;
                  have_name_val = 1;
@@ -2004,7 +2006,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
              break;
 
            case DW_AT_comp_dir:
-             if (abbrev->tag == DW_TAG_compile_unit)
+             if (abbrev->tag == DW_TAG_compile_unit
+                 || abbrev->tag == DW_TAG_skeleton_unit)
                {
                  comp_dir_val = val;
                  have_comp_dir_val = 1;
@@ -2012,19 +2015,22 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
              break;
 
            case DW_AT_str_offsets_base:
-             if (abbrev->tag == DW_TAG_compile_unit
+             if ((abbrev->tag == DW_TAG_compile_unit
+                  || abbrev->tag == DW_TAG_skeleton_unit)
                  && val.encoding == ATTR_VAL_REF_SECTION)
                u->str_offsets_base = val.u.uint;
              break;
 
            case DW_AT_addr_base:
-             if (abbrev->tag == DW_TAG_compile_unit
+             if ((abbrev->tag == DW_TAG_compile_unit
+                  || abbrev->tag == DW_TAG_skeleton_unit)
                  && val.encoding == ATTR_VAL_REF_SECTION)
                u->addr_base = val.u.uint;
              break;
 
            case DW_AT_rnglists_base:
-             if (abbrev->tag == DW_TAG_compile_unit
+             if ((abbrev->tag == DW_TAG_compile_unit
+                  || abbrev->tag == DW_TAG_skeleton_unit)
                  && val.encoding == ATTR_VAL_REF_SECTION)
                u->rnglists_base = val.u.uint;
              break;
@@ -2052,7 +2058,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
        }
 
       if (abbrev->tag == DW_TAG_compile_unit
-         || abbrev->tag == DW_TAG_subprogram)
+         || abbrev->tag == DW_TAG_subprogram
+         || abbrev->tag == DW_TAG_skeleton_unit)
        {
          if (!add_ranges (state, dwarf_sections, base_address,
                           is_bigendian, u, pcrange.lowpc, &pcrange,
@@ -2060,9 +2067,10 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
                           (void *) addrs))
            return 0;
 
-         /* If we found the PC range in the DW_TAG_compile_unit, we
-            can stop now.  */
-         if (abbrev->tag == DW_TAG_compile_unit
+         /* If we found the PC range in the DW_TAG_compile_unit or
+            DW_TAG_skeleton_unit, we can stop now.  */
+         if ((abbrev->tag == DW_TAG_compile_unit
+              || abbrev->tag == DW_TAG_skeleton_unit)
              && (pcrange.have_ranges
                  || (pcrange.have_lowpc && pcrange.have_highpc)))
            return 1;
@@ -3274,7 +3282,8 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
 
          /* The compile unit sets the base address for any address
             ranges in the function entries.  */
-         if (abbrev->tag == DW_TAG_compile_unit
+         if ((abbrev->tag == DW_TAG_compile_unit
+              || abbrev->tag == DW_TAG_skeleton_unit)
              && abbrev->attrs[i].name == DW_AT_low_pc)
            {
              if (val.encoding == ATTR_VAL_ADDRESS)