Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Unified Diff: gdb/arm-linux-tdep.c

Issue 11969036: Merge GDB 7.5.1 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@master
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gdb/arm-linux-nat.c ('k') | gdb/arm-symbian-tdep.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gdb/arm-linux-tdep.c
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index ac4860c3dbd1c58dbc6809d0fabaa0bce4176f4c..f4eaa5cc422e84a8799f64bbf4ee94b044057481 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -43,6 +43,12 @@
#include "gdbthread.h"
#include "symfile.h"
+#include "cli/cli-utils.h"
+#include "stap-probe.h"
+#include "parser-defs.h"
+#include "user-regs.h"
+#include <ctype.h>
+
#include "gdb_string.h"
/* This is defined in <elf.h> on ARM GNU/Linux systems. */
@@ -937,6 +943,9 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs,
= set_momentary_breakpoint (gdbarch, sal, get_frame_id (frame),
bp_step_resume);
+ /* set_momentary_breakpoint invalidates FRAME. */
+ frame = NULL;
+
/* We need to make sure we actually insert the momentary
breakpoint set above. */
insert_breakpoints ();
@@ -1053,6 +1062,122 @@ arm_linux_displaced_step_copy_insn (struct gdbarch *gdbarch,
return dsc;
}
+static int
+arm_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
+{
+ return (*s == '#' /* Literal number. */
+ || *s == '[' /* Register indirection or
+ displacement. */
+ || isalpha (*s)); /* Register value. */
+}
+
+/* This routine is used to parse a special token in ARM's assembly.
+
+ The special tokens parsed by it are:
+
+ - Register displacement (e.g, [fp, #-8])
+
+ It returns one if the special token has been parsed successfully,
+ or zero if the current token is not considered special. */
+
+static int
+arm_stap_parse_special_token (struct gdbarch *gdbarch,
+ struct stap_parse_info *p)
+{
+ if (*p->arg == '[')
+ {
+ /* Temporary holder for lookahead. */
+ const char *tmp = p->arg;
+ /* Used to save the register name. */
+ const char *start;
+ char *regname;
+ int len, offset;
+ int got_minus = 0;
+ long displacement;
+ struct stoken str;
+
+ ++tmp;
+ start = tmp;
+
+ /* Register name. */
+ while (isalnum (*tmp))
+ ++tmp;
+
+ if (*tmp != ',')
+ return 0;
+
+ len = tmp - start;
+ regname = alloca (len + 2);
+
+ offset = 0;
+ if (isdigit (*start))
+ {
+ /* If we are dealing with a register whose name begins with a
+ digit, it means we should prefix the name with the letter
+ `r', because GDB expects this name pattern. Otherwise (e.g.,
+ we are dealing with the register `fp'), we don't need to
+ add such a prefix. */
+ regname[0] = 'r';
+ offset = 1;
+ }
+
+ strncpy (regname + offset, start, len);
+ len += offset;
+ regname[len] = '\0';
+
+ if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
+ error (_("Invalid register name `%s' on expression `%s'."),
+ regname, p->saved_arg);
+
+ ++tmp;
+ tmp = skip_spaces_const (tmp);
+ if (*tmp++ != '#')
+ return 0;
+
+ if (*tmp == '-')
+ {
+ ++tmp;
+ got_minus = 1;
+ }
+
+ displacement = strtol (tmp, (char **) &tmp, 10);
+
+ /* Skipping last `]'. */
+ if (*tmp++ != ']')
+ return 0;
+
+ /* The displacement. */
+ write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+ write_exp_elt_longcst (displacement);
+ write_exp_elt_opcode (OP_LONG);
+ if (got_minus)
+ write_exp_elt_opcode (UNOP_NEG);
+
+ /* The register name. */
+ write_exp_elt_opcode (OP_REGISTER);
+ str.ptr = regname;
+ str.length = len;
+ write_exp_string (str);
+ write_exp_elt_opcode (OP_REGISTER);
+
+ write_exp_elt_opcode (BINOP_ADD);
+
+ /* Casting to the expected type. */
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (lookup_pointer_type (p->arg_type));
+ write_exp_elt_opcode (UNOP_CAST);
+
+ write_exp_elt_opcode (UNOP_IND);
+
+ p->arg = tmp;
+ }
+ else
+ return 0;
+
+ return 1;
+}
+
static void
arm_linux_init_abi (struct gdbarch_info info,
struct gdbarch *gdbarch)
@@ -1152,8 +1277,23 @@ arm_linux_init_abi (struct gdbarch_info info,
simple_displaced_step_free_closure);
set_gdbarch_displaced_step_location (gdbarch, displaced_step_at_entry_point);
+ /* Reversible debugging, process record. */
+ set_gdbarch_process_record (gdbarch, arm_process_record);
+
+ /* SystemTap functions. */
+ set_gdbarch_stap_integer_prefix (gdbarch, "#");
+ set_gdbarch_stap_register_prefix (gdbarch, "r");
+ set_gdbarch_stap_register_indirection_prefix (gdbarch, "[");
+ set_gdbarch_stap_register_indirection_suffix (gdbarch, "]");
+ set_gdbarch_stap_gdb_register_prefix (gdbarch, "r");
+ set_gdbarch_stap_is_single_operand (gdbarch, arm_stap_is_single_operand);
+ set_gdbarch_stap_parse_special_token (gdbarch,
+ arm_stap_parse_special_token);
tdep->syscall_next_pc = arm_linux_syscall_next_pc;
+
+ /* Syscall record. */
+ tdep->arm_swi_record = NULL;
}
/* Provide a prototype to silence -Wmissing-prototypes. */
« no previous file with comments | « gdb/arm-linux-nat.c ('k') | gdb/arm-symbian-tdep.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698