/* Handle SVR4 shared libraries for GDB, the GNU Debugger.
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
- 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GDB.
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 */
+/* Link map info to include in an allocated so_list entry. */
struct lm_info
{
SVR4 systems will fall back to using a symbol as the "startup
mapping complete" breakpoint address. */
-static char *solib_break_names[] =
+static const char * const solib_break_names[] =
{
"r_debug_state",
"_r_debug_state",
NULL
};
-static char *bkpt_names[] =
+static const char * const bkpt_names[] =
{
"_start",
"__start",
NULL
};
-static char *main_name_list[] =
+static const char * const main_name_list[] =
{
"main_$main",
NULL
return (svr4_same_1 (gdb->so_original_name, inferior->so_original_name));
}
-/* link map access functions */
+/* link map access functions. */
static CORE_ADDR
LM_ADDR_FROM_LINK_MAP (struct so_list *so)
struct svr4_info
{
- CORE_ADDR debug_base; /* Base of dynamic linker structures */
+ CORE_ADDR debug_base; /* Base of dynamic linker structures. */
/* Validity flag for debug_loader_offset. */
int debug_loader_offset_p;
/* Local function prototypes */
-static int match_main (char *);
-
-static CORE_ADDR bfd_lookup_symbol (bfd *, char *);
+static int match_main (const char *);
/*
*/
static CORE_ADDR
-bfd_lookup_symbol (bfd *abfd, char *symname)
+bfd_lookup_symbol (bfd *abfd, const char *symname)
{
long storage_needed;
asymbol *sym;
}
-/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
+/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
returned and the corresponding PTR is set. */
static int
If FROM_TTYP dereferences to a non-zero integer, allow messages to
be printed. This parameter is a pointer rather than an int because
open_symbol_file_object() is called via catch_errors() and
- catch_errors() requires a pointer argument. */
+ catch_errors() requires a pointer argument. */
static int
open_symbol_file_object (void *from_ttyp)
/* Always locate the debug struct, in case it has moved. */
info->debug_base = 0;
if (locate_base (info) == 0)
- return 0; /* failed somehow... */
+ return 0; /* failed somehow... */
/* First link map member should be the executable. */
lm = solib_svr4_r_map (info);
if (lm == 0)
- return 0; /* failed somehow... */
+ return 0; /* failed somehow... */
/* Read address of name from target memory to GDB. */
read_memory (lm + lmo->l_name_offset, l_name_buf, l_name_size);
inferior executable, so we must ignore it. For some versions of
SVR4, it has no name. For others (Solaris 2.3 for example), it
does have a name, so we can no longer use a missing name to
- decide when to ignore it. */
+ decide when to ignore it. */
else if (IGNORE_FIRST_LINK_MAP_ENTRY (new) && ldsomap == 0)
{
info->main_lm_addr = new->lm_info->lm_addr;
non-zero iff SONAME matches one of the known main executable names. */
static int
-match_main (char *soname)
+match_main (const char *soname)
{
- char **mainp;
+ const char * const *mainp;
for (mainp = main_name_list; *mainp != NULL; mainp++)
{
enable_break (struct svr4_info *info, int from_tty)
{
struct minimal_symbol *msymbol;
- char **bkpt_namep;
+ const char * const *bkpt_namep;
asection *interp_sect;
gdb_byte *interp_name;
CORE_ADDR sym_addr;
sym_addr = gdbarch_addr_bits_remove
(target_gdbarch, gdbarch_convert_from_func_ptr_addr (target_gdbarch,
- sym_addr,
- ¤t_target));
+ 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
}
}
- for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++)
+ if (!current_inferior ()->attach_flag)
{
- msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);
- if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
+ for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++)
{
- sym_addr = SYMBOL_VALUE_ADDRESS (msymbol);
- sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch,
- sym_addr,
- ¤t_target);
- create_solib_event_breakpoint (target_gdbarch, sym_addr);
- return 1;
+ msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);
+ if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
+ {
+ sym_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+ sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch,
+ sym_addr,
+ ¤t_target);
+ create_solib_event_breakpoint (target_gdbarch, sym_addr);
+ return 1;
+ }
}
}
return 0;
exec_bfd. Otherwise return 0.
We relocate all of the sections by the same amount. This
- behavior is mandated by recent editions of the System V ABI.
+ behavior is mandated by recent editions of the System V ABI.
According to the System V Application Binary Interface,
Edition 4.1, page 5-5:
may be different from EXEC_BFD as the file may have been prelinked
to a different address after the executable has been loaded.
Moreover the address of placement in target memory can be
- different from what the program headers in target memory say - this
- is the goal of PIE.
+ different from what the program headers in target memory say -
+ this is the goal of PIE.
Detected DISPLACEMENT covers both the offsets of PIE placement and
possible new prelink performed after start of the program. Here
if (phdrs_size != phdrs2_size
|| bfd_get_arch_size (exec_bfd) != arch_size)
ok = 0;
- else if (arch_size == 32 && phdrs_size >= sizeof (Elf32_External_Phdr)
+ else if (arch_size == 32
+ && phdrs_size >= sizeof (Elf32_External_Phdr)
&& phdrs_size % sizeof (Elf32_External_Phdr) == 0)
{
Elf_Internal_Ehdr *ehdr2 = elf_tdata (exec_bfd)->elf_header;
Elf32_External_Phdr *phdr2p;
gdb_byte *buf_vaddr_p, *buf_paddr_p;
CORE_ADDR vaddr, paddr;
+ asection *plt2_asect;
phdrp = &((Elf32_External_Phdr *) buf)[i];
buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr;
/* Check also other adjustment combinations - PR 11786. */
- vaddr = extract_unsigned_integer (buf_vaddr_p, 4, byte_order);
+ vaddr = extract_unsigned_integer (buf_vaddr_p, 4,
+ byte_order);
vaddr -= displacement;
store_unsigned_integer (buf_vaddr_p, 4, byte_order, vaddr);
- paddr = extract_unsigned_integer (buf_paddr_p, 4, byte_order);
+ paddr = extract_unsigned_integer (buf_paddr_p, 4,
+ byte_order);
paddr -= displacement;
store_unsigned_integer (buf_paddr_p, 4, byte_order, paddr);
if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
continue;
+ /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS. */
+ plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
+ if (plt2_asect)
+ {
+ int content2;
+ gdb_byte *buf_filesz_p = (gdb_byte *) &phdrp->p_filesz;
+ CORE_ADDR filesz;
+
+ content2 = (bfd_get_section_flags (exec_bfd, plt2_asect)
+ & SEC_HAS_CONTENTS) != 0;
+
+ filesz = extract_unsigned_integer (buf_filesz_p, 4,
+ byte_order);
+
+ /* PLT2_ASECT is from on-disk file (exec_bfd) while
+ FILESZ is from the in-memory image. */
+ if (content2)
+ filesz += bfd_get_section_size (plt2_asect);
+ else
+ filesz -= bfd_get_section_size (plt2_asect);
+
+ store_unsigned_integer (buf_filesz_p, 4, byte_order,
+ filesz);
+
+ if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
+ continue;
+ }
+
ok = 0;
break;
}
}
- else if (arch_size == 64 && phdrs_size >= sizeof (Elf64_External_Phdr)
+ else if (arch_size == 64
+ && phdrs_size >= sizeof (Elf64_External_Phdr)
&& phdrs_size % sizeof (Elf64_External_Phdr) == 0)
{
Elf_Internal_Ehdr *ehdr2 = elf_tdata (exec_bfd)->elf_header;
Elf64_External_Phdr *phdr2p;
gdb_byte *buf_vaddr_p, *buf_paddr_p;
CORE_ADDR vaddr, paddr;
+ asection *plt2_asect;
phdrp = &((Elf64_External_Phdr *) buf)[i];
buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr;
/* Check also other adjustment combinations - PR 11786. */
- vaddr = extract_unsigned_integer (buf_vaddr_p, 8, byte_order);
+ vaddr = extract_unsigned_integer (buf_vaddr_p, 8,
+ byte_order);
vaddr -= displacement;
store_unsigned_integer (buf_vaddr_p, 8, byte_order, vaddr);
- paddr = extract_unsigned_integer (buf_paddr_p, 8, byte_order);
+ paddr = extract_unsigned_integer (buf_paddr_p, 8,
+ byte_order);
paddr -= displacement;
store_unsigned_integer (buf_paddr_p, 8, byte_order, paddr);
if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
continue;
+ /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS. */
+ plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
+ if (plt2_asect)
+ {
+ int content2;
+ gdb_byte *buf_filesz_p = (gdb_byte *) &phdrp->p_filesz;
+ CORE_ADDR filesz;
+
+ content2 = (bfd_get_section_flags (exec_bfd, plt2_asect)
+ & SEC_HAS_CONTENTS) != 0;
+
+ filesz = extract_unsigned_integer (buf_filesz_p, 8,
+ byte_order);
+
+ /* PLT2_ASECT is from on-disk file (exec_bfd) while
+ FILESZ is from the in-memory image. */
+ if (content2)
+ filesz += bfd_get_section_size (plt2_asect);
+ else
+ filesz -= bfd_get_section_size (plt2_asect);
+
+ store_unsigned_integer (buf_filesz_p, 8, byte_order,
+ filesz);
+
+ if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
+ continue;
+ }
+
ok = 0;
break;
}
}
/* Relocate the main executable. This function should be called upon
- stopping the inferior process at the entry point to the program.
+ stopping the inferior process at the entry point to the program.
The entry point from BFD is compared to the AT_ENTRY of AUXV and if they are
different, the main executable is relocated by the proper amount. */
the `qOffsets' packet.
- The section offsets were not reset earlier, and the best we can
- hope is that the old offsets are still applicable to the new run.
- */
+ hope is that the old offsets are still applicable to the new run. */
if (! svr4_exec_displacement (&displacement))
return;
Now run the target. It will eventually hit the breakpoint, at
which point all of the libraries will have been mapped in and we
can go groveling around in the dynamic linker structures to find
- out what we need to know about them. */
+ out what we need to know about them. */
inf = current_inferior ();
tp = inferior_thread ();
clear_proceed_status ();
- inf->stop_soon = STOP_QUIETLY;
- tp->stop_signal = TARGET_SIGNAL_0;
+ inf->control.stop_soon = STOP_QUIETLY;
+ tp->suspend.stop_signal = TARGET_SIGNAL_0;
do
{
- target_resume (pid_to_ptid (-1), 0, tp->stop_signal);
+ target_resume (pid_to_ptid (-1), 0, tp->suspend.stop_signal);
wait_for_inferior (0);
}
- while (tp->stop_signal != TARGET_SIGNAL_TRAP);
- inf->stop_soon = NO_STOP_QUIETLY;
+ while (tp->suspend.stop_signal != TARGET_SIGNAL_TRAP);
+ inf->control.stop_soon = NO_STOP_QUIETLY;
#endif /* defined(_SCO_DS) */
}
struct target_so_ops svr4_so_ops;
-/* Lookup global symbol for ELF DSOs linked with -Bsymbolic. Those DSOs have a
+/* Lookup global symbol for ELF DSOs linked with -Bsymbolic. Those DSOs have a
different rule for symbol lookup. The lookup begins here in the DSO, not in
the main executable. */