static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
static int svr4_have_link_map_offsets (void);
+static void svr4_relocate_main_executable (void);
/* Link map info to include in an allocated so_list entry */
"_r_debug_state",
"_dl_debug_state",
"rtld_db_dlactivity",
+ "__dl_rtld_db_dlactivity",
"_rtld_debug_state",
NULL
if (so->lm_info->l_addr == (CORE_ADDR)-1)
{
struct bfd_section *dyninfo_sect;
- CORE_ADDR l_addr, l_dynaddr, dynaddr, align = 0x1000;
+ CORE_ADDR l_addr, l_dynaddr, dynaddr;
l_addr = LM_ADDR_FROM_LINK_MAP (so);
if (dynaddr + l_addr != l_dynaddr)
{
+ CORE_ADDR align = 0x1000;
+ CORE_ADDR minpagesize = align;
+
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
{
Elf_Internal_Ehdr *ehdr = elf_tdata (abfd)->elf_header;
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;
+
+ minpagesize = get_elf_backend_data (abfd)->minpagesize;
}
/* Turn it into a mask. */
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) == ((l_dynaddr - dynaddr) & align))
+ quite work.
+
+ One could expect more the condition
+ ((l_addr & align) == 0 && ((l_dynaddr - dynaddr) & align) == 0)
+ but the one below is relaxed for PPC. The PPC kernel supports
+ either 4k or 64k page sizes. To be prepared for 64k pages,
+ PPC ELF files are built using an alignment requirement of 64k.
+ However, when running on a kernel supporting 4k pages, the memory
+ mapping of the library may not actually happen on a 64k boundary!
+
+ (In the usual case where (l_addr & align) == 0, this check is
+ equivalent to the possibly expected check above.)
+
+ Even on PPC it must be zero-aligned at least for MINPAGESIZE. */
+
+ if ((l_addr & (minpagesize - 1)) == 0
+ && (l_addr & align) == ((l_dynaddr - dynaddr) & align))
{
l_addr = l_dynaddr - dynaddr;
- warning (_(".dynamic section for \"%s\" "
- "is not at the expected address"), so->so_name);
- warning (_("difference appears to be caused by prelink, "
- "adjusting expectations"));
+ if (info_verbose)
+ {
+ warning (_(".dynamic section for \"%s\" "
+ "is not at the expected address"), so->so_name);
+ warning (_("difference appears to be caused by prelink, "
+ "adjusting expectations"));
+ }
}
else
warning (_(".dynamic section for \"%s\" "
{
int arch_size, step, sect_size;
long dyn_tag;
- CORE_ADDR dyn_ptr;
+ CORE_ADDR dyn_ptr, dyn_addr;
gdb_byte *bufend, *bufstart, *buf;
Elf32_External_Dyn *x_dynp_32;
Elf64_External_Dyn *x_dynp_64;
target_section++)
if (sect == target_section->the_bfd_section)
break;
- gdb_assert (target_section < current_target_sections->sections_end);
+ if (target_section < current_target_sections->sections_end)
+ dyn_addr = target_section->addr;
+ else
+ {
+ /* ABFD may come from OBJFILE acting only as a symbol file without being
+ loaded into the target (see add_symbol_file_command). This case is
+ such fallback to the file VMA address without the possibility of
+ having the section relocated to its actual in-memory address. */
+
+ dyn_addr = bfd_section_vma (abfd, sect);
+ }
/* Read in .dynamic from the BFD. We will get the actual value
from memory later. */
CORE_ADDR ptr_addr;
ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
- ptr_addr = target_section->addr + (buf - bufstart) + arch_size / 8;
+ ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8;
if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0)
dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
*ptr = dyn_ptr;
sym_addr,
¤t_target));
+ /* On at least some versions of Solaris there's a dynamic relocation
+ on _r_debug.r_brk and SYM_ADDR may not be relocated yet, e.g., if
+ we get control before the dynamic linker has self-relocated.
+ Check if SYM_ADDR is in a known section, if it is assume we can
+ trust its value. This is just a heuristic though, it could go away
+ or be replaced if it's getting in the way.
+
+ On ARM we need to know whether the ISA of rtld_db_dlactivity (or
+ however it's spelled in your particular system) is ARM or Thumb.
+ That knowledge is encoded in the address, if it's Thumb the low bit
+ is 1. However, we've stripped that info above and it's not clear
+ what all the consequences are of passing a non-addr_bits_remove'd
+ address to create_solib_event_breakpoint. The call to
+ find_pc_section verifies we know about the address and have some
+ hope of computing the right kind of breakpoint to use (via
+ symbol info). It does mean that GDB needs to be pointed at a
+ non-stripped version of the dynamic linker in order to obtain
+ information it already knows about. Sigh. */
+
os = find_pc_section (sym_addr);
if (os != NULL)
{
static void
svr4_special_symbol_handling (void)
{
+ svr4_relocate_main_executable ();
}
/* Decide if the objfile needs to be relocated. As indicated above,
svr4_exec_displacement (void)
{
int found;
+ /* ENTRY_POINT is a possible function descriptor - before
+ a call to gdbarch_convert_from_func_ptr_addr. */
CORE_ADDR entry_point;
if (exec_bfd == NULL)
return 0;
if (target_auxv_search (¤t_target, AT_ENTRY, &entry_point) == 1)
- return entry_point - exec_entry_point (exec_bfd, ¤t_target);
+ return entry_point - bfd_get_start_address (exec_bfd);
return svr4_static_exec_displacement ();
}
info = get_svr4_info ();
/* Relocate the main executable if necessary. */
- svr4_relocate_main_executable ();
+ if (current_inferior ()->attach_flag == 0)
+ svr4_relocate_main_executable ();
if (!svr4_have_link_map_offsets ())
return;