mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-03 23:56:39 +00:00
gdb/
Support resolution of STT_GNU_IFUNC via breakpoints. * breakpoint.c (print_it_typical): Support bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return. (bpstat_what): Rename parameter to bs_head, new variable bs, adjust the loop. Support bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return. New comment after the loop. New loop for bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return breakpoints. (bptype_string, print_one_breakpoint_location): Support bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return. (user_settable_breakpoint): Return true also for bp_gnu_ifunc_resolver. (allocate_bp_location): Support bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return. (set_breakpoint_location_function): New parameter explicit_loc, describe it. Call find_pc_partial_function_gnu_ifunc with new variable IS_GNU_IFUNC and adjust the address for STT_GNU_IFUNC if EXPLICIT_LOC is not set. (set_raw_breakpoint): Set EXPLICIT_LOC for set_breakpoint_location_function. (clone_momentary_breakpoint): Use true for EXPLICIT_LOC of set_breakpoint_location_function. (mention): Support bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return. (add_location_to_breakpoint): Set EXPLICIT_LOC for set_breakpoint_location_function. (update_breakpoint_locations): Remove static. (breakpoint_re_set_one): Support bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return. * breakpoint.h (enum bptype): New fields bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return. (update_breakpoint_locations): New declaration. * elfread.c: Include gdbthread.h and regcache.h. (elf_gnu_ifunc_resolver_stop, elf_gnu_ifunc_resolver_return_stop): New functions. (elf_gnu_ifunc_fns): Install them. * minsyms.c (stub_gnu_ifunc_resolver_stop) (stub_gnu_ifunc_resolver_return_stop): New functions. (stub_gnu_ifunc_fns): Install them. * symtab.h (struct gnu_ifunc_fns): New fields gnu_ifunc_resolver_stop and gnu_ifunc_resolver_return_stop. (gnu_ifunc_resolver_stop, gnu_ifunc_resolver_return_stop): New.
This commit is contained in:
parent
07be84bf8f
commit
0e30163f12
@ -1,3 +1,48 @@
|
||||
2011-03-28 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Support resolution of STT_GNU_IFUNC via breakpoints.
|
||||
* breakpoint.c (print_it_typical): Support bp_gnu_ifunc_resolver and
|
||||
bp_gnu_ifunc_resolver_return.
|
||||
(bpstat_what): Rename parameter to bs_head, new variable bs, adjust
|
||||
the loop. Support bp_gnu_ifunc_resolver and
|
||||
bp_gnu_ifunc_resolver_return. New comment after the loop. New loop
|
||||
for bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return
|
||||
breakpoints.
|
||||
(bptype_string, print_one_breakpoint_location): Support
|
||||
bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return.
|
||||
(user_settable_breakpoint): Return true also for
|
||||
bp_gnu_ifunc_resolver.
|
||||
(allocate_bp_location): Support bp_gnu_ifunc_resolver and
|
||||
bp_gnu_ifunc_resolver_return.
|
||||
(set_breakpoint_location_function): New parameter explicit_loc,
|
||||
describe it. Call find_pc_partial_function_gnu_ifunc with new
|
||||
variable IS_GNU_IFUNC and adjust the address for STT_GNU_IFUNC if
|
||||
EXPLICIT_LOC is not set.
|
||||
(set_raw_breakpoint): Set EXPLICIT_LOC for
|
||||
set_breakpoint_location_function.
|
||||
(clone_momentary_breakpoint): Use true for EXPLICIT_LOC of
|
||||
set_breakpoint_location_function.
|
||||
(mention): Support bp_gnu_ifunc_resolver and
|
||||
bp_gnu_ifunc_resolver_return.
|
||||
(add_location_to_breakpoint): Set EXPLICIT_LOC for
|
||||
set_breakpoint_location_function.
|
||||
(update_breakpoint_locations): Remove static.
|
||||
(breakpoint_re_set_one): Support bp_gnu_ifunc_resolver and
|
||||
bp_gnu_ifunc_resolver_return.
|
||||
* breakpoint.h (enum bptype): New fields bp_gnu_ifunc_resolver and
|
||||
bp_gnu_ifunc_resolver_return.
|
||||
(update_breakpoint_locations): New declaration.
|
||||
* elfread.c: Include gdbthread.h and regcache.h.
|
||||
(elf_gnu_ifunc_resolver_stop, elf_gnu_ifunc_resolver_return_stop): New
|
||||
functions.
|
||||
(elf_gnu_ifunc_fns): Install them.
|
||||
* minsyms.c (stub_gnu_ifunc_resolver_stop)
|
||||
(stub_gnu_ifunc_resolver_return_stop): New functions.
|
||||
(stub_gnu_ifunc_fns): Install them.
|
||||
* symtab.h (struct gnu_ifunc_fns): New fields gnu_ifunc_resolver_stop
|
||||
and gnu_ifunc_resolver_return_stop.
|
||||
(gnu_ifunc_resolver_stop, gnu_ifunc_resolver_return_stop): New.
|
||||
|
||||
2011-03-28 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
STT_GNU_IFUNC reader implementation.
|
||||
|
@ -3504,6 +3504,8 @@ print_it_typical (bpstat bs)
|
||||
case bp_tracepoint:
|
||||
case bp_fast_tracepoint:
|
||||
case bp_jit_event:
|
||||
case bp_gnu_ifunc_resolver:
|
||||
case bp_gnu_ifunc_resolver_return:
|
||||
default:
|
||||
result = PRINT_UNKNOWN;
|
||||
break;
|
||||
@ -4378,7 +4380,7 @@ handle_jit_event (void)
|
||||
/* Decide what infrun needs to do with this bpstat. */
|
||||
|
||||
struct bpstat_what
|
||||
bpstat_what (bpstat bs)
|
||||
bpstat_what (bpstat bs_head)
|
||||
{
|
||||
struct bpstat_what retval;
|
||||
/* We need to defer calling `solib_add', as adding new symbols
|
||||
@ -4386,12 +4388,13 @@ bpstat_what (bpstat bs)
|
||||
and hence may clear unprocessed entries in the BS chain. */
|
||||
int shlib_event = 0;
|
||||
int jit_event = 0;
|
||||
bpstat bs;
|
||||
|
||||
retval.main_action = BPSTAT_WHAT_KEEP_CHECKING;
|
||||
retval.call_dummy = STOP_NONE;
|
||||
retval.is_longjmp = 0;
|
||||
|
||||
for (; bs != NULL; bs = bs->next)
|
||||
for (bs = bs_head; bs != NULL; bs = bs->next)
|
||||
{
|
||||
/* Extract this BS's action. After processing each BS, we check
|
||||
if its action overrides all we've seem so far. */
|
||||
@ -4521,6 +4524,16 @@ bpstat_what (bpstat bs)
|
||||
out already. */
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("bpstat_what: tracepoint encountered"));
|
||||
break;
|
||||
case bp_gnu_ifunc_resolver:
|
||||
/* Step over it (and insert bp_gnu_ifunc_resolver_return). */
|
||||
this_action = BPSTAT_WHAT_SINGLE;
|
||||
break;
|
||||
case bp_gnu_ifunc_resolver_return:
|
||||
/* The breakpoint will be removed, execution will restart from the
|
||||
PC of the former breakpoint. */
|
||||
this_action = BPSTAT_WHAT_KEEP_CHECKING;
|
||||
break;
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("bpstat_what: unhandled bptype %d"), (int) bptype);
|
||||
@ -4529,6 +4542,9 @@ bpstat_what (bpstat bs)
|
||||
retval.main_action = max (retval.main_action, this_action);
|
||||
}
|
||||
|
||||
/* These operations may affect the bs->breakpoint_at state so they are
|
||||
delayed after MAIN_ACTION is decided above. */
|
||||
|
||||
if (shlib_event)
|
||||
{
|
||||
if (debug_infrun)
|
||||
@ -4558,6 +4574,23 @@ bpstat_what (bpstat bs)
|
||||
handle_jit_event ();
|
||||
}
|
||||
|
||||
for (bs = bs_head; bs != NULL; bs = bs->next)
|
||||
{
|
||||
struct breakpoint *b = bs->breakpoint_at;
|
||||
|
||||
if (b == NULL)
|
||||
continue;
|
||||
switch (b->type)
|
||||
{
|
||||
case bp_gnu_ifunc_resolver:
|
||||
gnu_ifunc_resolver_stop (b);
|
||||
break;
|
||||
case bp_gnu_ifunc_resolver_return:
|
||||
gnu_ifunc_resolver_return_stop (b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -4715,6 +4748,8 @@ bptype_string (enum bptype type)
|
||||
{bp_fast_tracepoint, "fast tracepoint"},
|
||||
{bp_static_tracepoint, "static tracepoint"},
|
||||
{bp_jit_event, "jit events"},
|
||||
{bp_gnu_ifunc_resolver, "STT_GNU_IFUNC resolver"},
|
||||
{bp_gnu_ifunc_resolver_return, "STT_GNU_IFUNC resolver return"},
|
||||
};
|
||||
|
||||
if (((int) type >= (sizeof (bptypes) / sizeof (bptypes[0])))
|
||||
@ -4849,6 +4884,8 @@ print_one_breakpoint_location (struct breakpoint *b,
|
||||
case bp_fast_tracepoint:
|
||||
case bp_static_tracepoint:
|
||||
case bp_jit_event:
|
||||
case bp_gnu_ifunc_resolver:
|
||||
case bp_gnu_ifunc_resolver_return:
|
||||
if (opts.addressprint)
|
||||
{
|
||||
annotate_field (4);
|
||||
@ -5124,7 +5161,8 @@ user_settable_breakpoint (const struct breakpoint *b)
|
||||
|| b->type == bp_catchpoint
|
||||
|| b->type == bp_hardware_breakpoint
|
||||
|| is_tracepoint (b)
|
||||
|| is_watchpoint (b));
|
||||
|| is_watchpoint (b)
|
||||
|| b->type == bp_gnu_ifunc_resolver);
|
||||
}
|
||||
|
||||
/* Return true if this breakpoint was set by the user, false if it is
|
||||
@ -5620,6 +5658,8 @@ allocate_bp_location (struct breakpoint *bpt)
|
||||
case bp_longjmp_master:
|
||||
case bp_std_terminate_master:
|
||||
case bp_exception_master:
|
||||
case bp_gnu_ifunc_resolver:
|
||||
case bp_gnu_ifunc_resolver_return:
|
||||
loc->loc_type = bp_loc_software_breakpoint;
|
||||
break;
|
||||
case bp_hardware_breakpoint:
|
||||
@ -5726,9 +5766,12 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
|
||||
return b;
|
||||
}
|
||||
|
||||
/* Initialize loc->function_name. */
|
||||
/* Initialize loc->function_name. EXPLICIT_LOC says no indirect function
|
||||
resolutions should be made as the user specified the location explicitly
|
||||
enough. */
|
||||
|
||||
static void
|
||||
set_breakpoint_location_function (struct bp_location *loc)
|
||||
set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
|
||||
{
|
||||
gdb_assert (loc->owner != NULL);
|
||||
|
||||
@ -5736,8 +5779,33 @@ set_breakpoint_location_function (struct bp_location *loc)
|
||||
|| loc->owner->type == bp_hardware_breakpoint
|
||||
|| is_tracepoint (loc->owner))
|
||||
{
|
||||
find_pc_partial_function (loc->address, &(loc->function_name),
|
||||
NULL, NULL);
|
||||
int is_gnu_ifunc;
|
||||
|
||||
find_pc_partial_function_gnu_ifunc (loc->address, &loc->function_name,
|
||||
NULL, NULL, &is_gnu_ifunc);
|
||||
|
||||
if (is_gnu_ifunc && !explicit_loc)
|
||||
{
|
||||
struct breakpoint *b = loc->owner;
|
||||
|
||||
gdb_assert (loc->pspace == current_program_space);
|
||||
if (gnu_ifunc_resolve_name (loc->function_name,
|
||||
&loc->requested_address))
|
||||
{
|
||||
/* Recalculate ADDRESS based on new REQUESTED_ADDRESS. */
|
||||
loc->address = adjust_breakpoint_address (loc->gdbarch,
|
||||
loc->requested_address,
|
||||
b->type);
|
||||
}
|
||||
else if (b->type == bp_breakpoint && b->loc == loc
|
||||
&& loc->next == NULL && b->related_breakpoint == b)
|
||||
{
|
||||
/* Create only the whole new breakpoint of this type but do not
|
||||
mess more complicated breakpoints with multiple locations. */
|
||||
b->type = bp_gnu_ifunc_resolver;
|
||||
}
|
||||
}
|
||||
|
||||
if (loc->function_name)
|
||||
loc->function_name = xstrdup (loc->function_name);
|
||||
}
|
||||
@ -5812,7 +5880,8 @@ set_raw_breakpoint (struct gdbarch *gdbarch,
|
||||
b->loc->section = sal.section;
|
||||
b->line_number = sal.line;
|
||||
|
||||
set_breakpoint_location_function (b->loc);
|
||||
set_breakpoint_location_function (b->loc,
|
||||
sal.explicit_pc || sal.explicit_line);
|
||||
|
||||
breakpoints_changed ();
|
||||
|
||||
@ -6929,7 +6998,7 @@ clone_momentary_breakpoint (struct breakpoint *orig)
|
||||
|
||||
copy = set_raw_breakpoint_without_location (orig->gdbarch, orig->type);
|
||||
copy->loc = allocate_bp_location (copy);
|
||||
set_breakpoint_location_function (copy->loc);
|
||||
set_breakpoint_location_function (copy->loc, 1);
|
||||
|
||||
copy->loc->gdbarch = orig->loc->gdbarch;
|
||||
copy->loc->requested_address = orig->loc->requested_address;
|
||||
@ -7029,6 +7098,7 @@ mention (struct breakpoint *b)
|
||||
do_cleanups (ui_out_chain);
|
||||
break;
|
||||
case bp_breakpoint:
|
||||
case bp_gnu_ifunc_resolver:
|
||||
if (ui_out_is_mi_like_p (uiout))
|
||||
{
|
||||
say_where = 0;
|
||||
@ -7039,6 +7109,8 @@ mention (struct breakpoint *b)
|
||||
else
|
||||
printf_filtered (_("Breakpoint"));
|
||||
printf_filtered (_(" %d"), b->number);
|
||||
if (b->type == bp_gnu_ifunc_resolver)
|
||||
printf_filtered (_(" at gnu-indirect-function resolver"));
|
||||
say_where = 1;
|
||||
break;
|
||||
case bp_hardware_breakpoint:
|
||||
@ -7098,6 +7170,7 @@ mention (struct breakpoint *b)
|
||||
case bp_longjmp_master:
|
||||
case bp_std_terminate_master:
|
||||
case bp_exception_master:
|
||||
case bp_gnu_ifunc_resolver_return:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -7158,7 +7231,8 @@ add_location_to_breakpoint (struct breakpoint *b,
|
||||
gdb_assert (loc->pspace != NULL);
|
||||
loc->section = sal->section;
|
||||
|
||||
set_breakpoint_location_function (loc);
|
||||
set_breakpoint_location_function (loc,
|
||||
sal->explicit_pc || sal->explicit_line);
|
||||
return loc;
|
||||
}
|
||||
|
||||
@ -10399,7 +10473,7 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
|
||||
return sal;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
update_breakpoint_locations (struct breakpoint *b,
|
||||
struct symtabs_and_lines sals)
|
||||
{
|
||||
@ -10531,6 +10605,7 @@ breakpoint_re_set_one (void *bint)
|
||||
case bp_tracepoint:
|
||||
case bp_fast_tracepoint:
|
||||
case bp_static_tracepoint:
|
||||
case bp_gnu_ifunc_resolver:
|
||||
/* Do not attempt to re-set breakpoints disabled during startup. */
|
||||
if (b->enable_state == bp_startup_disabled)
|
||||
return 0;
|
||||
@ -10701,6 +10776,7 @@ breakpoint_re_set_one (void *bint)
|
||||
case bp_exception:
|
||||
case bp_exception_resume:
|
||||
case bp_jit_event:
|
||||
case bp_gnu_ifunc_resolver_return:
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -149,6 +149,19 @@ enum bptype
|
||||
|
||||
/* Event for JIT compiled code generation or deletion. */
|
||||
bp_jit_event,
|
||||
|
||||
/* Breakpoint is placed at the STT_GNU_IFUNC resolver. When hit GDB
|
||||
inserts new bp_gnu_ifunc_resolver_return at the caller.
|
||||
bp_gnu_ifunc_resolver is still being kept here as a different thread
|
||||
may still hit it before bp_gnu_ifunc_resolver_return is hit by the
|
||||
original thread. */
|
||||
bp_gnu_ifunc_resolver,
|
||||
|
||||
/* On its hit GDB now know the resolved address of the target
|
||||
STT_GNU_IFUNC function. Associated bp_gnu_ifunc_resolver can be
|
||||
deleted now and the breakpoint moved to the target function entry
|
||||
point. */
|
||||
bp_gnu_ifunc_resolver_return,
|
||||
};
|
||||
|
||||
/* States of enablement of breakpoint. */
|
||||
@ -890,6 +903,9 @@ extern int breakpoint_thread_match (struct address_space *,
|
||||
|
||||
extern void until_break_command (char *, int, int);
|
||||
|
||||
extern void update_breakpoint_locations (struct breakpoint *b,
|
||||
struct symtabs_and_lines sals);
|
||||
|
||||
extern void breakpoint_re_set (void);
|
||||
|
||||
extern void breakpoint_re_set_thread (struct breakpoint *);
|
||||
|
109
gdb/elfread.c
109
gdb/elfread.c
@ -41,6 +41,8 @@
|
||||
#include "gdbtypes.h"
|
||||
#include "value.h"
|
||||
#include "infcall.h"
|
||||
#include "gdbthread.h"
|
||||
#include "regcache.h"
|
||||
|
||||
extern void _initialize_elfread (void);
|
||||
|
||||
@ -948,6 +950,111 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
return address;
|
||||
}
|
||||
|
||||
/* Handle inferior hit of bp_gnu_ifunc_resolver, see its definition. */
|
||||
|
||||
static void
|
||||
elf_gnu_ifunc_resolver_stop (struct breakpoint *b)
|
||||
{
|
||||
struct breakpoint *b_return;
|
||||
struct frame_info *prev_frame = get_prev_frame (get_current_frame ());
|
||||
struct frame_id prev_frame_id = get_stack_frame_id (prev_frame);
|
||||
CORE_ADDR prev_pc = get_frame_pc (prev_frame);
|
||||
int thread_id = pid_to_thread_id (inferior_ptid);
|
||||
|
||||
gdb_assert (b->type == bp_gnu_ifunc_resolver);
|
||||
|
||||
for (b_return = b->related_breakpoint; b_return != b;
|
||||
b_return = b_return->related_breakpoint)
|
||||
{
|
||||
gdb_assert (b_return->type == bp_gnu_ifunc_resolver_return);
|
||||
gdb_assert (b_return->loc != NULL && b_return->loc->next == NULL);
|
||||
gdb_assert (frame_id_p (b_return->frame_id));
|
||||
|
||||
if (b_return->thread == thread_id
|
||||
&& b_return->loc->requested_address == prev_pc
|
||||
&& frame_id_eq (b_return->frame_id, prev_frame_id))
|
||||
break;
|
||||
}
|
||||
|
||||
if (b_return == b)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
|
||||
/* No need to call find_pc_line for symbols resolving as this is only
|
||||
a helper breakpointer never shown to the user. */
|
||||
|
||||
init_sal (&sal);
|
||||
sal.pspace = current_inferior ()->pspace;
|
||||
sal.pc = prev_pc;
|
||||
sal.section = find_pc_overlay (sal.pc);
|
||||
sal.explicit_pc = 1;
|
||||
b_return = set_momentary_breakpoint (get_frame_arch (prev_frame), sal,
|
||||
prev_frame_id,
|
||||
bp_gnu_ifunc_resolver_return);
|
||||
|
||||
/* Add new b_return to the ring list b->related_breakpoint. */
|
||||
gdb_assert (b_return->related_breakpoint == b_return);
|
||||
b_return->related_breakpoint = b->related_breakpoint;
|
||||
b->related_breakpoint = b_return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle inferior hit of bp_gnu_ifunc_resolver_return, see its definition. */
|
||||
|
||||
static void
|
||||
elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
|
||||
struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func;
|
||||
struct type *value_type = TYPE_TARGET_TYPE (func_func_type);
|
||||
struct regcache *regcache = get_thread_regcache (inferior_ptid);
|
||||
struct value *value;
|
||||
CORE_ADDR resolved_address, resolved_pc;
|
||||
struct symtab_and_line sal;
|
||||
struct symtabs_and_lines sals;
|
||||
|
||||
gdb_assert (b->type == bp_gnu_ifunc_resolver_return);
|
||||
|
||||
value = allocate_value (value_type);
|
||||
gdbarch_return_value (gdbarch, func_func_type, value_type, regcache,
|
||||
value_contents_raw (value), NULL);
|
||||
resolved_address = value_as_address (value);
|
||||
resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
|
||||
resolved_address,
|
||||
¤t_target);
|
||||
|
||||
while (b->related_breakpoint != b)
|
||||
{
|
||||
struct breakpoint *b_next = b->related_breakpoint;
|
||||
|
||||
switch (b->type)
|
||||
{
|
||||
case bp_gnu_ifunc_resolver:
|
||||
break;
|
||||
case bp_gnu_ifunc_resolver_return:
|
||||
delete_breakpoint (b);
|
||||
break;
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("handle_inferior_event: Invalid "
|
||||
"gnu-indirect-function breakpoint type %d"),
|
||||
(int) b->type);
|
||||
}
|
||||
b = b_next;
|
||||
}
|
||||
gdb_assert (b->type == bp_gnu_ifunc_resolver);
|
||||
|
||||
gdb_assert (current_program_space == b->pspace);
|
||||
elf_gnu_ifunc_record_cache (b->addr_string, resolved_pc);
|
||||
|
||||
sal = find_pc_line (resolved_pc, 0);
|
||||
sals.nelts = 1;
|
||||
sals.sals = &sal;
|
||||
|
||||
b->type = bp_breakpoint;
|
||||
update_breakpoint_locations (b, sals);
|
||||
}
|
||||
|
||||
struct build_id
|
||||
{
|
||||
size_t size;
|
||||
@ -1502,6 +1609,8 @@ static const struct gnu_ifunc_fns elf_gnu_ifunc_fns =
|
||||
{
|
||||
elf_gnu_ifunc_resolve_addr,
|
||||
elf_gnu_ifunc_resolve_name,
|
||||
elf_gnu_ifunc_resolver_stop,
|
||||
elf_gnu_ifunc_resolver_return_stop
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -729,12 +729,32 @@ stub_gnu_ifunc_resolve_name (const char *function_name,
|
||||
function_name);
|
||||
}
|
||||
|
||||
/* See elf_gnu_ifunc_resolver_stop for its real implementation. */
|
||||
|
||||
static void
|
||||
stub_gnu_ifunc_resolver_stop (struct breakpoint *b)
|
||||
{
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("elf_gnu_ifunc_resolver_stop cannot be reached."));
|
||||
}
|
||||
|
||||
/* See elf_gnu_ifunc_resolver_return_stop for its real implementation. */
|
||||
|
||||
static void
|
||||
stub_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
|
||||
{
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("elf_gnu_ifunc_resolver_return_stop cannot be reached."));
|
||||
}
|
||||
|
||||
/* See elf_gnu_ifunc_fns for its real implementation. */
|
||||
|
||||
static const struct gnu_ifunc_fns stub_gnu_ifunc_fns =
|
||||
{
|
||||
stub_gnu_ifunc_resolve_addr,
|
||||
stub_gnu_ifunc_resolve_name,
|
||||
stub_gnu_ifunc_resolver_stop,
|
||||
stub_gnu_ifunc_resolver_return_stop,
|
||||
};
|
||||
|
||||
/* A placeholder for &elf_gnu_ifunc_fns. */
|
||||
|
@ -1055,10 +1055,19 @@ struct gnu_ifunc_fns
|
||||
/* See elf_gnu_ifunc_resolve_name for its real implementation. */
|
||||
int (*gnu_ifunc_resolve_name) (const char *function_name,
|
||||
CORE_ADDR *function_address_p);
|
||||
|
||||
/* See elf_gnu_ifunc_resolver_stop for its real implementation. */
|
||||
void (*gnu_ifunc_resolver_stop) (struct breakpoint *b);
|
||||
|
||||
/* See elf_gnu_ifunc_resolver_return_stop for its real implementation. */
|
||||
void (*gnu_ifunc_resolver_return_stop) (struct breakpoint *b);
|
||||
};
|
||||
|
||||
#define gnu_ifunc_resolve_addr gnu_ifunc_fns_p->gnu_ifunc_resolve_addr
|
||||
#define gnu_ifunc_resolve_name gnu_ifunc_fns_p->gnu_ifunc_resolve_name
|
||||
#define gnu_ifunc_resolver_stop gnu_ifunc_fns_p->gnu_ifunc_resolver_stop
|
||||
#define gnu_ifunc_resolver_return_stop \
|
||||
gnu_ifunc_fns_p->gnu_ifunc_resolver_return_stop
|
||||
|
||||
extern const struct gnu_ifunc_fns *gnu_ifunc_fns_p;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user