mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 10:03:47 +08:00
gdb/
GDB internal type support for STT_GNU_IFUNC. * elfread.c (record_minimal_symbol): Support mst_text_gnu_ifunc. (elf_symtab_read): Set mst_text_gnu_ifunc for BSF_GNU_INDIRECT_FUNCTION. * eval.c (evaluate_subexp_standard): Support TYPE_GNU_IFUNC. * gdbtypes.c (init_type): Support TYPE_FLAG_GNU_IFUNC, builtin_func_func, nodebug_text_gnu_ifunc_symbol and nodebug_got_plt_symbol. * gdbtypes.h (enum type_flag_value): New entry TYPE_FLAG_GNU_IFUNC. (TYPE_GNU_IFUNC): New. (struct main_type): New field flag_gnu_ifunc. (struct builtin_type): New field builtin_func_func. (struct objfile_type): New fields nodebug_text_gnu_ifunc_symbol and nodebug_got_plt_symbol. * minsyms.c (lookup_minimal_symbol_text): Support mst_text_gnu_ifunc. (in_gnu_ifunc_stub): New. (prim_record_minimal_symbol, find_solib_trampoline_target): Support mst_text_gnu_ifunc. * parse.c (write_exp_msymbol): New variable ifunc_msym. Detect and support mst_text_gnu_ifunc. Support mst_slot_got_plt. * solib-svr4.c (svr4_in_dynsym_resolve_code): Return true also for in_gnu_ifunc_stub. * symmisc.c (dump_msymbols): Support mst_text_gnu_ifunc. * symtab.c (search_symbols): Likewise. * symtab.h (enum minimal_symbol_type): New fields mst_text_gnu_ifunc and mst_slot_got_plt. (in_gnu_ifunc_stub): New declaration.
This commit is contained in:
parent
d0fb5eaead
commit
0875794a96
@ -1,3 +1,33 @@
|
||||
2011-03-28 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
GDB internal type support for STT_GNU_IFUNC.
|
||||
* elfread.c (record_minimal_symbol): Support mst_text_gnu_ifunc.
|
||||
(elf_symtab_read): Set mst_text_gnu_ifunc for
|
||||
BSF_GNU_INDIRECT_FUNCTION.
|
||||
* eval.c (evaluate_subexp_standard): Support TYPE_GNU_IFUNC.
|
||||
* gdbtypes.c (init_type): Support TYPE_FLAG_GNU_IFUNC,
|
||||
builtin_func_func, nodebug_text_gnu_ifunc_symbol and
|
||||
nodebug_got_plt_symbol.
|
||||
* gdbtypes.h (enum type_flag_value): New entry TYPE_FLAG_GNU_IFUNC.
|
||||
(TYPE_GNU_IFUNC): New.
|
||||
(struct main_type): New field flag_gnu_ifunc.
|
||||
(struct builtin_type): New field builtin_func_func.
|
||||
(struct objfile_type): New fields nodebug_text_gnu_ifunc_symbol and
|
||||
nodebug_got_plt_symbol.
|
||||
* minsyms.c (lookup_minimal_symbol_text): Support mst_text_gnu_ifunc.
|
||||
(in_gnu_ifunc_stub): New.
|
||||
(prim_record_minimal_symbol, find_solib_trampoline_target): Support
|
||||
mst_text_gnu_ifunc.
|
||||
* parse.c (write_exp_msymbol): New variable ifunc_msym. Detect and
|
||||
support mst_text_gnu_ifunc. Support mst_slot_got_plt.
|
||||
* solib-svr4.c (svr4_in_dynsym_resolve_code): Return true also for
|
||||
in_gnu_ifunc_stub.
|
||||
* symmisc.c (dump_msymbols): Support mst_text_gnu_ifunc.
|
||||
* symtab.c (search_symbols): Likewise.
|
||||
* symtab.h (enum minimal_symbol_type): New fields mst_text_gnu_ifunc
|
||||
and mst_slot_got_plt.
|
||||
(in_gnu_ifunc_stub): New declaration.
|
||||
|
||||
2011-03-28 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Support a ring of related breakpoints.
|
||||
|
@ -185,7 +185,8 @@ record_minimal_symbol (const char *name, int name_len, int copy_name,
|
||||
{
|
||||
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||
|
||||
if (ms_type == mst_text || ms_type == mst_file_text)
|
||||
if (ms_type == mst_text || ms_type == mst_file_text
|
||||
|| ms_type == mst_text_gnu_ifunc)
|
||||
address = gdbarch_smash_text_address (gdbarch, address);
|
||||
|
||||
return prim_record_minimal_symbol_full (name, name_len, copy_name, address,
|
||||
@ -394,7 +395,10 @@ elf_symtab_read (struct objfile *objfile, int type,
|
||||
{
|
||||
if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
|
||||
{
|
||||
ms_type = mst_text;
|
||||
if (sym->flags & BSF_GNU_INDIRECT_FUNCTION)
|
||||
ms_type = mst_text_gnu_ifunc;
|
||||
else
|
||||
ms_type = mst_text;
|
||||
}
|
||||
else if ((sym->name[0] == '.' && sym->name[1] == 'L')
|
||||
|| ((sym->flags & BSF_LOCAL)
|
||||
|
@ -1832,6 +1832,8 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||
return value_zero (builtin_type (exp->gdbarch)->builtin_int,
|
||||
not_lval);
|
||||
}
|
||||
else if (TYPE_GNU_IFUNC (ftype))
|
||||
return allocate_value (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (ftype)));
|
||||
else if (TYPE_TARGET_TYPE (ftype))
|
||||
return allocate_value (TYPE_TARGET_TYPE (ftype));
|
||||
else
|
||||
|
@ -1902,6 +1902,8 @@ init_type (enum type_code code, int length, int flags,
|
||||
TYPE_STUB_SUPPORTED (type) = 1;
|
||||
if (flags & TYPE_FLAG_FIXED_INSTANCE)
|
||||
TYPE_FIXED_INSTANCE (type) = 1;
|
||||
if (flags & TYPE_FLAG_GNU_IFUNC)
|
||||
TYPE_GNU_IFUNC (type) = 1;
|
||||
|
||||
if (name)
|
||||
TYPE_NAME (type) = obsavestring (name, strlen (name),
|
||||
@ -3772,6 +3774,8 @@ gdbtypes_post_init (struct gdbarch *gdbarch)
|
||||
= lookup_pointer_type (builtin_type->builtin_void);
|
||||
builtin_type->builtin_func_ptr
|
||||
= lookup_pointer_type (lookup_function_type (builtin_type->builtin_void));
|
||||
builtin_type->builtin_func_func
|
||||
= lookup_function_type (builtin_type->builtin_func_ptr);
|
||||
|
||||
/* This type represents a GDB internal function. */
|
||||
builtin_type->internal_fn
|
||||
@ -3885,6 +3889,18 @@ objfile_type (struct objfile *objfile)
|
||||
"<text variable, no debug info>", objfile);
|
||||
TYPE_TARGET_TYPE (objfile_type->nodebug_text_symbol)
|
||||
= objfile_type->builtin_int;
|
||||
objfile_type->nodebug_text_gnu_ifunc_symbol
|
||||
= init_type (TYPE_CODE_FUNC, 1, TYPE_FLAG_GNU_IFUNC,
|
||||
"<text gnu-indirect-function variable, no debug info>",
|
||||
objfile);
|
||||
TYPE_TARGET_TYPE (objfile_type->nodebug_text_gnu_ifunc_symbol)
|
||||
= objfile_type->nodebug_text_symbol;
|
||||
objfile_type->nodebug_got_plt_symbol
|
||||
= init_type (TYPE_CODE_PTR, gdbarch_addr_bit (gdbarch) / 8, 0,
|
||||
"<text from jump slot in .got.plt, no debug info>",
|
||||
objfile);
|
||||
TYPE_TARGET_TYPE (objfile_type->nodebug_got_plt_symbol)
|
||||
= objfile_type->nodebug_text_symbol;
|
||||
objfile_type->nodebug_data_symbol
|
||||
= init_type (TYPE_CODE_INT,
|
||||
gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT, 0,
|
||||
|
@ -170,6 +170,7 @@ enum type_flag_value
|
||||
TYPE_FLAG_VECTOR = (1 << 15),
|
||||
TYPE_FLAG_FIXED_INSTANCE = (1 << 16),
|
||||
TYPE_FLAG_STUB_SUPPORTED = (1 << 17),
|
||||
TYPE_FLAG_GNU_IFUNC = (1 << 18),
|
||||
|
||||
/* Used for error-checking. */
|
||||
TYPE_FLAG_MIN = TYPE_FLAG_UNSIGNED
|
||||
@ -271,6 +272,12 @@ enum type_instance_flag_value
|
||||
|
||||
#define TYPE_NOTTEXT(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_NOTTEXT)
|
||||
|
||||
/* Used only for TYPE_CODE_FUNC where it specifies the real function
|
||||
address is returned by this function call. TYPE_TARGET_TYPE determines the
|
||||
final returned function type to be presented to user. */
|
||||
|
||||
#define TYPE_GNU_IFUNC(t) (TYPE_MAIN_TYPE (t)->flag_gnu_ifunc)
|
||||
|
||||
/* Type owner. If TYPE_OBJFILE_OWNED is true, the type is owned by
|
||||
the objfile retrieved as TYPE_OBJFILE. Otherweise, the type is
|
||||
owned by an architecture; TYPE_OBJFILE is NULL in this case. */
|
||||
@ -387,6 +394,7 @@ struct main_type
|
||||
unsigned int flag_varargs : 1;
|
||||
unsigned int flag_vector : 1;
|
||||
unsigned int flag_stub_supported : 1;
|
||||
unsigned int flag_gnu_ifunc : 1;
|
||||
unsigned int flag_fixed_instance : 1;
|
||||
unsigned int flag_objfile_owned : 1;
|
||||
/* True if this type was declared with "class" rather than
|
||||
@ -1178,6 +1186,10 @@ struct builtin_type
|
||||
(*) () can server as a generic function pointer. */
|
||||
struct type *builtin_func_ptr;
|
||||
|
||||
/* `function returning pointer to function (returning void)' type.
|
||||
The final void return type is not significant for it. */
|
||||
struct type *builtin_func_func;
|
||||
|
||||
|
||||
/* Special-purpose types. */
|
||||
|
||||
@ -1218,6 +1230,8 @@ struct objfile_type
|
||||
|
||||
/* Types used for symbols with no debug information. */
|
||||
struct type *nodebug_text_symbol;
|
||||
struct type *nodebug_text_gnu_ifunc_symbol;
|
||||
struct type *nodebug_got_plt_symbol;
|
||||
struct type *nodebug_data_symbol;
|
||||
struct type *nodebug_unknown_symbol;
|
||||
struct type *nodebug_tls_symbol;
|
||||
|
@ -334,8 +334,9 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf)
|
||||
msymbol = msymbol->hash_next)
|
||||
{
|
||||
if (strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0 &&
|
||||
(MSYMBOL_TYPE (msymbol) == mst_text ||
|
||||
MSYMBOL_TYPE (msymbol) == mst_file_text))
|
||||
(MSYMBOL_TYPE (msymbol) == mst_text
|
||||
|| MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc
|
||||
|| MSYMBOL_TYPE (msymbol) == mst_file_text))
|
||||
{
|
||||
switch (MSYMBOL_TYPE (msymbol))
|
||||
{
|
||||
@ -697,6 +698,16 @@ lookup_minimal_symbol_by_pc (CORE_ADDR pc)
|
||||
return lookup_minimal_symbol_by_pc_section (pc, NULL);
|
||||
}
|
||||
|
||||
/* Return non-zero iff PC is in an STT_GNU_IFUNC function resolver. */
|
||||
|
||||
int
|
||||
in_gnu_ifunc_stub (CORE_ADDR pc)
|
||||
{
|
||||
struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
|
||||
|
||||
return msymbol && MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc;
|
||||
}
|
||||
|
||||
/* Find the minimal symbol named NAME, and return both the minsym
|
||||
struct and its objfile. This only checks the linkage name. Sets
|
||||
*OBJFILE_P and returns the minimal symbol, if it is found. If it
|
||||
@ -766,6 +777,7 @@ prim_record_minimal_symbol (const char *name, CORE_ADDR address,
|
||||
switch (ms_type)
|
||||
{
|
||||
case mst_text:
|
||||
case mst_text_gnu_ifunc:
|
||||
case mst_file_text:
|
||||
case mst_solib_trampoline:
|
||||
section = SECT_OFF_TEXT (objfile);
|
||||
@ -1231,7 +1243,8 @@ find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc)
|
||||
{
|
||||
ALL_MSYMBOLS (objfile, msymbol)
|
||||
{
|
||||
if (MSYMBOL_TYPE (msymbol) == mst_text
|
||||
if ((MSYMBOL_TYPE (msymbol) == mst_text
|
||||
|| MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc)
|
||||
&& strcmp (SYMBOL_LINKAGE_NAME (msymbol),
|
||||
SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
|
||||
return SYMBOL_VALUE_ADDRESS (msymbol);
|
||||
|
24
gdb/parse.c
24
gdb/parse.c
@ -487,9 +487,22 @@ write_exp_msymbol (struct minimal_symbol *msymbol)
|
||||
pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, ¤t_target);
|
||||
if (pc != addr)
|
||||
{
|
||||
struct minimal_symbol *ifunc_msym = lookup_minimal_symbol_by_pc (pc);
|
||||
|
||||
/* In this case, assume we have a code symbol instead of
|
||||
a data symbol. */
|
||||
type = mst_text;
|
||||
|
||||
if (ifunc_msym != NULL && MSYMBOL_TYPE (ifunc_msym) == mst_text_gnu_ifunc
|
||||
&& SYMBOL_VALUE_ADDRESS (ifunc_msym) == pc)
|
||||
{
|
||||
/* A function descriptor has been resolved but PC is still in the
|
||||
STT_GNU_IFUNC resolver body (such as because inferior does not
|
||||
run to be able to call it). */
|
||||
|
||||
type = mst_text_gnu_ifunc;
|
||||
}
|
||||
else
|
||||
type = mst_text;
|
||||
section = NULL;
|
||||
addr = pc;
|
||||
}
|
||||
@ -521,6 +534,11 @@ write_exp_msymbol (struct minimal_symbol *msymbol)
|
||||
write_exp_elt_type (objfile_type (objfile)->nodebug_text_symbol);
|
||||
break;
|
||||
|
||||
case mst_text_gnu_ifunc:
|
||||
write_exp_elt_type (objfile_type (objfile)
|
||||
->nodebug_text_gnu_ifunc_symbol);
|
||||
break;
|
||||
|
||||
case mst_data:
|
||||
case mst_file_data:
|
||||
case mst_bss:
|
||||
@ -528,6 +546,10 @@ write_exp_msymbol (struct minimal_symbol *msymbol)
|
||||
write_exp_elt_type (objfile_type (objfile)->nodebug_data_symbol);
|
||||
break;
|
||||
|
||||
case mst_slot_got_plt:
|
||||
write_exp_elt_type (objfile_type (objfile)->nodebug_got_plt_symbol);
|
||||
break;
|
||||
|
||||
default:
|
||||
write_exp_elt_type (objfile_type (objfile)->nodebug_unknown_symbol);
|
||||
break;
|
||||
|
@ -1276,7 +1276,8 @@ 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, NULL)
|
||||
|| in_gnu_ifunc_stub (pc));
|
||||
}
|
||||
|
||||
/* Given an executable's ABFD and target, compute the entry-point
|
||||
|
@ -265,6 +265,9 @@ dump_msymbols (struct objfile *objfile, struct ui_file *outfile)
|
||||
case mst_text:
|
||||
ms_type = 'T';
|
||||
break;
|
||||
case mst_text_gnu_ifunc:
|
||||
ms_type = 'i';
|
||||
break;
|
||||
case mst_solib_trampoline:
|
||||
ms_type = 'S';
|
||||
break;
|
||||
|
@ -3006,7 +3006,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
|
||||
static const enum minimal_symbol_type types3[]
|
||||
= {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
|
||||
static const enum minimal_symbol_type types4[]
|
||||
= {mst_file_bss, mst_text, mst_abs, mst_unknown};
|
||||
= {mst_file_bss, mst_text_gnu_ifunc, mst_abs, mst_unknown};
|
||||
enum minimal_symbol_type ourtype;
|
||||
enum minimal_symbol_type ourtype2;
|
||||
enum minimal_symbol_type ourtype3;
|
||||
|
@ -290,6 +290,9 @@ enum minimal_symbol_type
|
||||
{
|
||||
mst_unknown = 0, /* Unknown type, the default */
|
||||
mst_text, /* Generally executable instructions */
|
||||
mst_text_gnu_ifunc, /* Executable code returning address
|
||||
of executable code */
|
||||
mst_slot_got_plt, /* GOT entries for .plt sections */
|
||||
mst_data, /* Generally initialized data */
|
||||
mst_bss, /* Generally uninitialized data */
|
||||
mst_abs, /* Generally absolute (nonrelocatable) */
|
||||
@ -1034,6 +1037,8 @@ extern struct minimal_symbol *lookup_minimal_symbol_by_pc_name
|
||||
|
||||
extern struct minimal_symbol *lookup_minimal_symbol_by_pc (CORE_ADDR);
|
||||
|
||||
extern int in_gnu_ifunc_stub (CORE_ADDR pc);
|
||||
|
||||
extern struct minimal_symbol *
|
||||
lookup_minimal_symbol_and_objfile (const char *,
|
||||
struct objfile **);
|
||||
|
Loading…
Reference in New Issue
Block a user