* minsyms.c: Include "target.h".
(find_solib_trampoline_target): Handle minimal symbols pointing to function descriptors as well. * Makefile.in (minsyms.o): Update dependencies. * ppc-linux-tdep.c (ppc64_standard_linkage): Rename to ... (ppc64_standard_linkage1): ... this. Fix optional instructions. (PPC64_STANDARD_LINKAGE_LEN): Rename to ... (PPC64_STANDARD_LINKAGE1_LEN): ... this. (ppc64_standard_linkage2, ppc64_standard_linkage3): New. (PPC64_STANDARD_LINKAGE2_LEN, PPC64_STANDARD_LINKAGE3_LEN): New. (ppc64_standard_linkage_target): Rename to ... (ppc64_standard_linkage1_target): ... this. (ppc64_standard_linkage2_target, ppc64_standard_linkage3_target): New. (ppc64_skip_trampoline_code): Support three variants of standard linkage stubs. Call find_solib_trampoline_target to handle glink stubs.
This commit is contained in:
parent
74d1f0631a
commit
42848c9656
|
@ -1,3 +1,23 @@
|
||||||
|
2008-05-16 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
|
* minsyms.c: Include "target.h".
|
||||||
|
(find_solib_trampoline_target): Handle minimal symbols pointing
|
||||||
|
to function descriptors as well.
|
||||||
|
* Makefile.in (minsyms.o): Update dependencies.
|
||||||
|
|
||||||
|
* ppc-linux-tdep.c (ppc64_standard_linkage): Rename to ...
|
||||||
|
(ppc64_standard_linkage1): ... this. Fix optional instructions.
|
||||||
|
(PPC64_STANDARD_LINKAGE_LEN): Rename to ...
|
||||||
|
(PPC64_STANDARD_LINKAGE1_LEN): ... this.
|
||||||
|
(ppc64_standard_linkage2, ppc64_standard_linkage3): New.
|
||||||
|
(PPC64_STANDARD_LINKAGE2_LEN, PPC64_STANDARD_LINKAGE3_LEN): New.
|
||||||
|
(ppc64_standard_linkage_target): Rename to ...
|
||||||
|
(ppc64_standard_linkage1_target): ... this.
|
||||||
|
(ppc64_standard_linkage2_target, ppc64_standard_linkage3_target): New.
|
||||||
|
(ppc64_skip_trampoline_code): Support three variants of standard
|
||||||
|
linkage stubs. Call find_solib_trampoline_target to handle
|
||||||
|
glink stubs.
|
||||||
|
|
||||||
2008-05-16 Ulrich Weigand <uweigand@de.ibm.com>
|
2008-05-16 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
* ppc-linux-tdep.c (ppc_linux_init_abi): Do not install
|
* ppc-linux-tdep.c (ppc_linux_init_abi): Do not install
|
||||||
|
|
|
@ -2501,7 +2501,8 @@ mep-tdep.o: $(defs_h) $(frame_h) $(frame_unwind_h) $(frame_base_h) \
|
||||||
mingw-hdep.o: mingw-hdep.c $(defs_h) $(serial_h) $(event_loop_h) \
|
mingw-hdep.o: mingw-hdep.c $(defs_h) $(serial_h) $(event_loop_h) \
|
||||||
$(gdb_assert_h) $(gdb_select_h) $(gdb_string_h) $(readline_h)
|
$(gdb_assert_h) $(gdb_select_h) $(gdb_string_h) $(readline_h)
|
||||||
minsyms.o: minsyms.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) \
|
minsyms.o: minsyms.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) \
|
||||||
$(symfile_h) $(objfiles_h) $(demangle_h) $(value_h) $(cp_abi_h)
|
$(symfile_h) $(objfiles_h) $(demangle_h) $(value_h) $(cp_abi_h) \
|
||||||
|
$(target_h)
|
||||||
mips64obsd-nat.o: mips64obsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
|
mips64obsd-nat.o: mips64obsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
|
||||||
$(target_h) $(mips_tdep_h) $(inf_ptrace_h)
|
$(target_h) $(mips_tdep_h) $(inf_ptrace_h)
|
||||||
mips64obsd-tdep.o: mips64obsd-tdep.c $(defs_h) $(osabi_h) $(regcache_h) \
|
mips64obsd-tdep.o: mips64obsd-tdep.c $(defs_h) $(osabi_h) $(regcache_h) \
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "demangle.h"
|
#include "demangle.h"
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
#include "cp-abi.h"
|
#include "cp-abi.h"
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
/* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
|
/* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
|
||||||
At the end, copy them all into one newly allocated location on an objfile's
|
At the end, copy them all into one newly allocated location on an objfile's
|
||||||
|
@ -1110,6 +1111,22 @@ find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc)
|
||||||
&& strcmp (SYMBOL_LINKAGE_NAME (msymbol),
|
&& strcmp (SYMBOL_LINKAGE_NAME (msymbol),
|
||||||
SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
|
SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
|
||||||
return SYMBOL_VALUE_ADDRESS (msymbol);
|
return SYMBOL_VALUE_ADDRESS (msymbol);
|
||||||
|
|
||||||
|
/* Also handle minimal symbols pointing to function descriptors. */
|
||||||
|
if (MSYMBOL_TYPE (msymbol) == mst_data
|
||||||
|
&& strcmp (SYMBOL_LINKAGE_NAME (msymbol),
|
||||||
|
SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
|
||||||
|
{
|
||||||
|
CORE_ADDR func;
|
||||||
|
func = gdbarch_convert_from_func_ptr_addr
|
||||||
|
(get_objfile_arch (objfile),
|
||||||
|
SYMBOL_VALUE_ADDRESS (msymbol),
|
||||||
|
¤t_target);
|
||||||
|
|
||||||
|
/* Ignore data symbols that are not function descriptors. */
|
||||||
|
if (func != SYMBOL_VALUE_ADDRESS (msymbol))
|
||||||
|
return func;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -331,7 +331,7 @@ ppc64_desc_entry_point (CORE_ADDR desc)
|
||||||
/* Pattern for the standard linkage function. These are built by
|
/* Pattern for the standard linkage function. These are built by
|
||||||
build_plt_stub in elf64-ppc.c, whose GLINK argument is always
|
build_plt_stub in elf64-ppc.c, whose GLINK argument is always
|
||||||
zero. */
|
zero. */
|
||||||
static struct insn_pattern ppc64_standard_linkage[] =
|
static struct insn_pattern ppc64_standard_linkage1[] =
|
||||||
{
|
{
|
||||||
/* addis r12, r2, <any> */
|
/* addis r12, r2, <any> */
|
||||||
{ insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 },
|
{ insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 },
|
||||||
|
@ -343,17 +343,16 @@ static struct insn_pattern ppc64_standard_linkage[] =
|
||||||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 },
|
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 },
|
||||||
|
|
||||||
/* addis r12, r12, 1 <optional> */
|
/* addis r12, r12, 1 <optional> */
|
||||||
{ insn_d (-1, -1, -1, -1), insn_d (15, 12, 2, 1), 1 },
|
{ insn_d (-1, -1, -1, -1), insn_d (15, 12, 12, 1), 1 },
|
||||||
|
|
||||||
/* ld r2, <any>(r12) */
|
/* ld r2, <any>(r12) */
|
||||||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 },
|
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 },
|
||||||
|
|
||||||
/* addis r12, r12, 1 <optional> */
|
/* addis r12, r12, 1 <optional> */
|
||||||
{ insn_d (-1, -1, -1, -1), insn_d (15, 12, 2, 1), 1 },
|
{ insn_d (-1, -1, -1, -1), insn_d (15, 12, 12, 1), 1 },
|
||||||
|
|
||||||
/* mtctr r11 */
|
/* mtctr r11 */
|
||||||
{ insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467),
|
{ insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 },
|
||||||
0 },
|
|
||||||
|
|
||||||
/* ld r11, <any>(r12) */
|
/* ld r11, <any>(r12) */
|
||||||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 },
|
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 },
|
||||||
|
@ -363,8 +362,68 @@ static struct insn_pattern ppc64_standard_linkage[] =
|
||||||
|
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
};
|
};
|
||||||
#define PPC64_STANDARD_LINKAGE_LEN \
|
#define PPC64_STANDARD_LINKAGE1_LEN \
|
||||||
(sizeof (ppc64_standard_linkage) / sizeof (ppc64_standard_linkage[0]))
|
(sizeof (ppc64_standard_linkage1) / sizeof (ppc64_standard_linkage1[0]))
|
||||||
|
|
||||||
|
static struct insn_pattern ppc64_standard_linkage2[] =
|
||||||
|
{
|
||||||
|
/* addis r12, r2, <any> */
|
||||||
|
{ insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 },
|
||||||
|
|
||||||
|
/* std r2, 40(r1) */
|
||||||
|
{ -1, insn_ds (62, 2, 1, 40, 0), 0 },
|
||||||
|
|
||||||
|
/* ld r11, <any>(r12) */
|
||||||
|
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 },
|
||||||
|
|
||||||
|
/* addi r12, r12, <any> <optional> */
|
||||||
|
{ insn_d (-1, -1, -1, 0), insn_d (14, 12, 12, 0), 1 },
|
||||||
|
|
||||||
|
/* mtctr r11 */
|
||||||
|
{ insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 },
|
||||||
|
|
||||||
|
/* ld r2, <any>(r12) */
|
||||||
|
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 },
|
||||||
|
|
||||||
|
/* ld r11, <any>(r12) */
|
||||||
|
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 },
|
||||||
|
|
||||||
|
/* bctr */
|
||||||
|
{ -1, 0x4e800420, 0 },
|
||||||
|
|
||||||
|
{ 0, 0, 0 }
|
||||||
|
};
|
||||||
|
#define PPC64_STANDARD_LINKAGE2_LEN \
|
||||||
|
(sizeof (ppc64_standard_linkage2) / sizeof (ppc64_standard_linkage2[0]))
|
||||||
|
|
||||||
|
static struct insn_pattern ppc64_standard_linkage3[] =
|
||||||
|
{
|
||||||
|
/* std r2, 40(r1) */
|
||||||
|
{ -1, insn_ds (62, 2, 1, 40, 0), 0 },
|
||||||
|
|
||||||
|
/* ld r11, <any>(r2) */
|
||||||
|
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 0 },
|
||||||
|
|
||||||
|
/* addi r2, r2, <any> <optional> */
|
||||||
|
{ insn_d (-1, -1, -1, 0), insn_d (14, 2, 2, 0), 1 },
|
||||||
|
|
||||||
|
/* mtctr r11 */
|
||||||
|
{ insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 },
|
||||||
|
|
||||||
|
/* ld r11, <any>(r2) */
|
||||||
|
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 0 },
|
||||||
|
|
||||||
|
/* ld r2, <any>(r2) */
|
||||||
|
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 2, 0, 0), 0 },
|
||||||
|
|
||||||
|
/* bctr */
|
||||||
|
{ -1, 0x4e800420, 0 },
|
||||||
|
|
||||||
|
{ 0, 0, 0 }
|
||||||
|
};
|
||||||
|
#define PPC64_STANDARD_LINKAGE3_LEN \
|
||||||
|
(sizeof (ppc64_standard_linkage3) / sizeof (ppc64_standard_linkage3[0]))
|
||||||
|
|
||||||
|
|
||||||
/* When the dynamic linker is doing lazy symbol resolution, the first
|
/* When the dynamic linker is doing lazy symbol resolution, the first
|
||||||
call to a function in another object will go like this:
|
call to a function in another object will go like this:
|
||||||
|
@ -413,8 +472,8 @@ static struct insn_pattern ppc64_standard_linkage[] =
|
||||||
standard linkage function will send them. (This doesn't deal with
|
standard linkage function will send them. (This doesn't deal with
|
||||||
dynamic linker lazy symbol resolution stubs.) */
|
dynamic linker lazy symbol resolution stubs.) */
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
ppc64_standard_linkage_target (struct frame_info *frame,
|
ppc64_standard_linkage1_target (struct frame_info *frame,
|
||||||
CORE_ADDR pc, unsigned int *insn)
|
CORE_ADDR pc, unsigned int *insn)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
|
struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
|
||||||
|
|
||||||
|
@ -430,20 +489,72 @@ ppc64_standard_linkage_target (struct frame_info *frame,
|
||||||
return ppc64_desc_entry_point (desc);
|
return ppc64_desc_entry_point (desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
ppc64_standard_linkage2_target (struct frame_info *frame,
|
||||||
|
CORE_ADDR pc, unsigned int *insn)
|
||||||
|
{
|
||||||
|
struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
|
||||||
|
|
||||||
|
/* The address of the function descriptor this linkage function
|
||||||
|
references. */
|
||||||
|
CORE_ADDR desc
|
||||||
|
= ((CORE_ADDR) get_frame_register_unsigned (frame,
|
||||||
|
tdep->ppc_gp0_regnum + 2)
|
||||||
|
+ (insn_d_field (insn[0]) << 16)
|
||||||
|
+ insn_ds_field (insn[2]));
|
||||||
|
|
||||||
|
/* The first word of the descriptor is the entry point. Return that. */
|
||||||
|
return ppc64_desc_entry_point (desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
ppc64_standard_linkage3_target (struct frame_info *frame,
|
||||||
|
CORE_ADDR pc, unsigned int *insn)
|
||||||
|
{
|
||||||
|
struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
|
||||||
|
|
||||||
|
/* The address of the function descriptor this linkage function
|
||||||
|
references. */
|
||||||
|
CORE_ADDR desc
|
||||||
|
= ((CORE_ADDR) get_frame_register_unsigned (frame,
|
||||||
|
tdep->ppc_gp0_regnum + 2)
|
||||||
|
+ insn_ds_field (insn[1]));
|
||||||
|
|
||||||
|
/* The first word of the descriptor is the entry point. Return that. */
|
||||||
|
return ppc64_desc_entry_point (desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Given that we've begun executing a call trampoline at PC, return
|
/* Given that we've begun executing a call trampoline at PC, return
|
||||||
the entry point of the function the trampoline will go to. */
|
the entry point of the function the trampoline will go to. */
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||||||
{
|
{
|
||||||
unsigned int ppc64_standard_linkage_insn[PPC64_STANDARD_LINKAGE_LEN];
|
unsigned int ppc64_standard_linkage1_insn[PPC64_STANDARD_LINKAGE1_LEN];
|
||||||
|
unsigned int ppc64_standard_linkage2_insn[PPC64_STANDARD_LINKAGE2_LEN];
|
||||||
|
unsigned int ppc64_standard_linkage3_insn[PPC64_STANDARD_LINKAGE3_LEN];
|
||||||
|
CORE_ADDR target;
|
||||||
|
|
||||||
if (insns_match_pattern (pc, ppc64_standard_linkage,
|
if (insns_match_pattern (pc, ppc64_standard_linkage1,
|
||||||
ppc64_standard_linkage_insn))
|
ppc64_standard_linkage1_insn))
|
||||||
return ppc64_standard_linkage_target (frame, pc,
|
pc = ppc64_standard_linkage1_target (frame, pc,
|
||||||
ppc64_standard_linkage_insn);
|
ppc64_standard_linkage1_insn);
|
||||||
|
else if (insns_match_pattern (pc, ppc64_standard_linkage2,
|
||||||
|
ppc64_standard_linkage2_insn))
|
||||||
|
pc = ppc64_standard_linkage2_target (frame, pc,
|
||||||
|
ppc64_standard_linkage2_insn);
|
||||||
|
else if (insns_match_pattern (pc, ppc64_standard_linkage3,
|
||||||
|
ppc64_standard_linkage3_insn))
|
||||||
|
pc = ppc64_standard_linkage3_target (frame, pc,
|
||||||
|
ppc64_standard_linkage3_insn);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* The PLT descriptor will either point to the already resolved target
|
||||||
|
address, or else to a glink stub. As the latter carry synthetic @plt
|
||||||
|
symbols, find_solib_trampoline_target should be able to resolve them. */
|
||||||
|
target = find_solib_trampoline_target (frame, pc);
|
||||||
|
return target? target : pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue