[patch 5/8] refactor gdbserver on installing fast tracepoint

Yao Qi
2011-11-08T06:33:09Z

[-- Attachment #1: Type: text/plain, Size: 169 bytes --]

This is a refactor patch, which convert some code into routines so that
the next patch (6/8) can use.

No functionality is changed in gdbserver.

--
Yao (é½å°§)

[-- Attachment #2: 0005-gdbserver-fast-tp-refactor.patch --]
[-- Type: text/x-patch, Size: 13942 bytes --]

gdb/gdbserver/

* mem-break.c (inc_ref_fast_tracepoint_jump): New.
* mem-break.h: Declare.
* tracepoint.c (cmd_qtstart): Move some code to ...
(clone_fast_tracepoint, install_fast_tracepoint): ... here.
New.
(download_tracepoints): Move some code to ...
(download_tracepoint_1): ... here. New.
---
gdb/gdbserver/mem-break.c | 6 +
gdb/gdbserver/mem-break.h | 3 +
gdb/gdbserver/tracepoint.c | 354 +++++++++++++++++++++++--------------------
3 files changed, 198 insertions(+), 165 deletions(-)

diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index 348f59d..a6c8ce6 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -302,6 +302,12 @@ delete_fast_tracepoint_jump (struct fast_tracepoint_jump *todel)
return ENOENT;
}

+void
+inc_ref_fast_tracepoint_jump (struct fast_tracepoint_jump *jp)
+{
+ jp->refcount++;
+}
+
struct fast_tracepoint_jump *
set_fast_tracepoint_jump (CORE_ADDR where,
unsigned char *insn, ULONGEST length)
diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h
index c5cb20c..2f8bee9 100644
--- a/gdb/gdbserver/mem-break.h
+++ b/gdb/gdbserver/mem-break.h
@@ -137,6 +137,9 @@ struct fast_tracepoint_jump *set_fast_tracepoint_jump (CORE_ADDR where,
unsigned char *insn,
ULONGEST length);

+/* Increment reference counter of JP. */
+void inc_ref_fast_tracepoint_jump (struct fast_tracepoint_jump *jp);
+
/* Delete fast tracepoint jump TODEL from our tables, and uninsert if
from memory. */

diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 95119d3..3a6a0f3 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -1245,6 +1245,7 @@ static void do_action_at_tracepoint (struct tracepoint_hit_ctx *ctx,

#ifndef IN_PROCESS_AGENT
static struct tracepoint *fast_tracepoint_from_ipa_tpoint_address (CORE_ADDR);
+static int install_fast_tracepoint (struct tracepoint *);
#endif

#if defined(__GNUC__)
@@ -2737,19 +2738,71 @@ probe_marker_at (CORE_ADDR address, char *errout)
return err;
}

-#define MAX_JUMP_SIZE 20
-
static void
-cmd_qtstart (char *packet)
+clone_fast_tracepoint (struct tracepoint *to, const struct tracepoint *from)
{
- struct tracepoint *tpoint, *prev_ftpoint, *prev_stpoint;
- CORE_ADDR jump_entry;
+ to->jump_pad = from->jump_pad;
+ to->jump_pad_end = from->jump_pad_end;
+ to->adjusted_insn_addr = from->adjusted_insn_addr;
+ to->adjusted_insn_addr_end = from->adjusted_insn_addr_end;
+ to->handle = from->handle;

+ gdb_assert (from->handle);
+ inc_ref_fast_tracepoint_jump ((struct fast_tracepoint_jump *) from->handle);
+}
+
+#define MAX_JUMP_SIZE 20
+
+/* Install fast tracepoint. Return 0 if successful, otherwise return
+ non-zero. */
+
+static int
+install_fast_tracepoint (struct tracepoint *tpoint)
+{
+ CORE_ADDR jentry, jump_entry;
+ int err = 0;
/* The jump to the jump pad of the last fast tracepoint
installed. */
unsigned char fjump[MAX_JUMP_SIZE];
ULONGEST fjump_size;

+ jentry = jump_entry = get_jump_space_head ();
+
+ /* Install the jump pad. */
+ err = install_fast_tracepoint_jump_pad (tpoint->obj_addr_on_target,
+ tpoint->address,
+ ipa_sym_addrs.addr_gdb_collect,
+ ipa_sym_addrs.addr_collecting,
+ tpoint->orig_size,
+ &jentry, fjump, &fjump_size,
+ &tpoint->adjusted_insn_addr,
+ &tpoint->adjusted_insn_addr_end);
+
+ if (err)
+ return 1;
+
+ /* Wire it in. */
+ tpoint->handle = set_fast_tracepoint_jump (tpoint->address, fjump,
+ fjump_size);
+
+ if (tpoint->handle != NULL)
+ {
+ tpoint->jump_pad = jump_entry;
+ tpoint->jump_pad_end = jentry;
+
+ /* Pad to 8-byte alignment. */
+ jentry = ((jentry + 7) & ~0x7);
+ claim_jump_space (jentry - jump_entry);
+ }
+
+ return 0;
+}
+
+static void
+cmd_qtstart (char *packet)
+{
+ struct tracepoint *tpoint, *prev_ftpoint, *prev_stpoint;
+
trace_debug ("Starting the trace");

/* Sort tracepoints by ascending address. This makes installing
@@ -2808,55 +2861,12 @@ cmd_qtstart (char *packet)
}

if (prev_ftpoint != NULL && prev_ftpoint->address == tpoint->address)
- {
- tpoint->handle = set_fast_tracepoint_jump (tpoint->address,
- fjump,
- fjump_size);
- tpoint->jump_pad = prev_ftpoint->jump_pad;
- tpoint->jump_pad_end = prev_ftpoint->jump_pad_end;
- tpoint->adjusted_insn_addr = prev_ftpoint->adjusted_insn_addr;
- tpoint->adjusted_insn_addr_end
- = prev_ftpoint->adjusted_insn_addr_end;
- }
+ clone_fast_tracepoint (tpoint, prev_ftpoint);
else
{
- CORE_ADDR jentry;
- int err = 0;
-
- prev_ftpoint = NULL;
-
- jentry = jump_entry = get_jump_space_head ();
-
- /* Install the jump pad. */
- err = install_fast_tracepoint_jump_pad
- (tpoint->obj_addr_on_target,
- tpoint->address,
- ipa_sym_addrs.addr_gdb_collect,
- ipa_sym_addrs.addr_collecting,
- tpoint->orig_size,
- &jentry,
- fjump, &fjump_size,
- &tpoint->adjusted_insn_addr,
- &tpoint->adjusted_insn_addr_end);
-
- /* Wire it in. */
- if (!err)
- tpoint->handle = set_fast_tracepoint_jump (tpoint->address,
- fjump, fjump_size);
-
- if (tpoint->handle != NULL)
- {
- tpoint->jump_pad = jump_entry;
- tpoint->jump_pad_end = jentry;
+ if (install_fast_tracepoint (tpoint) == 0)
+ prev_ftpoint = tpoint;

- /* Pad to 8-byte alignment. */
- jentry = ((jentry + 7) & ~0x7);
- claim_jump_space (jentry - jump_entry);
-
- /* So that we can handle multiple fast tracepoints
- at the same address easily. */
- prev_ftpoint = tpoint;
- }
}
}
else if (tpoint->type == static_tracepoint)
@@ -6325,50 +6335,152 @@ download_agent_expr (struct agent_expr *expr)
/* Align V up to N bits. */
#define UALIGN(V, N) (((V) + ((N) - 1)) & ~((N) - 1))

+/* Sync tracepoint with IPA, but leave maintenance of linked list to caller. */
+
static void
-download_tracepoints (void)
+download_tracepoint_1 (struct tracepoint *tpoint)
{
- CORE_ADDR tpptr = 0, prev_tpptr = 0;
- struct tracepoint *tpoint;
+ struct tracepoint target_tracepoint;
+ CORE_ADDR tpptr = 0;

- /* Start out empty. */
- write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, 0);
+ gdb_assert (tpoint->type == fast_tracepoint
+ || tpoint->type == static_tracepoint);

- for (tpoint = tracepoints; tpoint; tpoint = tpoint->next)
+ if (tpoint->cond != NULL && target_emit_ops () != NULL)
{
- struct tracepoint target_tracepoint;
+ CORE_ADDR jentry, jump_entry;

- if (tpoint->type != fast_tracepoint
- && tpoint->type != static_tracepoint)
- continue;
+ jentry = jump_entry = get_jump_space_head ();

- /* Maybe download a compiled condition. */
- if (tpoint->cond != NULL && target_emit_ops () != NULL)
+ if (tpoint->cond != NULL)
{
- CORE_ADDR jentry, jump_entry;
+ /* Pad to 8-byte alignment. (needed?) */
+ /* Actually this should be left for the target to
+ decide. */
+ jentry = UALIGN (jentry, 8);
+
+ compile_tracepoint_condition (tpoint, &jentry);
+ }
+
+ /* Pad to 8-byte alignment. */
+ jentry = UALIGN (jentry, 8);
+ claim_jump_space (jentry - jump_entry);
+ }

- jentry = jump_entry = get_jump_space_head ();
+ target_tracepoint = *tpoint;

- if (tpoint->cond != NULL)
+ tpptr = target_malloc (sizeof (*tpoint));
+ tpoint->obj_addr_on_target = tpptr;
+
+ /* Write the whole object. We'll fix up its pointers in a bit.
+ Assume no next for now. This is fixed up above on the next
+ iteration, if there's any. */
+ target_tracepoint.next = NULL;
+ /* Need to clear this here too, since we're downloading the
+ tracepoints before clearing our own copy. */
+ target_tracepoint.hit_count = 0;
+
+ write_inferior_memory (tpptr, (unsigned char *) &target_tracepoint,
+ sizeof (target_tracepoint));
+
+ if (tpoint->cond)
+ write_inferior_data_ptr (tpptr + offsetof (struct tracepoint,
+ cond),
+ download_agent_expr (tpoint->cond));
+
+ if (tpoint->numactions)
+ {
+ int i;
+ CORE_ADDR actions_array;
+
+ /* The pointers array. */
+ actions_array
+ = target_malloc (sizeof (*tpoint->actions) * tpoint->numactions);
+ write_inferior_data_ptr (tpptr + offsetof (struct tracepoint,
+ actions),
+ actions_array);
+
+ /* Now for each pointer, download the action. */
+ for (i = 0; i < tpoint->numactions; i++)
+ {
+ CORE_ADDR ipa_action = 0;
+ struct tracepoint_action *action = tpoint->actions[i];
+
+ switch (action->type)
{
- /* Pad to 8-byte alignment. (needed?) */
- /* Actually this should be left for the target to
- decide. */
- jentry = UALIGN (jentry, 8);
+ case 'M':
+ ipa_action
+ = target_malloc (sizeof (struct collect_memory_action));
+ write_inferior_memory (ipa_action,
+ (unsigned char *) action,
+ sizeof (struct collect_memory_action));
+ break;
+ case 'R':
+ ipa_action
+ = target_malloc (sizeof (struct collect_registers_action));
+ write_inferior_memory (ipa_action,
+ (unsigned char *) action,
+ sizeof (struct collect_registers_action));
+ break;
+ case 'X':
+ {
+ CORE_ADDR expr;
+ struct eval_expr_action *eaction
+ = (struct eval_expr_action *) action;

- compile_tracepoint_condition (tpoint, &jentry);
+ ipa_action = target_malloc (sizeof (*eaction));
+ write_inferior_memory (ipa_action,
+ (unsigned char *) eaction,
+ sizeof (*eaction));
+
+ expr = download_agent_expr (eaction->expr);
+ write_inferior_data_ptr
+ (ipa_action + offsetof (struct eval_expr_action, expr),
+ expr);
+ break;
+ }
+ case 'L':
+ ipa_action = target_malloc
+ (sizeof (struct collect_static_trace_data_action));
+ write_inferior_memory
+ (ipa_action,
+ (unsigned char *) action,
+ sizeof (struct collect_static_trace_data_action));
+ break;
+ default:
+ trace_debug ("unknown trace action '%c', ignoring",
+ action->type);
+ break;
}

- /* Pad to 8-byte alignment. */
- jentry = UALIGN (jentry, 8);
- claim_jump_space (jentry - jump_entry);
+ if (ipa_action != 0)
+ write_inferior_data_ptr
+ (actions_array + i * sizeof (sizeof (*tpoint->actions)),
+ ipa_action);
}
+ }
+}

- target_tracepoint = *tpoint;
+static void
+download_tracepoints (void)
+{
+ CORE_ADDR tpptr = 0, prev_tpptr = 0;
+ struct tracepoint *tpoint;
+
+ /* Start out empty. */
+ write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, 0);
+
+ for (tpoint = tracepoints; tpoint; tpoint = tpoint->next)
+ {
+ if (tpoint->type != fast_tracepoint
+ && tpoint->type != static_tracepoint)
+ continue;

prev_tpptr = tpptr;
- tpptr = target_malloc (sizeof (*tpoint));
- tpoint->obj_addr_on_target = tpptr;
+
+ download_tracepoint_1 (tpoint);
+
+ tpptr = tpoint->obj_addr_on_target;

if (tpoint == tracepoints)
{
@@ -6382,94 +6494,6 @@ download_tracepoints (void)
next),
tpptr);
}
-
- /* Write the whole object. We'll fix up its pointers in a bit.
- Assume no next for now. This is fixed up above on the next
- iteration, if there's any. */
- target_tracepoint.next = NULL;
- /* Need to clear this here too, since we're downloading the
- tracepoints before clearing our own copy. */
- target_tracepoint.hit_count = 0;
-
- write_inferior_memory (tpptr, (unsigned char *) &target_tracepoint,
- sizeof (target_tracepoint));
-
- if (tpoint->cond)
- write_inferior_data_ptr (tpptr + offsetof (struct tracepoint,
- cond),
- download_agent_expr (tpoint->cond));
-
- if (tpoint->numactions)
- {
- int i;
- CORE_ADDR actions_array;
-
- /* The pointers array. */
- actions_array
- = target_malloc (sizeof (*tpoint->actions) * tpoint->numactions);
- write_inferior_data_ptr (tpptr + offsetof (struct tracepoint,
- actions),
- actions_array);
-
- /* Now for each pointer, download the action. */
- for (i = 0; i < tpoint->numactions; i++)
- {
- CORE_ADDR ipa_action = 0;
- struct tracepoint_action *action = tpoint->actions[i];
-
- switch (action->type)
- {
- case 'M':
- ipa_action
- = target_malloc (sizeof (struct collect_memory_action));
- write_inferior_memory (ipa_action,
- (unsigned char *) action,
- sizeof (struct collect_memory_action));
- break;
- case 'R':
- ipa_action
- = target_malloc (sizeof (struct collect_registers_action));
- write_inferior_memory (ipa_action,
- (unsigned char *) action,
- sizeof (struct collect_registers_action));
- break;
- case 'X':
- {
- CORE_ADDR expr;
- struct eval_expr_action *eaction
- = (struct eval_expr_action *) action;
-
- ipa_action = target_malloc (sizeof (*eaction));
- write_inferior_memory (ipa_action,
- (unsigned char *) eaction,
- sizeof (*eaction));
-
- expr = download_agent_expr (eaction->expr);
- write_inferior_data_ptr
- (ipa_action + offsetof (struct eval_expr_action, expr),
- expr);
- break;
- }
- case 'L':
- ipa_action = target_malloc
- (sizeof (struct collect_static_trace_data_action));
- write_inferior_memory
- (ipa_action,
- (unsigned char *) action,
- sizeof (struct collect_static_trace_data_action));
- break;
- default:
- trace_debug ("unknown trace action '%c', ignoring",
- action->type);
- break;
- }
-
- if (ipa_action != 0)
- write_inferior_data_ptr
- (actions_array + i * sizeof (sizeof (*tpoint->actions)),
- ipa_action);
- }
- }
}
}

--
1.7.0.4