mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-04 04:08:50 +08:00
gdb/ChangeLog:
* solib-svr4.h (struct link_map_offsets): Add l_ld_offset and l_ld_size fields. * solib-svr4.c (struct lm_info): Add l_addr field. (LM_ADDR_FROM_LINK_MAP): Renamed from LM_ADDR. (HAS_LM_DYNAMIC_FROM_LINK_MAP): New. (LM_DYNAMIC_FROM_LINK_MAP): New. (LM_ADDR_CHECK): New. Use it instead of LM_ADDR. (svr4_current_sos): Initialize l_addr. Adjust. (svr4_relocate_section_addresses): Adjust. (svr4_ilp32_fetch_link_map_offsets): Define new members. (svr4_lp64_fetch_link_map_offsets): Likewise. * solib-legacy.c (legacy_svr4_fetch_link_map_offsets): Likewise. * mipsnbsd-tdep.c (mipsnbsd_ilp32_fetch_link_map_offsets): Likewise. (mipsnbsd_lp64_fetch_link_map_offsets): Likewise. * Makefile.in (solib-svr4.o): Depend on $(elf_bfd_h). gdb/testsuite/ChangeLog: * gdb.base/prelink.exp: New test. * gdb.base/prelink.c, gdb.base/prelink-lib.c: New sources.
This commit is contained in:
@ -1,3 +1,21 @@
|
|||||||
|
2006-02-28 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
|
* solib-svr4.h (struct link_map_offsets): Add l_ld_offset and
|
||||||
|
l_ld_size fields.
|
||||||
|
* solib-svr4.c (struct lm_info): Add l_addr field.
|
||||||
|
(LM_ADDR_FROM_LINK_MAP): Renamed from LM_ADDR.
|
||||||
|
(HAS_LM_DYNAMIC_FROM_LINK_MAP): New.
|
||||||
|
(LM_DYNAMIC_FROM_LINK_MAP): New.
|
||||||
|
(LM_ADDR_CHECK): New. Use it instead of LM_ADDR.
|
||||||
|
(svr4_current_sos): Initialize l_addr. Adjust.
|
||||||
|
(svr4_relocate_section_addresses): Adjust.
|
||||||
|
(svr4_ilp32_fetch_link_map_offsets): Define new members.
|
||||||
|
(svr4_lp64_fetch_link_map_offsets): Likewise.
|
||||||
|
* solib-legacy.c (legacy_svr4_fetch_link_map_offsets): Likewise.
|
||||||
|
* mipsnbsd-tdep.c (mipsnbsd_ilp32_fetch_link_map_offsets): Likewise.
|
||||||
|
(mipsnbsd_lp64_fetch_link_map_offsets): Likewise.
|
||||||
|
* Makefile.in (solib-svr4.o): Depend on $(elf_bfd_h).
|
||||||
|
|
||||||
2006-02-26 David S. Miller <davem@sunset.davemloft.net>
|
2006-02-26 David S. Miller <davem@sunset.davemloft.net>
|
||||||
|
|
||||||
* config/sparc/linux.mt (TDEPFILES): Add sol2-tdep.o.
|
* config/sparc/linux.mt (TDEPFILES): Add sol2-tdep.o.
|
||||||
|
@ -2582,7 +2582,8 @@ solib-sunos.o: solib-sunos.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) \
|
|||||||
solib-svr4.o: solib-svr4.c $(defs_h) $(elf_external_h) $(elf_common_h) \
|
solib-svr4.o: solib-svr4.c $(defs_h) $(elf_external_h) $(elf_common_h) \
|
||||||
$(elf_mips_h) $(symtab_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
|
$(elf_mips_h) $(symtab_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
|
||||||
$(gdbcore_h) $(target_h) $(inferior_h) $(gdb_assert_h) \
|
$(gdbcore_h) $(target_h) $(inferior_h) $(gdb_assert_h) \
|
||||||
$(solist_h) $(solib_h) $(solib_svr4_h) $(bfd_target_h) $(exec_h)
|
$(solist_h) $(solib_h) $(solib_svr4_h) $(bfd_target_h) $(elf_bfd_h) \
|
||||||
|
$(exec_h)
|
||||||
sol-thread.o: sol-thread.c $(defs_h) $(gdbthread_h) $(target_h) \
|
sol-thread.o: sol-thread.c $(defs_h) $(gdbthread_h) $(target_h) \
|
||||||
$(inferior_h) $(gdb_stat_h) $(gdbcmd_h) $(gdbcore_h) $(regcache_h) \
|
$(inferior_h) $(gdb_stat_h) $(gdbcmd_h) $(gdbcore_h) $(regcache_h) \
|
||||||
$(solib_h) $(symfile_h) $(gdb_string_h) $(gregset_h)
|
$(solib_h) $(symfile_h) $(gdb_string_h) $(gregset_h)
|
||||||
|
@ -339,6 +339,8 @@ mipsnbsd_ilp32_fetch_link_map_offsets (void)
|
|||||||
lmo.l_addr_size = 4;
|
lmo.l_addr_size = 4;
|
||||||
lmo.l_name_offset = 8;
|
lmo.l_name_offset = 8;
|
||||||
lmo.l_name_size = 4;
|
lmo.l_name_size = 4;
|
||||||
|
lmo.l_ld_offset = 12;
|
||||||
|
lmo.l_ld_size = 4;
|
||||||
lmo.l_next_offset = 16;
|
lmo.l_next_offset = 16;
|
||||||
lmo.l_next_size = 4;
|
lmo.l_next_size = 4;
|
||||||
lmo.l_prev_offset = 20;
|
lmo.l_prev_offset = 20;
|
||||||
@ -369,6 +371,8 @@ mipsnbsd_lp64_fetch_link_map_offsets (void)
|
|||||||
lmo.l_addr_size = 8;
|
lmo.l_addr_size = 8;
|
||||||
lmo.l_name_offset = 16;
|
lmo.l_name_offset = 16;
|
||||||
lmo.l_name_size = 8;
|
lmo.l_name_size = 8;
|
||||||
|
lmo.l_ld_offset = 24;
|
||||||
|
lmo.l_ld_size = 8;
|
||||||
lmo.l_next_offset = 32;
|
lmo.l_next_offset = 32;
|
||||||
lmo.l_next_size = 8;
|
lmo.l_next_size = 8;
|
||||||
lmo.l_prev_offset = 40;
|
lmo.l_prev_offset = 40;
|
||||||
|
@ -69,6 +69,9 @@ legacy_svr4_fetch_link_map_offsets (void)
|
|||||||
lmo.l_next_offset = offsetof (struct link_map, l_next);
|
lmo.l_next_offset = offsetof (struct link_map, l_next);
|
||||||
lmo.l_next_size = fieldsize (struct link_map, l_next);
|
lmo.l_next_size = fieldsize (struct link_map, l_next);
|
||||||
|
|
||||||
|
lmo.l_ld_offset = offsetof (struct link_map, l_ld);
|
||||||
|
lmo.l_ld_size = fieldsize (struct link_map, l_ld);
|
||||||
|
|
||||||
lmo.l_prev_offset = offsetof (struct link_map, l_prev);
|
lmo.l_prev_offset = offsetof (struct link_map, l_prev);
|
||||||
lmo.l_prev_size = fieldsize (struct link_map, l_prev);
|
lmo.l_prev_size = fieldsize (struct link_map, l_prev);
|
||||||
|
|
||||||
@ -84,6 +87,10 @@ legacy_svr4_fetch_link_map_offsets (void)
|
|||||||
lmo.l_next_offset = offsetof (struct link_map, lm_next);
|
lmo.l_next_offset = offsetof (struct link_map, lm_next);
|
||||||
lmo.l_next_size = fieldsize (struct link_map, lm_next);
|
lmo.l_next_size = fieldsize (struct link_map, lm_next);
|
||||||
|
|
||||||
|
/* FIXME: Is this the right field name, or is it available at all? */
|
||||||
|
lmo.l_ld_offset = offsetof (struct link_map, lm_ld);
|
||||||
|
lmo.l_ld_size = fieldsize (struct link_map, lm_ld);
|
||||||
|
|
||||||
lmo.l_name_offset = offsetof (struct link_map, lm_name);
|
lmo.l_name_offset = offsetof (struct link_map, lm_name);
|
||||||
lmo.l_name_size = fieldsize (struct link_map, lm_name);
|
lmo.l_name_size = fieldsize (struct link_map, lm_name);
|
||||||
#else /* !defined(HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS) */
|
#else /* !defined(HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS) */
|
||||||
@ -98,6 +105,10 @@ legacy_svr4_fetch_link_map_offsets (void)
|
|||||||
|
|
||||||
lmo.l_name_offset = offsetof (struct so_map, som_path);
|
lmo.l_name_offset = offsetof (struct so_map, som_path);
|
||||||
lmo.l_name_size = fieldsize (struct so_map, som_path);
|
lmo.l_name_size = fieldsize (struct so_map, som_path);
|
||||||
|
|
||||||
|
/* FIXME: Is the address of the dynamic table available? */
|
||||||
|
lmo.l_ld_offset = 0;
|
||||||
|
lmo.l_ld_size = 0;
|
||||||
#endif /* HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS */
|
#endif /* HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS */
|
||||||
#endif /* HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS */
|
#endif /* HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS */
|
||||||
#endif /* HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS */
|
#endif /* HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS */
|
||||||
|
113
gdb/solib-svr4.c
113
gdb/solib-svr4.c
@ -42,6 +42,7 @@
|
|||||||
#include "solib-svr4.h"
|
#include "solib-svr4.h"
|
||||||
|
|
||||||
#include "bfd-target.h"
|
#include "bfd-target.h"
|
||||||
|
#include "elf-bfd.h"
|
||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
|
|
||||||
static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
|
static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
|
||||||
@ -59,6 +60,13 @@ struct lm_info
|
|||||||
rather than void *, so that we may use byte offsets to find the
|
rather than void *, so that we may use byte offsets to find the
|
||||||
various fields without the need for a cast. */
|
various fields without the need for a cast. */
|
||||||
gdb_byte *lm;
|
gdb_byte *lm;
|
||||||
|
|
||||||
|
/* Amount by which addresses in the binary should be relocated to
|
||||||
|
match the inferior. This could most often be taken directly
|
||||||
|
from lm, but when prelinking is involved and the prelink base
|
||||||
|
address changes, we may need a different offset, we want to
|
||||||
|
warn about the difference and compute it only once. */
|
||||||
|
CORE_ADDR l_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* On SVR4 systems, a list of symbols in the dynamic linker where
|
/* On SVR4 systems, a list of symbols in the dynamic linker where
|
||||||
@ -127,14 +135,101 @@ static char *main_name_list[] =
|
|||||||
/* link map access functions */
|
/* link map access functions */
|
||||||
|
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
LM_ADDR (struct so_list *so)
|
LM_ADDR_FROM_LINK_MAP (struct so_list *so)
|
||||||
{
|
{
|
||||||
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
|
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
|
||||||
|
|
||||||
return (CORE_ADDR) extract_signed_integer (so->lm_info->lm + lmo->l_addr_offset,
|
return (CORE_ADDR) extract_signed_integer (so->lm_info->lm
|
||||||
|
+ lmo->l_addr_offset,
|
||||||
lmo->l_addr_size);
|
lmo->l_addr_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
HAS_LM_DYNAMIC_FROM_LINK_MAP ()
|
||||||
|
{
|
||||||
|
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
|
||||||
|
|
||||||
|
return (lmo->l_ld_size != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
LM_DYNAMIC_FROM_LINK_MAP (struct so_list *so)
|
||||||
|
{
|
||||||
|
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
|
||||||
|
|
||||||
|
gdb_assert (lmo->l_ld_size != 0);
|
||||||
|
|
||||||
|
return (CORE_ADDR) extract_signed_integer (so->lm_info->lm
|
||||||
|
+ lmo->l_ld_offset,
|
||||||
|
lmo->l_ld_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
LM_ADDR_CHECK (struct so_list *so, bfd *abfd)
|
||||||
|
{
|
||||||
|
if (so->lm_info->l_addr == (CORE_ADDR)-1)
|
||||||
|
{
|
||||||
|
struct bfd_section *dyninfo_sect;
|
||||||
|
CORE_ADDR l_addr, l_dynaddr, dynaddr, align = 0x1000;
|
||||||
|
|
||||||
|
l_addr = LM_ADDR_FROM_LINK_MAP (so);
|
||||||
|
|
||||||
|
if (! abfd || ! HAS_LM_DYNAMIC_FROM_LINK_MAP ())
|
||||||
|
goto set_addr;
|
||||||
|
|
||||||
|
l_dynaddr = LM_DYNAMIC_FROM_LINK_MAP (so);
|
||||||
|
|
||||||
|
dyninfo_sect = bfd_get_section_by_name (abfd, ".dynamic");
|
||||||
|
if (dyninfo_sect == NULL)
|
||||||
|
goto set_addr;
|
||||||
|
|
||||||
|
dynaddr = bfd_section_vma (abfd, dyninfo_sect);
|
||||||
|
|
||||||
|
if (dynaddr + l_addr != l_dynaddr)
|
||||||
|
{
|
||||||
|
warning (_(".dynamic section for \"%s\" "
|
||||||
|
"is not at the expected address"), so->so_name);
|
||||||
|
|
||||||
|
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
|
||||||
|
{
|
||||||
|
Elf_Internal_Ehdr *ehdr = elf_tdata (abfd)->elf_header;
|
||||||
|
Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
align = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < ehdr->e_phnum; i++)
|
||||||
|
if (phdr[i].p_type == PT_LOAD && phdr[i].p_align > align)
|
||||||
|
align = phdr[i].p_align;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn it into a mask. */
|
||||||
|
align--;
|
||||||
|
|
||||||
|
/* If the changes match the alignment requirements, we
|
||||||
|
assume we're using a core file that was generated by the
|
||||||
|
same binary, just prelinked with a different base offset.
|
||||||
|
If it doesn't match, we may have a different binary, the
|
||||||
|
same binary with the dynamic table loaded at an unrelated
|
||||||
|
location, or anything, really. To avoid regressions,
|
||||||
|
don't adjust the base offset in the latter case, although
|
||||||
|
odds are that, if things really changed, debugging won't
|
||||||
|
quite work. */
|
||||||
|
if ((l_addr & align) == 0 && ((dynaddr - l_dynaddr) & align) == 0)
|
||||||
|
{
|
||||||
|
l_addr = l_dynaddr - dynaddr;
|
||||||
|
warning (_("difference appears to be caused by prelink, "
|
||||||
|
"adjusting expectations"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_addr:
|
||||||
|
so->lm_info->l_addr = l_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return so->lm_info->l_addr;
|
||||||
|
}
|
||||||
|
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
LM_NEXT (struct so_list *so)
|
LM_NEXT (struct so_list *so)
|
||||||
{
|
{
|
||||||
@ -649,6 +744,8 @@ svr4_current_sos (void)
|
|||||||
free_so (new);
|
free_so (new);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
new->lm_info->l_addr = (CORE_ADDR)-1;
|
||||||
|
|
||||||
new->next = 0;
|
new->next = 0;
|
||||||
*link_ptr = new;
|
*link_ptr = new;
|
||||||
link_ptr = &new->next;
|
link_ptr = &new->next;
|
||||||
@ -912,7 +1009,7 @@ enable_break (void)
|
|||||||
if (strcmp (buf, so->so_original_name) == 0)
|
if (strcmp (buf, so->so_original_name) == 0)
|
||||||
{
|
{
|
||||||
load_addr_found = 1;
|
load_addr_found = 1;
|
||||||
load_addr = LM_ADDR (so);
|
load_addr = LM_ADDR_CHECK (so, tmp_bfd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
so = so->next;
|
so = so->next;
|
||||||
@ -1272,8 +1369,10 @@ static void
|
|||||||
svr4_relocate_section_addresses (struct so_list *so,
|
svr4_relocate_section_addresses (struct so_list *so,
|
||||||
struct section_table *sec)
|
struct section_table *sec)
|
||||||
{
|
{
|
||||||
sec->addr = svr4_truncate_ptr (sec->addr + LM_ADDR (so));
|
sec->addr = svr4_truncate_ptr (sec->addr + LM_ADDR_CHECK (so,
|
||||||
sec->endaddr = svr4_truncate_ptr (sec->endaddr + LM_ADDR (so));
|
sec->bfd));
|
||||||
|
sec->endaddr = svr4_truncate_ptr (sec->endaddr + LM_ADDR_CHECK (so,
|
||||||
|
sec->bfd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1362,6 +1461,8 @@ svr4_ilp32_fetch_link_map_offsets (void)
|
|||||||
lmo.l_addr_size = 4;
|
lmo.l_addr_size = 4;
|
||||||
lmo.l_name_offset = 4;
|
lmo.l_name_offset = 4;
|
||||||
lmo.l_name_size = 4;
|
lmo.l_name_size = 4;
|
||||||
|
lmo.l_ld_offset = 8;
|
||||||
|
lmo.l_ld_size = 4;
|
||||||
lmo.l_next_offset = 12;
|
lmo.l_next_offset = 12;
|
||||||
lmo.l_next_size = 4;
|
lmo.l_next_size = 4;
|
||||||
lmo.l_prev_offset = 16;
|
lmo.l_prev_offset = 16;
|
||||||
@ -1395,6 +1496,8 @@ svr4_lp64_fetch_link_map_offsets (void)
|
|||||||
lmo.l_addr_size = 8;
|
lmo.l_addr_size = 8;
|
||||||
lmo.l_name_offset = 8;
|
lmo.l_name_offset = 8;
|
||||||
lmo.l_name_size = 8;
|
lmo.l_name_size = 8;
|
||||||
|
lmo.l_ld_offset = 16;
|
||||||
|
lmo.l_ld_size = 8;
|
||||||
lmo.l_next_offset = 24;
|
lmo.l_next_offset = 24;
|
||||||
lmo.l_next_size = 8;
|
lmo.l_next_size = 8;
|
||||||
lmo.l_prev_offset = 32;
|
lmo.l_prev_offset = 32;
|
||||||
|
@ -50,6 +50,12 @@ struct link_map_offsets
|
|||||||
/* Size of l_addr field in struct link_map. */
|
/* Size of l_addr field in struct link_map. */
|
||||||
int l_addr_size;
|
int l_addr_size;
|
||||||
|
|
||||||
|
/* Offset to l_ld field in struct link_map. */
|
||||||
|
int l_ld_offset;
|
||||||
|
|
||||||
|
/* Size of l_ld field in struct link_map. */
|
||||||
|
int l_ld_size;
|
||||||
|
|
||||||
/* Offset to l_next field in struct link_map. */
|
/* Offset to l_next field in struct link_map. */
|
||||||
int l_next_offset;
|
int l_next_offset;
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2006-02-28 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
|
* gdb.base/prelink.exp: New test.
|
||||||
|
* gdb.base/prelink.c, gdb.base/prelink-lib.c: New sources.
|
||||||
|
|
||||||
2006-02-24 Wu Zhou <woodzltc@cn.ibm.com>
|
2006-02-24 Wu Zhou <woodzltc@cn.ibm.com>
|
||||||
|
|
||||||
* gdb.fortran/derived-type.f90: New file.
|
* gdb.fortran/derived-type.f90: New file.
|
||||||
|
34
gdb/testsuite/gdb.base/prelink-lib.c
Normal file
34
gdb/testsuite/gdb.base/prelink-lib.c
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2006 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 2 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, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
g (void (*p)(void))
|
||||||
|
{
|
||||||
|
p ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f(void (*p)(void)) {
|
||||||
|
g (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*h (void)) (void (*p)(void))
|
||||||
|
{
|
||||||
|
return f;
|
||||||
|
}
|
30
gdb/testsuite/gdb.base/prelink.c
Normal file
30
gdb/testsuite/gdb.base/prelink.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2006 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 2 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, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern void (*h (void)) (void (*)(void));
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
void (*f) (void (*)(void)) = h ();
|
||||||
|
printf ("%p\n", f);
|
||||||
|
f (0);
|
||||||
|
}
|
128
gdb/testsuite/gdb.base/prelink.exp
Normal file
128
gdb/testsuite/gdb.base/prelink.exp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# Copyright 2006 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 2 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
# Please email any bugs, comments, and/or additions to this file to:
|
||||||
|
# bug-gdb@prep.ai.mit.edu
|
||||||
|
|
||||||
|
# This file was written by Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
|
if $tracelevel then {
|
||||||
|
strace $tracelevel
|
||||||
|
}
|
||||||
|
|
||||||
|
set prms_id 0
|
||||||
|
set bug_id 0
|
||||||
|
|
||||||
|
# are we on a target board
|
||||||
|
if ![isnative] then {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if [get_compiler_info "ignored"] {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if {$gcc_compiled == 0} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
set testfile "prelink"
|
||||||
|
set srcfile ${testfile}.c
|
||||||
|
set binfile ${objdir}/${subdir}/${testfile}
|
||||||
|
|
||||||
|
set libsrcfile ${testfile}-lib.c
|
||||||
|
set libfile ${objdir}/${subdir}/${testfile}.so
|
||||||
|
if { [gdb_compile "${srcdir}/${subdir}/${libsrcfile}" "${libfile}" executable [list debug "additional_flags=-fpic -shared -nodefaultlibs"]] != ""} {
|
||||||
|
# If creating the shared library fails, maybe we don't have the right tools
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[catch "system \"prelink -NR ${libfile}\""] != 0} {
|
||||||
|
# Maybe we don't have prelink.
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
set srcfile ${testfile}.c
|
||||||
|
set binfile ${objdir}/${subdir}/${testfile}
|
||||||
|
if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${libfile}" "${binfile}" executable [list debug "additional_flags=-Wl,-rpath,${objdir}/${subdir}"]] != ""} {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
set found 0
|
||||||
|
set coredir "${objdir}/${subdir}/coredir.[getpid]"
|
||||||
|
file mkdir $coredir
|
||||||
|
catch "system \"(cd ${coredir}; ulimit -c unlimited; ${binfile}; true) >/dev/null 2>&1\""
|
||||||
|
|
||||||
|
foreach i "${coredir}/core ${coredir}/core.coremaker.c ${binfile}.core" {
|
||||||
|
if [remote_file build exists $i] {
|
||||||
|
remote_exec build "mv $i ${objdir}/${subdir}/prelink.core"
|
||||||
|
set found 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Check for "core.PID".
|
||||||
|
if { $found == 0 } {
|
||||||
|
set names [glob -nocomplain -directory $coredir core.*]
|
||||||
|
if {[llength $names] == 1} {
|
||||||
|
set corefile [file join $coredir [lindex $names 0]]
|
||||||
|
remote_exec build "mv $corefile ${objdir}/${subdir}/prelink.core"
|
||||||
|
set found 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch "system \"prelink -u ${libfile}\""
|
||||||
|
catch "system \"prelink -NR ${libfile}\""
|
||||||
|
|
||||||
|
# Try to clean up after ourselves.
|
||||||
|
remote_file build delete [file join $coredir coremmap.data]
|
||||||
|
remote_exec build "rmdir $coredir"
|
||||||
|
|
||||||
|
if { $found == 0 } {
|
||||||
|
warning "can't generate a core file - prelink tests suppressed - check ulimit -c"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start with a fresh gdb
|
||||||
|
|
||||||
|
gdb_exit
|
||||||
|
gdb_start
|
||||||
|
gdb_reinitialize_dir $srcdir/$subdir
|
||||||
|
gdb_load ${binfile}
|
||||||
|
|
||||||
|
set oldtimeout $timeout
|
||||||
|
set timeout [expr "$timeout + 60"]
|
||||||
|
verbose "Timeout is now $timeout seconds" 2
|
||||||
|
send_gdb "core-file $objdir/$subdir/prelink.core\n"
|
||||||
|
gdb_expect {
|
||||||
|
-re "warning: \.dynamic section.*not at the expected address" {
|
||||||
|
pass "changed base address"
|
||||||
|
}
|
||||||
|
-re ".*$gdb_prompt $" { fail "changed base address" }
|
||||||
|
timeout { fail "(timeout) changed base address" }
|
||||||
|
}
|
||||||
|
gdb_expect {
|
||||||
|
-re "warning: difference.*caused by prelink, adjusting" {
|
||||||
|
pass "prelink adjustment"
|
||||||
|
}
|
||||||
|
-re ".*$gdb_prompt $" { fail "prelink adjustment" }
|
||||||
|
timeout { fail "(timeout) prelink adjustment" }
|
||||||
|
}
|
||||||
|
set timeout $oldtimeout
|
||||||
|
verbose "Timeout is now $timeout seconds" 2
|
||||||
|
|
||||||
|
gdb_exit
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
Reference in New Issue
Block a user