gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 30 Jul 2010 16:04:30 +0000 (16:04 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 30 Jul 2010 16:04:30 +0000 (16:04 +0000)
* symfile.c (addr_section_name): New function.
(addrs_section_compar): Use it.
(addr_info_make_relative): Use it.  Move variable sect_name into a more
inner block.  Make ".dynbss" and ".sdynbss" checks more strict.

gdb/testsuite/
* gdb.base/prelink-lib.c (copyreloc): New initialized variable.
* gdb.base/prelink.c (copyreloc, bssvar, bssvarp): New variables.
(main): Use copyreloc.
* gdb.base/prelink.exp (split debug of executable)
(.dynbss vs. .bss address shift): New tests.

gdb/ChangeLog
gdb/symfile.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/prelink-lib.c
gdb/testsuite/gdb.base/prelink.c
gdb/testsuite/gdb.base/prelink.exp

index 2c2ab51b722805287e6494e834db1c7e7df6e735..e436f0b37e45eddc96edf9f1d28a06bdd8e24614 100644 (file)
@@ -1,3 +1,10 @@
+2010-07-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * symfile.c (addr_section_name): New function.
+       (addrs_section_compar): Use it.
+       (addr_info_make_relative): Use it.  Move variable sect_name into a more
+       inner block.  Make ".dynbss" and ".sdynbss" checks more strict.
+
 2010-07-30  Tom Tromey  <tromey@redhat.com>
 
        * configure: Rebuild.
index d8af3627a33cd77f409db85c354e5a5162e25d6c..2cb6b7f2fcbd67777c16840df85a380011d28d88 100644 (file)
@@ -547,6 +547,23 @@ relative_addr_info_to_section_offsets (struct section_offsets *section_offsets,
     }
 }
 
+/* Transform section name S for a name comparison.  prelink can split section
+   `.bss' into two sections `.dynbss' and `.bss' (in this order).  Similarly
+   prelink can split `.sbss' into `.sdynbss' and `.sbss'.  Use virtual address
+   of the new `.dynbss' (`.sdynbss') section as the adjacent new `.bss'
+   (`.sbss') section has invalid (increased) virtual address.  */
+
+static const char *
+addr_section_name (const char *s)
+{
+  if (strcmp (s, ".dynbss") == 0)
+    return ".bss";
+  if (strcmp (s, ".sdynbss") == 0)
+    return ".sbss";
+
+  return s;
+}
+
 /* qsort comparator for addrs_section_sort.  Sort entries in ascending order by
    their (name, sectindex) pair.  sectindex makes the sort by name stable.  */
 
@@ -557,7 +574,7 @@ addrs_section_compar (const void *ap, const void *bp)
   const struct other_sections *b = *((struct other_sections **) bp);
   int retval, a_idx, b_idx;
 
-  retval = strcmp (a->name, b->name);
+  retval = strcmp (addr_section_name (a->name), addr_section_name (b->name));
   if (retval)
     return retval;
 
@@ -641,14 +658,16 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
 
   while (*addrs_sorted)
     {
-      const char *sect_name = (*addrs_sorted)->name;
+      const char *sect_name = addr_section_name ((*addrs_sorted)->name);
 
       while (*abfd_addrs_sorted
-            && strcmp ((*abfd_addrs_sorted)->name, sect_name) < 0)
+            && strcmp (addr_section_name ((*abfd_addrs_sorted)->name),
+                       sect_name) < 0)
        abfd_addrs_sorted++;
 
       if (*abfd_addrs_sorted
-         && strcmp ((*abfd_addrs_sorted)->name, sect_name) == 0)
+         && strcmp (addr_section_name ((*abfd_addrs_sorted)->name),
+                    sect_name) == 0)
        {
          int index_in_addrs;
 
@@ -676,7 +695,6 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
 
   for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
     {
-      const char *sect_name = addrs->other[i].name;
       struct other_sections *sect = addrs_to_abfd_addrs[i];
 
       if (sect)
@@ -694,6 +712,9 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
        }
       else
        {
+         /* addr_section_name transformation is not used for SECT_NAME.  */
+         const char *sect_name = addrs->other[i].name;
+
          /* This section does not exist in ABFD, which is normally
             unexpected and we want to issue a warning.
 
@@ -704,12 +725,20 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
             a warning.  Shared libraries contain just the section
             ".gnu.liblist" but it is not marked as loadable there.  There is
             no other way to identify them than by their name as the sections
-            created by prelink have no special flags.  */
+            created by prelink have no special flags.
+
+            For the sections `.bss' and `.sbss' see addr_section_name.  */
 
          if (!(strcmp (sect_name, ".gnu.liblist") == 0
                || strcmp (sect_name, ".gnu.conflict") == 0
-               || strcmp (sect_name, ".dynbss") == 0
-               || strcmp (sect_name, ".sdynbss") == 0))
+               || (strcmp (sect_name, ".bss") == 0
+                   && i > 0
+                   && strcmp (addrs->other[i - 1].name, ".dynbss") == 0
+                   && addrs_to_abfd_addrs[i - 1] != NULL)
+               || (strcmp (sect_name, ".sbss") == 0
+                   && i > 0
+                   && strcmp (addrs->other[i - 1].name, ".sdynbss") == 0
+                   && addrs_to_abfd_addrs[i - 1] != NULL)))
            warning (_("section %s not found in %s"), sect_name,
                     bfd_get_filename (abfd));
 
index 275f2fd68bcd2a6e792adcd4cfa8f2ff4417625c..f364dea78e55cc227c9ca1df3614d8e21e544d53 100644 (file)
@@ -1,3 +1,11 @@
+2010-07-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * gdb.base/prelink-lib.c (copyreloc): New initialized variable.
+       * gdb.base/prelink.c (copyreloc, bssvar, bssvarp): New variables.
+       (main): Use copyreloc.
+       * gdb.base/prelink.exp (split debug of executable)
+       (.dynbss vs. .bss address shift): New tests.
+
 2010-07-29  Pedro Alves  <pedro@codesourcery.com>
 
        * gdb.threads/pthreads.exp (check_backtraces): Consume $gdb_prompt
index a28d72442117e4edd87b43ca631aa9cbe6231d0e..c8f7c10033f79bbd483a07a1774605ce4c1192f1 100644 (file)
@@ -16,6 +16,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+int copyreloc = 1;
+
 int
 g (void (*p)(void))
 {
index 115dc1fabc16b53b92dbd823d1fc7e9e7f0c34bd..96c1bb960a8f69663edce1343f840a02bb17723d 100644 (file)
 
 #include <stdio.h>
 
+extern int copyreloc;
+
+/* Test GDB itself finds `&bssvar' right.   */
+static int bssvar, *bssvarp = &bssvar;
+
 extern void (*h (void)) (void (*)(void));
 
 int
@@ -25,5 +30,6 @@ main (void)
 {
   void (*f) (void (*)(void)) = h ();
   printf ("%p\n", f);
+  printf ("%d\n", copyreloc);
   f (0);
 }
index 8931c9f2c44bb0d2b0614a84cb21ae9361cba176..fe88d257069529e8a296821d208a9a4f352ea610 100644 (file)
@@ -57,6 +57,13 @@ if {$prelink_args == ""} {
     return -1
 }
 
+set test "split debug of executable"
+if [gdb_gnu_strip_debug $binfile] {
+    fail $test
+} else {
+    pass $test
+}
+
 if ![prelink_yes $prelink_args] {
     # Maybe we don't have prelink.
     return -1
@@ -105,3 +112,5 @@ clean_restart $executable
 gdb_test_no_output "set verbose on"
 
 gdb_test "core-file $objdir/$subdir/prelink.core" "Using PIC \\(Position Independent Code\\) prelink displacement 0x\[^0\]\[0-9a-f\]* for \[^\r\n\]*[file tail ${libfile}].*" "seen displacement message"
+
+gdb_test "p &bssvar == bssvarp" " = 1" ".dynbss vs. .bss address shift"