* dwarf2read.c (dwarf2_build_psymtabs_hard): Move lowpc and highpc
authorDaniel Jacobowitz <drow@false.org>
Mon, 9 Feb 2009 00:07:53 +0000 (00:07 +0000)
committerDaniel Jacobowitz <drow@false.org>
Mon, 9 Feb 2009 00:07:53 +0000 (00:07 +0000)
inside the loop.  Only call addrmap_set_empty if the compilation unit
had DW_AT_high_pc and DW_AT_low_pc.  Update call to
scan_partial_symbols.
(scan_partial_symbols): Take NEED_PC argument and pass it along with
LOWPC and HIGHPC.
(add_partial_namespace): Take NEED_PC argument and pass it through.
(add_partial_subprogram): Take NEED_PC argument.  Update the addrmap
if necessary.

gdb/dwarf2read.c

index 4f2f7fb3f9e74bb7984c6f85b3bc89506c73c96e..925cfd028158771a2ebaffa344e10f0abdb0c971 100644 (file)
@@ -763,7 +763,7 @@ static void dwarf2_build_psymtabs_hard (struct objfile *, int);
 
 static void scan_partial_symbols (struct partial_die_info *,
                                  CORE_ADDR *, CORE_ADDR *,
-                                 struct dwarf2_cu *);
+                                 int, struct dwarf2_cu *);
 
 static void add_partial_symbol (struct partial_die_info *,
                                struct dwarf2_cu *);
@@ -772,14 +772,14 @@ static int pdi_needs_namespace (enum dwarf_tag tag);
 
 static void add_partial_namespace (struct partial_die_info *pdi,
                                   CORE_ADDR *lowpc, CORE_ADDR *highpc,
-                                  struct dwarf2_cu *cu);
+                                  int need_pc, struct dwarf2_cu *cu);
 
 static void add_partial_enumeration (struct partial_die_info *enum_pdi,
                                     struct dwarf2_cu *cu);
 
 static void add_partial_subprogram (struct partial_die_info *pdi,
                                    CORE_ADDR *lowpc, CORE_ADDR *highpc,
-                                   struct dwarf2_cu *cu);
+                                   int need_pc, struct dwarf2_cu *cu);
 
 static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi,
                                      gdb_byte *info_ptr,
@@ -1486,7 +1486,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
   struct partial_die_info comp_unit_die;
   struct partial_symtab *pst;
   struct cleanup *back_to;
-  CORE_ADDR lowpc, highpc, baseaddr;
+  CORE_ADDR baseaddr;
 
   info_ptr = dwarf2_per_objfile->info_buffer;
 
@@ -1607,6 +1607,13 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
                                  &comp_unit_die.highpc, &cu, pst))
            comp_unit_die.has_pc_info = 1;
        }
+      else if (comp_unit_die.has_pc_info
+              && comp_unit_die.lowpc < comp_unit_die.highpc)
+       /* Store the contiguous range if it is not empty; it can be empty for
+          CUs with no code.  */
+       addrmap_set_empty (objfile->psymtabs_addrmap,
+                          comp_unit_die.lowpc + baseaddr,
+                          comp_unit_die.highpc + baseaddr - 1, pst);
 
       /* Check if comp unit has_children.
          If so, read the rest of the partial symbols from this comp unit.
@@ -1614,13 +1621,15 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
       if (comp_unit_die.has_children)
        {
          struct partial_die_info *first_die;
+         CORE_ADDR lowpc, highpc;
 
          lowpc = ((CORE_ADDR) -1);
          highpc = ((CORE_ADDR) 0);
 
          first_die = load_partial_dies (abfd, info_ptr, 1, &cu);
 
-         scan_partial_symbols (first_die, &lowpc, &highpc, &cu);
+         scan_partial_symbols (first_die, &lowpc, &highpc,
+                               ! comp_unit_die.has_pc_info, &cu);
 
          /* If we didn't find a lowpc, set it to highpc to avoid
             complaints from `maint check'.  */
@@ -1638,12 +1647,6 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
       pst->textlow = comp_unit_die.lowpc + baseaddr;
       pst->texthigh = comp_unit_die.highpc + baseaddr;
 
-      /* Store the contiguous range; `DW_AT_ranges' range is stored above.  The
-         range can be also empty for CUs with no code.  */
-      if (!cu.has_ranges_offset && pst->textlow < pst->texthigh)
-       addrmap_set_empty (objfile->psymtabs_addrmap, pst->textlow,
-                          pst->texthigh - 1, pst);
-
       pst->n_global_syms = objfile->global_psymbols.next -
        (objfile->global_psymbols.list + pst->globals_offset);
       pst->n_static_syms = objfile->static_psymbols.next -
@@ -1788,13 +1791,16 @@ create_all_comp_units (struct objfile *objfile)
   dwarf2_per_objfile->n_comp_units = n_comp_units;
 }
 
-/* Process all loaded DIEs for compilation unit CU, starting at FIRST_DIE.
-   Also set *LOWPC and *HIGHPC to the lowest and highest PC values found
-   in CU.  */
+/* Process all loaded DIEs for compilation unit CU, starting at
+   FIRST_DIE.  The caller should pass NEED_PC == 1 if the compilation
+   unit DIE did not have PC info (DW_AT_low_pc and DW_AT_high_pc, or
+   DW_AT_ranges).  If NEED_PC is set, then this function will set
+   *LOWPC and *HIGHPC to the lowest and highest PC values found in CU
+   and record the covered ranges in the addrmap.  */
 
 static void
 scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
-                     CORE_ADDR *highpc, struct dwarf2_cu *cu)
+                     CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
   bfd *abfd = objfile->obfd;
@@ -1820,7 +1826,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
          switch (pdi->tag)
            {
            case DW_TAG_subprogram:
-             add_partial_subprogram (pdi, lowpc, highpc, cu);
+             add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu);
              break;
            case DW_TAG_variable:
            case DW_TAG_typedef:
@@ -1849,7 +1855,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
              add_partial_symbol (pdi, cu);
              break;
            case DW_TAG_namespace:
-             add_partial_namespace (pdi, lowpc, highpc, cu);
+             add_partial_namespace (pdi, lowpc, highpc, need_pc, cu);
              break;
            default:
              break;
@@ -2156,7 +2162,7 @@ pdi_needs_namespace (enum dwarf_tag tag)
 static void
 add_partial_namespace (struct partial_die_info *pdi,
                       CORE_ADDR *lowpc, CORE_ADDR *highpc,
-                      struct dwarf2_cu *cu)
+                      int need_pc, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
 
@@ -2167,7 +2173,7 @@ add_partial_namespace (struct partial_die_info *pdi,
   /* Now scan partial symbols in that namespace.  */
 
   if (pdi->has_children)
-    scan_partial_symbols (pdi->die_child, lowpc, highpc, cu);
+    scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu);
 }
 
 /* Read a partial die corresponding to a subprogram and create a partial
@@ -2183,7 +2189,7 @@ add_partial_namespace (struct partial_die_info *pdi,
 static void
 add_partial_subprogram (struct partial_die_info *pdi,
                        CORE_ADDR *lowpc, CORE_ADDR *highpc,
-                       struct dwarf2_cu *cu)
+                       int need_pc, struct dwarf2_cu *cu)
 {
   if (pdi->tag == DW_TAG_subprogram)
     {
@@ -2193,6 +2199,17 @@ add_partial_subprogram (struct partial_die_info *pdi,
             *lowpc = pdi->lowpc;
           if (pdi->highpc > *highpc)
             *highpc = pdi->highpc;
+         if (need_pc)
+           {
+             CORE_ADDR baseaddr;
+             struct objfile *objfile = cu->objfile;
+
+             baseaddr = ANOFFSET (objfile->section_offsets,
+                                  SECT_OFF_TEXT (objfile));
+             addrmap_set_empty (objfile->psymtabs_addrmap,
+                                pdi->lowpc, pdi->highpc - 1,
+                                cu->per_cu->psymtab);
+           }
           if (!pdi->is_declaration)
             add_partial_symbol (pdi, cu);
         }
@@ -2209,7 +2226,7 @@ add_partial_subprogram (struct partial_die_info *pdi,
          fixup_partial_die (pdi, cu);
          if (pdi->tag == DW_TAG_subprogram
              || pdi->tag == DW_TAG_lexical_block)
-           add_partial_subprogram (pdi, lowpc, highpc, cu);
+           add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu);
          pdi = pdi->die_sibling;
        }
     }