* 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.
This commit is contained in:
Jan Kratochvil 2010-07-30 16:04:30 +00:00
parent 420697bb59
commit 1276c7599c
6 changed files with 69 additions and 8 deletions

View 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.

View 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));

View 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

View 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))
{

View File

@ -18,6 +18,11 @@
#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);
}

View 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"