gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Sun, 4 May 2008 17:27:01 +0000 (17:27 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Sun, 4 May 2008 17:27:01 +0000 (17:27 +0000)
* Makefile.in: Update dependencies.
* dwarf2read.c: Include "addrmap.h"
(struct dwarf2_cu): New fields RANGES_OFFSET and HAS_RANGES_OFFSET.
(dwarf2_ranges_read): New prototype.
(dwarf2_build_psymtabs_hard): Initialize and prepare PSYMTABS_ADDRMAP.
Add discontiguous range to PSYMTABS_ADDRMAP by DWARF2_RANGES_READ on
HAS_RANGES_OFFSET, otherwise add there the contiguous range.
(dwarf2_ranges_read): New parameter RANGES_PST, update the function
comment for it.  Add the found ranges to RANGES_PST.  New variable
BASEADDR, initialize it the common way.
(dwarf2_get_pc_bounds): Update the caller for the new parameter.
(read_partial_die): `DW_AT_ranges' now only sets RANGES_OFFSET and
HAS_RANGES_OFFSET for the later processing.
* objfiles.h (struct objfile): New field PSYMTABS_ADDRMAP.
* symtab.c: Include "addrmap.h"
(find_pc_sect_psymtab): Support reading the field PSYMTABS_ADDRMAP.
Move the psymtab locator into ...
(find_pc_sect_psymtab_closer): ... a new function.

gdb/testsuite/
* gdb.dwarf2/dw2-ranges.S: Merge the secondary section with `.fini'.
* gdb.dwarf2/dw2-ranges.exp: Compile also `dw2-ranges2.S' and
`dw2-ranges3.S' and test also their MAIN2, FUNC2 and MAIN3 symbols.
* gdb.dwarf2/dw2-ranges2.S, gdb.dwarf2/dw2-ranges3.S: New files.

gdb/ChangeLog
gdb/Makefile.in
gdb/dwarf2read.c
gdb/objfiles.h
gdb/symtab.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.dwarf2/dw2-ranges.S
gdb/testsuite/gdb.dwarf2/dw2-ranges.exp
gdb/testsuite/gdb.dwarf2/dw2-ranges2.S [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/dw2-ranges3.S [new file with mode: 0644]

index 98b0aa8..98ce9b1 100644 (file)
@@ -6,6 +6,25 @@
        DW_AT_ENTRY_PC.  Set CU->HEADER.BASE_KNOWN and CU->HEADER.BASE_ADDRESS
        from these variables if it was still unset.
 
+       * Makefile.in: Update dependencies.
+       * dwarf2read.c: Include "addrmap.h"
+       (struct dwarf2_cu): New fields RANGES_OFFSET and HAS_RANGES_OFFSET.
+       (dwarf2_ranges_read): New prototype.
+       (dwarf2_build_psymtabs_hard): Initialize and prepare PSYMTABS_ADDRMAP.
+       Add discontiguous range to PSYMTABS_ADDRMAP by DWARF2_RANGES_READ on
+       HAS_RANGES_OFFSET, otherwise add there the contiguous range.
+       (dwarf2_ranges_read): New parameter RANGES_PST, update the function
+       comment for it.  Add the found ranges to RANGES_PST.  New variable
+       BASEADDR, initialize it the common way.
+       (dwarf2_get_pc_bounds): Update the caller for the new parameter.
+       (read_partial_die): `DW_AT_ranges' now only sets RANGES_OFFSET and
+       HAS_RANGES_OFFSET for the later processing.
+       * objfiles.h (struct objfile): New field PSYMTABS_ADDRMAP.
+       * symtab.c: Include "addrmap.h"
+       (find_pc_sect_psymtab): Support reading the field PSYMTABS_ADDRMAP.
+       Move the psymtab locator into ...
+       (find_pc_sect_psymtab_closer): ... a new function.
+
 2008-05-04  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * arch-utils.c (gdbarch_update_p): Use default values for
index 6bf3a55..576c68f 100644 (file)
@@ -2096,7 +2096,8 @@ dwarf2-frame.o: dwarf2-frame.c $(defs_h) $(dwarf2expr_h) $(elf_dwarf2_h) \
 dwarf2loc.o: dwarf2loc.c $(defs_h) $(ui_out_h) $(value_h) $(frame_h) \
        $(gdbcore_h) $(target_h) $(inferior_h) $(ax_h) $(ax_gdb_h) \
        $(regcache_h) $(objfiles_h) $(exceptions_h) $(elf_dwarf2_h) \
-       $(dwarf2expr_h) $(dwarf2loc_h) $(gdb_string_h) $(gdb_assert_h)
+       $(dwarf2expr_h) $(dwarf2loc_h) $(gdb_string_h) $(gdb_assert_h) \
+       $(addrmap_h)
 dwarf2read.o: dwarf2read.c $(defs_h) $(bfd_h) $(symtab_h) $(gdbtypes_h) \
        $(objfiles_h) $(elf_dwarf2_h) $(buildsym_h) $(demangle_h) \
        $(expression_h) $(filenames_h) $(macrotab_h) $(language_h) \
@@ -2915,7 +2916,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
        $(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \
        $(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \
        $(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \
-       $(solist_h) $(p_lang_h)
+       $(solist_h) $(p_lang_h) $(addrmap_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
        $(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
        $(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
index 952f3ae..67c4ef8 100644 (file)
@@ -45,6 +45,7 @@
 #include "hashtab.h"
 #include "command.h"
 #include "gdbcmd.h"
+#include "addrmap.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -303,6 +304,9 @@ struct dwarf2_cu
   /* Hash table holding all the loaded partial DIEs.  */
   htab_t partial_dies;
 
+  /* `.debug_ranges' offset for this `DW_TAG_compile_unit' DIE.  */
+  unsigned long ranges_offset;
+
   /* Storage for things with the same lifetime as this read-in compilation
      unit, including partial DIEs.  */
   struct obstack comp_unit_obstack;
@@ -345,6 +349,9 @@ struct dwarf2_cu
      DIEs for namespaces, we don't need to try to infer them
      from mangled names.  */
   unsigned int has_namespace_info : 1;
+
+  /* Field `ranges_offset' is filled in; flag as the value may be zero.  */
+  unsigned int has_ranges_offset : 1;
 };
 
 /* Persistent data held for a compilation unit, even when not
@@ -894,6 +901,9 @@ static void read_func_scope (struct die_info *, struct dwarf2_cu *);
 
 static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *);
 
+static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
+                              struct dwarf2_cu *, struct partial_symtab *);
+
 static int dwarf2_get_pc_bounds (struct die_info *,
                                 CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *);
 
@@ -1472,6 +1482,9 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
 
   create_all_comp_units (objfile);
 
+  objfile->psymtabs_addrmap = addrmap_create_mutable
+                                                   (&objfile->objfile_obstack);
+
   /* Since the objects we're extracting from .debug_info vary in
      length, only the individual functions to extract them (like
      read_comp_unit_head and load_partial_die) can really know whether
@@ -1537,7 +1550,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
       /* Allocate a new partial symbol table structure */
       pst = start_psymtab_common (objfile, objfile->section_offsets,
                                  comp_unit_die.name ? comp_unit_die.name : "",
-                                 comp_unit_die.lowpc,
+                                 /* TEXTLOW and TEXTHIGH are set below.  */
+                                 0,
                                  objfile->global_psymbols.next,
                                  objfile->static_psymbols.next);
 
@@ -1570,6 +1584,15 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
 
       this_cu->psymtab = pst;
 
+      /* Possibly set the default values of LOWPC and HIGHPC from
+         `DW_AT_ranges'.  */
+      if (cu.has_ranges_offset)
+       {
+         if (dwarf2_ranges_read (cu.ranges_offset, &comp_unit_die.lowpc,
+                                 &comp_unit_die.highpc, &cu, pst))
+           comp_unit_die.has_pc_info = 1;
+       }
+
       /* Check if comp unit has_children.
          If so, read the rest of the partial symbols from this comp unit.
          If not, there's no more debug_info for this comp unit. */
@@ -1600,6 +1623,12 @@ 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 -
@@ -1623,6 +1652,10 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
 
       do_cleanups (back_to_inner);
     }
+
+  objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
+                                                   &objfile->objfile_obstack);
+
   do_cleanups (back_to);
 }
 
@@ -3143,11 +3176,13 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 }
 
 /* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
-   Return 1 if the attributes are present and valid, otherwise, return 0.  */
+   Return 1 if the attributes are present and valid, otherwise, return 0.
+   If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'.  */
 
 static int
 dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
-                   CORE_ADDR *high_return, struct dwarf2_cu *cu)
+                   CORE_ADDR *high_return, struct dwarf2_cu *cu,
+                   struct partial_symtab *ranges_pst)
 {
   struct objfile *objfile = cu->objfile;
   struct comp_unit_head *cu_header = &cu->header;
@@ -3163,6 +3198,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
   int low_set;
   CORE_ADDR low = 0;
   CORE_ADDR high = 0;
+  CORE_ADDR baseaddr;
 
   found_base = cu_header->base_known;
   base = cu_header->base_address;
@@ -3190,6 +3226,9 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
 
   low_set = 0;
 
+  if (ranges_pst != NULL)
+    baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
   while (1)
     {
       CORE_ADDR range_beginning, range_end;
@@ -3229,6 +3268,11 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
       range_beginning += base;
       range_end += base;
 
+      if (ranges_pst != NULL && range_beginning < range_end)
+       addrmap_set_empty (objfile->psymtabs_addrmap,
+                          range_beginning + baseaddr, range_end - 1 + baseaddr,
+                          ranges_pst);
+
       /* FIXME: This is recording everything as a low-high
         segment of consecutive addresses.  We should have a
         data structure for discontiguous block ranges
@@ -3293,7 +3337,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
        {
          /* Value of the DW_AT_ranges attribute is the offset in the
             .debug_ranges section.  */
-         if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu))
+         if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, NULL))
            return 0;
          /* Found discontinuous range of addresses.  */
          ret = -1;
@@ -5880,9 +5924,11 @@ read_partial_die (struct partial_die_info *part_die,
            }
          break;
        case DW_AT_ranges:
-         if (dwarf2_ranges_read (DW_UNSND (&attr), &part_die->lowpc,
-                                 &part_die->highpc, cu))
-           has_low_pc_attr = has_high_pc_attr = 1;
+         if (part_die->tag == DW_TAG_compile_unit)
+           {
+             cu->ranges_offset = DW_UNSND (&attr);
+             cu->has_ranges_offset = 1;
+           }
          break;
        case DW_AT_location:
           /* Support the .debug_loc offsets */
index c3ae954..7e39b07 100644 (file)
@@ -220,6 +220,13 @@ struct objfile
 
     struct partial_symtab *psymtabs;
 
+    /* Map addresses to the entries of PSYMTABS.  It would be more efficient to
+       have a map per the whole process but ADDRMAP cannot selectively remove
+       its items during FREE_OBJFILE.  This mapping is already present even for
+       PARTIAL_SYMTABs which still have no corresponding full SYMTABs read.  */
+
+    struct addrmap *psymtabs_addrmap;
+
     /* List of freed partial symtabs, available for re-use */
 
     struct partial_symtab *free_psymtabs;
index 1c9425c..6c16b95 100644 (file)
@@ -41,6 +41,7 @@
 #include "objc-lang.h"
 #include "ada-lang.h"
 #include "p-lang.h"
+#include "addrmap.h"
 
 #include "hashtab.h"
 
@@ -767,6 +768,83 @@ matching_bfd_sections (asection *first, asection *second)
   return 0;
 }
 
+/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
+   We may find a different psymtab than PST.  See FIND_PC_SECT_PSYMTAB.  */
+
+struct partial_symtab *
+find_pc_sect_psymtab_closer (CORE_ADDR pc, asection *section,
+                            struct partial_symtab *pst,
+                            struct minimal_symbol *msymbol)
+{
+  struct objfile *objfile = pst->objfile;
+  struct partial_symtab *tpst;
+  struct partial_symtab *best_pst = pst;
+  CORE_ADDR best_addr = pst->textlow;
+
+  /* An objfile that has its functions reordered might have
+     many partial symbol tables containing the PC, but
+     we want the partial symbol table that contains the
+     function containing the PC.  */
+  if (!(objfile->flags & OBJF_REORDERED) &&
+      section == 0)    /* can't validate section this way */
+    return pst;
+
+  if (msymbol == NULL)
+    return (pst);
+
+  /* The code range of partial symtabs sometimes overlap, so, in
+     the loop below, we need to check all partial symtabs and
+     find the one that fits better for the given PC address. We
+     select the partial symtab that contains a symbol whose
+     address is closest to the PC address.  By closest we mean
+     that find_pc_sect_symbol returns the symbol with address
+     that is closest and still less than the given PC.  */
+  for (tpst = pst; tpst != NULL; tpst = tpst->next)
+    {
+      if (pc >= tpst->textlow && pc < tpst->texthigh)
+       {
+         struct partial_symbol *p;
+         CORE_ADDR this_addr;
+
+         /* NOTE: This assumes that every psymbol has a
+            corresponding msymbol, which is not necessarily
+            true; the debug info might be much richer than the
+            object's symbol table.  */
+         p = find_pc_sect_psymbol (tpst, pc, section);
+         if (p != NULL
+             && SYMBOL_VALUE_ADDRESS (p)
+             == SYMBOL_VALUE_ADDRESS (msymbol))
+           return tpst;
+
+         /* Also accept the textlow value of a psymtab as a
+            "symbol", to provide some support for partial
+            symbol tables with line information but no debug
+            symbols (e.g. those produced by an assembler).  */
+         if (p != NULL)
+           this_addr = SYMBOL_VALUE_ADDRESS (p);
+         else
+           this_addr = tpst->textlow;
+
+         /* Check whether it is closer than our current
+            BEST_ADDR.  Since this symbol address is
+            necessarily lower or equal to PC, the symbol closer
+            to PC is the symbol which address is the highest.
+            This way we return the psymtab which contains such
+            best match symbol. This can help in cases where the
+            symbol information/debuginfo is not complete, like
+            for instance on IRIX6 with gcc, where no debug info
+            is emitted for statics. (See also the nodebug.exp
+            testcase.) */
+         if (this_addr > best_addr)
+           {
+             best_addr = this_addr;
+             best_pst = tpst;
+           }
+       }
+    }
+  return best_pst;
+}
+
 /* Find which partial symtab contains PC and SECTION.  Return 0 if
    none.  We return the psymtab that contains a symbol whose address
    exactly matches PC, or, if we cannot find an exact match, the
@@ -774,7 +852,6 @@ matching_bfd_sections (asection *first, asection *second)
 struct partial_symtab *
 find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
 {
-  struct partial_symtab *pst;
   struct objfile *objfile;
   struct minimal_symbol *msymbol;
 
@@ -790,79 +867,53 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
          || msymbol->type == mst_file_bss))
     return NULL;
 
-  ALL_PSYMTABS (objfile, pst)
-  {
-    if (pc >= pst->textlow && pc < pst->texthigh)
+  /* Try just the PSYMTABS_ADDRMAP mapping first as it has better granularity
+     than the later used TEXTLOW/TEXTHIGH one.  */
+
+  ALL_OBJFILES (objfile)
+    if (objfile->psymtabs_addrmap != NULL)
       {
-       struct partial_symtab *tpst;
-       struct partial_symtab *best_pst = pst;
-       CORE_ADDR best_addr = pst->textlow;
-
-       /* An objfile that has its functions reordered might have
-          many partial symbol tables containing the PC, but
-          we want the partial symbol table that contains the
-          function containing the PC.  */
-       if (!(objfile->flags & OBJF_REORDERED) &&
-           section == 0)       /* can't validate section this way */
-         return (pst);
-
-       if (msymbol == NULL)
-         return (pst);
-
-       /* The code range of partial symtabs sometimes overlap, so, in
-          the loop below, we need to check all partial symtabs and
-          find the one that fits better for the given PC address. We
-          select the partial symtab that contains a symbol whose
-          address is closest to the PC address.  By closest we mean
-          that find_pc_sect_symbol returns the symbol with address
-          that is closest and still less than the given PC.  */
-       for (tpst = pst; tpst != NULL; tpst = tpst->next)
+       struct partial_symtab *pst;
+
+       pst = addrmap_find (objfile->psymtabs_addrmap, pc);
+       if (pst != NULL)
          {
-           if (pc >= tpst->textlow && pc < tpst->texthigh)
-             {
-               struct partial_symbol *p;
-               CORE_ADDR this_addr;
-
-               /* NOTE: This assumes that every psymbol has a
-                  corresponding msymbol, which is not necessarily
-                  true; the debug info might be much richer than the
-                  object's symbol table.  */
-               p = find_pc_sect_psymbol (tpst, pc, section);
-               if (p != NULL
-                   && SYMBOL_VALUE_ADDRESS (p)
-                   == SYMBOL_VALUE_ADDRESS (msymbol))
-                 return (tpst);
-
-               /* Also accept the textlow value of a psymtab as a
-                  "symbol", to provide some support for partial
-                  symbol tables with line information but no debug
-                  symbols (e.g. those produced by an assembler).  */
-               if (p != NULL)
-                 this_addr = SYMBOL_VALUE_ADDRESS (p);
-               else
-                 this_addr = tpst->textlow;
-
-               /* Check whether it is closer than our current
-                  BEST_ADDR.  Since this symbol address is
-                  necessarily lower or equal to PC, the symbol closer
-                  to PC is the symbol which address is the highest.
-                  This way we return the psymtab which contains such
-                  best match symbol. This can help in cases where the
-                  symbol information/debuginfo is not complete, like
-                  for instance on IRIX6 with gcc, where no debug info
-                  is emitted for statics. (See also the nodebug.exp
-                  testcase.) */
-               if (this_addr > best_addr)
-                 {
-                   best_addr = this_addr;
-                   best_pst = tpst;
-                 }
-             }
+           /* We do not try to call FIND_PC_SECT_PSYMTAB_CLOSER as
+              PSYMTABS_ADDRMAP we used has already the best 1-byte
+              granularity and FIND_PC_SECT_PSYMTAB_CLOSER may mislead us into
+              a worse chosen section due to the TEXTLOW/TEXTHIGH ranges
+              overlap.  */
+
+           return pst;
          }
-       return (best_pst);
       }
-  }
-  return (NULL);
+
+  /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
+     which still have no corresponding full SYMTABs read.  But it is not
+     present for non-DWARF2 debug infos not supporting PSYMTABS_ADDRMAP in GDB
+     so far.  */
+
+  ALL_OBJFILES (objfile)
+    {
+      struct partial_symtab *pst;
+
+      /* Check even OBJFILE with non-zero PSYMTABS_ADDRMAP as only several of
+        its CUs may be missing in PSYMTABS_ADDRMAP as they may be varying
+        debug info type in single OBJFILE.  */
+
+      ALL_OBJFILE_PSYMTABS (objfile, pst)
+       if (pc >= pst->textlow && pc < pst->texthigh)
+         {
+           struct partial_symtab *best_pst;
+
+           best_pst = find_pc_sect_psymtab_closer (pc, section, pst,
+                                                   msymbol);
+           if (best_pst != NULL)
+             return best_pst;
+         }
+    }
+
+  return NULL;
 }
 
 /* Find which partial symtab contains PC.  Return 0 if none. 
index 1e9b3ec..7071545 100644 (file)
@@ -1,3 +1,10 @@
+2008-05-04  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * gdb.dwarf2/dw2-ranges.S: Merge the secondary section with `.fini'.
+       * gdb.dwarf2/dw2-ranges.exp: Compile also `dw2-ranges2.S' and
+       `dw2-ranges3.S' and test also their MAIN2, FUNC2 and MAIN3 symbols.
+       * gdb.dwarf2/dw2-ranges2.S, gdb.dwarf2/dw2-ranges3.S: New files.
+
 2008-05-04  Vladimir Prus  <vladimir@codesourcery.com>
 
        * lib/mi-support.exp (mi_run_cmd): Allow for =thread-created
index 1334c0c..ac450f7 100644 (file)
@@ -35,7 +35,10 @@ main:        .int    0
        .endfunc
        .size   main, . - main
 
-       .section        .text.func, "ax", @progbits
+       /* `.fini' section is here to make sure `dw2-ranges.S'
+          vs. `dw2-ranges2.S' overlap their DW_AT_ranges with each other.  */
+       .section        .fini, "ax", @progbits
+
        .globl  func
        .func   func
 func:  .int    0
index 0009d82..a3ace15 100644 (file)
@@ -30,9 +30,23 @@ if {![istarget *-*-linux*]
 
 set testfile "dw2-ranges"
 set srcfile ${testfile}.S
-set binfile ${objdir}/${subdir}/${testfile}.o
+set srcfile2 ${testfile}2.S
+set srcfile3 ${testfile}3.S
+set objfile ${objdir}/${subdir}/${testfile}.o
+set objfile2 ${objdir}/${subdir}/${testfile}2.o
+set objfile3 ${objdir}/${subdir}/${testfile}3.o
+set binfile ${objdir}/${subdir}/${testfile}
 
-if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object debug] != "" } {
+if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {additional_flags=-gdwarf-2}] != "" } {
+    return -1
+}
+if {[gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${objfile2}" object {additional_flags=-gdwarf-2}] != "" } {
+    return -1
+}
+if {[gdb_compile "${srcdir}/${subdir}/${srcfile3}" "${objfile3}" object {additional_flags=-gstabs}] != "" } {
+    return -1
+}
+if {[gdb_compile "${objfile} ${objfile2} ${objfile3}" "${binfile}" executable {}] != "" } {
     return -1
 }
 
@@ -46,4 +60,8 @@ gdb_load ${binfile}
 # Wrong output:
 #      No line number information available for address 0x4
 
+gdb_test "info line main" "Line \[0-9\]* of .* starts at address .* and ends at .*"
 gdb_test "info line func" "Line \[0-9\]* of .* starts at address .* and ends at .*"
+gdb_test "info line main2" "Line \[0-9\]* of .* starts at address .* and ends at .*"
+gdb_test "info line func2" "Line \[0-9\]* of .* starts at address .* and ends at .*"
+gdb_test "info line main3" "Line \[0-9\]* of .* starts at address .* and ends at .*"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges2.S b/gdb/testsuite/gdb.dwarf2/dw2-ranges2.S
new file mode 100644 (file)
index 0000000..cf06f02
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+   Copyright 2007 Free Software Foundation, Inc.
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Despite the sections below will be adjacent the assembler has to produce
+   DW_AT_ranges as the linker could place both sections at arbitrary locations.
+   */
+
+       /* Such directive is required by GAS for builds without `-g'.  */
+       .file   1 "dw2-ranges2.S"
+
+       /* Without this directive GAS will not emit DWARF2 unless we provide an
+          instruction to assemble.  We want to avoid any instructions to
+          remain architecture independent.  */
+       .loc_mark_labels        1
+
+       .text
+
+       .globl  main2
+       .func   main2
+main2: .int    0
+       .endfunc
+       .size   main2, . - main2
+
+       /* `.fini' section is here to make sure `dw2-ranges.S'
+          vs. `dw2-ranges2.S' overlap their DW_AT_ranges with each other.  */
+       .section        .fini, "ax", @progbits
+
+       .globl  func2
+       .func   func2
+func2: .int    0
+       .endfunc
+       .size   func2, . - func2
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges3.S b/gdb/testsuite/gdb.dwarf2/dw2-ranges3.S
new file mode 100644 (file)
index 0000000..8e2c948
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+   Copyright 2007, 2008 Free Software Foundation, Inc.
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Despite the sections below will be adjacent the assembler has to produce
+   DW_AT_ranges as the linker could place both sections at arbitrary locations.
+   */
+
+       /* Such directive is required by GAS for builds without `-g'.  */
+       .file   1 "dw2-ranges3.S"
+
+       /* Without this directive GAS will not emit DWARF2 unless we provide an
+          instruction to assemble.  We want to avoid any instructions to
+          remain architecture independent.  */
+       .loc_mark_labels        1
+
+       .text
+
+       .globl  main3
+       .func   main3
+main3: .int    0
+       .endfunc
+       .size   main3, . - main3