* objfiles.h (pc_in_section): New prototype.

(in_plt_section): Remove name argument, replace prototype with
	static inline function.
	* mips-tdep.h: Include "objfiles.h".
	(in_mips_stubs_section): New function.
	* hppa-tdep.h (gdbarch_tdep): Remove name argument of
	in_solib_call_trampoline member.
	(hppa_in_solib_call_trampoline): Remove name argument.
	* objfiles.c (pc_in_section): New function.
	(in_plt_section): Remove function.
	* mips-linux-tdep.c: Include "objfiles.h".
	(mips_linux_in_dynsym_stub): Call in_mips_stubs_section.  Remove
	name argument.  Return 1 rather than the low 16-bit halfword of
	any instruction examined.
	(mips_linux_in_dynsym_resolve_code): Update
	mips_linux_in_dynsym_stub call accordingly.
	* mips-tdep.c (mips_stub_frame_sniffer): Use in_mips_stubs_section
	rather than an equivalent hand-coded sequence.
	* hppa-hpux-tdep.c (in_opd_section): Remove function.
	(hppa32_hpux_in_solib_call_trampoline): Remove name argument.
	(hppa64_hpux_in_solib_call_trampoline): Likewise.
	(hppa64_hpux_find_global_pointer): Use pc_in_section rather than
	in_opd_section.
	* hppa-tdep.c (hppa_stub_unwind_sniffer): Remove name argument
	on call to tdep->in_solib_call_trampoline.
	(hppa_in_solib_call_trampoline): Remove name argument, update
	according to in_plt_section change.
	(hppa_skip_trampoline_code): Update according to in_plt_section
	change.
	* aarch64-tdep.c (aarch64_stub_unwind_sniffer): Likewise.
	* arm-symbian-tdep.c (arm_symbian_skip_trampoline_code):
	Likewise.
	* arm-tdep.c (arm_stub_unwind_sniffer): Likewise.
	* hppa-linux-tdep.c (hppa_linux_find_global_pointer): Likewise.
	* hppabsd-tdep.c (hppabsd_find_global_pointer): Likewise.
	* nios2-tdep.c (nios2_stub_frame_sniffer): Likewise.
	* nto-tdep.c (nto_relocate_section_addresses): Likewise.
	* s390-tdep.c (s390_stub_frame_sniffer): Likewise.
	* sh-tdep.c (sh_stub_unwind_sniffer): Likewise.
	* solib-dsbt.c (dsbt_in_dynsym_resolve_code): Likewise.
	* solib-frv.c (frv_in_dynsym_resolve_code): Likewise.
	* solib-svr4.c (svr4_in_dynsym_resolve_code): Likewise.
	* solib-target.c (solib_target_in_dynsym_resolve_code): Likewise.
	* sparc-tdep.c (sparc_analyze_prologue): Likewise.
	* tic6x-tdep.c (tic6x_stub_unwind_sniffer): Likewise.
This commit is contained in:
Maciej W. Rozycki 2013-06-24 22:18:32 +00:00
parent b9b26a166a
commit 3e5d3a5aaf
24 changed files with 120 additions and 70 deletions

View File

@ -1,3 +1,51 @@
2013-06-24 Maciej W. Rozycki <macro@codesourcery.com>
* objfiles.h (pc_in_section): New prototype.
(in_plt_section): Remove name argument, replace prototype with
static inline function.
* mips-tdep.h: Include "objfiles.h".
(in_mips_stubs_section): New function.
* hppa-tdep.h (gdbarch_tdep): Remove name argument of
in_solib_call_trampoline member.
(hppa_in_solib_call_trampoline): Remove name argument.
* objfiles.c (pc_in_section): New function.
(in_plt_section): Remove function.
* mips-linux-tdep.c: Include "objfiles.h".
(mips_linux_in_dynsym_stub): Call in_mips_stubs_section. Remove
name argument. Return 1 rather than the low 16-bit halfword of
any instruction examined.
(mips_linux_in_dynsym_resolve_code): Update
mips_linux_in_dynsym_stub call accordingly.
* mips-tdep.c (mips_stub_frame_sniffer): Use in_mips_stubs_section
rather than an equivalent hand-coded sequence.
* hppa-hpux-tdep.c (in_opd_section): Remove function.
(hppa32_hpux_in_solib_call_trampoline): Remove name argument.
(hppa64_hpux_in_solib_call_trampoline): Likewise.
(hppa64_hpux_find_global_pointer): Use pc_in_section rather than
in_opd_section.
* hppa-tdep.c (hppa_stub_unwind_sniffer): Remove name argument
on call to tdep->in_solib_call_trampoline.
(hppa_in_solib_call_trampoline): Remove name argument, update
according to in_plt_section change.
(hppa_skip_trampoline_code): Update according to in_plt_section
change.
* aarch64-tdep.c (aarch64_stub_unwind_sniffer): Likewise.
* arm-symbian-tdep.c (arm_symbian_skip_trampoline_code):
Likewise.
* arm-tdep.c (arm_stub_unwind_sniffer): Likewise.
* hppa-linux-tdep.c (hppa_linux_find_global_pointer): Likewise.
* hppabsd-tdep.c (hppabsd_find_global_pointer): Likewise.
* nios2-tdep.c (nios2_stub_frame_sniffer): Likewise.
* nto-tdep.c (nto_relocate_section_addresses): Likewise.
* s390-tdep.c (s390_stub_frame_sniffer): Likewise.
* sh-tdep.c (sh_stub_unwind_sniffer): Likewise.
* solib-dsbt.c (dsbt_in_dynsym_resolve_code): Likewise.
* solib-frv.c (frv_in_dynsym_resolve_code): Likewise.
* solib-svr4.c (svr4_in_dynsym_resolve_code): Likewise.
* solib-target.c (solib_target_in_dynsym_resolve_code): Likewise.
* sparc-tdep.c (sparc_analyze_prologue): Likewise.
* tic6x-tdep.c (tic6x_stub_unwind_sniffer): Likewise.
2013-06-24 Joel Brobecker <brobecker@adacore.com>
* common/create-version.sh: Fix expansion of $host_alias

View File

@ -1094,7 +1094,7 @@ aarch64_stub_unwind_sniffer (const struct frame_unwind *self,
gdb_byte dummy[4];
addr_in_block = get_frame_address_in_block (this_frame);
if (in_plt_section (addr_in_block, NULL)
if (in_plt_section (addr_in_block)
/* We also use the stub winder if the target memory is unreadable
to avoid having the prologue unwinder trying to read it. */
|| target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)

View File

@ -38,7 +38,7 @@ arm_symbian_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
CORE_ADDR dest;
gdb_byte buf[4];
if (!in_plt_section (pc, NULL))
if (!in_plt_section (pc))
return 0;
if (target_read_memory (pc, buf, 4) != 0)

View File

@ -2907,7 +2907,7 @@ arm_stub_unwind_sniffer (const struct frame_unwind *self,
gdb_byte dummy[4];
addr_in_block = get_frame_address_in_block (this_frame);
if (in_plt_section (addr_in_block, NULL)
if (in_plt_section (addr_in_block)
/* We also use the stub winder if the target memory is unreadable
to avoid having the prologue unwinder trying to read it. */
|| target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)

View File

@ -65,28 +65,13 @@
extern void _initialize_hppa_hpux_tdep (void);
extern initialize_file_ftype _initialize_hppa_hpux_tdep;
static int
in_opd_section (CORE_ADDR pc)
{
struct obj_section *s;
int retval = 0;
s = find_pc_section (pc);
retval = (s != NULL
&& s->the_bfd_section->name != NULL
&& strcmp (s->the_bfd_section->name, ".opd") == 0);
return (retval);
}
/* Return one if PC is in the call path of a trampoline, else return zero.
Note we return one for *any* call trampoline (long-call, arg-reloc), not
just shared library trampolines (import, export). */
static int
hppa32_hpux_in_solib_call_trampoline (struct gdbarch *gdbarch,
CORE_ADDR pc, char *name)
hppa32_hpux_in_solib_call_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct bound_minimal_symbol minsym;
@ -156,8 +141,7 @@ hppa32_hpux_in_solib_call_trampoline (struct gdbarch *gdbarch,
}
static int
hppa64_hpux_in_solib_call_trampoline (struct gdbarch *gdbarch,
CORE_ADDR pc, char *name)
hppa64_hpux_in_solib_call_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@ -798,7 +782,7 @@ hppa64_hpux_find_global_pointer (struct gdbarch *gdbarch,
faddr = value_as_address (function);
if (in_opd_section (faddr))
if (pc_in_section (faddr, ".opd"))
{
target_read_memory (faddr, buf, sizeof (buf));
return extract_unsigned_integer (&buf[24], 8, byte_order);

View File

@ -356,7 +356,7 @@ hppa_linux_find_global_pointer (struct gdbarch *gdbarch,
/* If the address is in the plt section, then the real function hasn't
yet been fixed up by the linker so we cannot determine the gp of
that function. */
if (in_plt_section (faddr, NULL))
if (in_plt_section (faddr))
return 0;
faddr_sect = find_pc_section (faddr);

View File

@ -2417,7 +2417,7 @@ hppa_stub_unwind_sniffer (const struct frame_unwind *self,
if (pc == 0
|| (tdep->in_solib_call_trampoline != NULL
&& tdep->in_solib_call_trampoline (gdbarch, pc, NULL))
&& tdep->in_solib_call_trampoline (gdbarch, pc))
|| gdbarch_in_solib_return_trampoline (gdbarch, pc, NULL))
return 1;
return 0;
@ -2855,13 +2855,12 @@ hppa_in_dyncall (CORE_ADDR pc)
}
int
hppa_in_solib_call_trampoline (struct gdbarch *gdbarch,
CORE_ADDR pc, char *name)
hppa_in_solib_call_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc)
{
unsigned int insn[HPPA_MAX_INSN_PATTERN_LEN];
struct unwind_table_entry *u;
if (in_plt_section (pc, name) || hppa_in_dyncall (pc))
if (in_plt_section (pc) || hppa_in_dyncall (pc))
return 1;
/* The GNU toolchain produces linker stubs without unwind
@ -2918,13 +2917,13 @@ hppa_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
/* fallthrough */
}
if (in_plt_section (pc, NULL))
if (in_plt_section (pc))
{
pc = read_memory_typed_address (pc, func_ptr_type);
/* If the PLT slot has not yet been resolved, the target will be
the PLT stub. */
if (in_plt_section (pc, NULL))
if (in_plt_section (pc))
{
/* Sanity check: are we pointing to the PLT stub? */
if (!hppa_match_insns (gdbarch, pc, hppa_plt_stub, insn))

View File

@ -90,11 +90,9 @@ struct gdbarch_tdep
CORE_ADDR (*find_global_pointer) (struct gdbarch *, struct value *);
/* For shared libraries, each call goes through a small piece of
trampoline code in the ".plt", or equivalent, section.
IN_SOLIB_CALL_TRAMPOLINE evaluates to nonzero if we are currently
stopped in one of these. */
int (*in_solib_call_trampoline) (struct gdbarch *gdbarch,
CORE_ADDR pc, char *name);
trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE
evaluates to nonzero if we are currently stopped in one of these. */
int (*in_solib_call_trampoline) (struct gdbarch *gdbarch, CORE_ADDR pc);
/* For targets that support multiple spaces, we may have additional stubs
in the return path. These stubs are internal to the ABI, and users are
@ -242,7 +240,7 @@ extern struct minimal_symbol *
extern struct hppa_objfile_private *hppa_init_objfile_priv_data (struct objfile *objfile);
extern int hppa_in_solib_call_trampoline (struct gdbarch *gdbarch,
CORE_ADDR pc, char *name);
CORE_ADDR pc);
extern CORE_ADDR hppa_skip_trampoline_code (struct frame_info *, CORE_ADDR pc);
#endif /* hppa-tdep.h */

View File

@ -47,7 +47,7 @@ hppabsd_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
/* If the address is in the .plt section, then the real function
hasn't yet been fixed up by the linker so we cannot determine the
Global Pointer for that function. */
if (in_plt_section (faddr, NULL))
if (in_plt_section (faddr))
return 0;
faddr_sec = find_pc_section (faddr);

View File

@ -30,6 +30,7 @@
#include "trad-frame.h"
#include "tramp-frame.h"
#include "gdbtypes.h"
#include "objfiles.h"
#include "solib.h"
#include "solib-svr4.h"
#include "solist.h"
@ -666,25 +667,34 @@ mips_linux_core_read_description (struct gdbarch *gdbarch,
/* Check the code at PC for a dynamic linker lazy resolution stub.
Because they aren't in the .plt section, we pattern-match on the
code generated by GNU ld. They look like this:
GNU ld for MIPS has put lazy resolution stubs into a ".MIPS.stubs"
section uniformly since version 2.15. If the pc is in that section,
then we are in such a stub. Before that ".stub" was used in 32-bit
ELF binaries, however we do not bother checking for that since we
have never had and that case should be extremely rare these days.
Instead we pattern-match on the code generated by GNU ld. They look
like this:
lw t9,0x8010(gp)
addu t7,ra
jalr t9,ra
addiu t8,zero,INDEX
(with the appropriate doubleword instructions for N64). Also
return the dynamic symbol index used in the last instruction. */
(with the appropriate doubleword instructions for N64). As any lazy
resolution stubs in microMIPS binaries will always be in a
".MIPS.stubs" section we only ever verify standard MIPS patterns. */
static int
mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
mips_linux_in_dynsym_stub (CORE_ADDR pc)
{
gdb_byte buf[28], *p;
ULONGEST insn, insn1;
int n64 = (mips_abi (target_gdbarch ()) == MIPS_ABI_N64);
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
if (in_mips_stubs_section (pc))
return 1;
read_memory (pc - 12, buf, 28);
if (n64)
@ -742,7 +752,7 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
return 0;
}
return (insn & 0xffff);
return 1;
}
/* Return non-zero iff PC belongs to the dynamic linker resolution
@ -756,9 +766,10 @@ mips_linux_in_dynsym_resolve_code (CORE_ADDR pc)
if (svr4_in_dynsym_resolve_code (pc))
return 1;
/* Pattern match for the stub. It would be nice if there were a
more efficient way to avoid this check. */
if (mips_linux_in_dynsym_stub (pc, NULL))
/* Likewise for the stubs. They live in the .MIPS.stubs section these
days, so we check if the PC is within, than fall back to a pattern
match. */
if (mips_linux_in_dynsym_stub (pc))
return 1;
return 0;

View File

@ -3588,15 +3588,7 @@ mips_stub_frame_sniffer (const struct frame_unwind *self,
if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)
return 1;
if (in_plt_section (pc, NULL))
return 1;
/* Binutils for MIPS puts lazy resolution stubs into .MIPS.stubs. */
s = find_pc_section (pc);
if (s != NULL
&& strcmp (bfd_get_section_name (s->objfile->obfd, s->the_bfd_section),
".MIPS.stubs") == 0)
if (in_plt_section (pc) || in_mips_stubs_section (pc))
return 1;
/* Calling a PIC function from a non-PIC function passes through a

View File

@ -20,6 +20,8 @@
#ifndef MIPS_TDEP_H
#define MIPS_TDEP_H
#include "objfiles.h"
struct gdbarch;
/* All the possible MIPS ABIs. */
@ -184,4 +186,12 @@ extern void mips_write_pc (struct regcache *regcache, CORE_ADDR pc);
extern struct target_desc *mips_tdesc_gp32;
extern struct target_desc *mips_tdesc_gp64;
/* Return non-zero if PC is in a MIPS SVR4 lazy binding stub section. */
static inline int
in_mips_stubs_section (CORE_ADDR pc)
{
return pc_in_section (pc, ".MIPS.stubs");
}
#endif /* MIPS_TDEP_H */

View File

@ -1324,7 +1324,7 @@ nios2_stub_frame_sniffer (const struct frame_unwind *self,
if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)
return 1;
if (in_plt_section (pc, NULL))
if (in_plt_section (pc))
return 1;
return 0;

View File

@ -318,7 +318,7 @@ nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
int
nto_in_dynsym_resolve_code (CORE_ADDR pc)
{
if (in_plt_section (pc, NULL))
if (in_plt_section (pc))
return 1;
return 0;
}

View File

@ -1410,12 +1410,10 @@ find_pc_section (CORE_ADDR pc)
}
/* In SVR4, we recognize a trampoline by it's section name.
That is, if the pc is in a section named ".plt" then we are in
a trampoline. */
/* Return non-zero if PC is in a section called NAME. */
int
in_plt_section (CORE_ADDR pc, char *name)
pc_in_section (CORE_ADDR pc, char *name)
{
struct obj_section *s;
int retval = 0;
@ -1424,7 +1422,7 @@ in_plt_section (CORE_ADDR pc, char *name)
retval = (s != NULL
&& s->the_bfd_section->name != NULL
&& strcmp (s->the_bfd_section->name, ".plt") == 0);
&& strcmp (s->the_bfd_section->name, name) == 0);
return (retval);
}

View File

@ -495,7 +495,17 @@ extern int have_minimal_symbols (void);
extern struct obj_section *find_pc_section (CORE_ADDR pc);
extern int in_plt_section (CORE_ADDR, char *);
/* Return non-zero if PC is in a section called NAME. */
extern int pc_in_section (CORE_ADDR, char *);
/* Return non-zero if PC is in a SVR4-style procedure linkage table
section. */
static inline int
in_plt_section (CORE_ADDR pc)
{
return pc_in_section (pc, ".plt");
}
/* Keep a registry of per-objfile data-pointers required by other GDB
modules. */

View File

@ -2116,7 +2116,7 @@ s390_stub_frame_sniffer (const struct frame_unwind *self,
have trapped due to an invalid function pointer call. We handle
the non-existing current function like a PLT stub. */
addr_in_block = get_frame_address_in_block (this_frame);
if (in_plt_section (addr_in_block, NULL)
if (in_plt_section (addr_in_block)
|| s390_readinstruction (insn, get_frame_pc (this_frame)) < 0)
return 1;
return 0;

View File

@ -2036,7 +2036,7 @@ sh_stub_unwind_sniffer (const struct frame_unwind *self,
CORE_ADDR addr_in_block;
addr_in_block = get_frame_address_in_block (this_frame);
if (in_plt_section (addr_in_block, NULL))
if (in_plt_section (addr_in_block))
return 1;
return 0;

View File

@ -764,7 +764,7 @@ dsbt_in_dynsym_resolve_code (CORE_ADDR pc)
return ((pc >= info->interp_text_sect_low && pc < info->interp_text_sect_high)
|| (pc >= info->interp_plt_sect_low && pc < info->interp_plt_sect_high)
|| in_plt_section (pc, NULL));
|| in_plt_section (pc));
}
/* Print a warning about being unable to set the dynamic linker

View File

@ -448,7 +448,7 @@ frv_in_dynsym_resolve_code (CORE_ADDR pc)
{
return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
|| (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
|| in_plt_section (pc, NULL));
|| in_plt_section (pc));
}
/* Given a loadmap and an address, return the displacement needed

View File

@ -1532,7 +1532,7 @@ svr4_in_dynsym_resolve_code (CORE_ADDR pc)
&& pc < info->interp_text_sect_high)
|| (pc >= info->interp_plt_sect_low
&& pc < info->interp_plt_sect_high)
|| in_plt_section (pc, NULL)
|| in_plt_section (pc)
|| in_gnu_ifunc_stub (pc));
}

View File

@ -476,7 +476,7 @@ solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
/* We don't have a range of addresses for the dynamic linker; there
may not be one in the program's address space. So only report
PLT entries (which may be import stubs). */
return in_plt_section (pc, NULL);
return in_plt_section (pc);
}
struct target_so_ops solib_target_so_ops;

View File

@ -855,7 +855,7 @@ sparc_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
dynamic linker patches up the first PLT with some code that
starts with a SAVE instruction. Patch up PC such that it points
at the start of our PLT entry. */
if (tdep->plt_entry_size > 0 && in_plt_section (current_pc, NULL))
if (tdep->plt_entry_size > 0 && in_plt_section (current_pc))
pc = current_pc - ((current_pc - pc) % tdep->plt_entry_size);
insn = sparc_fetch_instruction (pc);

View File

@ -530,7 +530,7 @@ tic6x_stub_unwind_sniffer (const struct frame_unwind *self,
CORE_ADDR addr_in_block;
addr_in_block = get_frame_address_in_block (this_frame);
if (in_plt_section (addr_in_block, NULL))
if (in_plt_section (addr_in_block))
return 1;
return 0;