X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Ftracepoint.c;h=5fb8a5134ba3d5fa46e4328fb7ea19426e90571e;hb=be6d4f74c77c6f521afc873d226480e001cb99c2;hp=0671999ef90df3e6652e1def56ab711140c40389;hpb=99e8eb11cfcdde8cba6755ed4613c3cb079dfaa4;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index 0671999ef9..5fb8a5134b 100644 --- a/gdb/gdbserver/tracepoint.c +++ b/gdb/gdbserver/tracepoint.c @@ -1,5 +1,5 @@ /* Tracepoint code for remote server for GDB. - Copyright (C) 2009-2016 Free Software Foundation, Inc. + Copyright (C) 2009-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -19,17 +19,19 @@ #include "server.h" #include "tracepoint.h" #include "gdbthread.h" -#include "agent.h" #include "rsp-low.h" #include #include #include -#include "gdb_sys_time.h" +#include #include #include "ax.h" #include "tdesc.h" +#define IPA_SYM_STRUCT_NAME ipa_sym_addresses +#include "agent.h" + #define DEFAULT_TRACE_BUFFER_SIZE 5242880 /* 5*1024*1024 */ /* This file is built for both GDBserver, and the in-process @@ -108,7 +110,7 @@ trace_vdebug (const char *fmt, ...) # define gdb_trampoline_buffer_end IPA_SYM_EXPORTED_NAME (gdb_trampoline_buffer_end) # define gdb_trampoline_buffer_error IPA_SYM_EXPORTED_NAME (gdb_trampoline_buffer_error) # define collecting IPA_SYM_EXPORTED_NAME (collecting) -# define gdb_collect IPA_SYM_EXPORTED_NAME (gdb_collect) +# define gdb_collect_ptr IPA_SYM_EXPORTED_NAME (gdb_collect_ptr) # define stop_tracing IPA_SYM_EXPORTED_NAME (stop_tracing) # define flush_trace_buffer IPA_SYM_EXPORTED_NAME (flush_trace_buffer) # define about_to_request_buffer_space IPA_SYM_EXPORTED_NAME (about_to_request_buffer_space) @@ -126,14 +128,15 @@ trace_vdebug (const char *fmt, ...) # define traceframe_write_count IPA_SYM_EXPORTED_NAME (traceframe_write_count) # define traceframes_created IPA_SYM_EXPORTED_NAME (traceframes_created) # define trace_state_variables IPA_SYM_EXPORTED_NAME (trace_state_variables) -# define get_raw_reg IPA_SYM_EXPORTED_NAME (get_raw_reg) -# define get_trace_state_variable_value \ - IPA_SYM_EXPORTED_NAME (get_trace_state_variable_value) -# define set_trace_state_variable_value \ - IPA_SYM_EXPORTED_NAME (set_trace_state_variable_value) +# define get_raw_reg_ptr IPA_SYM_EXPORTED_NAME (get_raw_reg_ptr) +# define get_trace_state_variable_value_ptr \ + IPA_SYM_EXPORTED_NAME (get_trace_state_variable_value_ptr) +# define set_trace_state_variable_value_ptr \ + IPA_SYM_EXPORTED_NAME (set_trace_state_variable_value_ptr) # define ust_loaded IPA_SYM_EXPORTED_NAME (ust_loaded) # define helper_thread_id IPA_SYM_EXPORTED_NAME (helper_thread_id) # define cmd_buf IPA_SYM_EXPORTED_NAME (cmd_buf) +# define ipa_tdesc_idx IPA_SYM_EXPORTED_NAME (ipa_tdesc_idx) #endif #ifndef IN_PROCESS_AGENT @@ -149,7 +152,7 @@ struct ipa_sym_addresses CORE_ADDR addr_gdb_trampoline_buffer_end; CORE_ADDR addr_gdb_trampoline_buffer_error; CORE_ADDR addr_collecting; - CORE_ADDR addr_gdb_collect; + CORE_ADDR addr_gdb_collect_ptr; CORE_ADDR addr_stop_tracing; CORE_ADDR addr_flush_trace_buffer; CORE_ADDR addr_about_to_request_buffer_space; @@ -167,10 +170,11 @@ struct ipa_sym_addresses CORE_ADDR addr_traceframe_write_count; CORE_ADDR addr_traceframes_created; CORE_ADDR addr_trace_state_variables; - CORE_ADDR addr_get_raw_reg; - CORE_ADDR addr_get_trace_state_variable_value; - CORE_ADDR addr_set_trace_state_variable_value; + CORE_ADDR addr_get_raw_reg_ptr; + CORE_ADDR addr_get_trace_state_variable_value_ptr; + CORE_ADDR addr_set_trace_state_variable_value_ptr; CORE_ADDR addr_ust_loaded; + CORE_ADDR addr_ipa_tdesc_idx; }; static struct @@ -185,7 +189,7 @@ static struct IPA_SYM(gdb_trampoline_buffer_end), IPA_SYM(gdb_trampoline_buffer_error), IPA_SYM(collecting), - IPA_SYM(gdb_collect), + IPA_SYM(gdb_collect_ptr), IPA_SYM(stop_tracing), IPA_SYM(flush_trace_buffer), IPA_SYM(about_to_request_buffer_space), @@ -203,10 +207,11 @@ static struct IPA_SYM(traceframe_write_count), IPA_SYM(traceframes_created), IPA_SYM(trace_state_variables), - IPA_SYM(get_raw_reg), - IPA_SYM(get_trace_state_variable_value), - IPA_SYM(set_trace_state_variable_value), + IPA_SYM(get_raw_reg_ptr), + IPA_SYM(get_trace_state_variable_value_ptr), + IPA_SYM(set_trace_state_variable_value_ptr), IPA_SYM(ust_loaded), + IPA_SYM(ipa_tdesc_idx), }; static struct ipa_sym_addresses ipa_sym_addrs; @@ -445,6 +450,12 @@ write_inferior_integer (CORE_ADDR symaddr, int val) return write_inferior_memory (symaddr, (unsigned char *) &val, sizeof (val)); } +static int +write_inferior_int8 (CORE_ADDR symaddr, int8_t val) +{ + return write_inferior_memory (symaddr, (unsigned char *) &val, sizeof (val)); +} + static int write_inferior_uinteger (CORE_ADDR symaddr, unsigned int val) { @@ -452,7 +463,6 @@ write_inferior_uinteger (CORE_ADDR symaddr, unsigned int val) } static CORE_ADDR target_malloc (ULONGEST size); -static int write_inferior_data_ptr (CORE_ADDR where, CORE_ADDR ptr); #define COPY_FIELD_TO_BUF(BUF, OBJ, FIELD) \ do { \ @@ -462,28 +472,10 @@ static int write_inferior_data_ptr (CORE_ADDR where, CORE_ADDR ptr); #endif -/* Operations on various types of tracepoint actions. */ - -struct tracepoint_action; - -struct tracepoint_action_ops -{ - /* Download tracepoint action ACTION to IPA. Return the address of action - in IPA/inferior. */ - CORE_ADDR (*download) (const struct tracepoint_action *action); - - /* Send ACTION to agent via command buffer started from BUFFER. Return - updated head of command buffer. */ - char* (*send) (char *buffer, const struct tracepoint_action *action); -}; - /* Base action. Concrete actions inherit this. */ struct tracepoint_action { -#ifndef IN_PROCESS_AGENT - const struct tracepoint_action_ops *ops; -#endif char type; }; @@ -523,12 +515,10 @@ struct collect_static_trace_data_action static CORE_ADDR m_tracepoint_action_download (const struct tracepoint_action *action) { - int size_in_ipa = (sizeof (struct collect_memory_action) - - offsetof (struct tracepoint_action, type)); - CORE_ADDR ipa_action = target_malloc (size_in_ipa); + CORE_ADDR ipa_action = target_malloc (sizeof (struct collect_memory_action)); - write_inferior_memory (ipa_action, (unsigned char *) &action->type, - size_in_ipa); + write_inferior_memory (ipa_action, (unsigned char *) action, + sizeof (struct collect_memory_action)); return ipa_action; } @@ -545,21 +535,13 @@ m_tracepoint_action_send (char *buffer, const struct tracepoint_action *action) return buffer; } -static const struct tracepoint_action_ops m_tracepoint_action_ops = -{ - m_tracepoint_action_download, - m_tracepoint_action_send, -}; - static CORE_ADDR r_tracepoint_action_download (const struct tracepoint_action *action) { - int size_in_ipa = (sizeof (struct collect_registers_action) - - offsetof (struct tracepoint_action, type)); - CORE_ADDR ipa_action = target_malloc (size_in_ipa); + CORE_ADDR ipa_action = target_malloc (sizeof (struct collect_registers_action)); - write_inferior_memory (ipa_action, (unsigned char *) &action->type, - size_in_ipa); + write_inferior_memory (ipa_action, (unsigned char *) action, + sizeof (struct collect_registers_action)); return ipa_action; } @@ -570,28 +552,20 @@ r_tracepoint_action_send (char *buffer, const struct tracepoint_action *action) return buffer; } -static const struct tracepoint_action_ops r_tracepoint_action_ops = -{ - r_tracepoint_action_download, - r_tracepoint_action_send, -}; - static CORE_ADDR download_agent_expr (struct agent_expr *expr); static CORE_ADDR x_tracepoint_action_download (const struct tracepoint_action *action) { - int size_in_ipa = (sizeof (struct eval_expr_action) - - offsetof (struct tracepoint_action, type)); - CORE_ADDR ipa_action = target_malloc (size_in_ipa); + CORE_ADDR ipa_action = target_malloc (sizeof (struct eval_expr_action)); CORE_ADDR expr; - write_inferior_memory (ipa_action, (unsigned char *) &action->type, - size_in_ipa); - expr = download_agent_expr (((struct eval_expr_action *)action)->expr); - write_inferior_data_ptr (ipa_action + offsetof (struct eval_expr_action, expr) - - offsetof (struct tracepoint_action, type), - expr); + write_inferior_memory (ipa_action, (unsigned char *) action, + sizeof (struct eval_expr_action)); + expr = download_agent_expr (((struct eval_expr_action *) action)->expr); + write_inferior_data_pointer (ipa_action + + offsetof (struct eval_expr_action, expr), + expr); return ipa_action; } @@ -628,21 +602,14 @@ x_tracepoint_action_send ( char *buffer, const struct tracepoint_action *action) return agent_expr_send (buffer, eaction->expr); } -static const struct tracepoint_action_ops x_tracepoint_action_ops = -{ - x_tracepoint_action_download, - x_tracepoint_action_send, -}; - static CORE_ADDR l_tracepoint_action_download (const struct tracepoint_action *action) { - int size_in_ipa = (sizeof (struct collect_static_trace_data_action) - - offsetof (struct tracepoint_action, type)); - CORE_ADDR ipa_action = target_malloc (size_in_ipa); + CORE_ADDR ipa_action + = target_malloc (sizeof (struct collect_static_trace_data_action)); - write_inferior_memory (ipa_action, (unsigned char *) &action->type, - size_in_ipa); + write_inferior_memory (ipa_action, (unsigned char *) action, + sizeof (struct collect_static_trace_data_action)); return ipa_action; } @@ -653,11 +620,39 @@ l_tracepoint_action_send (char *buffer, const struct tracepoint_action *action) return buffer; } -static const struct tracepoint_action_ops l_tracepoint_action_ops = +static char * +tracepoint_action_send (char *buffer, const struct tracepoint_action *action) { - l_tracepoint_action_download, - l_tracepoint_action_send, -}; + switch (action->type) + { + case 'M': + return m_tracepoint_action_send (buffer, action); + case 'R': + return r_tracepoint_action_send (buffer, action); + case 'X': + return x_tracepoint_action_send (buffer, action); + case 'L': + return l_tracepoint_action_send (buffer, action); + } + error ("Unknown trace action '%c'.", action->type); +} + +static CORE_ADDR +tracepoint_action_download (const struct tracepoint_action *action) +{ + switch (action->type) + { + case 'M': + return m_tracepoint_action_download (action); + case 'R': + return r_tracepoint_action_download (action); + case 'X': + return x_tracepoint_action_download (action); + case 'L': + return l_tracepoint_action_download (action); + } + error ("Unknown trace action '%c'.", action->type); +} #endif /* This structure describes a piece of the source-level definition of @@ -980,11 +975,6 @@ struct traceframe fields (and no data) marks the end of trace data. */ #define TRACEFRAME_EOB_MARKER_SIZE offsetof (struct traceframe, data) -/* The traceframe to be used as the source of data to send back to - GDB. A value of -1 means to get data from the live program. */ - -int current_traceframe = -1; - /* This flag is true if the trace buffer is circular, meaning that when it fills, the oldest trace frames are discarded in order to make room. */ @@ -1917,9 +1907,9 @@ find_next_tracepoint_by_number (struct tracepoint *prev_tp, int num) /* Append another action to perform when the tracepoint triggers. */ static void -add_tracepoint_action (struct tracepoint *tpoint, char *packet) +add_tracepoint_action (struct tracepoint *tpoint, const char *packet) { - char *act; + const char *act; if (*packet == 'S') { @@ -1931,7 +1921,7 @@ add_tracepoint_action (struct tracepoint *tpoint, char *packet) while (*act) { - char *act_start = act; + const char *act_start = act; struct tracepoint_action *action = NULL; switch (*act) @@ -1944,7 +1934,6 @@ add_tracepoint_action (struct tracepoint *tpoint, char *packet) int is_neg; maction->base.type = *act; - maction->base.ops = &m_tracepoint_action_ops; action = &maction->base; ++act; @@ -1970,7 +1959,6 @@ add_tracepoint_action (struct tracepoint *tpoint, char *packet) XNEW (struct collect_registers_action); raction->base.type = *act; - raction->base.ops = &r_tracepoint_action_ops; action = &raction->base; trace_debug ("Want to collect registers"); @@ -1986,7 +1974,6 @@ add_tracepoint_action (struct tracepoint *tpoint, char *packet) XNEW (struct collect_static_trace_data_action); raction->base.type = *act; - raction->base.ops = &l_tracepoint_action_ops; action = &raction->base; trace_debug ("Want to collect static trace data"); @@ -2002,7 +1989,6 @@ add_tracepoint_action (struct tracepoint *tpoint, char *packet) struct eval_expr_action *xaction = XNEW (struct eval_expr_action); xaction->base.type = *act; - xaction->base.ops = &x_tracepoint_action_ops; action = &xaction->base; trace_debug ("Want to evaluate expression"); @@ -2290,10 +2276,11 @@ static struct traceframe * find_next_traceframe_in_range (CORE_ADDR lo, CORE_ADDR hi, int inside_p, int *tfnump) { + client_state &cs = get_client_state (); struct traceframe *tframe; CORE_ADDR tfaddr; - *tfnump = current_traceframe + 1; + *tfnump = cs.current_traceframe + 1; tframe = find_traceframe (*tfnump); /* The search is not supposed to wrap around. */ if (!tframe) @@ -2323,9 +2310,10 @@ find_next_traceframe_in_range (CORE_ADDR lo, CORE_ADDR hi, int inside_p, static struct traceframe * find_next_traceframe_by_tracepoint (int num, int *tfnump) { + client_state &cs = get_client_state (); struct traceframe *tframe; - *tfnump = current_traceframe + 1; + *tfnump = cs.current_traceframe + 1; tframe = find_traceframe (*tfnump); /* The search is not supposed to wrap around. */ if (!tframe) @@ -2354,6 +2342,7 @@ find_next_traceframe_by_tracepoint (int num, int *tfnump) static void cmd_qtinit (char *packet) { + client_state &cs = get_client_state (); struct trace_state_variable *tsv, *prev, *next; /* Can't do this command without a pid attached. */ @@ -2364,7 +2353,7 @@ cmd_qtinit (char *packet) } /* Make sure we don't try to read from a trace frame. */ - current_traceframe = -1; + cs.current_traceframe = -1; stop_tracing (); @@ -2496,8 +2485,7 @@ cmd_qtdp (char *own_buf) ULONGEST addr; ULONGEST count; struct tracepoint *tpoint; - char *actparm; - char *packet = own_buf; + const char *packet = own_buf; packet += strlen ("QTDP:"); @@ -2557,9 +2545,7 @@ cmd_qtdp (char *own_buf) } else if (*packet == 'X') { - actparm = (char *) packet; - tpoint->cond = gdb_parse_agent_expr (&actparm); - packet = actparm; + tpoint->cond = gdb_parse_agent_expr (&packet); } else if (*packet == '-') break; @@ -2668,8 +2654,9 @@ cmd_qtdpsrc (char *own_buf) { ULONGEST num, addr, start, slen; struct tracepoint *tpoint; - char *packet = own_buf; - char *saved, *srctype, *src; + const char *packet = own_buf; + const char *saved; + char *srctype, *src; size_t nbytes; struct source_string *last, *newlast; @@ -2731,7 +2718,7 @@ cmd_qtdv (char *own_buf) char *varname; size_t nbytes; struct trace_state_variable *tsv; - char *packet = own_buf; + const char *packet = own_buf; packet += strlen ("QTDV:"); @@ -2759,7 +2746,7 @@ cmd_qtdv (char *own_buf) static void cmd_qtenable_disable (char *own_buf, int enable) { - char *packet = own_buf; + const char *packet = own_buf; ULONGEST num, addr; struct tracepoint *tp; @@ -2800,8 +2787,8 @@ cmd_qtenable_disable (char *own_buf, int enable) write_enn (own_buf); return; } - - ret = write_inferior_integer (obj_addr, enable); + + ret = write_inferior_int8 (obj_addr, enable); done_accessing_memory (); if (ret) @@ -2826,6 +2813,7 @@ cmd_qtenable_disable (char *own_buf, int enable) static void cmd_qtv (char *own_buf) { + client_state &cs = get_client_state (); ULONGEST num; LONGEST val = 0; int err; @@ -2834,7 +2822,7 @@ cmd_qtv (char *own_buf) packet += strlen ("qTV:"); unpack_varlen_hex (packet, &num); - if (current_traceframe >= 0) + if (cs.current_traceframe >= 0) { err = traceframe_read_tsv ((int) num, &val); if (err) @@ -2881,7 +2869,7 @@ cmd_qtro (char *own_buf) { ULONGEST start, end; struct readonly_region *roreg; - char *packet = own_buf; + const char *packet = own_buf; trace_debug ("Want to mark readonly regions"); @@ -3085,6 +3073,7 @@ install_fast_tracepoint (struct tracepoint *tpoint, char *errbuf) { CORE_ADDR jentry, jump_entry; CORE_ADDR trampoline; + CORE_ADDR collect; ULONGEST trampoline_size; int err = 0; /* The jump to the jump pad of the last fast tracepoint @@ -3099,6 +3088,13 @@ install_fast_tracepoint (struct tracepoint *tpoint, char *errbuf) return 0; } + if (read_inferior_data_pointer (ipa_sym_addrs.addr_gdb_collect_ptr, + &collect)) + { + error ("error extracting gdb_collect_ptr"); + return 1; + } + jentry = jump_entry = get_jump_space_head (); trampoline = 0; @@ -3107,7 +3103,7 @@ install_fast_tracepoint (struct tracepoint *tpoint, char *errbuf) /* Install the jump pad. */ err = install_fast_tracepoint_jump_pad (tpoint->obj_addr_on_target, tpoint->address, - ipa_sym_addrs.addr_gdb_collect, + collect, ipa_sym_addrs.addr_collecting, tpoint->orig_size, &jentry, @@ -3231,9 +3227,17 @@ cmd_qtstart (char *packet) *packet = '\0'; + if (agent_loaded_p ()) + { + /* Tell IPA about the correct tdesc. */ + if (write_inferior_integer (ipa_sym_addrs.addr_ipa_tdesc_idx, + target_get_ipa_tdesc_idx ())) + error ("Error setting ipa_tdesc_idx variable in lib"); + } + /* Start out empty. */ if (agent_loaded_p ()) - write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, 0); + write_inferior_data_pointer (ipa_sym_addrs.addr_tracepoints, 0); /* Download and install tracepoints. */ for (tpoint = tracepoints; tpoint; tpoint = tpoint->next) @@ -3329,11 +3333,11 @@ cmd_qtstart (char *packet) if (tpoint == tracepoints) /* First object in list, set the head pointer in the inferior. */ - write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, tpptr); + write_inferior_data_pointer (ipa_sym_addrs.addr_tracepoints, tpptr); else - write_inferior_data_ptr (prev_tpptr + offsetof (struct tracepoint, - next), - tpptr); + write_inferior_data_pointer (prev_tpptr + + offsetof (struct tracepoint, next), + tpptr); } /* Any failure in the inner loop is sufficient cause to give @@ -3549,10 +3553,11 @@ cmd_qtdisconnected (char *own_buf) static void cmd_qtframe (char *own_buf) { + client_state &cs = get_client_state (); ULONGEST frame, pc, lo, hi, num; int tfnum, tpnum; struct traceframe *tframe; - char *packet = own_buf; + const char *packet = own_buf; packet += strlen ("QTFrame:"); @@ -3599,7 +3604,7 @@ cmd_qtframe (char *own_buf) if (tfnum == -1) { trace_debug ("Want to stop looking at traceframes"); - current_traceframe = -1; + cs.current_traceframe = -1; write_ok (own_buf); return; } @@ -3609,7 +3614,7 @@ cmd_qtframe (char *own_buf) if (tframe) { - current_traceframe = tfnum; + cs.current_traceframe = tfnum; sprintf (own_buf, "F%xT%x", tfnum, tframe->tpnum); } else @@ -3707,7 +3712,7 @@ cmd_qtp (char *own_buf) { ULONGEST num, addr; struct tracepoint *tpoint; - char *packet = own_buf; + const char *packet = own_buf; packet += strlen ("qTP:"); @@ -3951,17 +3956,6 @@ cmd_qtstmat (char *packet) run_inferior_command (packet, strlen (packet) + 1); } -/* Helper for gdb_agent_about_to_close. - Return non-zero if thread ENTRY is in the same process in DATA. */ - -static int -same_process_p (struct inferior_list_entry *entry, void *data) -{ - int *pid = (int *) data; - - return ptid_get_pid (entry->id) == *pid; -} - /* Sent the agent a command to close it. */ void @@ -3976,8 +3970,7 @@ gdb_agent_about_to_close (int pid) saved_thread = current_thread; /* Find any thread which belongs to process PID. */ - current_thread = (struct thread_info *) - find_inferior (&all_threads, same_process_p, &pid); + current_thread = find_any_thread_of_pid (pid); strcpy (buf, "close"); @@ -4012,7 +4005,7 @@ cmd_qtbuffer (char *own_buf) { ULONGEST offset, num, tot; unsigned char *tbp; - char *packet = own_buf; + const char *packet = own_buf; packet += strlen ("qTBuffer:"); @@ -4405,7 +4398,7 @@ tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc) wstep_link = &tinfo->while_stepping; trace_debug ("Thread %s finished a single-step for tracepoint %d at 0x%s", - target_pid_to_str (tinfo->entry.id), + target_pid_to_str (tinfo->id), wstep->tp_number, paddress (wstep->tp_address)); ctx.base.type = trap_tracepoint; @@ -4418,7 +4411,7 @@ tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc) { trace_debug ("NO TRACEPOINT %d at 0x%s FOR THREAD %s!", wstep->tp_number, paddress (wstep->tp_address), - target_pid_to_str (tinfo->entry.id)); + target_pid_to_str (tinfo->id)); /* Unlink. */ *wstep_link = wstep->next; @@ -4438,7 +4431,7 @@ tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc) { /* The requested numbers of steps have occurred. */ trace_debug ("Thread %s done stepping for tracepoint %d at 0x%s", - target_pid_to_str (tinfo->entry.id), + target_pid_to_str (tinfo->id), wstep->tp_number, paddress (wstep->tp_address)); /* Unlink the wstep. */ @@ -4529,7 +4522,7 @@ handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc) trace_debug ("lib stopped due to full buffer."); if (ipa_stopping_tracepoint) trace_debug ("lib stopped due to tpoint"); - if (ipa_stopping_tracepoint) + if (ipa_error_tracepoint) trace_debug ("lib stopped due to error"); } @@ -4585,7 +4578,7 @@ tracepoint_was_hit (struct thread_info *tinfo, CORE_ADDR stop_pc) && tpoint->type != static_tracepoint) { trace_debug ("Thread %s at address of tracepoint %d at 0x%s", - target_pid_to_str (tinfo->entry.id), + target_pid_to_str (tinfo->id), tpoint->number, paddress (tpoint->address)); /* Test the condition if present, and collect if true. */ @@ -4714,19 +4707,20 @@ collect_data_at_step (struct tracepoint_hit_ctx *ctx, #endif #ifdef IN_PROCESS_AGENT -/* The target description used by the IPA. Given that the IPA library - is built for a specific architecture that is loaded into the - inferior, there only needs to be one such description per - build. */ -const struct target_desc *ipa_tdesc; +/* The target description index for IPA. Passed from gdbserver, used + to select ipa_tdesc. */ +EXTERN_C_PUSH +IP_AGENT_EXPORT_VAR int ipa_tdesc_idx; +EXTERN_C_POP #endif static struct regcache * get_context_regcache (struct tracepoint_hit_ctx *ctx) { struct regcache *regcache = NULL; - #ifdef IN_PROCESS_AGENT + const struct target_desc *ipa_tdesc = get_ipa_tdesc (ipa_tdesc_idx); + if (ctx->type == fast_tracepoint) { struct fast_tracepoint_ctx *fctx = (struct fast_tracepoint_ctx *) ctx; @@ -5305,6 +5299,7 @@ traceframe_read_mem (int tfnum, CORE_ADDR addr, static int traceframe_read_tsv (int tsvnum, LONGEST *val) { + client_state &cs = get_client_state (); int tfnum; struct traceframe *tframe; unsigned char *database, *dataptr; @@ -5314,7 +5309,7 @@ traceframe_read_tsv (int tsvnum, LONGEST *val) trace_debug ("traceframe_read_tsv"); - tfnum = current_traceframe; + tfnum = cs.current_traceframe; if (tfnum < 0) { @@ -5575,7 +5570,7 @@ force_unlock_trace_buffer (void) case, if we want to move the thread out of the jump pad, we need to single-step it until this function returns 0. */ -int +fast_tpoint_collect_result fast_tracepoint_collecting (CORE_ADDR thread_area, CORE_ADDR stop_pc, struct fast_tpoint_collect_status *status) @@ -5650,7 +5645,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, if (tpoint == NULL) { warning ("in jump pad, but no matching tpoint?"); - return 0; + return fast_tpoint_collect_result::not_collecting; } else { @@ -5678,7 +5673,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, if (tpoint == NULL) { warning ("in trampoline, but no matching tpoint?"); - return 0; + return fast_tpoint_collect_result::not_collecting; } else { @@ -5706,14 +5701,14 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, { trace_debug ("fast_tracepoint_collecting:" " failed reading 'collecting' in the inferior"); - return 0; + return fast_tpoint_collect_result::not_collecting; } if (!ipa_collecting) { trace_debug ("fast_tracepoint_collecting: not collecting" " (and nobody is)."); - return 0; + return fast_tpoint_collect_result::not_collecting; } /* Some thread is collecting. Check which. */ @@ -5726,7 +5721,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, { trace_debug ("fast_tracepoint_collecting: not collecting " "(another thread is)"); - return 0; + return fast_tpoint_collect_result::not_collecting; } tpoint @@ -5736,7 +5731,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, warning ("fast_tracepoint_collecting: collecting, " "but tpoint %s not found?", paddress ((CORE_ADDR) ipa_collecting_obj.tpoint)); - return 0; + return fast_tpoint_collect_result::not_collecting; } /* The thread is within `gdb_collect', skip over the rest of @@ -5763,7 +5758,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, fast_tracepoint_collecting, returning continue-until-break at %s", paddress (tpoint->adjusted_insn_addr)); - return 1; /* continue */ + return fast_tpoint_collect_result::before_insn; /* continue */ } else { @@ -5774,7 +5769,7 @@ fast_tracepoint_collecting, returning continue-until-break at %s", paddress (tpoint->adjusted_insn_addr), paddress (tpoint->adjusted_insn_addr_end)); - return 2; /* single-step */ + return fast_tpoint_collect_result::at_insn; /* single-step */ } } @@ -5799,11 +5794,13 @@ IP_AGENT_EXPORT_FUNC void gdb_collect (struct tracepoint *tpoint, unsigned char *regs) { struct fast_tracepoint_ctx ctx; + const struct target_desc *ipa_tdesc; /* Don't do anything until the trace run is completely set up. */ if (!tracing) return; + ipa_tdesc = get_ipa_tdesc (ipa_tdesc_idx); ctx.base.type = fast_tracepoint; ctx.regs = regs; ctx.regcache_initted = 0; @@ -5862,6 +5859,25 @@ gdb_collect (struct tracepoint *tpoint, unsigned char *regs) } } +/* These global variables points to the corresponding functions. This is + necessary on powerpc64, where asking for function symbol address from gdb + results in returning the actual code pointer, instead of the descriptor + pointer. */ + +typedef void (*gdb_collect_ptr_type) (struct tracepoint *, unsigned char *); +typedef ULONGEST (*get_raw_reg_ptr_type) (const unsigned char *, int); +typedef LONGEST (*get_trace_state_variable_value_ptr_type) (int); +typedef void (*set_trace_state_variable_value_ptr_type) (int, LONGEST); + +EXTERN_C_PUSH +IP_AGENT_EXPORT_VAR gdb_collect_ptr_type gdb_collect_ptr = gdb_collect; +IP_AGENT_EXPORT_VAR get_raw_reg_ptr_type get_raw_reg_ptr = get_raw_reg; +IP_AGENT_EXPORT_VAR get_trace_state_variable_value_ptr_type + get_trace_state_variable_value_ptr = get_trace_state_variable_value; +IP_AGENT_EXPORT_VAR set_trace_state_variable_value_ptr_type + set_trace_state_variable_value_ptr = set_trace_state_variable_value; +EXTERN_C_POP + #endif #ifndef IN_PROCESS_AGENT @@ -5869,19 +5885,39 @@ gdb_collect (struct tracepoint *tpoint, unsigned char *regs) CORE_ADDR get_raw_reg_func_addr (void) { - return ipa_sym_addrs.addr_get_raw_reg; + CORE_ADDR res; + if (read_inferior_data_pointer (ipa_sym_addrs.addr_get_raw_reg_ptr, &res)) + { + error ("error extracting get_raw_reg_ptr"); + return 0; + } + return res; } CORE_ADDR get_get_tsv_func_addr (void) { - return ipa_sym_addrs.addr_get_trace_state_variable_value; + CORE_ADDR res; + if (read_inferior_data_pointer ( + ipa_sym_addrs.addr_get_trace_state_variable_value_ptr, &res)) + { + error ("error extracting get_trace_state_variable_value_ptr"); + return 0; + } + return res; } CORE_ADDR get_set_tsv_func_addr (void) { - return ipa_sym_addrs.addr_set_trace_state_variable_value; + CORE_ADDR res; + if (read_inferior_data_pointer ( + ipa_sym_addrs.addr_set_trace_state_variable_value_ptr, &res)) + { + error ("error extracting set_trace_state_variable_value_ptr"); + return 0; + } + return res; } static void @@ -5931,17 +5967,6 @@ compile_tracepoint_condition (struct tracepoint *tpoint, *jump_entry += 16; } -/* We'll need to adjust these when we consider bi-arch setups. */ - -static int -write_inferior_data_ptr (CORE_ADDR where, CORE_ADDR ptr) -{ - uintptr_t pptr = ptr; - - return write_inferior_memory (where, - (unsigned char *) &pptr, sizeof pptr); -} - /* The base pointer of the IPA's heap. This is the only memory the IPA is allowed to use. The IPA should _not_ call the inferior's `malloc' during operation. That'd be slow, and, most importantly, @@ -5987,8 +6012,8 @@ download_agent_expr (struct agent_expr *expr) write_inferior_memory (expr_addr, (unsigned char *) expr, sizeof (*expr)); expr_bytes = target_malloc (expr->length); - write_inferior_data_ptr (expr_addr + offsetof (struct agent_expr, bytes), - expr_bytes); + write_inferior_data_pointer (expr_addr + offsetof (struct agent_expr, bytes), + expr_bytes); write_inferior_memory (expr_bytes, expr->bytes, expr->length); return expr_addr; @@ -6046,9 +6071,9 @@ download_tracepoint_1 (struct tracepoint *tpoint) sizeof (target_tracepoint)); if (tpoint->cond) - write_inferior_data_ptr (tpptr + offsetof (struct tracepoint, - cond), - download_agent_expr (tpoint->cond)); + write_inferior_data_pointer (tpptr + + offsetof (struct tracepoint, cond), + download_agent_expr (tpoint->cond)); if (tpoint->numactions) { @@ -6058,20 +6083,20 @@ download_tracepoint_1 (struct tracepoint *tpoint) /* The pointers array. */ actions_array = target_malloc (sizeof (*tpoint->actions) * tpoint->numactions); - write_inferior_data_ptr (tpptr + offsetof (struct tracepoint, - actions), - actions_array); + write_inferior_data_pointer (tpptr + offsetof (struct tracepoint, + actions), + actions_array); /* Now for each pointer, download the action. */ for (i = 0; i < tpoint->numactions; i++) { struct tracepoint_action *action = tpoint->actions[i]; - CORE_ADDR ipa_action = action->ops->download (action); + CORE_ADDR ipa_action = tracepoint_action_download (action); if (ipa_action != 0) - write_inferior_data_ptr - (actions_array + i * sizeof (*tpoint->actions), - ipa_action); + write_inferior_data_pointer (actions_array + + i * sizeof (*tpoint->actions), + ipa_action); } } } @@ -6116,7 +6141,7 @@ tracepoint_send_agent (struct tracepoint *tpoint) struct tracepoint_action *action = tpoint->actions[i]; p[0] = action->type; - p = action->ops->send (&p[1], action); + p = tracepoint_action_send (&p[1], action); } get_jump_space_head (); @@ -6195,19 +6220,19 @@ download_tracepoint (struct tracepoint *tpoint) } /* tpoint->next = tp_prev->next */ - write_inferior_data_ptr (tpoint->obj_addr_on_target - + offsetof (struct tracepoint, next), - tp_prev_target_next_addr); + write_inferior_data_pointer (tpoint->obj_addr_on_target + + offsetof (struct tracepoint, next), + tp_prev_target_next_addr); /* tp_prev->next = tpoint */ - write_inferior_data_ptr (tp_prev->obj_addr_on_target - + offsetof (struct tracepoint, next), - tpoint->obj_addr_on_target); + write_inferior_data_pointer (tp_prev->obj_addr_on_target + + offsetof (struct tracepoint, next), + tpoint->obj_addr_on_target); } else /* First object in list, set the head pointer in the inferior. */ - write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, - tpoint->obj_addr_on_target); + write_inferior_data_pointer (ipa_sym_addrs.addr_tracepoints, + tpoint->obj_addr_on_target); } @@ -6218,7 +6243,7 @@ download_trace_state_variables (void) struct trace_state_variable *tsv; /* Start out empty. */ - write_inferior_data_ptr (ipa_sym_addrs.addr_trace_state_variables, 0); + write_inferior_data_pointer (ipa_sym_addrs.addr_trace_state_variables, 0); for (tsv = trace_state_variables; tsv != NULL; tsv = tsv->next) { @@ -6239,15 +6264,15 @@ download_trace_state_variables (void) /* First object in list, set the head pointer in the inferior. */ - write_inferior_data_ptr (ipa_sym_addrs.addr_trace_state_variables, - ptr); + write_inferior_data_pointer (ipa_sym_addrs.addr_trace_state_variables, + ptr); } else { - write_inferior_data_ptr (prev_ptr - + offsetof (struct trace_state_variable, - next), - ptr); + write_inferior_data_pointer (prev_ptr + + offsetof (struct trace_state_variable, + next), + ptr); } /* Write the whole object. We'll fix up its pointers in a bit. @@ -6263,10 +6288,10 @@ download_trace_state_variables (void) CORE_ADDR name_addr = target_malloc (size); write_inferior_memory (name_addr, (unsigned char *) tsv->name, size); - write_inferior_data_ptr (ptr - + offsetof (struct trace_state_variable, - name), - name_addr); + write_inferior_data_pointer (ptr + + offsetof (struct trace_state_variable, + name), + name_addr); } gdb_assert (tsv->getter == NULL); @@ -6275,9 +6300,9 @@ download_trace_state_variables (void) if (prev_ptr != 0) { /* Fixup the next pointer in the last item in the list. */ - write_inferior_data_ptr (prev_ptr - + offsetof (struct trace_state_variable, - next), 0); + write_inferior_data_pointer (prev_ptr + + offsetof (struct trace_state_variable, + next), 0); } } @@ -6660,6 +6685,7 @@ gdb_probe (const struct marker *mdata, void *probe_private, { struct tracepoint *tpoint; struct static_tracepoint_ctx ctx; + const struct target_desc *ipa_tdesc; /* Don't do anything until the trace run is completely set up. */ if (!tracing) @@ -6668,6 +6694,7 @@ gdb_probe (const struct marker *mdata, void *probe_private, return; } + ipa_tdesc = get_ipa_tdesc (ipa_tdesc_idx); ctx.base.type = static_tracepoint; ctx.regcache_initted = 0; ctx.regs = regs; @@ -6810,7 +6837,7 @@ static int run_inferior_command (char *cmd, int len) { int err = -1; - int pid = ptid_get_pid (current_ptid); + int pid = current_ptid.pid (); trace_debug ("run_inferior_command: running: %s", cmd); @@ -7303,7 +7330,6 @@ gdb_agent_init (void) } #include -#include IP_AGENT_EXPORT_VAR char *gdb_tp_heap_buffer; IP_AGENT_EXPORT_VAR char *gdb_jump_pad_buffer; @@ -7335,6 +7361,34 @@ initialize_tracepoint_ftlib (void) gdb_agent_init (); } +#ifndef HAVE_GETAUXVAL +/* Retrieve the value of TYPE from the auxiliary vector. If TYPE is not + found, 0 is returned. This function is provided if glibc is too old. */ + +unsigned long +getauxval (unsigned long type) +{ + unsigned long data[2]; + FILE *f = fopen ("/proc/self/auxv", "r"); + unsigned long value = 0; + + if (f == NULL) + return 0; + + while (fread (data, sizeof (data), 1, f) > 0) + { + if (data[0] == type) + { + value = data[1]; + break; + } + } + + fclose (f); + return value; +} +#endif + #endif /* IN_PROCESS_AGENT */ /* Return a timestamp, expressed as microseconds of the usual Unix @@ -7344,12 +7398,10 @@ initialize_tracepoint_ftlib (void) static LONGEST get_timestamp (void) { - struct timeval tv; + using namespace std::chrono; - if (gettimeofday (&tv, 0) != 0) - return -1; - else - return (LONGEST) tv.tv_sec * 1000000 + tv.tv_usec; + steady_clock::time_point now = steady_clock::now (); + return duration_cast (now.time_since_epoch ()).count (); } void @@ -7368,35 +7420,22 @@ initialize_tracepoint (void) #ifdef IN_PROCESS_AGENT { - uintptr_t addr; int pagesize; + size_t jump_pad_size; pagesize = sysconf (_SC_PAGE_SIZE); if (pagesize == -1) perror_with_name ("sysconf"); - gdb_tp_heap_buffer = (char *) xmalloc (5 * 1024 * 1024); - #define SCRATCH_BUFFER_NPAGES 20 - /* Allocate scratch buffer aligned on a page boundary, at a low - address (close to the main executable's code). */ - for (addr = pagesize; addr != 0; addr += pagesize) - { - gdb_jump_pad_buffer - = (char *) mmap ((void *) addr, - pagesize * SCRATCH_BUFFER_NPAGES, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, - -1, 0); - if (gdb_jump_pad_buffer != MAP_FAILED) - break; - } + jump_pad_size = pagesize * SCRATCH_BUFFER_NPAGES; - if (addr == 0) + gdb_tp_heap_buffer = (char *) xmalloc (5 * 1024 * 1024); + gdb_jump_pad_buffer = (char *) alloc_jump_pad_buffer (jump_pad_size); + if (gdb_jump_pad_buffer == NULL) perror_with_name ("mmap"); - - gdb_jump_pad_buffer_end = gdb_jump_pad_buffer + pagesize * SCRATCH_BUFFER_NPAGES; + gdb_jump_pad_buffer_end = gdb_jump_pad_buffer + jump_pad_size; } gdb_trampoline_buffer = gdb_trampoline_buffer_end = 0;