]>
Commit | Line | Data |
---|---|---|
3a58abaf AM |
1 | http://sourceware.org/gdb/wiki/ProjectArcher |
2 | http://sourceware.org/gdb/wiki/ArcherBranchManagement | |
3 | ||
4 | GIT snapshot: | |
f412e1b4 | 5 | commit 9f8d47f059091333d178bd249507fd25676860e7 |
3a58abaf AM |
6 | |
7 | branch `archer' - the merge of branches: | |
7566401a | 8 | archer-jankratochvil-vla |
51a5ef0f | 9 | archer-jankratochvil-watchpoint3 |
6ed6bacf | 10 | archer-tromey-python |
f412e1b4 | 11 | archer-sergiodj-stap |
3a58abaf AM |
12 | |
13 | ||
f412e1b4 PS |
14 | diff --git a/gdb/Makefile.in b/gdb/Makefile.in |
15 | index 38c93c9..3acacdb 100644 | |
16 | --- a/gdb/Makefile.in | |
17 | +++ b/gdb/Makefile.in | |
18 | @@ -720,8 +720,8 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ | |
6ed6bacf | 19 | sentinel-frame.c \ |
f412e1b4 | 20 | serial.c ser-base.c ser-unix.c skip.c \ |
6ed6bacf AM |
21 | solib.c solib-target.c source.c \ |
22 | - stabsread.c stack.c std-regs.c symfile.c symfile-mem.c symmisc.c \ | |
23 | - symtab.c \ | |
24 | + stabsread.c stack.c stap-probe.c std-regs.c \ | |
25 | + symfile.c symfile-mem.c symmisc.c symtab.c \ | |
26 | target.c target-descriptions.c target-memory.c \ | |
27 | thread.c top.c tracepoint.c \ | |
28 | trad-frame.c \ | |
f412e1b4 | 29 | @@ -817,7 +817,7 @@ osdata.h procfs.h python/py-event.h python/py-events.h python/py-stopevent.h \ |
6ed6bacf AM |
30 | python/python-internal.h python/python.h ravenscar-thread.h record.h \ |
31 | solib-darwin.h solib-ia64-hpux.h solib-spu.h windows-nat.h xcoffread.h \ | |
32 | gnulib/extra/arg-nonnull.h gnulib/extra/c++defs.h gnulib/extra/warn-on-use.h \ | |
f412e1b4 PS |
33 | -gnulib/stddef.in.h inline-frame.h skip.h \ |
34 | +gnulib/stddef.in.h inline-frame.h skip.h stap-probe.h \ | |
35 | common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \ | |
36 | common/linux-osdata.h gdb-dlfcn.h | |
3a58abaf | 37 | |
f412e1b4 PS |
38 | @@ -905,7 +905,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ |
39 | xml-support.o xml-syscall.o xml-utils.o \ | |
6ed6bacf AM |
40 | target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \ |
41 | inferior.o osdata.o gdb_usleep.o record.o gcore.o \ | |
f412e1b4 PS |
42 | - jit.o progspace.o skip.o \ |
43 | + jit.o progspace.o skip.o stap-probe.o \ | |
44 | common-utils.o buffer.o ptid.o gdb-dlfcn.o | |
6ed6bacf AM |
45 | |
46 | TSOBS = inflow.o | |
f412e1b4 | 47 | @@ -1293,6 +1293,12 @@ stamp-h: $(srcdir)/config.in config.status |
3a58abaf AM |
48 | CONFIG_LINKS= \ |
49 | $(SHELL) config.status | |
50 | ||
7566401a | 51 | +.gdbinit: $(srcdir)/gdbinit.in config.status |
3a58abaf AM |
52 | + CONFIG_FILES=".gdbinit:gdbinit.in" \ |
53 | + CONFIG_COMMANDS= \ | |
54 | + CONFIG_HEADERS= \ | |
55 | + $(SHELL) config.status | |
56 | + | |
7566401a | 57 | config.status: $(srcdir)/configure configure.tgt configure.host |
3a58abaf AM |
58 | $(SHELL) config.status --recheck |
59 | ||
f412e1b4 PS |
60 | diff --git a/gdb/NEWS b/gdb/NEWS |
61 | index 128825e..13dd88c 100644 | |
62 | --- a/gdb/NEWS | |
63 | +++ b/gdb/NEWS | |
64 | @@ -328,6 +328,10 @@ Renesas RL78 rl78-*-elf | |
6ed6bacf AM |
65 | Initial support for the OpenCL C language (http://www.khronos.org/opencl) |
66 | has been integrated into GDB. | |
67 | ||
68 | +* GDB now has support for SystemTap <sys/sdt.h> probes. You can set a | |
69 | + breakpoint using the new "probe:" linespec and inspect the probe | |
70 | + arguments using the new $_probe_arg family of convenience variables. | |
71 | + | |
72 | * Python scripting | |
73 | ||
74 | ** The function gdb.Write now accepts an optional keyword 'stream'. | |
f412e1b4 PS |
75 | diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c |
76 | index 29956d7..dc1fadd 100644 | |
77 | --- a/gdb/ada-lang.c | |
78 | +++ b/gdb/ada-lang.c | |
79 | @@ -11896,6 +11896,7 @@ ada_operator_length (const struct expression *exp, int pc, int *oplenp, | |
3a58abaf | 80 | |
51a5ef0f PS |
81 | static int |
82 | ada_operator_check (struct expression *exp, int pos, | |
7566401a | 83 | + int (*type_func) (struct type *type, void *data), |
51a5ef0f PS |
84 | int (*objfile_func) (struct objfile *objfile, void *data), |
85 | void *data) | |
86 | { | |
f412e1b4 | 87 | @@ -11910,12 +11911,15 @@ ada_operator_check (struct expression *exp, int pos, |
51a5ef0f PS |
88 | break; |
89 | ||
90 | default: | |
91 | - return operator_check_standard (exp, pos, objfile_func, data); | |
7566401a ER |
92 | + return operator_check_standard (exp, pos, type_func, objfile_func, |
93 | + data); | |
51a5ef0f PS |
94 | } |
95 | ||
96 | /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL. */ | |
97 | ||
98 | - if (type && TYPE_OBJFILE (type) | |
7566401a ER |
99 | + if (type && type_func && (*type_func) (type, data)) |
100 | + return 1; | |
101 | + if (type && TYPE_OBJFILE (type) && objfile_func | |
51a5ef0f PS |
102 | && (*objfile_func) (TYPE_OBJFILE (type), data)) |
103 | return 1; | |
104 | ||
f412e1b4 PS |
105 | diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c |
106 | index a0bdbd7..98760bf 100644 | |
107 | --- a/gdb/amd64-linux-nat.c | |
108 | +++ b/gdb/amd64-linux-nat.c | |
109 | @@ -336,8 +336,8 @@ amd64_linux_dr_get_status (void) | |
110 | return amd64_linux_dr_get (inferior_ptid, DR_STATUS); | |
111 | } | |
6ed6bacf | 112 | |
f412e1b4 PS |
113 | -/* Callback for iterate_over_lwps. Update the debug registers of |
114 | - LWP. */ | |
115 | +/* Callback for linux_nat_iterate_watchpoint_lwps. Update the debug registers | |
116 | + of LWP. */ | |
6ed6bacf | 117 | |
f412e1b4 PS |
118 | static int |
119 | update_debug_registers_callback (struct lwp_info *lwp, void *arg) | |
120 | @@ -363,9 +363,7 @@ update_debug_registers_callback (struct lwp_info *lwp, void *arg) | |
6ed6bacf | 121 | static void |
f412e1b4 | 122 | amd64_linux_dr_set_control (unsigned long control) |
6ed6bacf | 123 | { |
f412e1b4 | 124 | - ptid_t pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid)); |
6ed6bacf | 125 | - |
f412e1b4 PS |
126 | - iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL); |
127 | + linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL); | |
128 | } | |
129 | ||
130 | /* Set address REGNUM (zero based) to ADDR in all LWPs of the current | |
131 | @@ -378,7 +376,7 @@ amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr) | |
132 | ||
133 | gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR); | |
134 | ||
135 | - iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL); | |
136 | + linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL); | |
3a58abaf AM |
137 | } |
138 | ||
f412e1b4 PS |
139 | /* Called when resuming a thread. |
140 | @@ -400,6 +398,13 @@ amd64_linux_prepare_to_resume (struct lwp_info *lwp) | |
141 | struct i386_debug_reg_state *state = i386_debug_reg_state (); | |
142 | int i; | |
143 | ||
144 | + /* On Linux kernel before 2.6.33 commit | |
145 | + 72f674d203cd230426437cdcf7dd6f681dad8b0d | |
146 | + if you enable a breakpoint by the DR_CONTROL bits you need to have | |
147 | + already written the corresponding DR_FIRSTADDR...DR_LASTADDR registers. | |
6ed6bacf | 148 | + |
f412e1b4 PS |
149 | + Ensure DR_CONTROL gets written as the very last register here. */ |
150 | + | |
151 | for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++) | |
152 | if (state->dr_ref_count[i] > 0) | |
153 | { | |
154 | diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c | |
155 | index ca9ade6..c30185d 100644 | |
156 | --- a/gdb/amd64-linux-tdep.c | |
157 | +++ b/gdb/amd64-linux-tdep.c | |
158 | @@ -1362,6 +1362,15 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) | |
159 | set_gdbarch_process_record (gdbarch, i386_process_record); | |
160 | set_gdbarch_process_record_signal (gdbarch, amd64_linux_record_signal); | |
161 | ||
162 | + /* SystemTap variables and functions. */ | |
163 | + set_gdbarch_stap_integer_prefix (gdbarch, "$"); | |
164 | + set_gdbarch_stap_register_prefix (gdbarch, "%"); | |
165 | + set_gdbarch_stap_register_indirection_prefix (gdbarch, "("); | |
166 | + set_gdbarch_stap_register_indirection_sufix (gdbarch, ")"); | |
167 | + set_gdbarch_stap_is_single_operand (gdbarch, i386_stap_is_single_operand); | |
168 | + set_gdbarch_stap_parse_special_token (gdbarch, | |
169 | + i386_stap_parse_special_token); | |
170 | + | |
171 | /* Initialize the amd64_linux_record_tdep. */ | |
172 | /* These values are the size of the type that will be used in a system | |
173 | call. They are obtained from Linux Kernel source. */ | |
174 | diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c | |
175 | index ac4860c..d710682 100644 | |
176 | --- a/gdb/arm-linux-tdep.c | |
177 | +++ b/gdb/arm-linux-tdep.c | |
178 | @@ -43,6 +43,12 @@ | |
179 | #include "gdbthread.h" | |
180 | #include "symfile.h" | |
181 | ||
182 | +#include "cli/cli-utils.h" | |
183 | +#include "stap-probe.h" | |
184 | +#include "parser-defs.h" | |
185 | +#include "user-regs.h" | |
186 | +#include <ctype.h> | |
6ed6bacf | 187 | + |
f412e1b4 PS |
188 | #include "gdb_string.h" |
189 | ||
190 | /* This is defined in <elf.h> on ARM GNU/Linux systems. */ | |
191 | @@ -1053,6 +1059,122 @@ arm_linux_displaced_step_copy_insn (struct gdbarch *gdbarch, | |
192 | return dsc; | |
193 | } | |
194 | ||
195 | +static int | |
196 | +arm_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) | |
197 | +{ | |
198 | + return (*s == '#' /* Literal number. */ | |
199 | + || *s == '[' /* Register indirection or | |
200 | + displacement. */ | |
201 | + || isalpha (*s)); /* Register value. */ | |
6ed6bacf AM |
202 | +} |
203 | + | |
f412e1b4 | 204 | +/* This routine is used to parse a special token in ARM's assembly. |
6ed6bacf | 205 | + |
f412e1b4 | 206 | + The special tokens parsed by it are: |
6ed6bacf | 207 | + |
f412e1b4 | 208 | + - Register displacement (e.g, [fp, #-8]) |
6ed6bacf | 209 | + |
f412e1b4 PS |
210 | + It returns one if the special token has been parsed successfully, |
211 | + or zero if the current token is not considered special. */ | |
6ed6bacf | 212 | + |
f412e1b4 PS |
213 | +static int |
214 | +arm_stap_parse_special_token (struct gdbarch *gdbarch, | |
215 | + struct stap_parse_info *p) | |
216 | +{ | |
217 | + if (*p->arg == '[') | |
218 | + { | |
219 | + /* Temporary holder for lookahead. */ | |
220 | + const char *tmp = p->arg; | |
221 | + /* Used to save the register name. */ | |
222 | + const char *start; | |
223 | + char *regname; | |
224 | + int len, offset; | |
225 | + int got_minus = 0; | |
226 | + long displacement; | |
227 | + struct stoken str; | |
228 | + | |
229 | + ++tmp; | |
230 | + start = tmp; | |
231 | + | |
232 | + /* Register name. */ | |
233 | + while (isalnum (*tmp)) | |
234 | + ++tmp; | |
235 | + | |
236 | + if (*tmp != ',') | |
237 | + return 0; | |
238 | + | |
239 | + len = tmp - start; | |
240 | + regname = alloca (len + 2); | |
241 | + | |
242 | + offset = 0; | |
243 | + if (isdigit (*start)) | |
244 | + { | |
245 | + /* If we are dealing with a register whose name begins with a | |
246 | + digit, it means we should prefix the name with the letter | |
247 | + `r', because GDB expects this name pattern. Otherwise (e.g., | |
248 | + we are dealing with the register `fp'), we don't need to | |
249 | + add such a prefix. */ | |
250 | + regname[0] = 'r'; | |
251 | + offset = 1; | |
252 | + } | |
6ed6bacf | 253 | + |
f412e1b4 PS |
254 | + strncpy (regname + offset, start, len); |
255 | + len += offset; | |
256 | + regname[len] = '\0'; | |
6ed6bacf | 257 | + |
f412e1b4 PS |
258 | + if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1) |
259 | + error (_("Invalid register name `%s' on expression `%s'."), | |
260 | + regname, p->saved_arg); | |
6ed6bacf | 261 | + |
f412e1b4 PS |
262 | + ++tmp; |
263 | + tmp = skip_spaces_const (tmp); | |
264 | + if (*tmp++ != '#') | |
265 | + return 0; | |
6ed6bacf | 266 | + |
f412e1b4 PS |
267 | + if (*tmp == '-') |
268 | + { | |
269 | + ++tmp; | |
270 | + got_minus = 1; | |
6ed6bacf | 271 | + } |
6ed6bacf | 272 | + |
f412e1b4 | 273 | + displacement = strtol (tmp, (char **) &tmp, 10); |
6ed6bacf | 274 | + |
f412e1b4 PS |
275 | + /* Skipping last `]'. */ |
276 | + if (*tmp++ != ']') | |
277 | + return 0; | |
6ed6bacf | 278 | + |
f412e1b4 PS |
279 | + /* The displacement. */ |
280 | + write_exp_elt_opcode (OP_LONG); | |
281 | + write_exp_elt_type (builtin_type (gdbarch)->builtin_long); | |
282 | + write_exp_elt_longcst (displacement); | |
283 | + write_exp_elt_opcode (OP_LONG); | |
284 | + if (got_minus) | |
285 | + write_exp_elt_opcode (UNOP_NEG); | |
7566401a | 286 | + |
f412e1b4 PS |
287 | + /* The register name. */ |
288 | + write_exp_elt_opcode (OP_REGISTER); | |
289 | + str.ptr = regname; | |
290 | + str.length = len; | |
291 | + write_exp_string (str); | |
292 | + write_exp_elt_opcode (OP_REGISTER); | |
6ed6bacf | 293 | + |
f412e1b4 | 294 | + write_exp_elt_opcode (BINOP_ADD); |
6ed6bacf | 295 | + |
f412e1b4 PS |
296 | + /* Casting to the expected type. */ |
297 | + write_exp_elt_opcode (UNOP_CAST); | |
298 | + write_exp_elt_type (lookup_pointer_type (p->arg_type)); | |
299 | + write_exp_elt_opcode (UNOP_CAST); | |
7566401a | 300 | + |
f412e1b4 | 301 | + write_exp_elt_opcode (UNOP_IND); |
6ed6bacf | 302 | + |
f412e1b4 PS |
303 | + p->arg = tmp; |
304 | + } | |
305 | + else | |
306 | + return 0; | |
6ed6bacf | 307 | + |
f412e1b4 PS |
308 | + return 1; |
309 | +} | |
310 | + | |
311 | static void | |
312 | arm_linux_init_abi (struct gdbarch_info info, | |
313 | struct gdbarch *gdbarch) | |
314 | @@ -1152,6 +1274,15 @@ arm_linux_init_abi (struct gdbarch_info info, | |
315 | simple_displaced_step_free_closure); | |
316 | set_gdbarch_displaced_step_location (gdbarch, displaced_step_at_entry_point); | |
317 | ||
318 | + /* SystemTap functions. */ | |
319 | + set_gdbarch_stap_integer_prefix (gdbarch, "#"); | |
320 | + set_gdbarch_stap_register_prefix (gdbarch, "r"); | |
321 | + set_gdbarch_stap_register_indirection_prefix (gdbarch, "["); | |
322 | + set_gdbarch_stap_register_indirection_sufix (gdbarch, "]"); | |
323 | + set_gdbarch_stap_gdb_register_prefix (gdbarch, "r"); | |
324 | + set_gdbarch_stap_is_single_operand (gdbarch, arm_stap_is_single_operand); | |
325 | + set_gdbarch_stap_parse_special_token (gdbarch, | |
326 | + arm_stap_parse_special_token); | |
327 | ||
328 | tdep->syscall_next_pc = arm_linux_syscall_next_pc; | |
6ed6bacf | 329 | } |
f412e1b4 PS |
330 | diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c |
331 | index 31e91b9..4518f6b 100644 | |
332 | --- a/gdb/ax-gdb.c | |
333 | +++ b/gdb/ax-gdb.c | |
334 | @@ -95,8 +95,6 @@ static void gen_int_literal (struct agent_expr *ax, | |
335 | struct axs_value *value, | |
336 | LONGEST k, struct type *type); | |
6ed6bacf | 337 | |
f412e1b4 PS |
338 | - |
339 | -static void require_rvalue (struct agent_expr *ax, struct axs_value *value); | |
340 | static void gen_usual_unary (struct expression *exp, struct agent_expr *ax, | |
341 | struct axs_value *value); | |
342 | static int type_wider_than (struct type *type1, struct type *type2); | |
343 | @@ -157,8 +155,6 @@ static void gen_repeat (struct expression *exp, union exp_element **pc, | |
344 | static void gen_sizeof (struct expression *exp, union exp_element **pc, | |
345 | struct agent_expr *ax, struct axs_value *value, | |
346 | struct type *size_type); | |
347 | -static void gen_expr (struct expression *exp, union exp_element **pc, | |
348 | - struct agent_expr *ax, struct axs_value *value); | |
349 | static void gen_expr_binop_rest (struct expression *exp, | |
350 | enum exp_opcode op, union exp_element **pc, | |
351 | struct agent_expr *ax, | |
352 | @@ -789,7 +785,7 @@ gen_int_literal (struct agent_expr *ax, struct axs_value *value, LONGEST k, | |
353 | /* Take what's on the top of the stack (as described by VALUE), and | |
354 | try to make an rvalue out of it. Signal an error if we can't do | |
355 | that. */ | |
356 | -static void | |
357 | +void | |
358 | require_rvalue (struct agent_expr *ax, struct axs_value *value) | |
359 | { | |
360 | /* Only deal with scalars, structs and such may be too large | |
361 | @@ -1807,7 +1803,7 @@ gen_sizeof (struct expression *exp, union exp_element **pc, | |
362 | /* XXX: i18n */ | |
363 | /* A gen_expr function written by a Gen-X'er guy. | |
364 | Append code for the subexpression of EXPR starting at *POS_P to AX. */ | |
365 | -static void | |
366 | +void | |
367 | gen_expr (struct expression *exp, union exp_element **pc, | |
368 | struct agent_expr *ax, struct axs_value *value) | |
369 | { | |
370 | @@ -2042,7 +2038,8 @@ gen_expr (struct expression *exp, union exp_element **pc, | |
6ed6bacf AM |
371 | |
372 | case OP_INTERNALVAR: | |
373 | { | |
374 | - const char *name = internalvar_name ((*pc)[1].internalvar); | |
375 | + struct internalvar *var = (*pc)[1].internalvar; | |
376 | + const char *name = internalvar_name (var); | |
377 | struct trace_state_variable *tsv; | |
378 | ||
379 | (*pc) += 3; | |
f412e1b4 | 380 | @@ -2056,7 +2053,7 @@ gen_expr (struct expression *exp, union exp_element **pc, |
6ed6bacf AM |
381 | value->kind = axs_rvalue; |
382 | value->type = builtin_type (exp->gdbarch)->builtin_long_long; | |
383 | } | |
384 | - else | |
385 | + else if (! compile_internalvar_to_ax (var, ax, value)) | |
386 | error (_("$%s is not a trace state variable; GDB agent " | |
387 | "expressions cannot use convenience variables."), name); | |
388 | } | |
f412e1b4 PS |
389 | diff --git a/gdb/ax-gdb.h b/gdb/ax-gdb.h |
390 | index 48c35a4..09f6889 100644 | |
391 | --- a/gdb/ax-gdb.h | |
392 | +++ b/gdb/ax-gdb.h | |
393 | @@ -110,6 +110,11 @@ extern struct agent_expr *gen_trace_for_return_address (CORE_ADDR, | |
394 | ||
395 | extern struct agent_expr *gen_eval_for_expr (CORE_ADDR, struct expression *); | |
396 | ||
397 | +extern void gen_expr (struct expression *exp, union exp_element **pc, | |
398 | + struct agent_expr *ax, struct axs_value *value); | |
399 | + | |
400 | +extern void require_rvalue (struct agent_expr *ax, struct axs_value *value); | |
401 | + | |
402 | extern int trace_kludge; | |
403 | extern int trace_string_kludge; | |
404 | ||
405 | diff --git a/gdb/block.c b/gdb/block.c | |
406 | index 57ab4c2..573630e 100644 | |
407 | --- a/gdb/block.c | |
408 | +++ b/gdb/block.c | |
409 | @@ -369,3 +369,21 @@ allocate_block (struct obstack *obstack) | |
3a58abaf | 410 | |
7566401a | 411 | return bl; |
3a58abaf | 412 | } |
3a58abaf | 413 | + |
7566401a ER |
414 | +/* Return OBJFILE in which BLOCK is located or NULL if we cannot find it for |
415 | + whatever reason. */ | |
416 | + | |
417 | +struct objfile * | |
418 | +block_objfile (const struct block *block) | |
3a58abaf | 419 | +{ |
7566401a | 420 | + struct symbol *func; |
3a58abaf | 421 | + |
7566401a ER |
422 | + if (block == NULL) |
423 | + return NULL; | |
3a58abaf | 424 | + |
7566401a ER |
425 | + func = block_linkage_function (block); |
426 | + if (func == NULL) | |
427 | + return NULL; | |
428 | + | |
429 | + return SYMBOL_SYMTAB (func)->objfile; | |
430 | +} | |
f412e1b4 PS |
431 | diff --git a/gdb/block.h b/gdb/block.h |
432 | index 2cbcc1b..104c146 100644 | |
433 | --- a/gdb/block.h | |
434 | +++ b/gdb/block.h | |
435 | @@ -167,4 +167,6 @@ extern const struct block *block_global_block (const struct block *block); | |
7566401a ER |
436 | |
437 | extern struct block *allocate_block (struct obstack *obstack); | |
438 | ||
439 | +extern struct objfile *block_objfile (const struct block *block); | |
440 | + | |
441 | #endif /* BLOCK_H */ | |
f412e1b4 PS |
442 | diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c |
443 | index f6a0276..e406156 100644 | |
444 | --- a/gdb/breakpoint.c | |
445 | +++ b/gdb/breakpoint.c | |
446 | @@ -60,6 +60,8 @@ | |
7566401a ER |
447 | #include "jit.h" |
448 | #include "xml-syscall.h" | |
51a5ef0f | 449 | #include "parser-defs.h" |
6ed6bacf AM |
450 | +#include "gdb_regex.h" |
451 | +#include "stap-probe.h" | |
452 | #include "cli/cli-utils.h" | |
f412e1b4 PS |
453 | #include "continuations.h" |
454 | #include "stack.h" | |
455 | @@ -1239,9 +1241,10 @@ is_watchpoint (const struct breakpoint *bpt) | |
456 | static int | |
457 | watchpoint_in_thread_scope (struct watchpoint *b) | |
458 | { | |
459 | - return (ptid_equal (b->watchpoint_thread, null_ptid) | |
460 | - || (ptid_equal (inferior_ptid, b->watchpoint_thread) | |
461 | - && !is_executing (inferior_ptid))); | |
462 | + return (b->base.pspace == current_program_space | |
463 | + && (ptid_equal (b->watchpoint_thread, null_ptid) | |
464 | + || (ptid_equal (inferior_ptid, b->watchpoint_thread) | |
465 | + && !is_executing (inferior_ptid)))); | |
466 | } | |
7566401a | 467 | |
f412e1b4 PS |
468 | /* Set watchpoint B to disp_del_at_next_stop, even including its possible |
469 | @@ -1648,6 +1651,40 @@ unduplicated_should_be_inserted (struct bp_location *bl) | |
470 | return result; | |
7566401a | 471 | } |
3a58abaf | 472 | |
6ed6bacf | 473 | +/* See the comment in breakpoint.h. */ |
3a58abaf | 474 | + |
7566401a | 475 | +void |
6ed6bacf | 476 | +modify_semaphore (struct bp_location *loc, int set) |
3a58abaf | 477 | +{ |
6ed6bacf AM |
478 | + struct gdbarch *arch = loc->gdbarch; |
479 | + gdb_byte bytes[sizeof (LONGEST)]; | |
480 | + /* The ABI specifies "unsigned short". */ | |
481 | + struct type *type = builtin_type (arch)->builtin_unsigned_short; | |
482 | + CORE_ADDR address = loc->semaphore; | |
483 | + ULONGEST value; | |
3a58abaf | 484 | + |
6ed6bacf AM |
485 | + if (address == 0) |
486 | + return; | |
3a58abaf | 487 | + |
6ed6bacf AM |
488 | + /* Swallow errors. */ |
489 | + if (target_read_memory (address, bytes, TYPE_LENGTH (type)) != 0) | |
490 | + return; | |
7566401a | 491 | + |
6ed6bacf AM |
492 | + value = extract_unsigned_integer (bytes, TYPE_LENGTH (type), |
493 | + gdbarch_byte_order (arch)); | |
494 | + /* Note that we explicitly don't worry about overflow or | |
495 | + underflow. */ | |
496 | + if (set) | |
497 | + ++value; | |
498 | + else | |
499 | + --value; | |
3a58abaf | 500 | + |
6ed6bacf AM |
501 | + store_unsigned_integer (bytes, TYPE_LENGTH (type), |
502 | + gdbarch_byte_order (arch), value); | |
503 | + | |
504 | + target_write_memory (address, bytes, TYPE_LENGTH (type)); | |
3a58abaf AM |
505 | +} |
506 | + | |
6ed6bacf AM |
507 | /* Insert a low-level "breakpoint" of some type. BL is the breakpoint |
508 | location. Any error messages are printed to TMP_ERROR_STREAM; and | |
509 | DISABLED_BREAKS, and HW_BREAKPOINT_ERROR are used to report problems. | |
f412e1b4 PS |
510 | @@ -1741,6 +1778,8 @@ insert_bp_location (struct bp_location *bl, |
511 | /* No overlay handling: just set the breakpoint. */ | |
512 | ||
513 | val = bl->owner->ops->insert_location (bl); | |
6ed6bacf AM |
514 | + |
515 | + modify_semaphore (bl, 1); | |
516 | } | |
517 | else | |
518 | { | |
f412e1b4 | 519 | @@ -2224,11 +2263,23 @@ struct breakpoint_objfile_data |
6ed6bacf AM |
520 | /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any). */ |
521 | struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES]; | |
7566401a | 522 | |
f412e1b4 PS |
523 | + /* True if we have looked for longjmp probes. */ |
524 | + int longjmp_searched; | |
525 | + | |
526 | + /* SystemTap probe points for longjmp (if any). */ | |
527 | + VEC (stap_probe_p) *longjmp_probes; | |
3a58abaf | 528 | + |
6ed6bacf AM |
529 | /* Minimal symbol for "std::terminate()" (if any). */ |
530 | struct minimal_symbol *terminate_msym; | |
51a5ef0f | 531 | |
6ed6bacf AM |
532 | /* Minimal symbol for "_Unwind_DebugHook" (if any). */ |
533 | struct minimal_symbol *exception_msym; | |
51a5ef0f | 534 | + |
f412e1b4 PS |
535 | + /* True if we have looked for exception probes. */ |
536 | + int exception_searched; | |
537 | + | |
538 | + /* SystemTap probe points for unwinding (if any). */ | |
539 | + VEC (stap_probe_p) *exception_probes; | |
6ed6bacf | 540 | }; |
51a5ef0f | 541 | |
6ed6bacf | 542 | static const struct objfile_data *breakpoint_objfile_key; |
f412e1b4 PS |
543 | @@ -2265,6 +2316,15 @@ get_breakpoint_objfile_data (struct objfile *objfile) |
544 | } | |
3a58abaf | 545 | |
f412e1b4 PS |
546 | static void |
547 | +free_breakpoint_probes (struct objfile *obj, void *data) | |
548 | +{ | |
549 | + struct breakpoint_objfile_data *bp_objfile_data = data; | |
6ed6bacf | 550 | + |
f412e1b4 PS |
551 | + VEC_free (stap_probe_p, bp_objfile_data->longjmp_probes); |
552 | + VEC_free (stap_probe_p, bp_objfile_data->exception_probes); | |
553 | +} | |
554 | + | |
555 | +static void | |
556 | create_overlay_event_breakpoint (void) | |
557 | { | |
558 | struct objfile *objfile; | |
559 | @@ -2341,6 +2401,37 @@ create_longjmp_master_breakpoint (void) | |
7566401a | 560 | |
6ed6bacf | 561 | bp_objfile_data = get_breakpoint_objfile_data (objfile); |
7566401a | 562 | |
f412e1b4 | 563 | + if (!bp_objfile_data->longjmp_searched) |
6ed6bacf | 564 | + { |
f412e1b4 PS |
565 | + bp_objfile_data->longjmp_probes |
566 | + = find_probes_in_objfile (objfile, "libc", "longjmp"); | |
567 | + bp_objfile_data->longjmp_searched = 1; | |
568 | + } | |
6ed6bacf | 569 | + |
f412e1b4 PS |
570 | + if (bp_objfile_data->longjmp_probes != NULL) |
571 | + { | |
572 | + int i; | |
573 | + struct stap_probe *probe; | |
574 | + struct gdbarch *gdbarch = get_objfile_arch (objfile); | |
575 | + | |
576 | + for (i = 0; | |
577 | + VEC_iterate (stap_probe_p, | |
578 | + bp_objfile_data->longjmp_probes, | |
579 | + i, probe); | |
580 | + ++i) | |
51a5ef0f | 581 | + { |
6ed6bacf | 582 | + struct breakpoint *b; |
f412e1b4 PS |
583 | + |
584 | + b = create_internal_breakpoint (gdbarch, probe->address, | |
585 | + bp_longjmp_master, | |
586 | + &internal_breakpoint_ops); | |
587 | + b->addr_string = xstrdup ("-p libc:longjmp"); | |
6ed6bacf | 588 | + b->enable_state = bp_disabled; |
51a5ef0f | 589 | + } |
f412e1b4 PS |
590 | + |
591 | + continue; | |
51a5ef0f | 592 | + } |
51a5ef0f | 593 | + |
6ed6bacf AM |
594 | for (i = 0; i < NUM_LONGJMP_NAMES; i++) |
595 | { | |
596 | struct breakpoint *b; | |
f412e1b4 | 597 | @@ -2451,6 +2542,40 @@ create_exception_master_breakpoint (void) |
51a5ef0f | 598 | |
6ed6bacf | 599 | bp_objfile_data = get_breakpoint_objfile_data (objfile); |
51a5ef0f | 600 | |
6ed6bacf | 601 | + /* We prefer the SystemTap probe point if it exists. */ |
f412e1b4 | 602 | + if (!bp_objfile_data->exception_searched) |
51a5ef0f | 603 | + { |
f412e1b4 PS |
604 | + bp_objfile_data->exception_probes |
605 | + = find_probes_in_objfile (objfile, "libgcc", "unwind"); | |
606 | + bp_objfile_data->exception_searched = 1; | |
607 | + } | |
51a5ef0f | 608 | + |
f412e1b4 PS |
609 | + if (bp_objfile_data->exception_probes != NULL) |
610 | + { | |
611 | + struct gdbarch *gdbarch = get_objfile_arch (objfile); | |
612 | + int i; | |
613 | + struct stap_probe *probe; | |
614 | + | |
615 | + for (i = 0; | |
616 | + VEC_iterate (stap_probe_p, | |
617 | + bp_objfile_data->exception_probes, | |
618 | + i, probe); | |
619 | + ++i) | |
51a5ef0f | 620 | + { |
6ed6bacf | 621 | + struct breakpoint *b; |
6ed6bacf | 622 | + |
f412e1b4 PS |
623 | + b = create_internal_breakpoint (gdbarch, probe->address, |
624 | + bp_exception_master, | |
625 | + &internal_breakpoint_ops); | |
626 | + b->addr_string = xstrdup ("-p libgcc:unwind"); | |
6ed6bacf | 627 | + b->enable_state = bp_disabled; |
51a5ef0f | 628 | + } |
f412e1b4 PS |
629 | + |
630 | + continue; | |
51a5ef0f PS |
631 | + } |
632 | + | |
6ed6bacf AM |
633 | + /* Otherwise, try the hook function. */ |
634 | + | |
635 | if (msym_not_found_p (bp_objfile_data->exception_msym)) | |
636 | continue; | |
7566401a | 637 | |
f412e1b4 PS |
638 | @@ -2666,6 +2791,8 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is) |
639 | { | |
640 | /* No overlay handling: just remove the breakpoint. */ | |
641 | val = bl->owner->ops->remove_location (bl); | |
6ed6bacf AM |
642 | + |
643 | + modify_semaphore (bl, 0); | |
644 | } | |
645 | else | |
646 | { | |
f412e1b4 | 647 | @@ -7111,6 +7238,7 @@ momentary_breakpoint_from_master (struct breakpoint *orig, |
6ed6bacf AM |
648 | copy->loc->address = orig->loc->address; |
649 | copy->loc->section = orig->loc->section; | |
650 | copy->loc->pspace = orig->loc->pspace; | |
651 | + copy->loc->semaphore = orig->loc->semaphore; | |
652 | ||
f412e1b4 PS |
653 | if (orig->loc->source_file != NULL) |
654 | copy->loc->source_file = xstrdup (orig->loc->source_file); | |
655 | @@ -7196,6 +7324,7 @@ add_location_to_breakpoint (struct breakpoint *b, | |
656 | loc->requested_address = sal->pc; | |
657 | loc->address = adjusted_address; | |
6ed6bacf AM |
658 | loc->pspace = sal->pspace; |
659 | + loc->semaphore = sal->semaphore; | |
51a5ef0f PS |
660 | gdb_assert (loc->pspace != NULL); |
661 | loc->section = sal->section; | |
f412e1b4 PS |
662 | loc->gdbarch = loc_gdbarch; |
663 | @@ -13521,6 +13650,24 @@ all_tracepoints (void) | |
7566401a | 664 | return tp_vec; |
3a58abaf | 665 | } |
3a58abaf | 666 | |
6ed6bacf | 667 | +#if 0 |
7566401a ER |
668 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ |
669 | + | |
670 | +static void | |
671 | +breakpoint_types_mark_used (void) | |
672 | +{ | |
673 | + struct breakpoint *b; | |
3a58abaf | 674 | + |
7566401a ER |
675 | + ALL_BREAKPOINTS (b) |
676 | + { | |
677 | + if (b->exp) | |
678 | + exp_types_mark_used (b->exp); | |
679 | + if (b->val) | |
680 | + type_mark_used (value_type (b->val)); | |
681 | + } | |
682 | +} | |
6ed6bacf | 683 | +#endif |
3a58abaf | 684 | + |
7566401a | 685 | \f |
6ed6bacf AM |
686 | /* This help string is used for the break, hbreak, tbreak and thbreak |
687 | commands. It is defined as a macro to prevent duplication. | |
f412e1b4 PS |
688 | @@ -13815,7 +13962,8 @@ _initialize_breakpoint (void) |
689 | observer_attach_inferior_exit (clear_syscall_counts); | |
690 | observer_attach_memory_changed (invalidate_bp_value_on_memory_change); | |
691 | ||
692 | - breakpoint_objfile_key = register_objfile_data (); | |
693 | + breakpoint_objfile_key | |
694 | + = register_objfile_data_with_cleanup (NULL, free_breakpoint_probes); | |
695 | ||
696 | breakpoint_chain = 0; | |
697 | /* Don't bother to call set_breakpoint_count. $bpnum isn't useful | |
698 | @@ -14340,4 +14488,7 @@ range (including START-LOCATION and END-LOCATION).")); | |
7566401a | 699 | automatic_hardware_breakpoints = 1; |
3a58abaf | 700 | |
7566401a | 701 | observer_attach_about_to_proceed (breakpoint_about_to_proceed); |
6ed6bacf | 702 | +#if 0 |
7566401a | 703 | + observer_attach_mark_used (breakpoint_types_mark_used); |
6ed6bacf AM |
704 | +#endif |
705 | } | |
f412e1b4 PS |
706 | diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h |
707 | index 8a8d5f2..1e18562 100644 | |
708 | --- a/gdb/breakpoint.h | |
709 | +++ b/gdb/breakpoint.h | |
710 | @@ -379,6 +379,11 @@ struct bp_location | |
6ed6bacf AM |
711 | processor's architectual constraints. */ |
712 | CORE_ADDR requested_address; | |
713 | ||
714 | + /* If the location comes from a SystemTap probe point, and the probe | |
715 | + has an associated semaphore variable, then this is the address of | |
716 | + the semaphore. Otherwise, this is zero. */ | |
717 | + CORE_ADDR semaphore; | |
718 | + | |
719 | char *function_name; | |
720 | ||
721 | /* Details of the placed breakpoint, when inserted. */ | |
f412e1b4 PS |
722 | @@ -1412,4 +1417,11 @@ extern int user_breakpoint_p (struct breakpoint *); |
723 | /* Attempt to determine architecture of location identified by SAL. */ | |
724 | extern struct gdbarch *get_sal_arch (struct symtab_and_line sal); | |
6ed6bacf AM |
725 | |
726 | +/* Set or clear a SystemTap semaphore. LOC is the location which may | |
727 | + hold a semaphore. SET is non-zero if the semaphore should be set, | |
728 | + or zero if the semaphore should be cleared. Semaphores act as | |
729 | + reference counters, so calls to this function must be paired. */ | |
730 | + | |
731 | +extern void modify_semaphore (struct bp_location *location, int set); | |
732 | + | |
733 | #endif /* !defined (BREAKPOINT_H) */ | |
f412e1b4 PS |
734 | diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c |
735 | index db254dc..181de05 100644 | |
736 | --- a/gdb/c-typeprint.c | |
737 | +++ b/gdb/c-typeprint.c | |
738 | @@ -624,9 +624,14 @@ c_type_print_varspec_suffix (struct type *type, | |
6ed6bacf AM |
739 | fprintf_filtered (stream, ")"); |
740 | ||
741 | fprintf_filtered (stream, "["); | |
742 | - if (get_array_bounds (type, &low_bound, &high_bound)) | |
743 | - fprintf_filtered (stream, "%d", | |
744 | - (int) (high_bound - low_bound + 1)); | |
745 | + if (TYPE_RANGE_DATA (TYPE_INDEX_TYPE (type))->high.kind | |
746 | + != RANGE_BOUND_KIND_CONSTANT) | |
747 | + { | |
748 | + /* No _() - printed sources should not be locale dependent. */ | |
749 | + fprintf_filtered (stream, "variable"); | |
750 | + } | |
751 | + else if (get_array_bounds (type, &low_bound, &high_bound)) | |
752 | + fprintf_filtered (stream, "%d", (int) (high_bound - low_bound + 1)); | |
753 | fprintf_filtered (stream, "]"); | |
754 | ||
755 | c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, | |
f412e1b4 PS |
756 | diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c |
757 | index a7b2718..a1e5161 100644 | |
758 | --- a/gdb/cli/cli-utils.c | |
759 | +++ b/gdb/cli/cli-utils.c | |
760 | @@ -223,6 +223,18 @@ skip_spaces (char *chp) | |
761 | return chp; | |
762 | } | |
763 | ||
764 | +/* A const-correct version of the above. */ | |
765 | + | |
766 | +const char * | |
767 | +skip_spaces_const (const char *chp) | |
768 | +{ | |
769 | + if (chp == NULL) | |
770 | + return NULL; | |
771 | + while (*chp && isspace (*chp)) | |
772 | + chp++; | |
773 | + return chp; | |
774 | +} | |
775 | + | |
776 | /* See documentation in cli-utils.h. */ | |
777 | ||
778 | char * | |
779 | @@ -245,3 +257,32 @@ remove_trailing_whitespace (const char *start, char *s) | |
6ed6bacf AM |
780 | |
781 | return s; | |
7566401a | 782 | } |
3a58abaf | 783 | + |
6ed6bacf | 784 | +/* See documentation in cli-utils.h. */ |
3a58abaf | 785 | + |
6ed6bacf AM |
786 | +char * |
787 | +extract_arg (char **arg) | |
788 | +{ | |
789 | + char *result, *copy; | |
3a58abaf | 790 | + |
6ed6bacf AM |
791 | + if (!*arg) |
792 | + return NULL; | |
3a58abaf | 793 | + |
6ed6bacf AM |
794 | + /* Find the start of the argument. */ |
795 | + *arg = skip_spaces (*arg); | |
796 | + if (! **arg) | |
797 | + return NULL; | |
798 | + result = *arg; | |
7566401a | 799 | + |
6ed6bacf AM |
800 | + /* Find the end of the argument. */ |
801 | + *arg = skip_to_space (*arg + 1); | |
3a58abaf | 802 | + |
6ed6bacf AM |
803 | + if (result == *arg) |
804 | + return NULL; | |
3a58abaf | 805 | + |
6ed6bacf AM |
806 | + copy = xmalloc (*arg - result + 1); |
807 | + memcpy (copy, result, *arg - result); | |
808 | + copy[*arg - result] = '\0'; | |
3a58abaf | 809 | + |
6ed6bacf AM |
810 | + return copy; |
811 | +} | |
f412e1b4 PS |
812 | diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h |
813 | index e23c7d8..5f8a91d 100644 | |
814 | --- a/gdb/cli/cli-utils.h | |
815 | +++ b/gdb/cli/cli-utils.h | |
816 | @@ -94,6 +94,10 @@ extern int number_is_in_list (char *list, int number); | |
817 | ||
818 | extern char *skip_spaces (char *inp); | |
819 | ||
820 | +/* A const-correct version of the above. */ | |
821 | + | |
822 | +extern const char *skip_spaces_const (const char *inp); | |
823 | + | |
824 | /* Skip leading non-whitespace characters in INP, returning an updated | |
825 | pointer. If INP is NULL, return NULL. */ | |
826 | ||
827 | @@ -103,4 +107,11 @@ extern char *skip_to_space (char *inp); | |
6ed6bacf AM |
828 | START. */ |
829 | ||
830 | extern char *remove_trailing_whitespace (const char *start, char *s); | |
3a58abaf | 831 | + |
6ed6bacf AM |
832 | +/* A helper function to extract an argument from *ARG. An argument is |
833 | + delimited by whitespace. The return value is either NULL if no | |
834 | + argument was found, or an xmalloc'd string. */ | |
3a58abaf | 835 | + |
6ed6bacf | 836 | +extern char *extract_arg (char **arg); |
3a58abaf | 837 | + |
6ed6bacf | 838 | #endif /* CLI_UTILS_H */ |
f412e1b4 PS |
839 | diff --git a/gdb/coffread.c b/gdb/coffread.c |
840 | index c727228..e1fab6d 100644 | |
841 | --- a/gdb/coffread.c | |
842 | +++ b/gdb/coffread.c | |
843 | @@ -2195,6 +2195,7 @@ static const struct sym_fns coff_sym_fns = | |
3a58abaf | 844 | |
6ed6bacf AM |
845 | default_symfile_relocate, /* sym_relocate: Relocate a debug |
846 | section. */ | |
847 | + NULL, /* sym_probe_fns */ | |
848 | &psym_functions | |
849 | }; | |
3a58abaf | 850 | |
f412e1b4 PS |
851 | diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in |
852 | index 4296e5a..b04d12f 100644 | |
853 | --- a/gdb/data-directory/Makefile.in | |
854 | +++ b/gdb/data-directory/Makefile.in | |
855 | @@ -52,13 +52,24 @@ SYSCALLS_FILES = \ | |
6ed6bacf AM |
856 | PYTHON_DIR = python |
857 | PYTHON_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(PYTHON_DIR) | |
858 | PYTHON_FILES = \ | |
859 | + gdb/FrameIterator.py \ | |
860 | + gdb/FrameWrapper.py \ | |
861 | gdb/__init__.py \ | |
862 | - gdb/types.py \ | |
863 | - gdb/printing.py \ | |
f412e1b4 | 864 | - gdb/prompt.py \ |
6ed6bacf AM |
865 | + gdb/backtrace.py \ |
866 | gdb/command/__init__.py \ | |
6ed6bacf AM |
867 | + gdb/command/backtrace.py \ |
868 | + gdb/command/ignore_errors.py \ | |
869 | + gdb/command/pahole.py \ | |
f412e1b4 PS |
870 | gdb/command/pretty_printers.py \ |
871 | - gdb/command/prompt.py | |
872 | + gdb/command/prompt.py \ | |
6ed6bacf AM |
873 | + gdb/command/require.py \ |
874 | + gdb/command/upto.py \ | |
875 | + gdb/function/__init__.py \ | |
876 | + gdb/function/caller_is.py \ | |
877 | + gdb/function/in_scope.py \ | |
878 | + gdb/printing.py \ | |
f412e1b4 | 879 | + gdb/prompt.py \ |
6ed6bacf AM |
880 | + gdb/types.py |
881 | ||
882 | FLAGS_TO_PASS = \ | |
883 | "prefix=$(prefix)" \ | |
f412e1b4 PS |
884 | diff --git a/gdb/dbxread.c b/gdb/dbxread.c |
885 | index adf8315..c11e4d4 100644 | |
886 | --- a/gdb/dbxread.c | |
887 | +++ b/gdb/dbxread.c | |
888 | @@ -3588,6 +3588,7 @@ static const struct sym_fns aout_sym_fns = | |
6ed6bacf AM |
889 | default_symfile_segments, /* Get segment information from a file. */ |
890 | NULL, | |
891 | default_symfile_relocate, /* Relocate a debug section. */ | |
892 | + NULL, /* sym_probe_fns */ | |
893 | &psym_functions | |
894 | }; | |
3a58abaf | 895 | |
f412e1b4 PS |
896 | diff --git a/gdb/defs.h b/gdb/defs.h |
897 | index 83a716a..7f8752e 100644 | |
898 | --- a/gdb/defs.h | |
899 | +++ b/gdb/defs.h | |
900 | @@ -411,6 +411,8 @@ extern struct cleanup *make_cleanup_restore_page_info (void); | |
6ed6bacf AM |
901 | extern struct cleanup * |
902 | set_batch_flag_and_make_cleanup_restore_page_info (void); | |
903 | ||
904 | +extern struct cleanup *make_cleanup_restore_selected_frame (void); | |
3a58abaf | 905 | + |
6ed6bacf AM |
906 | extern char *gdb_realpath (const char *); |
907 | extern char *xfullpath (const char *); | |
908 | ||
f412e1b4 PS |
909 | diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo |
910 | index 20b0b67..57068c3 100644 | |
911 | --- a/gdb/doc/gdb.texinfo | |
912 | +++ b/gdb/doc/gdb.texinfo | |
913 | @@ -1173,6 +1173,16 @@ for remote debugging. | |
51a5ef0f PS |
914 | Run using @var{device} for your program's standard input and output. |
915 | @c FIXME: kingdon thinks there is more to -tty. Investigate. | |
3a58abaf AM |
916 | |
917 | +@item -P | |
918 | +@cindex @code{-P} | |
919 | +@itemx --python | |
920 | +@cindex @code{--python} | |
921 | +Change interpretation of command line so that the argument immediately | |
922 | +following this switch is taken to be the name of a Python script file. | |
923 | +This option stops option processing; subsequent options are passed to | |
924 | +Python as @code{sys.argv}. This option is only available if Python | |
925 | +scripting support was enabled when @value{GDBN} was configured. | |
926 | + | |
927 | @c resolve the situation of these eventually | |
928 | @item -tui | |
929 | @cindex @code{--tui} | |
f412e1b4 | 930 | @@ -3301,6 +3311,7 @@ all breakpoints in that range are operated on. |
6ed6bacf AM |
931 | * Conditions:: Break conditions |
932 | * Break Commands:: Breakpoint command lists | |
933 | * Save Breakpoints:: How to save breakpoints in a file | |
934 | +* Static Probe Points:: Listing static probe points | |
935 | * Error in Breakpoints:: ``Cannot insert breakpoints'' | |
936 | * Breakpoint-related Warnings:: ``Breakpoint address adjusted...'' | |
51a5ef0f | 937 | @end menu |
f412e1b4 | 938 | @@ -4530,6 +4541,50 @@ and remove the breakpoint definitions you're not interested in, or |
6ed6bacf AM |
939 | that can no longer be recreated. |
940 | @end table | |
3a58abaf | 941 | |
6ed6bacf AM |
942 | +@node Static Probe Points |
943 | +@subsection Static Probe Points | |
3a58abaf | 944 | + |
6ed6bacf AM |
945 | +@cindex SystemTap static probe point |
946 | +@cindex sdt-probe | |
947 | +The @sc{gnu}/Linux tool @code{SystemTap} provides a way for | |
948 | +applications to embed static probes, using @file{sys/sdt.h}. @value{GDBN} | |
949 | +can list the available probes, and you can put breakpoints at the | |
950 | +probe points (@pxref{Specify Location}). | |
51a5ef0f | 951 | + |
6ed6bacf AM |
952 | +You can examine the available @code{SystemTap} static probes using |
953 | +@code{info probes}: | |
51a5ef0f PS |
954 | + |
955 | +@table @code | |
6ed6bacf AM |
956 | +@kindex info probes |
957 | +@item info probes [@var{provider} [@var{name} [@var{objfile}]]] | |
958 | +List the available @code{SystemTap} static probes. | |
959 | + | |
960 | +If given, @var{provider} is a regular expression used to select which | |
961 | +providers to list. If omitted, all providers are listed. | |
51a5ef0f | 962 | + |
6ed6bacf AM |
963 | +If given, @var{name} is a regular expression used to select which |
964 | +probes to list. If omitted, all probes are listed. | |
51a5ef0f | 965 | + |
6ed6bacf AM |
966 | +If given, @var{objfile} is a regular expression used to select which |
967 | +object files (executable or shared libraries) to examine. If not | |
968 | +given, all object files are considered. | |
969 | +@end table | |
51a5ef0f | 970 | + |
6ed6bacf AM |
971 | +@vindex $_probe_arg@r{, convenience variable} |
972 | +A probe may specify up to ten arguments. These are available at the | |
973 | +point at which the probe is defined---that is, when the current PC is | |
974 | +at the probe's location. The arguments are available using the | |
975 | +convenience variables (@pxref{Convenience Vars}) | |
f412e1b4 | 976 | +@code{$_probe_arg0}@dots{}@code{$_probe_arg11}. Each probe argument is |
6ed6bacf AM |
977 | +an integer of the appropriate size; types are not preserved. The |
978 | +convenience variable @code{$_probe_argc} holds the number of arguments | |
979 | +at the current probe point. | |
980 | + | |
981 | +These variables are always available, but attempts to access them at | |
982 | +any location other than a probe point will cause @value{GDBN} to give | |
983 | +an error. | |
984 | + | |
985 | + | |
986 | @c @ifclear BARETARGET | |
987 | @node Error in Breakpoints | |
988 | @subsection ``Cannot insert breakpoints'' | |
f412e1b4 | 989 | @@ -6555,6 +6610,29 @@ specify the function unambiguously, e.g., if there are several |
6ed6bacf AM |
990 | functions with identical names in different source files. |
991 | @end table | |
992 | ||
993 | +@cindex SystemTap static probe point | |
f412e1b4 | 994 | +@item -p @r{[}@var{objfile}:@r{]}@r{[}@var{provider}:@r{]}@var{name} |
6ed6bacf AM |
995 | +The @sc{gnu}/Linux tool @code{SystemTap} provides a way for |
996 | +applications to embed static probes. This form of linespec specifies | |
997 | +the location of such a static probe. See | |
998 | +@uref{http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps} | |
999 | +for more information on static probes. | |
1000 | + | |
1001 | +If @var{objfile} is given, only probes coming from that shared library | |
1002 | +or executable are considered. If @var{provider} is given, then only | |
1003 | +probes from that provider are considered. | |
1004 | + | |
1005 | +@xref{Static Probe Points}, for more information on finding and using | |
1006 | +static probes. | |
1007 | + | |
1008 | +Some probes have an associated semaphore variable; for instance, this | |
1009 | +happens automatically if you defined your probe using a DTrace-style | |
1010 | +@file{.d} file. If your probe has a semaphore, @value{GDBN} will | |
1011 | +automatically enable it when you specify a breakpoint using the | |
f412e1b4 | 1012 | +@samp{-p} notation. But, if you put a breakpoint at a probe's |
6ed6bacf AM |
1013 | +location by some other method (e.g., @code{break file:line}), then |
1014 | +@value{GDBN} will not automatically set the semaphore. | |
51a5ef0f | 1015 | + |
6ed6bacf AM |
1016 | @end table |
1017 | ||
1018 | ||
f412e1b4 | 1019 | @@ -8811,6 +8889,10 @@ to match the format in which the data was printed. |
6ed6bacf AM |
1020 | The variable @code{$_exitcode} is automatically set to the exit code when |
1021 | the program being debugged terminates. | |
1022 | ||
1023 | +@item $_probe_argc | |
f412e1b4 | 1024 | +@itemx $_probe_arg0@dots{}$_probe_arg11 |
6ed6bacf | 1025 | +Arguments to a SystemTap static probe. @xref{Static Probe Points}. |
51a5ef0f | 1026 | + |
6ed6bacf AM |
1027 | @item $_sdata |
1028 | @vindex $_sdata@r{, inspect, convenience variable} | |
1029 | The variable @code{$_sdata} contains extra collected static tracepoint | |
f412e1b4 PS |
1030 | @@ -10763,6 +10845,16 @@ Collect all local variables. |
1031 | Collect the return address. This is helpful if you want to see more | |
1032 | of a backtrace. | |
51a5ef0f | 1033 | |
6ed6bacf AM |
1034 | +@item $_probe_argc |
1035 | +Collects the number of arguments from the @code{SystemTap} probe at | |
1036 | +which the tracepoint is located. | |
f412e1b4 | 1037 | +@xref{Static Probe Points,,Static Probe Points}. |
6ed6bacf AM |
1038 | + |
1039 | +@item $_probe_arg@var{N} | |
f412e1b4 | 1040 | +Where @var{N} varies from 0 to 11. Collects the @var{N}th argument |
6ed6bacf | 1041 | +from the @code{SystemTap} probe at which the tracepoint is located. |
f412e1b4 | 1042 | +@xref{Static Probe Points,,Static Probe Points}. |
6ed6bacf AM |
1043 | + |
1044 | @item $_sdata | |
1045 | @vindex $_sdata@r{, collect} | |
1046 | Collect static tracepoint marker specific data. Only available for | |
f412e1b4 | 1047 | @@ -21506,8 +21598,6 @@ containing @code{end}. For example: |
3a58abaf AM |
1048 | |
1049 | @smallexample | |
1050 | (@value{GDBP}) python | |
1051 | -Type python script | |
1052 | -End with a line saying just "end". | |
1053 | >print 23 | |
1054 | >end | |
1055 | 23 | |
f412e1b4 PS |
1056 | @@ -21521,6 +21611,14 @@ controlled using @code{set python print-stack}: if @code{full}, then |
1057 | full Python stack printing is enabled; if @code{none}, then Python stack | |
1058 | and message printing is disabled; if @code{message}, the default, only | |
1059 | the message component of the error is printed. | |
3a58abaf AM |
1060 | + |
1061 | +@kindex maint set python auto-load | |
1062 | +@item maint set python auto-load | |
1063 | +By default, @value{GDBN} will attempt to automatically load Python | |
1064 | +code when an object file is opened. This can be controlled using | |
1065 | +@code{maint set python auto-load}: if @code{on}, the default, then | |
1066 | +Python auto-loading is enabled; if @code{off}, then Python | |
1067 | +auto-loading is disabled. | |
1068 | @end table | |
1069 | ||
51a5ef0f | 1070 | It is also possible to execute a Python script from the @value{GDBN} |
f412e1b4 | 1071 | @@ -21542,6 +21640,14 @@ and thus is always available. |
3a58abaf AM |
1072 | @cindex python api |
1073 | @cindex programming in python | |
1074 | ||
1075 | +You can get quick online help for @value{GDBN}'s Python API by issuing | |
1076 | +the command @w{@kbd{python help (gdb)}}. | |
1077 | + | |
1078 | +Functions and methods which have two or more optional arguments allow | |
1079 | +them to be specified using keyword syntax. This allows passing some | |
1080 | +optional arguments while skipping others. Example: | |
1081 | +@w{@code{gdb.some_function ('foo', bar = 1, baz = 2)}}. | |
1082 | + | |
1083 | @cindex python stdout | |
1084 | @cindex python pagination | |
1085 | At startup, @value{GDBN} overrides Python's @code{sys.stdout} and | |
f412e1b4 PS |
1086 | diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo |
1087 | index 026dc59..f0f6ee3 100644 | |
1088 | --- a/gdb/doc/gdbint.texinfo | |
1089 | +++ b/gdb/doc/gdbint.texinfo | |
1090 | @@ -2103,6 +2103,18 @@ time, and so we attempt to handle symbols incrementally. For instance, | |
7566401a ER |
1091 | we create @dfn{partial symbol tables} consisting of only selected |
1092 | symbols, and only expand them to full symbol tables when necessary. | |
1093 | ||
1094 | +@menu | |
1095 | +* Symbol Reading:: | |
1096 | +* Partial Symbol Tables:: | |
1097 | +* Types:: | |
1098 | +* Object File Formats:: | |
1099 | +* Debugging File Formats:: | |
1100 | +* Adding a New Symbol Reader to GDB:: | |
1101 | +* Memory Management for Symbol Files:: | |
1102 | +* Memory Management for Types:: | |
1103 | +@end menu | |
1104 | + | |
1105 | +@node Symbol Reading | |
1106 | @section Symbol Reading | |
1107 | ||
1108 | @cindex symbol reading | |
f412e1b4 | 1109 | @@ -2195,6 +2207,7 @@ symtab. Upon return, @code{pst->readin} should have been set to 1, and |
7566401a ER |
1110 | zero if there were no symbols in that part of the symbol file. |
1111 | @end table | |
3a58abaf | 1112 | |
7566401a ER |
1113 | +@node Partial Symbol Tables |
1114 | @section Partial Symbol Tables | |
1115 | ||
1116 | @value{GDBN} has three types of symbol tables: | |
f412e1b4 | 1117 | @@ -2296,6 +2309,7 @@ and partial symbol tables behind a set of function pointers known as |
51a5ef0f PS |
1118 | the @dfn{quick symbol functions}. These are documented in |
1119 | @file{symfile.h}. | |
7566401a ER |
1120 | |
1121 | +@node Types | |
1122 | @section Types | |
1123 | ||
1124 | @unnumberedsubsec Fundamental Types (e.g., @code{FT_VOID}, @code{FT_BOOLEAN}). | |
f412e1b4 | 1125 | @@ -2318,6 +2332,7 @@ types map to one @code{TYPE_CODE_*} type, and are distinguished by |
7566401a ER |
1126 | other members of the type struct, such as whether the type is signed |
1127 | or unsigned, and how many bits it uses. | |
1128 | ||
1129 | +@anchor{Builtin Types} | |
1130 | @unnumberedsubsec Builtin Types (e.g., @code{builtin_type_void}, @code{builtin_type_char}). | |
1131 | ||
1132 | These are instances of type structs that roughly correspond to | |
f412e1b4 | 1133 | @@ -2332,6 +2347,7 @@ only one instance exists, while @file{c-lang.c} builds as many |
7566401a ER |
1134 | @code{TYPE_CODE_INT} types as needed, with each one associated with |
1135 | some particular objfile. | |
1136 | ||
1137 | +@node Object File Formats | |
1138 | @section Object File Formats | |
1139 | @cindex object file formats | |
1140 | ||
f412e1b4 | 1141 | @@ -2417,6 +2433,7 @@ SOM, which is a cross-language ABI). |
7566401a ER |
1142 | |
1143 | The SOM reader is in @file{somread.c}. | |
1144 | ||
1145 | +@node Debugging File Formats | |
1146 | @section Debugging File Formats | |
1147 | ||
1148 | This section describes characteristics of debugging information that | |
f412e1b4 | 1149 | @@ -2488,6 +2505,7 @@ DWARF 3 is an improved version of DWARF 2. |
7566401a ER |
1150 | @cindex SOM debugging info |
1151 | Like COFF, the SOM definition includes debugging information. | |
1152 | ||
1153 | +@node Adding a New Symbol Reader to GDB | |
1154 | @section Adding a New Symbol Reader to @value{GDBN} | |
1155 | ||
1156 | @cindex adding debugging info reader | |
f412e1b4 | 1157 | @@ -2510,6 +2528,7 @@ will only ever be implemented by one object file format may be called |
7566401a ER |
1158 | directly. This interface should be described in a file |
1159 | @file{bfd/lib@var{xyz}.h}, which is included by @value{GDBN}. | |
1160 | ||
1161 | +@node Memory Management for Symbol Files | |
1162 | @section Memory Management for Symbol Files | |
1163 | ||
1164 | Most memory associated with a loaded symbol file is stored on | |
f412e1b4 | 1165 | @@ -2521,10 +2540,45 @@ released when the objfile is unloaded or reloaded. Therefore one |
7566401a ER |
1166 | objfile must not reference symbol or type data from another objfile; |
1167 | they could be unloaded at different times. | |
1168 | ||
1169 | -User convenience variables, et cetera, have associated types. Normally | |
1170 | -these types live in the associated objfile. However, when the objfile | |
1171 | -is unloaded, those types are deep copied to global memory, so that | |
1172 | -the values of the user variables and history items are not lost. | |
1173 | +@node Memory Management for Types | |
1174 | +@section Memory Management for Types | |
1175 | +@cindex memory management for types | |
1176 | + | |
1177 | +@findex TYPE_OBJFILE | |
1178 | +@code{TYPE_OBJFILE} macro indicates the current memory owner of the type. | |
1179 | +Non-@code{NULL} value indicates it is owned by an objfile (specifically by its | |
1180 | +obstack) and in such case the type remains valid till the objfile is unloaded | |
1181 | +or reloaded. For such types with an associated objfile no reference counting | |
1182 | +is being made. | |
1183 | + | |
1184 | +User convenience variables, et cetera, have associated types. Normally these | |
1185 | +types live in the associated objfile. However, when the objfile is unloaded, | |
1186 | +those types are deep copied to global memory, so that the values of the user | |
1187 | +variables and history items are not lost. During the copy they will get their | |
1188 | +@code{TYPE_OBJFILE} set to @code{NULL} and become so-called @dfn{reclaimable} | |
1189 | +types. | |
1190 | + | |
1191 | +Types with null @code{TYPE_OBJFILE} can be either permanent types | |
1192 | +(@pxref{Builtin Types}) or reclaimable types which will be deallocated at the | |
1193 | +first idle @value{GDBN} moment if the last object referencing them is removed. | |
1194 | +Permanent types are allocated by the function @code{alloc_type} (and its | |
1195 | +derivations like @code{init_type}) specifying objfile as @code{NULL}. The | |
1196 | +reclaimable types are created the same way but moreover they need to have | |
1197 | +@code{type_init_group} called to start their tracking as being possibly | |
1198 | +deallocatable. | |
1199 | + | |
1200 | +@findex free_all_types | |
1201 | +When @value{GDBN} gets idle it always calls the @code{free_all_types} function | |
1202 | +which deallocates any unused types. All types currently not owned by an | |
1203 | +objfile must be marked as used on each @code{free_all_types} call as they would | |
1204 | +get deallocated as unused otherwise. | |
1205 | + | |
1206 | +@code{free_all_types} automatically checks for any cross-type references such | |
1207 | +as through @code{TYPE_TARGET_TYPE}, @code{TYPE_POINTER_TYPE} etc.@: and | |
1208 | +prevents early deallocation for any such existing references. Reclaimable | |
1209 | +types may reference any other reclaimable types or even permanent types. But | |
1210 | +permanent types must not reference reclaimable types (nor an objfile associated | |
1211 | +type). | |
1212 | ||
1213 | ||
1214 | @node Language Support | |
f412e1b4 PS |
1215 | diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi |
1216 | index 24233cb..efb2013 100644 | |
1217 | --- a/gdb/doc/observer.texi | |
1218 | +++ b/gdb/doc/observer.texi | |
1219 | @@ -226,6 +226,11 @@ Called before a top-level prompt is displayed. @var{current_prompt} is | |
1220 | the current top-level prompt. | |
7566401a ER |
1221 | @end deftypefun |
1222 | ||
6ed6bacf AM |
1223 | +@c @deftypefun void mark_used (void) |
1224 | +@c Mark any possibly reclaimable objects as used during a mark-and-sweep garbage | |
1225 | +@c collector pass. Currently only @code{type_mark_used} marker is supported. | |
1226 | +@c @end deftypefun | |
7566401a | 1227 | + |
51a5ef0f | 1228 | @deftypefun void test_notification (int @var{somearg}) |
7566401a ER |
1229 | This observer is used for internal testing. Do not use. |
1230 | See testsuite/gdb.gdb/observer.exp. | |
f412e1b4 PS |
1231 | diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c |
1232 | index 222fcc3..93389e0 100644 | |
1233 | --- a/gdb/dwarf2expr.c | |
1234 | +++ b/gdb/dwarf2expr.c | |
1235 | @@ -1449,6 +1449,14 @@ execute_stack_op (struct dwarf_expr_context *ctx, | |
1236 | } | |
1237 | break; | |
3a58abaf AM |
1238 | |
1239 | + case DW_OP_push_object_address: | |
f412e1b4 | 1240 | + if (ctx->funcs->get_object_address == NULL) |
3a58abaf AM |
1241 | + error (_("DWARF-2 expression error: DW_OP_push_object_address must " |
1242 | + "have a value to push.")); | |
f412e1b4 PS |
1243 | + result = (ctx->funcs->get_object_address) (ctx->baton); |
1244 | + result_val = value_from_ulongest (address_type, result); | |
3a58abaf AM |
1245 | + break; |
1246 | + | |
1247 | default: | |
1248 | error (_("Unhandled dwarf expression opcode 0x%x"), op); | |
1249 | } | |
f412e1b4 PS |
1250 | diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h |
1251 | index fd70bf9..5129c4e 100644 | |
1252 | --- a/gdb/dwarf2expr.h | |
1253 | +++ b/gdb/dwarf2expr.h | |
1254 | @@ -73,12 +73,10 @@ struct dwarf_expr_context_funcs | |
1255 | int dwarf_reg, CORE_ADDR fb_offset, | |
1256 | int deref_size); | |
1257 | ||
1258 | -#if 0 | |
51a5ef0f PS |
1259 | /* Not yet implemented. */ |
1260 | ||
3a58abaf AM |
1261 | /* Return the `object address' for DW_OP_push_object_address. */ |
1262 | CORE_ADDR (*get_object_address) (void *baton); | |
1263 | -#endif | |
f412e1b4 | 1264 | }; |
3a58abaf | 1265 | |
f412e1b4 PS |
1266 | /* The location of a value. */ |
1267 | diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c | |
1268 | index 313df7b..35e0766 100644 | |
1269 | --- a/gdb/dwarf2loc.c | |
1270 | +++ b/gdb/dwarf2loc.c | |
1271 | @@ -157,6 +157,9 @@ struct dwarf_expr_baton | |
3a58abaf AM |
1272 | { |
1273 | struct frame_info *frame; | |
51a5ef0f | 1274 | struct dwarf2_per_cu_data *per_cu; |
3a58abaf AM |
1275 | + /* From DW_TAG_variable's DW_AT_location (not DW_TAG_type's |
1276 | + DW_AT_data_location) for DW_OP_push_object_address. */ | |
1277 | + CORE_ADDR object_address; | |
1278 | }; | |
1279 | ||
1280 | /* Helper functions for dwarf2_evaluate_loc_desc. */ | |
f412e1b4 PS |
1281 | @@ -216,16 +219,14 @@ static void |
1282 | dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc, | |
1283 | const gdb_byte **start, size_t *length) | |
1284 | { | |
1285 | - if (SYMBOL_LOCATION_BATON (framefunc) == NULL) | |
1286 | - *length = 0; | |
1287 | - else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs) | |
1288 | + if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs) | |
1289 | { | |
1290 | struct dwarf2_loclist_baton *symbaton; | |
1291 | ||
51a5ef0f | 1292 | symbaton = SYMBOL_LOCATION_BATON (framefunc); |
6ed6bacf | 1293 | *start = dwarf2_find_location_expression (symbaton, length, pc); |
3a58abaf AM |
1294 | } |
1295 | - else | |
7566401a | 1296 | + else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_locexpr_funcs) |
3a58abaf AM |
1297 | { |
1298 | struct dwarf2_locexpr_baton *symbaton; | |
51a5ef0f | 1299 | |
f412e1b4 PS |
1300 | @@ -238,10 +239,23 @@ dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc, |
1301 | else | |
1302 | *length = 0; | |
1303 | } | |
7566401a | 1304 | + else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_missing_funcs) |
3a58abaf AM |
1305 | + { |
1306 | + struct dwarf2_locexpr_baton *symbaton; | |
1307 | + | |
1308 | + symbaton = SYMBOL_LOCATION_BATON (framefunc); | |
1309 | + gdb_assert (symbaton == NULL); | |
f412e1b4 PS |
1310 | + *length = 0; |
1311 | + } | |
3a58abaf AM |
1312 | + else |
1313 | + internal_error (__FILE__, __LINE__, | |
7566401a ER |
1314 | + _("Unsupported SYMBOL_COMPUTED_OPS %p for \"%s\""), |
1315 | + SYMBOL_COMPUTED_OPS (framefunc), | |
1316 | + SYMBOL_PRINT_NAME (framefunc)); | |
3a58abaf | 1317 | |
f412e1b4 | 1318 | if (*length == 0) |
3a58abaf AM |
1319 | error (_("Could not find the frame base for \"%s\"."), |
1320 | - SYMBOL_NATURAL_NAME (framefunc)); | |
1321 | + SYMBOL_PRINT_NAME (framefunc)); | |
1322 | } | |
1323 | ||
7566401a | 1324 | /* Helper function for dwarf2_evaluate_loc_desc. Computes the CFA for |
f412e1b4 PS |
1325 | @@ -309,6 +323,85 @@ dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset) |
1326 | ctx->funcs->get_frame_pc, ctx->baton); | |
3a58abaf AM |
1327 | } |
1328 | ||
1329 | +static CORE_ADDR | |
1330 | +dwarf_expr_object_address (void *baton) | |
1331 | +{ | |
1332 | + struct dwarf_expr_baton *debaton = baton; | |
1333 | + | |
1334 | + /* The message is suppressed in DWARF_BLOCK_EXEC. */ | |
1335 | + if (debaton->object_address == 0) | |
1336 | + error (_("Cannot resolve DW_OP_push_object_address for a missing object")); | |
1337 | + | |
1338 | + return debaton->object_address; | |
1339 | +} | |
1340 | + | |
1341 | +/* Address of the variable we are currently referring to. It is set from | |
1342 | + DW_TAG_variable's DW_AT_location (not DW_TAG_type's DW_AT_data_location) for | |
1343 | + DW_OP_push_object_address. */ | |
1344 | + | |
1345 | +static CORE_ADDR object_address; | |
1346 | + | |
1347 | +/* Callers use object_address_set while their callers use the result set so we | |
1348 | + cannot run the cleanup at the local block of our direct caller. Still we | |
1349 | + should reset OBJECT_ADDRESS at least for the next GDB command. */ | |
1350 | + | |
1351 | +static void | |
1352 | +object_address_cleanup (void *prev_save_voidp) | |
1353 | +{ | |
1354 | + CORE_ADDR *prev_save = prev_save_voidp; | |
1355 | + | |
1356 | + object_address = *prev_save; | |
1357 | + xfree (prev_save); | |
1358 | +} | |
1359 | + | |
1360 | +/* Set the base address - DW_AT_location - of a variable. It is being later | |
1361 | + used to derive other object addresses by DW_OP_push_object_address. | |
1362 | + | |
1363 | + It would be useful to sanity check ADDRESS - such as for some objects with | |
7566401a | 1364 | + unset value_raw_address - but some valid addresses may be zero (such as first |
3a58abaf AM |
1365 | + objects in relocatable .o files). */ |
1366 | + | |
1367 | +void | |
1368 | +object_address_set (CORE_ADDR address) | |
1369 | +{ | |
1370 | + CORE_ADDR *prev_save; | |
1371 | + | |
1372 | + prev_save = xmalloc (sizeof *prev_save); | |
1373 | + *prev_save = object_address; | |
1374 | + make_cleanup (object_address_cleanup, prev_save); | |
1375 | + | |
1376 | + object_address = address; | |
1377 | +} | |
1378 | + | |
f412e1b4 PS |
1379 | +/* Evaluate DWARF location list at DLLBATON expecting it produces exactly one |
1380 | + CORE_ADDR result stored to *ADDRP on the DWARF stack stack. If the result | |
1381 | + could not be found return zero and keep *ADDRP unchanged. */ | |
1382 | + | |
1383 | +int | |
1384 | +dwarf_loclist_baton_eval (struct dwarf2_loclist_baton *dllbaton, | |
1385 | + struct type *type, CORE_ADDR *addrp) | |
1386 | +{ | |
1387 | + struct frame_info *frame = get_selected_frame (NULL); | |
1388 | + const gdb_byte *data; | |
1389 | + size_t size; | |
1390 | + struct value *val; | |
1391 | + | |
1392 | + if (!dllbaton) | |
1393 | + return 0; | |
1394 | + | |
1395 | + data = dwarf2_find_location_expression (dllbaton, &size, | |
1396 | + get_frame_address_in_block (frame)); | |
1397 | + if (data == NULL) | |
1398 | + return 0; | |
1399 | + | |
1400 | + val = dwarf2_evaluate_loc_desc (type, frame, data, size, dllbaton->per_cu); | |
1401 | + if (value_optimized_out (val)) | |
1402 | + return 0; | |
1403 | + | |
1404 | + *addrp = value_as_address (val); | |
1405 | + return 1; | |
1406 | +} | |
1407 | + | |
1408 | /* Callback function for dwarf2_evaluate_loc_desc. */ | |
1409 | ||
1410 | static struct type * | |
1411 | @@ -990,10 +1083,12 @@ dwarf_expr_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx, | |
1412 | ||
1413 | saved_ctx.gdbarch = ctx->gdbarch; | |
1414 | saved_ctx.addr_size = ctx->addr_size; | |
1415 | + saved_ctx.ref_addr_size = ctx->ref_addr_size; | |
1416 | saved_ctx.offset = ctx->offset; | |
1417 | saved_ctx.baton = ctx->baton; | |
1418 | ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (baton_local.per_cu)); | |
1419 | ctx->addr_size = dwarf2_per_cu_addr_size (baton_local.per_cu); | |
1420 | + ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (baton_local.per_cu); | |
1421 | ctx->offset = dwarf2_per_cu_text_offset (baton_local.per_cu); | |
1422 | ctx->baton = &baton_local; | |
1423 | ||
1424 | @@ -1001,10 +1096,92 @@ dwarf_expr_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx, | |
1425 | ||
1426 | ctx->gdbarch = saved_ctx.gdbarch; | |
1427 | ctx->addr_size = saved_ctx.addr_size; | |
1428 | + ctx->ref_addr_size = saved_ctx.ref_addr_size; | |
1429 | ctx->offset = saved_ctx.offset; | |
1430 | ctx->baton = saved_ctx.baton; | |
1431 | } | |
1432 | ||
1433 | +/* Virtual method table for dwarf2_evaluate_loc_desc_full below. */ | |
1434 | + | |
1435 | +static const struct dwarf_expr_context_funcs dwarf_expr_ctx_funcs = | |
1436 | +{ | |
1437 | + dwarf_expr_read_reg, | |
1438 | + dwarf_expr_read_mem, | |
1439 | + dwarf_expr_frame_base, | |
1440 | + dwarf_expr_frame_cfa, | |
1441 | + dwarf_expr_frame_pc, | |
1442 | + dwarf_expr_tls_address, | |
1443 | + dwarf_expr_dwarf_call, | |
1444 | + dwarf_expr_get_base_type, | |
1445 | + dwarf_expr_push_dwarf_reg_entry_value, | |
1446 | + dwarf_expr_object_address | |
1447 | +}; | |
1448 | + | |
3a58abaf AM |
1449 | +/* Evaluate DWARF expression at DATA ... DATA + SIZE with its result readable |
1450 | + by dwarf_expr_fetch (RETVAL, 0). FRAME parameter can be NULL to call | |
1451 | + get_selected_frame to find it. Returned dwarf_expr_context freeing is | |
1452 | + pushed on the cleanup chain. */ | |
1453 | + | |
f412e1b4 PS |
1454 | +static void |
1455 | +dwarf_expr_prep_ctx (struct dwarf_expr_context *ctx, struct frame_info *frame, | |
1456 | + const gdb_byte *data, size_t size, | |
1457 | + struct dwarf2_per_cu_data *per_cu) | |
3a58abaf | 1458 | +{ |
3a58abaf | 1459 | + struct dwarf_expr_baton baton; |
51a5ef0f | 1460 | + struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); |
6ed6bacf | 1461 | + volatile struct gdb_exception ex; |
3a58abaf AM |
1462 | + |
1463 | + baton.frame = frame; | |
51a5ef0f | 1464 | + baton.per_cu = per_cu; |
3a58abaf AM |
1465 | + baton.object_address = object_address; |
1466 | + | |
51a5ef0f | 1467 | + ctx->gdbarch = get_objfile_arch (objfile); |
3a58abaf | 1468 | + ctx->addr_size = dwarf2_per_cu_addr_size (per_cu); |
f412e1b4 | 1469 | + ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu); |
51a5ef0f | 1470 | + ctx->offset = dwarf2_per_cu_text_offset (per_cu); |
3a58abaf | 1471 | + ctx->baton = &baton; |
f412e1b4 | 1472 | + ctx->funcs = &dwarf_expr_ctx_funcs; |
3a58abaf | 1473 | + |
f412e1b4 | 1474 | + dwarf_expr_eval (ctx, data, size); |
3a58abaf AM |
1475 | +} |
1476 | + | |
1477 | +/* Evaluate DWARF expression at DLBATON expecting it produces exactly one | |
1478 | + CORE_ADDR result on the DWARF stack stack. */ | |
1479 | + | |
1480 | +CORE_ADDR | |
1481 | +dwarf_locexpr_baton_eval (struct dwarf2_locexpr_baton *dlbaton) | |
1482 | +{ | |
1483 | + struct dwarf_expr_context *ctx; | |
1484 | + CORE_ADDR retval; | |
f412e1b4 PS |
1485 | + struct cleanup *back_to; |
1486 | + | |
1487 | + ctx = new_dwarf_expr_context (); | |
1488 | + back_to = make_cleanup_free_dwarf_expr_context (ctx); | |
1489 | + | |
1490 | + dwarf_expr_prep_ctx (ctx, get_selected_frame (NULL), dlbaton->data, | |
1491 | + dlbaton->size, dlbaton->per_cu); | |
3a58abaf | 1492 | + |
3a58abaf AM |
1493 | + if (ctx->num_pieces > 0) |
1494 | + error (_("DW_OP_*piece is unsupported for DW_FORM_block")); | |
3a58abaf | 1495 | + |
f412e1b4 | 1496 | + retval = dwarf_expr_fetch_address (ctx, 0); |
3a58abaf | 1497 | + |
7566401a ER |
1498 | + if (ctx->location == DWARF_VALUE_REGISTER) |
1499 | + { | |
1500 | + /* Inlined dwarf_expr_read_reg as we no longer have the baton. */ | |
1501 | + | |
1502 | + int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (ctx->gdbarch, retval); | |
1503 | + struct type *type = builtin_type (ctx->gdbarch)->builtin_data_ptr; | |
1504 | + struct frame_info *frame = get_selected_frame (NULL); | |
1505 | + | |
1506 | + retval = address_from_register (type, gdb_regnum, frame); | |
1507 | + } | |
1508 | + | |
3a58abaf AM |
1509 | + do_cleanups (back_to); |
1510 | + | |
1511 | + return retval; | |
1512 | +} | |
51a5ef0f | 1513 | + |
f412e1b4 PS |
1514 | /* VALUE must be of type lval_computed with entry_data_value_funcs. Perform |
1515 | the indirect method on it, that is use its stored target value, the sole | |
1516 | purpose of entry_data_value_funcs.. */ | |
1517 | @@ -1927,21 +2104,6 @@ invalid_synthetic_pointer (void) | |
1518 | "referenced via synthetic pointer")); | |
1519 | } | |
1520 | ||
1521 | -/* Virtual method table for dwarf2_evaluate_loc_desc_full below. */ | |
1522 | - | |
1523 | -static const struct dwarf_expr_context_funcs dwarf_expr_ctx_funcs = | |
1524 | -{ | |
1525 | - dwarf_expr_read_reg, | |
1526 | - dwarf_expr_read_mem, | |
1527 | - dwarf_expr_frame_base, | |
1528 | - dwarf_expr_frame_cfa, | |
1529 | - dwarf_expr_frame_pc, | |
1530 | - dwarf_expr_tls_address, | |
1531 | - dwarf_expr_dwarf_call, | |
1532 | - dwarf_expr_get_base_type, | |
1533 | - dwarf_expr_push_dwarf_reg_entry_value | |
1534 | -}; | |
1535 | - | |
1536 | /* Evaluate a location description, starting at DATA and with length | |
1537 | SIZE, to find the current location of variable of TYPE in the | |
1538 | context of FRAME. BYTE_OFFSET is applied after the contents are | |
1539 | @@ -1954,7 +2116,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, | |
6ed6bacf | 1540 | LONGEST byte_offset) |
3a58abaf AM |
1541 | { |
1542 | struct value *retval; | |
1543 | - struct dwarf_expr_baton baton; | |
1544 | struct dwarf_expr_context *ctx; | |
f412e1b4 PS |
1545 | struct cleanup *old_chain, *value_chain; |
1546 | struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); | |
1547 | @@ -1966,29 +2127,18 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, | |
1548 | if (size == 0) | |
1549 | return allocate_optimized_out_value (type); | |
3a58abaf AM |
1550 | |
1551 | - baton.frame = frame; | |
51a5ef0f | 1552 | - baton.per_cu = per_cu; |
6ed6bacf | 1553 | - |
f412e1b4 PS |
1554 | ctx = new_dwarf_expr_context (); |
1555 | old_chain = make_cleanup_free_dwarf_expr_context (ctx); | |
1556 | value_chain = make_cleanup_value_free_to_mark (value_mark ()); | |
1557 | ||
51a5ef0f | 1558 | - ctx->gdbarch = get_objfile_arch (objfile); |
3a58abaf | 1559 | - ctx->addr_size = dwarf2_per_cu_addr_size (per_cu); |
f412e1b4 | 1560 | - ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu); |
51a5ef0f | 1561 | - ctx->offset = dwarf2_per_cu_text_offset (per_cu); |
3a58abaf | 1562 | - ctx->baton = &baton; |
f412e1b4 PS |
1563 | - ctx->funcs = &dwarf_expr_ctx_funcs; |
1564 | - | |
1565 | TRY_CATCH (ex, RETURN_MASK_ERROR) | |
3a58abaf | 1566 | { |
f412e1b4 PS |
1567 | - dwarf_expr_eval (ctx, data, size); |
1568 | + dwarf_expr_prep_ctx (ctx, frame, data, size, per_cu); | |
6ed6bacf | 1569 | } |
f412e1b4 PS |
1570 | if (ex.reason < 0) |
1571 | { | |
1572 | if (ex.error == NOT_AVAILABLE_ERROR) | |
1573 | { | |
1574 | - do_cleanups (old_chain); | |
1575 | retval = allocate_value (type); | |
1576 | mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (type)); | |
1577 | return retval; | |
1578 | @@ -2052,6 +2202,16 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, | |
7566401a ER |
1579 | int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); |
1580 | ||
f412e1b4 PS |
1581 | do_cleanups (value_chain); |
1582 | + | |
6ed6bacf AM |
1583 | + /* Frame may be needed for check_typedef of TYPE_DYNAMIC. */ |
1584 | + make_cleanup_restore_selected_frame (); | |
1585 | + select_frame (frame); | |
1586 | + | |
7566401a ER |
1587 | + /* object_address_set called here is required in ALLOCATE_VALUE's |
1588 | + CHECK_TYPEDEF for the object's possible | |
1589 | + DW_OP_push_object_address. */ | |
1590 | + object_address_set (address); | |
1591 | + | |
6ed6bacf | 1592 | retval = allocate_value_lazy (type); |
7566401a | 1593 | VALUE_LVAL (retval) = lval_memory; |
6ed6bacf | 1594 | if (in_stack_memory) |
f412e1b4 | 1595 | @@ -3896,8 +4056,7 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, |
6ed6bacf | 1596 | dlbaton->per_cu); |
3a58abaf AM |
1597 | } |
1598 | ||
1599 | -/* The set of location functions used with the DWARF-2 expression | |
1600 | - evaluator and location lists. */ | |
1601 | +/* The set of location functions used with the DWARF-2 location lists. */ | |
7566401a | 1602 | const struct symbol_computed_ops dwarf2_loclist_funcs = { |
3a58abaf | 1603 | loclist_read_variable, |
f412e1b4 PS |
1604 | loclist_read_variable_at_entry, |
1605 | @@ -3906,6 +4065,48 @@ const struct symbol_computed_ops dwarf2_loclist_funcs = { | |
3a58abaf AM |
1606 | loclist_tracepoint_var_ref |
1607 | }; | |
f412e1b4 | 1608 | |
3a58abaf AM |
1609 | +static struct value * |
1610 | +missing_read_variable (struct symbol *symbol, struct frame_info *frame) | |
1611 | +{ | |
1612 | + struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); | |
1613 | + | |
1614 | + gdb_assert (dlbaton == NULL); | |
1615 | + error (_("Unable to resolve variable \"%s\""), SYMBOL_PRINT_NAME (symbol)); | |
1616 | +} | |
1617 | + | |
1618 | +static int | |
1619 | +missing_read_needs_frame (struct symbol *symbol) | |
1620 | +{ | |
1621 | + return 0; | |
1622 | +} | |
1623 | + | |
51a5ef0f PS |
1624 | +static void |
1625 | +missing_describe_location (struct symbol *symbol, CORE_ADDR addr, | |
1626 | + struct ui_file *stream) | |
3a58abaf AM |
1627 | +{ |
1628 | + fprintf_filtered (stream, _("a variable we are unable to resolve")); | |
3a58abaf AM |
1629 | +} |
1630 | + | |
1631 | +static void | |
7566401a ER |
1632 | +missing_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, |
1633 | + struct agent_expr *ax, struct axs_value *value) | |
3a58abaf AM |
1634 | +{ |
1635 | + struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); | |
1636 | + | |
1637 | + gdb_assert (dlbaton == NULL); | |
1638 | + error (_("Unable to resolve variable \"%s\""), SYMBOL_PRINT_NAME (symbol)); | |
1639 | +} | |
1640 | + | |
1641 | +/* The set of location functions used with the DWARF-2 evaluator when we are | |
1642 | + unable to resolve the symbols. */ | |
7566401a | 1643 | +const struct symbol_computed_ops dwarf2_missing_funcs = { |
3a58abaf | 1644 | + missing_read_variable, |
f412e1b4 | 1645 | + missing_read_variable, /* read_variable_at_entry */ |
3a58abaf AM |
1646 | + missing_read_needs_frame, |
1647 | + missing_describe_location, | |
1648 | + missing_tracepoint_var_ref | |
1649 | +}; | |
f412e1b4 PS |
1650 | + |
1651 | void | |
1652 | _initialize_dwarf2loc (void) | |
1653 | { | |
1654 | diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h | |
1655 | index a7f835f..52a44f1 100644 | |
1656 | --- a/gdb/dwarf2loc.h | |
1657 | +++ b/gdb/dwarf2loc.h | |
1658 | @@ -118,6 +118,15 @@ struct dwarf2_loclist_baton | |
3a58abaf | 1659 | |
7566401a ER |
1660 | extern const struct symbol_computed_ops dwarf2_locexpr_funcs; |
1661 | extern const struct symbol_computed_ops dwarf2_loclist_funcs; | |
1662 | +extern const struct symbol_computed_ops dwarf2_missing_funcs; | |
3a58abaf AM |
1663 | + |
1664 | +extern void object_address_set (CORE_ADDR address); | |
1665 | + | |
1666 | +extern CORE_ADDR dwarf_locexpr_baton_eval | |
1667 | + (struct dwarf2_locexpr_baton *dlbaton); | |
51a5ef0f PS |
1668 | + |
1669 | +extern int dwarf_loclist_baton_eval (struct dwarf2_loclist_baton *dllbaton, | |
1670 | + struct type *type, CORE_ADDR *addrp); | |
3a58abaf | 1671 | |
6ed6bacf AM |
1672 | /* Compile a DWARF location expression to an agent expression. |
1673 | ||
f412e1b4 PS |
1674 | diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c |
1675 | index 0ef0a5b..80e5fe4 100644 | |
1676 | --- a/gdb/dwarf2read.c | |
1677 | +++ b/gdb/dwarf2read.c | |
1678 | @@ -1209,6 +1209,9 @@ static void fill_in_loclist_baton (struct dwarf2_cu *cu, | |
6ed6bacf AM |
1679 | struct dwarf2_loclist_baton *baton, |
1680 | struct attribute *attr); | |
3a58abaf | 1681 | |
51a5ef0f PS |
1682 | +static struct dwarf2_loclist_baton *dwarf2_attr_to_loclist_baton |
1683 | + (struct attribute *attr, struct dwarf2_cu *cu); | |
3a58abaf | 1684 | + |
51a5ef0f PS |
1685 | static void dwarf2_symbol_mark_computed (struct attribute *attr, |
1686 | struct symbol *sym, | |
1687 | struct dwarf2_cu *cu); | |
f412e1b4 | 1688 | @@ -1240,6 +1243,9 @@ static void age_cached_comp_units (void); |
3a58abaf AM |
1689 | |
1690 | static void free_one_cached_comp_unit (void *); | |
1691 | ||
1692 | +static void fetch_die_type_attrs (struct die_info *die, struct type *type, | |
1693 | + struct dwarf2_cu *cu); | |
1694 | + | |
1695 | static struct type *set_die_type (struct die_info *, struct type *, | |
1696 | struct dwarf2_cu *); | |
1697 | ||
f412e1b4 | 1698 | @@ -1263,6 +1269,9 @@ static struct type *get_die_type_at_offset (unsigned int, |
3a58abaf AM |
1699 | |
1700 | static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu); | |
1701 | ||
1702 | +static struct dwarf2_locexpr_baton *dwarf2_attr_to_locexpr_baton | |
1703 | + (struct attribute *attr, struct dwarf2_cu *cu); | |
51a5ef0f | 1704 | + |
6ed6bacf AM |
1705 | static void dwarf2_release_queue (void *dummy); |
1706 | ||
f412e1b4 PS |
1707 | static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu); |
1708 | @@ -8001,6 +8010,29 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) | |
6ed6bacf AM |
1709 | new_symbol (die, this_type, cu); |
1710 | } | |
1711 | ||
1712 | +/* Create a new array dimension referencing its target type TYPE. | |
51a5ef0f | 1713 | + |
6ed6bacf AM |
1714 | + Multidimensional arrays are internally represented as a stack of |
1715 | + singledimensional arrays being referenced by their TYPE_TARGET_TYPE. */ | |
51a5ef0f | 1716 | + |
6ed6bacf AM |
1717 | +static struct type * |
1718 | +create_single_array_dimension (struct type *type, struct type *range_type, | |
1719 | + struct die_info *die, struct dwarf2_cu *cu) | |
51a5ef0f | 1720 | +{ |
6ed6bacf | 1721 | + type = create_array_type (NULL, type, range_type); |
51a5ef0f | 1722 | + |
6ed6bacf AM |
1723 | + /* These generic type attributes need to be fetched by |
1724 | + evaluate_subexp_standard <multi_f77_subscript>'s call of | |
1725 | + value_subscripted_rvalue only for the innermost array type. */ | |
1726 | + fetch_die_type_attrs (die, type, cu); | |
51a5ef0f | 1727 | + |
6ed6bacf AM |
1728 | + /* These generic type attributes are checked for allocated/associated |
1729 | + validity while accessing FIELD_LOC_KIND_DWARF_BLOCK. */ | |
1730 | + fetch_die_type_attrs (die, range_type, cu); | |
51a5ef0f | 1731 | + |
6ed6bacf AM |
1732 | + return type; |
1733 | +} | |
3a58abaf | 1734 | + |
6ed6bacf AM |
1735 | /* Extract all information from a DW_TAG_array_type DIE and put it in |
1736 | the DIE's type field. For now, this only handles one dimensional | |
1737 | arrays. */ | |
f412e1b4 | 1738 | @@ -8014,7 +8046,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) |
6ed6bacf AM |
1739 | struct type *element_type, *range_type, *index_type; |
1740 | struct type **range_types = NULL; | |
1741 | struct attribute *attr; | |
1742 | - int ndim = 0; | |
1743 | + int ndim = 0, i; | |
1744 | struct cleanup *back_to; | |
1745 | char *name; | |
3a58abaf | 1746 | |
f412e1b4 | 1747 | @@ -8067,17 +8099,19 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) |
6ed6bacf AM |
1748 | type = element_type; |
1749 | ||
1750 | if (read_array_order (die, cu) == DW_ORD_col_major) | |
1751 | - { | |
1752 | - int i = 0; | |
1753 | - | |
1754 | - while (i < ndim) | |
1755 | - type = create_array_type (NULL, type, range_types[i++]); | |
1756 | - } | |
1757 | - else | |
1758 | - { | |
1759 | - while (ndim-- > 0) | |
1760 | - type = create_array_type (NULL, type, range_types[ndim]); | |
1761 | - } | |
1762 | + for (i = 0; i < ndim; i++) | |
1763 | + type = create_single_array_dimension (type, range_types[i], die, cu); | |
1764 | + else /* (read_array_order (die, cu) == DW_ORD_row_major) */ | |
1765 | + for (i = ndim - 1; i >= 0; i--) | |
1766 | + type = create_single_array_dimension (type, range_types[i], die, cu); | |
3a58abaf | 1767 | + |
6ed6bacf AM |
1768 | + /* Data locations should be set only for the outermost dimension as they |
1769 | + would be confusing for the dereferenced offset on the inner ones. */ | |
1770 | + attr = dwarf2_attr (die, DW_AT_data_location, cu); | |
1771 | + if (attr_form_is_block (attr)) | |
1772 | + TYPE_DATA_LOCATION_DWARF_BLOCK (type) | |
1773 | + = dwarf2_attr_to_locexpr_baton (attr, cu); | |
1774 | + gdb_assert (!TYPE_DATA_LOCATION_IS_ADDR (type)); | |
1775 | ||
1776 | /* Understand Dwarf2 support for vector types (like they occur on | |
1777 | the PowerPC w/ AltiVec). Gcc just adds another attribute to the | |
f412e1b4 | 1778 | @@ -8561,29 +8595,114 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu) |
6ed6bacf AM |
1779 | struct gdbarch *gdbarch = get_objfile_arch (objfile); |
1780 | struct type *type, *range_type, *index_type, *char_type; | |
1781 | struct attribute *attr; | |
1782 | - unsigned int length; | |
1783 | + int length; | |
3a58abaf | 1784 | + |
6ed6bacf AM |
1785 | + index_type = objfile_type (objfile)->builtin_int; |
1786 | + /* RANGE_TYPE is allocated from OBJFILE, not as a permanent type. */ | |
1787 | + range_type = alloc_type (objfile); | |
1788 | + /* LOW_BOUND and HIGH_BOUND are set for real below. */ | |
1789 | + range_type = create_range_type (range_type, index_type, 0, -1); | |
3a58abaf | 1790 | + |
6ed6bacf AM |
1791 | + /* C/C++ should probably have the low bound 0 but C/C++ does not use |
1792 | + DW_TAG_string_type. */ | |
1793 | + TYPE_LOW_BOUND (range_type) = 1; | |
1794 | ||
1795 | attr = dwarf2_attr (die, DW_AT_string_length, cu); | |
1796 | - if (attr) | |
1797 | + if (attr && attr_form_is_block (attr)) | |
1798 | { | |
1799 | - length = DW_UNSND (attr); | |
1800 | + /* Security check for a size overflow. */ | |
1801 | + if (DW_BLOCK (attr)->size + 2 < DW_BLOCK (attr)->size) | |
1802 | + TYPE_HIGH_BOUND (range_type) = 1; | |
1803 | + /* Extend the DWARF block by a new DW_OP_deref/DW_OP_deref_size | |
1804 | + instruction as DW_AT_string_length specifies the length location, not | |
1805 | + its value. */ | |
1806 | + else | |
1807 | + { | |
1808 | + struct dwarf2_locexpr_baton *length_baton = NULL; | |
1809 | + struct dwarf_block *blk = DW_BLOCK (attr); | |
3a58abaf | 1810 | + |
6ed6bacf AM |
1811 | + /* Turn any single DW_OP_reg* into DW_OP_breg*(0) but clearing |
1812 | + DW_OP_deref* in such case. */ | |
3a58abaf | 1813 | + |
6ed6bacf AM |
1814 | + if (blk->size == 1 && blk->data[0] >= DW_OP_reg0 |
1815 | + && blk->data[0] <= DW_OP_reg31) | |
1816 | + length_baton = dwarf2_attr_to_locexpr_baton (attr, cu); | |
1817 | + else if (blk->size > 1 && blk->data[0] == DW_OP_regx) | |
1818 | + { | |
1819 | + ULONGEST ulongest; | |
1820 | + const gdb_byte *end; | |
3a58abaf | 1821 | + |
6ed6bacf AM |
1822 | + end = read_uleb128 (&blk->data[1], &blk->data[blk->size], |
1823 | + &ulongest); | |
1824 | + if (end == &blk->data[blk->size]) | |
1825 | + length_baton = dwarf2_attr_to_locexpr_baton (attr, cu); | |
1826 | + } | |
3a58abaf | 1827 | + |
6ed6bacf AM |
1828 | + if (length_baton == NULL) |
1829 | + { | |
1830 | + struct attribute *size_attr; | |
1831 | + gdb_byte *data; | |
3a58abaf | 1832 | + |
6ed6bacf AM |
1833 | + length_baton = obstack_alloc (&cu->comp_unit_obstack, |
1834 | + sizeof (*length_baton)); | |
1835 | + length_baton->per_cu = cu->per_cu; | |
1836 | + length_baton->size = DW_BLOCK (attr)->size + 2; | |
1837 | + data = obstack_alloc (&cu->comp_unit_obstack, | |
1838 | + length_baton->size); | |
1839 | + length_baton->data = data; | |
1840 | + memcpy (data, DW_BLOCK (attr)->data, DW_BLOCK (attr)->size); | |
3a58abaf | 1841 | + |
6ed6bacf AM |
1842 | + /* DW_AT_BYTE_SIZE existing together with DW_AT_STRING_LENGTH |
1843 | + specifies the size of an integer to fetch. */ | |
1844 | + size_attr = dwarf2_attr (die, DW_AT_byte_size, cu); | |
1845 | + if (size_attr) | |
1846 | + { | |
1847 | + data[DW_BLOCK (attr)->size] = DW_OP_deref_size; | |
1848 | + data[DW_BLOCK (attr)->size + 1] = DW_UNSND (size_attr); | |
1849 | + if (data[DW_BLOCK (attr)->size + 1] != DW_UNSND (size_attr)) | |
1850 | + complaint (&symfile_complaints, | |
1851 | + _("DW_AT_string_length's DW_AT_byte_size " | |
1852 | + "integer exceeds the byte size storage")); | |
1853 | + } | |
1854 | + else | |
1855 | + { | |
1856 | + data[DW_BLOCK (attr)->size] = DW_OP_deref; | |
1857 | + data[DW_BLOCK (attr)->size + 1] = DW_OP_nop; | |
1858 | + } | |
1859 | + } | |
3a58abaf | 1860 | + |
6ed6bacf AM |
1861 | + TYPE_RANGE_DATA (range_type)->high.kind |
1862 | + = RANGE_BOUND_KIND_DWARF_BLOCK; | |
1863 | + TYPE_RANGE_DATA (range_type)->high.u.dwarf_block = length_baton; | |
1864 | + TYPE_DYNAMIC (range_type) = 1; | |
1865 | + } | |
1866 | } | |
1867 | else | |
1868 | { | |
1869 | - /* Check for the DW_AT_byte_size attribute. */ | |
1870 | + if (attr && attr_form_is_constant (attr)) | |
1871 | + { | |
1872 | + /* We currently do not support a constant address where the location | |
1873 | + should be read from - attr_form_is_block is expected instead. See | |
1874 | + DWARF for the DW_AT_STRING_LENGTH vs. DW_AT_BYTE_SIZE difference. | |
1875 | + */ | |
1876 | + /* PASSTHRU */ | |
1877 | + } | |
3a58abaf | 1878 | + |
6ed6bacf AM |
1879 | attr = dwarf2_attr (die, DW_AT_byte_size, cu); |
1880 | - if (attr) | |
1881 | - { | |
1882 | - length = DW_UNSND (attr); | |
1883 | - } | |
1884 | + if (attr && attr_form_is_block (attr)) | |
1885 | + { | |
1886 | + TYPE_RANGE_DATA (range_type)->high.kind | |
1887 | + = RANGE_BOUND_KIND_DWARF_BLOCK; | |
1888 | + TYPE_RANGE_DATA (range_type)->high.u.dwarf_block = | |
1889 | + dwarf2_attr_to_locexpr_baton (attr, cu); | |
1890 | + TYPE_DYNAMIC (range_type) = 1; | |
1891 | + } | |
1892 | + else if (attr && attr_form_is_constant (attr)) | |
1893 | + TYPE_HIGH_BOUND (range_type) = dwarf2_get_attr_constant_value (attr, 0); | |
1894 | else | |
1895 | - { | |
1896 | - length = 1; | |
1897 | - } | |
1898 | + TYPE_HIGH_BOUND (range_type) = 1; | |
1899 | } | |
1900 | ||
1901 | - index_type = objfile_type (objfile)->builtin_int; | |
1902 | - range_type = create_range_type (NULL, index_type, 1, length); | |
1903 | char_type = language_string_char_type (cu->language_defn, gdbarch); | |
1904 | type = create_string_type (NULL, char_type, range_type); | |
1905 | ||
f412e1b4 | 1906 | @@ -8887,8 +9006,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) |
6ed6bacf AM |
1907 | struct type *base_type; |
1908 | struct type *range_type; | |
1909 | struct attribute *attr; | |
1910 | - LONGEST low = 0; | |
1911 | - LONGEST high = -1; | |
1912 | + LONGEST low; | |
1913 | char *name; | |
1914 | LONGEST negative_mask; | |
1915 | ||
f412e1b4 | 1916 | @@ -8901,53 +9019,126 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) |
6ed6bacf AM |
1917 | if (range_type) |
1918 | return range_type; | |
1919 | ||
1920 | - if (cu->language == language_fortran) | |
f412e1b4 PS |
1921 | - { |
1922 | - /* FORTRAN implies a lower bound of 1, if not given. */ | |
1923 | - low = 1; | |
1924 | - } | |
6ed6bacf AM |
1925 | + /* LOW_BOUND and HIGH_BOUND are set for real below. */ |
1926 | + range_type = create_range_type (NULL, base_type, 0, -1); | |
1927 | + TYPE_UNSIGNED (range_type) = 0; | |
3a58abaf | 1928 | + |
6ed6bacf AM |
1929 | + negative_mask = |
1930 | + (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1); | |
3a58abaf | 1931 | + |
6ed6bacf AM |
1932 | + /* Exclude language_ada from any TYPE_DYNAMIC constructs below. GDB Ada |
1933 | + supports implements the dynamic bounds in a non-DWARF way and the | |
1934 | + existing DWARF dynamic bounds are invalid, leading to memory access | |
1935 | + errors. */ | |
f412e1b4 PS |
1936 | |
1937 | - /* FIXME: For variable sized arrays either of these could be | |
1938 | - a variable rather than a constant value. We'll allow it, | |
1939 | - but we don't know how to handle it. */ | |
1940 | attr = dwarf2_attr (die, DW_AT_lower_bound, cu); | |
1941 | - if (attr) | |
1942 | - low = dwarf2_get_attr_constant_value (attr, 0); | |
6ed6bacf | 1943 | + if (attr && attr_form_is_block (attr) && cu->language != language_ada) |
f412e1b4 | 1944 | + { |
6ed6bacf AM |
1945 | + TYPE_RANGE_DATA (range_type)->low.kind = RANGE_BOUND_KIND_DWARF_BLOCK; |
1946 | + TYPE_RANGE_DATA (range_type)->low.u.dwarf_block = | |
1947 | + dwarf2_attr_to_locexpr_baton (attr, cu); | |
1948 | + TYPE_DYNAMIC (range_type) = 1; | |
1949 | + /* For setting a default if DW_AT_UPPER_BOUND would be missing. */ | |
1950 | + low = 0; | |
f412e1b4 | 1951 | + } |
6ed6bacf | 1952 | + else if (attr && is_ref_attr (attr) && cu->language != language_ada) |
51a5ef0f | 1953 | + { |
6ed6bacf AM |
1954 | + struct die_info *target_die; |
1955 | + struct dwarf2_cu *target_cu = cu; | |
1956 | + struct attribute *target_loc_attr; | |
1957 | ||
f412e1b4 | 1958 | - attr = dwarf2_attr (die, DW_AT_upper_bound, cu); |
6ed6bacf | 1959 | - if (attr) |
6ed6bacf AM |
1960 | + target_die = follow_die_ref_or_sig (die, attr, &target_cu); |
1961 | + gdb_assert (target_cu->objfile == cu->objfile); | |
1962 | + target_loc_attr = dwarf2_attr (target_die, DW_AT_location, target_cu); | |
f412e1b4 | 1963 | + |
6ed6bacf AM |
1964 | + TYPE_RANGE_DATA (range_type)->low.kind = RANGE_BOUND_KIND_DWARF_LOCLIST; |
1965 | + TYPE_RANGE_DATA (range_type)->low.u.dwarf_loclist.loclist | |
1966 | + = dwarf2_attr_to_loclist_baton (target_loc_attr, target_cu); | |
1967 | + TYPE_RANGE_DATA (range_type)->low.u.dwarf_loclist.type | |
1968 | + = die_type (target_die, target_cu); | |
1969 | + TYPE_DYNAMIC (range_type) = 1; | |
1970 | + /* For setting a default if DW_AT_UPPER_BOUND would be missing. */ | |
1971 | + low = 0; | |
51a5ef0f PS |
1972 | + } |
1973 | + else | |
6ed6bacf | 1974 | { |
f412e1b4 | 1975 | - if (attr_form_is_block (attr) || is_ref_attr (attr)) |
6ed6bacf AM |
1976 | - { |
1977 | - /* GCC encodes arrays with unspecified or dynamic length | |
1978 | - with a DW_FORM_block1 attribute or a reference attribute. | |
1979 | - FIXME: GDB does not yet know how to handle dynamic | |
1980 | - arrays properly, treat them as arrays with unspecified | |
1981 | - length for now. | |
1982 | - | |
1983 | - FIXME: jimb/2003-09-22: GDB does not really know | |
1984 | - how to handle arrays of unspecified length | |
1985 | - either; we just represent them as zero-length | |
1986 | - arrays. Choose an appropriate upper bound given | |
1987 | - the lower bound we've computed above. */ | |
1988 | - high = low - 1; | |
1989 | - } | |
1990 | + if (attr && attr_form_is_constant (attr)) | |
1991 | + low = dwarf2_get_attr_constant_value (attr, 0); | |
1992 | else | |
1993 | - high = dwarf2_get_attr_constant_value (attr, 1); | |
1994 | + { | |
1995 | + if (cu->language == language_fortran) | |
1996 | + { | |
1997 | + /* FORTRAN implies a lower bound of 1, if not given. */ | |
1998 | + low = 1; | |
1999 | + } | |
2000 | + else | |
2001 | + { | |
2002 | + /* According to DWARF we should assume the value 0 only for | |
2003 | + LANGUAGE_C and LANGUAGE_CPLUS. */ | |
2004 | + low = 0; | |
2005 | + } | |
2006 | + } | |
2007 | + if (!TYPE_UNSIGNED (base_type) && (low & negative_mask)) | |
2008 | + low |= negative_mask; | |
2009 | + TYPE_LOW_BOUND (range_type) = low; | |
2010 | + if (low >= 0) | |
2011 | + TYPE_UNSIGNED (range_type) = 1; | |
2012 | } | |
2013 | - else | |
2014 | + | |
2015 | + attr = dwarf2_attr (die, DW_AT_upper_bound, cu); | |
2016 | + if (!attr || (!attr_form_is_block (attr) && !attr_form_is_constant (attr) | |
2017 | + && !is_ref_attr (attr))) | |
2018 | { | |
2019 | attr = dwarf2_attr (die, DW_AT_count, cu); | |
2020 | - if (attr) | |
2021 | - { | |
2022 | - int count = dwarf2_get_attr_constant_value (attr, 1); | |
2023 | - high = low + count - 1; | |
2024 | + /* It does not hurt but it is needlessly ineffective in check_typedef. */ | |
2025 | + if (attr && (attr_form_is_block (attr) || attr_form_is_constant (attr))) | |
2026 | + { | |
2027 | + TYPE_RANGE_HIGH_BOUND_IS_COUNT (range_type) = 1; | |
2028 | + TYPE_DYNAMIC (range_type) = 1; | |
2029 | } | |
2030 | + /* Pass it now as the regular DW_AT_upper_bound. */ | |
7566401a ER |
2031 | + } |
2032 | + | |
6ed6bacf AM |
2033 | + if (attr && attr_form_is_block (attr) && cu->language != language_ada) |
2034 | + { | |
2035 | + TYPE_RANGE_DATA (range_type)->high.kind = RANGE_BOUND_KIND_DWARF_BLOCK; | |
2036 | + TYPE_RANGE_DATA (range_type)->high.u.dwarf_block = | |
2037 | + dwarf2_attr_to_locexpr_baton (attr, cu); | |
2038 | + TYPE_DYNAMIC (range_type) = 1; | |
2039 | + } | |
2040 | + else if (attr && is_ref_attr (attr) && cu->language != language_ada) | |
2041 | + { | |
2042 | + struct die_info *target_die; | |
2043 | + struct dwarf2_cu *target_cu = cu; | |
2044 | + struct attribute *target_loc_attr; | |
3a58abaf | 2045 | + |
6ed6bacf AM |
2046 | + target_die = follow_die_ref_or_sig (die, attr, &target_cu); |
2047 | + gdb_assert (target_cu->objfile == cu->objfile); | |
2048 | + target_loc_attr = dwarf2_attr (target_die, DW_AT_location, target_cu); | |
51a5ef0f | 2049 | + |
6ed6bacf AM |
2050 | + TYPE_RANGE_DATA (range_type)->high.kind = RANGE_BOUND_KIND_DWARF_LOCLIST; |
2051 | + TYPE_RANGE_DATA (range_type)->high.u.dwarf_loclist.loclist | |
2052 | + = dwarf2_attr_to_loclist_baton (target_loc_attr, target_cu); | |
2053 | + TYPE_RANGE_DATA (range_type)->high.u.dwarf_loclist.type | |
2054 | + = die_type (target_die, target_cu); | |
2055 | + TYPE_DYNAMIC (range_type) = 1; | |
2056 | + } | |
2057 | + else | |
2058 | + { | |
2059 | + LONGEST high; | |
7566401a | 2060 | + |
6ed6bacf AM |
2061 | + if (attr && attr_form_is_constant (attr)) |
2062 | + high = dwarf2_get_attr_constant_value (attr, 0); | |
2063 | else | |
2064 | { | |
2065 | - /* Unspecified array length. */ | |
2066 | + /* Ada expects an empty array on no boundary attributes. */ | |
2067 | + if (cu->language != language_ada) | |
2068 | + TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1; | |
2069 | high = low - 1; | |
2070 | } | |
2071 | + if (!TYPE_UNSIGNED (base_type) && (high & negative_mask)) | |
2072 | + high |= negative_mask; | |
2073 | + TYPE_HIGH_BOUND (range_type) = high; | |
2074 | } | |
2075 | ||
2076 | /* Dwarf-2 specifications explicitly allows to create subrange types | |
f412e1b4 | 2077 | @@ -8988,24 +9179,41 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) |
6ed6bacf AM |
2078 | } |
2079 | } | |
2080 | ||
2081 | - negative_mask = | |
2082 | - (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1); | |
2083 | - if (!TYPE_UNSIGNED (base_type) && (low & negative_mask)) | |
2084 | - low |= negative_mask; | |
2085 | - if (!TYPE_UNSIGNED (base_type) && (high & negative_mask)) | |
2086 | - high |= negative_mask; | |
2087 | - | |
2088 | - range_type = create_range_type (NULL, base_type, low, high); | |
6ed6bacf AM |
2089 | + /* DW_AT_bit_stride is currently unsupported as we count in bytes. */ |
2090 | + attr = dwarf2_attr (die, DW_AT_byte_stride, cu); | |
2091 | + if (attr && attr_form_is_block (attr) && cu->language != language_ada) | |
2092 | + { | |
2093 | + TYPE_RANGE_DATA (range_type)->byte_stride.kind | |
2094 | + = RANGE_BOUND_KIND_DWARF_BLOCK; | |
2095 | + TYPE_RANGE_DATA (range_type)->byte_stride.u.dwarf_block = | |
2096 | + dwarf2_attr_to_locexpr_baton (attr, cu); | |
2097 | + TYPE_DYNAMIC (range_type) = 1; | |
2098 | + } | |
2099 | + else if (attr && is_ref_attr (attr) && cu->language != language_ada) | |
2100 | + { | |
2101 | + struct die_info *target_die; | |
2102 | + struct dwarf2_cu *target_cu = cu; | |
2103 | + struct attribute *target_loc_attr; | |
f412e1b4 PS |
2104 | |
2105 | - /* Mark arrays with dynamic length at least as an array of unspecified | |
2106 | - length. GDB could check the boundary but before it gets implemented at | |
2107 | - least allow accessing the array elements. */ | |
2108 | - if (attr && attr_form_is_block (attr)) | |
2109 | - TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1; | |
6ed6bacf AM |
2110 | + target_die = follow_die_ref_or_sig (die, attr, &target_cu); |
2111 | + gdb_assert (target_cu->objfile == cu->objfile); | |
2112 | + target_loc_attr = dwarf2_attr (target_die, DW_AT_location, target_cu); | |
f412e1b4 PS |
2113 | |
2114 | - /* Ada expects an empty array on no boundary attributes. */ | |
2115 | - if (attr == NULL && cu->language != language_ada) | |
2116 | - TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1; | |
6ed6bacf AM |
2117 | + TYPE_RANGE_DATA (range_type)->byte_stride.kind |
2118 | + = RANGE_BOUND_KIND_DWARF_LOCLIST; | |
2119 | + TYPE_RANGE_DATA (range_type)->byte_stride.u.dwarf_loclist.loclist | |
2120 | + = dwarf2_attr_to_loclist_baton (target_loc_attr, target_cu); | |
2121 | + TYPE_RANGE_DATA (range_type)->byte_stride.u.dwarf_loclist.type | |
2122 | + = die_type (target_die, target_cu); | |
2123 | + TYPE_DYNAMIC (range_type) = 1; | |
2124 | + } | |
2125 | + else if (attr && attr_form_is_constant (attr)) | |
51a5ef0f | 2126 | + { |
6ed6bacf AM |
2127 | + TYPE_BYTE_STRIDE (range_type) = dwarf2_get_attr_constant_value (attr, 0); |
2128 | + if (TYPE_BYTE_STRIDE (range_type) == 0) | |
2129 | + complaint (&symfile_complaints, | |
2130 | + _("Found DW_AT_byte_stride with unsupported value 0")); | |
51a5ef0f | 2131 | + } |
6ed6bacf AM |
2132 | |
2133 | name = dwarf2_name (die, cu); | |
2134 | if (name) | |
f412e1b4 | 2135 | @@ -11545,10 +11753,12 @@ var_decode_location (struct attribute *attr, struct symbol *sym, |
6ed6bacf AM |
2136 | (i.e. when the value of a register or memory location is |
2137 | referenced, or a thread-local block, etc.). Then again, it might | |
2138 | not be worthwhile. I'm assuming that it isn't unless performance | |
2139 | - or memory numbers show me otherwise. */ | |
2140 | + or memory numbers show me otherwise. | |
2141 | + | |
2142 | + SYMBOL_CLASS may get overriden by dwarf2_symbol_mark_computed. */ | |
2143 | ||
2144 | - dwarf2_symbol_mark_computed (attr, sym, cu); | |
2145 | SYMBOL_CLASS (sym) = LOC_COMPUTED; | |
2146 | + dwarf2_symbol_mark_computed (attr, sym, cu); | |
2147 | ||
2148 | if (SYMBOL_COMPUTED_OPS (sym) == &dwarf2_loclist_funcs) | |
2149 | cu->has_loclist = 1; | |
f412e1b4 | 2150 | @@ -11589,6 +11799,8 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, |
6ed6bacf AM |
2151 | else |
2152 | sym = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol); | |
2153 | OBJSTAT (objfile, n_syms++); | |
2154 | + /* Some methods are called w/o checking SYMBOL_COMPUTED_OPS validity. */ | |
2155 | + SYMBOL_COMPUTED_OPS (sym) = &dwarf2_missing_funcs; | |
2156 | ||
2157 | /* Cache this symbol's name and the name's demangled form (if any). */ | |
2158 | SYMBOL_SET_LANGUAGE (sym, cu->language); | |
f412e1b4 | 2159 | @@ -12354,6 +12566,9 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu) |
6ed6bacf AM |
2160 | break; |
2161 | } | |
2162 | ||
2163 | + if (this_type) | |
2164 | + finalize_type (this_type); | |
51a5ef0f | 2165 | + |
6ed6bacf AM |
2166 | return this_type; |
2167 | } | |
2168 | ||
f412e1b4 | 2169 | @@ -15590,62 +15805,100 @@ fill_in_loclist_baton (struct dwarf2_cu *cu, |
6ed6bacf AM |
2170 | baton->base_address = cu->base_address; |
2171 | } | |
2172 | ||
2173 | -static void | |
2174 | -dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, | |
2175 | - struct dwarf2_cu *cu) | |
2176 | +/* Convert DW_BLOCK into struct dwarf2_locexpr_baton. ATTR must be a DW_BLOCK | |
2177 | + attribute type. */ | |
51a5ef0f | 2178 | + |
6ed6bacf AM |
2179 | +static struct dwarf2_locexpr_baton * |
2180 | +dwarf2_attr_to_locexpr_baton (struct attribute *attr, struct dwarf2_cu *cu) | |
2181 | { | |
f412e1b4 PS |
2182 | struct objfile *objfile = dwarf2_per_objfile->objfile; |
2183 | + struct dwarf2_locexpr_baton *baton; | |
2184 | ||
6ed6bacf AM |
2185 | - if (attr_form_is_section_offset (attr) |
2186 | - /* ".debug_loc" may not exist at all, or the offset may be outside | |
2187 | - the section. If so, fall through to the complaint in the | |
2188 | - other branch. */ | |
f412e1b4 | 2189 | - && DW_UNSND (attr) < dwarf2_section_size (objfile, |
6ed6bacf AM |
2190 | - &dwarf2_per_objfile->loc)) |
2191 | - { | |
2192 | - struct dwarf2_loclist_baton *baton; | |
6ed6bacf | 2193 | + gdb_assert (attr_form_is_block (attr)); |
f412e1b4 PS |
2194 | + |
2195 | + baton = obstack_alloc (&objfile->objfile_obstack, sizeof (*baton)); | |
6ed6bacf AM |
2196 | + baton->per_cu = cu->per_cu; |
2197 | + gdb_assert (baton->per_cu); | |
2198 | ||
f412e1b4 PS |
2199 | - baton = obstack_alloc (&objfile->objfile_obstack, |
2200 | - sizeof (struct dwarf2_loclist_baton)); | |
6ed6bacf AM |
2201 | + /* Note that we're just copying the block's data pointer |
2202 | + here, not the actual data. We're still pointing into the | |
2203 | + info_buffer for SYM's objfile; right now we never release | |
2204 | + that buffer, but when we do clean up properly this may | |
2205 | + need to change. */ | |
2206 | + baton->size = DW_BLOCK (attr)->size; | |
2207 | + baton->data = DW_BLOCK (attr)->data; | |
2208 | + gdb_assert (baton->size == 0 || baton->data != NULL); | |
f412e1b4 PS |
2209 | |
2210 | - fill_in_loclist_baton (cu, baton, attr); | |
6ed6bacf | 2211 | + return baton; |
7566401a | 2212 | +} |
6ed6bacf | 2213 | |
f412e1b4 PS |
2214 | - if (cu->base_known == 0) |
2215 | - complaint (&symfile_complaints, | |
2216 | - _("Location list used without " | |
2217 | - "specifying the CU base address.")); | |
6ed6bacf AM |
2218 | +static struct dwarf2_loclist_baton * |
2219 | +dwarf2_attr_to_loclist_baton (struct attribute *attr, struct dwarf2_cu *cu) | |
51a5ef0f | 2220 | +{ |
6ed6bacf | 2221 | + struct dwarf2_loclist_baton *baton; |
7566401a | 2222 | + |
6ed6bacf AM |
2223 | + /* DW_AT_location of the referenced DIE may be missing if the referenced |
2224 | + variable has been optimized out. */ | |
2225 | + if (!attr) | |
2226 | + return NULL; | |
51a5ef0f | 2227 | + |
6ed6bacf AM |
2228 | + dwarf2_read_section (dwarf2_per_objfile->objfile, |
2229 | + &dwarf2_per_objfile->loc); | |
51a5ef0f | 2230 | + |
6ed6bacf AM |
2231 | + if (!(attr_form_is_section_offset (attr) |
2232 | + /* ".debug_loc" may not exist at all, or the offset may be outside | |
2233 | + the section. If so, fall through to the complaint in the | |
2234 | + other branch. */ | |
2235 | + && DW_UNSND (attr) < dwarf2_section_size (dwarf2_per_objfile->objfile, | |
2236 | + &dwarf2_per_objfile->loc))) | |
2237 | + return NULL; | |
51a5ef0f | 2238 | + |
6ed6bacf AM |
2239 | + baton = obstack_alloc (&cu->objfile->objfile_obstack, |
2240 | + sizeof (struct dwarf2_loclist_baton)); | |
51a5ef0f | 2241 | + |
6ed6bacf | 2242 | + fill_in_loclist_baton (cu, baton, attr); |
51a5ef0f | 2243 | + |
6ed6bacf AM |
2244 | + if (cu->base_known == 0) |
2245 | + complaint (&symfile_complaints, | |
2246 | + _("Location list used without " | |
2247 | + "specifying the CU base address.")); | |
f412e1b4 | 2248 | |
6ed6bacf | 2249 | + return baton; |
51a5ef0f PS |
2250 | +} |
2251 | + | |
6ed6bacf AM |
2252 | +/* SYM may get its SYMBOL_CLASS overriden on invalid ATTR content. */ |
2253 | + | |
7566401a | 2254 | +static void |
6ed6bacf AM |
2255 | +dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, |
2256 | + struct dwarf2_cu *cu) | |
2257 | +{ | |
2258 | + struct dwarf2_loclist_baton *loclist_baton; | |
2259 | + | |
2260 | + loclist_baton = dwarf2_attr_to_loclist_baton (attr, cu); | |
2261 | + if (loclist_baton) | |
2262 | + { | |
2263 | SYMBOL_COMPUTED_OPS (sym) = &dwarf2_loclist_funcs; | |
2264 | - SYMBOL_LOCATION_BATON (sym) = baton; | |
2265 | + SYMBOL_LOCATION_BATON (sym) = loclist_baton; | |
2266 | + } | |
2267 | + else if (attr_form_is_block (attr)) | |
2268 | + { | |
2269 | + SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs; | |
2270 | + SYMBOL_LOCATION_BATON (sym) = dwarf2_attr_to_locexpr_baton (attr, cu); | |
2271 | } | |
2272 | else | |
2273 | { | |
2274 | - struct dwarf2_locexpr_baton *baton; | |
2275 | + dwarf2_invalid_attrib_class_complaint ("location description", | |
2276 | + SYMBOL_NATURAL_NAME (sym)); | |
2277 | ||
f412e1b4 | 2278 | - baton = obstack_alloc (&objfile->objfile_obstack, |
6ed6bacf AM |
2279 | - sizeof (struct dwarf2_locexpr_baton)); |
2280 | - baton->per_cu = cu->per_cu; | |
2281 | - gdb_assert (baton->per_cu); | |
2282 | + /* Some methods are called w/o checking SYMBOL_COMPUTED_OPS validity. */ | |
2283 | ||
2284 | - if (attr_form_is_block (attr)) | |
2285 | - { | |
2286 | - /* Note that we're just copying the block's data pointer | |
2287 | - here, not the actual data. We're still pointing into the | |
2288 | - info_buffer for SYM's objfile; right now we never release | |
2289 | - that buffer, but when we do clean up properly this may | |
2290 | - need to change. */ | |
2291 | - baton->size = DW_BLOCK (attr)->size; | |
2292 | - baton->data = DW_BLOCK (attr)->data; | |
2293 | - } | |
2294 | - else | |
2295 | - { | |
2296 | - dwarf2_invalid_attrib_class_complaint ("location description", | |
2297 | - SYMBOL_NATURAL_NAME (sym)); | |
2298 | - baton->size = 0; | |
6ed6bacf AM |
2299 | - } |
2300 | + SYMBOL_COMPUTED_OPS (sym) = &dwarf2_missing_funcs; | |
2301 | + SYMBOL_LOCATION_BATON (sym) = NULL; | |
2302 | ||
2303 | - SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs; | |
2304 | - SYMBOL_LOCATION_BATON (sym) = baton; | |
2305 | + /* For functions a missing DW_AT_frame_base does not optimize out the | |
2306 | + whole function definition, only its frame base resolving. */ | |
2307 | + if (attr->name == DW_AT_location) | |
2308 | + SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; | |
2309 | } | |
2310 | } | |
2311 | ||
f412e1b4 | 2312 | @@ -16003,6 +16256,25 @@ offset_and_type_eq (const void *item_lhs, const void *item_rhs) |
6ed6bacf AM |
2313 | return ofs_lhs->offset == ofs_rhs->offset; |
2314 | } | |
2315 | ||
2316 | +/* Fill in generic attributes applicable for type DIEs. */ | |
3a58abaf AM |
2317 | + |
2318 | +static void | |
6ed6bacf AM |
2319 | +fetch_die_type_attrs (struct die_info *die, struct type *type, |
2320 | + struct dwarf2_cu *cu) | |
3a58abaf AM |
2321 | +{ |
2322 | + struct attribute *attr; | |
51a5ef0f | 2323 | + |
6ed6bacf AM |
2324 | + attr = dwarf2_attr (die, DW_AT_allocated, cu); |
2325 | + if (attr_form_is_block (attr)) | |
2326 | + TYPE_ALLOCATED (type) = dwarf2_attr_to_locexpr_baton (attr, cu); | |
2327 | + gdb_assert (!TYPE_NOT_ALLOCATED (type)); | |
51a5ef0f | 2328 | + |
6ed6bacf AM |
2329 | + attr = dwarf2_attr (die, DW_AT_associated, cu); |
2330 | + if (attr_form_is_block (attr)) | |
2331 | + TYPE_ASSOCIATED (type) = dwarf2_attr_to_locexpr_baton (attr, cu); | |
2332 | + gdb_assert (!TYPE_NOT_ASSOCIATED (type)); | |
2333 | +} | |
51a5ef0f | 2334 | + |
6ed6bacf AM |
2335 | /* Set the type associated with DIE to TYPE. Save it in CU's hash |
2336 | table if necessary. For convenience, return TYPE. | |
2337 | ||
f412e1b4 | 2338 | @@ -16028,6 +16300,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) |
6ed6bacf AM |
2339 | struct objfile *objfile = cu->objfile; |
2340 | htab_t *type_hash_ptr; | |
2341 | ||
2342 | + fetch_die_type_attrs (die, type, cu); | |
3a58abaf | 2343 | + |
6ed6bacf AM |
2344 | /* For Ada types, make sure that the gnat-specific data is always |
2345 | initialized (if not already set). There are a few types where | |
2346 | we should not be doing so, because the type-specific area is | |
f412e1b4 PS |
2347 | diff --git a/gdb/elfread.c b/gdb/elfread.c |
2348 | index ddae099..aea443f 100644 | |
2349 | --- a/gdb/elfread.c | |
2350 | +++ b/gdb/elfread.c | |
2351 | @@ -36,6 +36,8 @@ | |
2352 | #include "demangle.h" | |
2353 | #include "psympriv.h" | |
2354 | #include "filenames.h" | |
6ed6bacf AM |
2355 | +#include "stap-probe.h" |
2356 | +#include "arch-utils.h" | |
f412e1b4 PS |
2357 | #include "gdbtypes.h" |
2358 | #include "value.h" | |
2359 | #include "infcall.h" | |
2360 | @@ -60,6 +62,21 @@ struct elfinfo | |
6ed6bacf AM |
2361 | asection *mdebugsect; /* Section pointer for .mdebug section */ |
2362 | }; | |
2363 | ||
2364 | +/* Per-objfile data for SystemTap probe info. */ | |
3a58abaf | 2365 | + |
6ed6bacf | 2366 | +static const struct objfile_data *stap_probe_key = NULL; |
51a5ef0f | 2367 | + |
6ed6bacf | 2368 | +/* Per-objfile data about SystemTap probes. */ |
51a5ef0f | 2369 | + |
6ed6bacf AM |
2370 | +struct stap_probe_per_objfile |
2371 | + { | |
2372 | + /* The number of probes in this objfile. */ | |
2373 | + int stap_num_probes; | |
51a5ef0f | 2374 | + |
6ed6bacf AM |
2375 | + /* The probes themselves. */ |
2376 | + struct stap_probe *probes; | |
2377 | + }; | |
7566401a | 2378 | + |
6ed6bacf AM |
2379 | static void free_elfinfo (void *); |
2380 | ||
2381 | /* Minimal symbols located at the GOT entries for .plt - that is the real | |
f412e1b4 | 2382 | @@ -1576,7 +1593,270 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst) |
6ed6bacf AM |
2383 | complaint (&symfile_complaints, |
2384 | _("elf/stab section information missing for %s"), filename); | |
2385 | } | |
3a58abaf | 2386 | + |
6ed6bacf AM |
2387 | +/* Helper function that parses the information contained in a |
2388 | + SystemTap's probe. Basically, the information consists in: | |
3a58abaf | 2389 | + |
6ed6bacf AM |
2390 | + - Probe's PC address; |
2391 | + - Link-time section address of `.stapsdt.base' section; | |
2392 | + - Link-time address of the semaphore variable, or ZERO if the | |
2393 | + probe doesn't have an associated semaphore; | |
2394 | + - Probe's provider name; | |
2395 | + - Probe's name; | |
2396 | + - Probe's argument format. */ | |
3a58abaf | 2397 | + |
6ed6bacf AM |
2398 | +static void |
2399 | +handle_probe (struct objfile *objfile, struct sdt_note *el, | |
2400 | + struct stap_probe *ret, CORE_ADDR base) | |
2401 | +{ | |
2402 | + bfd *abfd = objfile->obfd; | |
2403 | + int size = bfd_get_arch_size (abfd) / 8; | |
2404 | + struct gdbarch *gdbarch = get_objfile_arch (objfile); | |
2405 | + struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; | |
2406 | + CORE_ADDR base_ref; | |
2407 | + | |
f412e1b4 PS |
2408 | + ret->gdbarch = gdbarch; |
2409 | + | |
6ed6bacf AM |
2410 | + /* Provider and the name of the probe. */ |
2411 | + ret->provider = (const char *) &el->data[3 * size]; | |
2412 | + ret->name = memchr (ret->provider, '\0', | |
2413 | + (unsigned long *) el->data | |
2414 | + + el->size - (unsigned long *) ret->provider); | |
2415 | + /* Making sure there is a name. */ | |
2416 | + if (!ret->name) | |
2417 | + complaint (&symfile_complaints, _("corrupt probe when reading `%s'"), | |
2418 | + objfile->name); | |
2419 | + else | |
2420 | + ++ret->name; | |
2421 | + | |
2422 | + /* Retrieving the probe's address. */ | |
2423 | + ret->address = extract_typed_address ((const gdb_byte *) &el->data[0], | |
2424 | + ptr_type); | |
2425 | + /* Link-time sh_addr of `.stapsdt.base' section. */ | |
2426 | + base_ref = extract_typed_address ((const gdb_byte *) &el->data[size], | |
2427 | + ptr_type); | |
2428 | + /* Semaphore address. */ | |
2429 | + ret->sem_addr = extract_typed_address ((const gdb_byte *) &el->data[2 * size], | |
2430 | + ptr_type); | |
2431 | + | |
2432 | + ret->address += (ANOFFSET (objfile->section_offsets, | |
2433 | + SECT_OFF_TEXT (objfile)) | |
2434 | + + base - base_ref); | |
2435 | + if (ret->sem_addr) | |
2436 | + ret->sem_addr += (ANOFFSET (objfile->section_offsets, | |
2437 | + SECT_OFF_DATA (objfile)) | |
2438 | + + base - base_ref); | |
2439 | + | |
2440 | + /* Arguments. We can only extract the argument format if there is a valid | |
2441 | + name for this probe. */ | |
2442 | + if (ret->name) | |
2443 | + { | |
2444 | + ret->args = memchr (ret->name, '\0', | |
2445 | + (unsigned long *) el->data | |
2446 | + + el->size - (unsigned long *) ret->name); | |
2447 | + | |
f412e1b4 PS |
2448 | + if (ret->args != NULL) |
2449 | + ++ret->args; | |
2450 | + if (ret->args == NULL | |
2451 | + || (memchr (ret->args, '\0', (unsigned long *) el->data | |
2452 | + + el->size - (unsigned long *) ret->name) | |
2453 | + != el->data + el->size - 1)) | |
6ed6bacf AM |
2454 | + complaint (&symfile_complaints, _("corrupt probe when reading `%s'"), |
2455 | + objfile->name); | |
2456 | + } | |
2457 | + else | |
2458 | + ret->args = NULL; | |
51a5ef0f | 2459 | +} |
7566401a | 2460 | + |
6ed6bacf AM |
2461 | +/* The name of the SystemTap section where we will find information about |
2462 | + the probes. */ | |
51a5ef0f | 2463 | + |
6ed6bacf | 2464 | +#define STAP_BASE_SECTION_NAME ".stapsdt.base" |
51a5ef0f | 2465 | + |
6ed6bacf AM |
2466 | +/* Helper function which tries to find the base address of the SystemTap |
2467 | + base section named STAP_BASE_SECTION_NAME. */ | |
51a5ef0f | 2468 | + |
6ed6bacf AM |
2469 | +static void |
2470 | +get_base_address_1 (bfd *abfd, asection *sect, void *obj) | |
51a5ef0f | 2471 | +{ |
6ed6bacf AM |
2472 | + bfd_vma *base = (bfd_vma *) obj; |
2473 | + | |
2474 | + if (*base == (bfd_vma) -1 | |
2475 | + && (sect->flags & (SEC_DATA | SEC_ALLOC | SEC_HAS_CONTENTS)) | |
2476 | + && sect->name && !strcmp (sect->name, STAP_BASE_SECTION_NAME)) | |
2477 | + *base = sect->vma; | |
51a5ef0f PS |
2478 | +} |
2479 | + | |
6ed6bacf AM |
2480 | +/* Helper function which iterates over every section in the BFD file, |
2481 | + trying to find the base address of the SystemTap base section. | |
2482 | + Returns the section address if found, or -1 otherwise. */ | |
51a5ef0f | 2483 | + |
6ed6bacf AM |
2484 | +static bfd_vma |
2485 | +get_base_address (bfd *obfd) | |
2486 | +{ | |
2487 | + bfd_vma base = (bfd_vma) -1; | |
51a5ef0f | 2488 | + |
6ed6bacf | 2489 | + bfd_map_over_sections (obfd, get_base_address_1, (void *) &base); |
51a5ef0f | 2490 | + |
6ed6bacf | 2491 | + return base; |
51a5ef0f PS |
2492 | +} |
2493 | + | |
6ed6bacf AM |
2494 | +/* Implementation of `sym_get_probes', as documented in symfile.h. */ |
2495 | + | |
f412e1b4 | 2496 | +static struct stap_probe * |
6ed6bacf | 2497 | +elf_get_probes (struct objfile *objfile, int *num_probes) |
51a5ef0f | 2498 | +{ |
6ed6bacf AM |
2499 | + struct stap_probe *ret = NULL; |
2500 | + struct stap_probe_per_objfile *probes_per_objfile; | |
51a5ef0f | 2501 | + |
6ed6bacf AM |
2502 | + /* Initially, no probes. */ |
2503 | + *num_probes = 0; | |
51a5ef0f | 2504 | + |
6ed6bacf AM |
2505 | + /* Have we parsed this objfile's probes already? */ |
2506 | + probes_per_objfile | |
2507 | + = (struct stap_probe_per_objfile *) objfile_data (objfile, | |
2508 | + stap_probe_key); | |
51a5ef0f | 2509 | + |
6ed6bacf AM |
2510 | + if (!probes_per_objfile) |
2511 | + { | |
2512 | + /* If we are here, then this is the first time we are parsing the | |
2513 | + probe's information. We basically have to count how many probes | |
2514 | + the objfile has, and then fill in the necessary information | |
2515 | + for each one. */ | |
51a5ef0f | 2516 | + |
6ed6bacf AM |
2517 | + bfd *obfd = objfile->obfd; |
2518 | + bfd_vma base = get_base_address (obfd); | |
2519 | + struct sdt_note *iter; | |
2520 | + int i; | |
2521 | + int n = 0; | |
51a5ef0f | 2522 | + |
6ed6bacf AM |
2523 | + if (! elf_tdata (obfd)->sdt_note_head) |
2524 | + /* There isn't any probe here. */ | |
2525 | + return NULL; | |
51a5ef0f | 2526 | + |
6ed6bacf AM |
2527 | + /* Allocating space for probe info. */ |
2528 | + for (iter = elf_tdata (obfd)->sdt_note_head; | |
2529 | + iter; | |
2530 | + iter = iter->next, ++n); | |
51a5ef0f | 2531 | + |
6ed6bacf | 2532 | + ret = xcalloc (n, sizeof (struct stap_probe)); |
51a5ef0f | 2533 | + |
6ed6bacf AM |
2534 | + /* Parsing each probe's information. */ |
2535 | + for (iter = elf_tdata (obfd)->sdt_note_head, i = 0; | |
2536 | + iter; | |
2537 | + iter = iter->next, i++) | |
2538 | + /* We first have to handle all the information about the | |
2539 | + probe which is present in the section. */ | |
2540 | + handle_probe (objfile, iter, &ret[i], base); | |
3a58abaf | 2541 | + |
6ed6bacf AM |
2542 | + /* Creating a cache for these probes in the objfile's registry. */ |
2543 | + probes_per_objfile = xmalloc (sizeof (struct stap_probe_per_objfile)); | |
51a5ef0f | 2544 | + |
6ed6bacf AM |
2545 | + probes_per_objfile->stap_num_probes = n; |
2546 | + probes_per_objfile->probes = ret; | |
ab050a48 | 2547 | + |
6ed6bacf | 2548 | + set_objfile_data (objfile, stap_probe_key, probes_per_objfile); |
51a5ef0f | 2549 | + } |
6ed6bacf AM |
2550 | + else |
2551 | + ret = probes_per_objfile->probes; | |
3a58abaf | 2552 | + |
6ed6bacf | 2553 | + *num_probes = probes_per_objfile->stap_num_probes; |
3a58abaf | 2554 | + |
6ed6bacf | 2555 | + return ret; |
3a58abaf AM |
2556 | +} |
2557 | + | |
6ed6bacf AM |
2558 | +/* Implementation of `sym_get_probe_argument_count', as documented in |
2559 | + symfile.h. */ | |
2560 | + | |
2561 | +static int | |
2562 | +elf_get_probe_argument_count (struct objfile *objfile, | |
f412e1b4 | 2563 | + struct stap_probe *probe) |
51a5ef0f | 2564 | +{ |
6ed6bacf | 2565 | + const char *pargs = probe->args; |
7566401a | 2566 | + |
6ed6bacf AM |
2567 | + if (!pargs || !*pargs || *pargs == ':') |
2568 | + /* No arguments. */ | |
2569 | + return 0; | |
3a58abaf | 2570 | + |
6ed6bacf | 2571 | + return stap_get_probe_argument_count (probe); |
51a5ef0f | 2572 | +} |
3a58abaf | 2573 | + |
6ed6bacf AM |
2574 | +/* Implementation of `sym_evaluate_probe_argument', as documented in |
2575 | + symfile.h. */ | |
3a58abaf | 2576 | + |
6ed6bacf AM |
2577 | +static struct value * |
2578 | +elf_evaluate_probe_argument (struct objfile *objfile, | |
f412e1b4 | 2579 | + struct stap_probe *probe, |
6ed6bacf AM |
2580 | + struct frame_info *frame, |
2581 | + int n) | |
51a5ef0f | 2582 | +{ |
6ed6bacf | 2583 | + return stap_evaluate_probe_argument (objfile, probe, frame, n); |
3a58abaf AM |
2584 | +} |
2585 | + | |
6ed6bacf | 2586 | +/* Implementation of `sym_compile_to_ax', as documented in symfile.h. */ |
3a58abaf | 2587 | + |
51a5ef0f | 2588 | +static void |
6ed6bacf | 2589 | +elf_compile_to_ax (struct objfile *objfile, |
f412e1b4 | 2590 | + struct stap_probe *probe, |
6ed6bacf AM |
2591 | + struct agent_expr *expr, |
2592 | + struct axs_value *value, | |
2593 | + int n) | |
51a5ef0f | 2594 | +{ |
6ed6bacf | 2595 | + stap_compile_to_ax (objfile, probe, expr, value, n); |
51a5ef0f | 2596 | +} |
3a58abaf | 2597 | + |
6ed6bacf | 2598 | +/* Implementation of `sym_relocate_probe', as documented in symfile.h. */ |
3a58abaf | 2599 | + |
51a5ef0f | 2600 | +static void |
6ed6bacf AM |
2601 | +elf_symfile_relocate_probe (struct objfile *objfile, |
2602 | + struct section_offsets *new_offsets, | |
2603 | + struct section_offsets *delta) | |
51a5ef0f PS |
2604 | +{ |
2605 | + int i; | |
6ed6bacf AM |
2606 | + struct stap_probe_per_objfile *p |
2607 | + = (struct stap_probe_per_objfile *) objfile_data (objfile, | |
2608 | + stap_probe_key); | |
7566401a | 2609 | + |
6ed6bacf AM |
2610 | + if (!p) |
2611 | + /* No probe to relocate. */ | |
2612 | + return; | |
7566401a | 2613 | + |
6ed6bacf AM |
2614 | + for (i = 0; i < p->stap_num_probes; i++) |
2615 | + { | |
2616 | + p->probes[i].address += ANOFFSET (delta, SECT_OFF_TEXT (objfile)); | |
2617 | + if (p->probes[i].sem_addr) | |
2618 | + p->probes[i].sem_addr += ANOFFSET (delta, SECT_OFF_DATA (objfile)); | |
51a5ef0f | 2619 | + } |
7566401a ER |
2620 | +} |
2621 | + | |
6ed6bacf AM |
2622 | +/* Helper function used to free the space allocated for storing SystemTap |
2623 | + probe information. */ | |
2624 | + | |
51a5ef0f | 2625 | +static void |
6ed6bacf | 2626 | +stap_probe_key_free (struct objfile *objfile, void *d) |
7566401a | 2627 | +{ |
51a5ef0f | 2628 | + int i; |
6ed6bacf | 2629 | + struct stap_probe_per_objfile *data = (struct stap_probe_per_objfile *) d; |
7566401a | 2630 | + |
6ed6bacf AM |
2631 | + for (i = 0; i < data->stap_num_probes; i++) |
2632 | + stap_free_parsed_args (data->probes[i].parsed_args); | |
2633 | + xfree (data->probes); | |
2634 | + xfree (data); | |
2635 | +} | |
7566401a | 2636 | + |
6ed6bacf | 2637 | \f |
7566401a | 2638 | + |
6ed6bacf AM |
2639 | +/* Implementation `sym_probe_fns', as documented in symfile.h. */ |
2640 | + | |
2641 | +static const struct sym_probe_fns elf_probe_fns = | |
2642 | +{ | |
2643 | + elf_get_probes, /* sym_get_probes */ | |
2644 | + elf_get_probe_argument_count, /* sym_get_probe_argument_count */ | |
2645 | + elf_evaluate_probe_argument, /* sym_evaluate_probe_argument */ | |
2646 | + elf_compile_to_ax, /* sym_compile_to_ax */ | |
2647 | + elf_symfile_relocate_probe, /* sym_relocate_probe */ | |
2648 | +}; | |
7566401a | 2649 | + |
6ed6bacf AM |
2650 | /* Register that we are able to handle ELF object file formats. */ |
2651 | ||
2652 | static const struct sym_fns elf_sym_fns = | |
f412e1b4 | 2653 | @@ -1591,6 +1871,7 @@ static const struct sym_fns elf_sym_fns = |
6ed6bacf AM |
2654 | elf_symfile_segments, /* Get segment information from a file. */ |
2655 | NULL, | |
2656 | default_symfile_relocate, /* Relocate a debug section. */ | |
2657 | + &elf_probe_fns, /* sym_probe_fns */ | |
2658 | &psym_functions | |
2659 | }; | |
2660 | ||
f412e1b4 | 2661 | @@ -1609,6 +1890,7 @@ static const struct sym_fns elf_sym_fns_lazy_psyms = |
6ed6bacf AM |
2662 | elf_symfile_segments, /* Get segment information from a file. */ |
2663 | NULL, | |
2664 | default_symfile_relocate, /* Relocate a debug section. */ | |
2665 | + &elf_probe_fns, /* sym_probe_fns */ | |
2666 | &psym_functions | |
2667 | }; | |
2668 | ||
f412e1b4 | 2669 | @@ -1626,6 +1908,7 @@ static const struct sym_fns elf_sym_fns_gdb_index = |
6ed6bacf AM |
2670 | elf_symfile_segments, /* Get segment information from a file. */ |
2671 | NULL, | |
2672 | default_symfile_relocate, /* Relocate a debug section. */ | |
2673 | + &elf_probe_fns, /* sym_probe_fns */ | |
2674 | &dwarf2_gdb_index_functions | |
2675 | }; | |
2676 | ||
f412e1b4 | 2677 | @@ -1642,6 +1925,8 @@ static const struct gnu_ifunc_fns elf_gnu_ifunc_fns = |
6ed6bacf AM |
2678 | void |
2679 | _initialize_elfread (void) | |
2680 | { | |
2681 | + stap_probe_key | |
2682 | + = register_objfile_data_with_cleanup (NULL, stap_probe_key_free); | |
2683 | add_symtab_fns (&elf_sym_fns); | |
2684 | ||
2685 | elf_objfile_gnu_ifunc_cache_data = register_objfile_data (); | |
f412e1b4 PS |
2686 | diff --git a/gdb/eval.c b/gdb/eval.c |
2687 | index 0244f7a..b33d367 100644 | |
2688 | --- a/gdb/eval.c | |
2689 | +++ b/gdb/eval.c | |
2690 | @@ -41,6 +41,7 @@ | |
2691 | #include "gdb_obstack.h" | |
6ed6bacf AM |
2692 | #include "objfiles.h" |
2693 | #include "python/python.h" | |
6ed6bacf AM |
2694 | +#include "dwarf2loc.h" |
2695 | ||
2696 | #include "gdb_assert.h" | |
2697 | ||
f412e1b4 | 2698 | @@ -498,27 +499,217 @@ init_array_element (struct value *array, struct value *element, |
6ed6bacf AM |
2699 | } |
2700 | ||
2701 | static struct value * | |
2702 | -value_f90_subarray (struct value *array, | |
2703 | - struct expression *exp, int *pos, enum noside noside) | |
2704 | +value_f90_subarray (struct value *array, struct expression *exp, int *pos, | |
2705 | + int nargs, enum noside noside) | |
2706 | { | |
2707 | - int pc = (*pos) + 1; | |
2708 | - LONGEST low_bound, high_bound; | |
2709 | - struct type *range = check_typedef (TYPE_INDEX_TYPE (value_type (array))); | |
2710 | - enum f90_range_type range_type = longest_to_int (exp->elts[pc].longconst); | |
2711 | - | |
2712 | - *pos += 3; | |
f412e1b4 | 2713 | - |
6ed6bacf AM |
2714 | - if (range_type == LOW_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT) |
2715 | - low_bound = TYPE_LOW_BOUND (range); | |
f412e1b4 PS |
2716 | + /* Type to use for the newly allocated value ARRAY. */ |
2717 | + struct type *new_array_type; | |
2718 | + | |
6ed6bacf AM |
2719 | + /* Type being iterated for each dimension. */ |
2720 | + struct type *type, *type_last_target; | |
2721 | + | |
2722 | + /* Pointer in the last holder to the type of current dimension. */ | |
2723 | + struct type **typep = &new_array_type; | |
2724 | + | |
2725 | + struct subscript_index | |
2726 | + { | |
2727 | + enum { SUBSCRIPT_RANGE, SUBSCRIPT_NUMBER } kind; | |
2728 | + union | |
51a5ef0f | 2729 | + { |
6ed6bacf | 2730 | + struct subscript_range |
51a5ef0f | 2731 | + { |
6ed6bacf AM |
2732 | + enum f90_range_type f90_range_type; |
2733 | + LONGEST low_bound, high_bound; | |
51a5ef0f | 2734 | + } |
6ed6bacf AM |
2735 | + range; |
2736 | + LONGEST number; | |
2737 | + }; | |
51a5ef0f | 2738 | + } |
6ed6bacf AM |
2739 | + *subscript_array; |
2740 | + struct type **type_array; | |
2741 | + int i; | |
2742 | + struct cleanup *old_chain; | |
2743 | + CORE_ADDR value_byte_address, value_byte_offset = 0; | |
2744 | + htab_t copied_types; | |
2745 | + struct value *saved_array; | |
2746 | + | |
2747 | + old_chain = make_cleanup (null_cleanup, 0); | |
2748 | + object_address_set (value_raw_address (array)); | |
2749 | + | |
2750 | + if (value_optimized_out (array) | |
2751 | + || (VALUE_LVAL (array) != not_lval | |
2752 | + && VALUE_LVAL (array) != lval_memory | |
2753 | + && VALUE_LVAL (array) != lval_internalvar_component | |
2754 | + && VALUE_LVAL (array) != lval_internalvar)) | |
2755 | + error (_("value being subranged must be in memory")); | |
2756 | + type = check_typedef (value_type (array)); | |
2757 | + f_object_address_data_valid_or_error (type); | |
7566401a | 2758 | + |
6ed6bacf AM |
2759 | + copied_types = create_copied_types_hash (NULL); |
2760 | + type = copy_type_recursive (type, copied_types); | |
2761 | + htab_delete (copied_types); | |
7566401a | 2762 | + |
6ed6bacf AM |
2763 | + if (nargs != calc_f77_array_dims (type)) |
2764 | + error (_("Wrong number of subscripts")); | |
7566401a | 2765 | + |
6ed6bacf AM |
2766 | + if (TYPE_DATA_LOCATION_IS_ADDR (type)) |
2767 | + { | |
2768 | + value_byte_address = (TYPE_DATA_LOCATION_ADDR (type) | |
2769 | + + value_offset (array)); | |
2770 | + TYPE_DATA_LOCATION_IS_ADDR (type) = 0; | |
2771 | + TYPE_DATA_LOCATION_DWARF_BLOCK (type) = NULL; | |
2772 | + } | |
2773 | else | |
2774 | - low_bound = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside)); | |
2775 | + { | |
2776 | + gdb_assert (TYPE_DATA_LOCATION_DWARF_BLOCK (type) == NULL); | |
2777 | + value_byte_address = value_address (array); | |
2778 | + } | |
7566401a | 2779 | + |
6ed6bacf | 2780 | + new_array_type = type; |
7566401a | 2781 | + |
6ed6bacf | 2782 | + subscript_array = alloca (sizeof (*subscript_array) * nargs); |
7566401a | 2783 | + |
6ed6bacf | 2784 | + gdb_assert (nargs > 0); |
7566401a | 2785 | + |
6ed6bacf AM |
2786 | + /* Now that we know we have a legal array subscript expression |
2787 | + let us actually find out where this element exists in the array. */ | |
7566401a | 2788 | + |
6ed6bacf AM |
2789 | + /* Take array indices left to right. */ |
2790 | + for (i = 0; i < nargs; i++) | |
2791 | + { | |
2792 | + struct subscript_index *index = &subscript_array[i]; | |
7566401a | 2793 | + |
6ed6bacf AM |
2794 | + if (exp->elts[*pos].opcode == OP_F90_RANGE) |
2795 | + { | |
2796 | + int pc = (*pos) + 1; | |
2797 | + struct subscript_range *range; | |
7566401a | 2798 | + |
6ed6bacf AM |
2799 | + index->kind = SUBSCRIPT_RANGE; |
2800 | + range = &index->range; | |
7566401a | 2801 | + |
6ed6bacf AM |
2802 | + *pos += 3; |
2803 | + range->f90_range_type = longest_to_int (exp->elts[pc].longconst); | |
7566401a | 2804 | + |
6ed6bacf AM |
2805 | + if (range->f90_range_type == HIGH_BOUND_DEFAULT |
2806 | + || range->f90_range_type == NONE_BOUND_DEFAULT) | |
2807 | + range->low_bound = value_as_long (evaluate_subexp (NULL_TYPE, exp, | |
2808 | + pos, noside)); | |
7566401a | 2809 | + |
6ed6bacf AM |
2810 | + if (range->f90_range_type == LOW_BOUND_DEFAULT |
2811 | + || range->f90_range_type == NONE_BOUND_DEFAULT) | |
2812 | + range->high_bound = value_as_long (evaluate_subexp (NULL_TYPE, exp, | |
2813 | + pos, noside)); | |
2814 | + } | |
2815 | + else | |
51a5ef0f | 2816 | + { |
6ed6bacf AM |
2817 | + struct value *val; |
2818 | + | |
2819 | + index->kind = SUBSCRIPT_NUMBER; | |
2820 | ||
2821 | - if (range_type == HIGH_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT) | |
2822 | - high_bound = TYPE_HIGH_BOUND (range); | |
2823 | + /* Evaluate each subscript; it must be a legal integer in F77. */ | |
2824 | + val = evaluate_subexp_with_coercion (exp, pos, noside); | |
2825 | + index->number = value_as_long (val); | |
51a5ef0f PS |
2826 | + } |
2827 | + } | |
7566401a | 2828 | + |
6ed6bacf AM |
2829 | + /* Internal type of array is arranged right to left. */ |
2830 | + for (i = nargs - 1; i >= 0; i--) | |
7566401a | 2831 | + { |
6ed6bacf AM |
2832 | + struct subscript_index *index = &subscript_array[i]; |
2833 | + struct type *range_type = TYPE_INDEX_TYPE (type); | |
7566401a | 2834 | + |
6ed6bacf | 2835 | + switch (index->kind) |
7566401a | 2836 | + { |
6ed6bacf AM |
2837 | + case SUBSCRIPT_RANGE: |
2838 | + { | |
2839 | + struct subscript_range *range = &index->range; | |
2840 | + CORE_ADDR byte_offset; | |
2841 | + | |
2842 | + if (range->f90_range_type == LOW_BOUND_DEFAULT | |
2843 | + || range->f90_range_type == BOTH_BOUND_DEFAULT) | |
2844 | + range->low_bound = TYPE_LOW_BOUND (range_type); | |
2845 | + | |
2846 | + if (range->f90_range_type == HIGH_BOUND_DEFAULT | |
2847 | + || range->f90_range_type == BOTH_BOUND_DEFAULT) | |
2848 | + range->high_bound = TYPE_HIGH_BOUND (range_type); | |
2849 | + | |
2850 | + if (range->low_bound < TYPE_LOW_BOUND (range_type) | |
2851 | + || (!TYPE_HIGH_BOUND_UNDEFINED (range_type) | |
2852 | + && range->high_bound > TYPE_HIGH_BOUND (range_type))) | |
2853 | + error (_("slice out of range")); | |
2854 | + | |
2855 | + byte_offset = ((range->low_bound - TYPE_LOW_BOUND (range_type)) | |
2856 | + * TYPE_ARRAY_BYTE_STRIDE_VALUE (type)); | |
2857 | + TYPE_LOW_BOUND (range_type) = range->low_bound; | |
2858 | + TYPE_HIGH_BOUND (range_type) = range->high_bound; | |
2859 | + if (range->f90_range_type == LOW_BOUND_DEFAULT | |
2860 | + || range->f90_range_type == NONE_BOUND_DEFAULT) | |
2861 | + TYPE_HIGH_BOUND_UNDEFINED (range_type) = 0; | |
2862 | + | |
2863 | + typep = &TYPE_TARGET_TYPE (type); | |
2864 | + value_byte_offset += byte_offset; | |
2865 | + type = TYPE_TARGET_TYPE (type); | |
2866 | + } | |
2867 | + break; | |
7566401a | 2868 | + |
6ed6bacf AM |
2869 | + case SUBSCRIPT_NUMBER: |
2870 | + { | |
2871 | + CORE_ADDR byte_offset; | |
7566401a | 2872 | + |
6ed6bacf AM |
2873 | + if (index->number < TYPE_LOW_BOUND (range_type) |
2874 | + || (!TYPE_HIGH_BOUND_UNDEFINED (range_type) | |
2875 | + && index->number > TYPE_HIGH_BOUND (range_type))) | |
2876 | + error (_("no such vector element")); | |
7566401a | 2877 | + |
6ed6bacf AM |
2878 | + byte_offset = ((index->number - TYPE_LOW_BOUND (range_type)) |
2879 | + * TYPE_ARRAY_BYTE_STRIDE_VALUE (type)); | |
7566401a | 2880 | + |
6ed6bacf AM |
2881 | + type = TYPE_TARGET_TYPE (type); |
2882 | + *typep = type; | |
2883 | + value_byte_offset += byte_offset; | |
2884 | + } | |
2885 | + break; | |
2886 | + } | |
2887 | + } | |
51a5ef0f | 2888 | + |
6ed6bacf AM |
2889 | + type_last_target = type; |
2890 | + type_array = alloca (sizeof (*type_array) * nargs); | |
2891 | + i = 0; | |
2892 | + for (type = new_array_type; type != type_last_target; | |
2893 | + type = TYPE_TARGET_TYPE (type)) | |
2894 | + type_array[i++] = type; | |
2895 | + while (i > 0) | |
2896 | + { | |
2897 | + struct type *type = type_array[--i]; | |
51a5ef0f | 2898 | + |
6ed6bacf AM |
2899 | + /* Force TYPE_LENGTH (type) recalculation. */ |
2900 | + TYPE_TARGET_STUB (type) = 1; | |
2901 | + check_typedef (type); | |
2902 | + } | |
51a5ef0f | 2903 | + |
6ed6bacf AM |
2904 | + saved_array = array; |
2905 | + array = allocate_value_lazy (new_array_type); | |
2906 | + VALUE_LVAL (array) = VALUE_LVAL (saved_array); | |
2907 | + if (VALUE_LVAL (saved_array) == lval_internalvar_component) | |
2908 | + VALUE_LVAL (array) = lval_internalvar; | |
2909 | else | |
2910 | - high_bound = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside)); | |
2911 | + VALUE_LVAL (array) = VALUE_LVAL (saved_array); | |
2912 | + VALUE_FRAME_ID (array) = VALUE_FRAME_ID (saved_array); | |
2913 | + if (VALUE_LVAL (array) != lval_internalvar) | |
2914 | + set_value_address (array, value_byte_address + value_byte_offset); | |
f412e1b4 | 2915 | + |
6ed6bacf AM |
2916 | + if (!value_lazy (saved_array)) |
2917 | + { | |
2918 | + allocate_value_contents (array); | |
2919 | + set_value_lazy (array, 0); | |
f412e1b4 PS |
2920 | |
2921 | - return value_slice (array, low_bound, high_bound - low_bound + 1); | |
6ed6bacf AM |
2922 | + memcpy (value_contents_writeable (array), |
2923 | + value_contents (saved_array) + value_byte_offset, | |
2924 | + TYPE_LENGTH (new_array_type)); | |
2925 | + } | |
51a5ef0f | 2926 | + |
6ed6bacf AM |
2927 | + do_cleanups (old_chain); |
2928 | + return array; | |
51a5ef0f PS |
2929 | } |
2930 | ||
51a5ef0f | 2931 | |
f412e1b4 | 2932 | @@ -799,6 +990,7 @@ evaluate_subexp_standard (struct type *expect_type, |
6ed6bacf AM |
2933 | int save_pos1; |
2934 | struct symbol *function = NULL; | |
2935 | char *function_name = NULL; | |
2936 | + struct cleanup *old_chain; | |
51a5ef0f | 2937 | |
6ed6bacf AM |
2938 | pc = (*pos)++; |
2939 | op = exp->elts[pc].opcode; | |
f412e1b4 | 2940 | @@ -1874,6 +2066,8 @@ evaluate_subexp_standard (struct type *expect_type, |
51a5ef0f | 2941 | |
6ed6bacf AM |
2942 | /* First determine the type code we are dealing with. */ |
2943 | arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); | |
2944 | + old_chain = make_cleanup (null_cleanup, 0); | |
2945 | + object_address_set (value_raw_address (arg1)); | |
2946 | type = check_typedef (value_type (arg1)); | |
2947 | code = TYPE_CODE (type); | |
51a5ef0f | 2948 | |
f412e1b4 | 2949 | @@ -1894,23 +2088,13 @@ evaluate_subexp_standard (struct type *expect_type, |
6ed6bacf AM |
2950 | code = TYPE_CODE (type); |
2951 | } | |
2952 | } | |
2953 | + do_cleanups (old_chain); | |
51a5ef0f | 2954 | |
6ed6bacf | 2955 | switch (code) |
51a5ef0f | 2956 | { |
6ed6bacf AM |
2957 | case TYPE_CODE_ARRAY: |
2958 | - if (exp->elts[*pos].opcode == OP_F90_RANGE) | |
2959 | - return value_f90_subarray (arg1, exp, pos, noside); | |
2960 | - else | |
2961 | - goto multi_f77_subscript; | |
2962 | - | |
2963 | case TYPE_CODE_STRING: | |
2964 | - if (exp->elts[*pos].opcode == OP_F90_RANGE) | |
2965 | - return value_f90_subarray (arg1, exp, pos, noside); | |
2966 | - else | |
2967 | - { | |
2968 | - arg2 = evaluate_subexp_with_coercion (exp, pos, noside); | |
2969 | - return value_subscript (arg1, value_as_long (arg2)); | |
2970 | - } | |
2971 | + return value_f90_subarray (arg1, exp, pos, nargs, noside); | |
2972 | ||
2973 | case TYPE_CODE_PTR: | |
2974 | case TYPE_CODE_FUNC: | |
f412e1b4 | 2975 | @@ -2349,49 +2533,6 @@ evaluate_subexp_standard (struct type *expect_type, |
6ed6bacf AM |
2976 | } |
2977 | return (arg1); | |
51a5ef0f | 2978 | |
6ed6bacf AM |
2979 | - multi_f77_subscript: |
2980 | - { | |
2981 | - LONGEST subscript_array[MAX_FORTRAN_DIMS]; | |
2982 | - int ndimensions = 1, i; | |
2983 | - struct value *array = arg1; | |
51a5ef0f | 2984 | - |
6ed6bacf AM |
2985 | - if (nargs > MAX_FORTRAN_DIMS) |
2986 | - error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS); | |
51a5ef0f | 2987 | - |
6ed6bacf | 2988 | - ndimensions = calc_f77_array_dims (type); |
51a5ef0f | 2989 | - |
6ed6bacf AM |
2990 | - if (nargs != ndimensions) |
2991 | - error (_("Wrong number of subscripts")); | |
51a5ef0f | 2992 | - |
6ed6bacf | 2993 | - gdb_assert (nargs > 0); |
51a5ef0f | 2994 | - |
6ed6bacf AM |
2995 | - /* Now that we know we have a legal array subscript expression |
2996 | - let us actually find out where this element exists in the array. */ | |
2997 | - | |
2998 | - /* Take array indices left to right. */ | |
2999 | - for (i = 0; i < nargs; i++) | |
3000 | - { | |
3001 | - /* Evaluate each subscript; it must be a legal integer in F77. */ | |
3002 | - arg2 = evaluate_subexp_with_coercion (exp, pos, noside); | |
3003 | - | |
3004 | - /* Fill in the subscript array. */ | |
3005 | - | |
3006 | - subscript_array[i] = value_as_long (arg2); | |
3007 | - } | |
3008 | - | |
3009 | - /* Internal type of array is arranged right to left. */ | |
3010 | - for (i = nargs; i > 0; i--) | |
3011 | - { | |
3012 | - struct type *array_type = check_typedef (value_type (array)); | |
3013 | - LONGEST index = subscript_array[i - 1]; | |
3014 | - | |
3015 | - lower = f77_get_lowerbound (array_type); | |
3016 | - array = value_subscripted_rvalue (array, index, lower); | |
3017 | - } | |
3018 | - | |
3019 | - return array; | |
3020 | - } | |
3021 | - | |
3022 | case BINOP_LOGICAL_AND: | |
3023 | arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); | |
3024 | if (noside == EVAL_SKIP) | |
f412e1b4 | 3025 | @@ -2623,15 +2764,23 @@ evaluate_subexp_standard (struct type *expect_type, |
6ed6bacf AM |
3026 | if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR) |
3027 | expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type)); | |
3028 | arg1 = evaluate_subexp (expect_type, exp, pos, noside); | |
3029 | + old_chain = make_cleanup (null_cleanup, 0); | |
3030 | + object_address_set (value_raw_address (arg1)); | |
3031 | type = check_typedef (value_type (arg1)); | |
3032 | if (TYPE_CODE (type) == TYPE_CODE_METHODPTR | |
3033 | || TYPE_CODE (type) == TYPE_CODE_MEMBERPTR) | |
3034 | error (_("Attempt to dereference pointer " | |
3035 | "to member without an object")); | |
3036 | if (noside == EVAL_SKIP) | |
3037 | - goto nosideret; | |
3038 | + { | |
3039 | + do_cleanups (old_chain); | |
3040 | + goto nosideret; | |
3041 | + } | |
3042 | if (unop_user_defined_p (op, arg1)) | |
3043 | - return value_x_unop (arg1, op, noside); | |
3044 | + { | |
3045 | + do_cleanups (old_chain); | |
3046 | + return value_x_unop (arg1, op, noside); | |
3047 | + } | |
3048 | else if (noside == EVAL_AVOID_SIDE_EFFECTS) | |
3049 | { | |
3050 | type = check_typedef (value_type (arg1)); | |
f412e1b4 | 3051 | @@ -2640,12 +2789,18 @@ evaluate_subexp_standard (struct type *expect_type, |
6ed6bacf AM |
3052 | /* In C you can dereference an array to get the 1st elt. */ |
3053 | || TYPE_CODE (type) == TYPE_CODE_ARRAY | |
3054 | ) | |
3055 | - return value_zero (TYPE_TARGET_TYPE (type), | |
3056 | - lval_memory); | |
3057 | + { | |
3058 | + do_cleanups (old_chain); | |
3059 | + return value_zero (TYPE_TARGET_TYPE (type), | |
3060 | + lval_memory); | |
3061 | + } | |
3062 | else if (TYPE_CODE (type) == TYPE_CODE_INT) | |
3063 | - /* GDB allows dereferencing an int. */ | |
3064 | - return value_zero (builtin_type (exp->gdbarch)->builtin_int, | |
3065 | - lval_memory); | |
3066 | + { | |
3067 | + do_cleanups (old_chain); | |
3068 | + /* GDB allows dereferencing an int. */ | |
3069 | + return value_zero (builtin_type (exp->gdbarch)->builtin_int, | |
3070 | + lval_memory); | |
3071 | + } | |
3072 | else | |
3073 | error (_("Attempt to take contents of a non-pointer value.")); | |
3074 | } | |
f412e1b4 | 3075 | @@ -2655,9 +2810,14 @@ evaluate_subexp_standard (struct type *expect_type, |
6ed6bacf AM |
3076 | do. "long long" variables are rare enough that |
3077 | BUILTIN_TYPE_LONGEST would seem to be a mistake. */ | |
3078 | if (TYPE_CODE (type) == TYPE_CODE_INT) | |
3079 | - return value_at_lazy (builtin_type (exp->gdbarch)->builtin_int, | |
3080 | - (CORE_ADDR) value_as_address (arg1)); | |
3081 | - return value_ind (arg1); | |
3082 | + { | |
3083 | + do_cleanups (old_chain); | |
3084 | + return value_at_lazy (builtin_type (exp->gdbarch)->builtin_int, | |
3085 | + (CORE_ADDR) value_as_address (arg1)); | |
3086 | + } | |
3087 | + arg1 = value_ind (arg1); | |
3088 | + do_cleanups (old_chain); | |
3089 | + return arg1; | |
51a5ef0f | 3090 | |
6ed6bacf AM |
3091 | case UNOP_ADDR: |
3092 | /* C++: check for and handle pointer to members. */ | |
f412e1b4 | 3093 | @@ -2999,7 +3159,7 @@ evaluate_subexp_with_coercion (struct expression *exp, |
51a5ef0f | 3094 | { |
6ed6bacf AM |
3095 | enum exp_opcode op; |
3096 | int pc; | |
3097 | - struct value *val; | |
3098 | + struct value *val = NULL; | |
3099 | struct symbol *var; | |
3100 | struct type *type; | |
3101 | ||
f412e1b4 | 3102 | @@ -3010,13 +3170,18 @@ evaluate_subexp_with_coercion (struct expression *exp, |
51a5ef0f | 3103 | { |
6ed6bacf AM |
3104 | case OP_VAR_VALUE: |
3105 | var = exp->elts[pc + 2].symbol; | |
3106 | + /* address_of_variable will call object_address_set for check_typedef. | |
3107 | + Call it only if required as it can error-out on VAR in register. */ | |
3108 | + if (TYPE_DYNAMIC (SYMBOL_TYPE (var))) | |
3109 | + val = address_of_variable (var, exp->elts[pc + 1].block); | |
3110 | type = check_typedef (SYMBOL_TYPE (var)); | |
3111 | if (TYPE_CODE (type) == TYPE_CODE_ARRAY | |
3112 | && !TYPE_VECTOR (type) | |
3113 | && CAST_IS_CONVERSION (exp->language_defn)) | |
3114 | { | |
3115 | (*pos) += 4; | |
3116 | - val = address_of_variable (var, exp->elts[pc + 1].block); | |
3117 | + if (!val) | |
3118 | + val = address_of_variable (var, exp->elts[pc + 1].block); | |
3119 | return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)), | |
3120 | val); | |
3121 | } | |
f412e1b4 | 3122 | @@ -3068,9 +3233,13 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos) |
51a5ef0f | 3123 | |
6ed6bacf AM |
3124 | case OP_VAR_VALUE: |
3125 | (*pos) += 4; | |
3126 | - type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol)); | |
3127 | - return | |
3128 | - value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); | |
3129 | + /* We do not need to call read_var_value but the object evaluation may | |
3130 | + need to have executed object_address_set which needs valid | |
3131 | + SYMBOL_VALUE_ADDRESS of the symbol. Still VALUE returned by | |
3132 | + read_var_value we left as lazy. */ | |
3133 | + type = value_type (read_var_value (exp->elts[pc + 2].symbol, | |
3134 | + deprecated_safe_get_selected_frame ())); | |
3135 | + return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); | |
51a5ef0f | 3136 | |
6ed6bacf AM |
3137 | default: |
3138 | val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); | |
f412e1b4 | 3139 | @@ -3101,18 +3270,25 @@ parse_and_eval_type (char *p, int length) |
6ed6bacf AM |
3140 | int |
3141 | calc_f77_array_dims (struct type *array_type) | |
51a5ef0f | 3142 | { |
6ed6bacf AM |
3143 | - int ndimen = 1; |
3144 | - struct type *tmp_type; | |
3145 | + switch (TYPE_CODE (array_type)) | |
3146 | + { | |
3147 | + case TYPE_CODE_STRING: | |
3148 | + return 1; | |
51a5ef0f | 3149 | |
6ed6bacf AM |
3150 | - if ((TYPE_CODE (array_type) != TYPE_CODE_ARRAY)) |
3151 | - error (_("Can't get dimensions for a non-array type")); | |
3152 | + case TYPE_CODE_ARRAY: | |
3153 | + { | |
3154 | + int ndimen = 1; | |
3155 | ||
3156 | - tmp_type = array_type; | |
3157 | + while ((array_type = TYPE_TARGET_TYPE (array_type))) | |
3158 | + { | |
3159 | + if (TYPE_CODE (array_type) == TYPE_CODE_ARRAY) | |
3160 | + ++ndimen; | |
3161 | + } | |
3162 | + return ndimen; | |
3163 | + } | |
3164 | ||
3165 | - while ((tmp_type = TYPE_TARGET_TYPE (tmp_type))) | |
51a5ef0f | 3166 | - { |
6ed6bacf AM |
3167 | - if (TYPE_CODE (tmp_type) == TYPE_CODE_ARRAY) |
3168 | - ++ndimen; | |
3169 | + default: | |
3170 | + error (_("Can't get dimensions for a non-array/non-string type")); | |
3171 | } | |
3172 | - return ndimen; | |
3173 | + | |
51a5ef0f | 3174 | } |
f412e1b4 PS |
3175 | diff --git a/gdb/f-exp.y b/gdb/f-exp.y |
3176 | index b258c0a..1752973 100644 | |
3177 | --- a/gdb/f-exp.y | |
3178 | +++ b/gdb/f-exp.y | |
3179 | @@ -292,7 +292,9 @@ arglist : subrange | |
6ed6bacf AM |
3180 | { arglist_len = 1; } |
3181 | ; | |
3182 | ||
3183 | -arglist : arglist ',' exp %prec ABOVE_COMMA | |
3184 | +arglist : arglist ',' exp %prec ABOVE_COMMA | |
3185 | + { arglist_len++; } | |
3186 | + | arglist ',' subrange %prec ABOVE_COMMA | |
3187 | { arglist_len++; } | |
3188 | ; | |
3189 | ||
f412e1b4 PS |
3190 | diff --git a/gdb/f-lang.h b/gdb/f-lang.h |
3191 | index 3a46ebf..2b73e1f 100644 | |
3192 | --- a/gdb/f-lang.h | |
3193 | +++ b/gdb/f-lang.h | |
3194 | @@ -28,6 +28,10 @@ extern void f_error (char *); /* Defined in f-exp.y */ | |
6ed6bacf AM |
3195 | extern void f_print_type (struct type *, const char *, struct ui_file *, int, |
3196 | int); | |
51a5ef0f | 3197 | |
6ed6bacf AM |
3198 | +extern const char *f_object_address_data_valid_print_to_stream |
3199 | + (struct type *type, struct ui_file *stream); | |
3200 | +extern void f_object_address_data_valid_or_error (struct type *type); | |
51a5ef0f | 3201 | + |
6ed6bacf AM |
3202 | extern int f_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, |
3203 | struct ui_file *, int, | |
3204 | const struct value *, | |
f412e1b4 PS |
3205 | diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c |
3206 | index a95ef84..830917d 100644 | |
3207 | --- a/gdb/f-typeprint.c | |
3208 | +++ b/gdb/f-typeprint.c | |
3209 | @@ -31,7 +31,7 @@ | |
6ed6bacf AM |
3210 | #include "gdbcore.h" |
3211 | #include "target.h" | |
3212 | #include "f-lang.h" | |
3213 | - | |
3214 | +#include "dwarf2loc.h" | |
3215 | #include "gdb_string.h" | |
3216 | #include <errno.h> | |
3217 | ||
f412e1b4 | 3218 | @@ -48,6 +48,34 @@ void f_type_print_varspec_prefix (struct type *, struct ui_file *, |
6ed6bacf AM |
3219 | void f_type_print_base (struct type *, struct ui_file *, int, int); |
3220 | \f | |
3221 | ||
3222 | +const char * | |
3223 | +f_object_address_data_valid_print_to_stream (struct type *type, | |
3224 | + struct ui_file *stream) | |
51a5ef0f | 3225 | +{ |
6ed6bacf | 3226 | + const char *msg; |
51a5ef0f | 3227 | + |
6ed6bacf AM |
3228 | + msg = object_address_data_not_valid (type); |
3229 | + if (msg != NULL) | |
3230 | + { | |
3231 | + /* Assuming the content printed to STREAM should not be localized. */ | |
3232 | + fprintf_filtered (stream, "<%s>", msg); | |
3233 | + } | |
51a5ef0f | 3234 | + |
6ed6bacf AM |
3235 | + return msg; |
3236 | +} | |
51a5ef0f | 3237 | + |
6ed6bacf AM |
3238 | +void |
3239 | +f_object_address_data_valid_or_error (struct type *type) | |
3240 | +{ | |
3241 | + const char *msg; | |
3242 | + | |
3243 | + msg = object_address_data_not_valid (type); | |
3244 | + if (msg != NULL) | |
3245 | + { | |
3246 | + error (_("Cannot access it because the %s."), _(msg)); | |
3247 | + } | |
51a5ef0f PS |
3248 | +} |
3249 | + | |
6ed6bacf | 3250 | /* LEVEL is the depth to indent lines by. */ |
51a5ef0f | 3251 | |
6ed6bacf | 3252 | void |
f412e1b4 | 3253 | @@ -57,6 +85,9 @@ f_print_type (struct type *type, const char *varstring, struct ui_file *stream, |
6ed6bacf AM |
3254 | enum type_code code; |
3255 | int demangled_args; | |
51a5ef0f | 3256 | |
6ed6bacf AM |
3257 | + if (f_object_address_data_valid_print_to_stream (type, stream) != NULL) |
3258 | + return; | |
51a5ef0f | 3259 | + |
6ed6bacf AM |
3260 | f_type_print_base (type, stream, show, level); |
3261 | code = TYPE_CODE (type); | |
3262 | if ((varstring != NULL && *varstring != '\0') | |
f412e1b4 | 3263 | @@ -164,6 +195,9 @@ f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, |
51a5ef0f | 3264 | |
6ed6bacf AM |
3265 | QUIT; |
3266 | ||
3267 | + if (TYPE_CODE (type) != TYPE_CODE_TYPEDEF) | |
3268 | + CHECK_TYPEDEF (type); | |
51a5ef0f | 3269 | + |
6ed6bacf | 3270 | switch (TYPE_CODE (type)) |
51a5ef0f | 3271 | { |
6ed6bacf | 3272 | case TYPE_CODE_ARRAY: |
f412e1b4 PS |
3273 | diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c |
3274 | index 87b2ed1..5d263f2 100644 | |
3275 | --- a/gdb/f-valprint.c | |
3276 | +++ b/gdb/f-valprint.c | |
3277 | @@ -54,15 +54,17 @@ int f77_array_offset_tbl[MAX_FORTRAN_DIMS + 1][2]; | |
6ed6bacf AM |
3278 | /* The following macro gives us the size of the nth dimension, Where |
3279 | n is 1 based. */ | |
3a58abaf | 3280 | |
6ed6bacf AM |
3281 | -#define F77_DIM_SIZE(n) (f77_array_offset_tbl[n][1]) |
3282 | +#define F77_DIM_COUNT(n) (f77_array_offset_tbl[n][1]) | |
51a5ef0f | 3283 | |
6ed6bacf AM |
3284 | -/* The following gives us the offset for row n where n is 1-based. */ |
3285 | +/* The following gives us the element size for row n where n is 1-based. */ | |
51a5ef0f | 3286 | |
6ed6bacf AM |
3287 | -#define F77_DIM_OFFSET(n) (f77_array_offset_tbl[n][0]) |
3288 | +#define F77_DIM_BYTE_STRIDE(n) (f77_array_offset_tbl[n][0]) | |
3a58abaf | 3289 | |
6ed6bacf AM |
3290 | int |
3291 | f77_get_lowerbound (struct type *type) | |
3292 | { | |
3293 | + f_object_address_data_valid_or_error (type); | |
51a5ef0f | 3294 | + |
6ed6bacf AM |
3295 | if (TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED (type)) |
3296 | error (_("Lower bound may not be '*' in F77")); | |
3a58abaf | 3297 | |
6ed6bacf AM |
3298 | @@ -72,14 +74,17 @@ f77_get_lowerbound (struct type *type) |
3299 | int | |
3300 | f77_get_upperbound (struct type *type) | |
3301 | { | |
3302 | + f_object_address_data_valid_or_error (type); | |
51a5ef0f | 3303 | + |
6ed6bacf AM |
3304 | if (TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)) |
3305 | { | |
3306 | - /* We have an assumed size array on our hands. Assume that | |
3307 | - upper_bound == lower_bound so that we show at least 1 element. | |
3308 | - If the user wants to see more elements, let him manually ask for 'em | |
3309 | - and we'll subscript the array and show him. */ | |
3310 | + /* We have an assumed size array on our hands. As type_length_get | |
3311 | + already assumes a length zero of arrays with underfined bounds VALADDR | |
3312 | + passed to the Fortran functions does not contained the real inferior | |
3313 | + memory content. User should request printing of specific array | |
3314 | + elements instead. */ | |
3315 | ||
3316 | - return f77_get_lowerbound (type); | |
3317 | + return f77_get_lowerbound (type) - 1; | |
3318 | } | |
3319 | ||
3320 | return TYPE_ARRAY_UPPER_BOUND_VALUE (type); | |
f412e1b4 | 3321 | @@ -135,24 +140,29 @@ f77_create_arrayprint_offset_tbl (struct type *type, struct ui_file *stream) |
6ed6bacf AM |
3322 | upper = f77_get_upperbound (tmp_type); |
3323 | lower = f77_get_lowerbound (tmp_type); | |
3324 | ||
3325 | - F77_DIM_SIZE (ndimen) = upper - lower + 1; | |
3326 | + F77_DIM_COUNT (ndimen) = upper - lower + 1; | |
51a5ef0f | 3327 | + |
6ed6bacf AM |
3328 | + F77_DIM_BYTE_STRIDE (ndimen) = |
3329 | + TYPE_ARRAY_BYTE_STRIDE_VALUE (tmp_type); | |
3a58abaf | 3330 | |
6ed6bacf AM |
3331 | tmp_type = TYPE_TARGET_TYPE (tmp_type); |
3332 | ndimen++; | |
3333 | } | |
3334 | ||
3335 | - /* Now we multiply eltlen by all the offsets, so that later we | |
3336 | + /* Now we multiply eltlen by all the BYTE_STRIDEs, so that later we | |
3337 | can print out array elements correctly. Up till now we | |
3338 | - know an offset to apply to get the item but we also | |
3339 | + know an eltlen to apply to get the item but we also | |
3340 | have to know how much to add to get to the next item. */ | |
3341 | ||
3342 | ndimen--; | |
3343 | eltlen = TYPE_LENGTH (tmp_type); | |
3344 | - F77_DIM_OFFSET (ndimen) = eltlen; | |
3345 | + if (F77_DIM_BYTE_STRIDE (ndimen) == 0) | |
3346 | + F77_DIM_BYTE_STRIDE (ndimen) = eltlen; | |
3347 | while (--ndimen > 0) | |
51a5ef0f | 3348 | { |
6ed6bacf AM |
3349 | - eltlen *= F77_DIM_SIZE (ndimen + 1); |
3350 | - F77_DIM_OFFSET (ndimen) = eltlen; | |
3351 | + eltlen *= F77_DIM_COUNT (ndimen + 1); | |
3352 | + if (F77_DIM_BYTE_STRIDE (ndimen) == 0) | |
3353 | + F77_DIM_BYTE_STRIDE (ndimen) = eltlen; | |
51a5ef0f | 3354 | } |
6ed6bacf AM |
3355 | } |
3356 | ||
f412e1b4 | 3357 | @@ -174,37 +184,35 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type, |
6ed6bacf AM |
3358 | |
3359 | if (nss != ndimensions) | |
51a5ef0f | 3360 | { |
6ed6bacf AM |
3361 | - for (i = 0; |
3362 | - (i < F77_DIM_SIZE (nss) && (*elts) < options->print_max); | |
3363 | - i++) | |
3364 | + for (i = 0; (i < F77_DIM_COUNT (nss) && (*elts) < options->print_max); i++) | |
51a5ef0f | 3365 | { |
6ed6bacf AM |
3366 | fprintf_filtered (stream, "( "); |
3367 | f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type), | |
3368 | valaddr, | |
3369 | - embedded_offset + i * F77_DIM_OFFSET (nss), | |
3370 | + embedded_offset + i * F77_DIM_BYTE_STRIDE (nss), | |
3371 | address, | |
3372 | stream, recurse, val, options, elts); | |
3373 | fprintf_filtered (stream, ") "); | |
51a5ef0f | 3374 | } |
6ed6bacf AM |
3375 | - if (*elts >= options->print_max && i < F77_DIM_SIZE (nss)) |
3376 | + if (*elts >= options->print_max && i < F77_DIM_COUNT (nss)) | |
3377 | fprintf_filtered (stream, "..."); | |
3a58abaf | 3378 | } |
6ed6bacf AM |
3379 | else |
3380 | { | |
3381 | - for (i = 0; i < F77_DIM_SIZE (nss) && (*elts) < options->print_max; | |
3382 | + for (i = 0; i < F77_DIM_COUNT (nss) && (*elts) < options->print_max; | |
3383 | i++, (*elts)++) | |
3384 | { | |
3385 | val_print (TYPE_TARGET_TYPE (type), | |
3386 | valaddr, | |
3387 | - embedded_offset + i * F77_DIM_OFFSET (ndimensions), | |
3388 | + embedded_offset + i * F77_DIM_BYTE_STRIDE (ndimensions), | |
3389 | address, stream, recurse, | |
3390 | val, options, current_language); | |
3a58abaf | 3391 | |
6ed6bacf AM |
3392 | - if (i != (F77_DIM_SIZE (nss) - 1)) |
3393 | + if (i != (F77_DIM_COUNT (nss) - 1)) | |
3394 | fprintf_filtered (stream, ", "); | |
3395 | ||
3396 | if ((*elts == options->print_max - 1) | |
3397 | - && (i != (F77_DIM_SIZE (nss) - 1))) | |
3398 | + && (i != (F77_DIM_COUNT (nss) - 1))) | |
3399 | fprintf_filtered (stream, "..."); | |
51a5ef0f PS |
3400 | } |
3401 | } | |
f412e1b4 | 3402 | @@ -260,6 +268,9 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, |
6ed6bacf AM |
3403 | CORE_ADDR addr; |
3404 | int index; | |
51a5ef0f | 3405 | |
6ed6bacf AM |
3406 | + if (f_object_address_data_valid_print_to_stream (type, stream) != NULL) |
3407 | + return 0; | |
3408 | + | |
3409 | CHECK_TYPEDEF (type); | |
3410 | switch (TYPE_CODE (type)) | |
3411 | { | |
f412e1b4 PS |
3412 | diff --git a/gdb/findvar.c b/gdb/findvar.c |
3413 | index 79c4221..1bb7c22 100644 | |
3414 | --- a/gdb/findvar.c | |
3415 | +++ b/gdb/findvar.c | |
3416 | @@ -34,6 +34,7 @@ | |
6ed6bacf AM |
3417 | #include "user-regs.h" |
3418 | #include "block.h" | |
3419 | #include "objfiles.h" | |
3420 | +#include "dwarf2loc.h" | |
51a5ef0f | 3421 | |
6ed6bacf AM |
3422 | /* Basic byte-swapping routines. All 'extract' functions return a |
3423 | host-format integer from a target-format integer at ADDR which is | |
f412e1b4 | 3424 | @@ -407,8 +408,11 @@ symbol_read_needs_frame (struct symbol *sym) |
51a5ef0f | 3425 | |
6ed6bacf AM |
3426 | /* Given a struct symbol for a variable, |
3427 | and a stack frame id, read the value of the variable | |
3428 | - and return a (pointer to a) struct value containing the value. | |
f412e1b4 | 3429 | - If the variable cannot be found, throw error. */ |
6ed6bacf | 3430 | + and return a (pointer to a) struct value containing the value. |
f412e1b4 | 3431 | + If the variable cannot be found, throw error. |
6ed6bacf | 3432 | + We have to first find the address of the variable before allocating struct |
f412e1b4 | 3433 | + value to return as its size may depend on DW_OP_PUSH_OBJECT_ADDRESS possibly |
6ed6bacf | 3434 | + used by its type. */ |
3a58abaf | 3435 | |
6ed6bacf AM |
3436 | struct value * |
3437 | read_var_value (struct symbol *var, struct frame_info *frame) | |
f412e1b4 | 3438 | @@ -416,16 +420,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
6ed6bacf AM |
3439 | struct value *v; |
3440 | struct type *type = SYMBOL_TYPE (var); | |
3441 | CORE_ADDR addr; | |
3442 | - int len; | |
3443 | - | |
3444 | - /* Call check_typedef on our type to make sure that, if TYPE is | |
3445 | - a TYPE_CODE_TYPEDEF, its length is set to the length of the target type | |
3446 | - instead of zero. However, we do not replace the typedef type by the | |
3447 | - target type, because we want to keep the typedef in order to be able to | |
3448 | - set the returned value type description correctly. */ | |
3449 | - check_typedef (type); | |
3450 | - | |
3451 | - len = TYPE_LENGTH (type); | |
3a58abaf | 3452 | |
6ed6bacf AM |
3453 | if (symbol_read_needs_frame (var)) |
3454 | gdb_assert (frame); | |
f412e1b4 | 3455 | @@ -435,7 +429,7 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
6ed6bacf AM |
3456 | case LOC_CONST: |
3457 | /* Put the constant back in target format. */ | |
3458 | v = allocate_value (type); | |
3459 | - store_signed_integer (value_contents_raw (v), len, | |
3460 | + store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type), | |
3461 | gdbarch_byte_order (get_type_arch (type)), | |
3462 | (LONGEST) SYMBOL_VALUE (var)); | |
3463 | VALUE_LVAL (v) = not_lval; | |
f412e1b4 | 3464 | @@ -460,12 +454,12 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
3a58abaf | 3465 | |
6ed6bacf AM |
3466 | case LOC_CONST_BYTES: |
3467 | v = allocate_value (type); | |
3468 | - memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), len); | |
3469 | + memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), | |
3470 | + TYPE_LENGTH (type)); | |
3471 | VALUE_LVAL (v) = not_lval; | |
3472 | return v; | |
3a58abaf | 3473 | |
6ed6bacf AM |
3474 | case LOC_STATIC: |
3475 | - v = allocate_value_lazy (type); | |
3476 | if (overlay_debugging) | |
3477 | addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), | |
3478 | SYMBOL_OBJ_SECTION (var)); | |
f412e1b4 PS |
3479 | @@ -479,7 +473,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
3480 | error (_("Unknown argument list address for `%s'."), | |
3481 | SYMBOL_PRINT_NAME (var)); | |
6ed6bacf AM |
3482 | addr += SYMBOL_VALUE (var); |
3483 | - v = allocate_value_lazy (type); | |
3484 | break; | |
3485 | ||
3486 | case LOC_REF_ARG: | |
f412e1b4 | 3487 | @@ -494,14 +487,12 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
6ed6bacf AM |
3488 | argref += SYMBOL_VALUE (var); |
3489 | ref = value_at (lookup_pointer_type (type), argref); | |
3490 | addr = value_as_address (ref); | |
3491 | - v = allocate_value_lazy (type); | |
3492 | break; | |
3493 | } | |
3494 | ||
3495 | case LOC_LOCAL: | |
3496 | addr = get_frame_locals_address (frame); | |
3497 | addr += SYMBOL_VALUE (var); | |
3498 | - v = allocate_value_lazy (type); | |
3499 | break; | |
3500 | ||
3501 | case LOC_TYPEDEF: | |
f412e1b4 | 3502 | @@ -510,7 +501,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
6ed6bacf AM |
3503 | break; |
3504 | ||
3505 | case LOC_BLOCK: | |
3506 | - v = allocate_value_lazy (type); | |
3507 | if (overlay_debugging) | |
3508 | addr = symbol_overlayed_address | |
3509 | (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var)); | |
f412e1b4 PS |
3510 | @@ -536,7 +526,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
3511 | SYMBOL_PRINT_NAME (var)); | |
6ed6bacf AM |
3512 | |
3513 | addr = value_as_address (regval); | |
3514 | - v = allocate_value_lazy (type); | |
3515 | } | |
3516 | else | |
3517 | { | |
f412e1b4 | 3518 | @@ -576,7 +565,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
6ed6bacf AM |
3519 | if (obj_section |
3520 | && (obj_section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0) | |
3521 | addr = target_translate_tls_address (obj_section->objfile, addr); | |
3522 | - v = allocate_value_lazy (type); | |
3523 | } | |
3524 | break; | |
3525 | ||
f412e1b4 | 3526 | @@ -589,6 +577,10 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
3a58abaf AM |
3527 | break; |
3528 | } | |
3529 | ||
6ed6bacf AM |
3530 | + /* ADDR is set here for ALLOCATE_VALUE's CHECK_TYPEDEF for |
3531 | + DW_OP_PUSH_OBJECT_ADDRESS. */ | |
3532 | + object_address_set (addr); | |
3533 | + v = allocate_value_lazy (type); | |
3534 | VALUE_LVAL (v) = lval_memory; | |
3535 | set_value_address (v, addr); | |
3536 | return v; | |
f412e1b4 | 3537 | @@ -671,10 +663,11 @@ struct value * |
6ed6bacf AM |
3538 | value_from_register (struct type *type, int regnum, struct frame_info *frame) |
3539 | { | |
3540 | struct gdbarch *gdbarch = get_frame_arch (frame); | |
3541 | - struct type *type1 = check_typedef (type); | |
3542 | struct value *v; | |
3a58abaf | 3543 | |
6ed6bacf AM |
3544 | - if (gdbarch_convert_register_p (gdbarch, regnum, type1)) |
3545 | + type = check_typedef (type); | |
3546 | + | |
3547 | + if (gdbarch_convert_register_p (gdbarch, regnum, type)) | |
3548 | { | |
f412e1b4 PS |
3549 | int optim, unavail, ok; |
3550 | ||
3551 | @@ -689,7 +682,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) | |
6ed6bacf AM |
3552 | VALUE_LVAL (v) = lval_register; |
3553 | VALUE_FRAME_ID (v) = get_frame_id (frame); | |
3554 | VALUE_REGNUM (v) = regnum; | |
3555 | - ok = gdbarch_register_to_value (gdbarch, frame, regnum, type1, | |
3556 | + ok = gdbarch_register_to_value (gdbarch, frame, regnum, type, | |
3557 | value_contents_raw (v), &optim, | |
3558 | &unavail); | |
6ed6bacf | 3559 | |
f412e1b4 PS |
3560 | diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c |
3561 | index 1bd2341..431ddcc 100644 | |
3562 | --- a/gdb/gdbarch.c | |
3563 | +++ b/gdb/gdbarch.c | |
3564 | @@ -265,6 +265,16 @@ struct gdbarch | |
3565 | gdbarch_get_siginfo_type_ftype *get_siginfo_type; | |
3566 | gdbarch_record_special_symbol_ftype *record_special_symbol; | |
3567 | gdbarch_get_syscall_number_ftype *get_syscall_number; | |
3568 | + const char * stap_integer_prefix; | |
3569 | + const char * stap_integer_sufix; | |
3570 | + const char * stap_register_prefix; | |
3571 | + const char * stap_register_sufix; | |
3572 | + const char * stap_register_indirection_prefix; | |
3573 | + const char * stap_register_indirection_sufix; | |
3574 | + const char * stap_gdb_register_prefix; | |
3575 | + const char * stap_gdb_register_sufix; | |
3576 | + gdbarch_stap_is_single_operand_ftype *stap_is_single_operand; | |
3577 | + gdbarch_stap_parse_special_token_ftype *stap_parse_special_token; | |
3578 | int has_global_solist; | |
3579 | int has_global_breakpoints; | |
3580 | gdbarch_has_shared_address_space_ftype *has_shared_address_space; | |
3581 | @@ -423,6 +433,16 @@ struct gdbarch startup_gdbarch = | |
3582 | 0, /* get_siginfo_type */ | |
3583 | 0, /* record_special_symbol */ | |
3584 | 0, /* get_syscall_number */ | |
3585 | + 0, /* stap_integer_prefix */ | |
3586 | + 0, /* stap_integer_sufix */ | |
3587 | + 0, /* stap_register_prefix */ | |
3588 | + 0, /* stap_register_sufix */ | |
3589 | + 0, /* stap_register_indirection_prefix */ | |
3590 | + 0, /* stap_register_indirection_sufix */ | |
3591 | + 0, /* stap_gdb_register_prefix */ | |
3592 | + 0, /* stap_gdb_register_sufix */ | |
3593 | + 0, /* stap_is_single_operand */ | |
3594 | + 0, /* stap_parse_special_token */ | |
3595 | 0, /* has_global_solist */ | |
3596 | 0, /* has_global_breakpoints */ | |
3597 | default_has_shared_address_space, /* has_shared_address_space */ | |
3598 | @@ -715,6 +735,16 @@ verify_gdbarch (struct gdbarch *gdbarch) | |
3599 | /* Skip verify of get_siginfo_type, has predicate. */ | |
3600 | /* Skip verify of record_special_symbol, has predicate. */ | |
3601 | /* Skip verify of get_syscall_number, has predicate. */ | |
3602 | + /* Skip verify of stap_integer_prefix, invalid_p == 0 */ | |
3603 | + /* Skip verify of stap_integer_sufix, invalid_p == 0 */ | |
3604 | + /* Skip verify of stap_register_prefix, invalid_p == 0 */ | |
3605 | + /* Skip verify of stap_register_sufix, invalid_p == 0 */ | |
3606 | + /* Skip verify of stap_register_indirection_prefix, invalid_p == 0 */ | |
3607 | + /* Skip verify of stap_register_indirection_sufix, invalid_p == 0 */ | |
3608 | + /* Skip verify of stap_gdb_register_prefix, invalid_p == 0 */ | |
3609 | + /* Skip verify of stap_gdb_register_sufix, invalid_p == 0 */ | |
3610 | + /* Skip verify of stap_is_single_operand, has predicate. */ | |
3611 | + /* Skip verify of stap_parse_special_token, has predicate. */ | |
3612 | /* Skip verify of has_global_solist, invalid_p == 0 */ | |
3613 | /* Skip verify of has_global_breakpoints, invalid_p == 0 */ | |
3614 | /* Skip verify of has_shared_address_space, invalid_p == 0 */ | |
3615 | @@ -1267,6 +1297,42 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) | |
3616 | "gdbarch_dump: stabs_argument_has_addr = <%s>\n", | |
3617 | host_address_to_string (gdbarch->stabs_argument_has_addr)); | |
3618 | fprintf_unfiltered (file, | |
3619 | + "gdbarch_dump: stap_gdb_register_prefix = %s\n", | |
3620 | + gdbarch->stap_gdb_register_prefix); | |
3621 | + fprintf_unfiltered (file, | |
3622 | + "gdbarch_dump: stap_gdb_register_sufix = %s\n", | |
3623 | + gdbarch->stap_gdb_register_sufix); | |
3624 | + fprintf_unfiltered (file, | |
3625 | + "gdbarch_dump: stap_integer_prefix = %s\n", | |
3626 | + gdbarch->stap_integer_prefix); | |
3627 | + fprintf_unfiltered (file, | |
3628 | + "gdbarch_dump: stap_integer_sufix = %s\n", | |
3629 | + gdbarch->stap_integer_sufix); | |
3630 | + fprintf_unfiltered (file, | |
3631 | + "gdbarch_dump: gdbarch_stap_is_single_operand_p() = %d\n", | |
3632 | + gdbarch_stap_is_single_operand_p (gdbarch)); | |
3633 | + fprintf_unfiltered (file, | |
3634 | + "gdbarch_dump: stap_is_single_operand = <%s>\n", | |
3635 | + host_address_to_string (gdbarch->stap_is_single_operand)); | |
3636 | + fprintf_unfiltered (file, | |
3637 | + "gdbarch_dump: gdbarch_stap_parse_special_token_p() = %d\n", | |
3638 | + gdbarch_stap_parse_special_token_p (gdbarch)); | |
3639 | + fprintf_unfiltered (file, | |
3640 | + "gdbarch_dump: stap_parse_special_token = <%s>\n", | |
3641 | + host_address_to_string (gdbarch->stap_parse_special_token)); | |
3642 | + fprintf_unfiltered (file, | |
3643 | + "gdbarch_dump: stap_register_indirection_prefix = %s\n", | |
3644 | + gdbarch->stap_register_indirection_prefix); | |
3645 | + fprintf_unfiltered (file, | |
3646 | + "gdbarch_dump: stap_register_indirection_sufix = %s\n", | |
3647 | + gdbarch->stap_register_indirection_sufix); | |
3648 | + fprintf_unfiltered (file, | |
3649 | + "gdbarch_dump: stap_register_prefix = %s\n", | |
3650 | + gdbarch->stap_register_prefix); | |
3651 | + fprintf_unfiltered (file, | |
3652 | + "gdbarch_dump: stap_register_sufix = %s\n", | |
3653 | + gdbarch->stap_register_sufix); | |
3654 | + fprintf_unfiltered (file, | |
3655 | "gdbarch_dump: gdbarch_static_transform_name_p() = %d\n", | |
3656 | gdbarch_static_transform_name_p (gdbarch)); | |
3657 | fprintf_unfiltered (file, | |
3658 | @@ -3834,6 +3900,190 @@ set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, | |
3659 | gdbarch->get_syscall_number = get_syscall_number; | |
6ed6bacf AM |
3660 | } |
3661 | ||
f412e1b4 PS |
3662 | +const char * |
3663 | +gdbarch_stap_integer_prefix (struct gdbarch *gdbarch) | |
3664 | +{ | |
3665 | + gdb_assert (gdbarch != NULL); | |
3666 | + /* Skip verify of stap_integer_prefix, invalid_p == 0 */ | |
3667 | + if (gdbarch_debug >= 2) | |
3668 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_prefix called\n"); | |
3669 | + return gdbarch->stap_integer_prefix; | |
3670 | +} | |
3671 | + | |
3672 | +void | |
3673 | +set_gdbarch_stap_integer_prefix (struct gdbarch *gdbarch, | |
3674 | + const char * stap_integer_prefix) | |
3675 | +{ | |
3676 | + gdbarch->stap_integer_prefix = stap_integer_prefix; | |
3677 | +} | |
3678 | + | |
3679 | +const char * | |
3680 | +gdbarch_stap_integer_sufix (struct gdbarch *gdbarch) | |
3681 | +{ | |
3682 | + gdb_assert (gdbarch != NULL); | |
3683 | + /* Skip verify of stap_integer_sufix, invalid_p == 0 */ | |
3684 | + if (gdbarch_debug >= 2) | |
3685 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_sufix called\n"); | |
3686 | + return gdbarch->stap_integer_sufix; | |
3687 | +} | |
3688 | + | |
3689 | +void | |
3690 | +set_gdbarch_stap_integer_sufix (struct gdbarch *gdbarch, | |
3691 | + const char * stap_integer_sufix) | |
3692 | +{ | |
3693 | + gdbarch->stap_integer_sufix = stap_integer_sufix; | |
3694 | +} | |
3695 | + | |
3696 | +const char * | |
3697 | +gdbarch_stap_register_prefix (struct gdbarch *gdbarch) | |
3698 | +{ | |
3699 | + gdb_assert (gdbarch != NULL); | |
3700 | + /* Skip verify of stap_register_prefix, invalid_p == 0 */ | |
3701 | + if (gdbarch_debug >= 2) | |
3702 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_prefix called\n"); | |
3703 | + return gdbarch->stap_register_prefix; | |
3704 | +} | |
3705 | + | |
3706 | +void | |
3707 | +set_gdbarch_stap_register_prefix (struct gdbarch *gdbarch, | |
3708 | + const char * stap_register_prefix) | |
3709 | +{ | |
3710 | + gdbarch->stap_register_prefix = stap_register_prefix; | |
3711 | +} | |
3712 | + | |
3713 | +const char * | |
3714 | +gdbarch_stap_register_sufix (struct gdbarch *gdbarch) | |
3715 | +{ | |
3716 | + gdb_assert (gdbarch != NULL); | |
3717 | + /* Skip verify of stap_register_sufix, invalid_p == 0 */ | |
3718 | + if (gdbarch_debug >= 2) | |
3719 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_sufix called\n"); | |
3720 | + return gdbarch->stap_register_sufix; | |
3721 | +} | |
3722 | + | |
3723 | +void | |
3724 | +set_gdbarch_stap_register_sufix (struct gdbarch *gdbarch, | |
3725 | + const char * stap_register_sufix) | |
3726 | +{ | |
3727 | + gdbarch->stap_register_sufix = stap_register_sufix; | |
3728 | +} | |
3729 | + | |
3730 | +const char * | |
3731 | +gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch) | |
3732 | +{ | |
3733 | + gdb_assert (gdbarch != NULL); | |
3734 | + /* Skip verify of stap_register_indirection_prefix, invalid_p == 0 */ | |
3735 | + if (gdbarch_debug >= 2) | |
3736 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_prefix called\n"); | |
3737 | + return gdbarch->stap_register_indirection_prefix; | |
3738 | +} | |
3739 | + | |
3740 | +void | |
3741 | +set_gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch, | |
3742 | + const char * stap_register_indirection_prefix) | |
3743 | +{ | |
3744 | + gdbarch->stap_register_indirection_prefix = stap_register_indirection_prefix; | |
3745 | +} | |
3746 | + | |
3747 | +const char * | |
3748 | +gdbarch_stap_register_indirection_sufix (struct gdbarch *gdbarch) | |
3749 | +{ | |
3750 | + gdb_assert (gdbarch != NULL); | |
3751 | + /* Skip verify of stap_register_indirection_sufix, invalid_p == 0 */ | |
3752 | + if (gdbarch_debug >= 2) | |
3753 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_sufix called\n"); | |
3754 | + return gdbarch->stap_register_indirection_sufix; | |
3755 | +} | |
3756 | + | |
3757 | +void | |
3758 | +set_gdbarch_stap_register_indirection_sufix (struct gdbarch *gdbarch, | |
3759 | + const char * stap_register_indirection_sufix) | |
3760 | +{ | |
3761 | + gdbarch->stap_register_indirection_sufix = stap_register_indirection_sufix; | |
3762 | +} | |
3763 | + | |
3764 | +const char * | |
3765 | +gdbarch_stap_gdb_register_prefix (struct gdbarch *gdbarch) | |
3766 | +{ | |
3767 | + gdb_assert (gdbarch != NULL); | |
3768 | + /* Skip verify of stap_gdb_register_prefix, invalid_p == 0 */ | |
3769 | + if (gdbarch_debug >= 2) | |
3770 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_gdb_register_prefix called\n"); | |
3771 | + return gdbarch->stap_gdb_register_prefix; | |
3772 | +} | |
3773 | + | |
3774 | +void | |
3775 | +set_gdbarch_stap_gdb_register_prefix (struct gdbarch *gdbarch, | |
3776 | + const char * stap_gdb_register_prefix) | |
3777 | +{ | |
3778 | + gdbarch->stap_gdb_register_prefix = stap_gdb_register_prefix; | |
3779 | +} | |
3780 | + | |
3781 | +const char * | |
3782 | +gdbarch_stap_gdb_register_sufix (struct gdbarch *gdbarch) | |
3783 | +{ | |
3784 | + gdb_assert (gdbarch != NULL); | |
3785 | + /* Skip verify of stap_gdb_register_sufix, invalid_p == 0 */ | |
3786 | + if (gdbarch_debug >= 2) | |
3787 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_gdb_register_sufix called\n"); | |
3788 | + return gdbarch->stap_gdb_register_sufix; | |
3789 | +} | |
3790 | + | |
3791 | +void | |
3792 | +set_gdbarch_stap_gdb_register_sufix (struct gdbarch *gdbarch, | |
3793 | + const char * stap_gdb_register_sufix) | |
3794 | +{ | |
3795 | + gdbarch->stap_gdb_register_sufix = stap_gdb_register_sufix; | |
3796 | +} | |
3797 | + | |
3798 | +int | |
3799 | +gdbarch_stap_is_single_operand_p (struct gdbarch *gdbarch) | |
3800 | +{ | |
3801 | + gdb_assert (gdbarch != NULL); | |
3802 | + return gdbarch->stap_is_single_operand != NULL; | |
3803 | +} | |
3804 | + | |
3805 | +int | |
3806 | +gdbarch_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) | |
3807 | +{ | |
3808 | + gdb_assert (gdbarch != NULL); | |
3809 | + gdb_assert (gdbarch->stap_is_single_operand != NULL); | |
3810 | + if (gdbarch_debug >= 2) | |
3811 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_is_single_operand called\n"); | |
3812 | + return gdbarch->stap_is_single_operand (gdbarch, s); | |
3813 | +} | |
3814 | + | |
3815 | +void | |
3816 | +set_gdbarch_stap_is_single_operand (struct gdbarch *gdbarch, | |
3817 | + gdbarch_stap_is_single_operand_ftype stap_is_single_operand) | |
3818 | +{ | |
3819 | + gdbarch->stap_is_single_operand = stap_is_single_operand; | |
3820 | +} | |
3821 | + | |
3822 | +int | |
3823 | +gdbarch_stap_parse_special_token_p (struct gdbarch *gdbarch) | |
3824 | +{ | |
3825 | + gdb_assert (gdbarch != NULL); | |
3826 | + return gdbarch->stap_parse_special_token != NULL; | |
3827 | +} | |
3828 | + | |
3829 | +int | |
3830 | +gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, struct stap_parse_info *p) | |
3831 | +{ | |
3832 | + gdb_assert (gdbarch != NULL); | |
3833 | + gdb_assert (gdbarch->stap_parse_special_token != NULL); | |
3834 | + if (gdbarch_debug >= 2) | |
3835 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_parse_special_token called\n"); | |
3836 | + return gdbarch->stap_parse_special_token (gdbarch, p); | |
3837 | +} | |
3838 | + | |
3839 | +void | |
3840 | +set_gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, | |
3841 | + gdbarch_stap_parse_special_token_ftype stap_parse_special_token) | |
3842 | +{ | |
3843 | + gdbarch->stap_parse_special_token = stap_parse_special_token; | |
3844 | +} | |
3845 | + | |
3846 | int | |
3847 | gdbarch_has_global_solist (struct gdbarch *gdbarch) | |
3848 | { | |
3849 | diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h | |
3850 | index 044281c..294a63f 100644 | |
3851 | --- a/gdb/gdbarch.h | |
3852 | +++ b/gdb/gdbarch.h | |
3853 | @@ -55,6 +55,7 @@ struct core_regset_section; | |
3854 | struct syscall; | |
3855 | struct agent_expr; | |
3856 | struct axs_value; | |
3857 | +struct stap_parse_info; | |
3858 | ||
3859 | /* The architecture associated with the connection to the target. | |
3860 | ||
3861 | @@ -979,6 +980,125 @@ typedef LONGEST (gdbarch_get_syscall_number_ftype) (struct gdbarch *gdbarch, pti | |
3862 | extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid); | |
3863 | extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number); | |
3864 | ||
3865 | +/* SystemTap related fields and functions. | |
3866 | + Prefix used to mark an integer constant on the architecture's assembly | |
3867 | + For example, on x86 integer constants are written as: | |
3868 | + | |
3869 | + $10 ;; integer constant 10 | |
3870 | + | |
3871 | + in this case, this prefix would be the character `$'. */ | |
3872 | + | |
3873 | +extern const char * gdbarch_stap_integer_prefix (struct gdbarch *gdbarch); | |
3874 | +extern void set_gdbarch_stap_integer_prefix (struct gdbarch *gdbarch, const char * stap_integer_prefix); | |
3875 | + | |
3876 | +/* Sufix used to mark an integer constant on the architecture's assembly. */ | |
3877 | + | |
3878 | +extern const char * gdbarch_stap_integer_sufix (struct gdbarch *gdbarch); | |
3879 | +extern void set_gdbarch_stap_integer_sufix (struct gdbarch *gdbarch, const char * stap_integer_sufix); | |
3880 | + | |
3881 | +/* Prefix used to mark a register name on the architecture's assembly. | |
3882 | + For example, on x86 the register name is written as: | |
3883 | + | |
3884 | + %eax ;; register eax | |
3885 | + | |
3886 | + in this case, this prefix would be the character `%'. */ | |
3887 | + | |
3888 | +extern const char * gdbarch_stap_register_prefix (struct gdbarch *gdbarch); | |
3889 | +extern void set_gdbarch_stap_register_prefix (struct gdbarch *gdbarch, const char * stap_register_prefix); | |
3890 | + | |
3891 | +/* Sufix used to mark a register name on the architecture's assembly */ | |
3892 | + | |
3893 | +extern const char * gdbarch_stap_register_sufix (struct gdbarch *gdbarch); | |
3894 | +extern void set_gdbarch_stap_register_sufix (struct gdbarch *gdbarch, const char * stap_register_sufix); | |
3895 | + | |
3896 | +/* Prefix used to mark a register indirection on the architecture's assembly. | |
3897 | + For example, on x86 the register indirection is written as: | |
3898 | + | |
3899 | + (%eax) ;; indirecting eax | |
3900 | + | |
3901 | + in this case, this prefix would be the charater `('. | |
3902 | + | |
3903 | + Please note that we use the indirection prefix also for register | |
3904 | + displacement, e.g., `4(%eax)' on x86. */ | |
3905 | + | |
3906 | +extern const char * gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch); | |
3907 | +extern void set_gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch, const char * stap_register_indirection_prefix); | |
3908 | + | |
3909 | +/* Sufix used to mark a register indirection on the architecture's assembly. | |
3910 | + For example, on x86 the register indirection is written as: | |
3911 | + | |
3912 | + (%eax) ;; indirecting eax | |
3913 | + | |
3914 | + in this case, this prefix would be the charater `)'. | |
3915 | + | |
3916 | + Please note that we use the indirection sufix also for register | |
3917 | + displacement, e.g., `4(%eax)' on x86. */ | |
3918 | + | |
3919 | +extern const char * gdbarch_stap_register_indirection_sufix (struct gdbarch *gdbarch); | |
3920 | +extern void set_gdbarch_stap_register_indirection_sufix (struct gdbarch *gdbarch, const char * stap_register_indirection_sufix); | |
3921 | + | |
3922 | +/* Prefix used to name a register using GDB's nomenclature. | |
3923 | + | |
3924 | + For example, on PPC a register is represented by a number in the assembly | |
3925 | + language (e.g., `10' is the 10th general-purpose register). However, | |
3926 | + inside GDB this same register has an `r' appended to its name, so the 10th | |
3927 | + register would be represented as `r10' internally. */ | |
3928 | + | |
3929 | +extern const char * gdbarch_stap_gdb_register_prefix (struct gdbarch *gdbarch); | |
3930 | +extern void set_gdbarch_stap_gdb_register_prefix (struct gdbarch *gdbarch, const char * stap_gdb_register_prefix); | |
3931 | + | |
3932 | +/* Sufix used to name a register using GDB's nomenclature. */ | |
3933 | + | |
3934 | +extern const char * gdbarch_stap_gdb_register_sufix (struct gdbarch *gdbarch); | |
3935 | +extern void set_gdbarch_stap_gdb_register_sufix (struct gdbarch *gdbarch, const char * stap_gdb_register_sufix); | |
3936 | + | |
3937 | +/* Check if S is a single operand. | |
3938 | + | |
3939 | + Single operands can be: | |
3940 | + - Literal integers, e.g. `$10' on x86 | |
3941 | + - Register access, e.g. `%eax' on x86 | |
3942 | + - Register indirection, e.g. `(%eax)' on x86 | |
3943 | + - Register displacement, e.g. `4(%eax)' on x86 | |
3944 | + | |
3945 | + This function should check for these patterns on the string | |
3946 | + and return 1 if some were found, or zero otherwise. Please try to match | |
3947 | + as much info as you can from the string, i.e., if you have to match | |
3948 | + something like `(%', do not match just the `('. */ | |
3949 | + | |
3950 | +extern int gdbarch_stap_is_single_operand_p (struct gdbarch *gdbarch); | |
3951 | + | |
3952 | +typedef int (gdbarch_stap_is_single_operand_ftype) (struct gdbarch *gdbarch, const char *s); | |
3953 | +extern int gdbarch_stap_is_single_operand (struct gdbarch *gdbarch, const char *s); | |
3954 | +extern void set_gdbarch_stap_is_single_operand (struct gdbarch *gdbarch, gdbarch_stap_is_single_operand_ftype *stap_is_single_operand); | |
3955 | + | |
3956 | +/* Function used to handle a "special case" in the parser. | |
3957 | + | |
3958 | + A "special case" is considered to be an unknown token, i.e., a token | |
3959 | + that the parser does not know how to parse. A good example of special | |
3960 | + case would be ARM's register displacement syntax: | |
3961 | + | |
3962 | + [R0, #4] ;; displacing R0 by 4 | |
3963 | + | |
3964 | + Since the parser assumes that a register displacement is of the form: | |
3965 | + | |
3966 | + <number> <indirection_prefix> <register_name> <indirection_sufix> | |
3967 | + | |
3968 | + it means that it will not be able to recognize and parse this odd syntax. | |
3969 | + Therefore, we should add a special case function that will handle this token. | |
3970 | + | |
3971 | + This function should generate the proper expression form of the expression | |
3972 | + using GDB's internal expression mechanism (e.g., `write_exp_elt_opcode' | |
3973 | + and so on). It should also return 1 if the parsing was successful, or zero | |
3974 | + if the token was not recognized as a special token (in this case, returning | |
3975 | + zero means that the special parser is deferring the parsing to the generic | |
3976 | + parser), and should advance the buffer pointer (p->arg). */ | |
3977 | + | |
3978 | +extern int gdbarch_stap_parse_special_token_p (struct gdbarch *gdbarch); | |
3979 | + | |
3980 | +typedef int (gdbarch_stap_parse_special_token_ftype) (struct gdbarch *gdbarch, struct stap_parse_info *p); | |
3981 | +extern int gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, struct stap_parse_info *p); | |
3982 | +extern void set_gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, gdbarch_stap_parse_special_token_ftype *stap_parse_special_token); | |
3983 | + | |
3984 | /* True if the list of shared libraries is one and only for all | |
3985 | processes, as opposed to a list of shared libraries per inferior. | |
3986 | This usually means that all processes, although may or may not share | |
3987 | diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh | |
3988 | index 37281ba..879fab7 100755 | |
3989 | --- a/gdb/gdbarch.sh | |
3990 | +++ b/gdb/gdbarch.sh | |
3991 | @@ -792,6 +792,101 @@ M:void:record_special_symbol:struct objfile *objfile, asymbol *sym:objfile, sym | |
3992 | # Get architecture-specific system calls information from registers. | |
3993 | M:LONGEST:get_syscall_number:ptid_t ptid:ptid | |
3994 | ||
3995 | +# SystemTap related fields and functions. | |
3996 | + | |
3997 | +# Prefix used to mark an integer constant on the architecture's assembly | |
3998 | +# For example, on x86 integer constants are written as: | |
3999 | +# | |
4000 | +# \$10 ;; integer constant 10 | |
4001 | +# | |
4002 | +# in this case, this prefix would be the character \`\$\'. | |
4003 | +v:const char *:stap_integer_prefix:::0:0::0:gdbarch->stap_integer_prefix | |
4004 | + | |
4005 | +# Sufix used to mark an integer constant on the architecture's assembly. | |
4006 | +v:const char *:stap_integer_sufix:::0:0::0:gdbarch->stap_integer_sufix | |
4007 | + | |
4008 | +# Prefix used to mark a register name on the architecture's assembly. | |
4009 | +# For example, on x86 the register name is written as: | |
4010 | +# | |
4011 | +# \%eax ;; register eax | |
4012 | +# | |
4013 | +# in this case, this prefix would be the character \`\%\'. | |
4014 | +v:const char *:stap_register_prefix:::0:0::0:gdbarch->stap_register_prefix | |
4015 | + | |
4016 | +# Sufix used to mark a register name on the architecture's assembly | |
4017 | +v:const char *:stap_register_sufix:::0:0::0:gdbarch->stap_register_sufix | |
4018 | + | |
4019 | +# Prefix used to mark a register indirection on the architecture's assembly. | |
4020 | +# For example, on x86 the register indirection is written as: | |
4021 | +# | |
4022 | +# \(\%eax\) ;; indirecting eax | |
4023 | +# | |
4024 | +# in this case, this prefix would be the charater \`\(\'. | |
4025 | +# | |
4026 | +# Please note that we use the indirection prefix also for register | |
4027 | +# displacement, e.g., \`4\(\%eax\)\' on x86. | |
4028 | +v:const char *:stap_register_indirection_prefix:::0:0::0:gdbarch->stap_register_indirection_prefix | |
4029 | + | |
4030 | +# Sufix used to mark a register indirection on the architecture's assembly. | |
4031 | +# For example, on x86 the register indirection is written as: | |
4032 | +# | |
4033 | +# \(\%eax\) ;; indirecting eax | |
4034 | +# | |
4035 | +# in this case, this prefix would be the charater \`\)\'. | |
4036 | +# | |
4037 | +# Please note that we use the indirection sufix also for register | |
4038 | +# displacement, e.g., \`4\(\%eax\)\' on x86. | |
4039 | +v:const char *:stap_register_indirection_sufix:::0:0::0:gdbarch->stap_register_indirection_sufix | |
4040 | + | |
4041 | +# Prefix used to name a register using GDB's nomenclature. | |
4042 | +# | |
4043 | +# For example, on PPC a register is represented by a number in the assembly | |
4044 | +# language (e.g., \`10\' is the 10th general-purpose register). However, | |
4045 | +# inside GDB this same register has an \`r\' appended to its name, so the 10th | |
4046 | +# register would be represented as \`r10\' internally. | |
4047 | +v:const char *:stap_gdb_register_prefix:::0:0::0:gdbarch->stap_gdb_register_prefix | |
4048 | + | |
4049 | +# Sufix used to name a register using GDB's nomenclature. | |
4050 | +v:const char *:stap_gdb_register_sufix:::0:0::0:gdbarch->stap_gdb_register_sufix | |
4051 | + | |
4052 | +# Check if S is a single operand. | |
4053 | +# | |
4054 | +# Single operands can be: | |
4055 | +# \- Literal integers, e.g. \`\$10\' on x86 | |
4056 | +# \- Register access, e.g. \`\%eax\' on x86 | |
4057 | +# \- Register indirection, e.g. \`\(\%eax\)\' on x86 | |
4058 | +# \- Register displacement, e.g. \`4\(\%eax\)\' on x86 | |
4059 | +# | |
4060 | +# This function should check for these patterns on the string | |
4061 | +# and return 1 if some were found, or zero otherwise. Please try to match | |
4062 | +# as much info as you can from the string, i.e., if you have to match | |
4063 | +# something like \`\(\%\', do not match just the \`\(\'. | |
4064 | +M:int:stap_is_single_operand:const char *s:s | |
4065 | + | |
4066 | +# Function used to handle a "special case" in the parser. | |
4067 | +# | |
4068 | +# A "special case" is considered to be an unknown token, i.e., a token | |
4069 | +# that the parser does not know how to parse. A good example of special | |
4070 | +# case would be ARM's register displacement syntax: | |
4071 | +# | |
4072 | +# [R0, #4] ;; displacing R0 by 4 | |
4073 | +# | |
4074 | +# Since the parser assumes that a register displacement is of the form: | |
4075 | +# | |
4076 | +# <number> <indirection_prefix> <register_name> <indirection_sufix> | |
4077 | +# | |
4078 | +# it means that it will not be able to recognize and parse this odd syntax. | |
4079 | +# Therefore, we should add a special case function that will handle this token. | |
4080 | +# | |
4081 | +# This function should generate the proper expression form of the expression | |
4082 | +# using GDB\'s internal expression mechanism (e.g., \`write_exp_elt_opcode\' | |
4083 | +# and so on). It should also return 1 if the parsing was successful, or zero | |
4084 | +# if the token was not recognized as a special token (in this case, returning | |
4085 | +# zero means that the special parser is deferring the parsing to the generic | |
4086 | +# parser), and should advance the buffer pointer (p->arg). | |
4087 | +M:int:stap_parse_special_token:struct stap_parse_info *p:p | |
4088 | + | |
4089 | + | |
4090 | # True if the list of shared libraries is one and only for all | |
4091 | # processes, as opposed to a list of shared libraries per inferior. | |
4092 | # This usually means that all processes, although may or may not share | |
4093 | @@ -954,6 +1049,7 @@ struct core_regset_section; | |
4094 | struct syscall; | |
4095 | struct agent_expr; | |
4096 | struct axs_value; | |
4097 | +struct stap_parse_info; | |
4098 | ||
4099 | /* The architecture associated with the connection to the target. | |
4100 | ||
4101 | diff --git a/gdb/gdbinit.in b/gdb/gdbinit.in | |
4102 | index ffb7f53..a2e7e94 100644 | |
4103 | --- a/gdb/gdbinit.in | |
4104 | +++ b/gdb/gdbinit.in | |
4105 | @@ -1,5 +1,15 @@ | |
4106 | echo Setting up the environment for debugging gdb.\n | |
4107 | ||
4108 | +# Set up the Python library and "require" command. | |
4109 | +python | |
4110 | +from os.path import abspath | |
4111 | +gdb.datadir = abspath ('@srcdir@/python/lib') | |
4112 | +gdb.pythonlibdir = gdb.datadir | |
4113 | +gdb.__path__ = [gdb.datadir + '/gdb'] | |
4114 | +sys.path.insert(0, gdb.datadir) | |
4115 | +end | |
4116 | +source @srcdir@/python/lib/gdb/__init__.py | |
4117 | + | |
4118 | set complaints 1 | |
4119 | ||
4120 | b internal_error | |
4121 | diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c | |
4122 | index b09c1ec..8e0256c 100644 | |
4123 | --- a/gdb/gdbtypes.c | |
4124 | +++ b/gdb/gdbtypes.c | |
4125 | @@ -37,6 +37,9 @@ | |
4126 | #include "gdb_assert.h" | |
4127 | #include "hashtab.h" | |
4128 | #include "exceptions.h" | |
4129 | +#include "observer.h" | |
4130 | +#include "dwarf2expr.h" | |
4131 | +#include "dwarf2loc.h" | |
4132 | ||
4133 | /* Initialize BADNESS constants. */ | |
4134 | ||
4135 | @@ -141,7 +144,16 @@ static void print_bit_vector (B_TYPE *, int); | |
4136 | static void print_arg_types (struct field *, int, int); | |
4137 | static void dump_fn_fieldlists (struct type *, int); | |
4138 | static void print_cplus_stuff (struct type *, int); | |
4139 | +static LONGEST type_length_get (struct type *type, struct type *target_type, | |
4140 | + int full_span); | |
4141 | ||
4142 | +#if 0 | |
4143 | +/* The hash table holding all discardable `struct type *' references. */ | |
4144 | +static htab_t type_discardable_table; | |
4145 | + | |
4146 | +/* Current type_discardable_check pass used for TYPE_DISCARDABLE_AGE. */ | |
4147 | +static int type_discardable_age_current; | |
4148 | +#endif | |
4149 | ||
4150 | /* Allocate a new OBJFILE-associated type structure and fill it | |
4151 | with some defaults. Space for the type structure is allocated | |
4152 | @@ -172,6 +184,43 @@ alloc_type (struct objfile *objfile) | |
4153 | return type; | |
4154 | } | |
4155 | ||
4156 | +#if 0 | |
6ed6bacf AM |
4157 | +/* Declare TYPE as discardable on next garbage collection by free_all_types. |
4158 | + You must call type_mark_used during each free_all_types to protect TYPE from | |
4159 | + being deallocated. */ | |
3a58abaf | 4160 | + |
6ed6bacf AM |
4161 | +static void |
4162 | +set_type_as_discardable (struct type *type) | |
51a5ef0f | 4163 | +{ |
6ed6bacf | 4164 | + void **slot; |
51a5ef0f | 4165 | + |
6ed6bacf | 4166 | + gdb_assert (!TYPE_DISCARDABLE (type)); |
51a5ef0f | 4167 | + |
6ed6bacf AM |
4168 | + TYPE_DISCARDABLE (type) = 1; |
4169 | + TYPE_DISCARDABLE_AGE (type) = type_discardable_age_current; | |
51a5ef0f | 4170 | + |
6ed6bacf AM |
4171 | + slot = htab_find_slot (type_discardable_table, type, INSERT); |
4172 | + gdb_assert (!*slot); | |
4173 | + *slot = type; | |
4174 | +} | |
4175 | +#endif | |
51a5ef0f | 4176 | + |
6ed6bacf AM |
4177 | +/* Allocate a new type like alloc_type but preserve for it the discardability |
4178 | + state of PARENT_TYPE. */ | |
51a5ef0f | 4179 | + |
6ed6bacf AM |
4180 | +static struct type * |
4181 | +alloc_type_as_parent (struct type *parent_type) | |
4182 | +{ | |
4183 | + struct type *new_type = alloc_type_copy (parent_type); | |
51a5ef0f | 4184 | + |
6ed6bacf AM |
4185 | +#if 0 |
4186 | + if (TYPE_DISCARDABLE (parent_type)) | |
4187 | + set_type_as_discardable (new_type); | |
4188 | +#endif | |
51a5ef0f | 4189 | + |
6ed6bacf AM |
4190 | + return new_type; |
4191 | +} | |
3a58abaf | 4192 | + |
6ed6bacf AM |
4193 | /* Allocate a new GDBARCH-associated type structure and fill it |
4194 | with some defaults. Space for the type structure is allocated | |
4195 | on the heap. */ | |
f412e1b4 | 4196 | @@ -297,7 +346,7 @@ make_pointer_type (struct type *type, struct type **typeptr) |
51a5ef0f | 4197 | |
6ed6bacf | 4198 | if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ |
3a58abaf | 4199 | { |
6ed6bacf AM |
4200 | - ntype = alloc_type_copy (type); |
4201 | + ntype = alloc_type_as_parent (type); | |
4202 | if (typeptr) | |
4203 | *typeptr = ntype; | |
4204 | } | |
f412e1b4 | 4205 | @@ -374,7 +423,7 @@ make_reference_type (struct type *type, struct type **typeptr) |
3a58abaf | 4206 | |
6ed6bacf AM |
4207 | if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ |
4208 | { | |
4209 | - ntype = alloc_type_copy (type); | |
4210 | + ntype = alloc_type_as_parent (type); | |
4211 | if (typeptr) | |
4212 | *typeptr = ntype; | |
3a58abaf | 4213 | } |
f412e1b4 | 4214 | @@ -747,6 +796,7 @@ create_range_type (struct type *result_type, struct type *index_type, |
6ed6bacf AM |
4215 | TYPE_ZALLOC (result_type, sizeof (struct range_bounds)); |
4216 | TYPE_LOW_BOUND (result_type) = low_bound; | |
4217 | TYPE_HIGH_BOUND (result_type) = high_bound; | |
4218 | + TYPE_BYTE_STRIDE (result_type) = 0; | |
3a58abaf | 4219 | |
6ed6bacf AM |
4220 | if (low_bound >= 0) |
4221 | TYPE_UNSIGNED (result_type) = 1; | |
f412e1b4 | 4222 | @@ -890,26 +940,31 @@ create_array_type (struct type *result_type, |
51a5ef0f | 4223 | |
6ed6bacf AM |
4224 | TYPE_CODE (result_type) = TYPE_CODE_ARRAY; |
4225 | TYPE_TARGET_TYPE (result_type) = element_type; | |
4226 | - if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) | |
4227 | - low_bound = high_bound = 0; | |
4228 | - CHECK_TYPEDEF (element_type); | |
4229 | - /* Be careful when setting the array length. Ada arrays can be | |
4230 | - empty arrays with the high_bound being smaller than the low_bound. | |
4231 | - In such cases, the array length should be zero. */ | |
4232 | - if (high_bound < low_bound) | |
4233 | - TYPE_LENGTH (result_type) = 0; | |
4234 | - else | |
4235 | - TYPE_LENGTH (result_type) = | |
4236 | - TYPE_LENGTH (element_type) * (high_bound - low_bound + 1); | |
4237 | TYPE_NFIELDS (result_type) = 1; | |
4238 | TYPE_FIELDS (result_type) = | |
4239 | (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field)); | |
4240 | TYPE_INDEX_TYPE (result_type) = range_type; | |
4241 | TYPE_VPTR_FIELDNO (result_type) = -1; | |
51a5ef0f | 4242 | |
6ed6bacf AM |
4243 | - /* TYPE_FLAG_TARGET_STUB will take care of zero length arrays. */ |
4244 | + /* DWARF blocks may depend on runtime information like | |
4245 | + DW_OP_PUSH_OBJECT_ADDRESS not being available during the | |
4246 | + CREATE_ARRAY_TYPE time. */ | |
4247 | + if (TYPE_RANGE_DATA (range_type)->low.kind != RANGE_BOUND_KIND_CONSTANT | |
4248 | + || TYPE_RANGE_DATA (range_type)->high.kind != RANGE_BOUND_KIND_CONSTANT | |
4249 | + || TYPE_DYNAMIC (element_type)) | |
4250 | + TYPE_LENGTH (result_type) = 0; | |
4251 | + else | |
51a5ef0f | 4252 | + { |
6ed6bacf AM |
4253 | + CHECK_TYPEDEF (element_type); |
4254 | + TYPE_LENGTH (result_type) = type_length_get (result_type, element_type, | |
4255 | + 0); | |
4256 | + } | |
4257 | if (TYPE_LENGTH (result_type) == 0) | |
4258 | - TYPE_TARGET_STUB (result_type) = 1; | |
4259 | + { | |
4260 | + /* The real size will be computed for specific instances by | |
4261 | + CHECK_TYPEDEF. */ | |
4262 | + TYPE_TARGET_STUB (result_type) = 1; | |
51a5ef0f | 4263 | + } |
51a5ef0f | 4264 | |
6ed6bacf AM |
4265 | return result_type; |
4266 | } | |
f412e1b4 | 4267 | @@ -1438,6 +1493,105 @@ stub_noname_complaint (void) |
6ed6bacf | 4268 | complaint (&symfile_complaints, _("stub type has NULL name")); |
51a5ef0f PS |
4269 | } |
4270 | ||
6ed6bacf | 4271 | +/* Calculate the memory length of array TYPE. |
51a5ef0f | 4272 | + |
6ed6bacf AM |
4273 | + TARGET_TYPE should be set to `check_typedef (TYPE_TARGET_TYPE (type))' as |
4274 | + a performance hint. Feel free to pass NULL. Set FULL_SPAN to return the | |
4275 | + size incl. the possible padding of the last element - it may differ from the | |
4276 | + cleared FULL_SPAN return value (the expected SIZEOF) for non-zero | |
4277 | + TYPE_BYTE_STRIDE values. */ | |
51a5ef0f | 4278 | + |
6ed6bacf AM |
4279 | +static LONGEST |
4280 | +type_length_get (struct type *type, struct type *target_type, int full_span) | |
51a5ef0f | 4281 | +{ |
6ed6bacf AM |
4282 | + struct type *range_type; |
4283 | + LONGEST byte_stride = 0; /* `= 0' for a false GCC warning. */ | |
4284 | + LONGEST count, element_size, retval; | |
51a5ef0f | 4285 | + |
6ed6bacf AM |
4286 | + if (TYPE_CODE (type) != TYPE_CODE_ARRAY |
4287 | + && TYPE_CODE (type) != TYPE_CODE_STRING) | |
4288 | + return TYPE_LENGTH (type); | |
3a58abaf | 4289 | + |
6ed6bacf AM |
4290 | + /* Avoid executing TYPE_HIGH_BOUND for invalid (unallocated/unassociated) |
4291 | + Fortran arrays. The allocated data will never be used so they can be | |
4292 | + zero-length. */ | |
4293 | + if (object_address_data_not_valid (type)) | |
4294 | + return 0; | |
51a5ef0f | 4295 | + |
6ed6bacf AM |
4296 | + range_type = TYPE_INDEX_TYPE (type); |
4297 | + if (TYPE_LOW_BOUND_UNDEFINED (range_type) | |
4298 | + || TYPE_HIGH_BOUND_UNDEFINED (range_type)) | |
4299 | + return 0; | |
4300 | + count = TYPE_HIGH_BOUND (range_type) - TYPE_LOW_BOUND (range_type) + 1; | |
4301 | + /* It may happen for wrong DWARF annotations returning garbage data. */ | |
4302 | + if (count < 0) | |
4303 | + warning (_("Range for type %s has invalid bounds %s..%s"), | |
f412e1b4 | 4304 | + TYPE_ERROR_NAME (type), plongest (TYPE_LOW_BOUND (range_type)), |
6ed6bacf AM |
4305 | + plongest (TYPE_HIGH_BOUND (range_type))); |
4306 | + /* The code below does not handle count == 0 right. */ | |
4307 | + if (count <= 0) | |
4308 | + return 0; | |
4309 | + if (full_span || count > 1) | |
4310 | + { | |
4311 | + /* We do not use TYPE_ARRAY_BYTE_STRIDE_VALUE (type) here as we want to | |
4312 | + force FULL_SPAN to 1. */ | |
4313 | + byte_stride = TYPE_BYTE_STRIDE (range_type); | |
4314 | + if (byte_stride == 0) | |
4315 | + { | |
4316 | + if (target_type == NULL) | |
4317 | + target_type = check_typedef (TYPE_TARGET_TYPE (type)); | |
4318 | + byte_stride = type_length_get (target_type, NULL, 1); | |
4319 | + } | |
4320 | + } | |
51a5ef0f | 4321 | + |
6ed6bacf AM |
4322 | + /* For now, we conservatively take the array length to be 0 if its length |
4323 | + exceeds UINT_MAX. The code below assumes that for x < 0, | |
4324 | + (ULONGEST) x == -x + ULONGEST_MAX + 1, which is technically not guaranteed | |
4325 | + by C, but is usually true (because it would be true if x were unsigned | |
4326 | + with its high-order bit on). It uses the fact that high_bound-low_bound is | |
4327 | + always representable in ULONGEST and that if high_bound-low_bound+1 | |
4328 | + overflows, it overflows to 0. We must change these tests if we decide to | |
4329 | + increase the representation of TYPE_LENGTH from unsigned int to ULONGEST. | |
4330 | + */ | |
51a5ef0f | 4331 | + |
6ed6bacf | 4332 | + if (full_span) |
51a5ef0f | 4333 | + { |
6ed6bacf AM |
4334 | + retval = count * byte_stride; |
4335 | + if (count == 0 || retval / count != byte_stride || retval > UINT_MAX) | |
4336 | + retval = 0; | |
4337 | + return retval; | |
51a5ef0f | 4338 | + } |
6ed6bacf AM |
4339 | + if (target_type == NULL) |
4340 | + target_type = check_typedef (TYPE_TARGET_TYPE (type)); | |
4341 | + element_size = type_length_get (target_type, NULL, 1); | |
4342 | + retval = (count - 1) * byte_stride + element_size; | |
4343 | + if (retval < element_size | |
4344 | + || (byte_stride != 0 | |
4345 | + && (retval - element_size) / byte_stride != count - 1) | |
4346 | + || retval > UINT_MAX) | |
4347 | + retval = 0; | |
4348 | + return retval; | |
51a5ef0f PS |
4349 | +} |
4350 | + | |
6ed6bacf AM |
4351 | +/* Prepare TYPE after being read in by the backend. Currently this function |
4352 | + only propagates the TYPE_DYNAMIC flag. */ | |
51a5ef0f | 4353 | + |
6ed6bacf AM |
4354 | +void |
4355 | +finalize_type (struct type *type) | |
51a5ef0f | 4356 | +{ |
6ed6bacf | 4357 | + int i; |
3a58abaf | 4358 | + |
6ed6bacf AM |
4359 | + for (i = 0; i < TYPE_NFIELDS (type); ++i) |
4360 | + if (TYPE_FIELD_TYPE (type, i) && TYPE_DYNAMIC (TYPE_FIELD_TYPE (type, i))) | |
4361 | + break; | |
51a5ef0f | 4362 | + |
6ed6bacf AM |
4363 | + /* FIXME: cplus_stuff is ignored here. */ |
4364 | + if (i < TYPE_NFIELDS (type) | |
4365 | + || (TYPE_VPTR_BASETYPE (type) && TYPE_DYNAMIC (TYPE_VPTR_BASETYPE (type))) | |
4366 | + || (TYPE_TARGET_TYPE (type) && TYPE_DYNAMIC (TYPE_TARGET_TYPE (type)))) | |
4367 | + TYPE_DYNAMIC (type) = 1; | |
51a5ef0f PS |
4368 | +} |
4369 | + | |
6ed6bacf AM |
4370 | /* Find the real type of TYPE. This function returns the real type, |
4371 | after removing all layers of typedefs, and completing opaque or stub | |
4372 | types. Completion changes the TYPE argument, but stripping of | |
f412e1b4 | 4373 | @@ -1604,52 +1758,37 @@ check_typedef (struct type *type) |
6ed6bacf AM |
4374 | } |
4375 | } | |
4376 | ||
4377 | - if (TYPE_TARGET_STUB (type)) | |
4378 | + /* copy_type_recursive automatically makes the resulting type containing only | |
4379 | + constant values expected by the callers of this function. */ | |
4380 | + if (TYPE_DYNAMIC (type)) | |
4381 | + { | |
4382 | + htab_t copied_types; | |
51a5ef0f | 4383 | + |
6ed6bacf AM |
4384 | + copied_types = create_copied_types_hash (NULL); |
4385 | + type = copy_type_recursive (type, copied_types); | |
4386 | + htab_delete (copied_types); | |
51a5ef0f | 4387 | + |
6ed6bacf AM |
4388 | + gdb_assert (TYPE_DYNAMIC (type) == 0); |
4389 | + /* Force TYPE_LENGTH (type) recalculation. */ | |
4390 | + TYPE_DYNAMIC (type) = 1; | |
51a5ef0f | 4391 | + } |
6ed6bacf AM |
4392 | + |
4393 | + if (TYPE_TARGET_STUB (type) || TYPE_DYNAMIC (type)) | |
4394 | { | |
4395 | - struct type *range_type; | |
4396 | struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type)); | |
4397 | ||
4398 | + if (TYPE_DYNAMIC (type)) | |
4399 | + TYPE_TARGET_TYPE (type) = target_type; | |
4400 | if (TYPE_STUB (target_type) || TYPE_TARGET_STUB (target_type)) | |
4401 | { | |
4402 | /* Nothing we can do. */ | |
4403 | } | |
4404 | else if (TYPE_CODE (type) == TYPE_CODE_ARRAY | |
4405 | - && TYPE_NFIELDS (type) == 1 | |
4406 | - && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type)) | |
4407 | - == TYPE_CODE_RANGE)) | |
4408 | + || TYPE_CODE (type) == TYPE_CODE_STRING) | |
4409 | { | |
4410 | /* Now recompute the length of the array type, based on its | |
4411 | - number of elements and the target type's length. | |
4412 | - Watch out for Ada null Ada arrays where the high bound | |
4413 | - is smaller than the low bound. */ | |
4414 | - const LONGEST low_bound = TYPE_LOW_BOUND (range_type); | |
4415 | - const LONGEST high_bound = TYPE_HIGH_BOUND (range_type); | |
4416 | - ULONGEST len; | |
4417 | - | |
4418 | - if (high_bound < low_bound) | |
4419 | - len = 0; | |
4420 | - else | |
4421 | - { | |
4422 | - /* For now, we conservatively take the array length to be 0 | |
4423 | - if its length exceeds UINT_MAX. The code below assumes | |
4424 | - that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1, | |
4425 | - which is technically not guaranteed by C, but is usually true | |
4426 | - (because it would be true if x were unsigned with its | |
4427 | - high-order bit on). It uses the fact that | |
4428 | - high_bound-low_bound is always representable in | |
4429 | - ULONGEST and that if high_bound-low_bound+1 overflows, | |
4430 | - it overflows to 0. We must change these tests if we | |
4431 | - decide to increase the representation of TYPE_LENGTH | |
4432 | - from unsigned int to ULONGEST. */ | |
4433 | - ULONGEST ulow = low_bound, uhigh = high_bound; | |
4434 | - ULONGEST tlen = TYPE_LENGTH (target_type); | |
4435 | - | |
4436 | - len = tlen * (uhigh - ulow + 1); | |
4437 | - if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh | |
4438 | - || len > UINT_MAX) | |
4439 | - len = 0; | |
4440 | - } | |
4441 | - TYPE_LENGTH (type) = len; | |
4442 | + number of elements and the target type's length. */ | |
4443 | + TYPE_LENGTH (type) = type_length_get (type, target_type, 0); | |
4444 | TYPE_TARGET_STUB (type) = 0; | |
4445 | } | |
4446 | else if (TYPE_CODE (type) == TYPE_CODE_RANGE) | |
f412e1b4 | 4447 | @@ -1657,6 +1796,7 @@ check_typedef (struct type *type) |
6ed6bacf AM |
4448 | TYPE_LENGTH (type) = TYPE_LENGTH (target_type); |
4449 | TYPE_TARGET_STUB (type) = 0; | |
4450 | } | |
4451 | + TYPE_DYNAMIC (type) = 0; | |
4452 | } | |
4453 | ||
4454 | type = make_qualified_type (type, instance_flags, NULL); | |
f412e1b4 | 4455 | @@ -3310,33 +3450,42 @@ type_pair_eq (const void *item_lhs, const void *item_rhs) |
3a58abaf AM |
4456 | } |
4457 | ||
6ed6bacf AM |
4458 | /* Allocate the hash table used by copy_type_recursive to walk |
4459 | - types without duplicates. We use OBJFILE's obstack, because | |
4460 | - OBJFILE is about to be deleted. */ | |
4461 | + types without duplicates. */ | |
4462 | ||
4463 | htab_t | |
4464 | create_copied_types_hash (struct objfile *objfile) | |
4465 | { | |
4466 | - return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq, | |
4467 | - NULL, &objfile->objfile_obstack, | |
4468 | - hashtab_obstack_allocate, | |
4469 | - dummy_obstack_deallocate); | |
4470 | + if (objfile == NULL) | |
51a5ef0f | 4471 | + { |
6ed6bacf AM |
4472 | + /* NULL OBJFILE is for TYPE_DYNAMIC types already contained in |
4473 | + OBJFILE_MALLOC memory, such as those from VALUE_HISTORY_CHAIN. Table | |
4474 | + element entries get allocated by xmalloc - so use xfree. */ | |
4475 | + return htab_create (1, type_pair_hash, type_pair_eq, xfree); | |
51a5ef0f | 4476 | + } |
6ed6bacf | 4477 | + else |
51a5ef0f | 4478 | + { |
6ed6bacf AM |
4479 | + /* Use OBJFILE's obstack, because OBJFILE is about to be deleted. Table |
4480 | + element entries get allocated by xmalloc - so use xfree. */ | |
4481 | + return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq, | |
4482 | + xfree, &objfile->objfile_obstack, | |
4483 | + hashtab_obstack_allocate, | |
4484 | + dummy_obstack_deallocate); | |
51a5ef0f | 4485 | + } |
6ed6bacf AM |
4486 | } |
4487 | ||
4488 | -/* Recursively copy (deep copy) TYPE, if it is associated with | |
4489 | - OBJFILE. Return a new type allocated using malloc, a saved type if | |
4490 | - we have already visited TYPE (using COPIED_TYPES), or TYPE if it is | |
4491 | - not associated with OBJFILE. */ | |
4492 | +/* A helper for copy_type_recursive. This does all the work. OBJFILE is used | |
4493 | + only for an assertion checking. */ | |
4494 | ||
4495 | -struct type * | |
4496 | -copy_type_recursive (struct objfile *objfile, | |
4497 | - struct type *type, | |
4498 | - htab_t copied_types) | |
4499 | +static struct type * | |
4500 | +copy_type_recursive_1 (struct objfile *objfile, | |
4501 | + struct type *type, | |
4502 | + htab_t copied_types) | |
4503 | { | |
4504 | struct type_pair *stored, pair; | |
4505 | void **slot; | |
4506 | struct type *new_type; | |
4507 | ||
4508 | - if (! TYPE_OBJFILE_OWNED (type)) | |
4509 | + if (! TYPE_OBJFILE_OWNED (type) && !TYPE_DYNAMIC (type)) | |
4510 | return type; | |
4511 | ||
4512 | /* This type shouldn't be pointing to any types in other objfiles; | |
f412e1b4 | 4513 | @@ -3351,9 +3500,10 @@ copy_type_recursive (struct objfile *objfile, |
6ed6bacf AM |
4514 | new_type = alloc_type_arch (get_type_arch (type)); |
4515 | ||
4516 | /* We must add the new type to the hash table immediately, in case | |
4517 | - we encounter this type again during a recursive call below. */ | |
4518 | - stored | |
4519 | - = obstack_alloc (&objfile->objfile_obstack, sizeof (struct type_pair)); | |
4520 | + we encounter this type again during a recursive call below. Memory could | |
4521 | + be allocated from OBJFILE in the case we will be removing OBJFILE, this | |
4522 | + optimization is missed and xfree is called for it from COPIED_TYPES. */ | |
4523 | + stored = xmalloc (sizeof (*stored)); | |
4524 | stored->old = type; | |
4525 | stored->new = new_type; | |
4526 | *slot = stored; | |
f412e1b4 | 4527 | @@ -3364,6 +3514,21 @@ copy_type_recursive (struct objfile *objfile, |
6ed6bacf AM |
4528 | TYPE_OBJFILE_OWNED (new_type) = 0; |
4529 | TYPE_OWNER (new_type).gdbarch = get_type_arch (type); | |
4530 | ||
4531 | +#if 0 | |
4532 | + /* TYPE_MAIN_TYPE memory copy above rewrote the TYPE_DISCARDABLE flag so we | |
4533 | + need to initialize it again. And even if TYPE was already discardable | |
4534 | + NEW_TYPE so far is not registered in TYPE_DISCARDABLE_TABLE. */ | |
4535 | + TYPE_DISCARDABLE (new_type) = 0; | |
4536 | + set_type_as_discardable (new_type); | |
4537 | +#endif | |
3a58abaf | 4538 | + |
6ed6bacf AM |
4539 | + /* Pre-clear the fields processed by delete_main_type. If DWARF block |
4540 | + evaluations below call error we would leave an unfreeable TYPE. */ | |
4541 | + TYPE_TARGET_TYPE (new_type) = NULL; | |
4542 | + TYPE_VPTR_BASETYPE (new_type) = NULL; | |
4543 | + TYPE_NFIELDS (new_type) = 0; | |
4544 | + TYPE_FIELDS (new_type) = NULL; | |
3a58abaf | 4545 | + |
6ed6bacf AM |
4546 | if (TYPE_NAME (type)) |
4547 | TYPE_NAME (new_type) = xstrdup (TYPE_NAME (type)); | |
4548 | if (TYPE_TAG_NAME (type)) | |
f412e1b4 | 4549 | @@ -3372,12 +3537,48 @@ copy_type_recursive (struct objfile *objfile, |
6ed6bacf AM |
4550 | TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type); |
4551 | TYPE_LENGTH (new_type) = TYPE_LENGTH (type); | |
4552 | ||
4553 | + if (TYPE_ALLOCATED (new_type)) | |
51a5ef0f | 4554 | + { |
6ed6bacf | 4555 | + gdb_assert (!TYPE_NOT_ALLOCATED (new_type)); |
3a58abaf | 4556 | + |
6ed6bacf AM |
4557 | + if (!dwarf_locexpr_baton_eval (TYPE_ALLOCATED (new_type))) |
4558 | + TYPE_NOT_ALLOCATED (new_type) = 1; | |
4559 | + TYPE_ALLOCATED (new_type) = NULL; | |
51a5ef0f | 4560 | + } |
3a58abaf | 4561 | + |
6ed6bacf | 4562 | + if (TYPE_ASSOCIATED (new_type)) |
51a5ef0f | 4563 | + { |
6ed6bacf AM |
4564 | + gdb_assert (!TYPE_NOT_ASSOCIATED (new_type)); |
4565 | + | |
4566 | + if (!dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (new_type))) | |
4567 | + TYPE_NOT_ASSOCIATED (new_type) = 1; | |
4568 | + TYPE_ASSOCIATED (new_type) = NULL; | |
51a5ef0f | 4569 | + } |
3a58abaf | 4570 | + |
6ed6bacf AM |
4571 | + if (!TYPE_DATA_LOCATION_IS_ADDR (new_type) |
4572 | + && TYPE_DATA_LOCATION_DWARF_BLOCK (new_type)) | |
51a5ef0f | 4573 | + { |
6ed6bacf AM |
4574 | + if (TYPE_NOT_ALLOCATED (new_type) |
4575 | + || TYPE_NOT_ASSOCIATED (new_type)) | |
4576 | + TYPE_DATA_LOCATION_DWARF_BLOCK (new_type) = NULL; | |
51a5ef0f PS |
4577 | + else |
4578 | + { | |
6ed6bacf AM |
4579 | + TYPE_DATA_LOCATION_IS_ADDR (new_type) = 1; |
4580 | + TYPE_DATA_LOCATION_ADDR (new_type) = dwarf_locexpr_baton_eval | |
4581 | + (TYPE_DATA_LOCATION_DWARF_BLOCK (new_type)); | |
51a5ef0f | 4582 | + } |
51a5ef0f | 4583 | + } |
51a5ef0f | 4584 | + |
6ed6bacf AM |
4585 | /* Copy the fields. */ |
4586 | if (TYPE_NFIELDS (type)) | |
4587 | { | |
4588 | int i, nfields; | |
4589 | ||
4590 | + /* TYPE_CODE_RANGE uses TYPE_RANGE_DATA of the union with TYPE_FIELDS. */ | |
4591 | + gdb_assert (TYPE_CODE (type) != TYPE_CODE_RANGE); | |
51a5ef0f | 4592 | + |
6ed6bacf AM |
4593 | nfields = TYPE_NFIELDS (type); |
4594 | + TYPE_NFIELDS (new_type) = nfields; | |
4595 | TYPE_FIELDS (new_type) = XCALLOC (nfields, struct field); | |
4596 | for (i = 0; i < nfields; i++) | |
4597 | { | |
f412e1b4 | 4598 | @@ -3386,8 +3587,8 @@ copy_type_recursive (struct objfile *objfile, |
6ed6bacf AM |
4599 | TYPE_FIELD_BITSIZE (new_type, i) = TYPE_FIELD_BITSIZE (type, i); |
4600 | if (TYPE_FIELD_TYPE (type, i)) | |
4601 | TYPE_FIELD_TYPE (new_type, i) | |
4602 | - = copy_type_recursive (objfile, TYPE_FIELD_TYPE (type, i), | |
4603 | - copied_types); | |
4604 | + = copy_type_recursive_1 (objfile, TYPE_FIELD_TYPE (type, i), | |
4605 | + copied_types); | |
4606 | if (TYPE_FIELD_NAME (type, i)) | |
4607 | TYPE_FIELD_NAME (new_type, i) = | |
4608 | xstrdup (TYPE_FIELD_NAME (type, i)); | |
f412e1b4 | 4609 | @@ -3414,24 +3615,184 @@ copy_type_recursive (struct objfile *objfile, |
6ed6bacf AM |
4610 | } |
4611 | } | |
4612 | ||
4613 | + /* Both FIELD_LOC_KIND_DWARF_BLOCK and TYPE_RANGE_HIGH_BOUND_IS_COUNT were | |
4614 | + possibly converted. */ | |
4615 | + TYPE_DYNAMIC (new_type) = 0; | |
51a5ef0f | 4616 | + |
6ed6bacf AM |
4617 | /* For range types, copy the bounds information. */ |
4618 | - if (TYPE_CODE (type) == TYPE_CODE_RANGE) | |
4619 | + if (TYPE_CODE (new_type) == TYPE_CODE_RANGE) | |
4620 | { | |
4621 | TYPE_RANGE_DATA (new_type) = xmalloc (sizeof (struct range_bounds)); | |
4622 | *TYPE_RANGE_DATA (new_type) = *TYPE_RANGE_DATA (type); | |
51a5ef0f | 4623 | + |
6ed6bacf AM |
4624 | + switch (TYPE_RANGE_DATA (new_type)->low.kind) |
4625 | + { | |
4626 | + case RANGE_BOUND_KIND_CONSTANT: | |
4627 | + break; | |
4628 | + case RANGE_BOUND_KIND_DWARF_BLOCK: | |
4629 | + /* `struct dwarf2_locexpr_baton' is too bound to its objfile so | |
4630 | + it is expected to be made constant by CHECK_TYPEDEF. | |
4631 | + TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE. | |
4632 | + */ | |
4633 | + if (TYPE_NOT_ALLOCATED (new_type) || TYPE_NOT_ASSOCIATED (new_type) | |
4634 | + || ! has_stack_frames ()) | |
4635 | + { | |
4636 | + /* We should set 1 for Fortran but how to find the language? */ | |
4637 | + TYPE_LOW_BOUND (new_type) = 0; | |
4638 | + TYPE_LOW_BOUND_UNDEFINED (new_type) = 1; | |
4639 | + } | |
4640 | + else | |
4641 | + { | |
4642 | + TYPE_LOW_BOUND (new_type) = dwarf_locexpr_baton_eval | |
4643 | + (TYPE_RANGE_DATA (new_type)->low.u.dwarf_block); | |
4644 | + if (TYPE_LOW_BOUND (new_type) >= 0) | |
4645 | + TYPE_UNSIGNED (new_type) = 1; | |
4646 | + } | |
4647 | + TYPE_RANGE_DATA (new_type)->low.kind = RANGE_BOUND_KIND_CONSTANT; | |
4648 | + break; | |
4649 | + case RANGE_BOUND_KIND_DWARF_LOCLIST: | |
4650 | + { | |
4651 | + CORE_ADDR addr; | |
51a5ef0f | 4652 | + |
6ed6bacf AM |
4653 | + /* `struct dwarf2_loclist_baton' is too bound to its objfile so |
4654 | + it is expected to be made constant by CHECK_TYPEDEF. | |
4655 | + TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE. | |
4656 | + */ | |
4657 | + if (! TYPE_NOT_ALLOCATED (new_type) | |
4658 | + && ! TYPE_NOT_ASSOCIATED (new_type) && has_stack_frames () | |
4659 | + && dwarf_loclist_baton_eval | |
4660 | + (TYPE_RANGE_DATA (new_type)->low.u.dwarf_loclist.loclist, | |
4661 | + TYPE_RANGE_DATA (new_type)->low.u.dwarf_loclist.type, &addr)) | |
4662 | + { | |
4663 | + TYPE_LOW_BOUND (new_type) = addr; | |
4664 | + if (TYPE_LOW_BOUND (new_type) >= 0) | |
4665 | + TYPE_UNSIGNED (new_type) = 1; | |
4666 | + } | |
4667 | + else | |
4668 | + { | |
4669 | + /* We should set 1 for Fortran but how to find the language? */ | |
4670 | + TYPE_LOW_BOUND (new_type) = 0; | |
4671 | + TYPE_LOW_BOUND_UNDEFINED (new_type) = 1; | |
4672 | + } | |
4673 | + TYPE_RANGE_DATA (new_type)->low.kind = RANGE_BOUND_KIND_CONSTANT; | |
4674 | + } | |
4675 | + break; | |
4676 | + } | |
51a5ef0f | 4677 | + |
6ed6bacf AM |
4678 | + switch (TYPE_RANGE_DATA (new_type)->high.kind) |
4679 | + { | |
4680 | + case RANGE_BOUND_KIND_CONSTANT: | |
4681 | + break; | |
4682 | + case RANGE_BOUND_KIND_DWARF_BLOCK: | |
4683 | + /* `struct dwarf2_locexpr_baton' is too bound to its objfile so | |
4684 | + it is expected to be made constant by CHECK_TYPEDEF. | |
4685 | + TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE. | |
4686 | + */ | |
4687 | + if (TYPE_NOT_ALLOCATED (new_type) || TYPE_NOT_ASSOCIATED (new_type) | |
4688 | + || ! has_stack_frames ()) | |
4689 | + { | |
4690 | + TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (new_type) - 1; | |
4691 | + TYPE_HIGH_BOUND_UNDEFINED (new_type) = 1; | |
4692 | + } | |
4693 | + else | |
4694 | + TYPE_HIGH_BOUND (new_type) = dwarf_locexpr_baton_eval | |
4695 | + (TYPE_RANGE_DATA (new_type)->high.u.dwarf_block); | |
4696 | + TYPE_RANGE_DATA (new_type)->high.kind = RANGE_BOUND_KIND_CONSTANT; | |
4697 | + break; | |
4698 | + case RANGE_BOUND_KIND_DWARF_LOCLIST: | |
4699 | + { | |
4700 | + CORE_ADDR addr; | |
51a5ef0f | 4701 | + |
6ed6bacf AM |
4702 | + /* `struct dwarf2_loclist_baton' is too bound to its objfile so |
4703 | + it is expected to be made constant by CHECK_TYPEDEF. | |
4704 | + TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE. | |
4705 | + */ | |
4706 | + if (! TYPE_NOT_ALLOCATED (new_type) | |
4707 | + && ! TYPE_NOT_ASSOCIATED (new_type) && has_stack_frames () | |
4708 | + && dwarf_loclist_baton_eval | |
4709 | + (TYPE_RANGE_DATA (new_type)->high.u.dwarf_loclist.loclist, | |
4710 | + TYPE_RANGE_DATA (new_type)->high.u.dwarf_loclist.type, | |
4711 | + &addr)) | |
4712 | + TYPE_HIGH_BOUND (new_type) = addr; | |
4713 | + else | |
4714 | + { | |
4715 | + TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (new_type) - 1; | |
4716 | + TYPE_HIGH_BOUND_UNDEFINED (new_type) = 1; | |
4717 | + } | |
4718 | + TYPE_RANGE_DATA (new_type)->high.kind = RANGE_BOUND_KIND_CONSTANT; | |
4719 | + } | |
4720 | + break; | |
4721 | + } | |
51a5ef0f | 4722 | + |
6ed6bacf AM |
4723 | + switch (TYPE_RANGE_DATA (new_type)->byte_stride.kind) |
4724 | + { | |
4725 | + case RANGE_BOUND_KIND_CONSTANT: | |
4726 | + break; | |
4727 | + case RANGE_BOUND_KIND_DWARF_BLOCK: | |
4728 | + /* `struct dwarf2_locexpr_baton' is too bound to its objfile so | |
4729 | + it is expected to be made constant by CHECK_TYPEDEF. | |
4730 | + TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE. | |
4731 | + */ | |
4732 | + if (TYPE_NOT_ALLOCATED (new_type) || TYPE_NOT_ASSOCIATED (new_type) | |
4733 | + || ! has_stack_frames ()) | |
4734 | + TYPE_BYTE_STRIDE (new_type) = 0; | |
4735 | + else | |
4736 | + TYPE_BYTE_STRIDE (new_type) = dwarf_locexpr_baton_eval | |
4737 | + (TYPE_RANGE_DATA (new_type)->byte_stride.u.dwarf_block); | |
4738 | + TYPE_RANGE_DATA (new_type)->byte_stride.kind | |
4739 | + = RANGE_BOUND_KIND_CONSTANT; | |
4740 | + break; | |
4741 | + case RANGE_BOUND_KIND_DWARF_LOCLIST: | |
4742 | + { | |
4743 | + CORE_ADDR addr = 0; | |
51a5ef0f | 4744 | + |
6ed6bacf AM |
4745 | + /* `struct dwarf2_loclist_baton' is too bound to its objfile so |
4746 | + it is expected to be made constant by CHECK_TYPEDEF. | |
4747 | + TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE. | |
4748 | + */ | |
4749 | + if (! TYPE_NOT_ALLOCATED (new_type) | |
4750 | + && ! TYPE_NOT_ASSOCIATED (new_type) && has_stack_frames ()) | |
4751 | + dwarf_loclist_baton_eval | |
4752 | + (TYPE_RANGE_DATA (new_type)->byte_stride.u.dwarf_loclist.loclist, | |
4753 | + TYPE_RANGE_DATA (new_type)->byte_stride.u.dwarf_loclist.type, | |
4754 | + &addr); | |
4755 | + TYPE_BYTE_STRIDE (new_type) = addr; | |
4756 | + TYPE_RANGE_DATA (new_type)->byte_stride.kind | |
4757 | + = RANGE_BOUND_KIND_CONSTANT; | |
4758 | + } | |
4759 | + break; | |
4760 | + } | |
51a5ef0f | 4761 | + |
6ed6bacf AM |
4762 | + /* Convert TYPE_RANGE_HIGH_BOUND_IS_COUNT into a regular bound. */ |
4763 | + if (TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type)) | |
4764 | + { | |
4765 | + TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (new_type) | |
4766 | + + TYPE_HIGH_BOUND (new_type) - 1; | |
4767 | + TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type) = 0; | |
4768 | + } | |
4769 | } | |
4770 | ||
4771 | /* Copy pointers to other types. */ | |
4772 | if (TYPE_TARGET_TYPE (type)) | |
4773 | TYPE_TARGET_TYPE (new_type) = | |
4774 | - copy_type_recursive (objfile, | |
4775 | - TYPE_TARGET_TYPE (type), | |
4776 | - copied_types); | |
4777 | + copy_type_recursive_1 (objfile, | |
4778 | + TYPE_TARGET_TYPE (type), | |
4779 | + copied_types); | |
4780 | if (TYPE_VPTR_BASETYPE (type)) | |
4781 | TYPE_VPTR_BASETYPE (new_type) = | |
4782 | - copy_type_recursive (objfile, | |
4783 | - TYPE_VPTR_BASETYPE (type), | |
4784 | - copied_types); | |
4785 | + copy_type_recursive_1 (objfile, | |
4786 | + TYPE_VPTR_BASETYPE (type), | |
4787 | + copied_types); | |
51a5ef0f | 4788 | + |
6ed6bacf | 4789 | + if (TYPE_CODE (new_type) == TYPE_CODE_ARRAY) |
51a5ef0f | 4790 | + { |
6ed6bacf AM |
4791 | + struct type *new_index_type = TYPE_INDEX_TYPE (new_type); |
4792 | + | |
4793 | + if (TYPE_BYTE_STRIDE (new_index_type) == 0) | |
4794 | + TYPE_BYTE_STRIDE (new_index_type) | |
4795 | + = TYPE_LENGTH (TYPE_TARGET_TYPE (new_type)); | |
51a5ef0f PS |
4796 | + } |
4797 | + | |
6ed6bacf AM |
4798 | /* Maybe copy the type_specific bits. |
4799 | ||
4800 | NOTE drow/2005-12-09: We do not copy the C++-specific bits like | |
f412e1b4 | 4801 | @@ -3448,6 +3809,17 @@ copy_type_recursive (struct objfile *objfile, |
6ed6bacf AM |
4802 | return new_type; |
4803 | } | |
4804 | ||
4805 | +/* Recursively copy (deep copy) TYPE. Return a new type allocated using | |
4806 | + malloc, a saved type if we have already visited TYPE (using COPIED_TYPES), | |
4807 | + or TYPE if it is not associated with OBJFILE. */ | |
4808 | + | |
4809 | +struct type * | |
4810 | +copy_type_recursive (struct type *type, | |
4811 | + htab_t copied_types) | |
4812 | +{ | |
4813 | + return copy_type_recursive_1 (TYPE_OBJFILE (type), type, copied_types); | |
4814 | +} | |
4815 | + | |
4816 | /* Make a copy of the given TYPE, except that the pointer & reference | |
4817 | types are not preserved. | |
4818 | ||
f412e1b4 | 4819 | @@ -3470,6 +3842,201 @@ copy_type (const struct type *type) |
6ed6bacf AM |
4820 | return new_type; |
4821 | } | |
4822 | ||
4823 | +#if 0 | |
4824 | +/* Callback type for main_type_crawl. */ | |
4825 | +typedef int (*main_type_crawl_iter) (struct type *type, void *data); | |
51a5ef0f | 4826 | + |
6ed6bacf AM |
4827 | +/* Iterate all main_type structures reachable through any `struct type *' from |
4828 | + TYPE. ITER will be called only for one type of each main_type, use | |
4829 | + TYPE_CHAIN traversal to find all the type instances. ITER is being called | |
4830 | + for each main_type found. ITER returns non-zero if main_type_crawl should | |
4831 | + depth-first enter the specific type. ITER must provide some detection for | |
4832 | + reentering the same main_type as this function would otherwise endlessly | |
4833 | + loop. */ | |
51a5ef0f | 4834 | + |
6ed6bacf AM |
4835 | +static void |
4836 | +main_type_crawl (struct type *type, main_type_crawl_iter iter, void *data) | |
4837 | +{ | |
4838 | + struct type *type_iter; | |
4839 | + int i; | |
51a5ef0f | 4840 | + |
6ed6bacf AM |
4841 | + if (!type) |
4842 | + return; | |
51a5ef0f | 4843 | + |
6ed6bacf | 4844 | + gdb_assert (TYPE_OBJFILE (type) == NULL); |
51a5ef0f | 4845 | + |
6ed6bacf AM |
4846 | + /* `struct cplus_struct_type' handling is unsupported by this function. */ |
4847 | + gdb_assert ((TYPE_CODE (type) != TYPE_CODE_STRUCT | |
4848 | + && TYPE_CODE (type) != TYPE_CODE_UNION) | |
4849 | + || !HAVE_CPLUS_STRUCT (type)); | |
51a5ef0f | 4850 | + |
6ed6bacf AM |
4851 | + if (!(*iter) (type, data)) |
4852 | + return; | |
51a5ef0f | 4853 | + |
6ed6bacf AM |
4854 | + /* Iterate all the type instances of this main_type. */ |
4855 | + type_iter = type; | |
4856 | + do | |
4857 | + { | |
4858 | + gdb_assert (TYPE_MAIN_TYPE (type_iter) == TYPE_MAIN_TYPE (type)); | |
51a5ef0f | 4859 | + |
6ed6bacf AM |
4860 | + main_type_crawl (TYPE_POINTER_TYPE (type), iter, data); |
4861 | + main_type_crawl (TYPE_REFERENCE_TYPE (type), iter, data); | |
51a5ef0f | 4862 | + |
6ed6bacf AM |
4863 | + type_iter = TYPE_CHAIN (type_iter); |
4864 | + } | |
4865 | + while (type_iter != type); | |
51a5ef0f | 4866 | + |
6ed6bacf AM |
4867 | + for (i = 0; i < TYPE_NFIELDS (type); i++) |
4868 | + main_type_crawl (TYPE_FIELD_TYPE (type, i), iter, data); | |
51a5ef0f | 4869 | + |
6ed6bacf AM |
4870 | + main_type_crawl (TYPE_TARGET_TYPE (type), iter, data); |
4871 | + main_type_crawl (TYPE_VPTR_BASETYPE (type), iter, data); | |
51a5ef0f PS |
4872 | +} |
4873 | + | |
6ed6bacf AM |
4874 | +/* A helper for delete_type which deletes a main_type and the things to which |
4875 | + it refers. TYPE is a type whose main_type we wish to destroy. */ | |
4876 | + | |
51a5ef0f | 4877 | +static void |
6ed6bacf | 4878 | +delete_main_type (struct type *type) |
51a5ef0f | 4879 | +{ |
6ed6bacf | 4880 | + int i; |
51a5ef0f | 4881 | + |
6ed6bacf AM |
4882 | + gdb_assert (TYPE_DISCARDABLE (type)); |
4883 | + gdb_assert (TYPE_OBJFILE (type) == NULL); | |
51a5ef0f | 4884 | + |
6ed6bacf AM |
4885 | + xfree (TYPE_NAME (type)); |
4886 | + xfree (TYPE_TAG_NAME (type)); | |
51a5ef0f | 4887 | + |
6ed6bacf AM |
4888 | + for (i = 0; i < TYPE_NFIELDS (type); ++i) |
4889 | + { | |
4890 | + xfree (TYPE_FIELD_NAME (type, i)); | |
51a5ef0f | 4891 | + |
6ed6bacf AM |
4892 | + if (TYPE_FIELD_LOC_KIND (type, i) == FIELD_LOC_KIND_PHYSNAME) |
4893 | + xfree (TYPE_FIELD_STATIC_PHYSNAME (type, i)); | |
4894 | + } | |
4895 | + xfree (TYPE_FIELDS (type)); | |
51a5ef0f | 4896 | + |
6ed6bacf | 4897 | + gdb_assert (!HAVE_CPLUS_STRUCT (type)); |
51a5ef0f | 4898 | + |
6ed6bacf AM |
4899 | + xfree (TYPE_MAIN_TYPE (type)); |
4900 | +} | |
51a5ef0f | 4901 | + |
6ed6bacf AM |
4902 | +/* Delete all the instances on TYPE_CHAIN of TYPE, including their referenced |
4903 | + main_type. TYPE must be a reclaimable type - neither permanent nor objfile | |
4904 | + associated. */ | |
51a5ef0f PS |
4905 | + |
4906 | +static void | |
6ed6bacf AM |
4907 | +delete_type_chain (struct type *type) |
4908 | +{ | |
4909 | + struct type *type_iter, *type_iter_to_free; | |
51a5ef0f | 4910 | + |
6ed6bacf AM |
4911 | + gdb_assert (TYPE_DISCARDABLE (type)); |
4912 | + gdb_assert (TYPE_OBJFILE (type) == NULL); | |
51a5ef0f | 4913 | + |
6ed6bacf | 4914 | + delete_main_type (type); |
51a5ef0f | 4915 | + |
6ed6bacf AM |
4916 | + type_iter = type; |
4917 | + do | |
4918 | + { | |
4919 | + type_iter_to_free = type_iter; | |
4920 | + type_iter = TYPE_CHAIN (type_iter); | |
4921 | + xfree (type_iter_to_free); | |
4922 | + } | |
4923 | + while (type_iter != type); | |
4924 | +} | |
51a5ef0f | 4925 | + |
6ed6bacf | 4926 | +/* Hash function for type_discardable_table. */ |
51a5ef0f | 4927 | + |
6ed6bacf AM |
4928 | +static hashval_t |
4929 | +type_discardable_hash (const void *p) | |
4930 | +{ | |
4931 | + const struct type *type = p; | |
51a5ef0f | 4932 | + |
6ed6bacf AM |
4933 | + return htab_hash_pointer (TYPE_MAIN_TYPE (type)); |
4934 | +} | |
51a5ef0f | 4935 | + |
6ed6bacf | 4936 | +/* Equality function for type_discardable_table. */ |
51a5ef0f | 4937 | + |
6ed6bacf AM |
4938 | +static int |
4939 | +type_discardable_equal (const void *a, const void *b) | |
4940 | +{ | |
4941 | + const struct type *left = a; | |
4942 | + const struct type *right = b; | |
7566401a | 4943 | + |
6ed6bacf | 4944 | + return TYPE_MAIN_TYPE (left) == TYPE_MAIN_TYPE (right); |
51a5ef0f | 4945 | +} |
7566401a | 4946 | + |
6ed6bacf | 4947 | +/* A helper for type_mark_used. */ |
51a5ef0f | 4948 | + |
6ed6bacf AM |
4949 | +static int |
4950 | +type_mark_used_crawl (struct type *type, void *unused) | |
7566401a | 4951 | +{ |
6ed6bacf AM |
4952 | + if (!TYPE_DISCARDABLE (type)) |
4953 | + return 0; | |
51a5ef0f | 4954 | + |
6ed6bacf | 4955 | + if (TYPE_DISCARDABLE_AGE (type) == type_discardable_age_current) |
51a5ef0f | 4956 | + return 0; |
7566401a | 4957 | + |
6ed6bacf AM |
4958 | + TYPE_DISCARDABLE_AGE (type) = type_discardable_age_current; |
4959 | + | |
4960 | + /* Continue the traversal. */ | |
4961 | + return 1; | |
51a5ef0f PS |
4962 | +} |
4963 | + | |
6ed6bacf | 4964 | +/* Mark TYPE and its connected types as used in this free_all_types pass. */ |
51a5ef0f PS |
4965 | + |
4966 | +void | |
6ed6bacf | 4967 | +type_mark_used (struct type *type) |
51a5ef0f | 4968 | +{ |
6ed6bacf AM |
4969 | + if (type == NULL) |
4970 | + return; | |
51a5ef0f | 4971 | + |
6ed6bacf AM |
4972 | + if (!TYPE_DISCARDABLE (type)) |
4973 | + return; | |
4974 | + | |
4975 | + main_type_crawl (type, type_mark_used_crawl, NULL); | |
51a5ef0f PS |
4976 | +} |
4977 | + | |
6ed6bacf AM |
4978 | +/* A traverse callback for type_discardable_table which removes any |
4979 | + type_discardable whose reference count is now zero (unused link). */ | |
4980 | + | |
4981 | +static int | |
4982 | +type_discardable_remove (void **slot, void *unused) | |
51a5ef0f | 4983 | +{ |
6ed6bacf | 4984 | + struct type *type = *slot; |
51a5ef0f | 4985 | + |
6ed6bacf | 4986 | + gdb_assert (TYPE_DISCARDABLE (type)); |
51a5ef0f | 4987 | + |
6ed6bacf | 4988 | + if (TYPE_DISCARDABLE_AGE (type) != type_discardable_age_current) |
51a5ef0f | 4989 | + { |
6ed6bacf | 4990 | + delete_type_chain (type); |
3a58abaf | 4991 | + |
6ed6bacf | 4992 | + htab_clear_slot (type_discardable_table, slot); |
7566401a ER |
4993 | + } |
4994 | + | |
6ed6bacf | 4995 | + return 1; |
7566401a ER |
4996 | +} |
4997 | + | |
6ed6bacf AM |
4998 | +/* Free all the reclaimable types that have been allocated and that have |
4999 | + currently zero reference counter. | |
3a58abaf | 5000 | + |
6ed6bacf AM |
5001 | + This function is called after each command, successful or not. Use this |
5002 | + cleanup only in the GDB idle state as GDB only marks those types used by | |
5003 | + globally tracked objects (with no autovariable references tracking). */ | |
3a58abaf | 5004 | + |
6ed6bacf AM |
5005 | +void |
5006 | +free_all_types (void) | |
3a58abaf | 5007 | +{ |
6ed6bacf AM |
5008 | + /* Mark a new pass. As GDB checks all the entries were visited after each |
5009 | + pass there cannot be any stale entries already containing the changed | |
5010 | + value. */ | |
5011 | + type_discardable_age_current ^= 1; | |
51a5ef0f | 5012 | + |
6ed6bacf | 5013 | + observer_notify_mark_used (); |
51a5ef0f | 5014 | + |
6ed6bacf | 5015 | + htab_traverse (type_discardable_table, type_discardable_remove, NULL); |
3a58abaf | 5016 | +} |
6ed6bacf | 5017 | +#endif |
3a58abaf | 5018 | |
6ed6bacf | 5019 | /* Helper functions to initialize architecture-specific types. */ |
3a58abaf | 5020 | |
f412e1b4 | 5021 | @@ -4002,6 +4569,13 @@ void |
6ed6bacf AM |
5022 | _initialize_gdbtypes (void) |
5023 | { | |
5024 | gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init); | |
3a58abaf | 5025 | + |
6ed6bacf AM |
5026 | +#if 0 |
5027 | + type_discardable_table = htab_create_alloc (20, type_discardable_hash, | |
5028 | + type_discardable_equal, NULL, | |
5029 | + xcalloc, xfree); | |
5030 | +#endif | |
3a58abaf | 5031 | + |
6ed6bacf | 5032 | objfile_type_data = register_objfile_data (); |
3a58abaf | 5033 | |
6ed6bacf | 5034 | add_setshow_zinteger_cmd ("overload", no_class, &overload_debug, |
f412e1b4 PS |
5035 | diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h |
5036 | index 2070f00..40db606 100644 | |
5037 | --- a/gdb/gdbtypes.h | |
5038 | +++ b/gdb/gdbtypes.h | |
5039 | @@ -213,6 +213,11 @@ enum type_instance_flag_value | |
51a5ef0f | 5040 | |
6ed6bacf | 5041 | #define TYPE_TARGET_STUB(t) (TYPE_MAIN_TYPE (t)->flag_target_stub) |
51a5ef0f | 5042 | |
6ed6bacf AM |
5043 | +/* Type needs to be evaluated on each CHECK_TYPEDEF and its results must not be |
5044 | + sticky. */ | |
51a5ef0f | 5045 | + |
6ed6bacf | 5046 | +#define TYPE_DYNAMIC(t) (TYPE_MAIN_TYPE (t)->flag_dynamic) |
51a5ef0f | 5047 | + |
6ed6bacf AM |
5048 | /* Static type. If this is set, the corresponding type had |
5049 | a static modifier. | |
5050 | Note: This may be unnecessary, since static data members | |
f412e1b4 | 5051 | @@ -296,6 +301,50 @@ enum type_instance_flag_value |
51a5ef0f | 5052 | |
f412e1b4 | 5053 | #define TYPE_FLAG_ENUM(t) (TYPE_MAIN_TYPE (t)->flag_flag_enum) |
51a5ef0f | 5054 | |
6ed6bacf AM |
5055 | +#if 0 |
5056 | +/* Define this type as being reclaimable during free_all_types. Type is | |
5057 | + required to be have TYPE_OBJFILE set to NULL. Setting this flag requires | |
5058 | + initializing TYPE_DISCARDABLE_AGE, see alloc_type_discardable. */ | |
51a5ef0f | 5059 | + |
6ed6bacf | 5060 | +#define TYPE_DISCARDABLE(t) (TYPE_MAIN_TYPE (t)->flag_discardable) |
51a5ef0f | 5061 | + |
6ed6bacf AM |
5062 | +/* Marker this type has been visited by the type_mark_used by this |
5063 | + mark-and-sweep types garbage collecting pass. Current pass is represented | |
5064 | + by TYPE_DISCARDABLE_AGE_CURRENT. */ | |
5065 | + | |
5066 | +#define TYPE_DISCARDABLE_AGE(t) (TYPE_MAIN_TYPE (t)->flag_discardable_age) | |
5067 | +#endif | |
5068 | + | |
5069 | +/* Is HIGH_BOUND a low-bound relative count (1) or the high bound itself (0)? */ | |
5070 | + | |
5071 | +#define TYPE_RANGE_HIGH_BOUND_IS_COUNT(range_type) \ | |
5072 | + (TYPE_MAIN_TYPE (range_type)->flag_range_high_bound_is_count) | |
5073 | + | |
5074 | +/* Not allocated. TYPE_ALLOCATED(t) must be NULL in such case. If this flag | |
5075 | + is unset and TYPE_ALLOCATED(t) is NULL then the type is allocated. If this | |
5076 | + flag is unset and TYPE_ALLOCATED(t) is not NULL then its DWARF block | |
5077 | + determines the actual allocation state. */ | |
5078 | + | |
5079 | +#define TYPE_NOT_ALLOCATED(t) (TYPE_MAIN_TYPE (t)->flag_not_allocated) | |
5080 | + | |
5081 | +/* Not associated. TYPE_ASSOCIATED(t) must be NULL in such case. If this flag | |
5082 | + is unset and TYPE_ASSOCIATED(t) is NULL then the type is associated. If | |
5083 | + this flag is unset and TYPE_ASSOCIATED(t) is not NULL then its DWARF block | |
5084 | + determines the actual association state. */ | |
5085 | + | |
5086 | +#define TYPE_NOT_ASSOCIATED(t) (TYPE_MAIN_TYPE (t)->flag_not_associated) | |
5087 | + | |
5088 | +/* Address of the actual data as for DW_AT_data_location. Its dwarf block must | |
5089 | + not be evaluated unless both TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are | |
5090 | + false. If TYPE_DATA_LOCATION_IS_ADDR set then TYPE_DATA_LOCATION_ADDR value | |
5091 | + is the actual data address value. If unset and | |
5092 | + TYPE_DATA_LOCATION_DWARF_BLOCK is NULL then the value is the normal | |
5093 | + value_raw_address. If unset and TYPE_DATA_LOCATION_DWARF_BLOCK is not NULL | |
5094 | + then its DWARF block determines the actual data address. */ | |
5095 | + | |
5096 | +#define TYPE_DATA_LOCATION_IS_ADDR(t) \ | |
5097 | + (TYPE_MAIN_TYPE (t)->flag_data_location_is_addr) | |
5098 | + | |
5099 | /* Constant type. If this is set, the corresponding type has a | |
5100 | const modifier. */ | |
51a5ef0f | 5101 | |
f412e1b4 | 5102 | @@ -405,6 +454,15 @@ struct main_type |
6ed6bacf AM |
5103 | /* True if this type was declared with "class" rather than |
5104 | "struct". */ | |
5105 | unsigned int flag_declared_class : 1; | |
5106 | +#if 0 | |
5107 | + unsigned int flag_discardable : 1; | |
5108 | + unsigned int flag_discardable_age : 1; | |
5109 | +#endif | |
5110 | + unsigned int flag_dynamic : 1; | |
5111 | + unsigned int flag_range_high_bound_is_count : 1; | |
5112 | + unsigned int flag_not_allocated : 1; | |
5113 | + unsigned int flag_not_associated : 1; | |
5114 | + unsigned int flag_data_location_is_addr : 1; | |
5115 | ||
f412e1b4 PS |
5116 | /* True if this is an enum type with disjoint values. This affects |
5117 | how the enum is printed. */ | |
5118 | @@ -483,6 +541,20 @@ struct main_type | |
6ed6bacf AM |
5119 | |
5120 | struct type *target_type; | |
5121 | ||
5122 | + /* For DW_AT_data_location. */ | |
5123 | + union | |
5124 | + { | |
5125 | + struct dwarf2_locexpr_baton *dwarf_block; | |
5126 | + CORE_ADDR addr; | |
5127 | + } | |
5128 | + data_location; | |
5129 | + | |
5130 | + /* For DW_AT_allocated. */ | |
5131 | + struct dwarf2_locexpr_baton *allocated; | |
5132 | + | |
5133 | + /* For DW_AT_associated. */ | |
5134 | + struct dwarf2_locexpr_baton *associated; | |
5135 | + | |
5136 | /* For structure and union types, a description of each field. | |
5137 | For set and pascal array types, there is one "field", | |
5138 | whose type is the domain type of the set or array. | |
f412e1b4 | 5139 | @@ -563,13 +635,34 @@ struct main_type |
6ed6bacf AM |
5140 | |
5141 | struct range_bounds | |
5142 | { | |
5143 | + struct | |
51a5ef0f | 5144 | + { |
6ed6bacf | 5145 | + union |
51a5ef0f | 5146 | + { |
6ed6bacf AM |
5147 | + LONGEST constant; |
5148 | + struct dwarf2_locexpr_baton *dwarf_block; | |
5149 | + struct | |
5150 | + { | |
5151 | + struct dwarf2_loclist_baton *loclist; | |
5152 | + struct type *type; | |
5153 | + } | |
5154 | + dwarf_loclist; | |
51a5ef0f | 5155 | + } |
6ed6bacf AM |
5156 | + u; |
5157 | + enum range_bound_kind | |
51a5ef0f | 5158 | + { |
6ed6bacf AM |
5159 | + RANGE_BOUND_KIND_CONSTANT, |
5160 | + RANGE_BOUND_KIND_DWARF_BLOCK, | |
5161 | + RANGE_BOUND_KIND_DWARF_LOCLIST | |
51a5ef0f | 5162 | + } |
6ed6bacf | 5163 | + kind; |
51a5ef0f | 5164 | + } |
6ed6bacf AM |
5165 | /* Low bound of range. */ |
5166 | - | |
5167 | - LONGEST low; | |
5168 | - | |
5169 | + low, | |
5170 | /* High bound of range. */ | |
5171 | - | |
5172 | - LONGEST high; | |
5173 | + high, | |
5174 | + /* Byte stride of range. */ | |
5175 | + byte_stride; | |
51a5ef0f | 5176 | |
6ed6bacf AM |
5177 | /* Flags indicating whether the values of low and high are |
5178 | valid. When true, the respective range value is | |
f412e1b4 | 5179 | @@ -1016,9 +1109,9 @@ extern void allocate_gnat_aux_type (struct type *); |
6ed6bacf AM |
5180 | #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type |
5181 | #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type | |
5182 | #define TYPE_CHAIN(thistype) (thistype)->chain | |
5183 | -/* Note that if thistype is a TYPEDEF type, you have to call check_typedef. | |
5184 | - But check_typedef does set the TYPE_LENGTH of the TYPEDEF type, | |
5185 | - so you only have to call check_typedef once. Since allocate_value | |
5186 | +/* Note that if thistype is a TYPEDEF, ARRAY or STRING type, you have to call | |
5187 | + check_typedef. But check_typedef does set the TYPE_LENGTH of the TYPEDEF | |
5188 | + type, so you only have to call check_typedef once. Since allocate_value | |
5189 | calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe. */ | |
5190 | #define TYPE_LENGTH(thistype) (thistype)->length | |
5191 | /* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real | |
f412e1b4 | 5192 | @@ -1026,11 +1119,16 @@ extern void allocate_gnat_aux_type (struct type *); |
6ed6bacf AM |
5193 | #define TYPE_CODE(thistype) TYPE_MAIN_TYPE(thistype)->code |
5194 | #define TYPE_NFIELDS(thistype) TYPE_MAIN_TYPE(thistype)->nfields | |
5195 | #define TYPE_FIELDS(thistype) TYPE_MAIN_TYPE(thistype)->flds_bnds.fields | |
5196 | +#define TYPE_DATA_LOCATION_DWARF_BLOCK(thistype) TYPE_MAIN_TYPE (thistype)->data_location.dwarf_block | |
5197 | +#define TYPE_DATA_LOCATION_ADDR(thistype) TYPE_MAIN_TYPE (thistype)->data_location.addr | |
5198 | +#define TYPE_ALLOCATED(thistype) TYPE_MAIN_TYPE (thistype)->allocated | |
5199 | +#define TYPE_ASSOCIATED(thistype) TYPE_MAIN_TYPE (thistype)->associated | |
51a5ef0f | 5200 | |
6ed6bacf AM |
5201 | #define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0) |
5202 | #define TYPE_RANGE_DATA(thistype) TYPE_MAIN_TYPE(thistype)->flds_bnds.bounds | |
5203 | -#define TYPE_LOW_BOUND(range_type) TYPE_RANGE_DATA(range_type)->low | |
5204 | -#define TYPE_HIGH_BOUND(range_type) TYPE_RANGE_DATA(range_type)->high | |
5205 | +#define TYPE_LOW_BOUND(range_type) TYPE_RANGE_DATA(range_type)->low.u.constant | |
5206 | +#define TYPE_HIGH_BOUND(range_type) TYPE_RANGE_DATA(range_type)->high.u.constant | |
5207 | +#define TYPE_BYTE_STRIDE(range_type) TYPE_RANGE_DATA(range_type)->byte_stride.u.constant | |
5208 | #define TYPE_LOW_BOUND_UNDEFINED(range_type) \ | |
5209 | TYPE_RANGE_DATA(range_type)->low_undefined | |
5210 | #define TYPE_HIGH_BOUND_UNDEFINED(range_type) \ | |
f412e1b4 | 5211 | @@ -1047,7 +1145,14 @@ extern void allocate_gnat_aux_type (struct type *); |
6ed6bacf | 5212 | (TYPE_HIGH_BOUND(TYPE_INDEX_TYPE((arraytype)))) |
51a5ef0f | 5213 | |
6ed6bacf AM |
5214 | #define TYPE_ARRAY_LOWER_BOUND_VALUE(arraytype) \ |
5215 | - (TYPE_LOW_BOUND(TYPE_INDEX_TYPE((arraytype)))) | |
5216 | + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (arraytype)) | |
51a5ef0f | 5217 | + |
6ed6bacf AM |
5218 | +/* TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)) with a fallback to the |
5219 | + element size if no specific stride value is known. */ | |
5220 | +#define TYPE_ARRAY_BYTE_STRIDE_VALUE(arraytype) \ | |
5221 | + (TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)) == 0 \ | |
5222 | + ? TYPE_LENGTH (TYPE_TARGET_TYPE (arraytype)) \ | |
5223 | + : TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype))) | |
51a5ef0f | 5224 | |
6ed6bacf | 5225 | /* C++ */ |
51a5ef0f | 5226 | |
f412e1b4 | 5227 | @@ -1482,6 +1587,18 @@ extern struct type *create_array_type (struct type *, struct type *, |
6ed6bacf AM |
5228 | struct type *); |
5229 | extern struct type *lookup_array_range_type (struct type *, int, int); | |
5230 | ||
5231 | +extern CORE_ADDR type_range_any_field_internal (struct type *range_type, | |
5232 | + int fieldno); | |
51a5ef0f | 5233 | + |
6ed6bacf | 5234 | +extern int type_range_high_bound_internal (struct type *range_type); |
51a5ef0f | 5235 | + |
6ed6bacf | 5236 | +extern int type_range_count_bound_internal (struct type *range_type); |
51a5ef0f | 5237 | + |
6ed6bacf AM |
5238 | +extern CORE_ADDR type_range_byte_stride_internal (struct type *range_type, |
5239 | + struct type *element_type); | |
51a5ef0f | 5240 | + |
6ed6bacf | 5241 | +extern void finalize_type (struct type *type); |
51a5ef0f | 5242 | + |
6ed6bacf AM |
5243 | extern struct type *create_string_type (struct type *, struct type *, |
5244 | struct type *); | |
5245 | extern struct type *lookup_string_range_type (struct type *, int, int); | |
f412e1b4 | 5246 | @@ -1527,6 +1644,10 @@ extern int is_public_ancestor (struct type *, struct type *); |
51a5ef0f | 5247 | |
6ed6bacf | 5248 | extern int is_unique_ancestor (struct type *, struct value *); |
51a5ef0f | 5249 | |
6ed6bacf AM |
5250 | +#if 0 |
5251 | +extern void type_mark_used (struct type *type); | |
5252 | +#endif | |
51a5ef0f | 5253 | + |
6ed6bacf | 5254 | /* Overload resolution */ |
51a5ef0f | 5255 | |
6ed6bacf | 5256 | #define LENGTH_MATCH(bv) ((bv)->rank[0]) |
f412e1b4 | 5257 | @@ -1602,10 +1723,13 @@ extern void maintenance_print_type (char *, int); |
51a5ef0f | 5258 | |
6ed6bacf AM |
5259 | extern htab_t create_copied_types_hash (struct objfile *objfile); |
5260 | ||
5261 | -extern struct type *copy_type_recursive (struct objfile *objfile, | |
5262 | - struct type *type, | |
5263 | +extern struct type *copy_type_recursive (struct type *type, | |
5264 | htab_t copied_types); | |
5265 | ||
5266 | extern struct type *copy_type (const struct type *type); | |
5267 | ||
5268 | +#if 0 | |
5269 | +extern void free_all_types (void); | |
5270 | +#endif | |
51a5ef0f | 5271 | + |
6ed6bacf | 5272 | #endif /* GDBTYPES_H */ |
f412e1b4 PS |
5273 | diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c |
5274 | index 4b1b20f..38e7027 100644 | |
5275 | --- a/gdb/i386-linux-nat.c | |
5276 | +++ b/gdb/i386-linux-nat.c | |
5277 | @@ -708,8 +708,8 @@ i386_linux_dr_get_status (void) | |
5278 | return i386_linux_dr_get (inferior_ptid, DR_STATUS); | |
6ed6bacf | 5279 | } |
51a5ef0f | 5280 | |
f412e1b4 PS |
5281 | -/* Callback for iterate_over_lwps. Update the debug registers of |
5282 | - LWP. */ | |
5283 | +/* Callback for linux_nat_iterate_watchpoint_lwps. Update the debug registers | |
5284 | + of LWP. */ | |
51a5ef0f | 5285 | |
f412e1b4 PS |
5286 | static int |
5287 | update_debug_registers_callback (struct lwp_info *lwp, void *arg) | |
5288 | @@ -735,9 +735,7 @@ update_debug_registers_callback (struct lwp_info *lwp, void *arg) | |
6ed6bacf | 5289 | static void |
f412e1b4 | 5290 | i386_linux_dr_set_control (unsigned long control) |
51a5ef0f | 5291 | { |
f412e1b4 | 5292 | - ptid_t pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid)); |
6ed6bacf | 5293 | - |
f412e1b4 PS |
5294 | - iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL); |
5295 | + linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL); | |
6ed6bacf AM |
5296 | } |
5297 | ||
f412e1b4 PS |
5298 | /* Set address REGNUM (zero based) to ADDR in all LWPs of the current |
5299 | @@ -750,7 +748,7 @@ i386_linux_dr_set_addr (int regnum, CORE_ADDR addr) | |
51a5ef0f | 5300 | |
f412e1b4 | 5301 | gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR); |
3a58abaf | 5302 | |
f412e1b4 PS |
5303 | - iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL); |
5304 | + linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL); | |
5305 | } | |
5306 | ||
5307 | /* Called when resuming a thread. | |
5308 | @@ -772,6 +770,9 @@ i386_linux_prepare_to_resume (struct lwp_info *lwp) | |
5309 | struct i386_debug_reg_state *state = i386_debug_reg_state (); | |
5310 | int i; | |
5311 | ||
5312 | + /* See amd64_linux_prepare_to_resume for Linux kernel note on | |
5313 | + i386_linux_dr_set calls ordering. */ | |
6ed6bacf | 5314 | + |
f412e1b4 PS |
5315 | for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++) |
5316 | if (state->dr_ref_count[i] > 0) | |
5317 | { | |
5318 | diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c | |
5319 | index eb114ef..f80e05a 100644 | |
5320 | --- a/gdb/i386-linux-tdep.c | |
5321 | +++ b/gdb/i386-linux-tdep.c | |
5322 | @@ -903,6 +903,15 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) | |
5323 | i386_linux_get_syscall_number); | |
5324 | ||
5325 | set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type); | |
5326 | + | |
5327 | + /* SystemTap variables and functions. */ | |
5328 | + set_gdbarch_stap_integer_prefix (gdbarch, "$"); | |
5329 | + set_gdbarch_stap_register_prefix (gdbarch, "%"); | |
5330 | + set_gdbarch_stap_register_indirection_prefix (gdbarch, "("); | |
5331 | + set_gdbarch_stap_register_indirection_sufix (gdbarch, ")"); | |
5332 | + set_gdbarch_stap_is_single_operand (gdbarch, i386_stap_is_single_operand); | |
5333 | + set_gdbarch_stap_parse_special_token (gdbarch, | |
5334 | + i386_stap_parse_special_token); | |
5335 | } | |
5336 | ||
5337 | /* Provide a prototype to silence -Wmissing-prototypes. */ | |
5338 | diff --git a/gdb/i386-nat.c b/gdb/i386-nat.c | |
5339 | index fa17823..846b2b8 100644 | |
5340 | --- a/gdb/i386-nat.c | |
5341 | +++ b/gdb/i386-nat.c | |
5342 | @@ -25,6 +25,7 @@ | |
5343 | #include "gdbcmd.h" | |
5344 | #include "target.h" | |
5345 | #include "gdb_assert.h" | |
5346 | +#include "inferior.h" | |
5347 | ||
5348 | /* Support for hardware watchpoints and breakpoints using the i386 | |
5349 | debug registers. | |
5350 | @@ -170,14 +171,88 @@ i386_init_dregs (struct i386_debug_reg_state *state) | |
5351 | state->dr_status_mirror = 0; | |
6ed6bacf | 5352 | } |
3a58abaf | 5353 | |
f412e1b4 PS |
5354 | -/* The local mirror of the inferior's debug registers. Currently this |
5355 | - is a global, but it should really be per-inferior. */ | |
5356 | -static struct i386_debug_reg_state dr_mirror; | |
5357 | +/* Per-inferior data key. */ | |
5358 | +static const struct inferior_data *i386_inferior_data; | |
3a58abaf | 5359 | + |
f412e1b4 PS |
5360 | +/* Per-inferior data. */ |
5361 | +struct i386_inferior_data | |
6ed6bacf | 5362 | + { |
f412e1b4 PS |
5363 | + /* Copy of i386 hardware debug registers for performance reasons. */ |
5364 | + struct i386_debug_reg_state state; | |
6ed6bacf AM |
5365 | + }; |
5366 | + | |
f412e1b4 | 5367 | +/* Per-inferior hook for register_inferior_data_with_cleanup. */ |
3a58abaf | 5368 | + |
6ed6bacf AM |
5369 | +static void |
5370 | +i386_inferior_data_cleanup (struct inferior *inf, void *arg) | |
5371 | +{ | |
5372 | + struct i386_inferior_data *inf_data = arg; | |
3a58abaf | 5373 | + |
6ed6bacf AM |
5374 | + xfree (inf_data); |
5375 | +} | |
5376 | + | |
f412e1b4 PS |
5377 | +/* Get data specific for INFERIOR_PTID LWP. Return special data area |
5378 | + for processes being detached. */ | |
5379 | + | |
6ed6bacf AM |
5380 | +static struct i386_inferior_data * |
5381 | +i386_inferior_data_get (void) | |
3a58abaf | 5382 | +{ |
6ed6bacf AM |
5383 | + struct inferior *inf = current_inferior (); |
5384 | + struct i386_inferior_data *inf_data; | |
5385 | + | |
5386 | + inf_data = inferior_data (inf, i386_inferior_data); | |
5387 | + if (inf_data == NULL) | |
5388 | + { | |
5389 | + inf_data = xzalloc (sizeof (*inf_data)); | |
5390 | + set_inferior_data (current_inferior (), i386_inferior_data, inf_data); | |
5391 | + } | |
3a58abaf | 5392 | + |
6ed6bacf AM |
5393 | + if (inf->pid != ptid_get_pid (inferior_ptid)) |
5394 | + { | |
f412e1b4 PS |
5395 | + /* INFERIOR_PTID is being detached from the inferior INF. |
5396 | + Provide local cache specific for the detached LWP. */ | |
5397 | + | |
6ed6bacf AM |
5398 | + static struct i386_inferior_data detached_inf_data_local; |
5399 | + static int detached_inf_pid = -1; | |
3a58abaf | 5400 | + |
6ed6bacf AM |
5401 | + if (detached_inf_pid != ptid_get_pid (inferior_ptid)) |
5402 | + { | |
f412e1b4 PS |
5403 | + /* Reinitialize the local cache if INFERIOR_PTID is |
5404 | + different from the LWP last detached. | |
5405 | + | |
5406 | + Linux kernel before 2.6.33 commit | |
5407 | + 72f674d203cd230426437cdcf7dd6f681dad8b0d | |
5408 | + will inherit hardware debug registers from parent | |
5409 | + on fork/vfork/clone. Newer Linux kernels create such tasks with | |
5410 | + zeroed debug registers. | |
5411 | + | |
5412 | + GDB will remove all breakpoints (and watchpoints) from the forked | |
5413 | + off process. We also need to reset the debug registers in that | |
5414 | + process to be compatible with the older Linux kernels. | |
5415 | + | |
5416 | + Copy the debug registers mirrors into the new process so that all | |
5417 | + breakpoints and watchpoints can be removed together. The debug | |
5418 | + registers mirror will become zeroed in the end before detaching | |
5419 | + the forked off process. */ | |
6ed6bacf | 5420 | + |
f412e1b4 | 5421 | + detached_inf_pid = ptid_get_pid (inferior_ptid); |
6ed6bacf AM |
5422 | + memcpy (&detached_inf_data_local, inf_data, |
5423 | + sizeof (detached_inf_data_local)); | |
6ed6bacf AM |
5424 | + } |
5425 | + | |
5426 | + return &detached_inf_data_local; | |
5427 | + } | |
3a58abaf | 5428 | + |
6ed6bacf | 5429 | + return inf_data; |
3a58abaf AM |
5430 | +} |
5431 | + | |
f412e1b4 PS |
5432 | +/* Get debug registers state for INFERIOR_PTID, see |
5433 | + i386_inferior_data_get. */ | |
6ed6bacf | 5434 | |
f412e1b4 PS |
5435 | struct i386_debug_reg_state * |
5436 | i386_debug_reg_state (void) | |
5437 | { | |
5438 | - return &dr_mirror; | |
5439 | + return &i386_inferior_data_get ()->state; | |
5440 | } | |
5441 | ||
5442 | /* Whether or not to print the mirrored debug registers. */ | |
5443 | @@ -230,7 +305,9 @@ static int i386_handle_nonaligned_watchpoint (struct i386_debug_reg_state *state | |
6ed6bacf AM |
5444 | void |
5445 | i386_cleanup_dregs (void) | |
3a58abaf | 5446 | { |
f412e1b4 PS |
5447 | - i386_init_dregs (&dr_mirror); |
5448 | + struct i386_debug_reg_state *state = i386_debug_reg_state (); | |
5449 | + | |
5450 | + i386_init_dregs (state); | |
6ed6bacf | 5451 | } |
3a58abaf | 5452 | |
6ed6bacf | 5453 | /* Print the values of the mirrored debug registers. This is called |
f412e1b4 PS |
5454 | @@ -494,20 +571,21 @@ Invalid value %d of operation in i386_handle_nonaligned_watchpoint.\n"), |
5455 | static void | |
5456 | i386_update_inferior_debug_regs (struct i386_debug_reg_state *new_state) | |
6ed6bacf | 5457 | { |
f412e1b4 | 5458 | + struct i386_debug_reg_state *state = i386_debug_reg_state (); |
6ed6bacf | 5459 | int i; |
3a58abaf | 5460 | |
f412e1b4 | 5461 | ALL_DEBUG_REGISTERS (i) |
6ed6bacf | 5462 | { |
f412e1b4 PS |
5463 | - if (I386_DR_VACANT (new_state, i) != I386_DR_VACANT (&dr_mirror, i)) |
5464 | + if (I386_DR_VACANT (new_state, i) != I386_DR_VACANT (state, i)) | |
5465 | i386_dr_low.set_addr (i, new_state->dr_mirror[i]); | |
5466 | else | |
5467 | - gdb_assert (new_state->dr_mirror[i] == dr_mirror.dr_mirror[i]); | |
5468 | + gdb_assert (new_state->dr_mirror[i] == state->dr_mirror[i]); | |
6ed6bacf | 5469 | } |
3a58abaf | 5470 | |
f412e1b4 PS |
5471 | - if (new_state->dr_control_mirror != dr_mirror.dr_control_mirror) |
5472 | + if (new_state->dr_control_mirror != state->dr_control_mirror) | |
5473 | i386_dr_low.set_control (new_state->dr_control_mirror); | |
6ed6bacf | 5474 | |
f412e1b4 PS |
5475 | - dr_mirror = *new_state; |
5476 | + *state = *new_state; | |
5477 | } | |
5478 | ||
5479 | /* Insert a watchpoint to watch a memory region which starts at | |
5480 | @@ -518,10 +596,11 @@ static int | |
5481 | i386_insert_watchpoint (CORE_ADDR addr, int len, int type, | |
5482 | struct expression *cond) | |
5483 | { | |
5484 | + struct i386_debug_reg_state *state = i386_debug_reg_state (); | |
5485 | int retval; | |
5486 | /* Work on a local copy of the debug registers, and on success, | |
5487 | commit the change back to the inferior. */ | |
5488 | - struct i386_debug_reg_state local_state = dr_mirror; | |
5489 | + struct i386_debug_reg_state local_state = *state; | |
5490 | ||
5491 | if (type == hw_read) | |
5492 | return 1; /* unsupported */ | |
5493 | @@ -542,7 +621,7 @@ i386_insert_watchpoint (CORE_ADDR addr, int len, int type, | |
5494 | i386_update_inferior_debug_regs (&local_state); | |
5495 | ||
5496 | if (maint_show_dr) | |
5497 | - i386_show_dr (&dr_mirror, "insert_watchpoint", addr, len, type); | |
5498 | + i386_show_dr (state, "insert_watchpoint", addr, len, type); | |
5499 | ||
5500 | return retval; | |
5501 | } | |
5502 | @@ -554,10 +633,11 @@ static int | |
5503 | i386_remove_watchpoint (CORE_ADDR addr, int len, int type, | |
5504 | struct expression *cond) | |
5505 | { | |
5506 | + struct i386_debug_reg_state *state = i386_debug_reg_state (); | |
5507 | int retval; | |
5508 | /* Work on a local copy of the debug registers, and on success, | |
5509 | commit the change back to the inferior. */ | |
5510 | - struct i386_debug_reg_state local_state = dr_mirror; | |
5511 | + struct i386_debug_reg_state local_state = *state; | |
5512 | ||
5513 | if (((len != 1 && len !=2 && len !=4) && !(TARGET_HAS_DR_LEN_8 && len == 8)) | |
5514 | || addr % len != 0) | |
5515 | @@ -575,7 +655,7 @@ i386_remove_watchpoint (CORE_ADDR addr, int len, int type, | |
5516 | i386_update_inferior_debug_regs (&local_state); | |
5517 | ||
5518 | if (maint_show_dr) | |
5519 | - i386_show_dr (&dr_mirror, "remove_watchpoint", addr, len, type); | |
5520 | + i386_show_dr (state, "remove_watchpoint", addr, len, type); | |
5521 | ||
5522 | return retval; | |
5523 | } | |
5524 | @@ -586,11 +666,12 @@ i386_remove_watchpoint (CORE_ADDR addr, int len, int type, | |
6ed6bacf | 5525 | static int |
f412e1b4 | 5526 | i386_region_ok_for_watchpoint (CORE_ADDR addr, int len) |
3a58abaf | 5527 | { |
f412e1b4 PS |
5528 | + struct i386_debug_reg_state *state = i386_debug_reg_state (); |
5529 | int nregs; | |
5530 | ||
5531 | /* Compute how many aligned watchpoints we would need to cover this | |
5532 | region. */ | |
5533 | - nregs = i386_handle_nonaligned_watchpoint (&dr_mirror, | |
5534 | + nregs = i386_handle_nonaligned_watchpoint (state, | |
5535 | WP_COUNT, addr, len, hw_write); | |
5536 | return nregs <= DR_NADDR ? 1 : 0; | |
5537 | } | |
5538 | @@ -602,6 +683,7 @@ i386_region_ok_for_watchpoint (CORE_ADDR addr, int len) | |
6ed6bacf AM |
5539 | static int |
5540 | i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p) | |
5541 | { | |
f412e1b4 | 5542 | + struct i386_debug_reg_state *state = i386_debug_reg_state (); |
6ed6bacf AM |
5543 | CORE_ADDR addr = 0; |
5544 | int i; | |
5545 | int rc = 0; | |
f412e1b4 PS |
5546 | @@ -615,25 +697,24 @@ i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p) |
5547 | unsigned control = 0; | |
5548 | ||
5549 | /* In non-stop/async, threads can be running while we change the | |
5550 | - global dr_mirror (and friends). Say, we set a watchpoint, and | |
5551 | - let threads resume. Now, say you delete the watchpoint, or | |
5552 | - add/remove watchpoints such that dr_mirror changes while threads | |
5553 | - are running. On targets that support non-stop, | |
5554 | - inserting/deleting watchpoints updates the global dr_mirror only. | |
5555 | - It does not update the real thread's debug registers; that's only | |
5556 | - done prior to resume. Instead, if threads are running when the | |
5557 | - mirror changes, a temporary and transparent stop on all threads | |
5558 | - is forced so they can get their copy of the debug registers | |
5559 | - updated on re-resume. Now, say, a thread hit a watchpoint before | |
5560 | - having been updated with the new dr_mirror contents, and we | |
5561 | - haven't yet handled the corresponding SIGTRAP. If we trusted | |
5562 | - dr_mirror below, we'd mistake the real trapped address (from the | |
5563 | - last time we had updated debug registers in the thread) with | |
5564 | - whatever was currently in dr_mirror. So to fix this, dr_mirror | |
5565 | - always represents intention, what we _want_ threads to have in | |
5566 | - debug registers. To get at the address and cause of the trap, we | |
5567 | - need to read the state the thread still has in its debug | |
5568 | - registers. | |
5569 | + STATE (and friends). Say, we set a watchpoint, and let threads | |
5570 | + resume. Now, say you delete the watchpoint, or add/remove | |
5571 | + watchpoints such that STATE changes while threads are running. | |
5572 | + On targets that support non-stop, inserting/deleting watchpoints | |
5573 | + updates the STATE only. It does not update the real thread's | |
5574 | + debug registers; that's only done prior to resume. Instead, if | |
5575 | + threads are running when the mirror changes, a temporary and | |
5576 | + transparent stop on all threads is forced so they can get their | |
5577 | + copy of the debug registers updated on re-resume. Now, say, | |
5578 | + a thread hit a watchpoint before having been updated with the new | |
5579 | + STATE contents, and we haven't yet handled the corresponding | |
5580 | + SIGTRAP. If we trusted STATE below, we'd mistake the real | |
5581 | + trapped address (from the last time we had updated debug | |
5582 | + registers in the thread) with whatever was currently in STATE. | |
5583 | + So to fix this, STATE always represents intention, what we _want_ | |
5584 | + threads to have in debug registers. To get at the address and | |
5585 | + cause of the trap, we need to read the state the thread still has | |
5586 | + in its debug registers. | |
5587 | ||
5588 | In sum, always get the current debug register values the current | |
5589 | thread has, instead of trusting the global mirror. If the thread | |
5590 | @@ -663,11 +744,11 @@ i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p) | |
5591 | addr = i386_dr_low.get_addr (i); | |
6ed6bacf AM |
5592 | rc = 1; |
5593 | if (maint_show_dr) | |
f412e1b4 PS |
5594 | - i386_show_dr (&dr_mirror, "watchpoint_hit", addr, -1, hw_write); |
5595 | + i386_show_dr (state, "watchpoint_hit", addr, -1, hw_write); | |
5596 | } | |
5597 | } | |
5598 | if (maint_show_dr && addr == 0) | |
5599 | - i386_show_dr (&dr_mirror, "stopped_data_addr", 0, 0, hw_write); | |
5600 | + i386_show_dr (state, "stopped_data_addr", 0, 0, hw_write); | |
5601 | ||
5602 | if (rc) | |
5603 | *addr_p = addr; | |
5604 | @@ -687,11 +768,12 @@ static int | |
5605 | i386_insert_hw_breakpoint (struct gdbarch *gdbarch, | |
5606 | struct bp_target_info *bp_tgt) | |
5607 | { | |
5608 | + struct i386_debug_reg_state *state = i386_debug_reg_state (); | |
5609 | unsigned len_rw = i386_length_and_rw_bits (1, hw_execute); | |
5610 | CORE_ADDR addr = bp_tgt->placed_address; | |
5611 | /* Work on a local copy of the debug registers, and on success, | |
5612 | commit the change back to the inferior. */ | |
5613 | - struct i386_debug_reg_state local_state = dr_mirror; | |
5614 | + struct i386_debug_reg_state local_state = *state; | |
5615 | int retval = i386_insert_aligned_watchpoint (&local_state, | |
5616 | addr, len_rw) ? EBUSY : 0; | |
5617 | ||
5618 | @@ -699,7 +781,7 @@ i386_insert_hw_breakpoint (struct gdbarch *gdbarch, | |
5619 | i386_update_inferior_debug_regs (&local_state); | |
5620 | ||
5621 | if (maint_show_dr) | |
5622 | - i386_show_dr (&dr_mirror, "insert_hwbp", addr, 1, hw_execute); | |
5623 | + i386_show_dr (state, "insert_hwbp", addr, 1, hw_execute); | |
5624 | ||
5625 | return retval; | |
5626 | } | |
5627 | @@ -711,11 +793,12 @@ static int | |
5628 | i386_remove_hw_breakpoint (struct gdbarch *gdbarch, | |
5629 | struct bp_target_info *bp_tgt) | |
5630 | { | |
5631 | + struct i386_debug_reg_state *state = i386_debug_reg_state (); | |
5632 | unsigned len_rw = i386_length_and_rw_bits (1, hw_execute); | |
5633 | CORE_ADDR addr = bp_tgt->placed_address; | |
5634 | /* Work on a local copy of the debug registers, and on success, | |
5635 | commit the change back to the inferior. */ | |
5636 | - struct i386_debug_reg_state local_state = dr_mirror; | |
5637 | + struct i386_debug_reg_state local_state = *state; | |
5638 | int retval = i386_remove_aligned_watchpoint (&local_state, | |
5639 | addr, len_rw); | |
5640 | ||
5641 | @@ -723,7 +806,7 @@ i386_remove_hw_breakpoint (struct gdbarch *gdbarch, | |
5642 | i386_update_inferior_debug_regs (&local_state); | |
5643 | ||
5644 | if (maint_show_dr) | |
5645 | - i386_show_dr (&dr_mirror, "remove_hwbp", addr, 1, hw_execute); | |
5646 | + i386_show_dr (state, "remove_hwbp", addr, 1, hw_execute); | |
5647 | ||
5648 | return retval; | |
5649 | } | |
5650 | @@ -788,6 +871,10 @@ i386_use_watchpoints (struct target_ops *t) | |
6ed6bacf AM |
5651 | t->to_remove_watchpoint = i386_remove_watchpoint; |
5652 | t->to_insert_hw_breakpoint = i386_insert_hw_breakpoint; | |
5653 | t->to_remove_hw_breakpoint = i386_remove_hw_breakpoint; | |
5654 | + | |
5655 | + if (i386_inferior_data == NULL) | |
5656 | + i386_inferior_data | |
5657 | + = register_inferior_data_with_cleanup (i386_inferior_data_cleanup); | |
5658 | } | |
3a58abaf | 5659 | |
6ed6bacf | 5660 | void |
f412e1b4 PS |
5661 | diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c |
5662 | index 549297e..5783c4c 100644 | |
5663 | --- a/gdb/i386-tdep.c | |
5664 | +++ b/gdb/i386-tdep.c | |
5665 | @@ -58,8 +58,14 @@ | |
5666 | #include "features/i386/i386-avx.c" | |
5667 | #include "features/i386/i386-mmx.c" | |
3a58abaf | 5668 | |
f412e1b4 PS |
5669 | +#include "stap-probe.h" |
5670 | #include "ax.h" | |
5671 | #include "ax-gdb.h" | |
5672 | +#include "user-regs.h" | |
5673 | +#include "cli/cli-utils.h" | |
5674 | +#include "expression.h" | |
5675 | +#include "parser-defs.h" | |
5676 | +#include <ctype.h> | |
3a58abaf | 5677 | |
f412e1b4 PS |
5678 | /* Register names. */ |
5679 | ||
5680 | @@ -7246,6 +7252,312 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, | |
5681 | return valid_p; | |
5682 | } | |
5683 | ||
5684 | +int | |
5685 | +i386_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) | |
5686 | +{ | |
5687 | + return (*s == '$' /* Literal number. */ | |
5688 | + || (isdigit (*s) && s[1] == '(' && s[2] == '%') /* Displacement. */ | |
5689 | + || (*s == '(' && s[1] == '%') /* Register indirection. */ | |
5690 | + || (*s == '%' && isalpha (s[1]))); /* Register access. */ | |
5691 | +} | |
3a58abaf | 5692 | + |
f412e1b4 PS |
5693 | +int |
5694 | +i386_stap_parse_special_token (struct gdbarch *gdbarch, | |
5695 | + struct stap_parse_info *p) | |
5696 | +{ | |
5697 | + const char *s = p->arg; | |
6ed6bacf | 5698 | + |
f412e1b4 PS |
5699 | + /* In order to parse special tokens, we use a state-machine that go |
5700 | + through every known token and try to get a match. */ | |
5701 | + enum | |
5702 | + { | |
5703 | + TRIPLET, | |
5704 | + THREE_ARG_DISPLACEMENT, | |
5705 | + DONE | |
5706 | + } current_state; | |
6ed6bacf | 5707 | + |
f412e1b4 | 5708 | + current_state = TRIPLET; |
6ed6bacf | 5709 | + |
f412e1b4 | 5710 | + /* The special tokens to be parsed here are: |
6ed6bacf | 5711 | + |
f412e1b4 PS |
5712 | + - `register base + (register index * size) + offset', as represented |
5713 | + in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'. | |
6ed6bacf | 5714 | + |
f412e1b4 PS |
5715 | + - Operands of the form `-8+3+1(%rbp)', which must be interpreted as |
5716 | + `*(-8 + 3 - 1 + (void *) $eax)'. */ | |
5717 | + | |
5718 | + while (current_state != DONE) | |
5719 | + { | |
5720 | + const char *s = p->arg; | |
5721 | + | |
5722 | + switch (current_state) | |
5723 | + { | |
5724 | + case TRIPLET: | |
5725 | + { | |
5726 | + if (isdigit (*s) || *s == '-' || *s == '+') | |
5727 | + { | |
5728 | + int got_minus[3]; | |
5729 | + int i; | |
5730 | + long displacements[3]; | |
5731 | + const char *start; | |
5732 | + char *regname; | |
5733 | + int len; | |
5734 | + struct stoken str; | |
5735 | + | |
5736 | + got_minus[0] = 0; | |
5737 | + if (*s == '+') | |
5738 | + ++s; | |
5739 | + else if (*s == '-') | |
5740 | + { | |
5741 | + ++s; | |
5742 | + got_minus[0] = 1; | |
5743 | + } | |
5744 | + | |
5745 | + displacements[0] = strtol (s, (char **) &s, 10); | |
5746 | + | |
5747 | + if (*s != '+' && *s != '-') | |
5748 | + /* We are not dealing with a triplet. */ | |
5749 | + break; | |
5750 | + | |
5751 | + got_minus[1] = 0; | |
5752 | + if (*s == '+') | |
5753 | + ++s; | |
5754 | + else | |
5755 | + { | |
5756 | + ++s; | |
5757 | + got_minus[1] = 1; | |
5758 | + } | |
5759 | + | |
5760 | + displacements[1] = strtol (s, (char **) &s, 10); | |
5761 | + | |
5762 | + if (*s != '+' && *s != '-') | |
5763 | + /* We are not dealing with a triplet. */ | |
5764 | + break; | |
5765 | + | |
5766 | + got_minus[2] = 0; | |
5767 | + if (*s == '+') | |
5768 | + ++s; | |
5769 | + else | |
5770 | + { | |
5771 | + ++s; | |
5772 | + got_minus[2] = 1; | |
5773 | + } | |
5774 | + | |
5775 | + displacements[2] = strtol (s, (char **) &s, 10); | |
5776 | + | |
5777 | + if (*s != '(' || s[1] != '%') | |
5778 | + break; | |
5779 | + | |
5780 | + s += 2; | |
5781 | + start = s; | |
5782 | + | |
5783 | + while (isalnum (*s)) | |
5784 | + ++s; | |
5785 | + | |
5786 | + if (*s++ != ')') | |
5787 | + break; | |
5788 | + | |
5789 | + len = s - start; | |
5790 | + regname = alloca (len + 1); | |
5791 | + | |
5792 | + strncpy (regname, start, len); | |
5793 | + regname[len] = '\0'; | |
5794 | + | |
5795 | + if (user_reg_map_name_to_regnum (gdbarch, | |
5796 | + regname, len) == -1) | |
5797 | + error (_("Invalid register name `%s' " | |
5798 | + "on expression `%s'."), | |
5799 | + regname, p->saved_arg); | |
5800 | + | |
5801 | + for (i = 0; i < 3; i++) | |
5802 | + { | |
5803 | + write_exp_elt_opcode (OP_LONG); | |
5804 | + write_exp_elt_type | |
5805 | + (builtin_type (gdbarch)->builtin_long); | |
5806 | + write_exp_elt_longcst (displacements[i]); | |
5807 | + write_exp_elt_opcode (OP_LONG); | |
5808 | + if (got_minus[i]) | |
5809 | + write_exp_elt_opcode (UNOP_NEG); | |
5810 | + } | |
5811 | + | |
5812 | + write_exp_elt_opcode (OP_REGISTER); | |
5813 | + str.ptr = regname; | |
5814 | + str.length = len; | |
5815 | + write_exp_string (str); | |
5816 | + write_exp_elt_opcode (OP_REGISTER); | |
5817 | + | |
5818 | + write_exp_elt_opcode (UNOP_CAST); | |
5819 | + write_exp_elt_type (builtin_type (gdbarch)->builtin_data_ptr); | |
5820 | + write_exp_elt_opcode (UNOP_CAST); | |
5821 | + | |
5822 | + write_exp_elt_opcode (BINOP_ADD); | |
5823 | + write_exp_elt_opcode (BINOP_ADD); | |
5824 | + write_exp_elt_opcode (BINOP_ADD); | |
5825 | + | |
5826 | + write_exp_elt_opcode (UNOP_CAST); | |
5827 | + write_exp_elt_type (lookup_pointer_type (p->arg_type)); | |
5828 | + write_exp_elt_opcode (UNOP_CAST); | |
5829 | + | |
5830 | + write_exp_elt_opcode (UNOP_IND); | |
5831 | + | |
5832 | + p->arg = s; | |
5833 | + | |
5834 | + return 1; | |
5835 | + } | |
5836 | + break; | |
5837 | + } | |
5838 | + case THREE_ARG_DISPLACEMENT: | |
5839 | + { | |
5840 | + if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+') | |
5841 | + { | |
5842 | + int offset_minus = 0; | |
5843 | + long offset = 0; | |
5844 | + int size_minus = 0; | |
5845 | + long size = 0; | |
5846 | + const char *start; | |
5847 | + char *base; | |
5848 | + int len_base; | |
5849 | + char *index; | |
5850 | + int len_index; | |
5851 | + struct stoken base_token, index_token; | |
5852 | + | |
5853 | + if (*s == '+') | |
5854 | + ++s; | |
5855 | + else if (*s == '-') | |
5856 | + { | |
5857 | + ++s; | |
5858 | + offset_minus = 1; | |
5859 | + } | |
5860 | + | |
5861 | + if (offset_minus && !isdigit (*s)) | |
5862 | + break; | |
5863 | + | |
5864 | + if (isdigit (*s)) | |
5865 | + offset = strtol (s, (char **) &s, 10); | |
5866 | + | |
5867 | + if (*s != '(' || s[1] != '%') | |
5868 | + break; | |
5869 | + | |
5870 | + s += 2; | |
5871 | + start = s; | |
5872 | + | |
5873 | + while (isalnum (*s)) | |
5874 | + ++s; | |
5875 | + | |
5876 | + if (*s != ',' || s[1] != '%') | |
5877 | + break; | |
5878 | + | |
5879 | + len_base = s - start; | |
5880 | + base = alloca (len_base + 1); | |
5881 | + strncpy (base, start, len_base); | |
5882 | + base[len_base] = '\0'; | |
5883 | + | |
5884 | + if (user_reg_map_name_to_regnum (gdbarch, | |
5885 | + base, len_base) == -1) | |
5886 | + error (_("Invalid register name `%s' " | |
5887 | + "on expression `%s'."), | |
5888 | + base, p->saved_arg); | |
5889 | + | |
5890 | + s += 2; | |
5891 | + start = s; | |
5892 | + | |
5893 | + while (isalnum (*s)) | |
5894 | + ++s; | |
5895 | + | |
5896 | + len_index = s - start; | |
5897 | + index = alloca (len_index + 1); | |
5898 | + strncpy (index, start, len_index); | |
5899 | + index[len_index] = '\0'; | |
5900 | + | |
5901 | + if (user_reg_map_name_to_regnum (gdbarch, | |
5902 | + index, len_index) == -1) | |
5903 | + error (_("Invalid register name `%s' " | |
5904 | + "on expression `%s'."), | |
5905 | + index, p->saved_arg); | |
5906 | + | |
5907 | + if (*s != ',' && *s != ')') | |
5908 | + break; | |
5909 | + | |
5910 | + if (*s == ',') | |
5911 | + { | |
5912 | + ++s; | |
5913 | + if (*s == '+') | |
5914 | + ++s; | |
5915 | + else if (*s == '-') | |
5916 | + { | |
5917 | + ++s; | |
5918 | + size_minus = 1; | |
5919 | + } | |
5920 | + | |
5921 | + size = strtol (s, (char **) &s, 10); | |
5922 | + | |
5923 | + if (*s != ')') | |
5924 | + break; | |
5925 | + } | |
5926 | + | |
5927 | + ++s; | |
5928 | + | |
5929 | + if (offset) | |
5930 | + { | |
5931 | + write_exp_elt_opcode (OP_LONG); | |
5932 | + write_exp_elt_type | |
5933 | + (builtin_type (gdbarch)->builtin_long); | |
5934 | + write_exp_elt_longcst (offset); | |
5935 | + write_exp_elt_opcode (OP_LONG); | |
5936 | + if (offset_minus) | |
5937 | + write_exp_elt_opcode (UNOP_NEG); | |
5938 | + } | |
5939 | + | |
5940 | + write_exp_elt_opcode (OP_REGISTER); | |
5941 | + base_token.ptr = base; | |
5942 | + base_token.length = len_base; | |
5943 | + write_exp_string (base_token); | |
5944 | + write_exp_elt_opcode (OP_REGISTER); | |
5945 | + | |
5946 | + if (offset) | |
5947 | + write_exp_elt_opcode (BINOP_ADD); | |
5948 | + | |
5949 | + write_exp_elt_opcode (OP_REGISTER); | |
5950 | + index_token.ptr = index; | |
5951 | + index_token.length = len_index; | |
5952 | + write_exp_string (index_token); | |
5953 | + write_exp_elt_opcode (OP_REGISTER); | |
5954 | + | |
5955 | + if (size) | |
5956 | + { | |
5957 | + write_exp_elt_opcode (OP_LONG); | |
5958 | + write_exp_elt_type | |
5959 | + (builtin_type (gdbarch)->builtin_long); | |
5960 | + write_exp_elt_longcst (size); | |
5961 | + write_exp_elt_opcode (OP_LONG); | |
5962 | + if (size_minus) | |
5963 | + write_exp_elt_opcode (UNOP_NEG); | |
5964 | + write_exp_elt_opcode (BINOP_MUL); | |
5965 | + } | |
5966 | + | |
5967 | + write_exp_elt_opcode (BINOP_ADD); | |
5968 | + | |
5969 | + write_exp_elt_opcode (UNOP_CAST); | |
5970 | + write_exp_elt_type (lookup_pointer_type (p->arg_type)); | |
5971 | + write_exp_elt_opcode (UNOP_CAST); | |
5972 | + | |
5973 | + write_exp_elt_opcode (UNOP_IND); | |
5974 | + | |
5975 | + p->arg = s; | |
5976 | + | |
5977 | + return 1; | |
5978 | + } | |
5979 | + break; | |
5980 | + } | |
5981 | + } | |
5982 | + | |
5983 | + /* Advancing to the next state. */ | |
5984 | + ++current_state; | |
5985 | + } | |
5986 | + | |
5987 | + return 0; | |
5988 | +} | |
5989 | + | |
5990 | \f | |
5991 | static struct gdbarch * | |
5992 | i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | |
5993 | diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h | |
5994 | index 870054f..9ffbe44 100644 | |
5995 | --- a/gdb/i386-tdep.h | |
5996 | +++ b/gdb/i386-tdep.h | |
5997 | @@ -379,6 +379,15 @@ extern void i386_svr4_init_abi (struct gdbarch_info, struct gdbarch *); | |
5998 | ||
5999 | extern int i386_process_record (struct gdbarch *gdbarch, | |
6000 | struct regcache *regcache, CORE_ADDR addr); | |
6001 | + | |
6002 | +/* SystemTap related functions. */ | |
6003 | + | |
6004 | +extern int i386_stap_is_single_operand (struct gdbarch *gdbarch, | |
6005 | + const char *s); | |
6006 | + | |
6007 | +extern int i386_stap_parse_special_token (struct gdbarch *gdbarch, | |
6008 | + struct stap_parse_info *p); | |
6009 | + | |
6010 | \f | |
6011 | ||
6012 | /* Functions and variables exported from i386bsd-tdep.c. */ | |
6013 | diff --git a/gdb/infrun.c b/gdb/infrun.c | |
6014 | index 24d2720..c516b8b 100644 | |
6015 | --- a/gdb/infrun.c | |
6016 | +++ b/gdb/infrun.c | |
6017 | @@ -55,6 +55,8 @@ | |
6018 | #include "continuations.h" | |
6019 | #include "interps.h" | |
6020 | #include "skip.h" | |
6ed6bacf AM |
6021 | +#include "stap-probe.h" |
6022 | +#include "objfiles.h" | |
3a58abaf | 6023 | |
6ed6bacf | 6024 | /* Prototypes for local functions */ |
3a58abaf | 6025 | |
f412e1b4 PS |
6026 | @@ -2379,7 +2381,7 @@ static void handle_step_into_function (struct gdbarch *gdbarch, |
6027 | static void handle_step_into_function_backward (struct gdbarch *gdbarch, | |
6028 | struct execution_control_state *ecs); | |
6ed6bacf AM |
6029 | static void check_exception_resume (struct execution_control_state *, |
6030 | - struct frame_info *, struct symbol *); | |
6031 | + struct frame_info *); | |
6032 | ||
6033 | static void stop_stepping (struct execution_control_state *ecs); | |
6034 | static void prepare_to_wait (struct execution_control_state *ecs); | |
f412e1b4 | 6035 | @@ -4417,9 +4419,17 @@ process_event_stop_test: |
6ed6bacf AM |
6036 | |
6037 | if (what.is_longjmp) | |
6038 | { | |
6039 | - if (!gdbarch_get_longjmp_target_p (gdbarch) | |
6040 | - || !gdbarch_get_longjmp_target (gdbarch, | |
6041 | - frame, &jmp_buf_pc)) | |
6042 | + struct value *arg_value; | |
6043 | + | |
6044 | + /* If we set the longjmp breakpoint via a SystemTap probe, | |
6045 | + then use it to extract the arguments. The destination | |
6046 | + PC is the third argument to the probe. */ | |
6047 | + arg_value = stap_safe_evaluate_at_pc (frame, 2); | |
6048 | + if (arg_value) | |
6049 | + jmp_buf_pc = value_as_address (arg_value); | |
6050 | + else if (!gdbarch_get_longjmp_target_p (gdbarch) | |
6051 | + || !gdbarch_get_longjmp_target (gdbarch, | |
6052 | + frame, &jmp_buf_pc)) | |
6053 | { | |
6054 | if (debug_infrun) | |
6055 | fprintf_unfiltered (gdb_stdlog, | |
f412e1b4 | 6056 | @@ -4437,12 +4447,7 @@ process_event_stop_test: |
6ed6bacf | 6057 | insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc); |
3a58abaf AM |
6058 | } |
6059 | else | |
6ed6bacf AM |
6060 | - { |
6061 | - struct symbol *func = get_frame_function (frame); | |
6062 | - | |
6063 | - if (func) | |
6064 | - check_exception_resume (ecs, frame, func); | |
6065 | - } | |
6066 | + check_exception_resume (ecs, frame); | |
6067 | keep_going (ecs); | |
6068 | return; | |
3a58abaf | 6069 | |
f412e1b4 | 6070 | @@ -5524,15 +5529,65 @@ insert_exception_resume_breakpoint (struct thread_info *tp, |
3a58abaf | 6071 | } |
6ed6bacf | 6072 | } |
3a58abaf | 6073 | |
6ed6bacf AM |
6074 | +/* A helper for check_exception_resume that sets an |
6075 | + exception-breakpoint based on a SystemTap probe. */ | |
3a58abaf | 6076 | + |
6ed6bacf AM |
6077 | +static void |
6078 | +insert_exception_resume_from_probe (struct thread_info *tp, | |
6079 | + const struct stap_probe *probe, | |
6080 | + struct objfile *objfile, | |
6081 | + struct frame_info *frame) | |
6082 | +{ | |
6083 | + struct value *arg_value; | |
6084 | + CORE_ADDR handler; | |
6085 | + struct breakpoint *bp; | |
3a58abaf | 6086 | + |
6ed6bacf AM |
6087 | + arg_value = stap_safe_evaluate_at_pc (frame, 1); |
6088 | + if (!arg_value) | |
6089 | + return; | |
3a58abaf | 6090 | + |
6ed6bacf | 6091 | + handler = value_as_address (arg_value); |
3a58abaf | 6092 | + |
6ed6bacf AM |
6093 | + if (debug_infrun) |
6094 | + fprintf_unfiltered (gdb_stdlog, | |
6095 | + "infrun: exception resume at %s\n", | |
6096 | + paddress (get_objfile_arch (objfile), | |
6097 | + handler)); | |
7566401a | 6098 | + |
6ed6bacf AM |
6099 | + bp = set_momentary_breakpoint_at_pc (get_frame_arch (frame), |
6100 | + handler, bp_exception_resume); | |
6101 | + bp->thread = tp->num; | |
6102 | + inferior_thread ()->control.exception_resume_breakpoint = bp; | |
6103 | +} | |
51a5ef0f | 6104 | + |
6ed6bacf AM |
6105 | /* This is called when an exception has been intercepted. Check to |
6106 | see whether the exception's destination is of interest, and if so, | |
6107 | set an exception resume breakpoint there. */ | |
3a58abaf | 6108 | |
6ed6bacf AM |
6109 | static void |
6110 | check_exception_resume (struct execution_control_state *ecs, | |
6111 | - struct frame_info *frame, struct symbol *func) | |
6112 | + struct frame_info *frame) | |
6113 | { | |
f412e1b4 | 6114 | volatile struct gdb_exception e; |
6ed6bacf AM |
6115 | + struct objfile *objfile; |
6116 | + const struct stap_probe *probe; | |
6117 | + struct symbol *func; | |
7566401a | 6118 | + |
6ed6bacf AM |
6119 | + /* First see if this exception unwinding breakpoint was set via a |
6120 | + SystemTap probe point. If so, the probe has two arguments: the | |
6121 | + CFA and the HANDLER. We ignore the CFA, extract the handler, and | |
6122 | + set a breakpoint there. */ | |
6123 | + probe = find_probe_by_pc (get_frame_pc (frame), &objfile); | |
6124 | + if (probe) | |
6125 | + { | |
6126 | + insert_exception_resume_from_probe (ecs->event_thread, probe, | |
6127 | + objfile, frame); | |
6128 | + return; | |
6129 | + } | |
6130 | + | |
6131 | + func = get_frame_function (frame); | |
6132 | + if (!func) | |
6133 | + return; | |
51a5ef0f | 6134 | |
6ed6bacf AM |
6135 | TRY_CATCH (e, RETURN_MASK_ERROR) |
6136 | { | |
f412e1b4 | 6137 | @@ -6564,7 +6619,8 @@ static const struct lval_funcs siginfo_value_funcs = |
6ed6bacf | 6138 | if there's no object available. */ |
51a5ef0f | 6139 | |
6ed6bacf AM |
6140 | static struct value * |
6141 | -siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var) | |
6142 | +siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var, | |
6143 | + void *ignore) | |
6144 | { | |
6145 | if (target_has_stack | |
6146 | && !ptid_equal (inferior_ptid, null_ptid) | |
f412e1b4 | 6147 | @@ -7059,6 +7115,15 @@ show_schedule_multiple (struct ui_file *file, int from_tty, |
6ed6bacf AM |
6148 | "of all processes is %s.\n"), value); |
6149 | } | |
51a5ef0f | 6150 | |
6ed6bacf | 6151 | +/* Implementation of `siginfo' variable. */ |
3a58abaf | 6152 | + |
6ed6bacf AM |
6153 | +static const struct internalvar_funcs siginfo_funcs = |
6154 | +{ | |
6155 | + siginfo_make_value, | |
6156 | + NULL, | |
6157 | + NULL | |
6158 | +}; | |
6159 | + | |
6160 | void | |
6161 | _initialize_infrun (void) | |
6162 | { | |
f412e1b4 | 6163 | @@ -7347,7 +7412,7 @@ enabled by default on some platforms."), |
6ed6bacf AM |
6164 | value with a void typed value, and when we get here, gdbarch |
6165 | isn't initialized yet. At this point, we're quite sure there | |
6166 | isn't another convenience variable of the same name. */ | |
6167 | - create_internalvar_type_lazy ("_siginfo", siginfo_make_value); | |
6168 | + create_internalvar_type_lazy ("_siginfo", &siginfo_funcs, NULL); | |
6169 | ||
6170 | add_setshow_boolean_cmd ("observer", no_class, | |
6171 | &observer_mode_1, _("\ | |
f412e1b4 PS |
6172 | diff --git a/gdb/linespec.c b/gdb/linespec.c |
6173 | index 0782c54..31bb36c 100644 | |
6174 | --- a/gdb/linespec.c | |
6175 | +++ b/gdb/linespec.c | |
6176 | @@ -43,6 +43,7 @@ | |
6ed6bacf | 6177 | #include "cli/cli-utils.h" |
f412e1b4 PS |
6178 | #include "filenames.h" |
6179 | #include "ada-lang.h" | |
6ed6bacf AM |
6180 | +#include "stap-probe.h" |
6181 | ||
f412e1b4 PS |
6182 | typedef struct symtab *symtab_p; |
6183 | DEF_VEC_P (symtab_p); | |
6184 | @@ -802,6 +803,7 @@ keep_name_info (char *p, int on_boundary) | |
6ed6bacf AM |
6185 | PC returned is 0. |
6186 | FILE:FUNCTION -- likewise, but prefer functions in that file. | |
6187 | *EXPR -- line in which address EXPR appears. | |
f412e1b4 | 6188 | + -p [OBJFILE:][PROVIDER:]NAME -- a systemtap static probe |
6ed6bacf AM |
6189 | |
6190 | This may all be followed by an "if EXPR", which we ignore. | |
6191 | ||
f412e1b4 PS |
6192 | @@ -872,6 +874,9 @@ decode_line_internal (struct linespec_state *self, char **argptr) |
6193 | return decode_indirect (self, argptr); | |
6194 | } | |
6ed6bacf | 6195 | |
f412e1b4 PS |
6196 | + if (strncmp (*argptr, "-p", 2) == 0 && isspace ((*argptr)[2])) |
6197 | + return parse_stap_probe (argptr, self->canonical); | |
6ed6bacf AM |
6198 | + |
6199 | is_quoted = (strchr (get_gdb_completer_quote_characters (), | |
6200 | **argptr) != NULL); | |
6201 | ||
f412e1b4 PS |
6202 | diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c |
6203 | index 50d4efd..893b7c4 100644 | |
6204 | --- a/gdb/linux-nat.c | |
6205 | +++ b/gdb/linux-nat.c | |
6206 | @@ -288,6 +288,7 @@ static void restore_child_signals_mask (sigset_t *prev_mask); | |
6207 | struct lwp_info; | |
6208 | static struct lwp_info *add_lwp (ptid_t ptid); | |
6209 | static void purge_lwp_list (int pid); | |
6210 | +static void delete_lwp (ptid_t ptid); | |
6211 | static struct lwp_info *find_lwp_pid (ptid_t ptid); | |
6212 | ||
6213 | \f | |
6214 | @@ -584,6 +585,31 @@ linux_child_post_startup_inferior (ptid_t ptid) | |
6215 | linux_enable_tracesysgood (ptid); | |
51a5ef0f PS |
6216 | } |
6217 | ||
f412e1b4 | 6218 | +/* Return the number of known LWPs in the tgid given by PID. */ |
6ed6bacf AM |
6219 | + |
6220 | +static int | |
f412e1b4 | 6221 | +num_lwps (int pid) |
7566401a | 6222 | +{ |
f412e1b4 PS |
6223 | + int count = 0; |
6224 | + struct lwp_info *lp; | |
7566401a | 6225 | + |
f412e1b4 PS |
6226 | + for (lp = lwp_list; lp; lp = lp->next) |
6227 | + if (ptid_get_pid (lp->ptid) == pid) | |
6228 | + count++; | |
6229 | + | |
6230 | + return count; | |
6231 | +} | |
7566401a | 6232 | + |
f412e1b4 | 6233 | +/* Call delete_lwp with prototype compatible for make_cleanup. */ |
7566401a | 6234 | + |
f412e1b4 PS |
6235 | +static void |
6236 | +delete_lwp_cleanup (void *lp_voidp) | |
6237 | +{ | |
6238 | + struct lwp_info *lp = lp_voidp; | |
6239 | + | |
6240 | + delete_lwp (lp->ptid); | |
3a58abaf AM |
6241 | +} |
6242 | + | |
f412e1b4 PS |
6243 | static int |
6244 | linux_child_follow_fork (struct target_ops *ops, int follow_child) | |
6245 | { | |
6246 | @@ -630,6 +656,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \ | |
6247 | /* Detach new forked process? */ | |
6248 | if (detach_fork) | |
6249 | { | |
6250 | + struct cleanup *old_chain; | |
6251 | + | |
6252 | /* Before detaching from the child, remove all breakpoints | |
6253 | from it. If we forked, then this has already been taken | |
6254 | care of by infrun.c. If we vforked however, any | |
6255 | @@ -652,7 +680,28 @@ holding the child stopped. Try \"set detach-on-fork\" or \ | |
6256 | child_pid); | |
6257 | } | |
6258 | ||
6259 | + old_chain = save_inferior_ptid (); | |
6260 | + inferior_ptid = ptid_build (child_pid, child_pid, 0); | |
6261 | + | |
6262 | + child_lp = add_lwp (inferior_ptid); | |
6263 | + child_lp->stopped = 1; | |
6264 | + child_lp->last_resume_kind = resume_stop; | |
6265 | + make_cleanup (delete_lwp_cleanup, child_lp); | |
6266 | + | |
6267 | + /* CHILD_LP has new PID, therefore linux_nat_new_thread is not called for it. | |
6268 | + See i386_inferior_data_get for the Linux kernel specifics. | |
6269 | + Ensure linux_nat_prepare_to_resume will reset the hardware debug | |
6270 | + registers. It is done by the linux_nat_new_thread call, which is | |
6271 | + being skipped in add_lwp above for the first lwp of a pid. */ | |
6272 | + gdb_assert (num_lwps (GET_PID (child_lp->ptid)) == 1); | |
6273 | + if (linux_nat_new_thread != NULL) | |
6274 | + linux_nat_new_thread (child_lp); | |
6275 | + | |
6276 | + if (linux_nat_prepare_to_resume != NULL) | |
6277 | + linux_nat_prepare_to_resume (child_lp); | |
6278 | ptrace (PTRACE_DETACH, child_pid, 0, 0); | |
3a58abaf | 6279 | + |
f412e1b4 PS |
6280 | + do_cleanups (old_chain); |
6281 | } | |
6282 | else | |
6283 | { | |
6284 | @@ -670,6 +719,9 @@ holding the child stopped. Try \"set detach-on-fork\" or \ | |
6285 | save_current_program_space (); | |
6286 | ||
6287 | inferior_ptid = ptid_build (child_pid, child_pid, 0); | |
6288 | + reinit_frame_cache (); | |
6289 | + registers_changed (); | |
6290 | + | |
6291 | add_thread (inferior_ptid); | |
6292 | child_lp = add_lwp (inferior_ptid); | |
6293 | child_lp->stopped = 1; | |
6294 | @@ -861,6 +913,9 @@ holding the child stopped. Try \"set detach-on-fork\" or \ | |
6295 | informing the solib layer about this new process. */ | |
6296 | ||
6297 | inferior_ptid = ptid_build (child_pid, child_pid, 0); | |
6298 | + reinit_frame_cache (); | |
6299 | + registers_changed (); | |
6300 | + | |
6301 | add_thread (inferior_ptid); | |
6302 | child_lp = add_lwp (inferior_ptid); | |
6303 | child_lp->stopped = 1; | |
6304 | @@ -1111,21 +1166,6 @@ purge_lwp_list (int pid) | |
6305 | } | |
6306 | } | |
6307 | ||
6308 | -/* Return the number of known LWPs in the tgid given by PID. */ | |
6309 | - | |
6310 | -static int | |
6311 | -num_lwps (int pid) | |
6312 | -{ | |
6313 | - int count = 0; | |
6314 | - struct lwp_info *lp; | |
6315 | - | |
6316 | - for (lp = lwp_list; lp; lp = lp->next) | |
6317 | - if (ptid_get_pid (lp->ptid) == pid) | |
6318 | - count++; | |
6319 | - | |
6320 | - return count; | |
6321 | -} | |
6322 | - | |
6323 | /* Add the LWP specified by PID to the list. Return a pointer to the | |
6324 | structure describing the new LWP. The LWP should already be stopped | |
6325 | (with an exception for the very first LWP). */ | |
6326 | @@ -1235,6 +1275,46 @@ iterate_over_lwps (ptid_t filter, | |
6327 | return NULL; | |
6328 | } | |
6329 | ||
6330 | +/* Iterate like iterate_over_lwps does except when forking-off a child call | |
6331 | + CALLBACK with CALLBACK_DATA specifically only for that new child PID. */ | |
6ed6bacf AM |
6332 | + |
6333 | +void | |
6334 | +linux_nat_iterate_watchpoint_lwps | |
6335 | + (linux_nat_iterate_watchpoint_lwps_ftype callback, void *callback_data) | |
3a58abaf | 6336 | +{ |
6ed6bacf AM |
6337 | + int inferior_pid = ptid_get_pid (inferior_ptid); |
6338 | + struct inferior *inf = current_inferior (); | |
7566401a | 6339 | + |
6ed6bacf AM |
6340 | + if (inf->pid == inferior_pid) |
6341 | + { | |
f412e1b4 PS |
6342 | + /* Iterate all the threads of the current inferior. Without specifying |
6343 | + INFERIOR_PID it would iterate all threads of all inferiors, which is | |
6344 | + inappropriate for watchpoints. */ | |
6ed6bacf | 6345 | + |
f412e1b4 | 6346 | + iterate_over_lwps (pid_to_ptid (inferior_pid), callback, callback_data); |
6ed6bacf AM |
6347 | + } |
6348 | + else | |
6349 | + { | |
6350 | + /* Detaching a new child PID temporarily present in INFERIOR_PID. */ | |
6351 | + | |
f412e1b4 PS |
6352 | + struct lwp_info *child_lp; |
6353 | + struct cleanup *old_chain; | |
6354 | + pid_t child_pid = GET_PID (inferior_ptid); | |
6355 | + ptid_t child_ptid = ptid_build (child_pid, child_pid, 0); | |
6356 | + | |
6357 | + gdb_assert (!is_lwp (inferior_ptid)); | |
6358 | + gdb_assert (find_lwp_pid (child_ptid) == NULL); | |
6359 | + child_lp = add_lwp (child_ptid); | |
6360 | + child_lp->stopped = 1; | |
6361 | + child_lp->last_resume_kind = resume_stop; | |
6362 | + old_chain = make_cleanup (delete_lwp_cleanup, child_lp); | |
6363 | + | |
6364 | + callback (child_lp, callback_data); | |
6365 | + | |
6366 | + do_cleanups (old_chain); | |
6ed6bacf | 6367 | + } |
7566401a ER |
6368 | +} |
6369 | + | |
6ed6bacf AM |
6370 | /* Update our internal state when changing from one checkpoint to |
6371 | another indicated by NEW_PTID. We can only switch single-threaded | |
6372 | applications, so we only create one new LWP, and the previous list | |
f412e1b4 PS |
6373 | diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h |
6374 | index d9dc71b..6217370 100644 | |
6375 | --- a/gdb/linux-nat.h | |
6376 | +++ b/gdb/linux-nat.h | |
6377 | @@ -158,6 +158,12 @@ struct lwp_info *iterate_over_lwps (ptid_t filter, | |
6ed6bacf AM |
6378 | void *), |
6379 | void *data); | |
3a58abaf | 6380 | |
f412e1b4 PS |
6381 | +typedef int (*linux_nat_iterate_watchpoint_lwps_ftype) (struct lwp_info *lwp, |
6382 | + void *arg); | |
6ed6bacf AM |
6383 | + |
6384 | +extern void linux_nat_iterate_watchpoint_lwps | |
6385 | + (linux_nat_iterate_watchpoint_lwps_ftype callback, void *callback_data); | |
6386 | + | |
6387 | /* Create a prototype generic GNU/Linux target. The client can | |
6388 | override it with local methods. */ | |
6389 | struct target_ops * linux_target (void); | |
f412e1b4 PS |
6390 | diff --git a/gdb/machoread.c b/gdb/machoread.c |
6391 | index 9fa97e1..d6f0f38 100644 | |
6392 | --- a/gdb/machoread.c | |
6393 | +++ b/gdb/machoread.c | |
6394 | @@ -1032,6 +1032,7 @@ static const struct sym_fns macho_sym_fns = { | |
6ed6bacf AM |
6395 | default_symfile_segments, /* Get segment information from a file. */ |
6396 | NULL, | |
6397 | macho_symfile_relocate, /* Relocate a debug section. */ | |
6398 | + NULL, /* sym_get_probes */ | |
6399 | &psym_functions | |
6400 | }; | |
3a58abaf | 6401 | |
f412e1b4 PS |
6402 | diff --git a/gdb/main.c b/gdb/main.c |
6403 | index 8b45c25..c7ea0df 100644 | |
6404 | --- a/gdb/main.c | |
6405 | +++ b/gdb/main.c | |
6406 | @@ -37,6 +37,7 @@ | |
3a58abaf | 6407 | |
6ed6bacf AM |
6408 | #include "interps.h" |
6409 | #include "main.h" | |
6410 | +#include "python/python.h" | |
6411 | #include "source.h" | |
6412 | #include "cli/cli-cmds.h" | |
6413 | #include "python/python.h" | |
f412e1b4 | 6414 | @@ -264,6 +265,8 @@ captured_main (void *data) |
6ed6bacf AM |
6415 | char *cdarg = NULL; |
6416 | char *ttyarg = NULL; | |
3a58abaf | 6417 | |
6ed6bacf | 6418 | + int python_script = 0; |
3a58abaf | 6419 | + |
6ed6bacf AM |
6420 | /* These are static so that we can take their address in an |
6421 | initializer. */ | |
6422 | static int print_help; | |
f412e1b4 | 6423 | @@ -457,10 +460,14 @@ captured_main (void *data) |
6ed6bacf AM |
6424 | {"args", no_argument, &set_args, 1}, |
6425 | {"l", required_argument, 0, 'l'}, | |
6426 | {"return-child-result", no_argument, &return_child_result, 1}, | |
6427 | +#if HAVE_PYTHON | |
6428 | + {"python", no_argument, 0, 'P'}, | |
6429 | + {"P", no_argument, 0, 'P'}, | |
6430 | +#endif | |
6431 | {0, no_argument, 0, 0} | |
6432 | }; | |
3a58abaf | 6433 | |
6ed6bacf AM |
6434 | - while (1) |
6435 | + while (!python_script) | |
6436 | { | |
6437 | int option_index; | |
3a58abaf | 6438 | |
f412e1b4 | 6439 | @@ -478,6 +485,9 @@ captured_main (void *data) |
6ed6bacf AM |
6440 | case 0: |
6441 | /* Long option that just sets a flag. */ | |
6442 | break; | |
6443 | + case 'P': | |
6444 | + python_script = 1; | |
6445 | + break; | |
6446 | case OPT_SE: | |
6447 | symarg = optarg; | |
6448 | execarg = optarg; | |
f412e1b4 | 6449 | @@ -673,7 +683,31 @@ captured_main (void *data) |
6ed6bacf AM |
6450 | |
6451 | /* Now that gdb_init has created the initial inferior, we're in | |
6452 | position to set args for that inferior. */ | |
6453 | - if (set_args) | |
6454 | + if (python_script) | |
3a58abaf | 6455 | + { |
6ed6bacf AM |
6456 | + /* The first argument is a python script to evaluate, and |
6457 | + subsequent arguments are passed to the script for | |
6458 | + processing there. */ | |
6459 | + if (optind >= argc) | |
6460 | + { | |
6461 | + fprintf_unfiltered (gdb_stderr, | |
6462 | + _("%s: Python script file name required\n"), | |
6463 | + argv[0]); | |
6464 | + exit (1); | |
3a58abaf | 6465 | + } |
51a5ef0f | 6466 | + |
6ed6bacf AM |
6467 | + /* FIXME: should handle inferior I/O intelligently here. |
6468 | + E.g., should be possible to run gdb in pipeline and have | |
6469 | + Python (and gdb) output go to stderr or file; and if a | |
6470 | + prompt is needed, open the tty. */ | |
6471 | + quiet = 1; | |
6472 | + /* FIXME: should read .gdbinit if, and only if, a prompt is | |
6473 | + requested by the script. Though... maybe this is not | |
6474 | + ideal? */ | |
6475 | + /* FIXME: likewise, reading in history. */ | |
6476 | + inhibit_gdbinit = 1; | |
51a5ef0f | 6477 | + } |
6ed6bacf AM |
6478 | + else if (set_args) |
6479 | { | |
6480 | /* The remaining options are the command-line options for the | |
6481 | inferior. The first one is the sym/exec file, and the rest | |
f412e1b4 | 6482 | @@ -922,7 +956,8 @@ captured_main (void *data) |
3a58abaf | 6483 | |
6ed6bacf AM |
6484 | /* Read in the old history after all the command files have been |
6485 | read. */ | |
6486 | - init_history (); | |
6487 | + if (!python_script) | |
6488 | + init_history (); | |
3a58abaf | 6489 | |
6ed6bacf | 6490 | if (batch_flag) |
3a58abaf | 6491 | { |
f412e1b4 | 6492 | @@ -933,13 +968,25 @@ captured_main (void *data) |
6ed6bacf AM |
6493 | /* Show time and/or space usage. */ |
6494 | do_cleanups (pre_stat_chain); | |
3a58abaf | 6495 | |
6ed6bacf AM |
6496 | - /* NOTE: cagney/1999-11-07: There is probably no reason for not |
6497 | - moving this loop and the code found in captured_command_loop() | |
6498 | - into the command_loop() proper. The main thing holding back that | |
6499 | - change - SET_TOP_LEVEL() - has been eliminated. */ | |
6500 | - while (1) | |
6501 | +#if HAVE_PYTHON | |
6502 | + if (python_script) | |
6503 | { | |
6504 | - catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); | |
6505 | + extern int pagination_enabled; | |
6506 | + pagination_enabled = 0; | |
6507 | + run_python_script (argc - optind, &argv[optind]); | |
6508 | + return 1; | |
6509 | + } | |
6510 | + else | |
6511 | +#endif | |
6512 | + { | |
6513 | + /* NOTE: cagney/1999-11-07: There is probably no reason for not | |
6514 | + moving this loop and the code found in captured_command_loop() | |
6515 | + into the command_loop() proper. The main thing holding back that | |
6516 | + change - SET_TOP_LEVEL() - has been eliminated. */ | |
6517 | + while (1) | |
6518 | + { | |
6519 | + catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); | |
6520 | + } | |
3a58abaf | 6521 | } |
6ed6bacf | 6522 | /* No exit -- exit is through quit_command. */ |
3a58abaf | 6523 | } |
f412e1b4 | 6524 | @@ -971,7 +1018,12 @@ print_gdb_help (struct ui_file *stream) |
6ed6bacf AM |
6525 | fputs_unfiltered (_("\ |
6526 | This is the GNU debugger. Usage:\n\n\ | |
6527 | gdb [options] [executable-file [core-file or process-id]]\n\ | |
6528 | - gdb [options] --args executable-file [inferior-arguments ...]\n\n\ | |
6529 | + gdb [options] --args executable-file [inferior-arguments ...]\n"), stream); | |
6530 | +#if HAVE_PYTHON | |
6531 | + fputs_unfiltered (_("\ | |
6532 | + gdb [options] [--python|-P] script-file [script-arguments ...]\n"), stream); | |
6533 | +#endif | |
6534 | + fputs_unfiltered (_("\n\ | |
6535 | Options:\n\n\ | |
6536 | "), stream); | |
6537 | fputs_unfiltered (_("\ | |
f412e1b4 | 6538 | @@ -1009,7 +1061,13 @@ Options:\n\n\ |
6ed6bacf AM |
6539 | --nw Do not use a window interface.\n\ |
6540 | --nx Do not read "), stream); | |
6541 | fputs_unfiltered (gdbinit, stream); | |
6542 | - fputs_unfiltered (_(" file.\n\ | |
6543 | + fputs_unfiltered (_(" file.\n"), stream); | |
6544 | +#if HAVE_PYTHON | |
6545 | + fputs_unfiltered (_("\ | |
6546 | + --python, -P Following argument is Python script file; remaining\n\ | |
6547 | + arguments are passed to script.\n"), stream); | |
6548 | +#endif | |
6549 | + fputs_unfiltered (_("\ | |
6550 | --quiet Do not print version number on startup.\n\ | |
6551 | --readnow Fully read symbol files on first access.\n\ | |
6552 | "), stream); | |
f412e1b4 PS |
6553 | diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c |
6554 | index 4de7392..fb0b550 100644 | |
6555 | --- a/gdb/mi/mi-cmd-var.c | |
6556 | +++ b/gdb/mi/mi-cmd-var.c | |
6557 | @@ -721,7 +721,6 @@ mi_cmd_var_update (char *command, char **argv, int argc) | |
6ed6bacf AM |
6558 | } |
6559 | else | |
6560 | { | |
6561 | - /* Get varobj handle, if a valid var obj name was specified */ | |
6562 | struct varobj *var = varobj_get_handle (name); | |
3a58abaf | 6563 | |
6ed6bacf | 6564 | varobj_update_one (var, print_values, 1 /* explicit */); |
f412e1b4 PS |
6565 | diff --git a/gdb/mipsread.c b/gdb/mipsread.c |
6566 | index 5790730..23ceece 100644 | |
6567 | --- a/gdb/mipsread.c | |
6568 | +++ b/gdb/mipsread.c | |
6569 | @@ -401,6 +401,7 @@ static const struct sym_fns ecoff_sym_fns = | |
6ed6bacf AM |
6570 | default_symfile_segments, /* Get segment information from a file. */ |
6571 | NULL, | |
6572 | default_symfile_relocate, /* Relocate a debug section. */ | |
6573 | + NULL, /* sym_probe_fns */ | |
6574 | &psym_functions | |
6575 | }; | |
3a58abaf | 6576 | |
f412e1b4 PS |
6577 | diff --git a/gdb/objfiles.c b/gdb/objfiles.c |
6578 | index 1cf5aee..d1640ef 100644 | |
6579 | --- a/gdb/objfiles.c | |
6580 | +++ b/gdb/objfiles.c | |
6581 | @@ -811,6 +811,11 @@ objfile_relocate1 (struct objfile *objfile, | |
6ed6bacf AM |
6582 | obj_section_addr (s)); |
6583 | } | |
3a58abaf | 6584 | |
6ed6bacf AM |
6585 | + /* Relocating SystemTap probes. */ |
6586 | + if (objfile->sf && objfile->sf->sym_probe_fns) | |
6587 | + objfile->sf->sym_probe_fns->sym_relocate_probe (objfile, | |
6588 | + new_offsets, delta); | |
6589 | + | |
6590 | /* Data changed. */ | |
6591 | return 1; | |
6592 | } | |
f412e1b4 PS |
6593 | diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c |
6594 | index c5bef8a..fc3beb3 100644 | |
6595 | --- a/gdb/p-valprint.c | |
6596 | +++ b/gdb/p-valprint.c | |
6ed6bacf AM |
6597 | @@ -39,6 +39,7 @@ |
6598 | #include "cp-abi.h" | |
6599 | #include "cp-support.h" | |
6600 | #include "exceptions.h" | |
6601 | +#include "dwarf2loc.h" | |
6602 | \f | |
3a58abaf | 6603 | |
6ed6bacf | 6604 | /* See val_print for a description of the various parameters of this |
f412e1b4 | 6605 | @@ -63,8 +64,31 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, |
6ed6bacf AM |
6606 | struct type *char_type; |
6607 | LONGEST val; | |
6608 | CORE_ADDR addr; | |
6609 | + struct cleanup *back_to; | |
6610 | + struct type *saved_type = type; | |
6611 | + CORE_ADDR saved_address = address; | |
6612 | + | |
6613 | + back_to = make_cleanup (null_cleanup, 0); | |
6614 | + address += embedded_offset; | |
6615 | + type = object_address_get_data (type, &address); | |
6616 | + if (type == NULL) | |
3a58abaf | 6617 | + { |
6ed6bacf AM |
6618 | + fputs_filtered (object_address_data_not_valid (saved_type), stream); |
6619 | + gdb_flush (stream); | |
6620 | + do_cleanups (back_to); | |
6621 | + return 0; | |
3a58abaf | 6622 | + } |
6ed6bacf | 6623 | + if (address != saved_address + embedded_offset) |
3a58abaf | 6624 | + { |
6ed6bacf AM |
6625 | + size_t length = TYPE_LENGTH (type); |
6626 | ||
6627 | - CHECK_TYPEDEF (type); | |
6628 | + valaddr = xmalloc (length); | |
6629 | + make_cleanup (xfree, (gdb_byte *) valaddr); | |
6630 | + read_memory (address, (gdb_byte *) valaddr, length); | |
6631 | + embedded_offset = 0; | |
3a58abaf | 6632 | + } |
6ed6bacf AM |
6633 | + else |
6634 | + address -= embedded_offset; | |
6635 | switch (TYPE_CODE (type)) | |
6636 | { | |
6637 | case TYPE_CODE_ARRAY: | |
f412e1b4 | 6638 | @@ -120,8 +144,8 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, |
6ed6bacf AM |
6639 | { |
6640 | i = 0; | |
6641 | } | |
6642 | - val_print_array_elements (type, valaddr, embedded_offset, | |
6643 | - address, stream, recurse, | |
6644 | + val_print_array_elements (saved_type, valaddr, embedded_offset, | |
6645 | + saved_address, stream, recurse, | |
6646 | original_value, options, i); | |
6647 | fprintf_filtered (stream, "}"); | |
6648 | } | |
f412e1b4 | 6649 | @@ -160,6 +184,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, |
6ed6bacf AM |
6650 | /* Try to print what function it points to. */ |
6651 | print_address_demangle (gdbarch, addr, stream, demangle); | |
6652 | /* Return value is irrelevant except for string pointers. */ | |
6653 | + do_cleanups (back_to); | |
6654 | return (0); | |
6655 | } | |
6656 | ||
f412e1b4 | 6657 | @@ -251,6 +276,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, |
6ed6bacf AM |
6658 | /* Return number of characters printed, including the terminating |
6659 | '\0' if we reached the end. val_print_string takes care including | |
6660 | the terminating '\0' if necessary. */ | |
6661 | + do_cleanups (back_to); | |
6662 | return i; | |
6663 | ||
6664 | break; | |
f412e1b4 | 6665 | @@ -576,6 +602,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, |
6ed6bacf AM |
6666 | TYPE_CODE (type)); |
6667 | } | |
6668 | gdb_flush (stream); | |
6669 | + do_cleanups (back_to); | |
6670 | return (0); | |
3a58abaf | 6671 | } |
6ed6bacf | 6672 | \f |
f412e1b4 PS |
6673 | diff --git a/gdb/parse.c b/gdb/parse.c |
6674 | index 32a3bd6..9eaf2de 100644 | |
6675 | --- a/gdb/parse.c | |
6676 | +++ b/gdb/parse.c | |
6677 | @@ -113,8 +113,6 @@ show_parserdebug (struct ui_file *file, int from_tty, | |
6678 | ||
6679 | static void free_funcalls (void *ignore); | |
6680 | ||
6681 | -static int prefixify_expression (struct expression *); | |
6682 | - | |
6683 | static int prefixify_subexp (struct expression *, struct expression *, int, | |
6684 | int); | |
6685 | ||
6686 | @@ -188,7 +186,7 @@ free_funcalls (void *ignore) | |
6687 | the expout array. LANG is the language used to parse the expression. | |
6688 | And GDBARCH is the gdbarch to use during parsing. */ | |
6689 | ||
6690 | -static void | |
6691 | +void | |
6692 | initialize_expout (int initial_size, const struct language_defn *lang, | |
6693 | struct gdbarch *gdbarch) | |
6694 | { | |
6695 | @@ -204,7 +202,7 @@ initialize_expout (int initial_size, const struct language_defn *lang, | |
6696 | It is generally used when the parser has just been parsed and | |
6697 | created. */ | |
6698 | ||
6699 | -static void | |
6700 | +void | |
6701 | reallocate_expout (void) | |
6702 | { | |
6703 | /* Record the actual number of expression elements, and then | |
6704 | @@ -811,7 +809,7 @@ copy_name (struct stoken token) | |
6705 | return the index of the subexpression which is the left-hand-side | |
6706 | of the struct operation at EXPOUT_LAST_STRUCT. */ | |
6707 | ||
6708 | -static int | |
6709 | +int | |
6710 | prefixify_expression (struct expression *expr) | |
6711 | { | |
6712 | int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts); | |
6713 | @@ -1529,6 +1527,7 @@ parser_fprintf (FILE *x, const char *y, ...) | |
3a58abaf | 6714 | |
6ed6bacf AM |
6715 | int |
6716 | operator_check_standard (struct expression *exp, int pos, | |
6717 | + int (*type_func) (struct type *type, void *data), | |
6718 | int (*objfile_func) (struct objfile *objfile, | |
6719 | void *data), | |
6720 | void *data) | |
f412e1b4 | 6721 | @@ -1570,7 +1569,7 @@ operator_check_standard (struct expression *exp, int pos, |
6ed6bacf AM |
6722 | struct type *type = elts[pos + 2 + arg].type; |
6723 | struct objfile *objfile = TYPE_OBJFILE (type); | |
3a58abaf | 6724 | |
6ed6bacf AM |
6725 | - if (objfile && (*objfile_func) (objfile, data)) |
6726 | + if (objfile && objfile_func && (*objfile_func) (objfile, data)) | |
6727 | return 1; | |
6728 | } | |
6729 | } | |
f412e1b4 | 6730 | @@ -1588,7 +1587,8 @@ operator_check_standard (struct expression *exp, int pos, |
3a58abaf | 6731 | |
6ed6bacf AM |
6732 | /* Check objfile where the variable itself is placed. |
6733 | SYMBOL_OBJ_SECTION (symbol) may be NULL. */ | |
6734 | - if ((*objfile_func) (SYMBOL_SYMTAB (symbol)->objfile, data)) | |
6735 | + if (objfile_func | |
6736 | + && (*objfile_func) (SYMBOL_SYMTAB (symbol)->objfile, data)) | |
6737 | return 1; | |
3a58abaf | 6738 | |
6ed6bacf | 6739 | /* Check objfile where is placed the code touching the variable. */ |
f412e1b4 | 6740 | @@ -1601,24 +1601,27 @@ operator_check_standard (struct expression *exp, int pos, |
3a58abaf | 6741 | |
6ed6bacf | 6742 | /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL. */ |
3a58abaf | 6743 | |
6ed6bacf AM |
6744 | - if (type && TYPE_OBJFILE (type) |
6745 | + if (type && type_func && (*type_func) (type, data)) | |
6746 | + return 1; | |
6747 | + if (type && TYPE_OBJFILE (type) && objfile_func | |
6748 | && (*objfile_func) (TYPE_OBJFILE (type), data)) | |
6749 | return 1; | |
6750 | - if (objfile && (*objfile_func) (objfile, data)) | |
6751 | + if (objfile && objfile_func && (*objfile_func) (objfile, data)) | |
6752 | return 1; | |
6753 | ||
6754 | return 0; | |
6755 | } | |
6756 | ||
6757 | -/* Call OBJFILE_FUNC for any TYPE and OBJFILE found being referenced by EXP. | |
6758 | - The functions are never called with NULL OBJFILE. Functions get passed an | |
6759 | - arbitrary caller supplied DATA pointer. If any of the functions returns | |
6760 | - non-zero value then (any other) non-zero value is immediately returned to | |
6761 | - the caller. Otherwise zero is returned after iterating through whole EXP. | |
6762 | - */ | |
6763 | +/* Call TYPE_FUNC and OBJFILE_FUNC for any TYPE and OBJFILE found being | |
6764 | + referenced by EXP. The functions are never called with NULL TYPE or NULL | |
6765 | + OBJFILE. Functions get passed an arbitrary caller supplied DATA pointer. | |
6766 | + If any of the functions returns non-zero value then (any other) non-zero | |
6767 | + value is immediately returned to the caller. Otherwise zero is returned | |
6768 | + after iterating through whole EXP. */ | |
6769 | ||
6770 | static int | |
6771 | exp_iterate (struct expression *exp, | |
6772 | + int (*type_func) (struct type *type, void *data), | |
6773 | int (*objfile_func) (struct objfile *objfile, void *data), | |
6774 | void *data) | |
6775 | { | |
f412e1b4 | 6776 | @@ -1633,7 +1636,9 @@ exp_iterate (struct expression *exp, |
6ed6bacf AM |
6777 | |
6778 | pos = endpos - oplen; | |
6779 | if (exp->language_defn->la_exp_desc->operator_check (exp, pos, | |
6780 | - objfile_func, data)) | |
6781 | + type_func, | |
6782 | + objfile_func, | |
6783 | + data)) | |
6784 | return 1; | |
3a58abaf | 6785 | |
6ed6bacf | 6786 | endpos = pos; |
f412e1b4 | 6787 | @@ -1664,8 +1669,29 @@ exp_uses_objfile (struct expression *exp, struct objfile *objfile) |
6ed6bacf AM |
6788 | { |
6789 | gdb_assert (objfile->separate_debug_objfile_backlink == NULL); | |
6790 | ||
6791 | - return exp_iterate (exp, exp_uses_objfile_iter, objfile); | |
6792 | + return exp_iterate (exp, NULL, exp_uses_objfile_iter, objfile); | |
6793 | +} | |
3a58abaf | 6794 | + |
6ed6bacf | 6795 | +/* Helper for exp_types_mark_used. */ |
3a58abaf | 6796 | + |
6ed6bacf AM |
6797 | +#if 0 |
6798 | +static int | |
6799 | +exp_types_mark_used_iter (struct type *type, void *unused) | |
6800 | +{ | |
6801 | + type_mark_used (type); | |
3a58abaf | 6802 | + |
6ed6bacf AM |
6803 | + /* Continue the traversal. */ |
6804 | + return 0; | |
6805 | +} | |
3a58abaf | 6806 | + |
6ed6bacf | 6807 | +/* Call type_mark_used for any type contained in EXP. */ |
3a58abaf | 6808 | + |
6ed6bacf AM |
6809 | +void |
6810 | +exp_types_mark_used (struct expression *exp) | |
6811 | +{ | |
6812 | + exp_iterate (exp, exp_types_mark_used_iter, NULL, NULL); | |
6813 | } | |
6814 | +#endif | |
3a58abaf | 6815 | |
6ed6bacf AM |
6816 | void |
6817 | _initialize_parse (void) | |
f412e1b4 PS |
6818 | diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h |
6819 | index 16b40ac..c3813ff 100644 | |
6820 | --- a/gdb/parser-defs.h | |
6821 | +++ b/gdb/parser-defs.h | |
6822 | @@ -130,6 +130,24 @@ union type_stack_elt | |
6823 | extern union type_stack_elt *type_stack; | |
6824 | extern int type_stack_depth, type_stack_size; | |
6825 | ||
6826 | +/* Allocate and initialize `expout' and its related variables `expout_size' | |
6827 | + and `expout_ptr'. | |
6828 | + | |
6829 | + The first argument is the initial size to be used for xmalloc. The second | |
6830 | + argument is the language related to the expression. The third argument is | |
6831 | + corresponding gdbarch. */ | |
6832 | + | |
6833 | +extern void initialize_expout (int, const struct language_defn *, | |
6834 | + struct gdbarch *); | |
6835 | + | |
6836 | +/* Reallocate `expout' in order to free excessive elements that might have | |
6837 | + been created during the parsing. Set the number of elements | |
6838 | + accordingly. */ | |
6839 | + | |
6840 | +extern void reallocate_expout (void); | |
6841 | + | |
6842 | +extern int prefixify_expression (struct expression *expr); | |
6843 | + | |
6844 | extern void write_exp_elt_opcode (enum exp_opcode); | |
6845 | ||
6846 | extern void write_exp_elt_sym (struct symbol *); | |
6847 | @@ -191,6 +209,8 @@ extern void operator_length_standard (const struct expression *, int, int *, | |
6ed6bacf | 6848 | int *); |
3a58abaf | 6849 | |
6ed6bacf AM |
6850 | extern int operator_check_standard (struct expression *exp, int pos, |
6851 | + int (*type_func) (struct type *type, | |
6852 | + void *data), | |
6853 | int (*objfile_func) | |
6854 | (struct objfile *objfile, void *data), | |
6855 | void *data); | |
f412e1b4 | 6856 | @@ -277,6 +297,7 @@ struct exp_descriptor |
6ed6bacf AM |
6857 | value should be immediately returned to the caller. Otherwise zero |
6858 | should be returned. */ | |
6859 | int (*operator_check) (struct expression *exp, int pos, | |
6860 | + int (*type_func) (struct type *type, void *data), | |
6861 | int (*objfile_func) (struct objfile *objfile, | |
6862 | void *data), | |
6863 | void *data); | |
f412e1b4 | 6864 | @@ -315,4 +336,10 @@ extern void parser_fprintf (FILE *, const char *, ...) ATTRIBUTE_PRINTF (2, 3); |
6ed6bacf AM |
6865 | |
6866 | extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile); | |
6867 | ||
6868 | +extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile); | |
51a5ef0f | 6869 | + |
6ed6bacf AM |
6870 | +#if 0 |
6871 | +extern void exp_types_mark_used (struct expression *exp); | |
6872 | +#endif | |
51a5ef0f | 6873 | + |
6ed6bacf | 6874 | #endif /* PARSER_DEFS_H */ |
f412e1b4 PS |
6875 | diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c |
6876 | index af80919..3077c4b 100644 | |
6877 | --- a/gdb/ppc-linux-nat.c | |
6878 | +++ b/gdb/ppc-linux-nat.c | |
6879 | @@ -1468,14 +1468,13 @@ ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot) | |
6880 | if (!have_ptrace_booke_interface ()) | |
6881 | { | |
6882 | int tid; | |
6883 | - ptid_t ptid = inferior_ptid; | |
6884 | ||
6885 | /* We need to know whether ptrace supports PTRACE_SET_DEBUGREG | |
6886 | and whether the target has DABR. If either answer is no, the | |
6887 | ptrace call will return -1. Fail in that case. */ | |
6888 | - tid = TIDGET (ptid); | |
6889 | + tid = TIDGET (inferior_ptid); | |
6890 | if (tid == 0) | |
6891 | - tid = PIDGET (ptid); | |
6892 | + tid = PIDGET (inferior_ptid); | |
6893 | ||
6894 | if (ptrace (PTRACE_SET_DEBUGREG, tid, 0, 0) == -1) | |
6895 | return 0; | |
6896 | @@ -1566,8 +1565,9 @@ booke_find_thread_points_by_tid (int tid, int alloc_new) | |
6897 | /* This function is a generic wrapper that is responsible for inserting a | |
6898 | *point (i.e., calling `ptrace' in order to issue the request to the | |
6899 | kernel) and registering it internally in GDB. */ | |
6900 | + | |
6901 | static void | |
6902 | -booke_insert_point (struct ppc_hw_breakpoint *b, int tid) | |
6903 | +booke_insert_point (struct lwp_info *lp, struct ppc_hw_breakpoint *b) | |
6904 | { | |
6905 | int i; | |
6906 | long slot; | |
6907 | @@ -1580,12 +1580,12 @@ booke_insert_point (struct ppc_hw_breakpoint *b, int tid) | |
6908 | memcpy (p, b, sizeof (struct ppc_hw_breakpoint)); | |
6909 | ||
6910 | errno = 0; | |
6911 | - slot = ptrace (PPC_PTRACE_SETHWDEBUG, tid, 0, p); | |
6912 | + slot = ptrace (PPC_PTRACE_SETHWDEBUG, TIDGET (lp->ptid), 0, p); | |
6913 | if (slot < 0) | |
6914 | perror_with_name (_("Unexpected error setting breakpoint or watchpoint")); | |
6915 | ||
6916 | /* Everything went fine, so we have to register this *point. */ | |
6917 | - t = booke_find_thread_points_by_tid (tid, 1); | |
6918 | + t = booke_find_thread_points_by_tid (TIDGET (lp->ptid), 1); | |
6919 | gdb_assert (t != NULL); | |
6920 | hw_breaks = t->hw_breaks; | |
6921 | ||
6922 | @@ -1603,17 +1603,33 @@ booke_insert_point (struct ppc_hw_breakpoint *b, int tid) | |
6923 | discard_cleanups (c); | |
6ed6bacf AM |
6924 | } |
6925 | ||
f412e1b4 PS |
6926 | -/* This function is a generic wrapper that is responsible for removing a |
6927 | - *point (i.e., calling `ptrace' in order to issue the request to the | |
6928 | - kernel), and unregistering it internally at GDB. */ | |
6929 | -static void | |
6930 | -booke_remove_point (struct ppc_hw_breakpoint *b, int tid) | |
6931 | +/* Callback for linux_nat_iterate_watchpoint_lwps | |
6932 | + calling booke_insert_point. */ | |
6933 | + | |
6934 | +static int | |
6935 | +booke_insert_point_callback (struct lwp_info *lp, void *b_voidp) | |
6936 | { | |
6937 | + struct ppc_hw_breakpoint *b = b_voidp; | |
6938 | + | |
6939 | + booke_insert_point (lp, b); | |
51a5ef0f | 6940 | + |
f412e1b4 PS |
6941 | + /* Continue the traversal. */ |
6942 | + return 0; | |
6ed6bacf | 6943 | +} |
51a5ef0f | 6944 | + |
f412e1b4 PS |
6945 | +/* This function is a callback for linux_nat_iterate_watchpoint_lwps that is |
6946 | + responsible for removing a *point (i.e., calling `ptrace' in order to issue | |
6947 | + the request to the kernel), and unregistering it internally at GDB. */ | |
6948 | + | |
6949 | +static int | |
6950 | +booke_remove_point_callback (struct lwp_info *lp, void *b_voidp) | |
6951 | +{ | |
6952 | + struct ppc_hw_breakpoint *b = b_voidp; | |
6953 | int i; | |
6954 | struct hw_break_tuple *hw_breaks; | |
6955 | struct thread_points *t; | |
6ed6bacf | 6956 | |
f412e1b4 PS |
6957 | - t = booke_find_thread_points_by_tid (tid, 0); |
6958 | + t = booke_find_thread_points_by_tid (TIDGET (lp->ptid), 0); | |
6959 | gdb_assert (t != NULL); | |
6960 | hw_breaks = t->hw_breaks; | |
6961 | ||
6962 | @@ -1627,13 +1643,17 @@ booke_remove_point (struct ppc_hw_breakpoint *b, int tid) | |
6963 | breakpoints/watchpoints as "one-shot", that is, they are automatically | |
6964 | deleted when hit. */ | |
6965 | errno = 0; | |
6966 | - if (ptrace (PPC_PTRACE_DELHWDEBUG, tid, 0, hw_breaks[i].slot) < 0) | |
6967 | + if (ptrace (PPC_PTRACE_DELHWDEBUG, TIDGET (lp->ptid), 0, hw_breaks[i].slot) | |
6968 | + < 0) | |
6969 | if (errno != ENOENT) | |
6970 | perror_with_name (_("Unexpected error deleting " | |
6971 | "breakpoint or watchpoint")); | |
6972 | ||
6973 | xfree (hw_breaks[i].hw_break); | |
6974 | hw_breaks[i].hw_break = NULL; | |
6975 | + | |
6976 | + /* Continue the traversal. */ | |
6977 | + return 0; | |
6978 | } | |
6979 | ||
6980 | /* Return the number of registers needed for a ranged breakpoint. */ | |
6981 | @@ -1653,7 +1673,6 @@ static int | |
6ed6bacf AM |
6982 | ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch, |
6983 | struct bp_target_info *bp_tgt) | |
6984 | { | |
6ed6bacf AM |
6985 | - struct lwp_info *lp; |
6986 | struct ppc_hw_breakpoint p; | |
6987 | ||
6988 | if (!have_ptrace_booke_interface ()) | |
f412e1b4 | 6989 | @@ -1679,8 +1698,7 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch, |
6ed6bacf AM |
6990 | p.addr2 = 0; |
6991 | } | |
6992 | ||
f412e1b4 PS |
6993 | - ALL_LWPS (lp) |
6994 | - booke_insert_point (&p, TIDGET (lp->ptid)); | |
6ed6bacf AM |
6995 | + linux_nat_iterate_watchpoint_lwps (booke_insert_point_callback, &p); |
6996 | ||
6997 | return 0; | |
6998 | } | |
f412e1b4 | 6999 | @@ -1689,7 +1707,6 @@ static int |
6ed6bacf AM |
7000 | ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch, |
7001 | struct bp_target_info *bp_tgt) | |
7002 | { | |
6ed6bacf AM |
7003 | - struct lwp_info *lp; |
7004 | struct ppc_hw_breakpoint p; | |
7005 | ||
7006 | if (!have_ptrace_booke_interface ()) | |
f412e1b4 | 7007 | @@ -1715,8 +1732,7 @@ ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch, |
6ed6bacf | 7008 | p.addr2 = 0; |
51a5ef0f PS |
7009 | } |
7010 | ||
f412e1b4 PS |
7011 | - ALL_LWPS (lp) |
7012 | - booke_remove_point (&p, TIDGET (lp->ptid)); | |
7013 | + linux_nat_iterate_watchpoint_lwps (booke_remove_point_callback, &p); | |
7014 | ||
7015 | return 0; | |
7016 | } | |
7017 | @@ -1745,7 +1761,6 @@ static int | |
7018 | ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, | |
7019 | CORE_ADDR mask, int rw) | |
7020 | { | |
7021 | - struct lwp_info *lp; | |
7022 | struct ppc_hw_breakpoint p; | |
7023 | ||
7024 | gdb_assert (have_ptrace_booke_interface ()); | |
7025 | @@ -1758,8 +1773,7 @@ ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, | |
7026 | p.addr2 = mask; | |
7027 | p.condition_value = 0; | |
7028 | ||
7029 | - ALL_LWPS (lp) | |
7030 | - booke_insert_point (&p, TIDGET (lp->ptid)); | |
7031 | + linux_nat_iterate_watchpoint_lwps (booke_insert_point_callback, &p); | |
7032 | ||
7033 | return 0; | |
7034 | } | |
7035 | @@ -1773,7 +1787,6 @@ static int | |
7036 | ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, | |
7037 | CORE_ADDR mask, int rw) | |
7038 | { | |
7039 | - struct lwp_info *lp; | |
7040 | struct ppc_hw_breakpoint p; | |
7041 | ||
7042 | gdb_assert (have_ptrace_booke_interface ()); | |
7043 | @@ -1786,8 +1799,7 @@ ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, | |
7044 | p.addr2 = mask; | |
7045 | p.condition_value = 0; | |
7046 | ||
7047 | - ALL_LWPS (lp) | |
7048 | - booke_remove_point (&p, TIDGET (lp->ptid)); | |
6ed6bacf | 7049 | + linux_nat_iterate_watchpoint_lwps (booke_remove_point_callback, &p); |
3a58abaf | 7050 | |
6ed6bacf AM |
7051 | return 0; |
7052 | } | |
f412e1b4 PS |
7053 | @@ -1797,10 +1809,16 @@ static int |
7054 | can_use_watchpoint_cond_accel (void) | |
7055 | { | |
7056 | struct thread_points *p; | |
7057 | - int tid = TIDGET (inferior_ptid); | |
7058 | int cnt = booke_debug_info.num_condition_regs, i; | |
7059 | CORE_ADDR tmp_value; | |
7060 | ||
7061 | + /* Overload thread id onto process id. */ | |
7062 | + int tid = TIDGET (inferior_ptid); | |
7063 | + | |
7064 | + /* No thread id, just use process id. */ | |
7065 | + if (tid == 0) | |
7066 | + tid = PIDGET (inferior_ptid); | |
7067 | + | |
7068 | if (!have_ptrace_booke_interface () || cnt == 0) | |
7069 | return 0; | |
7070 | ||
7071 | @@ -1999,6 +2017,22 @@ ppc_linux_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int rw, | |
6ed6bacf | 7072 | && check_condition (addr, cond, &data_value, &len)); |
3a58abaf AM |
7073 | } |
7074 | ||
f412e1b4 PS |
7075 | +/* Callback for linux_nat_iterate_watchpoint_lwps setting RETP_VOIDP by |
7076 | + PTRACE_SET_DEBUGREG for LP. */ | |
7077 | + | |
7078 | +static int | |
7079 | +set_saved_dabr_value_callback (struct lwp_info *lp, void *retp_voidp) | |
3a58abaf | 7080 | +{ |
6ed6bacf AM |
7081 | + int *retp = retp_voidp; |
7082 | + | |
f412e1b4 PS |
7083 | + if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (lp->ptid), 0, saved_dabr_value) |
7084 | + < 0) | |
6ed6bacf | 7085 | + *retp = -1; |
f412e1b4 PS |
7086 | + |
7087 | + /* Continue the traversal. */ | |
7088 | + return 0; | |
3a58abaf AM |
7089 | +} |
7090 | + | |
6ed6bacf AM |
7091 | /* Set up P with the parameters necessary to request a watchpoint covering |
7092 | LEN bytes starting at ADDR and if possible with condition expression COND | |
7093 | evaluated by hardware. INSERT tells if we are creating a request for | |
f412e1b4 | 7094 | @@ -2054,7 +2088,6 @@ static int |
6ed6bacf AM |
7095 | ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw, |
7096 | struct expression *cond) | |
7097 | { | |
7098 | - struct lwp_info *lp; | |
6ed6bacf | 7099 | int ret = -1; |
3a58abaf | 7100 | |
6ed6bacf | 7101 | if (have_ptrace_booke_interface ()) |
f412e1b4 | 7102 | @@ -2063,8 +2096,7 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw, |
6ed6bacf AM |
7103 | |
7104 | create_watchpoint_request (&p, addr, len, rw, cond, 1); | |
7105 | ||
f412e1b4 PS |
7106 | - ALL_LWPS (lp) |
7107 | - booke_insert_point (&p, TIDGET (lp->ptid)); | |
6ed6bacf AM |
7108 | + linux_nat_iterate_watchpoint_lwps (booke_insert_point_callback, &p); |
7109 | ||
7110 | ret = 0; | |
7111 | } | |
f412e1b4 | 7112 | @@ -2107,12 +2139,8 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw, |
6ed6bacf AM |
7113 | |
7114 | saved_dabr_value = dabr_value; | |
7115 | ||
f412e1b4 PS |
7116 | - ALL_LWPS (lp) |
7117 | - if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (lp->ptid), 0, | |
6ed6bacf AM |
7118 | - saved_dabr_value) < 0) |
7119 | - return -1; | |
7120 | - | |
7121 | ret = 0; | |
7122 | + linux_nat_iterate_watchpoint_lwps (set_saved_dabr_value_callback, &ret); | |
7123 | } | |
7124 | ||
7125 | return ret; | |
f412e1b4 | 7126 | @@ -2122,7 +2150,6 @@ static int |
6ed6bacf AM |
7127 | ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw, |
7128 | struct expression *cond) | |
7129 | { | |
7130 | - struct lwp_info *lp; | |
6ed6bacf AM |
7131 | int ret = -1; |
7132 | ||
7133 | if (have_ptrace_booke_interface ()) | |
f412e1b4 | 7134 | @@ -2131,20 +2158,16 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw, |
6ed6bacf AM |
7135 | |
7136 | create_watchpoint_request (&p, addr, len, rw, cond, 0); | |
7137 | ||
f412e1b4 PS |
7138 | - ALL_LWPS (lp) |
7139 | - booke_remove_point (&p, TIDGET (lp->ptid)); | |
6ed6bacf AM |
7140 | + linux_nat_iterate_watchpoint_lwps (booke_remove_point_callback, &p); |
7141 | ||
7142 | ret = 0; | |
7143 | } | |
7144 | else | |
7145 | { | |
7146 | saved_dabr_value = 0; | |
f412e1b4 PS |
7147 | - ALL_LWPS (lp) |
7148 | - if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (lp->ptid), 0, | |
6ed6bacf AM |
7149 | - saved_dabr_value) < 0) |
7150 | - return -1; | |
7151 | ||
7152 | ret = 0; | |
7153 | + linux_nat_iterate_watchpoint_lwps (set_saved_dabr_value_callback, &ret); | |
7154 | } | |
7155 | ||
7156 | return ret; | |
f412e1b4 PS |
7157 | @@ -2171,7 +2194,7 @@ ppc_linux_new_thread (struct lwp_info *lp) |
7158 | /* Copy that thread's breakpoints and watchpoints to the new thread. */ | |
7159 | for (i = 0; i < max_slots_number; i++) | |
7160 | if (hw_breaks[i].hw_break) | |
7161 | - booke_insert_point (hw_breaks[i].hw_break, tid); | |
7162 | + booke_insert_point (lp, hw_breaks[i].hw_break); | |
7163 | } | |
7164 | else | |
7165 | ptrace (PTRACE_SET_DEBUGREG, tid, 0, saved_dabr_value); | |
7166 | @@ -2229,7 +2252,14 @@ ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) | |
7167 | /* The index (or slot) of the *point is passed in the si_errno field. */ | |
7168 | int slot = siginfo_p->si_errno; | |
7169 | ||
7170 | - t = booke_find_thread_points_by_tid (TIDGET (inferior_ptid), 0); | |
7171 | + /* Overload thread id onto process id. */ | |
7172 | + int tid = TIDGET (inferior_ptid); | |
7173 | + | |
7174 | + /* No thread id, just use process id. */ | |
7175 | + if (tid == 0) | |
7176 | + tid = PIDGET (inferior_ptid); | |
7177 | + | |
7178 | + t = booke_find_thread_points_by_tid (tid, 0); | |
7179 | ||
7180 | /* Find out if this *point is a hardware breakpoint. | |
7181 | If so, we should return 0. */ | |
7182 | diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c | |
7183 | index b6470fe..f871309 100644 | |
7184 | --- a/gdb/ppc-linux-tdep.c | |
7185 | +++ b/gdb/ppc-linux-tdep.c | |
7186 | @@ -65,6 +65,14 @@ | |
7187 | #include "features/rs6000/powerpc-isa205-vsx64l.c" | |
7188 | #include "features/rs6000/powerpc-e500l.c" | |
7189 | ||
7190 | +#include "stap-probe.h" | |
7191 | +#include "ax.h" | |
7192 | +#include "ax-gdb.h" | |
7193 | +#include "cli/cli-utils.h" | |
7194 | +#include "parser-defs.h" | |
7195 | +#include "user-regs.h" | |
7196 | +#include <ctype.h> | |
7197 | + | |
7198 | /* The syscall's XML filename for PPC and PPC64. */ | |
7199 | #define XML_SYSCALL_FILENAME_PPC "syscalls/ppc-linux.xml" | |
7200 | #define XML_SYSCALL_FILENAME_PPC64 "syscalls/ppc64-linux.xml" | |
7201 | @@ -1192,6 +1200,65 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, | |
7202 | } | |
7203 | } | |
7204 | ||
7205 | +static int | |
7206 | +ppc_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) | |
7207 | +{ | |
7208 | + return (*s == 'i' /* Literal number. */ | |
7209 | + || (isdigit (*s) && s[1] == '(' | |
7210 | + && isdigit (s[2])) /* Displacement. */ | |
7211 | + || (*s == '(' && isdigit (s[1])) /* Register indirection. */ | |
7212 | + || isdigit (*s)); /* Register value. */ | |
7213 | +} | |
7214 | + | |
7215 | +static int | |
7216 | +ppc_stap_parse_special_token (struct gdbarch *gdbarch, | |
7217 | + struct stap_parse_info *p) | |
7218 | +{ | |
7219 | + if (isdigit (*p->arg)) | |
7220 | + { | |
7221 | + /* This temporary pointer is needed because we have to do a lookahead. | |
7222 | + We could be dealing with a register displacement, and in such case | |
7223 | + we would not need to do anything. */ | |
7224 | + const char *s = p->arg; | |
7225 | + char *regname; | |
7226 | + int len; | |
7227 | + struct stoken str; | |
7228 | + | |
7229 | + while (isdigit (*s)) | |
7230 | + ++s; | |
7231 | + | |
7232 | + if (*s == '(') | |
7233 | + /* It is a register displacement indeed. Returning 0 means we are | |
7234 | + deferring the treatment of this case to the generic parser. */ | |
7235 | + return 0; | |
7236 | + | |
7237 | + len = s - p->arg; | |
7238 | + regname = alloca (len + 2); | |
7239 | + regname[0] = 'r'; | |
7240 | + | |
7241 | + strncpy (regname + 1, p->arg, len); | |
7242 | + ++len; | |
7243 | + regname[len] = '\0'; | |
7244 | + | |
7245 | + if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1) | |
7246 | + error (_("Invalid register name `%s' on expression `%s'."), | |
7247 | + regname, p->saved_arg); | |
7248 | + | |
7249 | + write_exp_elt_opcode (OP_REGISTER); | |
7250 | + str.ptr = regname; | |
7251 | + str.length = len; | |
7252 | + write_exp_string (str); | |
7253 | + write_exp_elt_opcode (OP_REGISTER); | |
7254 | + | |
7255 | + p->arg = s; | |
7256 | + } | |
7257 | + else | |
7258 | + /* All the other tokens should be handled correctly by the generic | |
7259 | + parser. */ | |
7260 | + return 0; | |
7261 | + | |
7262 | + return 1; | |
7263 | +} | |
7264 | ||
7265 | /* Cell/B.E. active SPE context tracking support. */ | |
7266 | ||
7267 | @@ -1509,6 +1576,15 @@ ppc_linux_init_abi (struct gdbarch_info info, | |
7268 | /* Get the syscall number from the arch's register. */ | |
7269 | set_gdbarch_get_syscall_number (gdbarch, ppc_linux_get_syscall_number); | |
7270 | ||
7271 | + /* SystemTap functions. */ | |
7272 | + set_gdbarch_stap_integer_prefix (gdbarch, "i"); | |
7273 | + set_gdbarch_stap_register_indirection_prefix (gdbarch, "("); | |
7274 | + set_gdbarch_stap_register_indirection_sufix (gdbarch, ")"); | |
7275 | + set_gdbarch_stap_gdb_register_prefix (gdbarch, "r"); | |
7276 | + set_gdbarch_stap_is_single_operand (gdbarch, ppc_stap_is_single_operand); | |
7277 | + set_gdbarch_stap_parse_special_token (gdbarch, | |
7278 | + ppc_stap_parse_special_token); | |
7279 | + | |
7280 | if (tdep->wordsize == 4) | |
7281 | { | |
7282 | /* Until November 2001, gcc did not comply with the 32 bit SysV | |
7283 | diff --git a/gdb/printcmd.c b/gdb/printcmd.c | |
7284 | index bee8a85..00f332d 100644 | |
7285 | --- a/gdb/printcmd.c | |
7286 | +++ b/gdb/printcmd.c | |
7287 | @@ -49,6 +49,7 @@ | |
7288 | #include "charset.h" | |
7289 | #include "arch-utils.h" | |
7290 | #include "cli/cli-utils.h" | |
7291 | +#include "dwarf2loc.h" | |
7292 | ||
7293 | #ifdef TUI | |
7294 | #include "tui/tui.h" /* For tui_active et al. */ | |
7295 | @@ -971,6 +972,11 @@ print_command_1 (char *exp, int inspect, int voidprint) | |
6ed6bacf AM |
7296 | else |
7297 | val = access_value_history (0); | |
7298 | ||
7299 | + /* Do not try to OBJECT_ADDRESS_SET here anything. We are interested in the | |
7300 | + source variable base addresses as found by READ_VAR_VALUE. The value here | |
7301 | + can be already a calculated expression address inappropriate for | |
7302 | + DW_OP_push_object_address. */ | |
7566401a | 7303 | + |
6ed6bacf AM |
7304 | if (voidprint || (val && value_type (val) && |
7305 | TYPE_CODE (value_type (val)) != TYPE_CODE_VOID)) | |
7306 | { | |
f412e1b4 PS |
7307 | @@ -1059,6 +1065,9 @@ output_command (char *exp, int from_tty) |
7308 | ||
7309 | val = evaluate_expression (expr); | |
7310 | ||
7311 | + if (VALUE_LVAL (val) == lval_memory) | |
7312 | + object_address_set (value_raw_address (val)); | |
7313 | + | |
7314 | annotate_value_begin (value_type (val)); | |
7315 | ||
7316 | get_formatted_print_options (&opts, format); | |
7317 | @@ -1472,6 +1481,24 @@ x_command (char *exp, int from_tty) | |
6ed6bacf AM |
7318 | set_internalvar (lookup_internalvar ("__"), last_examine_value); |
7319 | } | |
7320 | } | |
7321 | + | |
7322 | +#if 0 | |
7323 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ | |
7566401a ER |
7324 | + |
7325 | +static void | |
6ed6bacf | 7326 | +print_types_mark_used (void) |
7566401a | 7327 | +{ |
6ed6bacf | 7328 | + struct display *d; |
7566401a | 7329 | + |
6ed6bacf AM |
7330 | + if (last_examine_value) |
7331 | + type_mark_used (value_type (last_examine_value)); | |
7566401a | 7332 | + |
6ed6bacf AM |
7333 | + for (d = display_chain; d; d = d->next) |
7334 | + if (d->exp) | |
7335 | + exp_types_mark_used (d->exp); | |
7336 | +} | |
7337 | +#endif | |
7566401a | 7338 | + |
6ed6bacf AM |
7339 | \f |
7340 | ||
7341 | /* Add an expression to the auto-display chain. | |
f412e1b4 PS |
7342 | @@ -1971,6 +1998,10 @@ print_variable_and_value (const char *name, struct symbol *var, |
7343 | struct value_print_options opts; | |
7344 | ||
7345 | val = read_var_value (var, frame); | |
7346 | + | |
7347 | + make_cleanup_restore_selected_frame (); | |
7348 | + select_frame (frame); | |
7349 | + | |
7350 | get_user_print_options (&opts); | |
7351 | opts.deref_ref = 1; | |
7352 | common_val_print (val, stream, indent, &opts, current_language); | |
7353 | @@ -2884,4 +2915,8 @@ Show printing of source filename and line number with <symbol>."), NULL, | |
6ed6bacf AM |
7354 | add_com ("eval", no_class, eval_command, _("\ |
7355 | Convert \"printf format string\", arg1, arg2, arg3, ..., argn to\n\ | |
7356 | a command line, and call it.")); | |
7566401a | 7357 | + |
6ed6bacf AM |
7358 | +#if 0 |
7359 | + observer_attach_mark_used (print_types_mark_used); | |
7360 | +#endif | |
7361 | } | |
f412e1b4 PS |
7362 | diff --git a/gdb/python/lib/gdb/FrameIterator.py b/gdb/python/lib/gdb/FrameIterator.py |
7363 | new file mode 100644 | |
7364 | index 0000000..5654546 | |
7365 | --- /dev/null | |
7366 | +++ b/gdb/python/lib/gdb/FrameIterator.py | |
6ed6bacf AM |
7367 | @@ -0,0 +1,33 @@ |
7368 | +# Iterator over frames. | |
7566401a | 7369 | + |
6ed6bacf | 7370 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. |
7566401a | 7371 | + |
6ed6bacf AM |
7372 | +# This program is free software; you can redistribute it and/or modify |
7373 | +# it under the terms of the GNU General Public License as published by | |
7374 | +# the Free Software Foundation; either version 3 of the License, or | |
7375 | +# (at your option) any later version. | |
7376 | +# | |
7377 | +# This program is distributed in the hope that it will be useful, | |
7378 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
7379 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
7380 | +# GNU General Public License for more details. | |
7381 | +# | |
7382 | +# You should have received a copy of the GNU General Public License | |
7383 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
7566401a | 7384 | + |
6ed6bacf AM |
7385 | +class FrameIterator: |
7386 | + """An iterator that iterates over frames.""" | |
7566401a | 7387 | + |
6ed6bacf AM |
7388 | + def __init__ (self, frame): |
7389 | + "Initialize a FrameIterator. FRAME is the starting frame." | |
7390 | + self.frame = frame | |
7566401a | 7391 | + |
6ed6bacf AM |
7392 | + def __iter__ (self): |
7393 | + return self | |
3a58abaf | 7394 | + |
6ed6bacf AM |
7395 | + def next (self): |
7396 | + result = self.frame | |
7397 | + if result is None: | |
7398 | + raise StopIteration | |
7399 | + self.frame = result.older () | |
7400 | + return result | |
f412e1b4 PS |
7401 | diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py |
7402 | new file mode 100644 | |
7403 | index 0000000..b790a54 | |
7404 | --- /dev/null | |
7405 | +++ b/gdb/python/lib/gdb/FrameWrapper.py | |
6ed6bacf AM |
7406 | @@ -0,0 +1,112 @@ |
7407 | +# Wrapper API for frames. | |
3a58abaf | 7408 | + |
6ed6bacf | 7409 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. |
3a58abaf | 7410 | + |
6ed6bacf AM |
7411 | +# This program is free software; you can redistribute it and/or modify |
7412 | +# it under the terms of the GNU General Public License as published by | |
7413 | +# the Free Software Foundation; either version 3 of the License, or | |
7414 | +# (at your option) any later version. | |
7415 | +# | |
7416 | +# This program is distributed in the hope that it will be useful, | |
7417 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
7418 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
7419 | +# GNU General Public License for more details. | |
7420 | +# | |
7421 | +# You should have received a copy of the GNU General Public License | |
7422 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 7423 | + |
6ed6bacf | 7424 | +import gdb |
3a58abaf | 7425 | + |
6ed6bacf AM |
7426 | +# FIXME: arguably all this should be on Frame somehow. |
7427 | +class FrameWrapper: | |
7428 | + def __init__ (self, frame): | |
7429 | + self.frame = frame; | |
3a58abaf | 7430 | + |
6ed6bacf AM |
7431 | + def write_symbol (self, stream, sym, block): |
7432 | + if len (sym.linkage_name): | |
7433 | + nsym, is_field_of_this = gdb.lookup_symbol (sym.linkage_name, block) | |
7434 | + if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER: | |
7435 | + sym = nsym | |
7436 | + | |
7437 | + stream.write (sym.print_name + "=") | |
7438 | + try: | |
7439 | + val = self.read_var (sym) | |
7440 | + if val != None: | |
7441 | + val = str (val) | |
7442 | + # FIXME: would be nice to have a more precise exception here. | |
7443 | + except RuntimeError, text: | |
7444 | + val = text | |
7445 | + if val == None: | |
7446 | + stream.write ("???") | |
7447 | + else: | |
7448 | + stream.write (str (val)) | |
7449 | + | |
7450 | + def print_frame_locals (self, stream, func): | |
7451 | + if not func: | |
7452 | + return | |
7453 | + | |
7454 | + first = True | |
7455 | + block = func.value | |
7456 | + | |
7457 | + for sym in block: | |
7458 | + if sym.is_argument: | |
7459 | + continue; | |
7460 | + | |
7461 | + self.write_symbol (stream, sym, block) | |
7462 | + stream.write ('\n') | |
7463 | + | |
7464 | + def print_frame_args (self, stream, func): | |
7465 | + if not func: | |
7466 | + return | |
7467 | + | |
7468 | + first = True | |
7469 | + block = func.value | |
7470 | + | |
7471 | + for sym in block: | |
7472 | + if not sym.is_argument: | |
7473 | + continue; | |
7474 | + | |
7475 | + if not first: | |
7476 | + stream.write (", ") | |
7477 | + | |
7478 | + self.write_symbol (stream, sym, block) | |
7479 | + first = False | |
7480 | + | |
7481 | + # FIXME: this should probably just be a method on gdb.Frame. | |
7482 | + # But then we need stream wrappers. | |
7483 | + def describe (self, stream, full): | |
7484 | + if self.type () == gdb.DUMMY_FRAME: | |
7485 | + stream.write (" <function called from gdb>\n") | |
7486 | + elif self.type () == gdb.SIGTRAMP_FRAME: | |
7487 | + stream.write (" <signal handler called>\n") | |
7488 | + else: | |
7489 | + sal = self.find_sal () | |
7490 | + pc = self.pc () | |
7491 | + name = self.name () | |
7492 | + if not name: | |
7493 | + name = "??" | |
7494 | + if pc != sal.pc or not sal.symtab: | |
7495 | + stream.write (" 0x%08x in" % pc) | |
7496 | + stream.write (" " + name + " (") | |
3a58abaf | 7497 | + |
6ed6bacf AM |
7498 | + func = self.function () |
7499 | + self.print_frame_args (stream, func) | |
3a58abaf | 7500 | + |
6ed6bacf | 7501 | + stream.write (")") |
3a58abaf | 7502 | + |
6ed6bacf AM |
7503 | + if sal.symtab and sal.symtab.filename: |
7504 | + stream.write (" at " + sal.symtab.filename) | |
7505 | + stream.write (":" + str (sal.line)) | |
3a58abaf | 7506 | + |
6ed6bacf AM |
7507 | + if not self.name () or (not sal.symtab or not sal.symtab.filename): |
7508 | + lib = gdb.solib_address (pc) | |
7509 | + if lib: | |
7510 | + stream.write (" from " + lib) | |
3a58abaf | 7511 | + |
6ed6bacf | 7512 | + stream.write ("\n") |
3a58abaf | 7513 | + |
6ed6bacf AM |
7514 | + if full: |
7515 | + self.print_frame_locals (stream, func) | |
3a58abaf | 7516 | + |
6ed6bacf AM |
7517 | + def __getattr__ (self, name): |
7518 | + return getattr (self.frame, name) | |
f412e1b4 PS |
7519 | diff --git a/gdb/python/lib/gdb/backtrace.py b/gdb/python/lib/gdb/backtrace.py |
7520 | new file mode 100644 | |
7521 | index 0000000..6bb4fb1 | |
7522 | --- /dev/null | |
7523 | +++ b/gdb/python/lib/gdb/backtrace.py | |
6ed6bacf AM |
7524 | @@ -0,0 +1,42 @@ |
7525 | +# Filtering backtrace. | |
3a58abaf | 7526 | + |
6ed6bacf | 7527 | +# Copyright (C) 2008, 2011 Free Software Foundation, Inc. |
3a58abaf | 7528 | + |
6ed6bacf AM |
7529 | +# This program is free software; you can redistribute it and/or modify |
7530 | +# it under the terms of the GNU General Public License as published by | |
7531 | +# the Free Software Foundation; either version 3 of the License, or | |
7532 | +# (at your option) any later version. | |
7533 | +# | |
7534 | +# This program is distributed in the hope that it will be useful, | |
7535 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
7536 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
7537 | +# GNU General Public License for more details. | |
7538 | +# | |
7539 | +# You should have received a copy of the GNU General Public License | |
7540 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 7541 | + |
6ed6bacf AM |
7542 | +import gdb |
7543 | +import itertools | |
3a58abaf | 7544 | + |
6ed6bacf AM |
7545 | +# Our only exports. |
7546 | +__all__ = ['push_frame_filter', 'create_frame_filter'] | |
3a58abaf | 7547 | + |
6ed6bacf | 7548 | +frame_filter = None |
3a58abaf | 7549 | + |
6ed6bacf AM |
7550 | +def push_frame_filter (constructor): |
7551 | + """Register a new backtrace filter class with the 'backtrace' command. | |
7552 | +The filter will be passed an iterator as an argument. The iterator | |
7553 | +will return gdb.Frame-like objects. The filter should in turn act as | |
7554 | +an iterator returning such objects.""" | |
7555 | + global frame_filter | |
7556 | + if frame_filter == None: | |
7557 | + frame_filter = constructor | |
7558 | + else: | |
7559 | + frame_filter = lambda iterator, filter = frame_filter: constructor (filter (iterator)) | |
3a58abaf | 7560 | + |
6ed6bacf AM |
7561 | +def create_frame_filter (iter): |
7562 | + global frame_filter | |
7563 | + if frame_filter is None: | |
7564 | + return iter | |
7565 | + return frame_filter (iter) | |
3a58abaf | 7566 | + |
f412e1b4 PS |
7567 | diff --git a/gdb/python/lib/gdb/command/backtrace.py b/gdb/python/lib/gdb/command/backtrace.py |
7568 | new file mode 100644 | |
7569 | index 0000000..eeea909 | |
7570 | --- /dev/null | |
7571 | +++ b/gdb/python/lib/gdb/command/backtrace.py | |
6ed6bacf AM |
7572 | @@ -0,0 +1,106 @@ |
7573 | +# New backtrace command. | |
7566401a | 7574 | + |
6ed6bacf | 7575 | +# Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc. |
3a58abaf | 7576 | + |
6ed6bacf AM |
7577 | +# This program is free software; you can redistribute it and/or modify |
7578 | +# it under the terms of the GNU General Public License as published by | |
7579 | +# the Free Software Foundation; either version 3 of the License, or | |
7580 | +# (at your option) any later version. | |
7581 | +# | |
7582 | +# This program is distributed in the hope that it will be useful, | |
7583 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
7584 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
7585 | +# GNU General Public License for more details. | |
7586 | +# | |
7587 | +# You should have received a copy of the GNU General Public License | |
7588 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 7589 | + |
6ed6bacf AM |
7590 | +import gdb |
7591 | +import gdb.backtrace | |
7592 | +import itertools | |
7593 | +from gdb.FrameIterator import FrameIterator | |
7594 | +from gdb.FrameWrapper import FrameWrapper | |
7595 | +import sys | |
3a58abaf | 7596 | + |
6ed6bacf AM |
7597 | +class ReverseBacktraceParameter (gdb.Parameter): |
7598 | + """The new-backtrace command can show backtraces in 'reverse' order. | |
7599 | +This means that the innermost frame will be printed last. | |
7600 | +Note that reverse backtraces are more expensive to compute.""" | |
3a58abaf | 7601 | + |
6ed6bacf AM |
7602 | + set_doc = "Enable or disable reverse backtraces." |
7603 | + show_doc = "Show whether backtraces will be printed in reverse order." | |
3a58abaf | 7604 | + |
6ed6bacf AM |
7605 | + def __init__(self): |
7606 | + gdb.Parameter.__init__ (self, "reverse-backtrace", | |
7607 | + gdb.COMMAND_STACK, gdb.PARAM_BOOLEAN) | |
7608 | + # Default to compatibility with gdb. | |
7609 | + self.value = False | |
3a58abaf | 7610 | + |
6ed6bacf AM |
7611 | +class FilteringBacktrace (gdb.Command): |
7612 | + """Print backtrace of all stack frames, or innermost COUNT frames. | |
7613 | +With a negative argument, print outermost -COUNT frames. | |
7614 | +Use of the 'full' qualifier also prints the values of the local variables. | |
7615 | +Use of the 'raw' qualifier avoids any filtering by loadable modules. | |
7616 | +""" | |
3a58abaf | 7617 | + |
6ed6bacf AM |
7618 | + def __init__ (self): |
7619 | + # FIXME: this is not working quite well enough to replace | |
7620 | + # "backtrace" yet. | |
7621 | + gdb.Command.__init__ (self, "new-backtrace", gdb.COMMAND_STACK) | |
7622 | + self.reverse = ReverseBacktraceParameter() | |
7566401a | 7623 | + |
6ed6bacf AM |
7624 | + def reverse_iter (self, iter): |
7625 | + result = [] | |
7626 | + for item in iter: | |
7627 | + result.append (item) | |
7628 | + result.reverse() | |
7629 | + return result | |
7566401a | 7630 | + |
6ed6bacf AM |
7631 | + def final_n (self, iter, x): |
7632 | + result = [] | |
7633 | + for item in iter: | |
7634 | + result.append (item) | |
7635 | + return result[x:] | |
7566401a | 7636 | + |
6ed6bacf AM |
7637 | + def invoke (self, arg, from_tty): |
7638 | + i = 0 | |
7639 | + count = 0 | |
7640 | + filter = True | |
7641 | + full = False | |
3a58abaf | 7642 | + |
6ed6bacf AM |
7643 | + for word in arg.split (" "): |
7644 | + if word == '': | |
7645 | + continue | |
7646 | + elif word == 'raw': | |
7647 | + filter = False | |
7648 | + elif word == 'full': | |
7649 | + full = True | |
7650 | + else: | |
7651 | + count = int (word) | |
3a58abaf | 7652 | + |
6ed6bacf AM |
7653 | + # FIXME: provide option to start at selected frame |
7654 | + # However, should still number as if starting from newest | |
7655 | + newest_frame = gdb.newest_frame() | |
7656 | + iter = itertools.imap (FrameWrapper, | |
7657 | + FrameIterator (newest_frame)) | |
7658 | + if filter: | |
7659 | + iter = gdb.backtrace.create_frame_filter (iter) | |
51a5ef0f | 7660 | + |
6ed6bacf AM |
7661 | + # Now wrap in an iterator that numbers the frames. |
7662 | + iter = itertools.izip (itertools.count (0), iter) | |
51a5ef0f | 7663 | + |
6ed6bacf AM |
7664 | + # Reverse if the user wanted that. |
7665 | + if self.reverse.value: | |
7666 | + iter = self.reverse_iter (iter) | |
7566401a | 7667 | + |
6ed6bacf AM |
7668 | + # Extract sub-range user wants. |
7669 | + if count < 0: | |
7670 | + iter = self.final_n (iter, count) | |
7671 | + elif count > 0: | |
7672 | + iter = itertools.islice (iter, 0, count) | |
7566401a | 7673 | + |
6ed6bacf AM |
7674 | + for pair in iter: |
7675 | + sys.stdout.write ("#%-2d" % pair[0]) | |
7676 | + pair[1].describe (sys.stdout, full) | |
7566401a | 7677 | + |
6ed6bacf | 7678 | +FilteringBacktrace() |
f412e1b4 PS |
7679 | diff --git a/gdb/python/lib/gdb/command/ignore_errors.py b/gdb/python/lib/gdb/command/ignore_errors.py |
7680 | new file mode 100644 | |
7681 | index 0000000..6fa48ff | |
7682 | --- /dev/null | |
7683 | +++ b/gdb/python/lib/gdb/command/ignore_errors.py | |
6ed6bacf AM |
7684 | @@ -0,0 +1,37 @@ |
7685 | +# Ignore errors in user commands. | |
7566401a | 7686 | + |
6ed6bacf | 7687 | +# Copyright (C) 2008 Free Software Foundation, Inc. |
3a58abaf | 7688 | + |
6ed6bacf AM |
7689 | +# This program is free software; you can redistribute it and/or modify |
7690 | +# it under the terms of the GNU General Public License as published by | |
7691 | +# the Free Software Foundation; either version 3 of the License, or | |
7692 | +# (at your option) any later version. | |
7693 | +# | |
7694 | +# This program is distributed in the hope that it will be useful, | |
7695 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
7696 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
7697 | +# GNU General Public License for more details. | |
7698 | +# | |
7699 | +# You should have received a copy of the GNU General Public License | |
7700 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 7701 | + |
6ed6bacf | 7702 | +import gdb |
3a58abaf | 7703 | + |
6ed6bacf AM |
7704 | +class IgnoreErrorsCommand (gdb.Command): |
7705 | + """Execute a single command, ignoring all errors. | |
7706 | +Only one-line commands are supported. | |
7707 | +This is primarily useful in scripts.""" | |
3a58abaf | 7708 | + |
6ed6bacf AM |
7709 | + def __init__ (self): |
7710 | + super (IgnoreErrorsCommand, self).__init__ ("ignore-errors", | |
7711 | + gdb.COMMAND_OBSCURE, | |
7712 | + # FIXME... | |
7713 | + gdb.COMPLETE_COMMAND) | |
3a58abaf | 7714 | + |
6ed6bacf AM |
7715 | + def invoke (self, arg, from_tty): |
7716 | + try: | |
7717 | + gdb.execute (arg, from_tty) | |
7718 | + except: | |
7719 | + pass | |
3a58abaf | 7720 | + |
6ed6bacf | 7721 | +IgnoreErrorsCommand () |
f412e1b4 PS |
7722 | diff --git a/gdb/python/lib/gdb/command/pahole.py b/gdb/python/lib/gdb/command/pahole.py |
7723 | new file mode 100644 | |
7724 | index 0000000..21a0bf0 | |
7725 | --- /dev/null | |
7726 | +++ b/gdb/python/lib/gdb/command/pahole.py | |
6ed6bacf AM |
7727 | @@ -0,0 +1,75 @@ |
7728 | +# pahole command for gdb | |
3a58abaf | 7729 | + |
6ed6bacf | 7730 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. |
3a58abaf | 7731 | + |
6ed6bacf AM |
7732 | +# This program is free software; you can redistribute it and/or modify |
7733 | +# it under the terms of the GNU General Public License as published by | |
7734 | +# the Free Software Foundation; either version 3 of the License, or | |
7735 | +# (at your option) any later version. | |
7736 | +# | |
7737 | +# This program is distributed in the hope that it will be useful, | |
7738 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
7739 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
7740 | +# GNU General Public License for more details. | |
7741 | +# | |
7742 | +# You should have received a copy of the GNU General Public License | |
7743 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 7744 | + |
6ed6bacf | 7745 | +import gdb |
3a58abaf | 7746 | + |
6ed6bacf AM |
7747 | +class Pahole (gdb.Command): |
7748 | + """Show the holes in a structure. | |
7749 | +This command takes a single argument, a type name. | |
7750 | +It prints the type and displays comments showing where holes are.""" | |
3a58abaf | 7751 | + |
6ed6bacf AM |
7752 | + def __init__ (self): |
7753 | + super (Pahole, self).__init__ ("pahole", gdb.COMMAND_NONE, | |
7754 | + gdb.COMPLETE_SYMBOL) | |
51a5ef0f | 7755 | + |
6ed6bacf AM |
7756 | + def pahole (self, type, level, name): |
7757 | + if name is None: | |
7758 | + name = '' | |
7759 | + tag = type.tag | |
7760 | + if tag is None: | |
7761 | + tag = '' | |
7762 | + print '%sstruct %s {' % (' ' * (2 * level), tag) | |
7763 | + bitpos = 0 | |
7764 | + for field in type.fields (): | |
7765 | + # Skip static fields. | |
7766 | + if not hasattr (field, ('bitpos')): | |
7767 | + continue | |
51a5ef0f | 7768 | + |
6ed6bacf | 7769 | + ftype = field.type.strip_typedefs() |
3a58abaf | 7770 | + |
6ed6bacf AM |
7771 | + if bitpos != field.bitpos: |
7772 | + hole = field.bitpos - bitpos | |
7773 | + print ' /* XXX %d bit hole, try to pack */' % hole | |
7774 | + bitpos = field.bitpos | |
7775 | + if field.bitsize > 0: | |
7776 | + fieldsize = field.bitsize | |
7777 | + else: | |
7778 | + # TARGET_CHAR_BIT here... | |
7779 | + fieldsize = 8 * ftype.sizeof | |
3a58abaf | 7780 | + |
6ed6bacf AM |
7781 | + # TARGET_CHAR_BIT |
7782 | + print ' /* %3d %3d */' % (int (bitpos / 8), int (fieldsize / 8)), | |
7783 | + bitpos = bitpos + fieldsize | |
3a58abaf | 7784 | + |
6ed6bacf AM |
7785 | + if ftype.code == gdb.TYPE_CODE_STRUCT: |
7786 | + self.pahole (ftype, level + 1, field.name) | |
7787 | + else: | |
7788 | + print ' ' * (2 + 2 * level), | |
7789 | + print '%s %s' % (str (ftype), field.name) | |
3a58abaf | 7790 | + |
6ed6bacf AM |
7791 | + print ' ' * (14 + 2 * level), |
7792 | + print '} %s' % name | |
3a58abaf | 7793 | + |
6ed6bacf AM |
7794 | + def invoke (self, arg, from_tty): |
7795 | + type = gdb.lookup_type (arg) | |
7796 | + type = type.strip_typedefs () | |
7797 | + if type.code != gdb.TYPE_CODE_STRUCT: | |
7798 | + raise TypeError, '%s is not a struct type' % arg | |
7799 | + print ' ' * 14, | |
7800 | + self.pahole (type, 0, '') | |
7566401a | 7801 | + |
6ed6bacf | 7802 | +Pahole() |
f412e1b4 PS |
7803 | diff --git a/gdb/python/lib/gdb/command/require.py b/gdb/python/lib/gdb/command/require.py |
7804 | new file mode 100644 | |
7805 | index 0000000..1fbc1e8 | |
7806 | --- /dev/null | |
7807 | +++ b/gdb/python/lib/gdb/command/require.py | |
6ed6bacf AM |
7808 | @@ -0,0 +1,57 @@ |
7809 | +# Demand-loading commands. | |
3a58abaf | 7810 | + |
6ed6bacf | 7811 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. |
3a58abaf | 7812 | + |
6ed6bacf AM |
7813 | +# This program is free software; you can redistribute it and/or modify |
7814 | +# it under the terms of the GNU General Public License as published by | |
7815 | +# the Free Software Foundation; either version 3 of the License, or | |
7816 | +# (at your option) any later version. | |
7817 | +# | |
7818 | +# This program is distributed in the hope that it will be useful, | |
7819 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
7820 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
7821 | +# GNU General Public License for more details. | |
7822 | +# | |
7823 | +# You should have received a copy of the GNU General Public License | |
7824 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 7825 | + |
6ed6bacf AM |
7826 | +import gdb |
7827 | +import os | |
3a58abaf | 7828 | + |
6ed6bacf AM |
7829 | +class RequireCommand (gdb.Command): |
7830 | + """Prefix command for requiring features.""" | |
7566401a | 7831 | + |
6ed6bacf AM |
7832 | + def __init__ (self): |
7833 | + super (RequireCommand, self).__init__ ("require", | |
7834 | + gdb.COMMAND_SUPPORT, | |
7835 | + gdb.COMPLETE_NONE, | |
7836 | + True) | |
7566401a | 7837 | + |
6ed6bacf AM |
7838 | +class RequireSubcommand (gdb.Command): |
7839 | + """Demand-load a command by name.""" | |
3a58abaf | 7840 | + |
6ed6bacf AM |
7841 | + def __init__ (self, name): |
7842 | + self.__doc__ = "Demand-load a %s by name." % name | |
7843 | + super (RequireSubcommand, self).__init__ ("require %s" % name, | |
7844 | + gdb.COMMAND_SUPPORT) | |
7845 | + self.name = name | |
51a5ef0f | 7846 | + |
6ed6bacf AM |
7847 | + def invoke (self, arg, from_tty): |
7848 | + for cmd in arg.split(): | |
7849 | + exec ('import gdb.' + self.name + '.' + cmd, globals ()) | |
51a5ef0f | 7850 | + |
6ed6bacf AM |
7851 | + def complete (self, text, word): |
7852 | + dir = gdb.pythondir + '/gdb/' + self.name | |
7853 | + result = [] | |
7854 | + for file in os.listdir(dir): | |
7855 | + if not file.startswith (word) or not file.endswith ('.py'): | |
7856 | + continue | |
7857 | + feature = file[0:-3] | |
7858 | + if feature == 'require' or feature == '__init__': | |
7859 | + continue | |
7860 | + result.append (feature) | |
7861 | + return result | |
51a5ef0f | 7862 | + |
6ed6bacf AM |
7863 | +RequireCommand() |
7864 | +RequireSubcommand("command") | |
7865 | +RequireSubcommand("function") | |
f412e1b4 PS |
7866 | diff --git a/gdb/python/lib/gdb/command/upto.py b/gdb/python/lib/gdb/command/upto.py |
7867 | new file mode 100644 | |
7868 | index 0000000..faf54ed | |
7869 | --- /dev/null | |
7870 | +++ b/gdb/python/lib/gdb/command/upto.py | |
6ed6bacf AM |
7871 | @@ -0,0 +1,129 @@ |
7872 | +# upto command. | |
51a5ef0f | 7873 | + |
6ed6bacf | 7874 | +# Copyright (C) 2009 Free Software Foundation, Inc. |
51a5ef0f | 7875 | + |
6ed6bacf AM |
7876 | +# This program is free software; you can redistribute it and/or modify |
7877 | +# it under the terms of the GNU General Public License as published by | |
7878 | +# the Free Software Foundation; either version 3 of the License, or | |
7879 | +# (at your option) any later version. | |
7880 | +# | |
7881 | +# This program is distributed in the hope that it will be useful, | |
7882 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
7883 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
7884 | +# GNU General Public License for more details. | |
7885 | +# | |
7886 | +# You should have received a copy of the GNU General Public License | |
7887 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
51a5ef0f | 7888 | + |
6ed6bacf AM |
7889 | +import gdb |
7890 | +import re | |
7891 | +from gdb.FrameIterator import FrameIterator | |
7892 | +from gdb.FrameWrapper import FrameWrapper | |
ab050a48 | 7893 | + |
6ed6bacf AM |
7894 | +class UptoPrefix (gdb.Command): |
7895 | + def __init__ (self): | |
7896 | + super (UptoPrefix, self).__init__ ("upto", gdb.COMMAND_STACK, | |
7897 | + prefix = True) | |
51a5ef0f | 7898 | + |
6ed6bacf AM |
7899 | +class UptoImplementation (gdb.Command): |
7900 | + def __init__ (self, subcommand): | |
7901 | + super (UptoImplementation, self).__init__ ("upto " + subcommand, | |
7902 | + gdb.COMMAND_STACK) | |
51a5ef0f | 7903 | + |
6ed6bacf AM |
7904 | + def search (self): |
7905 | + saved = gdb.selected_frame () | |
7906 | + iter = FrameIterator (saved) | |
7907 | + found = False | |
7908 | + try: | |
7909 | + for frame in iter: | |
7910 | + frame.select () | |
7911 | + try: | |
7912 | + if self.filter (frame): | |
7913 | + wrapper = FrameWrapper (frame) | |
7914 | + wrapper.describe (sys.stdout, False) | |
7915 | + return | |
7916 | + except: | |
7917 | + pass | |
7918 | + except: | |
7919 | + pass | |
7920 | + saved.select () | |
7921 | + raise RuntimeError, 'Could not find a matching frame' | |
51a5ef0f | 7922 | + |
6ed6bacf AM |
7923 | + def invoke (self, arg, from_tty): |
7924 | + self.rx = re.compile (arg) | |
7925 | + self.search () | |
51a5ef0f | 7926 | + |
6ed6bacf AM |
7927 | +class UptoSymbolCommand (UptoImplementation): |
7928 | + """Select and print some calling stack frame, based on symbol. | |
7929 | +The argument is a regular expression. This command moves up the | |
7930 | +stack, stopping at the first frame whose symbol matches the regular | |
7931 | +expression.""" | |
7566401a | 7932 | + |
6ed6bacf AM |
7933 | + def __init__ (self): |
7934 | + super (UptoSymbolCommand, self).__init__ ("symbol") | |
3a58abaf | 7935 | + |
6ed6bacf AM |
7936 | + def filter (self, frame): |
7937 | + name = frame.name () | |
7938 | + if name is not None: | |
7939 | + if self.rx.search (name) is not None: | |
7940 | + return True | |
7941 | + return False | |
7566401a | 7942 | + |
6ed6bacf AM |
7943 | +class UptoSourceCommand (UptoImplementation): |
7944 | + """Select and print some calling stack frame, based on source file. | |
7945 | +The argument is a regular expression. This command moves up the | |
7946 | +stack, stopping at the first frame whose source file name matches the | |
7947 | +regular expression.""" | |
7948 | + | |
7949 | + def __init__ (self): | |
7950 | + super (UptoSourceCommand, self).__init__ ("source") | |
7951 | + | |
7952 | + def filter (self, frame): | |
7953 | + name = frame.find_sal ().symtab.filename | |
7954 | + if name is not None: | |
7955 | + if self.rx.search (name) is not None: | |
7956 | + return True | |
7957 | + return False | |
7566401a | 7958 | + |
6ed6bacf AM |
7959 | +class UptoObjectCommand (UptoImplementation): |
7960 | + """Select and print some calling stack frame, based on object file. | |
7961 | +The argument is a regular expression. This command moves up the | |
7962 | +stack, stopping at the first frame whose object file name matches the | |
7963 | +regular expression.""" | |
7566401a | 7964 | + |
6ed6bacf AM |
7965 | + def __init__ (self): |
7966 | + super (UptoObjectCommand, self).__init__ ("object") | |
3a58abaf | 7967 | + |
6ed6bacf AM |
7968 | + def filter (self, frame): |
7969 | + name = frame.find_sal ().symtab.objfile.filename | |
7970 | + if name is not None: | |
7971 | + if self.rx.search (name) is not None: | |
7972 | + return True | |
7973 | + return False | |
3a58abaf | 7974 | + |
6ed6bacf AM |
7975 | +class UptoWhereCommand (UptoImplementation): |
7976 | + """Select and print some calling stack frame, based on expression. | |
7977 | +The argument is an expression. This command moves up the stack, | |
7978 | +parsing and evaluating the expression in each frame. This stops when | |
7979 | +the expression evaluates to a non-zero (true) value.""" | |
3a58abaf | 7980 | + |
6ed6bacf AM |
7981 | + def __init__ (self): |
7982 | + super (UptoWhereCommand, self).__init__ ("where") | |
7566401a | 7983 | + |
6ed6bacf AM |
7984 | + def filter (self, frame): |
7985 | + try: | |
7986 | + if gdb.parse_and_eval (self.expression): | |
7987 | + return True | |
7988 | + except: | |
7989 | + pass | |
7990 | + return False | |
51a5ef0f | 7991 | + |
6ed6bacf AM |
7992 | + def invoke (self, arg, from_tty): |
7993 | + self.expression = arg | |
7994 | + self.search () | |
51a5ef0f | 7995 | + |
6ed6bacf AM |
7996 | +UptoPrefix () |
7997 | +UptoSymbolCommand () | |
7998 | +UptoSourceCommand () | |
7999 | +UptoObjectCommand () | |
8000 | +UptoWhereCommand () | |
f412e1b4 PS |
8001 | diff --git a/gdb/python/lib/gdb/function/__init__.py b/gdb/python/lib/gdb/function/__init__.py |
8002 | new file mode 100644 | |
8003 | index 0000000..8b13789 | |
8004 | --- /dev/null | |
8005 | +++ b/gdb/python/lib/gdb/function/__init__.py | |
6ed6bacf | 8006 | @@ -0,0 +1 @@ |
51a5ef0f | 8007 | + |
f412e1b4 PS |
8008 | diff --git a/gdb/python/lib/gdb/function/caller_is.py b/gdb/python/lib/gdb/function/caller_is.py |
8009 | new file mode 100644 | |
8010 | index 0000000..2b9c5c7 | |
8011 | --- /dev/null | |
8012 | +++ b/gdb/python/lib/gdb/function/caller_is.py | |
6ed6bacf AM |
8013 | @@ -0,0 +1,58 @@ |
8014 | +# Caller-is functions. | |
51a5ef0f | 8015 | + |
6ed6bacf | 8016 | +# Copyright (C) 2008 Free Software Foundation, Inc. |
51a5ef0f | 8017 | + |
6ed6bacf AM |
8018 | +# This program is free software; you can redistribute it and/or modify |
8019 | +# it under the terms of the GNU General Public License as published by | |
8020 | +# the Free Software Foundation; either version 3 of the License, or | |
8021 | +# (at your option) any later version. | |
8022 | +# | |
8023 | +# This program is distributed in the hope that it will be useful, | |
8024 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
8025 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
8026 | +# GNU General Public License for more details. | |
8027 | +# | |
8028 | +# You should have received a copy of the GNU General Public License | |
8029 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
7566401a | 8030 | + |
6ed6bacf AM |
8031 | +import gdb |
8032 | +import re | |
7566401a | 8033 | + |
6ed6bacf AM |
8034 | +class CallerIs (gdb.Function): |
8035 | + """Return True if the calling function's name is equal to a string. | |
8036 | +This function takes one or two arguments. | |
8037 | +The first argument is the name of a function; if the calling function's | |
8038 | +name is equal to this argument, this function returns True. | |
8039 | +The optional second argument tells this function how many stack frames | |
8040 | +to traverse to find the calling function. The default is 1.""" | |
3a58abaf | 8041 | + |
6ed6bacf AM |
8042 | + def __init__ (self): |
8043 | + super (CallerIs, self).__init__ ("caller_is") | |
3a58abaf | 8044 | + |
6ed6bacf AM |
8045 | + def invoke (self, name, nframes = 1): |
8046 | + frame = gdb.selected_frame () | |
8047 | + while nframes > 0: | |
8048 | + frame = frame.older () | |
8049 | + nframes = nframes - 1 | |
8050 | + return frame.name () == name.string () | |
3a58abaf | 8051 | + |
6ed6bacf AM |
8052 | +class CallerMatches (gdb.Function): |
8053 | + """Return True if the calling function's name matches a string. | |
8054 | +This function takes one or two arguments. | |
8055 | +The first argument is a regular expression; if the calling function's | |
8056 | +name is matched by this argument, this function returns True. | |
8057 | +The optional second argument tells this function how many stack frames | |
8058 | +to traverse to find the calling function. The default is 1.""" | |
3a58abaf | 8059 | + |
6ed6bacf AM |
8060 | + def __init__ (self): |
8061 | + super (CallerMatches, self).__init__ ("caller_matches") | |
3a58abaf | 8062 | + |
6ed6bacf AM |
8063 | + def invoke (self, name, nframes = 1): |
8064 | + frame = gdb.selected_frame () | |
8065 | + while nframes > 0: | |
8066 | + frame = frame.older () | |
8067 | + nframes = nframes - 1 | |
8068 | + return re.match (name.string (), frame.name ()) is not None | |
3a58abaf | 8069 | + |
6ed6bacf AM |
8070 | +CallerIs() |
8071 | +CallerMatches() | |
f412e1b4 PS |
8072 | diff --git a/gdb/python/lib/gdb/function/in_scope.py b/gdb/python/lib/gdb/function/in_scope.py |
8073 | new file mode 100644 | |
8074 | index 0000000..debb3bb | |
8075 | --- /dev/null | |
8076 | +++ b/gdb/python/lib/gdb/function/in_scope.py | |
6ed6bacf AM |
8077 | @@ -0,0 +1,47 @@ |
8078 | +# In-scope function. | |
3a58abaf | 8079 | + |
6ed6bacf | 8080 | +# Copyright (C) 2008 Free Software Foundation, Inc. |
3a58abaf | 8081 | + |
6ed6bacf AM |
8082 | +# This program is free software; you can redistribute it and/or modify |
8083 | +# it under the terms of the GNU General Public License as published by | |
8084 | +# the Free Software Foundation; either version 3 of the License, or | |
8085 | +# (at your option) any later version. | |
8086 | +# | |
8087 | +# This program is distributed in the hope that it will be useful, | |
8088 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
8089 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
8090 | +# GNU General Public License for more details. | |
8091 | +# | |
8092 | +# You should have received a copy of the GNU General Public License | |
8093 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 8094 | + |
6ed6bacf | 8095 | +import gdb |
3a58abaf | 8096 | + |
6ed6bacf AM |
8097 | +class InScope (gdb.Function): |
8098 | + """Return True if all the given variables or macros are in scope. | |
8099 | +Takes one argument for each variable name to be checked.""" | |
3a58abaf | 8100 | + |
6ed6bacf AM |
8101 | + def __init__ (self): |
8102 | + super (InScope, self).__init__ ("in_scope") | |
3a58abaf | 8103 | + |
6ed6bacf AM |
8104 | + def invoke (self, *vars): |
8105 | + if len (vars) == 0: | |
8106 | + raise TypeError, "in_scope takes at least one argument" | |
3a58abaf | 8107 | + |
6ed6bacf AM |
8108 | + # gdb.Value isn't hashable so it can't be put in a map. |
8109 | + # Convert to string first. | |
8110 | + wanted = set (map (lambda x: x.string (), vars)) | |
8111 | + found = set () | |
8112 | + block = gdb.selected_frame ().block () | |
8113 | + while block: | |
8114 | + for sym in block: | |
8115 | + if (sym.is_argument or sym.is_constant | |
8116 | + or sym.is_function or sym.is_variable): | |
8117 | + if sym.name in wanted: | |
8118 | + found.add (sym.name) | |
3a58abaf | 8119 | + |
6ed6bacf | 8120 | + block = block.superblock |
3a58abaf | 8121 | + |
6ed6bacf AM |
8122 | + return wanted == found |
8123 | + | |
8124 | +InScope () | |
f412e1b4 PS |
8125 | diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c |
8126 | index dadb037..864da99 100644 | |
8127 | --- a/gdb/python/py-type.c | |
8128 | +++ b/gdb/python/py-type.c | |
8129 | @@ -30,6 +30,8 @@ | |
6ed6bacf AM |
8130 | #include "vec.h" |
8131 | #include "bcache.h" | |
f412e1b4 | 8132 | #include "dwarf2loc.h" |
6ed6bacf AM |
8133 | +#include "observer.h" |
8134 | +#include "gdb_assert.h" | |
51a5ef0f | 8135 | |
6ed6bacf AM |
8136 | typedef struct pyty_type_object |
8137 | { | |
f412e1b4 | 8138 | @@ -38,11 +40,19 @@ typedef struct pyty_type_object |
3a58abaf | 8139 | |
6ed6bacf AM |
8140 | /* If a Type object is associated with an objfile, it is kept on a |
8141 | doubly-linked list, rooted in the objfile. This lets us copy the | |
8142 | - underlying struct type when the objfile is deleted. */ | |
8143 | + underlying struct type when the objfile is deleted. | |
3a58abaf | 8144 | + |
6ed6bacf AM |
8145 | + With NULL objfile Type still can be doubly-linked in the list |
8146 | + PYTY_OBJECTS_DISCARDABLE. */ | |
8147 | struct pyty_type_object *prev; | |
8148 | struct pyty_type_object *next; | |
8149 | } type_object; | |
8150 | ||
8151 | +#if 0 | |
8152 | +/* First element of a doubly-linked list of TYPE_DISCARDABLE Types. */ | |
8153 | +static type_object *pyty_objects_discardable; | |
3a58abaf | 8154 | +#endif |
6ed6bacf AM |
8155 | + |
8156 | static PyTypeObject type_object_type; | |
3a58abaf | 8157 | |
6ed6bacf | 8158 | /* A Field object. */ |
f412e1b4 | 8159 | @@ -1150,8 +1160,63 @@ typy_richcompare (PyObject *self, PyObject *other, int op) |
3a58abaf | 8160 | |
6ed6bacf | 8161 | \f |
3a58abaf | 8162 | |
6ed6bacf AM |
8163 | +/* Key associated with each objfile pointing to the first element of |
8164 | + a doubly-linked list of Types associated with this objfile. */ | |
8165 | static const struct objfile_data *typy_objfile_data_key; | |
8166 | ||
8167 | +/* Link TYPE_OBJ to its appropriate list. Either to its objfile associated one | |
8168 | + or at least to the global list for TYPE_DISCARDABLE Types. Permanent types | |
8169 | + do not get linked anywhere. */ | |
8170 | +static void | |
8171 | +typy_link (type_object *type_obj) | |
8172 | +{ | |
8173 | + type_obj->prev = NULL; | |
8174 | + | |
8175 | + if (type_obj->type && TYPE_OBJFILE (type_obj->type)) | |
51a5ef0f | 8176 | + { |
6ed6bacf | 8177 | + struct objfile *objfile = TYPE_OBJFILE (type_obj->type); |
3a58abaf | 8178 | + |
6ed6bacf AM |
8179 | + type_obj->next = objfile_data (objfile, typy_objfile_data_key); |
8180 | + if (type_obj->next) | |
8181 | + type_obj->next->prev = type_obj; | |
8182 | + set_objfile_data (objfile, typy_objfile_data_key, type_obj); | |
3a58abaf | 8183 | + } |
6ed6bacf AM |
8184 | +#if 0 |
8185 | + else if (type_obj->type && TYPE_DISCARDABLE (type_obj->type)) | |
3a58abaf | 8186 | + { |
6ed6bacf AM |
8187 | + type_obj->next = pyty_objects_discardable; |
8188 | + if (type_obj->next) | |
8189 | + type_obj->next->prev = type_obj; | |
8190 | + pyty_objects_discardable = type_obj; | |
8191 | + } | |
3a58abaf | 8192 | +#endif |
6ed6bacf AM |
8193 | + else |
8194 | + type_obj->next = NULL; | |
8195 | +} | |
3a58abaf | 8196 | + |
6ed6bacf AM |
8197 | +/* Unlink TYPE_OBJ from its current list. Permanent types are not linked |
8198 | + anywhere and this function has no effect on them. */ | |
8199 | +static void | |
8200 | +typy_unlink (type_object *type_obj) | |
51a5ef0f | 8201 | +{ |
6ed6bacf AM |
8202 | + if (type_obj->prev) |
8203 | + type_obj->prev->next = type_obj->next; | |
8204 | + else if (type_obj->type && TYPE_OBJFILE (type_obj->type)) | |
8205 | + { | |
8206 | + /* Must reset head of list. */ | |
8207 | + struct objfile *objfile = TYPE_OBJFILE (type_obj->type); | |
8208 | + | |
8209 | + set_objfile_data (objfile, typy_objfile_data_key, type_obj->next); | |
8210 | + } | |
8211 | +#if 0 | |
8212 | + else if (pyty_objects_discardable == type_obj) | |
8213 | + pyty_objects_discardable = type_obj->next; | |
8214 | +#endif | |
51a5ef0f | 8215 | + |
6ed6bacf AM |
8216 | + if (type_obj->next) |
8217 | + type_obj->next->prev = type_obj->prev; | |
51a5ef0f | 8218 | +} |
3a58abaf | 8219 | + |
6ed6bacf AM |
8220 | static void |
8221 | save_objfile_types (struct objfile *objfile, void *datum) | |
8222 | { | |
f412e1b4 | 8223 | @@ -1169,12 +1234,13 @@ save_objfile_types (struct objfile *objfile, void *datum) |
51a5ef0f | 8224 | { |
6ed6bacf | 8225 | type_object *next = obj->next; |
3a58abaf | 8226 | |
6ed6bacf AM |
8227 | - htab_empty (copied_types); |
8228 | + gdb_assert (TYPE_OBJFILE (obj->type) == objfile); | |
8229 | + typy_unlink (obj); | |
3a58abaf | 8230 | |
6ed6bacf AM |
8231 | - obj->type = copy_type_recursive (objfile, obj->type, copied_types); |
8232 | + obj->type = copy_type_recursive (obj->type, copied_types); | |
3a58abaf | 8233 | |
6ed6bacf AM |
8234 | - obj->next = NULL; |
8235 | - obj->prev = NULL; | |
8236 | + gdb_assert (TYPE_OBJFILE (obj->type) == NULL); | |
8237 | + typy_link (obj); | |
3a58abaf | 8238 | |
6ed6bacf | 8239 | obj = next; |
51a5ef0f | 8240 | } |
f412e1b4 | 8241 | @@ -1185,43 +1251,28 @@ save_objfile_types (struct objfile *objfile, void *datum) |
51a5ef0f | 8242 | } |
6ed6bacf AM |
8243 | |
8244 | static void | |
8245 | -set_type (type_object *obj, struct type *type) | |
8246 | +typy_dealloc (PyObject *obj) | |
8247 | { | |
8248 | - obj->type = type; | |
8249 | - obj->prev = NULL; | |
8250 | - if (type && TYPE_OBJFILE (type)) | |
8251 | - { | |
8252 | - struct objfile *objfile = TYPE_OBJFILE (type); | |
f412e1b4 PS |
8253 | + type_object *type_obj = (type_object *) obj; |
8254 | ||
6ed6bacf AM |
8255 | - obj->next = objfile_data (objfile, typy_objfile_data_key); |
8256 | - if (obj->next) | |
8257 | - obj->next->prev = obj; | |
8258 | - set_objfile_data (objfile, typy_objfile_data_key, obj); | |
8259 | - } | |
8260 | - else | |
8261 | - obj->next = NULL; | |
6ed6bacf | 8262 | + typy_unlink (type_obj); |
51a5ef0f | 8263 | + |
6ed6bacf AM |
8264 | + type_obj->ob_type->tp_free (obj); |
8265 | } | |
3a58abaf | 8266 | |
6ed6bacf AM |
8267 | +#if 0 |
8268 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ | |
8269 | static void | |
8270 | -typy_dealloc (PyObject *obj) | |
8271 | +typy_types_mark_used (void) | |
8272 | { | |
8273 | - type_object *type = (type_object *) obj; | |
8274 | - | |
8275 | - if (type->prev) | |
8276 | - type->prev->next = type->next; | |
8277 | - else if (type->type && TYPE_OBJFILE (type->type)) | |
8278 | - { | |
8279 | - /* Must reset head of list. */ | |
8280 | - struct objfile *objfile = TYPE_OBJFILE (type->type); | |
8281 | - | |
8282 | - if (objfile) | |
8283 | - set_objfile_data (objfile, typy_objfile_data_key, type->next); | |
8284 | - } | |
8285 | - if (type->next) | |
8286 | - type->next->prev = type->prev; | |
8287 | + type_object *type_obj; | |
51a5ef0f | 8288 | |
6ed6bacf AM |
8289 | - type->ob_type->tp_free (type); |
8290 | + for (type_obj = pyty_objects_discardable; | |
8291 | + type_obj != NULL; | |
8292 | + type_obj = type_obj->next) | |
8293 | + type_mark_used (type_obj->type); | |
8294 | } | |
8295 | +#endif | |
3a58abaf | 8296 | |
f412e1b4 PS |
8297 | /* Return number of fields ("length" of the field dictionary). */ |
8298 | ||
8299 | @@ -1444,7 +1495,10 @@ type_to_type_object (struct type *type) | |
51a5ef0f | 8300 | |
6ed6bacf AM |
8301 | type_obj = PyObject_New (type_object, &type_object_type); |
8302 | if (type_obj) | |
8303 | - set_type (type_obj, type); | |
8304 | + { | |
8305 | + type_obj->type = type; | |
8306 | + typy_link (type_obj); | |
8307 | + } | |
51a5ef0f | 8308 | |
6ed6bacf AM |
8309 | return (PyObject *) type_obj; |
8310 | } | |
f412e1b4 | 8311 | @@ -1524,6 +1578,10 @@ gdbpy_initialize_types (void) |
51a5ef0f | 8312 | |
6ed6bacf AM |
8313 | Py_INCREF (&field_object_type); |
8314 | PyModule_AddObject (gdb_module, "Field", (PyObject *) &field_object_type); | |
8315 | + | |
8316 | +#if 0 | |
8317 | + observer_attach_mark_used (typy_types_mark_used); | |
8318 | +#endif | |
8319 | } | |
51a5ef0f | 8320 | |
6ed6bacf | 8321 | \f |
f412e1b4 PS |
8322 | diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c |
8323 | index 760360e..d935f54 100644 | |
8324 | --- a/gdb/python/py-value.c | |
8325 | +++ b/gdb/python/py-value.c | |
6ed6bacf AM |
8326 | @@ -28,6 +28,7 @@ |
8327 | #include "infcall.h" | |
8328 | #include "expression.h" | |
8329 | #include "cp-abi.h" | |
8330 | +#include "observer.h" | |
51a5ef0f | 8331 | |
6ed6bacf | 8332 | #ifdef HAVE_PYTHON |
51a5ef0f | 8333 | |
f412e1b4 | 8334 | @@ -1335,6 +1336,19 @@ gdbpy_is_value_object (PyObject *obj) |
6ed6bacf | 8335 | return PyObject_TypeCheck (obj, &value_object_type); |
51a5ef0f PS |
8336 | } |
8337 | ||
6ed6bacf AM |
8338 | +#if 0 |
8339 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ | |
8340 | + | |
8341 | +static void | |
8342 | +python_types_mark_used (void) | |
8343 | +{ | |
8344 | + value_object *iter; | |
8345 | + | |
8346 | + for (iter = values_in_python; iter; iter = iter->next) | |
8347 | + type_mark_used (value_type (iter->value)); | |
8348 | +} | |
8349 | +#endif | |
8350 | + | |
8351 | void | |
8352 | gdbpy_initialize_values (void) | |
51a5ef0f | 8353 | { |
f412e1b4 | 8354 | @@ -1345,6 +1359,10 @@ gdbpy_initialize_values (void) |
6ed6bacf | 8355 | PyModule_AddObject (gdb_module, "Value", (PyObject *) &value_object_type); |
51a5ef0f | 8356 | |
6ed6bacf AM |
8357 | values_in_python = NULL; |
8358 | + | |
8359 | +#if 0 | |
8360 | + observer_attach_mark_used (python_types_mark_used); | |
8361 | +#endif | |
8362 | } | |
51a5ef0f | 8363 | |
6ed6bacf | 8364 | \f |
f412e1b4 PS |
8365 | diff --git a/gdb/python/python.c b/gdb/python/python.c |
8366 | index 5a0d776..af01dfd 100644 | |
8367 | --- a/gdb/python/python.c | |
8368 | +++ b/gdb/python/python.c | |
8369 | @@ -66,10 +66,13 @@ static const char *gdbpy_should_print_stack = python_excp_message; | |
6ed6bacf AM |
8370 | #include "linespec.h" |
8371 | #include "source.h" | |
8372 | #include "version.h" | |
8373 | +#include "inferior.h" | |
8374 | +#include "gdbthread.h" | |
8375 | #include "target.h" | |
8376 | #include "gdbthread.h" | |
f412e1b4 PS |
8377 | #include "observer.h" |
8378 | #include "interps.h" | |
6ed6bacf | 8379 | +#include "event-top.h" |
51a5ef0f | 8380 | |
6ed6bacf AM |
8381 | static PyMethodDef GdbMethods[]; |
8382 | ||
f412e1b4 | 8383 | @@ -946,6 +949,53 @@ gdbpy_print_stack (void) |
6ed6bacf AM |
8384 | |
8385 | /* Return the current Progspace. | |
8386 | There always is one. */ | |
8387 | +/* True if 'gdb -P' was used, false otherwise. */ | |
8388 | +static int running_python_script; | |
3a58abaf | 8389 | + |
6ed6bacf AM |
8390 | +/* True if we are currently in a call to 'gdb.cli', false otherwise. */ |
8391 | +static int in_cli; | |
7566401a | 8392 | + |
6ed6bacf AM |
8393 | +/* Enter the command loop. */ |
8394 | + | |
8395 | +static PyObject * | |
8396 | +gdbpy_cli (PyObject *unused1, PyObject *unused2) | |
7566401a | 8397 | +{ |
6ed6bacf AM |
8398 | + if (! running_python_script || in_cli) |
8399 | + return PyErr_Format (PyExc_RuntimeError, "cannot invoke CLI recursively"); | |
7566401a | 8400 | + |
6ed6bacf AM |
8401 | + in_cli = 1; |
8402 | + cli_command_loop (); | |
8403 | + in_cli = 0; | |
8404 | + | |
8405 | + Py_RETURN_NONE; | |
7566401a ER |
8406 | +} |
8407 | + | |
6ed6bacf AM |
8408 | +/* Set up the Python argument vector and evaluate a script. This is |
8409 | + used to implement 'gdb -P'. */ | |
7566401a ER |
8410 | + |
8411 | +void | |
6ed6bacf | 8412 | +run_python_script (int argc, char **argv) |
7566401a | 8413 | +{ |
6ed6bacf AM |
8414 | + FILE *input; |
8415 | + | |
8416 | + /* We never free this, since we plan to exit at the end. */ | |
8417 | + ensure_python_env (get_current_arch (), current_language); | |
8418 | + | |
8419 | + running_python_script = 1; | |
8420 | + PySys_SetArgv (argc - 1, argv + 1); | |
8421 | + input = fopen (argv[0], "r"); | |
8422 | + if (! input) | |
8423 | + { | |
8424 | + fprintf (stderr, "could not open %s: %s\n", argv[0], strerror (errno)); | |
8425 | + exit (1); | |
8426 | + } | |
8427 | + PyRun_SimpleFile (input, argv[0]); | |
8428 | + fclose (input); | |
8429 | + exit (0); | |
8430 | +} | |
8431 | + | |
8432 | +\f | |
8433 | + | |
51a5ef0f | 8434 | |
6ed6bacf AM |
8435 | static PyObject * |
8436 | gdbpy_get_current_progspace (PyObject *unused1, PyObject *unused2) | |
f412e1b4 | 8437 | @@ -1386,6 +1436,8 @@ static PyMethodDef GdbMethods[] = |
6ed6bacf AM |
8438 | "Get a value from history" }, |
8439 | { "execute", (PyCFunction) execute_gdb_command, METH_VARARGS | METH_KEYWORDS, | |
8440 | "Execute a gdb command" }, | |
8441 | + { "cli", gdbpy_cli, METH_NOARGS, | |
8442 | + "Enter the gdb CLI" }, | |
8443 | { "parameter", gdbpy_parameter, METH_VARARGS, | |
8444 | "Return a gdb parameter's value" }, | |
7566401a | 8445 | |
f412e1b4 PS |
8446 | diff --git a/gdb/python/python.h b/gdb/python/python.h |
8447 | index 9e461f7..57b21da 100644 | |
8448 | --- a/gdb/python/python.h | |
8449 | +++ b/gdb/python/python.h | |
8450 | @@ -32,6 +32,8 @@ void eval_python_from_control_command (struct command_line *); | |
8451 | ||
8452 | void source_python_script (const char *file); | |
8453 | ||
8454 | +void run_python_script (int argc, char **argv); | |
8455 | + | |
8456 | int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, | |
8457 | int embedded_offset, CORE_ADDR address, | |
8458 | struct ui_file *stream, int recurse, | |
8459 | diff --git a/gdb/remote.c b/gdb/remote.c | |
8460 | index f348536..e20f6bf 100644 | |
8461 | --- a/gdb/remote.c | |
8462 | +++ b/gdb/remote.c | |
8463 | @@ -9948,7 +9948,7 @@ remote_download_tracepoint (struct bp_location *loc) | |
8464 | char **stepping_actions; | |
8465 | int ndx; | |
8466 | struct cleanup *old_chain = NULL; | |
8467 | - struct agent_expr *aexpr; | |
8468 | + struct agent_expr *aexpr = NULL; | |
8469 | struct cleanup *aexpr_chain = NULL; | |
8470 | char *pkt; | |
8471 | struct breakpoint *b = loc->owner; | |
8472 | diff --git a/gdb/s390-nat.c b/gdb/s390-nat.c | |
8473 | index 2755e58..8df3fd1 100644 | |
8474 | --- a/gdb/s390-nat.c | |
8475 | +++ b/gdb/s390-nat.c | |
8476 | @@ -515,6 +515,17 @@ s390_fix_watch_points (struct lwp_info *lp) | |
8477 | perror_with_name (_("Couldn't modify watchpoint status")); | |
8478 | } | |
8479 | ||
8480 | +/* Callback for iterate_over_lwps, to call s390_fix_watch_points. */ | |
8481 | + | |
8482 | +static int | |
8483 | +s390_fix_watch_points_iterate (struct lwp_info *lp, void *arg) | |
8484 | +{ | |
8485 | + s390_fix_watch_points (lp); | |
8486 | + | |
8487 | + /* Continue the traversal. */ | |
8488 | + return 0; | |
8489 | +} | |
8490 | + | |
8491 | static int | |
8492 | s390_insert_watchpoint (CORE_ADDR addr, int len, int type, | |
8493 | struct expression *cond) | |
8494 | @@ -531,8 +542,8 @@ s390_insert_watchpoint (CORE_ADDR addr, int len, int type, | |
8495 | area->next = watch_base; | |
8496 | watch_base = area; | |
8497 | ||
8498 | - ALL_LWPS (lp) | |
8499 | - s390_fix_watch_points (lp); | |
8500 | + iterate_over_lwps (minus_one_ptid, s390_fix_watch_points_iterate, NULL); | |
8501 | + | |
8502 | return 0; | |
8503 | } | |
8504 | ||
8505 | @@ -559,8 +570,8 @@ s390_remove_watchpoint (CORE_ADDR addr, int len, int type, | |
8506 | *parea = area->next; | |
8507 | xfree (area); | |
8508 | ||
8509 | - ALL_LWPS (lp) | |
8510 | - s390_fix_watch_points (lp); | |
8511 | + iterate_over_lwps (minus_one_ptid, s390_fix_watch_points_iterate, NULL); | |
8512 | + | |
8513 | return 0; | |
8514 | } | |
8515 | ||
8516 | diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c | |
8517 | index ac0c526..dd0e477 100644 | |
8518 | --- a/gdb/s390-tdep.c | |
8519 | +++ b/gdb/s390-tdep.c | |
8520 | @@ -55,6 +55,12 @@ | |
8521 | #include "features/s390x-linux64v1.c" | |
8522 | #include "features/s390x-linux64v2.c" | |
8523 | ||
8524 | +#include "stap-probe.h" | |
8525 | +#include "ax.h" | |
8526 | +#include "ax-gdb.h" | |
8527 | +#include "user-regs.h" | |
8528 | +#include "cli/cli-utils.h" | |
8529 | +#include <ctype.h> | |
8530 | ||
8531 | /* The tdep structure. */ | |
8532 | ||
8533 | @@ -2953,6 +2959,15 @@ s390_address_class_name_to_type_flags (struct gdbarch *gdbarch, | |
8534 | return 0; | |
8535 | } | |
8536 | ||
8537 | +static int | |
8538 | +s390_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) | |
8539 | +{ | |
8540 | + return ((isdigit (*s) && s[1] == '(' && s[2] == '%') /* Displacement | |
8541 | + or indirection. */ | |
8542 | + || *s == '%' /* Register access. */ | |
8543 | + || isdigit (*s)); /* Literal number. */ | |
8544 | +} | |
8545 | + | |
8546 | /* Set up gdbarch struct. */ | |
8547 | ||
8548 | static struct gdbarch * | |
8549 | @@ -3283,6 +3298,12 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | |
7566401a | 8550 | |
f412e1b4 | 8551 | set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type); |
7566401a | 8552 | |
f412e1b4 PS |
8553 | + /* SystemTap functions. */ |
8554 | + set_gdbarch_stap_register_prefix (gdbarch, "%"); | |
8555 | + set_gdbarch_stap_register_indirection_prefix (gdbarch, "("); | |
8556 | + set_gdbarch_stap_register_indirection_sufix (gdbarch, ")"); | |
8557 | + set_gdbarch_stap_is_single_operand (gdbarch, s390_stap_is_single_operand); | |
6ed6bacf | 8558 | + |
f412e1b4 PS |
8559 | return gdbarch; |
8560 | } | |
8561 | ||
8562 | diff --git a/gdb/somread.c b/gdb/somread.c | |
8563 | index e621cba..19a15e2 100644 | |
8564 | --- a/gdb/somread.c | |
8565 | +++ b/gdb/somread.c | |
8566 | @@ -427,6 +427,7 @@ static const struct sym_fns som_sym_fns = | |
6ed6bacf AM |
8567 | default_symfile_segments, /* Get segment information from a file. */ |
8568 | NULL, | |
8569 | default_symfile_relocate, /* Relocate a debug section. */ | |
8570 | + NULL, /* sym_get_probes */ | |
8571 | &psym_functions | |
8572 | }; | |
8573 | ||
f412e1b4 PS |
8574 | diff --git a/gdb/stack.c b/gdb/stack.c |
8575 | index b15b5fc..b2dad29 100644 | |
8576 | --- a/gdb/stack.c | |
8577 | +++ b/gdb/stack.c | |
8578 | @@ -509,6 +509,10 @@ print_frame_args (struct symbol *func, struct frame_info *frame, | |
8579 | stb = ui_out_stream_new (uiout); | |
8580 | old_chain = make_cleanup_ui_out_stream_delete (stb); | |
8581 | ||
8582 | + /* Frame may be needed for check_typedef of TYPE_DYNAMIC. */ | |
8583 | + make_cleanup_restore_selected_frame (); | |
8584 | + select_frame (frame); | |
8585 | + | |
8586 | if (func) | |
8587 | { | |
8588 | struct block *b = SYMBOL_BLOCK_VALUE (func); | |
8589 | diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c | |
8590 | new file mode 100644 | |
8591 | index 0000000..123530f | |
8592 | --- /dev/null | |
8593 | +++ b/gdb/stap-probe.c | |
8594 | @@ -0,0 +1,1672 @@ | |
6ed6bacf AM |
8595 | +/* SystemTap probe support for GDB. |
8596 | + | |
8597 | + Copyright (C) 2011 Free Software Foundation, Inc. | |
8598 | + | |
8599 | + This file is part of GDB. | |
8600 | + | |
8601 | + This program is free software; you can redistribute it and/or modify | |
8602 | + it under the terms of the GNU General Public License as published by | |
8603 | + the Free Software Foundation; either version 3 of the License, or | |
8604 | + (at your option) any later version. | |
7566401a | 8605 | + |
6ed6bacf AM |
8606 | + This program is distributed in the hope that it will be useful, |
8607 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
8608 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
8609 | + GNU General Public License for more details. | |
7566401a | 8610 | + |
6ed6bacf AM |
8611 | + You should have received a copy of the GNU General Public License |
8612 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
7566401a | 8613 | + |
6ed6bacf AM |
8614 | +#include "defs.h" |
8615 | +#include "stap-probe.h" | |
8616 | +#include "vec.h" | |
8617 | +#include "ui-out.h" | |
8618 | +#include "gdb_regex.h" | |
8619 | +#include "objfiles.h" | |
8620 | +#include "arch-utils.h" | |
8621 | +#include "command.h" | |
f412e1b4 | 8622 | +#include "gdbcmd.h" |
6ed6bacf AM |
8623 | +#include "filenames.h" |
8624 | +#include "value.h" | |
8625 | +#include "exceptions.h" | |
8626 | +#include "ax.h" | |
8627 | +#include "ax-gdb.h" | |
6ed6bacf AM |
8628 | +#include "complaints.h" |
8629 | +#include "cli/cli-utils.h" | |
8630 | +#include "linespec.h" | |
f412e1b4 PS |
8631 | +#include "user-regs.h" |
8632 | +#include "parser-defs.h" | |
8633 | +#include "language.h" | |
7566401a | 8634 | + |
6ed6bacf | 8635 | +#include <ctype.h> |
7566401a | 8636 | + |
f412e1b4 PS |
8637 | +/* The maximum number of arguments that a probe can have, |
8638 | + as defined in <sys/sdt.h>. */ | |
8639 | + | |
8640 | +#define STAP_MAX_ARGS 12 | |
7566401a | 8641 | + |
f412e1b4 PS |
8642 | +/* Should we display debug information for the probe's argument expression |
8643 | + parsing? */ | |
8644 | + | |
8645 | +static int stap_expression_debug = 0; | |
3a58abaf | 8646 | + |
6ed6bacf | 8647 | +/* The various possibilities of bitness defined for a probe's argument. |
7566401a | 8648 | + |
6ed6bacf | 8649 | + The relationship is: |
7566401a | 8650 | + |
6ed6bacf AM |
8651 | + - STAP_ARG_BITNESS_UNDEFINED: The user hasn't specified the bitness. |
8652 | + - STAP_ARG_BITNESS_32BIT_UNSIGNED: argument string starts with `4@'. | |
8653 | + - STAP_ARG_BITNESS_32BIT_SIGNED: argument string starts with `-4@'. | |
8654 | + - STAP_ARG_BITNESS_64BIT_UNSIGNED: argument string starts with `8@'. | |
8655 | + - STAP_ARG_BITNESS_64BIT_SIGNED: argument string starts with `-8@'. */ | |
8656 | + | |
8657 | +enum stap_arg_bitness | |
7566401a | 8658 | +{ |
6ed6bacf AM |
8659 | + STAP_ARG_BITNESS_UNDEFINED, |
8660 | + STAP_ARG_BITNESS_32BIT_UNSIGNED, | |
8661 | + STAP_ARG_BITNESS_32BIT_SIGNED, | |
8662 | + STAP_ARG_BITNESS_64BIT_UNSIGNED, | |
8663 | + STAP_ARG_BITNESS_64BIT_SIGNED, | |
8664 | +}; | |
7566401a | 8665 | + |
6ed6bacf | 8666 | +/* The following structure represents a single argument for the probe. */ |
7566401a | 8667 | + |
6ed6bacf AM |
8668 | +struct stap_probe_arg |
8669 | +{ | |
8670 | + /* The bitness of this argument. */ | |
8671 | + enum stap_arg_bitness bitness; | |
7566401a | 8672 | + |
f412e1b4 PS |
8673 | + /* The corresponding `struct type *' to the bitness. */ |
8674 | + struct type *atype; | |
6ed6bacf | 8675 | + |
f412e1b4 PS |
8676 | + /* The argument converted to an internal GDB expression. */ |
8677 | + struct expression *aexpr; | |
8678 | +}; | |
6ed6bacf AM |
8679 | + |
8680 | +/* Structure that holds information about all arguments of a probe. */ | |
8681 | + | |
8682 | +struct stap_args_info | |
51a5ef0f | 8683 | +{ |
6ed6bacf AM |
8684 | + /* The number of valid parsed arguments. */ |
8685 | + int n_args; | |
3a58abaf | 8686 | + |
6ed6bacf AM |
8687 | + /* The probe to which these arguments belong. */ |
8688 | + struct stap_probe *probe; | |
51a5ef0f | 8689 | + |
f412e1b4 PS |
8690 | + /* Information about each argument. This is an array of `stap_probe_arg', |
8691 | + with each entry representing one argument. */ | |
8692 | + struct stap_probe_arg *args; | |
6ed6bacf | 8693 | +}; |
7566401a | 8694 | + |
f412e1b4 PS |
8695 | +/* When parsing the arguments, we have to establish different precedences |
8696 | + for the various kinds of asm operators. This enumeration represents those | |
8697 | + precedences. | |
3a58abaf | 8698 | + |
f412e1b4 PS |
8699 | + This logic behind this is available at |
8700 | + <http://sourceware.org/binutils/docs/as/Infix-Ops.html#Infix-Ops>, or using | |
8701 | + the command "info '(as)Infix Ops'". */ | |
3a58abaf | 8702 | + |
f412e1b4 | 8703 | +enum stap_operand_prec |
6ed6bacf | 8704 | +{ |
f412e1b4 PS |
8705 | + /* Lowest precedence, used for non-recognized operands or for the beginning |
8706 | + of the parsing process. */ | |
8707 | + STAP_OPERAND_PREC_NONE = 0, | |
3a58abaf | 8708 | + |
f412e1b4 PS |
8709 | + /* Precedence of logical OR. */ |
8710 | + STAP_OPERAND_PREC_LOGICAL_OR, | |
3a58abaf | 8711 | + |
f412e1b4 PS |
8712 | + /* Precedence of logical AND. */ |
8713 | + STAP_OPERAND_PREC_LOGICAL_AND, | |
3a58abaf | 8714 | + |
f412e1b4 PS |
8715 | + /* Precedence of additive (plus, minus) and comparative (equal, less, |
8716 | + greater-than, etc) operands. */ | |
8717 | + STAP_OPERAND_PREC_ADD_CMP, | |
3a58abaf | 8718 | + |
f412e1b4 PS |
8719 | + /* Precedence of bitwise operands (bitwise OR, XOR, bitwise AND, |
8720 | + logical NOT). */ | |
8721 | + STAP_OPERAND_PREC_BITWISE, | |
3a58abaf | 8722 | + |
f412e1b4 PS |
8723 | + /* Precedence of multiplicative operands (multiplication, division, |
8724 | + remainder, left shift and right shift). */ | |
8725 | + STAP_OPERAND_PREC_MUL | |
8726 | +}; | |
3a58abaf | 8727 | + |
f412e1b4 PS |
8728 | +/* This dummy variable is used when parsing a probe's argument fails. |
8729 | + In this case, the number of arguments for this probe is zero, so that's | |
8730 | + why this variable is useful. */ | |
3a58abaf | 8731 | + |
f412e1b4 PS |
8732 | +static struct stap_args_info dummy_stap_args_info = |
8733 | + { 0, NULL, NULL }; | |
3a58abaf | 8734 | + |
f412e1b4 PS |
8735 | +static void stap_parse_argument_1 (struct stap_parse_info *p, int has_lhs, |
8736 | + enum stap_operand_prec prec); | |
3a58abaf | 8737 | + |
f412e1b4 | 8738 | +static void stap_parse_argument_conditionally (struct stap_parse_info *p); |
3a58abaf | 8739 | + |
f412e1b4 | 8740 | +/* Returns 1 if *S is an operator, zero otherwise. */ |
6ed6bacf | 8741 | + |
f412e1b4 | 8742 | +static int stap_is_operator (char op); |
6ed6bacf | 8743 | + |
f412e1b4 PS |
8744 | +static void |
8745 | +show_stapexpressiondebug (struct ui_file *file, int from_tty, | |
8746 | + struct cmd_list_element *c, const char *value) | |
8747 | +{ | |
8748 | + fprintf_filtered (file, _("SystemTap Probe expression debugging is %s.\n"), | |
8749 | + value); | |
6ed6bacf AM |
8750 | +} |
8751 | + | |
f412e1b4 PS |
8752 | +/* Returns the operator precedence level of OP, or STAP_OPERAND_PREC_NONE |
8753 | + if the operator code was not recognized. */ | |
6ed6bacf | 8754 | + |
f412e1b4 | 8755 | +static enum stap_operand_prec |
6ed6bacf AM |
8756 | +stap_get_operator_prec (enum exp_opcode op) |
8757 | +{ | |
8758 | + switch (op) | |
8759 | + { | |
8760 | + case BINOP_LOGICAL_OR: | |
f412e1b4 | 8761 | + return STAP_OPERAND_PREC_LOGICAL_OR; |
3a58abaf | 8762 | + |
6ed6bacf | 8763 | + case BINOP_LOGICAL_AND: |
f412e1b4 | 8764 | + return STAP_OPERAND_PREC_LOGICAL_AND; |
3a58abaf | 8765 | + |
f412e1b4 PS |
8766 | + case BINOP_ADD: |
8767 | + case BINOP_SUB: | |
8768 | + case BINOP_EQUAL: | |
8769 | + case BINOP_NOTEQUAL: | |
8770 | + case BINOP_LESS: | |
8771 | + case BINOP_LEQ: | |
8772 | + case BINOP_GTR: | |
8773 | + case BINOP_GEQ: | |
8774 | + return STAP_OPERAND_PREC_ADD_CMP; | |
3a58abaf | 8775 | + |
f412e1b4 PS |
8776 | + case BINOP_BITWISE_IOR: |
8777 | + case BINOP_BITWISE_AND: | |
8778 | + case BINOP_BITWISE_XOR: | |
8779 | + case UNOP_LOGICAL_NOT: | |
8780 | + return STAP_OPERAND_PREC_BITWISE; | |
3a58abaf | 8781 | + |
f412e1b4 PS |
8782 | + case BINOP_MUL: |
8783 | + case BINOP_DIV: | |
8784 | + case BINOP_REM: | |
8785 | + case BINOP_LSH: | |
8786 | + case BINOP_RSH: | |
8787 | + return STAP_OPERAND_PREC_MUL; | |
3a58abaf | 8788 | + |
6ed6bacf | 8789 | + default: |
f412e1b4 | 8790 | + return STAP_OPERAND_PREC_NONE; |
6ed6bacf AM |
8791 | + } |
8792 | +} | |
3a58abaf | 8793 | + |
f412e1b4 PS |
8794 | +/* Given S, read the operator in it and fills the OP pointer with its code. |
8795 | + Return 1 on success, zero if the operator was not recognized. */ | |
3a58abaf | 8796 | + |
6ed6bacf | 8797 | +static int |
f412e1b4 | 8798 | +stap_get_opcode (const char **s, enum exp_opcode *op) |
6ed6bacf | 8799 | +{ |
f412e1b4 | 8800 | + const char c = **s; |
6ed6bacf | 8801 | + int ret = 1; |
3a58abaf | 8802 | + |
6ed6bacf | 8803 | + *s += 1; |
3a58abaf | 8804 | + |
6ed6bacf AM |
8805 | + switch (c) |
8806 | + { | |
8807 | + case '*': | |
8808 | + *op = BINOP_MUL; | |
8809 | + break; | |
3a58abaf | 8810 | + |
6ed6bacf AM |
8811 | + case '/': |
8812 | + *op = BINOP_DIV; | |
8813 | + break; | |
3a58abaf | 8814 | + |
6ed6bacf | 8815 | + case '%': |
f412e1b4 | 8816 | + *op = BINOP_REM; |
6ed6bacf | 8817 | + break; |
3a58abaf | 8818 | + |
6ed6bacf AM |
8819 | + case '<': |
8820 | + *op = BINOP_LESS; | |
8821 | + if (**s == '<') | |
8822 | + { | |
8823 | + *s += 1; | |
8824 | + *op = BINOP_LSH; | |
8825 | + } | |
8826 | + else if (**s == '=') | |
8827 | + { | |
8828 | + *s += 1; | |
8829 | + *op = BINOP_LEQ; | |
8830 | + } | |
8831 | + else if (**s == '>') | |
8832 | + { | |
8833 | + *s += 1; | |
8834 | + *op = BINOP_NOTEQUAL; | |
8835 | + } | |
8836 | + break; | |
3a58abaf | 8837 | + |
6ed6bacf AM |
8838 | + case '>': |
8839 | + *op = BINOP_GTR; | |
8840 | + if (**s == '>') | |
8841 | + { | |
8842 | + *s += 1; | |
8843 | + *op = BINOP_RSH; | |
8844 | + } | |
8845 | + else if (**s == '=') | |
8846 | + { | |
8847 | + *s += 1; | |
8848 | + *op = BINOP_GEQ; | |
8849 | + } | |
8850 | + break; | |
3a58abaf | 8851 | + |
6ed6bacf AM |
8852 | + case '|': |
8853 | + *op = BINOP_BITWISE_IOR; | |
8854 | + if (**s == '|') | |
8855 | + { | |
8856 | + *s += 1; | |
8857 | + *op = BINOP_LOGICAL_OR; | |
8858 | + } | |
8859 | + break; | |
3a58abaf | 8860 | + |
6ed6bacf AM |
8861 | + case '&': |
8862 | + *op = BINOP_BITWISE_AND; | |
8863 | + if (**s == '&') | |
8864 | + { | |
8865 | + *s += 1; | |
8866 | + *op = BINOP_LOGICAL_AND; | |
8867 | + } | |
8868 | + break; | |
3a58abaf | 8869 | + |
6ed6bacf AM |
8870 | + case '^': |
8871 | + *op = BINOP_BITWISE_XOR; | |
8872 | + break; | |
3a58abaf | 8873 | + |
6ed6bacf AM |
8874 | + case '!': |
8875 | + *op = UNOP_LOGICAL_NOT; | |
8876 | + break; | |
3a58abaf | 8877 | + |
6ed6bacf AM |
8878 | + case '+': |
8879 | + *op = BINOP_ADD; | |
8880 | + break; | |
3a58abaf | 8881 | + |
6ed6bacf AM |
8882 | + case '-': |
8883 | + *op = BINOP_SUB; | |
8884 | + break; | |
3a58abaf | 8885 | + |
6ed6bacf AM |
8886 | + case '=': |
8887 | + if (**s != '=') | |
8888 | + { | |
8889 | + ret = 0; | |
8890 | + break; | |
8891 | + } | |
8892 | + *op = BINOP_EQUAL; | |
8893 | + break; | |
3a58abaf | 8894 | + |
6ed6bacf AM |
8895 | + default: |
8896 | + /* We didn't find any operator. */ | |
8897 | + *s -= 1; | |
8898 | + return 0; | |
8899 | + } | |
3a58abaf | 8900 | + |
6ed6bacf AM |
8901 | + return ret; |
8902 | +} | |
3a58abaf | 8903 | + |
f412e1b4 PS |
8904 | +/* Given the bitness of the argument, represented by B, return the |
8905 | + corresponding `struct type *'. */ | |
3a58abaf | 8906 | + |
f412e1b4 PS |
8907 | +static struct type * |
8908 | +stap_get_expected_argument_type (struct gdbarch *gdbarch, | |
8909 | + enum stap_arg_bitness b) | |
6ed6bacf | 8910 | +{ |
f412e1b4 | 8911 | + switch (b) |
6ed6bacf | 8912 | + { |
f412e1b4 PS |
8913 | + case STAP_ARG_BITNESS_UNDEFINED: |
8914 | + if (gdbarch_addr_bit (gdbarch) == 32) | |
8915 | + return builtin_type (gdbarch)->builtin_uint32; | |
8916 | + else | |
8917 | + return builtin_type (gdbarch)->builtin_uint64; | |
7566401a | 8918 | + |
f412e1b4 PS |
8919 | + case STAP_ARG_BITNESS_32BIT_SIGNED: |
8920 | + return builtin_type (gdbarch)->builtin_int32; | |
7566401a | 8921 | + |
f412e1b4 PS |
8922 | + case STAP_ARG_BITNESS_32BIT_UNSIGNED: |
8923 | + return builtin_type (gdbarch)->builtin_uint32; | |
7566401a | 8924 | + |
f412e1b4 PS |
8925 | + case STAP_ARG_BITNESS_64BIT_SIGNED: |
8926 | + return builtin_type (gdbarch)->builtin_int64; | |
7566401a | 8927 | + |
f412e1b4 PS |
8928 | + case STAP_ARG_BITNESS_64BIT_UNSIGNED: |
8929 | + return builtin_type (gdbarch)->builtin_uint64; | |
7566401a | 8930 | + |
6ed6bacf | 8931 | + default: |
f412e1b4 PS |
8932 | + internal_error (__FILE__, __LINE__, |
8933 | + _("Undefined bitness for probe.")); | |
8934 | + break; | |
6ed6bacf AM |
8935 | + } |
8936 | +} | |
7566401a | 8937 | + |
f412e1b4 PS |
8938 | +static void |
8939 | +stap_parse_register_operand (struct stap_parse_info *p) | |
8940 | +{ | |
8941 | + /* Simple flag to indicate whether we have seen a minus signal before | |
8942 | + certain number. */ | |
8943 | + int got_minus = 0; | |
8944 | + /* Flags to indicate whether this register access is being displaced and/or | |
8945 | + indirected. */ | |
8946 | + int disp_p = 0, indirect_p = 0; | |
8947 | + struct gdbarch *gdbarch = p->gdbarch; | |
8948 | + /* Needed to generate the register name as a part of an expression. */ | |
8949 | + struct stoken str; | |
8950 | + /* Variables used to extract the register name from the probe's | |
8951 | + argument. */ | |
6ed6bacf | 8952 | + const char *start; |
6ed6bacf | 8953 | + char *regname; |
f412e1b4 PS |
8954 | + int len; |
8955 | + | |
8956 | + /* Prefixes for the parser. */ | |
8957 | + const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch); | |
8958 | + const char *reg_ind_prefix | |
8959 | + = gdbarch_stap_register_indirection_prefix (gdbarch); | |
8960 | + const char *gdb_reg_prefix = gdbarch_stap_gdb_register_prefix (gdbarch); | |
8961 | + int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0; | |
8962 | + int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0; | |
8963 | + int gdb_reg_prefix_len = gdb_reg_prefix ? strlen (gdb_reg_prefix) : 0; | |
8964 | + | |
8965 | + /* Sufixes for the parser. */ | |
8966 | + const char *reg_sufix = gdbarch_stap_register_sufix (gdbarch); | |
8967 | + const char *reg_ind_sufix | |
8968 | + = gdbarch_stap_register_indirection_sufix (gdbarch); | |
8969 | + const char *gdb_reg_sufix = gdbarch_stap_gdb_register_sufix (gdbarch); | |
8970 | + int reg_sufix_len = reg_sufix ? strlen (reg_sufix) : 0; | |
8971 | + int reg_ind_sufix_len = reg_ind_sufix ? strlen (reg_ind_sufix) : 0; | |
8972 | + int gdb_reg_sufix_len = gdb_reg_sufix ? strlen (gdb_reg_sufix) : 0; | |
8973 | + | |
8974 | + /* Checking for a displacement argument. */ | |
8975 | + if (*p->arg == '+') | |
8976 | + /* If it's a plus sign, we don't need to do anything, just advance the | |
8977 | + pointer. */ | |
8978 | + ++p->arg; | |
8979 | + | |
8980 | + if (*p->arg == '-') | |
6ed6bacf | 8981 | + { |
f412e1b4 PS |
8982 | + got_minus = 1; |
8983 | + ++p->arg; | |
6ed6bacf | 8984 | + } |
f412e1b4 PS |
8985 | + |
8986 | + if (isdigit (*p->arg)) | |
6ed6bacf | 8987 | + { |
f412e1b4 PS |
8988 | + /* The value of the displacement. */ |
8989 | + long displacement; | |
8990 | + | |
8991 | + disp_p = 1; | |
8992 | + displacement = strtol (p->arg, (char **) &p->arg, 10); | |
8993 | + | |
8994 | + /* Generating the expression for the displacement. */ | |
8995 | + write_exp_elt_opcode (OP_LONG); | |
8996 | + write_exp_elt_type (builtin_type (gdbarch)->builtin_long); | |
8997 | + write_exp_elt_longcst (displacement); | |
8998 | + write_exp_elt_opcode (OP_LONG); | |
8999 | + if (got_minus) | |
9000 | + write_exp_elt_opcode (UNOP_NEG); | |
6ed6bacf | 9001 | + } |
3a58abaf | 9002 | + |
f412e1b4 PS |
9003 | + /* Getting rid of register indirection prefix. */ |
9004 | + if (reg_ind_prefix | |
9005 | + && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0) | |
6ed6bacf | 9006 | + { |
f412e1b4 PS |
9007 | + indirect_p = 1; |
9008 | + p->arg += reg_ind_prefix_len; | |
9009 | + } | |
3a58abaf | 9010 | + |
f412e1b4 PS |
9011 | + if (disp_p && !indirect_p) |
9012 | + error (_("Invalid register displacement syntax on expression `%s'."), | |
9013 | + p->saved_arg); | |
3a58abaf | 9014 | + |
f412e1b4 PS |
9015 | + /* Getting rid of register prefix. */ |
9016 | + if (reg_prefix && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0) | |
9017 | + p->arg += reg_prefix_len; | |
3a58abaf | 9018 | + |
f412e1b4 PS |
9019 | + /* Now we should have only the register name. Let's extract it and get |
9020 | + the associated number. */ | |
9021 | + start = p->arg; | |
3a58abaf | 9022 | + |
f412e1b4 PS |
9023 | + /* We assume the register name is composed by letters and numbers. */ |
9024 | + while (isalnum (*p->arg)) | |
9025 | + ++p->arg; | |
3a58abaf | 9026 | + |
f412e1b4 | 9027 | + len = p->arg - start; |
3a58abaf | 9028 | + |
f412e1b4 PS |
9029 | + regname = alloca (len + gdb_reg_prefix_len + gdb_reg_sufix_len + 1); |
9030 | + regname[0] = '\0'; | |
3a58abaf | 9031 | + |
f412e1b4 PS |
9032 | + /* We only add the GDB's register prefix/sufix if we are dealing with |
9033 | + a numeric register. */ | |
9034 | + if (gdb_reg_prefix && isdigit (*start)) | |
9035 | + { | |
9036 | + strncpy (regname, gdb_reg_prefix, gdb_reg_prefix_len); | |
9037 | + strncpy (regname + gdb_reg_prefix_len, start, len); | |
3a58abaf | 9038 | + |
f412e1b4 PS |
9039 | + if (gdb_reg_sufix) |
9040 | + strncpy (regname + gdb_reg_prefix_len + len, | |
9041 | + gdb_reg_sufix, gdb_reg_sufix_len); | |
3a58abaf | 9042 | + |
f412e1b4 | 9043 | + len += gdb_reg_prefix_len + gdb_reg_sufix_len; |
6ed6bacf | 9044 | + } |
f412e1b4 PS |
9045 | + else |
9046 | + strncpy (regname, start, len); | |
3a58abaf | 9047 | + |
f412e1b4 PS |
9048 | + regname[len] = '\0'; |
9049 | + /* Is this a valid register name? */ | |
9050 | + if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1) | |
9051 | + error (_("Invalid register name `%s' on expression `%s'."), | |
9052 | + regname, p->saved_arg); | |
3a58abaf | 9053 | + |
f412e1b4 PS |
9054 | + write_exp_elt_opcode (OP_REGISTER); |
9055 | + str.ptr = regname; | |
9056 | + str.length = len; | |
9057 | + write_exp_string (str); | |
9058 | + write_exp_elt_opcode (OP_REGISTER); | |
6ed6bacf | 9059 | + |
f412e1b4 | 9060 | + if (indirect_p) |
3a58abaf | 9061 | + { |
f412e1b4 PS |
9062 | + if (disp_p) |
9063 | + write_exp_elt_opcode (BINOP_ADD); | |
3a58abaf | 9064 | + |
f412e1b4 PS |
9065 | + /* Casting to the expected type. */ |
9066 | + write_exp_elt_opcode (UNOP_CAST); | |
9067 | + write_exp_elt_type (lookup_pointer_type (p->arg_type)); | |
9068 | + write_exp_elt_opcode (UNOP_CAST); | |
3a58abaf | 9069 | + |
f412e1b4 PS |
9070 | + write_exp_elt_opcode (UNOP_IND); |
9071 | + } | |
3a58abaf | 9072 | + |
f412e1b4 PS |
9073 | + /* Getting rid of the register name sufix. */ |
9074 | + if (reg_sufix) | |
9075 | + { | |
9076 | + if (strncmp (p->arg, reg_sufix, reg_sufix_len) != 0) | |
9077 | + error (_("Missing register name sufix `%s' on expression `%s'."), | |
9078 | + reg_sufix, p->saved_arg); | |
3a58abaf | 9079 | + |
f412e1b4 PS |
9080 | + p->arg += reg_sufix_len; |
9081 | + } | |
3a58abaf | 9082 | + |
f412e1b4 PS |
9083 | + /* Getting rid of the register indirection sufix. */ |
9084 | + if (indirect_p && reg_ind_sufix) | |
9085 | + { | |
9086 | + if (strncmp (p->arg, reg_ind_sufix, reg_ind_sufix_len) != 0) | |
9087 | + error (_("Missing indirection sufix `%s' on expression `%s'."), | |
9088 | + reg_ind_sufix, p->saved_arg); | |
3a58abaf | 9089 | + |
f412e1b4 PS |
9090 | + p->arg += reg_ind_sufix_len; |
9091 | + } | |
9092 | +} | |
51a5ef0f | 9093 | + |
f412e1b4 PS |
9094 | +static void |
9095 | +stap_parse_single_operand (struct stap_parse_info *p) | |
9096 | +{ | |
9097 | + struct gdbarch *gdbarch = p->gdbarch; | |
9098 | + /* Prefixes for the parser. */ | |
9099 | + const char *const_prefix = gdbarch_stap_integer_prefix (gdbarch); | |
9100 | + const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch); | |
9101 | + const char *reg_ind_prefix | |
9102 | + = gdbarch_stap_register_indirection_prefix (gdbarch); | |
9103 | + int const_prefix_len = const_prefix ? strlen (const_prefix) : 0; | |
9104 | + int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0; | |
9105 | + int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0; | |
9106 | + | |
9107 | + /* Sufixes for the parser. */ | |
9108 | + const char *const_sufix = gdbarch_stap_integer_sufix (gdbarch); | |
9109 | + const char *reg_sufix = gdbarch_stap_register_sufix (gdbarch); | |
9110 | + const char *reg_ind_sufix | |
9111 | + = gdbarch_stap_register_indirection_sufix (gdbarch); | |
9112 | + int const_sufix_len = const_sufix ? strlen (const_sufix) : 0; | |
9113 | + int reg_sufix_len = reg_sufix ? strlen (reg_sufix) : 0; | |
9114 | + int reg_ind_sufix_len = reg_ind_sufix ? strlen (reg_ind_sufix) : 0; | |
9115 | + | |
9116 | + /* We first try to parse this token as a "special token". */ | |
9117 | + if (gdbarch_stap_parse_special_token_p (gdbarch)) | |
9118 | + { | |
9119 | + int ret = gdbarch_stap_parse_special_token (gdbarch, p); | |
3a58abaf | 9120 | + |
f412e1b4 PS |
9121 | + if (ret) |
9122 | + /* If the return value of the above function is not zero, | |
9123 | + it means it successfully parsed the special token. | |
3a58abaf | 9124 | + |
f412e1b4 PS |
9125 | + If it is NULL, we try to parse it using our method. */ |
9126 | + return; | |
9127 | + } | |
51a5ef0f | 9128 | + |
f412e1b4 PS |
9129 | + if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+') |
9130 | + { | |
9131 | + char c = *p->arg; | |
9132 | + /* We use this variable to do a lookahead. */ | |
9133 | + const char *tmp = p->arg; | |
51a5ef0f | 9134 | + |
f412e1b4 | 9135 | + ++tmp; |
51a5ef0f | 9136 | + |
f412e1b4 PS |
9137 | + /* This is an unary operation. Here is a list of allowed tokens |
9138 | + here: | |
51a5ef0f | 9139 | + |
f412e1b4 PS |
9140 | + - numeric literal; |
9141 | + - number (from register displacement) | |
9142 | + - subexpression (beginning with `(') | |
51a5ef0f | 9143 | + |
f412e1b4 PS |
9144 | + We handle the register displacement here, and the other cases |
9145 | + recursively. */ | |
9146 | + if (isdigit (*tmp)) | |
9147 | + { | |
9148 | + int number = strtol (tmp, (char **) &tmp, 10); | |
51a5ef0f | 9149 | + |
f412e1b4 PS |
9150 | + if (p->inside_paren_p) |
9151 | + tmp = skip_spaces_const (tmp); | |
9152 | + if (!reg_ind_prefix | |
9153 | + || strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0) | |
9154 | + goto not_displacement; | |
6ed6bacf | 9155 | + |
f412e1b4 PS |
9156 | + /* If we are here, it means it is a displacement. The only |
9157 | + operations allowed here are `-' and `+'. */ | |
9158 | + if (c == '~') | |
9159 | + error (_("Invalid operator `%c' for register displacement " | |
9160 | + "on expression `%s'."), c, p->saved_arg); | |
9161 | + | |
9162 | + stap_parse_register_operand (p); | |
9163 | + } | |
9164 | + else | |
9165 | +not_displacement: | |
9166 | + { | |
9167 | + p->arg = tmp; | |
9168 | + stap_parse_argument_conditionally (p); | |
9169 | + if (c == '-') | |
9170 | + write_exp_elt_opcode (UNOP_NEG); | |
9171 | + else if (c == '~') | |
9172 | + write_exp_elt_opcode (UNOP_COMPLEMENT); | |
9173 | + } | |
6ed6bacf | 9174 | + } |
f412e1b4 PS |
9175 | + else if (isdigit (*p->arg)) |
9176 | + { | |
9177 | + /* A temporary variable, needed for lookahead. */ | |
9178 | + const char *tmp = p->arg; | |
9179 | + long number; | |
9180 | + | |
9181 | + /* We can be dealing with a numeric constant (if `const_prefix' is | |
9182 | + NULL), or with a register displacement. */ | |
9183 | + number = strtol (tmp, (char **) &tmp, 10); | |
9184 | + | |
9185 | + if (p->inside_paren_p) | |
9186 | + tmp = skip_spaces_const (tmp); | |
9187 | + if (!const_prefix && reg_ind_prefix | |
9188 | + && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0) | |
9189 | + { | |
9190 | + /* We are dealing with a numeric constant. */ | |
9191 | + write_exp_elt_opcode (OP_LONG); | |
9192 | + write_exp_elt_type (builtin_type (gdbarch)->builtin_long); | |
9193 | + write_exp_elt_longcst (number); | |
9194 | + write_exp_elt_opcode (OP_LONG); | |
51a5ef0f | 9195 | + |
f412e1b4 PS |
9196 | + p->arg = tmp; |
9197 | + | |
9198 | + if (const_sufix) | |
9199 | + { | |
9200 | + if (strncmp (p->arg, const_sufix, const_sufix_len) == 0) | |
9201 | + p->arg += const_sufix_len; | |
9202 | + else | |
9203 | + error (_("Invalid constant sufix on expression `%s'."), | |
9204 | + p->saved_arg); | |
9205 | + } | |
9206 | + } | |
9207 | + else if (reg_ind_prefix | |
9208 | + && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) == 0) | |
9209 | + stap_parse_register_operand (p); | |
9210 | + else | |
9211 | + error (_("Unknown numeric token on expression `%s'."), | |
9212 | + p->saved_arg); | |
9213 | + } | |
9214 | + else if (const_prefix | |
9215 | + && strncmp (p->arg, const_prefix, const_prefix_len) == 0) | |
9216 | + { | |
9217 | + /* We are dealing with a numeric constant. */ | |
9218 | + long number; | |
3a58abaf | 9219 | + |
f412e1b4 PS |
9220 | + p->arg += const_prefix_len; |
9221 | + number = strtol (p->arg, (char **) &p->arg, 10); | |
51a5ef0f | 9222 | + |
f412e1b4 PS |
9223 | + write_exp_elt_opcode (OP_LONG); |
9224 | + write_exp_elt_type (builtin_type (gdbarch)->builtin_long); | |
9225 | + write_exp_elt_longcst (number); | |
9226 | + write_exp_elt_opcode (OP_LONG); | |
51a5ef0f | 9227 | + |
f412e1b4 PS |
9228 | + if (const_sufix) |
9229 | + { | |
9230 | + if (strncmp (p->arg, const_sufix, const_sufix_len) == 0) | |
9231 | + p->arg += const_sufix_len; | |
9232 | + else | |
9233 | + error (_("Invalid constant sufix on expression `%s'."), | |
9234 | + p->saved_arg); | |
9235 | + } | |
9236 | + } | |
9237 | + else if ((reg_prefix | |
9238 | + && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0) | |
9239 | + || (reg_ind_prefix | |
9240 | + && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0)) | |
9241 | + stap_parse_register_operand (p); | |
9242 | + else | |
9243 | + error (_("Operator `%c' not recognized on expression `%s'."), | |
9244 | + *p->arg, p->saved_arg); | |
9245 | +} | |
9246 | + | |
9247 | +static void | |
9248 | +stap_parse_argument_conditionally (struct stap_parse_info *p) | |
9249 | +{ | |
9250 | + if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+' /* Unary. */ | |
9251 | + || isdigit (*p->arg) | |
9252 | + || gdbarch_stap_is_single_operand (p->gdbarch, p->arg)) | |
9253 | + stap_parse_single_operand (p); | |
9254 | + else if (*p->arg == '(') | |
3a58abaf | 9255 | + { |
6ed6bacf | 9256 | + /* We are dealing with a parenthesized operand. It means we |
f412e1b4 | 9257 | + have to parse it as it was a separate expression, without |
6ed6bacf | 9258 | + left-side or precedence. */ |
f412e1b4 PS |
9259 | + ++p->arg; |
9260 | + p->arg = skip_spaces_const (p->arg); | |
9261 | + ++p->inside_paren_p; | |
51a5ef0f | 9262 | + |
f412e1b4 | 9263 | + stap_parse_argument_1 (p, 0, STAP_OPERAND_PREC_NONE); |
3a58abaf | 9264 | + |
f412e1b4 PS |
9265 | + --p->inside_paren_p; |
9266 | + if (*p->arg != ')') | |
6ed6bacf | 9267 | + error (_("Missign close-paren on expression `%s'."), |
f412e1b4 | 9268 | + p->saved_arg); |
3a58abaf | 9269 | + |
f412e1b4 PS |
9270 | + ++p->arg; |
9271 | + if (p->inside_paren_p) | |
9272 | + p->arg = skip_spaces_const (p->arg); | |
6ed6bacf AM |
9273 | + } |
9274 | + else | |
f412e1b4 | 9275 | + error (_("Cannot parse expression `%s'."), p->saved_arg); |
3a58abaf AM |
9276 | +} |
9277 | + | |
f412e1b4 PS |
9278 | +static void |
9279 | +stap_parse_argument_1 (struct stap_parse_info *p, int has_lhs, | |
9280 | + enum stap_operand_prec prec) | |
6ed6bacf | 9281 | +{ |
f412e1b4 | 9282 | + /* This is an operator-precedence parser. |
6ed6bacf AM |
9283 | + |
9284 | + We work with left- and right-sides of expressions, and | |
f412e1b4 | 9285 | + parse them depending on the precedence of the operators |
6ed6bacf AM |
9286 | + we find. */ |
9287 | + | |
f412e1b4 PS |
9288 | + if (p->inside_paren_p) |
9289 | + p->arg = skip_spaces_const (p->arg); | |
6ed6bacf | 9290 | + |
f412e1b4 | 9291 | + if (!has_lhs) |
6ed6bacf | 9292 | + /* We were called without a left-side, either because this is the |
f412e1b4 PS |
9293 | + first call, or because we were called to parse a parenthesized |
9294 | + expression. It doesn't really matter; we have to parse the | |
6ed6bacf | 9295 | + left-side in order to continue the process. */ |
f412e1b4 | 9296 | + stap_parse_argument_conditionally (p); |
6ed6bacf | 9297 | + |
f412e1b4 | 9298 | + /* Start to parse the right-side, and to "join" left and right sides |
6ed6bacf AM |
9299 | + depending on the operation specified. |
9300 | + | |
9301 | + This loop shall continue until we run out of characters in the input, | |
9302 | + or until we find a close-parenthesis, which means that we've reached | |
9303 | + the end of a sub-expression. */ | |
f412e1b4 | 9304 | + while (p->arg && *p->arg && *p->arg != ')' && !isspace (*p->arg)) |
6ed6bacf | 9305 | + { |
f412e1b4 | 9306 | + const char *tmp_exp_buf; |
6ed6bacf | 9307 | + enum exp_opcode opcode; |
f412e1b4 | 9308 | + enum stap_operand_prec cur_prec; |
6ed6bacf | 9309 | + |
f412e1b4 PS |
9310 | + if (!stap_is_operator (*p->arg)) |
9311 | + error (_("Invalid operator `%c' on expression `%s'."), *p->arg, | |
9312 | + p->saved_arg); | |
6ed6bacf AM |
9313 | + |
9314 | + /* We have to save the current value of the expression buffer because | |
9315 | + the `stap_get_opcode' modifies it in order to get the current | |
9316 | + operator. If this operator's precedence is lower than PREC, we | |
9317 | + should return and not advance the expression buffer pointer. */ | |
f412e1b4 | 9318 | + tmp_exp_buf = p->arg; |
6ed6bacf AM |
9319 | + stap_get_opcode (&tmp_exp_buf, &opcode); |
9320 | + | |
9321 | + cur_prec = stap_get_operator_prec (opcode); | |
9322 | + if (cur_prec < prec) | |
9323 | + /* If the precedence of the operator that we are seeing now is | |
9324 | + lower than the precedence of the first operator seen before | |
f412e1b4 | 9325 | + this parsing process began, it means we should stop parsing |
6ed6bacf AM |
9326 | + and return. */ |
9327 | + break; | |
3a58abaf | 9328 | + |
f412e1b4 PS |
9329 | + p->arg = tmp_exp_buf; |
9330 | + if (p->inside_paren_p) | |
9331 | + p->arg = skip_spaces_const (p->arg); | |
51a5ef0f | 9332 | + |
f412e1b4 PS |
9333 | + /* Parse the right-side of the expression. */ |
9334 | + stap_parse_argument_conditionally (p); | |
51a5ef0f | 9335 | + |
f412e1b4 | 9336 | + /* While we still have operators, try to parse another |
6ed6bacf | 9337 | + right-side, but using the current right-side as a left-side. */ |
f412e1b4 | 9338 | + while (*p->arg && stap_is_operator (*p->arg)) |
6ed6bacf AM |
9339 | + { |
9340 | + enum exp_opcode lookahead_opcode; | |
f412e1b4 | 9341 | + enum stap_operand_prec lookahead_prec; |
6ed6bacf AM |
9342 | + |
9343 | + /* Saving the current expression buffer position. The explanation | |
9344 | + is the same as above. */ | |
f412e1b4 | 9345 | + tmp_exp_buf = p->arg; |
6ed6bacf AM |
9346 | + stap_get_opcode (&tmp_exp_buf, &lookahead_opcode); |
9347 | + lookahead_prec = stap_get_operator_prec (lookahead_opcode); | |
9348 | + | |
9349 | + if (lookahead_prec <= prec) | |
9350 | + /* If we are dealing with an operator whose precedence is lower | |
9351 | + than the first one, just abandon the attempt. */ | |
9352 | + break; | |
3a58abaf | 9353 | + |
f412e1b4 PS |
9354 | + /* Parse the right-side of the expression, but since we already |
9355 | + have a left-side at this point, set `has_lhs' to 1. */ | |
9356 | + stap_parse_argument_1 (p, 1, lookahead_prec); | |
6ed6bacf | 9357 | + } |
3a58abaf | 9358 | + |
f412e1b4 | 9359 | + write_exp_elt_opcode (opcode); |
3a58abaf | 9360 | + } |
51a5ef0f | 9361 | +} |
3a58abaf | 9362 | + |
f412e1b4 | 9363 | +/* Parse a probe's argument. |
3a58abaf | 9364 | + |
f412e1b4 PS |
9365 | + Assuming that: |
9366 | + | |
9367 | + LP = literal integer prefix | |
9368 | + LS = literal integer sufix | |
9369 | + | |
9370 | + RP = register prefix | |
9371 | + RS = register sufix | |
9372 | + | |
9373 | + RIP = register indirection prefix | |
9374 | + RIS = register indirection sufix | |
9375 | + | |
9376 | + This routine assumes that arguments' tokens are of the form: | |
9377 | + | |
9378 | + - [LP] NUMBER [LS] | |
9379 | + - [RP] REGISTER [RS] | |
9380 | + - [RIP] [RP] REGISTER [RS] [RIS] | |
9381 | + - If we find a number without LP, we try to parse it as a literal integer | |
9382 | + constant (if LP == NULL), or as a register displacement. | |
9383 | + - We count parenthesis, and only skip whitespaces if we are inside them. | |
9384 | + - If we find an operator, we skip it. | |
9385 | + | |
9386 | + This function can also call a special function that will try to match | |
9387 | + unknown tokens. It will return 1 if the argument has been parsed | |
9388 | + successfully, or zero otherwise. */ | |
9389 | + | |
9390 | +static int | |
9391 | +stap_parse_argument (const char **arg, struct type *atype, | |
9392 | + struct gdbarch *gdbarch) | |
51a5ef0f | 9393 | +{ |
f412e1b4 PS |
9394 | + struct stap_parse_info p; |
9395 | + volatile struct gdb_exception e; | |
9396 | + | |
9397 | + /* We need to initialize the expression buffer, in order to begin | |
9398 | + our parsing efforts. The language here does not matter, since we | |
9399 | + are using our own parser. */ | |
9400 | + initialize_expout (10, current_language, gdbarch); | |
9401 | + | |
9402 | + p.saved_arg = *arg; | |
9403 | + p.arg = *arg; | |
9404 | + p.arg_type = atype; | |
9405 | + p.gdbarch = gdbarch; | |
9406 | + p.inside_paren_p = 0; | |
3a58abaf | 9407 | + |
f412e1b4 PS |
9408 | + TRY_CATCH (e, RETURN_MASK_ERROR) |
9409 | + { | |
9410 | + stap_parse_argument_1 (&p, 0, STAP_OPERAND_PREC_NONE); | |
9411 | + } | |
9412 | + if (e.reason < 0) | |
9413 | + { | |
9414 | + xfree (expout); | |
9415 | + return 0; | |
9416 | + } | |
9417 | + | |
9418 | + gdb_assert (p.inside_paren_p == 0); | |
3a58abaf | 9419 | + |
f412e1b4 PS |
9420 | + /* Casting the final expression to the appropriate type. */ |
9421 | + write_exp_elt_opcode (UNOP_CAST); | |
9422 | + write_exp_elt_type (atype); | |
9423 | + write_exp_elt_opcode (UNOP_CAST); | |
3a58abaf | 9424 | + |
f412e1b4 | 9425 | + reallocate_expout (); |
3a58abaf | 9426 | + |
f412e1b4 PS |
9427 | + p.arg = skip_spaces_const (p.arg); |
9428 | + *arg = p.arg; | |
9429 | + | |
9430 | + return 1; | |
3a58abaf AM |
9431 | +} |
9432 | + | |
f412e1b4 PS |
9433 | +/* Helper function which is responsible for freeing the space allocated to |
9434 | + hold information about a probe's arguments. */ | |
3a58abaf | 9435 | + |
f412e1b4 PS |
9436 | +static void |
9437 | +stap_free_args_info (void *args_info_ptr) | |
3a58abaf | 9438 | +{ |
f412e1b4 PS |
9439 | + struct stap_args_info *a = (struct stap_args_info *) args_info_ptr; |
9440 | + int i; | |
6ed6bacf | 9441 | + |
f412e1b4 PS |
9442 | + for (i = 0; i < a->n_args; i++) |
9443 | + xfree (a->args[i].aexpr); | |
3a58abaf | 9444 | + |
f412e1b4 PS |
9445 | + xfree (a->args); |
9446 | + xfree (a); | |
3a58abaf AM |
9447 | +} |
9448 | + | |
f412e1b4 PS |
9449 | +/* Function which parses an argument string from PROBE, correctly splitting |
9450 | + the arguments and storing their information in properly ways. | |
9451 | + | |
9452 | + Consider the following argument string (x86 syntax): | |
9453 | + | |
9454 | + `4@%eax 4@$10' | |
9455 | + | |
9456 | + We have two arguments, `%eax' and `$10', both with 32-bit unsigned bitness. | |
9457 | + This function basically handles them, properly filling some structures with | |
9458 | + this information. */ | |
3a58abaf | 9459 | + |
51a5ef0f | 9460 | +static void |
f412e1b4 PS |
9461 | +stap_parse_probe_arguments (struct stap_probe *probe) |
9462 | +{ | |
9463 | + struct stap_args_info *args_info; | |
9464 | + struct cleanup *back_to; | |
9465 | + const char *cur = probe->args; | |
9466 | + int current_arg = -1; | |
9467 | + /* This is a state-machine parser, which means we will always be | |
9468 | + in a known state when parsing an argument. The state could be | |
9469 | + either `NEW_ARG' if we are parsing a new argument, `BITNESS' if | |
9470 | + we are parsing the bitness-definition part (i.e., `4@'), or | |
9471 | + `PARSE_ARG' if we are actually parsing the argument part. */ | |
9472 | + enum | |
6ed6bacf | 9473 | + { |
f412e1b4 PS |
9474 | + NEW_ARG, |
9475 | + BITNESS, | |
9476 | + PARSE_ARG, | |
9477 | + } current_state; | |
9478 | + | |
9479 | + /* For now, we assume everything is not going to work. */ | |
9480 | + probe->parsed_args = &dummy_stap_args_info; | |
9481 | + | |
9482 | + if (!cur || !*cur || *cur == ':') | |
9483 | + return; | |
9484 | + | |
9485 | + args_info = xmalloc (sizeof (struct stap_args_info)); | |
9486 | + args_info->n_args = 0; | |
9487 | + back_to = make_cleanup (stap_free_args_info, args_info); | |
9488 | + args_info->args = xcalloc (STAP_MAX_ARGS, sizeof (struct stap_probe_arg)); | |
9489 | + | |
9490 | + /* Ok, let's start. */ | |
9491 | + current_state = NEW_ARG; | |
9492 | + | |
9493 | + while (*cur) | |
9494 | + { | |
9495 | + switch (current_state) | |
9496 | + { | |
9497 | + case NEW_ARG: | |
9498 | + ++current_arg; | |
9499 | + | |
9500 | + if (current_arg >= STAP_MAX_ARGS) | |
9501 | + { | |
9502 | + complaint (&symfile_complaints, | |
9503 | + _("probe `%s' has more arguments than the maximum " | |
9504 | + "allowed"), probe->name); | |
9505 | + do_cleanups (back_to); | |
9506 | + return; | |
9507 | + } | |
9508 | + | |
9509 | + current_state = BITNESS; | |
9510 | + break; | |
9511 | + | |
9512 | + case BITNESS: | |
9513 | + { | |
9514 | + enum stap_arg_bitness b; | |
9515 | + int got_minus = 0; | |
9516 | + | |
9517 | + /* We expect to find something like: | |
9518 | + | |
9519 | + N@OP | |
9520 | + | |
9521 | + Where `N' can be [+,-][4,8]. This is not mandatory, so | |
9522 | + we check it here. If we don't find it, go to the next | |
9523 | + state. */ | |
9524 | + if ((*cur == '-' && cur[1] && cur[2] != '@') | |
9525 | + && cur[1] != '@') | |
9526 | + { | |
9527 | + current_state = PARSE_ARG; | |
9528 | + args_info->args[current_arg].bitness | |
9529 | + = STAP_ARG_BITNESS_UNDEFINED; | |
9530 | + break; | |
9531 | + } | |
9532 | + | |
9533 | + if (*cur == '-') | |
9534 | + { | |
9535 | + /* Discard the `-'. */ | |
9536 | + ++cur; | |
9537 | + got_minus = 1; | |
9538 | + } | |
9539 | + | |
9540 | + if (*cur == '4') | |
9541 | + b = got_minus ? STAP_ARG_BITNESS_32BIT_SIGNED | |
9542 | + : STAP_ARG_BITNESS_32BIT_UNSIGNED; | |
9543 | + else if (*cur == '8') | |
9544 | + b = got_minus ? STAP_ARG_BITNESS_64BIT_SIGNED | |
9545 | + : STAP_ARG_BITNESS_64BIT_UNSIGNED; | |
9546 | + else | |
9547 | + { | |
9548 | + /* We have an error, because we don't expect anything | |
9549 | + except 4 and 8. */ | |
9550 | + complaint (&symfile_complaints, | |
9551 | + _("unrecognized bitness `%c' for probe `%s'"), | |
9552 | + *cur, probe->name); | |
9553 | + do_cleanups (back_to); | |
9554 | + return; | |
9555 | + } | |
9556 | + | |
9557 | + args_info->args[current_arg].bitness = b; | |
9558 | + args_info->args[current_arg].atype | |
9559 | + = stap_get_expected_argument_type (probe->gdbarch, b); | |
9560 | + /* Discard the number and the `@' sign. */ | |
9561 | + cur += 2; | |
9562 | + /* Move on. */ | |
9563 | + current_state = PARSE_ARG; | |
9564 | + } | |
9565 | + break; | |
9566 | + | |
9567 | + case PARSE_ARG: | |
9568 | + { | |
9569 | + if (!stap_parse_argument (&cur, | |
9570 | + args_info->args[current_arg].atype, | |
9571 | + probe->gdbarch)) | |
9572 | + { | |
9573 | + /* We have tried to parse this argument, but it's | |
9574 | + malformed. This is an error. */ | |
9575 | + complaint (&symfile_complaints, | |
9576 | + _("malformed argument for probe `%s'"), | |
9577 | + probe->name); | |
9578 | + do_cleanups (back_to); | |
9579 | + return; | |
9580 | + } | |
9581 | + | |
9582 | + if (stap_expression_debug) | |
9583 | + dump_raw_expression (expout, gdb_stdlog, | |
9584 | + "before conversion to prefix form"); | |
9585 | + | |
9586 | + prefixify_expression (expout); | |
9587 | + | |
9588 | + if (stap_expression_debug) | |
9589 | + dump_prefix_expression (expout, gdb_stdlog); | |
9590 | + | |
9591 | + args_info->args[current_arg].aexpr = expout; | |
9592 | + expout = NULL; | |
9593 | + | |
9594 | + ++args_info->n_args; | |
9595 | + /* Start it over again. */ | |
9596 | + cur = skip_spaces_const (cur); | |
9597 | + current_state = NEW_ARG; | |
9598 | + } | |
9599 | + break; | |
9600 | + } | |
9601 | + | |
9602 | + if (!*cur && current_state != NEW_ARG) | |
9603 | + { | |
9604 | + /* We reached the end of the argument string, but we're | |
9605 | + still in the middle of the process of parsing an argument. | |
9606 | + It means the argument string is malformed. */ | |
9607 | + complaint (&symfile_complaints, | |
9608 | + _("malformed argument for probe `%s'"), | |
9609 | + probe->name); | |
9610 | + do_cleanups (back_to); | |
9611 | + return; | |
9612 | + } | |
9613 | + } | |
9614 | + | |
9615 | + args_info->args = xrealloc (args_info->args, | |
9616 | + args_info->n_args | |
9617 | + * sizeof (struct stap_probe_arg)); | |
9618 | + args_info->probe = probe; | |
9619 | + | |
9620 | + probe->parsed_args = args_info; | |
9621 | + | |
9622 | + discard_cleanups (back_to); | |
9623 | +} | |
9624 | + | |
9625 | +/* See definition in stap-probe.h. */ | |
9626 | + | |
9627 | +int | |
9628 | +stap_get_probe_argument_count (struct stap_probe *probe) | |
9629 | +{ | |
9630 | + if (!probe->parsed_args) | |
9631 | + stap_parse_probe_arguments (probe); | |
9632 | + | |
9633 | + return probe->parsed_args->n_args; | |
9634 | +} | |
9635 | + | |
9636 | +/* Return 1 if OP is a valid operator inside a probe argument, or zero | |
9637 | + otherwise. */ | |
9638 | + | |
9639 | +static int | |
9640 | +stap_is_operator (char op) | |
9641 | +{ | |
9642 | + return (op == '+' || op == '-' || op == '*' || op == '/' | |
9643 | + || op == '>' || op == '<' || op == '!' || op == '^' | |
9644 | + || op == '|' || op == '&' || op == '%' || op == '='); | |
9645 | +} | |
3a58abaf | 9646 | + |
f412e1b4 | 9647 | +/* See definition in stap-probe.h. */ |
3a58abaf | 9648 | + |
f412e1b4 PS |
9649 | +struct value * |
9650 | +stap_evaluate_probe_argument (struct objfile *objfile, | |
9651 | + struct stap_probe *probe, | |
9652 | + struct frame_info *frame, | |
9653 | + int n) | |
9654 | +{ | |
9655 | + int pos = 0; | |
3a58abaf | 9656 | + |
f412e1b4 PS |
9657 | + if (!probe->parsed_args) |
9658 | + stap_parse_probe_arguments (probe); | |
3a58abaf | 9659 | + |
f412e1b4 PS |
9660 | + if (!probe->parsed_args->args |
9661 | + || n >= probe->parsed_args->n_args) | |
9662 | + return NULL; | |
6ed6bacf | 9663 | + |
f412e1b4 PS |
9664 | + /* This is needed because on some architectures (e.g., ARM) we need |
9665 | + the frame's gdbarch in order to compute the value of the frame | |
9666 | + pointer. */ | |
9667 | + probe->parsed_args->args[n].aexpr->gdbarch = get_frame_arch (frame); | |
3a58abaf | 9668 | + |
f412e1b4 PS |
9669 | + return evaluate_subexp_standard (probe->parsed_args->args[n].atype, |
9670 | + probe->parsed_args->args[n].aexpr, | |
9671 | + &pos, EVAL_NORMAL); | |
3a58abaf AM |
9672 | +} |
9673 | + | |
6ed6bacf | 9674 | +/* See definition in stap-probe.h. */ |
3a58abaf | 9675 | + |
6ed6bacf AM |
9676 | +void |
9677 | +stap_compile_to_ax (struct objfile *objfile, | |
f412e1b4 | 9678 | + struct stap_probe *probe, |
6ed6bacf AM |
9679 | + struct agent_expr *expr, |
9680 | + struct axs_value *value, | |
9681 | + int n) | |
9682 | +{ | |
f412e1b4 PS |
9683 | + union exp_element *pc; |
9684 | + | |
6ed6bacf | 9685 | + if (!probe->parsed_args) |
f412e1b4 | 9686 | + stap_parse_probe_arguments (probe); |
3a58abaf | 9687 | + |
f412e1b4 | 9688 | + if (!probe->parsed_args->args |
6ed6bacf AM |
9689 | + || n >= probe->parsed_args->n_args) |
9690 | + return; | |
9691 | + | |
f412e1b4 PS |
9692 | + pc = probe->parsed_args->args[n].aexpr->elts; |
9693 | + gen_expr (probe->parsed_args->args[n].aexpr, &pc, expr, value); | |
9694 | + | |
9695 | + require_rvalue (expr, value); | |
9696 | + value->type = probe->parsed_args->args[n].atype; | |
6ed6bacf AM |
9697 | +} |
9698 | + | |
9699 | +struct value * | |
9700 | +stap_safe_evaluate_at_pc (struct frame_info *frame, int n) | |
3a58abaf | 9701 | +{ |
f412e1b4 | 9702 | + struct stap_probe *probe; |
6ed6bacf AM |
9703 | + struct objfile *objfile; |
9704 | + int n_probes; | |
3a58abaf | 9705 | + |
6ed6bacf AM |
9706 | + probe = find_probe_by_pc (get_frame_pc (frame), &objfile); |
9707 | + if (!probe) | |
9708 | + return NULL; | |
9709 | + gdb_assert (objfile->sf && objfile->sf->sym_probe_fns); | |
9710 | + | |
9711 | + n_probes | |
9712 | + = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile, | |
9713 | + probe); | |
9714 | + if (n >= n_probes) | |
9715 | + return NULL; | |
9716 | + | |
9717 | + return objfile->sf->sym_probe_fns->sym_evaluate_probe_argument (objfile, | |
9718 | + probe, | |
9719 | + frame, | |
9720 | + n); | |
3a58abaf AM |
9721 | +} |
9722 | + | |
6ed6bacf AM |
9723 | +/* This function frees the space allocated to hold information about |
9724 | + the probe's parsed arguments. */ | |
3a58abaf | 9725 | + |
6ed6bacf AM |
9726 | +void |
9727 | +stap_free_parsed_args (struct stap_args_info *parsed_args) | |
9728 | +{ | |
9729 | + int i; | |
3a58abaf | 9730 | + |
6ed6bacf AM |
9731 | + if (!parsed_args |
9732 | + || parsed_args == &dummy_stap_args_info | |
9733 | + || parsed_args->n_args == 0) | |
9734 | + return; | |
9735 | + | |
9736 | + for (i = 0; i < parsed_args->n_args; i++) | |
f412e1b4 | 9737 | + xfree (parsed_args->args[i].aexpr); |
6ed6bacf | 9738 | + |
f412e1b4 | 9739 | + xfree (parsed_args->args); |
6ed6bacf AM |
9740 | + xfree (parsed_args); |
9741 | +} | |
9742 | + | |
9743 | +/* A utility structure. A VEC of these is built when handling "info | |
9744 | + probes". */ | |
9745 | + | |
9746 | +struct stap_probe_and_objfile | |
9747 | +{ | |
9748 | + /* The probe. */ | |
f412e1b4 | 9749 | + struct stap_probe *probe; |
6ed6bacf AM |
9750 | + /* The probe's objfile. */ |
9751 | + struct objfile *objfile; | |
9752 | +}; | |
9753 | + | |
9754 | +typedef struct stap_probe_and_objfile stap_entry; | |
9755 | +DEF_VEC_O (stap_entry); | |
9756 | + | |
9757 | +/* A helper function for collect_probes that compiles a regexp and | |
9758 | + throws an exception on error. This installs a cleanup to free the | |
9759 | + resulting pattern on success. If RX is NULL, this does nothing. */ | |
9760 | + | |
9761 | +static void | |
9762 | +compile_rx_or_error (regex_t *pattern, const char *rx, const char *message) | |
3a58abaf | 9763 | +{ |
6ed6bacf | 9764 | + int code; |
3a58abaf | 9765 | + |
6ed6bacf AM |
9766 | + if (!rx) |
9767 | + return; | |
3a58abaf | 9768 | + |
6ed6bacf AM |
9769 | + code = regcomp (pattern, rx, REG_NOSUB); |
9770 | + if (code == 0) | |
9771 | + make_regfree_cleanup (pattern); | |
51a5ef0f | 9772 | + else |
3a58abaf | 9773 | + { |
6ed6bacf AM |
9774 | + char *err = get_regcomp_error (code, pattern); |
9775 | + | |
9776 | + make_cleanup (xfree, err); | |
9777 | + error (_("%s: %s"), message, err); | |
3a58abaf | 9778 | + } |
6ed6bacf AM |
9779 | +} |
9780 | + | |
9781 | +/* Make a vector of probes matching OBJNAME, PROVIDER, and PROBE. | |
9782 | + Each argument is a regexp, or NULL, which matches anything. */ | |
9783 | + | |
9784 | +static VEC (stap_entry) * | |
9785 | +collect_probes (char *objname, char *provider, char *probe) | |
9786 | +{ | |
9787 | + struct objfile *objfile; | |
9788 | + VEC (stap_entry) *result = NULL; | |
9789 | + struct cleanup *cleanup; | |
9790 | + regex_t obj_pat, prov_pat, probe_pat; | |
9791 | + | |
9792 | + cleanup = make_cleanup (VEC_cleanup (stap_entry), &result); | |
9793 | + | |
9794 | + compile_rx_or_error (&prov_pat, provider, _("Invalid provider regexp")); | |
9795 | + compile_rx_or_error (&probe_pat, probe, _("Invalid probe regexp")); | |
9796 | + compile_rx_or_error (&obj_pat, objname, _("Invalid object file regexp")); | |
9797 | + | |
9798 | + ALL_OBJFILES (objfile) | |
9799 | + { | |
f412e1b4 | 9800 | + struct stap_probe *probes; |
6ed6bacf AM |
9801 | + int i, num_probes; |
9802 | + | |
9803 | + if (! objfile->sf || ! objfile->sf->sym_probe_fns) | |
9804 | + continue; | |
9805 | + | |
9806 | + if (objname) | |
9807 | + { | |
9808 | + if (regexec (&obj_pat, objfile->name, 0, NULL, 0) != 0) | |
9809 | + continue; | |
9810 | + } | |
3a58abaf | 9811 | + |
6ed6bacf AM |
9812 | + probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile, &num_probes); |
9813 | + for (i = 0; i < num_probes; ++i) | |
9814 | + { | |
9815 | + stap_entry entry; | |
9816 | + | |
9817 | + if (provider) | |
9818 | + { | |
9819 | + if (regexec (&prov_pat, probes[i].provider, 0, NULL, 0) != 0) | |
9820 | + continue; | |
9821 | + } | |
9822 | + | |
9823 | + if (probe) | |
9824 | + { | |
9825 | + if (regexec (&probe_pat, probes[i].name, 0, NULL, 0) != 0) | |
9826 | + continue; | |
9827 | + } | |
9828 | + | |
9829 | + entry.probe = &probes[i]; | |
9830 | + entry.objfile = objfile; | |
9831 | + VEC_safe_push (stap_entry, result, &entry); | |
9832 | + } | |
9833 | + } | |
9834 | + | |
9835 | + discard_cleanups (cleanup); | |
9836 | + return result; | |
3a58abaf AM |
9837 | +} |
9838 | + | |
6ed6bacf | 9839 | +/* A qsort comparison function for stap_entry objects. */ |
3a58abaf | 9840 | + |
6ed6bacf AM |
9841 | +static int |
9842 | +compare_entries (const void *a, const void *b) | |
3a58abaf | 9843 | +{ |
6ed6bacf AM |
9844 | + const stap_entry *ea = a; |
9845 | + const stap_entry *eb = b; | |
9846 | + int v; | |
3a58abaf | 9847 | + |
6ed6bacf AM |
9848 | + v = strcmp (ea->probe->provider, eb->probe->provider); |
9849 | + if (v) | |
9850 | + return v; | |
3a58abaf | 9851 | + |
6ed6bacf AM |
9852 | + v = strcmp (ea->probe->name, eb->probe->name); |
9853 | + if (v) | |
9854 | + return v; | |
51a5ef0f | 9855 | + |
6ed6bacf AM |
9856 | + if (ea->probe->address < eb->probe->address) |
9857 | + return -1; | |
9858 | + if (ea->probe->address > eb->probe->address) | |
9859 | + return 1; | |
51a5ef0f | 9860 | + |
6ed6bacf AM |
9861 | + return strcmp (ea->objfile->name, eb->objfile->name); |
9862 | +} | |
9863 | + | |
9864 | +/* Implementation of the "info probes" command. */ | |
9865 | + | |
9866 | +static void | |
9867 | +info_probes_command (char *arg, int from_tty) | |
9868 | +{ | |
9869 | + char *provider, *probe = NULL, *objname = NULL; | |
9870 | + struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); | |
9871 | + VEC (stap_entry) *items; | |
9872 | + int i, addr_width, any_found; | |
9873 | + stap_entry *entry; | |
9874 | + | |
9875 | + provider = extract_arg (&arg); | |
9876 | + if (provider) | |
9877 | + { | |
9878 | + make_cleanup (xfree, provider); | |
9879 | + | |
9880 | + probe = extract_arg (&arg); | |
9881 | + if (probe) | |
51a5ef0f | 9882 | + { |
6ed6bacf AM |
9883 | + make_cleanup (xfree, probe); |
9884 | + | |
9885 | + objname = extract_arg (&arg); | |
9886 | + if (objname) | |
9887 | + make_cleanup (xfree, objname); | |
51a5ef0f | 9888 | + } |
3a58abaf | 9889 | + } |
51a5ef0f | 9890 | + |
6ed6bacf AM |
9891 | + items = collect_probes (objname, provider, probe); |
9892 | + make_cleanup (VEC_cleanup (stap_entry), &items); | |
f412e1b4 | 9893 | + make_cleanup_ui_out_table_begin_end (current_uiout, 5, |
6ed6bacf AM |
9894 | + VEC_length (stap_entry, items), |
9895 | + "SystemTapProbes"); | |
3a58abaf | 9896 | + |
6ed6bacf AM |
9897 | + if (! VEC_empty (stap_entry, items)) |
9898 | + qsort (VEC_address (stap_entry, items), | |
9899 | + VEC_length (stap_entry, items), | |
9900 | + sizeof (stap_entry), | |
9901 | + compare_entries); | |
9902 | + | |
9903 | + addr_width = 4 + (gdbarch_ptr_bit (get_current_arch ()) / 4); | |
9904 | + | |
f412e1b4 PS |
9905 | + ui_out_table_header (current_uiout, 10, ui_left, "provider", _("Provider")); |
9906 | + ui_out_table_header (current_uiout, 10, ui_left, "name", _("Name")); | |
9907 | + ui_out_table_header (current_uiout, addr_width - 1, ui_left, "addr", _("Where")); | |
9908 | + ui_out_table_header (current_uiout, addr_width - 1, ui_left, "semaphore", | |
6ed6bacf | 9909 | + _("Semaphore")); |
f412e1b4 PS |
9910 | + ui_out_table_header (current_uiout, 30, ui_left, "object", _("Object")); |
9911 | + ui_out_table_body (current_uiout); | |
6ed6bacf AM |
9912 | + |
9913 | + for (i = 0; VEC_iterate (stap_entry, items, i, entry); ++i) | |
51a5ef0f | 9914 | + { |
6ed6bacf | 9915 | + struct cleanup *inner; |
3a58abaf | 9916 | + |
f412e1b4 | 9917 | + inner = make_cleanup_ui_out_tuple_begin_end (current_uiout, "probe"); |
3a58abaf | 9918 | + |
f412e1b4 PS |
9919 | + ui_out_field_string (current_uiout, "provider", entry->probe->provider); |
9920 | + ui_out_field_string (current_uiout, "name", entry->probe->name); | |
9921 | + ui_out_field_core_addr (current_uiout, "addr", get_current_arch (), | |
6ed6bacf AM |
9922 | + entry->probe->address); |
9923 | + if (entry->probe->sem_addr == 0) | |
f412e1b4 | 9924 | + ui_out_field_skip (current_uiout, "semaphore"); |
6ed6bacf | 9925 | + else |
f412e1b4 | 9926 | + ui_out_field_core_addr (current_uiout, "semaphore", get_current_arch (), |
6ed6bacf | 9927 | + entry->probe->sem_addr); |
f412e1b4 PS |
9928 | + ui_out_field_string (current_uiout, "object", entry->objfile->name); |
9929 | + ui_out_text (current_uiout, "\n"); | |
6ed6bacf AM |
9930 | + |
9931 | + do_cleanups (inner); | |
51a5ef0f | 9932 | + } |
3a58abaf | 9933 | + |
6ed6bacf AM |
9934 | + any_found = ! VEC_empty (stap_entry, items); |
9935 | + do_cleanups (cleanup); | |
3a58abaf | 9936 | + |
6ed6bacf | 9937 | + if (! any_found) |
f412e1b4 | 9938 | + ui_out_message (current_uiout, 0, _("No probes matched.\n")); |
3a58abaf AM |
9939 | +} |
9940 | + | |
6ed6bacf AM |
9941 | +\f |
9942 | + | |
9943 | +/* See definition in stap-probe.h. */ | |
51a5ef0f | 9944 | + |
f412e1b4 PS |
9945 | +VEC (stap_probe_p) * |
9946 | +find_probes_in_objfile (struct objfile *objfile, | |
9947 | + const char *provider, | |
9948 | + const char *name) | |
51a5ef0f | 9949 | +{ |
f412e1b4 | 9950 | + struct stap_probe *probes; |
6ed6bacf | 9951 | + int i, num_probes; |
f412e1b4 | 9952 | + VEC (stap_probe_p) *result = NULL; |
6ed6bacf AM |
9953 | + |
9954 | + if (! objfile->sf || ! objfile->sf->sym_probe_fns) | |
9955 | + return NULL; | |
9956 | + | |
9957 | + probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile, &num_probes); | |
9958 | + for (i = 0; i < num_probes; ++i) | |
9959 | + { | |
9960 | + if (strcmp (probes[i].provider, provider) != 0) | |
9961 | + continue; | |
51a5ef0f | 9962 | + |
6ed6bacf AM |
9963 | + if (strcmp (probes[i].name, name) != 0) |
9964 | + continue; | |
3a58abaf | 9965 | + |
f412e1b4 | 9966 | + VEC_safe_push (stap_probe_p, result, &probes[i]); |
6ed6bacf | 9967 | + } |
3a58abaf | 9968 | + |
f412e1b4 | 9969 | + return result; |
6ed6bacf AM |
9970 | +} |
9971 | + | |
9972 | +/* See definition in stap-probe.h. */ | |
9973 | + | |
9974 | +struct symtabs_and_lines | |
9975 | +parse_stap_probe (char **argptr, struct linespec_result *canonical) | |
3a58abaf | 9976 | +{ |
f412e1b4 | 9977 | + char *arg_start, *arg_end, *arg; |
6ed6bacf | 9978 | + char *objfile_name = NULL, *provider = NULL, *name, *p; |
51a5ef0f | 9979 | + struct cleanup *cleanup; |
6ed6bacf AM |
9980 | + struct symtabs_and_lines result; |
9981 | + struct objfile *objfile; | |
9982 | + | |
9983 | + result.sals = NULL; | |
9984 | + result.nelts = 0; | |
9985 | + | |
f412e1b4 PS |
9986 | + arg_start = *argptr; |
9987 | + /* The caller ensured that this starts with '-p'. */ | |
9988 | + gdb_assert (arg_start && strncmp (arg_start, "-p", 2) == 0); | |
9989 | + arg_end = arg_start + 2; | |
9990 | + arg_end = skip_spaces (arg_end); | |
9991 | + | |
9992 | + if (!*arg_end) | |
9993 | + error (_("argument to `-p' missing")); | |
9994 | + | |
9995 | + arg = arg_end; | |
9996 | + arg_end = skip_to_space (arg_end); | |
9997 | + | |
9998 | + /* We make a copy here so we can write over parts with impunity. */ | |
9999 | + arg = savestring (arg, arg_end - arg); | |
6ed6bacf | 10000 | + cleanup = make_cleanup (xfree, arg); |
6ed6bacf AM |
10001 | + |
10002 | + /* Extract each word from the argument, separated by ":"s. */ | |
10003 | + p = strchr (arg, ':'); | |
10004 | + if (p == NULL) | |
10005 | + { | |
f412e1b4 | 10006 | + /* This is `-p name'. */ |
6ed6bacf AM |
10007 | + name = arg; |
10008 | + } | |
10009 | + else | |
10010 | + { | |
10011 | + char *hold = p + 1; | |
10012 | + | |
10013 | + *p = '\0'; | |
10014 | + p = strchr (hold, ':'); | |
10015 | + if (p == NULL) | |
10016 | + { | |
f412e1b4 | 10017 | + /* This is `-p provider:name'. */ |
6ed6bacf AM |
10018 | + provider = arg; |
10019 | + name = hold; | |
10020 | + } | |
10021 | + else | |
10022 | + { | |
f412e1b4 | 10023 | + /* This is `-p objfile:provider:name'. */ |
6ed6bacf AM |
10024 | + *p = '\0'; |
10025 | + objfile_name = arg; | |
10026 | + provider = hold; | |
10027 | + name = p + 1; | |
10028 | + } | |
10029 | + } | |
10030 | + | |
10031 | + if (*name == '\0') | |
10032 | + error (_("no probe name specified")); | |
10033 | + if (provider && *provider == '\0') | |
10034 | + error (_("invalid provider name")); | |
10035 | + if (objfile_name && *objfile_name == '\0') | |
10036 | + error (_("invalid objfile name")); | |
10037 | + | |
6ed6bacf AM |
10038 | + ALL_OBJFILES (objfile) |
10039 | + { | |
f412e1b4 | 10040 | + struct stap_probe *probes; |
6ed6bacf AM |
10041 | + int i, num_probes; |
10042 | + | |
10043 | + if (! objfile->sf || ! objfile->sf->sym_probe_fns) | |
10044 | + continue; | |
10045 | + | |
10046 | + if (objfile_name | |
10047 | + && FILENAME_CMP (objfile->name, objfile_name) != 0 | |
10048 | + && FILENAME_CMP (lbasename (objfile->name), objfile_name) != 0) | |
10049 | + continue; | |
10050 | + | |
10051 | + probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile, &num_probes); | |
10052 | + for (i = 0; i < num_probes; ++i) | |
10053 | + { | |
10054 | + struct symtab_and_line *sal; | |
10055 | + | |
10056 | + if (provider && strcmp (probes[i].provider, provider) != 0) | |
10057 | + continue; | |
10058 | + | |
10059 | + if (strcmp (probes[i].name, name) != 0) | |
10060 | + continue; | |
10061 | + | |
10062 | + ++result.nelts; | |
10063 | + result.sals = xrealloc (result.sals, | |
10064 | + result.nelts * sizeof (struct symtab_and_line)); | |
10065 | + sal = &result.sals[result.nelts - 1]; | |
3a58abaf | 10066 | + |
6ed6bacf | 10067 | + init_sal (sal); |
3a58abaf | 10068 | + |
6ed6bacf AM |
10069 | + sal->pc = probes[i].address; |
10070 | + sal->explicit_pc = 1; | |
10071 | + sal->section = find_pc_overlay (sal->pc); | |
10072 | + sal->pspace = current_program_space; | |
10073 | + sal->semaphore = probes[i].sem_addr; | |
6ed6bacf AM |
10074 | + } |
10075 | + } | |
10076 | + | |
10077 | + if (result.nelts == 0) | |
10078 | + { | |
10079 | + throw_error (NOT_FOUND_ERROR, | |
10080 | + _("No probe matching objfile=`%s', provider=`%s', name=`%s'"), | |
10081 | + objfile_name ? objfile_name : _("<any>"), | |
10082 | + provider ? provider : _("<any>"), | |
10083 | + name); | |
10084 | + } | |
10085 | + | |
10086 | + if (canonical) | |
3a58abaf | 10087 | + { |
6ed6bacf AM |
10088 | + canonical->special_display = 1; |
10089 | + canonical->pre_expanded = 1; | |
f412e1b4 | 10090 | + canonical->addr_string = savestring (*argptr, arg_end - *argptr); |
3a58abaf AM |
10091 | + } |
10092 | + | |
f412e1b4 | 10093 | + *argptr = arg_end; |
51a5ef0f | 10094 | + do_cleanups (cleanup); |
6ed6bacf AM |
10095 | + |
10096 | + return result; | |
51a5ef0f PS |
10097 | +} |
10098 | + | |
6ed6bacf AM |
10099 | +\f |
10100 | + | |
10101 | +/* See definition in stap-probe.h. */ | |
10102 | + | |
f412e1b4 | 10103 | +struct stap_probe * |
6ed6bacf | 10104 | +find_probe_by_pc (CORE_ADDR pc, struct objfile **objfile_out) |
51a5ef0f | 10105 | +{ |
6ed6bacf | 10106 | + struct objfile *objfile; |
3a58abaf | 10107 | + |
6ed6bacf AM |
10108 | + ALL_OBJFILES (objfile) |
10109 | + { | |
f412e1b4 | 10110 | + struct stap_probe *probes; |
6ed6bacf AM |
10111 | + int i, num_probes; |
10112 | + stap_entry entry; | |
3a58abaf | 10113 | + |
6ed6bacf AM |
10114 | + if (! objfile->sf || ! objfile->sf->sym_probe_fns) |
10115 | + continue; | |
3a58abaf | 10116 | + |
6ed6bacf AM |
10117 | + /* If this proves too inefficient, we can replace with a hash. */ |
10118 | + probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile, &num_probes); | |
10119 | + for (i = 0; i < num_probes; ++i) | |
10120 | + { | |
10121 | + if (probes[i].address == pc) | |
10122 | + { | |
10123 | + *objfile_out = objfile; | |
10124 | + return &probes[i]; | |
10125 | + } | |
10126 | + } | |
10127 | + } | |
3a58abaf | 10128 | + |
6ed6bacf AM |
10129 | + return NULL; |
10130 | +} | |
51a5ef0f | 10131 | + |
6ed6bacf AM |
10132 | +/* This is called to compute the value of one of the $_probe_arg* |
10133 | + convenience variables. */ | |
3a58abaf | 10134 | + |
6ed6bacf AM |
10135 | +static struct value * |
10136 | +compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar, | |
10137 | + void *data) | |
10138 | +{ | |
10139 | + struct frame_info *frame = get_selected_frame (_("No frame selected")); | |
10140 | + CORE_ADDR pc = get_frame_pc (frame); | |
10141 | + int sel = (int) (uintptr_t) data; | |
10142 | + struct objfile *objfile; | |
f412e1b4 | 10143 | + struct stap_probe *pc_probe; |
6ed6bacf | 10144 | + int n_probes; |
3a58abaf | 10145 | + |
f412e1b4 PS |
10146 | + /* SEL==-1 means "_probe_argc". */ |
10147 | + gdb_assert (sel >= -1 && sel <= STAP_MAX_ARGS); | |
6ed6bacf AM |
10148 | + |
10149 | + pc_probe = find_probe_by_pc (pc, &objfile); | |
10150 | + if (pc_probe == NULL) | |
10151 | + error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc)); | |
10152 | + | |
10153 | + n_probes | |
10154 | + = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile, | |
10155 | + pc_probe); | |
f412e1b4 | 10156 | + if (sel == -1) |
6ed6bacf AM |
10157 | + return value_from_longest (builtin_type (arch)->builtin_int, n_probes); |
10158 | + | |
10159 | + if (sel >= n_probes) | |
10160 | + error (_("Invalid probe argument %d -- probe has %d arguments available"), | |
10161 | + sel, n_probes); | |
10162 | + | |
10163 | + return objfile->sf->sym_probe_fns->sym_evaluate_probe_argument (objfile, | |
10164 | + pc_probe, | |
10165 | + frame, sel); | |
3a58abaf AM |
10166 | +} |
10167 | + | |
6ed6bacf AM |
10168 | +/* This is called to compile one of the $_probe_arg* convenience |
10169 | + variables into an agent expression. */ | |
10170 | + | |
3a58abaf | 10171 | +static void |
6ed6bacf AM |
10172 | +compile_probe_arg (struct internalvar *ivar, struct agent_expr *expr, |
10173 | + struct axs_value *value, void *data) | |
3a58abaf | 10174 | +{ |
6ed6bacf AM |
10175 | + CORE_ADDR pc = expr->scope; |
10176 | + int sel = (int) (uintptr_t) data; | |
10177 | + struct objfile *objfile; | |
f412e1b4 | 10178 | + struct stap_probe *pc_probe; |
6ed6bacf AM |
10179 | + int n_probes; |
10180 | + | |
f412e1b4 PS |
10181 | + /* SEL==-1 means "_probe_argc". */ |
10182 | + gdb_assert (sel >= -1 && sel <= STAP_MAX_ARGS); | |
6ed6bacf AM |
10183 | + |
10184 | + pc_probe = find_probe_by_pc (pc, &objfile); | |
10185 | + if (pc_probe == NULL) | |
10186 | + error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc)); | |
10187 | + | |
10188 | + n_probes | |
10189 | + = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile, | |
10190 | + pc_probe); | |
f412e1b4 | 10191 | + if (sel == -1) |
3a58abaf | 10192 | + { |
6ed6bacf AM |
10193 | + value->kind = axs_rvalue; |
10194 | + value->type = builtin_type (expr->gdbarch)->builtin_int; | |
10195 | + ax_const_l (expr, n_probes); | |
10196 | + return; | |
3a58abaf | 10197 | + } |
6ed6bacf AM |
10198 | + |
10199 | + gdb_assert (sel >= 0); | |
10200 | + if (sel >= n_probes) | |
10201 | + error (_("Invalid probe argument %d -- probe has %d arguments available"), | |
10202 | + sel, n_probes); | |
10203 | + | |
10204 | + objfile->sf->sym_probe_fns->sym_compile_to_ax (objfile, pc_probe, | |
10205 | + expr, value, sel); | |
3a58abaf AM |
10206 | +} |
10207 | + | |
10208 | +\f | |
10209 | + | |
6ed6bacf AM |
10210 | +/* Implementation of `$_probe_arg*' set of variables. */ |
10211 | + | |
10212 | +static const struct internalvar_funcs probe_funcs = | |
10213 | +{ | |
10214 | + compute_probe_arg, | |
10215 | + compile_probe_arg, | |
10216 | + NULL | |
10217 | +}; | |
10218 | + | |
10219 | +void | |
10220 | +_initialize_stap_probe (void) | |
10221 | +{ | |
10222 | + add_info ("probes", info_probes_command, _("\ | |
10223 | +Show available static probes.\n\ | |
10224 | +Usage: info probes [PROVIDER [NAME [OBJECT]]]\n\ | |
10225 | +Each argument is a regular expression, used to select probes.\n\ | |
10226 | +PROVIDER matches probe provider names.\n\ | |
10227 | +NAME matches the probe names.\n\ | |
10228 | +OBJECT match the executable or shared library name.")); | |
10229 | + | |
f412e1b4 PS |
10230 | + add_setshow_zinteger_cmd ("stap-expression", class_maintenance, |
10231 | + &stap_expression_debug, | |
10232 | + _("Set SystemTap expression debugging."), | |
10233 | + _("Show SystemTap expression debugging."), | |
10234 | + _("When non-zero, the internal representation " | |
10235 | + "of SystemTap expressions will be printed."), | |
10236 | + NULL, | |
10237 | + show_stapexpressiondebug, | |
10238 | + &setdebuglist, &showdebuglist); | |
10239 | + | |
6ed6bacf | 10240 | + create_internalvar_type_lazy ("_probe_argc", &probe_funcs, |
f412e1b4 | 10241 | + (void *) (uintptr_t) -1); |
6ed6bacf AM |
10242 | + create_internalvar_type_lazy ("_probe_arg0", &probe_funcs, |
10243 | + (void *) (uintptr_t) 0); | |
10244 | + create_internalvar_type_lazy ("_probe_arg1", &probe_funcs, | |
10245 | + (void *) (uintptr_t) 1); | |
10246 | + create_internalvar_type_lazy ("_probe_arg2", &probe_funcs, | |
10247 | + (void *) (uintptr_t) 2); | |
10248 | + create_internalvar_type_lazy ("_probe_arg3", &probe_funcs, | |
10249 | + (void *) (uintptr_t) 3); | |
10250 | + create_internalvar_type_lazy ("_probe_arg4", &probe_funcs, | |
10251 | + (void *) (uintptr_t) 4); | |
10252 | + create_internalvar_type_lazy ("_probe_arg5", &probe_funcs, | |
10253 | + (void *) (uintptr_t) 5); | |
10254 | + create_internalvar_type_lazy ("_probe_arg6", &probe_funcs, | |
10255 | + (void *) (uintptr_t) 6); | |
10256 | + create_internalvar_type_lazy ("_probe_arg7", &probe_funcs, | |
10257 | + (void *) (uintptr_t) 7); | |
10258 | + create_internalvar_type_lazy ("_probe_arg8", &probe_funcs, | |
10259 | + (void *) (uintptr_t) 8); | |
10260 | + create_internalvar_type_lazy ("_probe_arg9", &probe_funcs, | |
10261 | + (void *) (uintptr_t) 9); | |
f412e1b4 PS |
10262 | + create_internalvar_type_lazy ("_probe_arg10", &probe_funcs, |
10263 | + (void *) (uintptr_t) 10); | |
10264 | + create_internalvar_type_lazy ("_probe_arg11", &probe_funcs, | |
10265 | + (void *) (uintptr_t) 11); | |
10266 | +} | |
10267 | diff --git a/gdb/stap-probe.h b/gdb/stap-probe.h | |
10268 | new file mode 100644 | |
10269 | index 0000000..9b6dc7a | |
10270 | --- /dev/null | |
10271 | +++ b/gdb/stap-probe.h | |
10272 | @@ -0,0 +1,144 @@ | |
6ed6bacf AM |
10273 | +/* SystemTap probe support for GDB. |
10274 | + | |
10275 | + Copyright (C) 2011 Free Software Foundation, Inc. | |
10276 | + | |
10277 | + This file is part of GDB. | |
10278 | + | |
10279 | + This program is free software; you can redistribute it and/or modify | |
10280 | + it under the terms of the GNU General Public License as published by | |
10281 | + the Free Software Foundation; either version 3 of the License, or | |
10282 | + (at your option) any later version. | |
10283 | + | |
10284 | + This program is distributed in the hope that it will be useful, | |
10285 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10286 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10287 | + GNU General Public License for more details. | |
10288 | + | |
10289 | + You should have received a copy of the GNU General Public License | |
10290 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
10291 | + | |
10292 | +#if !defined (STAP_PROBE_H) | |
10293 | +#define STAP_PROBE_H 1 | |
10294 | + | |
f412e1b4 PS |
10295 | +#include "vec.h" |
10296 | + | |
6ed6bacf AM |
10297 | +struct stap_args_info; |
10298 | +struct axs_value; | |
10299 | +struct linespec_result; | |
10300 | + | |
10301 | +/* Main structure which holds information about a SystemTap probe. */ | |
10302 | + | |
10303 | +struct stap_probe | |
10304 | +{ | |
10305 | + /* The provider of this probe. */ | |
10306 | + const char *provider; | |
10307 | + | |
10308 | + /* The name of the probe. */ | |
10309 | + const char *name; | |
10310 | + | |
10311 | + /* The address where the probe is inserted. */ | |
10312 | + CORE_ADDR address; | |
10313 | + | |
10314 | + /* The address of the probe's semaphore, or 0 if this probe does not | |
10315 | + have an associated semaphore. */ | |
10316 | + CORE_ADDR sem_addr; | |
10317 | + | |
10318 | + /* Probe's arguments. Users should generally not examine this, but | |
10319 | + should instead extract information about the arguments using the | |
10320 | + methods provided in sym_probe_fns. */ | |
10321 | + const char *args; | |
51a5ef0f | 10322 | + |
6ed6bacf AM |
10323 | + /* Probe's arguments after parsing. This is an opaque structure that |
10324 | + will hold information about the arguments pointed by ARGS. */ | |
10325 | + struct stap_args_info *parsed_args; | |
f412e1b4 PS |
10326 | + |
10327 | + /* gdbarch structure associated with this probe. */ | |
10328 | + struct gdbarch *gdbarch; | |
10329 | +}; | |
10330 | + | |
10331 | +/* Structure which holds information about the parsing process of one probe's | |
10332 | + argument. */ | |
10333 | + | |
10334 | +struct stap_parse_info | |
10335 | +{ | |
10336 | + /* The probe's argument in a string format. */ | |
10337 | + const char *arg; | |
10338 | + | |
10339 | + /* A pointer to the full chain of arguments. This is useful for printing | |
10340 | + error messages. The parser functions should not modify this argument | |
10341 | + directly; instead, they should use the ARG pointer above. */ | |
10342 | + const char *saved_arg; | |
10343 | + | |
10344 | + /* The expected argument type (bitness), as defined in the probe's | |
10345 | + argument. For instance, if the argument begins with `-8@', it means | |
10346 | + the bitness is 64-bit signed. In this case, ARG_TYPE would represent | |
10347 | + the type `int64_t'. */ | |
10348 | + struct type *arg_type; | |
10349 | + | |
10350 | + /* A pointer to the current gdbarch. */ | |
10351 | + struct gdbarch *gdbarch; | |
10352 | + | |
10353 | + /* Greater than zero if we are inside a parenthesized expression. Useful | |
10354 | + for knowing when to skip spaces or not. */ | |
10355 | + int inside_paren_p; | |
6ed6bacf | 10356 | +}; |
51a5ef0f | 10357 | + |
f412e1b4 PS |
10358 | +typedef struct stap_probe *stap_probe_p; |
10359 | +DEF_VEC_P (stap_probe_p); | |
51a5ef0f | 10360 | + |
6ed6bacf AM |
10361 | +/* A helper for linespec that decodes a stap probe specification. It |
10362 | + returns a symtabs_and_lines object and updates *ARGPTR or throws an | |
10363 | + error. */ | |
51a5ef0f | 10364 | + |
6ed6bacf AM |
10365 | +extern struct symtabs_and_lines parse_stap_probe (char **argptr, |
10366 | + struct linespec_result *canon); | |
51a5ef0f | 10367 | + |
f412e1b4 PS |
10368 | +/* Search OBJFILE for a probe with the given PROVIDER and NAME. |
10369 | + Return a VEC of all probes that were found. If no matching probe | |
10370 | + is found, return NULL. The caller must free the VEC. */ | |
51a5ef0f | 10371 | + |
f412e1b4 PS |
10372 | +extern VEC (stap_probe_p) *find_probes_in_objfile (struct objfile *objfile, |
10373 | + const char *provider, | |
10374 | + const char *name); | |
51a5ef0f | 10375 | + |
6ed6bacf AM |
10376 | +/* Given a PC, find an associated SystemTap probe. If a probe is |
10377 | + found, set *OBJFILE_OUT to the probe's objfile, and return the | |
10378 | + probe. If no probe is found, return NULL. */ | |
3a58abaf | 10379 | + |
f412e1b4 PS |
10380 | +extern struct stap_probe *find_probe_by_pc (CORE_ADDR pc, |
10381 | + struct objfile **objfile_out); | |
3a58abaf | 10382 | + |
6ed6bacf AM |
10383 | +/* Given PROBE, returns the number of arguments present in that probe's |
10384 | + argument string. */ | |
3a58abaf | 10385 | + |
f412e1b4 | 10386 | +extern int stap_get_probe_argument_count (struct stap_probe *probe); |
3a58abaf | 10387 | + |
6ed6bacf AM |
10388 | +/* Given PARSED_ARGS, frees the space allocated to hold information about |
10389 | + the probe's parsed arguments. */ | |
3a58abaf | 10390 | + |
6ed6bacf | 10391 | +extern void stap_free_parsed_args (struct stap_args_info *parsed_args); |
51a5ef0f | 10392 | + |
f412e1b4 | 10393 | +/* Evaluate the probe's argument N, returning a value corresponding |
6ed6bacf | 10394 | + to it. */ |
7566401a | 10395 | + |
6ed6bacf | 10396 | +extern struct value *stap_evaluate_probe_argument (struct objfile *objfile, |
f412e1b4 | 10397 | + struct stap_probe *probe, |
6ed6bacf AM |
10398 | + struct frame_info *frame, |
10399 | + int n); | |
3a58abaf | 10400 | + |
6ed6bacf | 10401 | +/* Compile the probe's argument N to agent expression. */ |
3a58abaf | 10402 | + |
6ed6bacf | 10403 | +extern void stap_compile_to_ax (struct objfile *objfile, |
f412e1b4 | 10404 | + struct stap_probe *probe, |
6ed6bacf AM |
10405 | + struct agent_expr *expr, |
10406 | + struct axs_value *value, | |
10407 | + int n); | |
3a58abaf | 10408 | + |
6ed6bacf AM |
10409 | +/* A convenience function that finds a probe at the PC in FRAME and |
10410 | + evaluates argument N. If there is no probe at that location, or if | |
10411 | + the probe does not have enough arguments, this returns NULL. */ | |
3a58abaf | 10412 | + |
6ed6bacf AM |
10413 | +extern struct value *stap_safe_evaluate_at_pc (struct frame_info *frame, |
10414 | + int n); | |
3a58abaf | 10415 | + |
6ed6bacf | 10416 | +#endif /* !defined (STAP_PROBE_H) */ |
f412e1b4 PS |
10417 | diff --git a/gdb/symfile.h b/gdb/symfile.h |
10418 | index 6b664cd..6ca797d 100644 | |
10419 | --- a/gdb/symfile.h | |
10420 | +++ b/gdb/symfile.h | |
10421 | @@ -29,6 +29,11 @@ struct objfile; | |
6ed6bacf AM |
10422 | struct obj_section; |
10423 | struct obstack; | |
10424 | struct block; | |
10425 | +struct stap_probe; | |
10426 | +struct value; | |
10427 | +struct frame_info; | |
10428 | +struct agent_expr; | |
10429 | +struct axs_value; | |
7566401a | 10430 | |
6ed6bacf | 10431 | /* Comparison function for symbol look ups. */ |
7566401a | 10432 | |
f412e1b4 PS |
10433 | @@ -299,6 +304,52 @@ struct quick_symbol_functions |
10434 | int need_fullname); | |
6ed6bacf | 10435 | }; |
51a5ef0f | 10436 | |
6ed6bacf AM |
10437 | +/* Structure of functions used for SystemTap probe support. If one of |
10438 | + these functions is provided, all must be. */ | |
10439 | + | |
10440 | +struct sym_probe_fns | |
10441 | +{ | |
10442 | + /* If non-NULL, return an array of SystemTap probe objects. The | |
10443 | + number of objects is returned in *NUM_PROBES. */ | |
f412e1b4 | 10444 | + struct stap_probe *(*sym_get_probes) (struct objfile *, |
6ed6bacf AM |
10445 | + int *num_probes); |
10446 | + | |
10447 | + /* Return the number of arguments available to PROBE. PROBE will | |
10448 | + have come from a call to this objfile's sym_get_probes method. | |
10449 | + If you provide an implementation of sym_get_probes, you must | |
10450 | + implement this method as well. */ | |
10451 | + int (*sym_get_probe_argument_count) (struct objfile *objfile, | |
f412e1b4 | 10452 | + struct stap_probe *probe); |
6ed6bacf AM |
10453 | + |
10454 | + /* Evaluate the Nth argument available to PROBE. PROBE will have | |
10455 | + come from a call to this objfile's sym_get_probes method. N will | |
10456 | + be between 0 and the number of arguments available to this probe. | |
10457 | + FRAME is the frame in which the evaluation is done; the frame's | |
10458 | + PC will match the address of the probe. If you provide an | |
10459 | + implementation of sym_get_probes, you must implement this method | |
10460 | + as well. */ | |
10461 | + struct value *(*sym_evaluate_probe_argument) (struct objfile *objfile, | |
f412e1b4 | 10462 | + struct stap_probe *probe, |
6ed6bacf AM |
10463 | + struct frame_info *frame, |
10464 | + int n); | |
10465 | + | |
10466 | + /* Compile the Nth probe argument to an agent expression. PROBE | |
10467 | + will have come from a call to this objfile's sym_get_probes | |
10468 | + method. N will be between 0 and the number of arguments | |
10469 | + available to this probe. EXPR and VALUE are the agent expression | |
10470 | + that is being updated. */ | |
10471 | + void (*sym_compile_to_ax) (struct objfile *objfile, | |
f412e1b4 | 10472 | + struct stap_probe *probe, |
6ed6bacf AM |
10473 | + struct agent_expr *expr, |
10474 | + struct axs_value *value, | |
10475 | + int n); | |
10476 | + | |
10477 | + /* Relocate the probe section of OBJFILE. */ | |
10478 | + void (*sym_relocate_probe) (struct objfile *objfile, | |
10479 | + struct section_offsets *new_offsets, | |
10480 | + struct section_offsets *delta); | |
10481 | +}; | |
3a58abaf | 10482 | + |
6ed6bacf AM |
10483 | /* Structure to keep track of symbol reading functions for various |
10484 | object file types. */ | |
10485 | ||
f412e1b4 | 10486 | @@ -369,6 +420,10 @@ struct sym_fns |
6ed6bacf AM |
10487 | |
10488 | bfd_byte *(*sym_relocate) (struct objfile *, asection *sectp, bfd_byte *buf); | |
10489 | ||
10490 | + /* If non-NULL, this objfile has probe support, and all the probe | |
10491 | + functions referred to here will be non-NULL. */ | |
10492 | + const struct sym_probe_fns *sym_probe_fns; | |
10493 | + | |
10494 | /* The "quick" (aka partial) symbol functions for this symbol | |
10495 | reader. */ | |
10496 | const struct quick_symbol_functions *qf; | |
f412e1b4 PS |
10497 | diff --git a/gdb/symtab.c b/gdb/symtab.c |
10498 | index 1746d69..2abc17f 100644 | |
10499 | --- a/gdb/symtab.c | |
10500 | +++ b/gdb/symtab.c | |
10501 | @@ -869,6 +869,7 @@ init_sal (struct symtab_and_line *sal) | |
6ed6bacf AM |
10502 | sal->end = 0; |
10503 | sal->explicit_pc = 0; | |
10504 | sal->explicit_line = 0; | |
10505 | + sal->semaphore = 0; | |
51a5ef0f | 10506 | } |
6ed6bacf | 10507 | \f |
51a5ef0f | 10508 | |
f412e1b4 PS |
10509 | diff --git a/gdb/symtab.h b/gdb/symtab.h |
10510 | index 4836dd6..668a22b 100644 | |
10511 | --- a/gdb/symtab.h | |
10512 | +++ b/gdb/symtab.h | |
10513 | @@ -1056,6 +1056,10 @@ struct symtab_and_line | |
6ed6bacf AM |
10514 | CORE_ADDR end; |
10515 | int explicit_pc; | |
10516 | int explicit_line; | |
10517 | + | |
10518 | + /* If non-zero, the semaphore location associated with a SystemTap | |
10519 | + probe. */ | |
10520 | + CORE_ADDR semaphore; | |
10521 | }; | |
10522 | ||
10523 | extern void init_sal (struct symtab_and_line *sal); | |
f412e1b4 PS |
10524 | diff --git a/gdb/testsuite/gdb.ada/packed_array.exp b/gdb/testsuite/gdb.ada/packed_array.exp |
10525 | index 678639c..47a2202 100644 | |
10526 | --- a/gdb/testsuite/gdb.ada/packed_array.exp | |
10527 | +++ b/gdb/testsuite/gdb.ada/packed_array.exp | |
10528 | @@ -60,5 +60,11 @@ gdb_test_multiple "$test" "$test" { | |
10529 | # are. Observed with (FSF GNU Ada 4.5.3 20110124). | |
10530 | xfail $test | |
10531 | } | |
10532 | + -re "= \\(\\)\[\r\n\]+$gdb_prompt $" { | |
10533 | + # archer-jankratochvil-vla resolves it as a dynamic type resolved as an | |
10534 | + # empty array [0..-1]. | |
10535 | + # DW_AT_upper_bound : (DW_OP_fbreg: -48; DW_OP_deref) | |
10536 | + xfail $test | |
10537 | + } | |
10538 | } | |
10539 | ||
10540 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S | |
10541 | new file mode 100644 | |
10542 | index 0000000..83faaf6 | |
10543 | --- /dev/null | |
10544 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S | |
51a5ef0f PS |
10545 | @@ -0,0 +1,457 @@ |
10546 | + .file "x86_64-vla-pointer.c" | |
10547 | + .section .debug_abbrev,"",@progbits | |
10548 | +.Ldebug_abbrev0: | |
10549 | + .section .debug_info,"",@progbits | |
10550 | +.Ldebug_info0: | |
10551 | + .section .debug_line,"",@progbits | |
10552 | +.Ldebug_line0: | |
7566401a | 10553 | + .text |
51a5ef0f PS |
10554 | +.Ltext0: |
10555 | +.globl foo | |
10556 | + .type foo, @function | |
10557 | +foo: | |
10558 | +.LFB2: | |
10559 | + .file 1 "x86_64-vla-pointer.c" | |
10560 | + .loc 1 22 0 | |
10561 | + pushq %rbp | |
10562 | +.LCFI0: | |
10563 | + movq %rsp, %rbp | |
10564 | +.LCFI1: | |
10565 | + subq $64, %rsp | |
10566 | +.LCFI2: | |
10567 | + movl %edi, -36(%rbp) | |
10568 | + .loc 1 22 0 | |
10569 | + movq %rsp, %rax | |
10570 | + movq %rax, -48(%rbp) | |
10571 | + .loc 1 23 0 | |
10572 | + movl -36(%rbp), %edx | |
10573 | + movslq %edx,%rax | |
10574 | + subq $1, %rax | |
10575 | + movq %rax, -24(%rbp) | |
10576 | + .loc 1 24 0 | |
10577 | + movslq %edx,%rax | |
10578 | + addq $15, %rax | |
10579 | + addq $15, %rax | |
10580 | + shrq $4, %rax | |
10581 | + salq $4, %rax | |
10582 | + subq %rax, %rsp | |
10583 | + movq %rsp, -56(%rbp) | |
10584 | + movq -56(%rbp), %rax | |
10585 | + addq $15, %rax | |
10586 | + shrq $4, %rax | |
10587 | + salq $4, %rax | |
10588 | + movq %rax, -56(%rbp) | |
10589 | + movq -56(%rbp), %rax | |
10590 | + movq %rax, -16(%rbp) | |
10591 | + .loc 1 27 0 | |
10592 | + movl $0, -4(%rbp) | |
10593 | + jmp .L2 | |
10594 | +.L3: | |
10595 | + .loc 1 28 0 | |
10596 | + movl -4(%rbp), %esi | |
10597 | + movl -4(%rbp), %eax | |
10598 | + movl %eax, %ecx | |
10599 | + movq -16(%rbp), %rdx | |
10600 | + movslq %esi,%rax | |
10601 | + movb %cl, (%rdx,%rax) | |
10602 | + .loc 1 27 0 | |
10603 | + addl $1, -4(%rbp) | |
10604 | +.L2: | |
10605 | + movl -4(%rbp), %eax | |
10606 | + cmpl -36(%rbp), %eax | |
10607 | + jl .L3 | |
10608 | + .loc 1 30 0 | |
10609 | + .globl break_here | |
10610 | +break_here: | |
10611 | + movq -16(%rbp), %rax | |
10612 | + movb $0, (%rax) | |
10613 | + movq -48(%rbp), %rsp | |
10614 | + .loc 1 31 0 | |
10615 | + leave | |
10616 | + ret | |
10617 | +.LFE2: | |
10618 | + .size foo, .-foo | |
10619 | + .section .debug_frame,"",@progbits | |
10620 | +.Lframe0: | |
10621 | + .long .LECIE0-.LSCIE0 | |
10622 | +.LSCIE0: | |
10623 | + .long 0xffffffff | |
10624 | + .byte 0x1 | |
10625 | + .string "" | |
10626 | + .uleb128 0x1 | |
10627 | + .sleb128 -8 | |
10628 | + .byte 0x10 | |
10629 | + .byte 0xc | |
10630 | + .uleb128 0x7 | |
10631 | + .uleb128 0x8 | |
10632 | + .byte 0x90 | |
10633 | + .uleb128 0x1 | |
10634 | + .align 8 | |
10635 | +.LECIE0: | |
10636 | +.LSFDE0: | |
10637 | + .long .LEFDE0-.LASFDE0 | |
10638 | +.LASFDE0: | |
10639 | + .long .Lframe0 | |
10640 | + .quad .LFB2 | |
10641 | + .quad .LFE2-.LFB2 | |
10642 | + .byte 0x4 | |
10643 | + .long .LCFI0-.LFB2 | |
10644 | + .byte 0xe | |
10645 | + .uleb128 0x10 | |
10646 | + .byte 0x86 | |
10647 | + .uleb128 0x2 | |
10648 | + .byte 0x4 | |
10649 | + .long .LCFI1-.LCFI0 | |
10650 | + .byte 0xd | |
10651 | + .uleb128 0x6 | |
10652 | + .align 8 | |
10653 | +.LEFDE0: | |
10654 | + .section .eh_frame,"a",@progbits | |
10655 | +.Lframe1: | |
10656 | + .long .LECIE1-.LSCIE1 | |
10657 | +.LSCIE1: | |
10658 | + .long 0x0 | |
10659 | + .byte 0x1 | |
10660 | + .string "zR" | |
10661 | + .uleb128 0x1 | |
10662 | + .sleb128 -8 | |
10663 | + .byte 0x10 | |
10664 | + .uleb128 0x1 | |
10665 | + .byte 0x3 | |
10666 | + .byte 0xc | |
10667 | + .uleb128 0x7 | |
10668 | + .uleb128 0x8 | |
10669 | + .byte 0x90 | |
10670 | + .uleb128 0x1 | |
10671 | + .align 8 | |
10672 | +.LECIE1: | |
10673 | +.LSFDE1: | |
10674 | + .long .LEFDE1-.LASFDE1 | |
10675 | +.LASFDE1: | |
10676 | + .long .LASFDE1-.Lframe1 | |
10677 | + .long .LFB2 | |
10678 | + .long .LFE2-.LFB2 | |
10679 | + .uleb128 0x0 | |
10680 | + .byte 0x4 | |
10681 | + .long .LCFI0-.LFB2 | |
10682 | + .byte 0xe | |
10683 | + .uleb128 0x10 | |
10684 | + .byte 0x86 | |
10685 | + .uleb128 0x2 | |
10686 | + .byte 0x4 | |
10687 | + .long .LCFI1-.LCFI0 | |
10688 | + .byte 0xd | |
10689 | + .uleb128 0x6 | |
10690 | + .align 8 | |
10691 | +.LEFDE1: | |
10692 | + .text | |
10693 | +.Letext0: | |
10694 | + .section .debug_loc,"",@progbits | |
10695 | +.Ldebug_loc0: | |
10696 | +.LLST0: | |
10697 | + .quad .LFB2-.Ltext0 | |
10698 | + .quad .LCFI0-.Ltext0 | |
10699 | + .value 0x2 | |
10700 | + .byte 0x77 | |
10701 | + .sleb128 8 | |
10702 | + .quad .LCFI0-.Ltext0 | |
10703 | + .quad .LCFI1-.Ltext0 | |
10704 | + .value 0x2 | |
10705 | + .byte 0x77 | |
10706 | + .sleb128 16 | |
10707 | + .quad .LCFI1-.Ltext0 | |
10708 | + .quad .LFE2-.Ltext0 | |
10709 | + .value 0x2 | |
10710 | + .byte 0x76 | |
10711 | + .sleb128 16 | |
10712 | + .quad 0x0 | |
10713 | + .quad 0x0 | |
10714 | + .section .debug_info | |
10715 | +.Ldebug_relative: | |
10716 | + .long .Ldebug_end - .Ldebug_start | |
10717 | +.Ldebug_start: | |
10718 | + .value 0x2 | |
10719 | + .long .Ldebug_abbrev0 | |
10720 | + .byte 0x8 | |
10721 | + .uleb128 0x1 | |
10722 | + .long .LASF2 | |
10723 | + .byte 0x1 | |
10724 | + .long .LASF3 | |
10725 | + .long .LASF4 | |
10726 | + .quad .Ltext0 | |
10727 | + .quad .Letext0 | |
10728 | + .long .Ldebug_line0 | |
10729 | + .uleb128 0x2 | |
10730 | + .byte 0x1 | |
10731 | + .string "foo" | |
10732 | + .byte 0x1 | |
10733 | + .byte 0x16 | |
10734 | + .byte 0x1 | |
10735 | + .quad .LFB2 | |
10736 | + .quad .LFE2 | |
10737 | + .long .LLST0 | |
10738 | + .long .Ltype_int - .Ldebug_relative | |
10739 | + .uleb128 0x3 | |
10740 | + .long .LASF5 | |
10741 | + .byte 0x1 | |
10742 | + .byte 0x15 | |
10743 | + .long .Ltype_int - .Ldebug_relative | |
10744 | + .byte 0x2 | |
10745 | + .byte 0x91 | |
10746 | + .sleb128 -52 | |
10747 | +.Ltag_pointer: | |
10748 | + .uleb128 0x4 | |
10749 | + .byte 0x8 /* DW_AT_byte_size */ | |
10750 | + .long .Ltag_array_type - .debug_info /* DW_AT_type */ | |
10751 | + .uleb128 0x5 /* Abbrev Number: 5 (DW_TAG_variable) */ | |
10752 | + .long .LASF0 | |
10753 | + .byte 0x1 | |
10754 | + .byte 0x18 | |
10755 | +#if 1 | |
10756 | + .long .Ltag_pointer - .debug_info | |
10757 | +#else | |
10758 | + /* Debugging only: Skip the typedef indirection. */ | |
10759 | + .long .Ltag_array_type - .debug_info | |
10760 | +#endif | |
10761 | + /* DW_AT_location: DW_FORM_block1: start */ | |
10762 | + .byte 0x3 | |
10763 | + .byte 0x91 | |
10764 | + .sleb128 -32 | |
10765 | +#if 0 | |
10766 | + .byte 0x6 /* DW_OP_deref */ | |
10767 | +#else | |
10768 | + .byte 0x96 /* DW_OP_nop */ | |
10769 | +#endif | |
10770 | + /* DW_AT_location: DW_FORM_block1: end */ | |
10771 | + .uleb128 0x6 | |
10772 | + .string "i" | |
10773 | + .byte 0x1 | |
10774 | + .byte 0x19 | |
10775 | + .long .Ltype_int - .Ldebug_relative | |
10776 | + .byte 0x2 | |
10777 | + .byte 0x91 | |
10778 | + .sleb128 -20 | |
10779 | + .byte 0x0 | |
10780 | +.Ltype_int: | |
10781 | + .uleb128 0x7 | |
10782 | + .byte 0x4 | |
10783 | + .byte 0x5 | |
10784 | + .string "int" | |
10785 | +.Ltag_array_type: | |
10786 | + .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */ | |
10787 | + .long .Ltype_char - .Ldebug_relative | |
10788 | + .long .Ltype_ulong - .Ldebug_relative /* DW_AT_sibling: DW_FORM_ref4 */ | |
10789 | +1: /* DW_AT_data_location: DW_FORM_block1: start */ | |
10790 | + .byte 2f - 3f /* length */ | |
10791 | +3: | |
10792 | + .byte 0x97 /* DW_OP_push_object_address */ | |
10793 | +#if 1 | |
10794 | + .byte 0x6 /* DW_OP_deref */ | |
10795 | +#else | |
10796 | + .byte 0x96 /* DW_OP_nop */ | |
10797 | +#endif | |
10798 | +2: /* DW_AT_data_location: DW_FORM_block1: end */ | |
10799 | + .uleb128 0x9 | |
10800 | + .long .Ltype_char - .Ldebug_relative /* DW_AT_type: DW_FORM_ref4 */ | |
10801 | + .byte 0x3 | |
10802 | + .byte 0x91 | |
10803 | + .sleb128 -40 | |
10804 | + .byte 0x6 | |
10805 | + .byte 0x0 | |
10806 | +.Ltype_ulong: | |
10807 | + .uleb128 0xa | |
10808 | + .byte 0x8 | |
10809 | + .byte 0x7 | |
10810 | +.Ltype_char: | |
10811 | + .uleb128 0xb | |
10812 | + .byte 0x1 | |
10813 | + .byte 0x6 | |
10814 | + .long .LASF1 | |
10815 | + .byte 0x0 | |
10816 | +.Ldebug_end: | |
10817 | + .section .debug_abbrev | |
10818 | + .uleb128 0x1 | |
10819 | + .uleb128 0x11 | |
10820 | + .byte 0x1 | |
10821 | + .uleb128 0x25 | |
10822 | + .uleb128 0xe | |
10823 | + .uleb128 0x13 | |
10824 | + .uleb128 0xb | |
10825 | + .uleb128 0x3 | |
10826 | + .uleb128 0xe | |
10827 | + .uleb128 0x1b | |
10828 | + .uleb128 0xe | |
10829 | + .uleb128 0x11 | |
10830 | + .uleb128 0x1 | |
10831 | + .uleb128 0x12 | |
10832 | + .uleb128 0x1 | |
10833 | + .uleb128 0x10 | |
10834 | + .uleb128 0x6 | |
10835 | + .byte 0x0 | |
10836 | + .byte 0x0 | |
10837 | + .uleb128 0x2 | |
10838 | + .uleb128 0x2e | |
10839 | + .byte 0x1 | |
10840 | + .uleb128 0x3f | |
10841 | + .uleb128 0xc | |
10842 | + .uleb128 0x3 | |
10843 | + .uleb128 0x8 | |
10844 | + .uleb128 0x3a | |
10845 | + .uleb128 0xb | |
10846 | + .uleb128 0x3b | |
10847 | + .uleb128 0xb | |
10848 | + .uleb128 0x27 | |
10849 | + .uleb128 0xc | |
10850 | + .uleb128 0x11 | |
10851 | + .uleb128 0x1 | |
10852 | + .uleb128 0x12 | |
10853 | + .uleb128 0x1 | |
10854 | + .uleb128 0x40 | |
10855 | + .uleb128 0x6 | |
10856 | + .uleb128 0x1 | |
10857 | + .uleb128 0x13 | |
10858 | + .byte 0x0 | |
10859 | + .byte 0x0 | |
10860 | + .uleb128 0x3 | |
10861 | + .uleb128 0x5 | |
10862 | + .byte 0x0 | |
10863 | + .uleb128 0x3 | |
10864 | + .uleb128 0xe | |
10865 | + .uleb128 0x3a | |
10866 | + .uleb128 0xb | |
10867 | + .uleb128 0x3b | |
10868 | + .uleb128 0xb | |
10869 | + .uleb128 0x49 | |
10870 | + .uleb128 0x13 | |
10871 | + .uleb128 0x2 | |
10872 | + .uleb128 0xa | |
10873 | + .byte 0x0 | |
10874 | + .byte 0x0 | |
10875 | + .uleb128 0x4 /* .Ltag_pointer abbrev */ | |
10876 | + .uleb128 0x0f /* DW_TAG_pointer_type */ | |
10877 | + .byte 0x0 | |
10878 | + .uleb128 0x0b | |
10879 | + .uleb128 0xb | |
10880 | + .uleb128 0x49 | |
10881 | + .uleb128 0x13 | |
10882 | + .byte 0x0 | |
10883 | + .byte 0x0 | |
10884 | + .uleb128 0x5 | |
10885 | + .uleb128 0x34 | |
10886 | + .byte 0x0 | |
10887 | + .uleb128 0x3 | |
10888 | + .uleb128 0xe | |
10889 | + .uleb128 0x3a | |
10890 | + .uleb128 0xb | |
10891 | + .uleb128 0x3b | |
10892 | + .uleb128 0xb | |
10893 | + .uleb128 0x49 | |
10894 | + .uleb128 0x13 | |
10895 | + .uleb128 0x2 | |
10896 | + .uleb128 0xa | |
10897 | + .byte 0x0 | |
10898 | + .byte 0x0 | |
10899 | + .uleb128 0x6 | |
10900 | + .uleb128 0x34 | |
10901 | + .byte 0x0 | |
10902 | + .uleb128 0x3 | |
10903 | + .uleb128 0x8 | |
10904 | + .uleb128 0x3a | |
10905 | + .uleb128 0xb | |
10906 | + .uleb128 0x3b | |
10907 | + .uleb128 0xb | |
10908 | + .uleb128 0x49 | |
10909 | + .uleb128 0x13 | |
10910 | + .uleb128 0x2 | |
10911 | + .uleb128 0xa | |
10912 | + .byte 0x0 | |
10913 | + .byte 0x0 | |
10914 | + .uleb128 0x7 | |
10915 | + .uleb128 0x24 | |
10916 | + .byte 0x0 | |
10917 | + .uleb128 0xb | |
10918 | + .uleb128 0xb | |
10919 | + .uleb128 0x3e | |
10920 | + .uleb128 0xb | |
10921 | + .uleb128 0x3 | |
10922 | + .uleb128 0x8 | |
10923 | + .byte 0x0 | |
10924 | + .byte 0x0 | |
10925 | + .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */ | |
10926 | + .uleb128 0x1 | |
10927 | + .byte 0x1 | |
10928 | + .uleb128 0x49 /* DW_AT_type */ | |
10929 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
10930 | + .uleb128 0x1 /* DW_AT_sibling */ | |
10931 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
10932 | + .uleb128 0x50 /* DW_AT_data_location */ | |
10933 | + .uleb128 0xa /* DW_FORM_block1 */ | |
10934 | + .byte 0x0 | |
10935 | + .byte 0x0 | |
10936 | + .uleb128 0x9 | |
10937 | + .uleb128 0x21 | |
10938 | + .byte 0x0 | |
10939 | + .uleb128 0x49 /* DW_AT_type */ | |
10940 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
10941 | + .uleb128 0x2f | |
10942 | + .uleb128 0xa | |
10943 | + .byte 0x0 | |
10944 | + .byte 0x0 | |
10945 | + .uleb128 0xa | |
10946 | + .uleb128 0x24 | |
10947 | + .byte 0x0 | |
10948 | + .uleb128 0xb | |
10949 | + .uleb128 0xb | |
10950 | + .uleb128 0x3e | |
10951 | + .uleb128 0xb | |
10952 | + .byte 0x0 | |
10953 | + .byte 0x0 | |
10954 | + .uleb128 0xb | |
10955 | + .uleb128 0x24 | |
10956 | + .byte 0x0 | |
10957 | + .uleb128 0xb | |
10958 | + .uleb128 0xb | |
10959 | + .uleb128 0x3e | |
10960 | + .uleb128 0xb | |
10961 | + .uleb128 0x3 | |
10962 | + .uleb128 0xe | |
10963 | + .byte 0x0 | |
10964 | + .byte 0x0 | |
10965 | + .byte 0x0 | |
10966 | + .section .debug_pubnames,"",@progbits | |
10967 | + .long 0x16 | |
10968 | + .value 0x2 | |
10969 | + .long .Ldebug_info0 | |
10970 | + .long 0xa8 | |
10971 | + .long 0x2d | |
10972 | + .string "foo" | |
10973 | + .long 0x0 | |
10974 | + .section .debug_aranges,"",@progbits | |
10975 | + .long 0x2c | |
10976 | + .value 0x2 | |
10977 | + .long .Ldebug_info0 | |
10978 | + .byte 0x8 | |
10979 | + .byte 0x0 | |
10980 | + .value 0x0 | |
10981 | + .value 0x0 | |
10982 | + .quad .Ltext0 | |
10983 | + .quad .Letext0-.Ltext0 | |
10984 | + .quad 0x0 | |
10985 | + .quad 0x0 | |
10986 | + .section .debug_str,"MS",@progbits,1 | |
10987 | +.LASF0: | |
10988 | + .string "array" | |
10989 | +.LASF5: | |
10990 | + .string "size" | |
10991 | +.LASF3: | |
10992 | + .string "x86_64-vla-pointer.c" | |
10993 | +.LASF6: | |
10994 | + .string "array_t" | |
10995 | +.LASF1: | |
10996 | + .string "char" | |
10997 | +.LASF4: | |
10998 | + .string "gdb.arch" | |
10999 | +.LASF2: | |
11000 | + .string "GNU C 4.3.2 20081105 (Red Hat 4.3.2-7)" | |
11001 | + .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)" | |
11002 | + .section .note.GNU-stack,"",@progbits | |
f412e1b4 PS |
11003 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c |
11004 | new file mode 100644 | |
11005 | index 0000000..fe2c8f7 | |
11006 | --- /dev/null | |
11007 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c | |
51a5ef0f | 11008 | @@ -0,0 +1,43 @@ |
7566401a | 11009 | +/* This testcase is part of GDB, the GNU debugger. |
3a58abaf | 11010 | + |
51a5ef0f | 11011 | + Copyright 2009 Free Software Foundation, Inc. |
3a58abaf AM |
11012 | + |
11013 | + This program is free software; you can redistribute it and/or modify | |
11014 | + it under the terms of the GNU General Public License as published by | |
51a5ef0f | 11015 | + the Free Software Foundation; either version 3 of the License, or |
3a58abaf AM |
11016 | + (at your option) any later version. |
11017 | + | |
11018 | + This program is distributed in the hope that it will be useful, | |
11019 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11020 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11021 | + GNU General Public License for more details. | |
3a58abaf | 11022 | + |
51a5ef0f PS |
11023 | + You should have received a copy of the GNU General Public License |
11024 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
3a58abaf | 11025 | + |
51a5ef0f | 11026 | +#if 0 |
7566401a ER |
11027 | + |
11028 | +void | |
51a5ef0f | 11029 | +foo (int size) |
3a58abaf | 11030 | +{ |
51a5ef0f PS |
11031 | + typedef char array_t[size]; |
11032 | + array_t array; | |
11033 | + int i; | |
3a58abaf | 11034 | + |
51a5ef0f PS |
11035 | + for (i = 0; i < size; i++) |
11036 | + array[i] = i; | |
3a58abaf | 11037 | + |
51a5ef0f | 11038 | + array[0] = 0; /* break-here */ |
7566401a ER |
11039 | +} |
11040 | + | |
51a5ef0f PS |
11041 | +#else |
11042 | + | |
7566401a | 11043 | +int |
51a5ef0f | 11044 | +main (void) |
7566401a | 11045 | +{ |
51a5ef0f PS |
11046 | + foo (26); |
11047 | + foo (78); | |
3a58abaf AM |
11048 | + return 0; |
11049 | +} | |
3a58abaf | 11050 | + |
51a5ef0f | 11051 | +#endif |
f412e1b4 PS |
11052 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp |
11053 | new file mode 100644 | |
11054 | index 0000000..d243cf1 | |
11055 | --- /dev/null | |
11056 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp | |
51a5ef0f | 11057 | @@ -0,0 +1,66 @@ |
7566401a | 11058 | +# Copyright 2009 Free Software Foundation, Inc. |
3a58abaf AM |
11059 | + |
11060 | +# This program is free software; you can redistribute it and/or modify | |
11061 | +# it under the terms of the GNU General Public License as published by | |
11062 | +# the Free Software Foundation; either version 3 of the License, or | |
11063 | +# (at your option) any later version. | |
11064 | +# | |
11065 | +# This program is distributed in the hope that it will be useful, | |
11066 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11067 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11068 | +# GNU General Public License for more details. | |
11069 | +# | |
11070 | +# You should have received a copy of the GNU General Public License | |
11071 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
11072 | + | |
51a5ef0f PS |
11073 | +if ![istarget "x86_64-*-*"] then { |
11074 | + verbose "Skipping over gdb.arch/x86_64-vla-pointer.exp test made only for x86_64." | |
11075 | + return | |
3a58abaf AM |
11076 | +} |
11077 | + | |
51a5ef0f PS |
11078 | +set testfile x86_64-vla-pointer |
11079 | +set srcasmfile ${testfile}-foo.S | |
11080 | +set srcfile ${testfile}.c | |
11081 | +set binfile ${objdir}/${subdir}/${testfile} | |
11082 | +set binobjfile ${objdir}/${subdir}/${testfile}-foo.o | |
11083 | +if { [gdb_compile "${srcdir}/${subdir}/${srcasmfile}" "${binobjfile}" object {}] != "" } { | |
11084 | + untested "Couldn't compile test program" | |
7566401a | 11085 | + return -1 |
3a58abaf | 11086 | +} |
51a5ef0f PS |
11087 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${binobjfile}" "${binfile}" executable {debug}] != "" } { |
11088 | + untested "Couldn't compile test program" | |
3a58abaf AM |
11089 | + return -1 |
11090 | +} | |
11091 | + | |
11092 | +gdb_exit | |
11093 | +gdb_start | |
11094 | +gdb_reinitialize_dir $srcdir/$subdir | |
11095 | +gdb_load ${binfile} | |
11096 | + | |
51a5ef0f PS |
11097 | +if ![runto_main] { |
11098 | + untested x86_64-vla-pointer | |
11099 | + return -1 | |
3a58abaf AM |
11100 | +} |
11101 | + | |
51a5ef0f PS |
11102 | +gdb_breakpoint "break_here" |
11103 | + | |
11104 | +gdb_continue_to_breakpoint "break_here" | |
11105 | + | |
11106 | +gdb_test "whatis array" "type = char \\(\\*\\)\\\[variable\\\]" "first: whatis array" | |
11107 | +gdb_test "ptype array" "type = char \\(\\*\\)\\\[26\\\]" "first: ptype array" | |
11108 | + | |
11109 | +gdb_test "whatis *array" "type = char \\\[26\\\]" "first: whatis *array" | |
11110 | +gdb_test "ptype *array" "type = char \\\[26\\\]" "first: ptype *array" | |
11111 | + | |
11112 | +gdb_test "p (*array)\[1\]" "\\$\[0-9\] = 1 '\\\\001'" | |
11113 | +gdb_test "p (*array)\[2\]" "\\$\[0-9\] = 2 '\\\\002'" | |
11114 | +gdb_test "p (*array)\[3\]" "\\$\[0-9\] = 3 '\\\\003'" | |
11115 | +gdb_test "p (*array)\[4\]" "\\$\[0-9\] = 4 '\\\\004'" | |
11116 | + | |
11117 | +gdb_continue_to_breakpoint "break_here" | |
11118 | + | |
11119 | +gdb_test "whatis array" "type = char \\(\\*\\)\\\[variable\\\]" "second: whatis array" | |
11120 | +gdb_test "ptype array" "type = char \\(\\*\\)\\\[78\\\]" "second: ptype array" | |
11121 | + | |
11122 | +gdb_test "whatis *array" "type = char \\\[78\\\]" "second: whatis *array" | |
11123 | +gdb_test "ptype *array" "type = char \\\[78\\\]" "second: ptype *array" | |
f412e1b4 PS |
11124 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S |
11125 | new file mode 100644 | |
11126 | index 0000000..66f7a39 | |
11127 | --- /dev/null | |
11128 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S | |
51a5ef0f PS |
11129 | @@ -0,0 +1,455 @@ |
11130 | + .file "x86_64-vla-typedef.c" | |
11131 | + .section .debug_abbrev,"",@progbits | |
11132 | +.Ldebug_abbrev0: | |
11133 | + .section .debug_info,"",@progbits | |
11134 | +.Ldebug_info0: | |
11135 | + .section .debug_line,"",@progbits | |
11136 | +.Ldebug_line0: | |
11137 | + .text | |
11138 | +.Ltext0: | |
11139 | +.globl foo | |
11140 | + .type foo, @function | |
11141 | +foo: | |
11142 | +.LFB2: | |
11143 | + .file 1 "x86_64-vla-typedef.c" | |
11144 | + .loc 1 22 0 | |
11145 | + pushq %rbp | |
11146 | +.LCFI0: | |
11147 | + movq %rsp, %rbp | |
11148 | +.LCFI1: | |
11149 | + subq $64, %rsp | |
11150 | +.LCFI2: | |
11151 | + movl %edi, -36(%rbp) | |
11152 | + .loc 1 22 0 | |
11153 | + movq %rsp, %rax | |
11154 | + movq %rax, -48(%rbp) | |
11155 | + .loc 1 23 0 | |
11156 | + movl -36(%rbp), %edx | |
11157 | + movslq %edx,%rax | |
11158 | + subq $1, %rax | |
11159 | + movq %rax, -24(%rbp) | |
11160 | + .loc 1 24 0 | |
11161 | + movslq %edx,%rax | |
11162 | + addq $15, %rax | |
11163 | + addq $15, %rax | |
11164 | + shrq $4, %rax | |
11165 | + salq $4, %rax | |
11166 | + subq %rax, %rsp | |
11167 | + movq %rsp, -56(%rbp) | |
11168 | + movq -56(%rbp), %rax | |
11169 | + addq $15, %rax | |
11170 | + shrq $4, %rax | |
11171 | + salq $4, %rax | |
11172 | + movq %rax, -56(%rbp) | |
11173 | + movq -56(%rbp), %rax | |
11174 | + movq %rax, -16(%rbp) | |
11175 | + .loc 1 27 0 | |
11176 | + movl $0, -4(%rbp) | |
11177 | + jmp .L2 | |
11178 | +.L3: | |
11179 | + .loc 1 28 0 | |
11180 | + movl -4(%rbp), %esi | |
11181 | + movl -4(%rbp), %eax | |
11182 | + movl %eax, %ecx | |
11183 | + movq -16(%rbp), %rdx | |
11184 | + movslq %esi,%rax | |
11185 | + movb %cl, (%rdx,%rax) | |
11186 | + .loc 1 27 0 | |
11187 | + addl $1, -4(%rbp) | |
11188 | +.L2: | |
11189 | + movl -4(%rbp), %eax | |
11190 | + cmpl -36(%rbp), %eax | |
11191 | + jl .L3 | |
11192 | + .loc 1 30 0 | |
11193 | + .globl break_here | |
11194 | +break_here: | |
11195 | + movq -16(%rbp), %rax | |
11196 | + movb $0, (%rax) | |
11197 | + movq -48(%rbp), %rsp | |
11198 | + .loc 1 31 0 | |
11199 | + leave | |
11200 | + ret | |
11201 | +.LFE2: | |
11202 | + .size foo, .-foo | |
11203 | + .section .debug_frame,"",@progbits | |
11204 | +.Lframe0: | |
11205 | + .long .LECIE0-.LSCIE0 | |
11206 | +.LSCIE0: | |
11207 | + .long 0xffffffff | |
11208 | + .byte 0x1 | |
11209 | + .string "" | |
11210 | + .uleb128 0x1 | |
11211 | + .sleb128 -8 | |
11212 | + .byte 0x10 | |
11213 | + .byte 0xc | |
11214 | + .uleb128 0x7 | |
11215 | + .uleb128 0x8 | |
11216 | + .byte 0x90 | |
11217 | + .uleb128 0x1 | |
11218 | + .align 8 | |
11219 | +.LECIE0: | |
11220 | +.LSFDE0: | |
11221 | + .long .LEFDE0-.LASFDE0 | |
11222 | +.LASFDE0: | |
11223 | + .long .Lframe0 | |
11224 | + .quad .LFB2 | |
11225 | + .quad .LFE2-.LFB2 | |
11226 | + .byte 0x4 | |
11227 | + .long .LCFI0-.LFB2 | |
11228 | + .byte 0xe | |
11229 | + .uleb128 0x10 | |
11230 | + .byte 0x86 | |
11231 | + .uleb128 0x2 | |
11232 | + .byte 0x4 | |
11233 | + .long .LCFI1-.LCFI0 | |
11234 | + .byte 0xd | |
11235 | + .uleb128 0x6 | |
11236 | + .align 8 | |
11237 | +.LEFDE0: | |
11238 | + .section .eh_frame,"a",@progbits | |
11239 | +.Lframe1: | |
11240 | + .long .LECIE1-.LSCIE1 | |
11241 | +.LSCIE1: | |
11242 | + .long 0x0 | |
11243 | + .byte 0x1 | |
11244 | + .string "zR" | |
11245 | + .uleb128 0x1 | |
11246 | + .sleb128 -8 | |
11247 | + .byte 0x10 | |
11248 | + .uleb128 0x1 | |
11249 | + .byte 0x3 | |
11250 | + .byte 0xc | |
11251 | + .uleb128 0x7 | |
11252 | + .uleb128 0x8 | |
11253 | + .byte 0x90 | |
11254 | + .uleb128 0x1 | |
11255 | + .align 8 | |
11256 | +.LECIE1: | |
11257 | +.LSFDE1: | |
11258 | + .long .LEFDE1-.LASFDE1 | |
11259 | +.LASFDE1: | |
11260 | + .long .LASFDE1-.Lframe1 | |
11261 | + .long .LFB2 | |
11262 | + .long .LFE2-.LFB2 | |
11263 | + .uleb128 0x0 | |
11264 | + .byte 0x4 | |
11265 | + .long .LCFI0-.LFB2 | |
11266 | + .byte 0xe | |
11267 | + .uleb128 0x10 | |
11268 | + .byte 0x86 | |
11269 | + .uleb128 0x2 | |
11270 | + .byte 0x4 | |
11271 | + .long .LCFI1-.LCFI0 | |
11272 | + .byte 0xd | |
11273 | + .uleb128 0x6 | |
11274 | + .align 8 | |
11275 | +.LEFDE1: | |
11276 | + .text | |
11277 | +.Letext0: | |
11278 | + .section .debug_loc,"",@progbits | |
11279 | +.Ldebug_loc0: | |
11280 | +.LLST0: | |
11281 | + .quad .LFB2-.Ltext0 | |
11282 | + .quad .LCFI0-.Ltext0 | |
11283 | + .value 0x2 | |
11284 | + .byte 0x77 | |
11285 | + .sleb128 8 | |
11286 | + .quad .LCFI0-.Ltext0 | |
11287 | + .quad .LCFI1-.Ltext0 | |
11288 | + .value 0x2 | |
11289 | + .byte 0x77 | |
11290 | + .sleb128 16 | |
11291 | + .quad .LCFI1-.Ltext0 | |
11292 | + .quad .LFE2-.Ltext0 | |
11293 | + .value 0x2 | |
11294 | + .byte 0x76 | |
11295 | + .sleb128 16 | |
11296 | + .quad 0x0 | |
11297 | + .quad 0x0 | |
11298 | + .section .debug_info | |
11299 | + .long .Ldebug_end - .Ldebug_start | |
11300 | +.Ldebug_start: | |
11301 | + .value 0x2 | |
11302 | + .long .Ldebug_abbrev0 | |
11303 | + .byte 0x8 | |
11304 | + .uleb128 0x1 | |
11305 | + .long .LASF2 | |
11306 | + .byte 0x1 | |
11307 | + .long .LASF3 | |
11308 | + .long .LASF4 | |
11309 | + .quad .Ltext0 | |
11310 | + .quad .Letext0 | |
11311 | + .long .Ldebug_line0 | |
11312 | + .uleb128 0x2 | |
11313 | + .byte 0x1 | |
11314 | + .string "foo" | |
11315 | + .byte 0x1 | |
11316 | + .byte 0x16 | |
11317 | + .byte 0x1 | |
11318 | + .quad .LFB2 | |
11319 | + .quad .LFE2 | |
11320 | + .long .LLST0 | |
11321 | + .long 0x83 | |
11322 | + .uleb128 0x3 | |
11323 | + .long .LASF5 | |
11324 | + .byte 0x1 | |
11325 | + .byte 0x15 | |
11326 | + .long 0x83 | |
11327 | + .byte 0x2 | |
11328 | + .byte 0x91 | |
11329 | + .sleb128 -52 | |
11330 | +.Ltag_typedef: | |
11331 | + .uleb128 0x4 | |
11332 | + .long .LASF6 | |
11333 | + .byte 0x1 | |
11334 | + .byte 0x17 | |
11335 | + .long .Ltag_array_type - .debug_info | |
11336 | + .uleb128 0x5 /* Abbrev Number: 5 (DW_TAG_variable) */ | |
11337 | + .long .LASF0 | |
11338 | + .byte 0x1 | |
11339 | + .byte 0x18 | |
11340 | +#if 1 | |
11341 | + .long .Ltag_typedef - .debug_info | |
11342 | +#else | |
11343 | + /* Debugging only: Skip the typedef indirection. */ | |
11344 | + .long .Ltag_array_type - .debug_info | |
11345 | +#endif | |
11346 | + /* DW_AT_location: DW_FORM_block1: start */ | |
11347 | + .byte 0x3 | |
11348 | + .byte 0x91 | |
11349 | + .sleb128 -32 | |
11350 | +#if 0 | |
11351 | + .byte 0x6 /* DW_OP_deref */ | |
11352 | +#else | |
11353 | + .byte 0x96 /* DW_OP_nop */ | |
11354 | +#endif | |
11355 | + /* DW_AT_location: DW_FORM_block1: end */ | |
11356 | + .uleb128 0x6 | |
11357 | + .string "i" | |
11358 | + .byte 0x1 | |
11359 | + .byte 0x19 | |
11360 | + .long 0x83 | |
11361 | + .byte 0x2 | |
11362 | + .byte 0x91 | |
11363 | + .sleb128 -20 | |
11364 | + .byte 0x0 | |
11365 | + .uleb128 0x7 | |
11366 | + .byte 0x4 | |
11367 | + .byte 0x5 | |
11368 | + .string "int" | |
11369 | +.Ltag_array_type: | |
11370 | + .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */ | |
11371 | + .long 0xa0 + (2f - 1f) /* DW_AT_type: DW_FORM_ref4 */ | |
11372 | + .long 0x9d + (2f - 1f) /* DW_AT_sibling: DW_FORM_ref4 */ | |
11373 | +1: /* DW_AT_data_location: DW_FORM_block1: start */ | |
11374 | + .byte 2f - 3f /* length */ | |
11375 | +3: | |
11376 | + .byte 0x97 /* DW_OP_push_object_address */ | |
11377 | + .byte 0x6 /* DW_OP_deref */ | |
11378 | +2: /* DW_AT_data_location: DW_FORM_block1: end */ | |
11379 | + .uleb128 0x9 | |
11380 | + .long 0x9d + (2b - 1b) /* DW_AT_type: DW_FORM_ref4 */ | |
11381 | + .byte 0x3 | |
11382 | + .byte 0x91 | |
11383 | + .sleb128 -40 | |
11384 | + .byte 0x6 | |
11385 | + .byte 0x0 | |
11386 | + .uleb128 0xa | |
11387 | + .byte 0x8 | |
11388 | + .byte 0x7 | |
11389 | + .uleb128 0xb | |
11390 | + .byte 0x1 | |
11391 | + .byte 0x6 | |
11392 | + .long .LASF1 | |
11393 | + .byte 0x0 | |
11394 | +.Ldebug_end: | |
11395 | + .section .debug_abbrev | |
11396 | + .uleb128 0x1 | |
11397 | + .uleb128 0x11 | |
11398 | + .byte 0x1 | |
11399 | + .uleb128 0x25 | |
11400 | + .uleb128 0xe | |
11401 | + .uleb128 0x13 | |
11402 | + .uleb128 0xb | |
11403 | + .uleb128 0x3 | |
11404 | + .uleb128 0xe | |
11405 | + .uleb128 0x1b | |
11406 | + .uleb128 0xe | |
11407 | + .uleb128 0x11 | |
11408 | + .uleb128 0x1 | |
11409 | + .uleb128 0x12 | |
11410 | + .uleb128 0x1 | |
11411 | + .uleb128 0x10 | |
11412 | + .uleb128 0x6 | |
11413 | + .byte 0x0 | |
11414 | + .byte 0x0 | |
11415 | + .uleb128 0x2 | |
11416 | + .uleb128 0x2e | |
11417 | + .byte 0x1 | |
11418 | + .uleb128 0x3f | |
11419 | + .uleb128 0xc | |
11420 | + .uleb128 0x3 | |
11421 | + .uleb128 0x8 | |
11422 | + .uleb128 0x3a | |
11423 | + .uleb128 0xb | |
11424 | + .uleb128 0x3b | |
11425 | + .uleb128 0xb | |
11426 | + .uleb128 0x27 | |
11427 | + .uleb128 0xc | |
11428 | + .uleb128 0x11 | |
11429 | + .uleb128 0x1 | |
11430 | + .uleb128 0x12 | |
11431 | + .uleb128 0x1 | |
11432 | + .uleb128 0x40 | |
11433 | + .uleb128 0x6 | |
11434 | + .uleb128 0x1 | |
11435 | + .uleb128 0x13 | |
11436 | + .byte 0x0 | |
11437 | + .byte 0x0 | |
11438 | + .uleb128 0x3 | |
11439 | + .uleb128 0x5 | |
11440 | + .byte 0x0 | |
11441 | + .uleb128 0x3 | |
11442 | + .uleb128 0xe | |
11443 | + .uleb128 0x3a | |
11444 | + .uleb128 0xb | |
11445 | + .uleb128 0x3b | |
11446 | + .uleb128 0xb | |
11447 | + .uleb128 0x49 | |
11448 | + .uleb128 0x13 | |
11449 | + .uleb128 0x2 | |
11450 | + .uleb128 0xa | |
11451 | + .byte 0x0 | |
11452 | + .byte 0x0 | |
11453 | + .uleb128 0x4 | |
11454 | + .uleb128 0x16 | |
11455 | + .byte 0x0 | |
11456 | + .uleb128 0x3 | |
11457 | + .uleb128 0xe | |
11458 | + .uleb128 0x3a | |
11459 | + .uleb128 0xb | |
11460 | + .uleb128 0x3b | |
11461 | + .uleb128 0xb | |
11462 | + .uleb128 0x49 | |
11463 | + .uleb128 0x13 | |
11464 | + .byte 0x0 | |
11465 | + .byte 0x0 | |
11466 | + .uleb128 0x5 | |
11467 | + .uleb128 0x34 | |
11468 | + .byte 0x0 | |
11469 | + .uleb128 0x3 | |
11470 | + .uleb128 0xe | |
11471 | + .uleb128 0x3a | |
11472 | + .uleb128 0xb | |
11473 | + .uleb128 0x3b | |
11474 | + .uleb128 0xb | |
11475 | + .uleb128 0x49 | |
11476 | + .uleb128 0x13 | |
11477 | + .uleb128 0x2 | |
11478 | + .uleb128 0xa | |
11479 | + .byte 0x0 | |
11480 | + .byte 0x0 | |
11481 | + .uleb128 0x6 | |
11482 | + .uleb128 0x34 | |
11483 | + .byte 0x0 | |
11484 | + .uleb128 0x3 | |
11485 | + .uleb128 0x8 | |
11486 | + .uleb128 0x3a | |
11487 | + .uleb128 0xb | |
11488 | + .uleb128 0x3b | |
11489 | + .uleb128 0xb | |
11490 | + .uleb128 0x49 | |
11491 | + .uleb128 0x13 | |
11492 | + .uleb128 0x2 | |
11493 | + .uleb128 0xa | |
11494 | + .byte 0x0 | |
11495 | + .byte 0x0 | |
11496 | + .uleb128 0x7 | |
11497 | + .uleb128 0x24 | |
11498 | + .byte 0x0 | |
11499 | + .uleb128 0xb | |
11500 | + .uleb128 0xb | |
11501 | + .uleb128 0x3e | |
11502 | + .uleb128 0xb | |
11503 | + .uleb128 0x3 | |
11504 | + .uleb128 0x8 | |
11505 | + .byte 0x0 | |
11506 | + .byte 0x0 | |
11507 | + .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */ | |
11508 | + .uleb128 0x1 | |
11509 | + .byte 0x1 | |
11510 | + .uleb128 0x49 /* DW_AT_type */ | |
11511 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
11512 | + .uleb128 0x1 /* DW_AT_sibling */ | |
11513 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
11514 | + .uleb128 0x50 /* DW_AT_data_location */ | |
11515 | + .uleb128 0xa /* DW_FORM_block1 */ | |
11516 | + .byte 0x0 | |
11517 | + .byte 0x0 | |
11518 | + .uleb128 0x9 | |
11519 | + .uleb128 0x21 | |
11520 | + .byte 0x0 | |
11521 | + .uleb128 0x49 /* DW_AT_type */ | |
11522 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
11523 | + .uleb128 0x2f | |
11524 | + .uleb128 0xa | |
11525 | + .byte 0x0 | |
11526 | + .byte 0x0 | |
11527 | + .uleb128 0xa | |
11528 | + .uleb128 0x24 | |
11529 | + .byte 0x0 | |
11530 | + .uleb128 0xb | |
11531 | + .uleb128 0xb | |
11532 | + .uleb128 0x3e | |
11533 | + .uleb128 0xb | |
11534 | + .byte 0x0 | |
11535 | + .byte 0x0 | |
11536 | + .uleb128 0xb | |
11537 | + .uleb128 0x24 | |
11538 | + .byte 0x0 | |
11539 | + .uleb128 0xb | |
11540 | + .uleb128 0xb | |
11541 | + .uleb128 0x3e | |
11542 | + .uleb128 0xb | |
11543 | + .uleb128 0x3 | |
11544 | + .uleb128 0xe | |
11545 | + .byte 0x0 | |
11546 | + .byte 0x0 | |
11547 | + .byte 0x0 | |
11548 | + .section .debug_pubnames,"",@progbits | |
11549 | + .long 0x16 | |
11550 | + .value 0x2 | |
11551 | + .long .Ldebug_info0 | |
11552 | + .long 0xa8 | |
11553 | + .long 0x2d | |
11554 | + .string "foo" | |
11555 | + .long 0x0 | |
11556 | + .section .debug_aranges,"",@progbits | |
11557 | + .long 0x2c | |
11558 | + .value 0x2 | |
11559 | + .long .Ldebug_info0 | |
11560 | + .byte 0x8 | |
11561 | + .byte 0x0 | |
11562 | + .value 0x0 | |
11563 | + .value 0x0 | |
11564 | + .quad .Ltext0 | |
11565 | + .quad .Letext0-.Ltext0 | |
11566 | + .quad 0x0 | |
11567 | + .quad 0x0 | |
11568 | + .section .debug_str,"MS",@progbits,1 | |
11569 | +.LASF0: | |
11570 | + .string "array" | |
11571 | +.LASF5: | |
11572 | + .string "size" | |
11573 | +.LASF3: | |
11574 | + .string "x86_64-vla-typedef.c" | |
11575 | +.LASF6: | |
11576 | + .string "array_t" | |
11577 | +.LASF1: | |
11578 | + .string "char" | |
11579 | +.LASF4: | |
11580 | + .string "gdb.arch" | |
11581 | +.LASF2: | |
11582 | + .string "GNU C 4.3.2 20081105 (Red Hat 4.3.2-7)" | |
11583 | + .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)" | |
11584 | + .section .note.GNU-stack,"",@progbits | |
f412e1b4 PS |
11585 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c |
11586 | new file mode 100644 | |
11587 | index 0000000..b809c4e | |
11588 | --- /dev/null | |
11589 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c | |
51a5ef0f PS |
11590 | @@ -0,0 +1,43 @@ |
11591 | +/* This testcase is part of GDB, the GNU debugger. | |
3a58abaf | 11592 | + |
51a5ef0f | 11593 | + Copyright 2008 Free Software Foundation, Inc. |
3a58abaf | 11594 | + |
51a5ef0f PS |
11595 | + This program is free software; you can redistribute it and/or modify |
11596 | + it under the terms of the GNU General Public License as published by | |
11597 | + the Free Software Foundation; either version 3 of the License, or | |
11598 | + (at your option) any later version. | |
3a58abaf | 11599 | + |
51a5ef0f PS |
11600 | + This program is distributed in the hope that it will be useful, |
11601 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11602 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11603 | + GNU General Public License for more details. | |
3a58abaf | 11604 | + |
51a5ef0f PS |
11605 | + You should have received a copy of the GNU General Public License |
11606 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
3a58abaf | 11607 | + |
51a5ef0f | 11608 | +#if 0 |
3a58abaf | 11609 | + |
51a5ef0f PS |
11610 | +void |
11611 | +foo (int size) | |
11612 | +{ | |
11613 | + typedef char array_t[size]; | |
11614 | + array_t array; | |
11615 | + int i; | |
3a58abaf | 11616 | + |
51a5ef0f PS |
11617 | + for (i = 0; i < size; i++) |
11618 | + array[i] = i; | |
3a58abaf | 11619 | + |
51a5ef0f PS |
11620 | + array[0] = 0; /* break-here */ |
11621 | +} | |
3a58abaf | 11622 | + |
51a5ef0f | 11623 | +#else |
3a58abaf | 11624 | + |
51a5ef0f PS |
11625 | +int |
11626 | +main (void) | |
11627 | +{ | |
11628 | + foo (26); | |
11629 | + foo (78); | |
11630 | + return 0; | |
11631 | +} | |
3a58abaf | 11632 | + |
51a5ef0f | 11633 | +#endif |
f412e1b4 PS |
11634 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp |
11635 | new file mode 100644 | |
11636 | index 0000000..b05411e | |
11637 | --- /dev/null | |
11638 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp | |
51a5ef0f | 11639 | @@ -0,0 +1,64 @@ |
7566401a | 11640 | +# Copyright 2009 Free Software Foundation, Inc. |
3a58abaf | 11641 | + |
7566401a ER |
11642 | +# This program is free software; you can redistribute it and/or modify |
11643 | +# it under the terms of the GNU General Public License as published by | |
51a5ef0f | 11644 | +# the Free Software Foundation; either version 3 of the License, or |
7566401a | 11645 | +# (at your option) any later version. |
51a5ef0f | 11646 | +# |
7566401a ER |
11647 | +# This program is distributed in the hope that it will be useful, |
11648 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11649 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11650 | +# GNU General Public License for more details. | |
51a5ef0f | 11651 | +# |
7566401a | 11652 | +# You should have received a copy of the GNU General Public License |
51a5ef0f | 11653 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
3a58abaf | 11654 | + |
51a5ef0f | 11655 | +# Test DW_AT_data_location accessed through DW_TAG_typedef intermediate. |
3a58abaf | 11656 | + |
51a5ef0f PS |
11657 | +if ![istarget "x86_64-*-*"] then { |
11658 | + verbose "Skipping over gdb.arch/x86_64-vla-typedef.exp test made only for x86_64." | |
11659 | + return | |
3a58abaf | 11660 | +} |
3a58abaf | 11661 | + |
51a5ef0f PS |
11662 | +set testfile x86_64-vla-typedef |
11663 | +set srcasmfile ${testfile}-foo.S | |
11664 | +set srcfile ${testfile}.c | |
3a58abaf | 11665 | +set binfile ${objdir}/${subdir}/${testfile} |
51a5ef0f PS |
11666 | +set binobjfile ${objdir}/${subdir}/${testfile}-foo.o |
11667 | +if { [gdb_compile "${srcdir}/${subdir}/${srcasmfile}" "${binobjfile}" object {}] != "" } { | |
11668 | + untested "Couldn't compile test program" | |
11669 | + return -1 | |
11670 | +} | |
11671 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${binobjfile}" "${binfile}" executable {debug}] != "" } { | |
11672 | + untested "Couldn't compile test program" | |
3a58abaf AM |
11673 | + return -1 |
11674 | +} | |
11675 | + | |
7566401a ER |
11676 | +gdb_exit |
11677 | +gdb_start | |
11678 | +gdb_reinitialize_dir $srcdir/$subdir | |
11679 | +gdb_load ${binfile} | |
3a58abaf | 11680 | + |
51a5ef0f PS |
11681 | +if ![runto_main] { |
11682 | + untested x86_64-vla-typedef | |
11683 | + return -1 | |
11684 | +} | |
3a58abaf | 11685 | + |
51a5ef0f | 11686 | +gdb_breakpoint "break_here" |
3a58abaf | 11687 | + |
51a5ef0f | 11688 | +gdb_continue_to_breakpoint "break_here" |
3a58abaf | 11689 | + |
51a5ef0f | 11690 | +gdb_test "whatis array" "type = array_t" "first: whatis array" |
3a58abaf | 11691 | + |
51a5ef0f | 11692 | +gdb_test "ptype array" "type = char \\\[26\\\]" "first: ptype array" |
3a58abaf | 11693 | + |
51a5ef0f PS |
11694 | +gdb_test "p array\[1\]" "\\$\[0-9\] = 1 '\\\\001'" |
11695 | +gdb_test "p array\[2\]" "\\$\[0-9\] = 2 '\\\\002'" | |
11696 | +gdb_test "p array\[3\]" "\\$\[0-9\] = 3 '\\\\003'" | |
11697 | +gdb_test "p array\[4\]" "\\$\[0-9\] = 4 '\\\\004'" | |
3a58abaf | 11698 | + |
51a5ef0f | 11699 | +gdb_continue_to_breakpoint "break_here" |
3a58abaf | 11700 | + |
51a5ef0f | 11701 | +gdb_test "whatis array" "type = array_t" "second: whatis array" |
3a58abaf | 11702 | + |
51a5ef0f | 11703 | +gdb_test "ptype array" "type = char \\\[78\\\]" "second: ptype array" |
f412e1b4 PS |
11704 | diff --git a/gdb/testsuite/gdb.base/arrayidx.c b/gdb/testsuite/gdb.base/arrayidx.c |
11705 | index a99137e..c3dc2d9 100644 | |
11706 | --- a/gdb/testsuite/gdb.base/arrayidx.c | |
11707 | +++ b/gdb/testsuite/gdb.base/arrayidx.c | |
51a5ef0f PS |
11708 | @@ -17,6 +17,13 @@ |
11709 | ||
11710 | int array[] = {1, 2, 3, 4}; | |
11711 | ||
11712 | +#ifdef __GNUC__ | |
11713 | +struct | |
11714 | + { | |
11715 | + int a[0]; | |
11716 | + } unbound; | |
11717 | +#endif | |
11718 | + | |
11719 | int | |
11720 | main (void) | |
11721 | { | |
f412e1b4 PS |
11722 | diff --git a/gdb/testsuite/gdb.base/arrayidx.exp b/gdb/testsuite/gdb.base/arrayidx.exp |
11723 | index cba0024..0dc0e46 100644 | |
11724 | --- a/gdb/testsuite/gdb.base/arrayidx.exp | |
11725 | +++ b/gdb/testsuite/gdb.base/arrayidx.exp | |
11726 | @@ -53,4 +53,12 @@ gdb_test "print array" \ | |
51a5ef0f PS |
11727 | "\\{\\\[0\\\] = 1, \\\[1\\\] = 2, \\\[2\\\] = 3, \\\[3\\\] = 4\\}" \ |
11728 | "Print array with array-indexes on" | |
11729 | ||
11730 | - | |
6ed6bacf | 11731 | +set test "p unbound.a == &unbound.a\[0\]" |
51a5ef0f | 11732 | +gdb_test_multiple $test $test { |
6ed6bacf | 11733 | + -re " = 1\r\n$gdb_prompt $" { |
51a5ef0f PS |
11734 | + pass $test |
11735 | + } | |
6ed6bacf AM |
11736 | + -re "No symbol \"unbound\" in current context.\r\n$gdb_prompt $" { |
11737 | + unsupported "$test (no GCC)" | |
11738 | + } | |
51a5ef0f | 11739 | +} |
f412e1b4 PS |
11740 | diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp |
11741 | index 9677396..55d03a9 100644 | |
11742 | --- a/gdb/testsuite/gdb.base/default.exp | |
11743 | +++ b/gdb/testsuite/gdb.base/default.exp | |
11744 | @@ -610,6 +610,19 @@ gdb_test_list_exact "show convenience" "show convenience" \ | |
6ed6bacf AM |
11745 | {$_sdata = void} \ |
11746 | {$_siginfo = void} \ | |
11747 | {$_thread = 0} \ | |
11748 | + {$_probe_argc = <error: No frame selected>} \ | |
11749 | + {$_probe_arg0 = <error: No frame selected>} \ | |
11750 | + {$_probe_arg1 = <error: No frame selected>} \ | |
11751 | + {$_probe_arg2 = <error: No frame selected>} \ | |
11752 | + {$_probe_arg3 = <error: No frame selected>} \ | |
11753 | + {$_probe_arg4 = <error: No frame selected>} \ | |
11754 | + {$_probe_arg5 = <error: No frame selected>} \ | |
11755 | + {$_probe_arg6 = <error: No frame selected>} \ | |
11756 | + {$_probe_arg7 = <error: No frame selected>} \ | |
11757 | + {$_probe_arg8 = <error: No frame selected>} \ | |
11758 | + {$_probe_arg9 = <error: No frame selected>} \ | |
f412e1b4 PS |
11759 | + {$_probe_arg10 = <error: No frame selected>} \ |
11760 | + {$_probe_arg11 = <error: No frame selected>} \ | |
6ed6bacf AM |
11761 | } |
11762 | ||
11763 | #test show directories | |
f412e1b4 PS |
11764 | diff --git a/gdb/testsuite/gdb.base/internal-var-field-address.c b/gdb/testsuite/gdb.base/internal-var-field-address.c |
11765 | new file mode 100644 | |
11766 | index 0000000..eeb7b85 | |
11767 | --- /dev/null | |
11768 | +++ b/gdb/testsuite/gdb.base/internal-var-field-address.c | |
51a5ef0f PS |
11769 | @@ -0,0 +1,20 @@ |
11770 | +/* This testcase is part of GDB, the GNU debugger. | |
11771 | + | |
11772 | + Copyright 2009 Free Software Foundation, Inc. | |
11773 | + | |
11774 | + This program is free software; you can redistribute it and/or modify | |
11775 | + it under the terms of the GNU General Public License as published by | |
11776 | + the Free Software Foundation; either version 3 of the License, or | |
11777 | + (at your option) any later version. | |
11778 | + | |
11779 | + This program is distributed in the hope that it will be useful, | |
11780 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11781 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11782 | + GNU General Public License for more details. | |
11783 | + | |
11784 | + You should have received a copy of the GNU General Public License | |
11785 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
11786 | + | |
11787 | +struct { | |
11788 | + int field; | |
11789 | +} staticstruct = { 1 }; | |
f412e1b4 PS |
11790 | diff --git a/gdb/testsuite/gdb.base/internal-var-field-address.exp b/gdb/testsuite/gdb.base/internal-var-field-address.exp |
11791 | new file mode 100644 | |
11792 | index 0000000..6d82e73 | |
11793 | --- /dev/null | |
11794 | +++ b/gdb/testsuite/gdb.base/internal-var-field-address.exp | |
51a5ef0f PS |
11795 | @@ -0,0 +1,26 @@ |
11796 | +# Copyright 2009 Free Software Foundation, Inc. | |
11797 | + | |
11798 | +# This program is free software; you can redistribute it and/or modify | |
11799 | +# it under the terms of the GNU General Public License as published by | |
11800 | +# the Free Software Foundation; either version 3 of the License, or | |
11801 | +# (at your option) any later version. | |
11802 | +# | |
11803 | +# This program is distributed in the hope that it will be useful, | |
11804 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11805 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11806 | +# GNU General Public License for more details. | |
11807 | +# | |
11808 | +# You should have received a copy of the GNU General Public License | |
11809 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
11810 | + | |
11811 | +set test internal-var-field-address | |
11812 | +set binfile ${test}.x | |
11813 | +if { [gdb_compile "${srcdir}/${subdir}/${test}.c" "${objdir}/${subdir}/${binfile}" object {debug}] != "" } { | |
11814 | + untested "Couldn't compile test program" | |
7566401a ER |
11815 | + return -1 |
11816 | +} | |
3a58abaf | 11817 | + |
7566401a ER |
11818 | +clean_restart $binfile |
11819 | + | |
51a5ef0f PS |
11820 | +gdb_test {set $varstruct = staticstruct} |
11821 | +gdb_test {p $varstruct.field} " = 1" | |
f412e1b4 PS |
11822 | diff --git a/gdb/testsuite/gdb.base/stap-probe.c b/gdb/testsuite/gdb.base/stap-probe.c |
11823 | new file mode 100644 | |
11824 | index 0000000..236da96 | |
11825 | --- /dev/null | |
11826 | +++ b/gdb/testsuite/gdb.base/stap-probe.c | |
11827 | @@ -0,0 +1,108 @@ | |
6ed6bacf AM |
11828 | +/* This testcase is part of GDB, the GNU debugger. |
11829 | + | |
11830 | + Copyright 2011 Free Software Foundation, Inc. | |
11831 | + | |
11832 | + This program is free software; you can redistribute it and/or modify | |
11833 | + it under the terms of the GNU General Public License as published by | |
11834 | + the Free Software Foundation; either version 3 of the License, or | |
11835 | + (at your option) any later version. | |
11836 | + | |
11837 | + This program is distributed in the hope that it will be useful, | |
11838 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11839 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11840 | + GNU General Public License for more details. | |
11841 | + | |
11842 | + You should have received a copy of the GNU General Public License | |
11843 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
11844 | + | |
11845 | +#if USE_PROBES | |
11846 | + | |
11847 | +#define _SDT_HAS_SEMAPHORES | |
11848 | +__extension__ unsigned short teste_user_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes"))); | |
11849 | +#define TEST teste_user_semaphore | |
11850 | + | |
11851 | +__extension__ unsigned short teste_two_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes"))); | |
11852 | +#define TEST2 teste_two_semaphore | |
11853 | + | |
f412e1b4 PS |
11854 | +__extension__ unsigned short teste_m4_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes"))); |
11855 | + | |
11856 | +__extension__ unsigned short teste_pstr_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes"))); | |
11857 | + | |
11858 | +__extension__ unsigned short teste_ps_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes"))); | |
6ed6bacf AM |
11859 | +#else |
11860 | + | |
11861 | +#define TEST 1 | |
11862 | +#define TEST2 1 | |
11863 | + | |
11864 | +#endif | |
11865 | + | |
11866 | +#include <sys/sdt.h> | |
11867 | + | |
11868 | +/* We only support SystemTap and only the v3 form. */ | |
11869 | +#if _SDT_NOTE_TYPE != 3 | |
11870 | +#error "not using SystemTap v3 probes" | |
11871 | +#endif | |
11872 | + | |
f412e1b4 PS |
11873 | +struct funcs |
11874 | +{ | |
11875 | + int val; | |
11876 | + | |
11877 | + const char *(*ps) (int); | |
11878 | +}; | |
11879 | + | |
11880 | +static void | |
6ed6bacf AM |
11881 | +m1 (void) |
11882 | +{ | |
11883 | + if (TEST2) | |
11884 | + STAP_PROBE (teste, two); | |
11885 | +} | |
11886 | + | |
f412e1b4 | 11887 | +static void |
6ed6bacf AM |
11888 | +m2 (void) |
11889 | +{ | |
11890 | + if (TEST2) | |
11891 | + STAP_PROBE (teste, two); | |
11892 | +} | |
11893 | + | |
f412e1b4 | 11894 | +static int |
6ed6bacf AM |
11895 | +f (int x) |
11896 | +{ | |
11897 | + if (TEST) | |
f412e1b4 | 11898 | + STAP_PROBE1 (teste, user, x); |
6ed6bacf AM |
11899 | + return x+5; |
11900 | +} | |
11901 | + | |
f412e1b4 PS |
11902 | +static const char * |
11903 | +pstr (int val) | |
11904 | +{ | |
11905 | + const char *a = "This is a test message."; | |
11906 | + const char *b = "This is another test message."; | |
11907 | + | |
11908 | + STAP_PROBE3 (teste, ps, a, b, val); | |
11909 | + | |
11910 | + return val == 0 ? a : b; | |
11911 | +} | |
11912 | + | |
11913 | +static void | |
11914 | +m4 (const struct funcs *fs, int v) | |
11915 | +{ | |
11916 | + STAP_PROBE3 (teste, m4, fs->val, fs->ps (v), v); | |
11917 | +} | |
11918 | + | |
6ed6bacf AM |
11919 | +int |
11920 | +main() | |
11921 | +{ | |
f412e1b4 PS |
11922 | + struct funcs fs; |
11923 | + | |
11924 | + fs.val = 42; | |
11925 | + fs.ps = pstr; | |
11926 | + | |
11927 | + f (f (23)); | |
11928 | + m1 (); | |
11929 | + m2 (); | |
11930 | + | |
11931 | + m4 (&fs, 0); | |
11932 | + m4 (&fs, 1); | |
11933 | + | |
11934 | + return 0; /* last break here */ | |
6ed6bacf | 11935 | +} |
f412e1b4 PS |
11936 | diff --git a/gdb/testsuite/gdb.base/stap-probe.exp b/gdb/testsuite/gdb.base/stap-probe.exp |
11937 | new file mode 100644 | |
11938 | index 0000000..468efb9 | |
11939 | --- /dev/null | |
11940 | +++ b/gdb/testsuite/gdb.base/stap-probe.exp | |
11941 | @@ -0,0 +1,187 @@ | |
6ed6bacf AM |
11942 | +# Copyright (C) 2011 Free Software Foundation, Inc. |
11943 | + | |
11944 | +# This program is free software; you can redistribute it and/or modify | |
11945 | +# it under the terms of the GNU General Public License as published by | |
11946 | +# the Free Software Foundation; either version 3 of the License, or | |
11947 | +# (at your option) any later version. | |
11948 | +# | |
11949 | +# This program is distributed in the hope that it will be useful, | |
11950 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11951 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11952 | +# GNU General Public License for more details. | |
11953 | +# | |
11954 | +# You should have received a copy of the GNU General Public License | |
11955 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
11956 | + | |
11957 | +set testfile stap-probe | |
11958 | + | |
11959 | +# Run the tests. We run the tests two different ways: once with a | |
11960 | +# plain probe, and once with a probe that has an associated semaphore. | |
11961 | +# This returns -1 on failure to compile or start, 0 otherwise. | |
11962 | +proc stap_test {{arg ""}} { | |
11963 | + global testfile hex | |
11964 | + | |
11965 | + if {$arg != ""} { | |
11966 | + set arg "additional_flags=$arg" | |
f412e1b4 | 11967 | + set addendum ", with semaphore, not optimized" |
6ed6bacf | 11968 | + } else { |
f412e1b4 | 11969 | + set addendum ", no semaphore, not optimized" |
6ed6bacf AM |
11970 | + } |
11971 | + | |
11972 | + if {[prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c \ | |
11973 | + [concat $arg debug]]} { | |
11974 | + return -1 | |
11975 | + } | |
11976 | + | |
11977 | + if ![runto_main] { | |
11978 | + return -1 | |
11979 | + } | |
11980 | + | |
11981 | + gdb_test "print \$_probe_argc" "No SystemTap probe at PC $hex" \ | |
11982 | + "check argument not at probe point$addendum" | |
11983 | + | |
11984 | + gdb_test "info probes" \ | |
11985 | + "teste *user *$hex .*" \ | |
11986 | + "info probes$addendum" | |
11987 | + | |
f412e1b4 PS |
11988 | + if {[runto "-p teste:user"]} { |
11989 | + pass "run to -p teste:user$addendum" | |
11990 | + } else { | |
11991 | + fail "run to -p teste:user$addendum" | |
11992 | + } | |
11993 | + | |
11994 | + # Test probe arguments. | |
11995 | + gdb_test "print \$_probe_argc" " = 1" \ | |
11996 | + "print \$_probe_argc for probe user$addendum" | |
11997 | + gdb_test "print \$_probe_arg0 == x" " = 1" \ | |
11998 | + "check \$_probe_arg0 for probe user$addendum" | |
11999 | + gdb_test "print \$_probe_arg1" \ | |
12000 | + "Invalid probe argument 1 -- probe has 1 arguments available" \ | |
12001 | + "check \$_probe_arg1 for probe user$addendum" | |
12002 | + | |
12003 | + # Set a breakpoint with multiple probe locations. | |
12004 | + gdb_test "break -p teste:two" \ | |
12005 | + "Breakpoint \[0-9\]+ at $hex.*2 locations.*" \ | |
12006 | + "set multi-location probe breakpoint (probe two)$addendum" | |
12007 | + | |
12008 | + # Reinit GDB, set a breakpoint on probe m4. | |
12009 | + delete_breakpoints | |
12010 | + rerun_to_main | |
12011 | + if {[runto "-p teste:m4"]} { | |
12012 | + pass "run to -p teste:m4$addendum" | |
12013 | + } else { | |
12014 | + fail "run to -p teste:m4$addendum" | |
12015 | + } | |
12016 | + | |
12017 | + # Testing probe arguments. | |
12018 | + gdb_test "print \$_probe_argc" " = 3" \ | |
12019 | + "print \$_probe_argc for probe m4$addendum" | |
12020 | + gdb_test "print \$_probe_arg0" " = 42" \ | |
12021 | + "check \$_probe_arg0 for probe m4$addendum" | |
12022 | + gdb_test "print (const char *) \$_probe_arg1" \ | |
12023 | + " = $hex .This is a test message.*" \ | |
12024 | + "check \$_probe_arg1 for probe m4$addendum" | |
12025 | + gdb_test "print \$_probe_arg2 == v" " = 1" \ | |
12026 | + "check \$_probe_arg2 for probe m4$addendum" | |
12027 | + | |
12028 | + # Reinit GDB, set a breakpoint on probe ps. | |
12029 | + delete_breakpoints | |
12030 | + rerun_to_main | |
12031 | + if {[runto "-p teste:ps"]} { | |
12032 | + pass "run to -p teste:m4$addendum" | |
12033 | + } else { | |
12034 | + fail "run to -p teste:m4$addendum" | |
12035 | + } | |
12036 | + | |
12037 | + gdb_test "print \$_probe_argc" " = 3" \ | |
12038 | + "print \$_probe_argc for probe ps$addendum" | |
12039 | + gdb_test "print (const char *) \$_probe_arg1" \ | |
12040 | + " = $hex .This is another test message.*" \ | |
12041 | + "print \$_probe_arg1 for probe ps$addendum" | |
12042 | + | |
12043 | + return 0 | |
12044 | +} | |
12045 | + | |
12046 | +proc stap_test_no_debuginfo {{ arg "" }} { | |
12047 | + global testfile hex | |
12048 | + | |
12049 | + if {$arg != ""} { | |
12050 | + set arg "additional_flags=$arg" | |
12051 | + set addendum ", with semaphore, optimized" | |
12052 | + } else { | |
12053 | + set addendum ", no semaphore, optimized" | |
12054 | + } | |
12055 | + | |
12056 | + if {[prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c \ | |
12057 | + {$arg nodebug optimize=-O2}]} { | |
12058 | + return -1 | |
12059 | + } | |
12060 | + | |
12061 | + if {[runto "-p teste:user"]} { | |
12062 | + pass "run to -p teste:user$addendum" | |
6ed6bacf | 12063 | + } else { |
f412e1b4 | 12064 | + fail "run to -p teste:user$addendum" |
6ed6bacf AM |
12065 | + } |
12066 | + | |
12067 | + # Test probe arguments. | |
f412e1b4 PS |
12068 | + gdb_test "print \$_probe_argc" " = 1" \ |
12069 | + "print \$_probe_argc for probe user$addendum" | |
12070 | + gdb_test "print \$_probe_arg0 == 23" " = 1" \ | |
12071 | + "check \$_probe_arg0 for probe user$addendum" | |
6ed6bacf AM |
12072 | + gdb_test "print \$_probe_arg1" \ |
12073 | + "Invalid probe argument 1 -- probe has 1 arguments available" \ | |
f412e1b4 | 12074 | + "check \$_probe_arg1 for probe user$addendum" |
6ed6bacf AM |
12075 | + |
12076 | + # Set a breakpoint with multiple probe locations. | |
f412e1b4 PS |
12077 | + # In this scenario, we may expect more than 2 locations because of |
12078 | + # the optimizations (inlining, loop unrolling, etc). | |
12079 | + gdb_test "break -p teste:two" \ | |
12080 | + "Breakpoint .* at $hex.*\[0-9\]+ locations.*" \ | |
12081 | + "set multi-location probe breakpoint (probe two)$addendum" | |
12082 | + | |
12083 | + # Reinit GDB, set a breakpoint on probe m4. | |
12084 | + delete_breakpoints | |
12085 | + rerun_to_main | |
12086 | + if {[runto "-p teste:m4"]} { | |
12087 | + pass "run to -p teste:m4$addendum" | |
12088 | + } else { | |
12089 | + fail "run to -p teste:m4$addendum" | |
12090 | + } | |
12091 | + | |
12092 | + # Testing probe arguments. | |
12093 | + gdb_test "print \$_probe_argc" " = 3" \ | |
12094 | + "print \$_probe_argc for probe m4$addendum" | |
12095 | + gdb_test "print \$_probe_arg0" " = 42" \ | |
12096 | + "check \$_probe_arg0 for probe m4$addendum" | |
12097 | + gdb_test "print (const char *) \$_probe_arg1" \ | |
12098 | + " = $hex .This is a test message.*" \ | |
12099 | + "check \$_probe_arg1 for probe m4$addendum" | |
12100 | + gdb_test "print \$_probe_arg2 == 0" " = 1" \ | |
12101 | + "check \$_probe_arg2 for probe m4$addendum" | |
12102 | + | |
12103 | + # Reinit GDB, set a breakpoint on probe ps. | |
12104 | + delete_breakpoints | |
12105 | + rerun_to_main | |
12106 | + if {[runto "-p teste:ps"]} { | |
12107 | + pass "run to -p teste:m4$addendum" | |
12108 | + } else { | |
12109 | + fail "run to -p teste:m4$addendum" | |
12110 | + } | |
12111 | + | |
12112 | + gdb_test "print \$_probe_argc" " = 3" \ | |
12113 | + "print \$_probe_argc for probe ps$addendum" | |
12114 | + gdb_test "print (const char *) \$_probe_arg1" \ | |
12115 | + " = $hex .This is another test message.*" \ | |
12116 | + "print \$_probe_arg1 for probe ps$addendum" | |
6ed6bacf AM |
12117 | + |
12118 | + return 0 | |
12119 | +} | |
12120 | + | |
12121 | +if {[stap_test] == -1} { | |
12122 | + untested stap-probe.exp | |
12123 | + return -1 | |
12124 | +} | |
f412e1b4 | 12125 | + |
6ed6bacf | 12126 | +stap_test "-DUSE_PROBES" |
f412e1b4 PS |
12127 | +stap_test_no_debuginfo |
12128 | +stap_test_no_debuginfo "-DUSE_PROBES" | |
12129 | diff --git a/gdb/testsuite/gdb.base/vla-frame.c b/gdb/testsuite/gdb.base/vla-frame.c | |
12130 | new file mode 100644 | |
12131 | index 0000000..5750f68 | |
12132 | --- /dev/null | |
12133 | +++ b/gdb/testsuite/gdb.base/vla-frame.c | |
12134 | @@ -0,0 +1,31 @@ | |
12135 | +/* This testcase is part of GDB, the GNU debugger. | |
12136 | + | |
12137 | + Copyright 2011 Free Software Foundation, Inc. | |
12138 | + | |
12139 | + This program is free software; you can redistribute it and/or modify | |
12140 | + it under the terms of the GNU General Public License as published by | |
12141 | + the Free Software Foundation; either version 3 of the License, or | |
12142 | + (at your option) any later version. | |
12143 | + | |
12144 | + This program is distributed in the hope that it will be useful, | |
12145 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12146 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12147 | + GNU General Public License for more details. | |
12148 | + | |
12149 | + You should have received a copy of the GNU General Public License | |
12150 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
12151 | + | |
12152 | +#include <string.h> | |
12153 | + | |
12154 | +int | |
12155 | +main (int argc, char **argv) | |
12156 | +{ | |
12157 | + char s[2 + argc]; | |
12158 | + void (*f) (char *) = 0; | |
12159 | + | |
12160 | + memset (s, 0, sizeof (s)); | |
12161 | + s[0] = 'X'; | |
12162 | + | |
12163 | + f (s); | |
12164 | + return 0; | |
12165 | +} | |
12166 | diff --git a/gdb/testsuite/gdb.base/vla-frame.exp b/gdb/testsuite/gdb.base/vla-frame.exp | |
12167 | new file mode 100644 | |
12168 | index 0000000..47736c7 | |
12169 | --- /dev/null | |
12170 | +++ b/gdb/testsuite/gdb.base/vla-frame.exp | |
12171 | @@ -0,0 +1,38 @@ | |
12172 | +# Copyright 2011 Free Software Foundation, Inc. | |
12173 | +# | |
12174 | +# This program is free software; you can redistribute it and/or modify | |
12175 | +# it under the terms of the GNU General Public License as published by | |
12176 | +# the Free Software Foundation; either version 3 of the License, or | |
12177 | +# (at your option) any later version. | |
12178 | +# | |
12179 | +# This program is distributed in the hope that it will be useful, | |
12180 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12181 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12182 | +# GNU General Public License for more details. | |
12183 | +# | |
12184 | +# You should have received a copy of the GNU General Public License | |
12185 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
12186 | + | |
12187 | +set testfile vla-frame | |
12188 | +set executable ${testfile} | |
12189 | + | |
12190 | +if { [prepare_for_testing ${testfile}.exp ${executable}] } { | |
12191 | + return -1 | |
12192 | +} | |
12193 | + | |
12194 | +if ![runto_main] { | |
12195 | + return -1 | |
12196 | +} | |
12197 | + | |
12198 | +set test "continue" | |
12199 | +gdb_test_multiple $test $test { | |
12200 | + -re "Continuing\\.\r\n\r\nProgram received signal SIGSEGV, Segmentation fault\\.\r\n0x0+ in \\?\\? \\(\\)\r\n$gdb_prompt $" { | |
12201 | + pass $test | |
12202 | + } | |
12203 | + -re "\r\n$gdb_prompt $" { | |
12204 | + untested ${testfile}.exp | |
12205 | + return | |
12206 | + } | |
12207 | +} | |
12208 | + | |
12209 | +gdb_test "bt full" "\r\n +s = \"X\\\\000\"\r\n.*" | |
12210 | diff --git a/gdb/testsuite/gdb.base/vla-overflow.c b/gdb/testsuite/gdb.base/vla-overflow.c | |
12211 | new file mode 100644 | |
12212 | index 0000000..c5d5ee0 | |
12213 | --- /dev/null | |
12214 | +++ b/gdb/testsuite/gdb.base/vla-overflow.c | |
51a5ef0f PS |
12215 | @@ -0,0 +1,30 @@ |
12216 | +/* This testcase is part of GDB, the GNU debugger. | |
12217 | + | |
12218 | + Copyright 2008 Free Software Foundation, Inc. | |
12219 | + | |
12220 | + This program is free software; you can redistribute it and/or modify | |
12221 | + it under the terms of the GNU General Public License as published by | |
12222 | + the Free Software Foundation; either version 3 of the License, or | |
12223 | + (at your option) any later version. | |
12224 | + | |
12225 | + This program is distributed in the hope that it will be useful, | |
12226 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12227 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12228 | + GNU General Public License for more details. | |
12229 | + | |
12230 | + You should have received a copy of the GNU General Public License | |
12231 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
12232 | + | |
12233 | +#include <stdlib.h> | |
12234 | + | |
12235 | +int | |
12236 | +main (int argc, char **argv) | |
12237 | +{ | |
12238 | + int array[argc]; | |
12239 | + | |
12240 | + array[0] = array[0]; | |
12241 | + | |
12242 | + abort (); | |
7566401a | 12243 | + |
51a5ef0f PS |
12244 | + return 0; |
12245 | +} | |
f412e1b4 PS |
12246 | diff --git a/gdb/testsuite/gdb.base/vla-overflow.exp b/gdb/testsuite/gdb.base/vla-overflow.exp |
12247 | new file mode 100644 | |
12248 | index 0000000..24a608f | |
12249 | --- /dev/null | |
12250 | +++ b/gdb/testsuite/gdb.base/vla-overflow.exp | |
51a5ef0f PS |
12251 | @@ -0,0 +1,109 @@ |
12252 | +# Copyright 2008 Free Software Foundation, Inc. | |
3a58abaf AM |
12253 | + |
12254 | +# This program is free software; you can redistribute it and/or modify | |
12255 | +# it under the terms of the GNU General Public License as published by | |
51a5ef0f | 12256 | +# the Free Software Foundation; either version 3 of the License, or |
3a58abaf | 12257 | +# (at your option) any later version. |
51a5ef0f | 12258 | +# |
3a58abaf AM |
12259 | +# This program is distributed in the hope that it will be useful, |
12260 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12261 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12262 | +# GNU General Public License for more details. | |
51a5ef0f | 12263 | +# |
3a58abaf | 12264 | +# You should have received a copy of the GNU General Public License |
51a5ef0f PS |
12265 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
12266 | + | |
12267 | +# We could crash in: | |
12268 | +# #0 block_linkage_function (bl=0x0) at ../../gdb/block.c:69 | |
12269 | +# #1 in dwarf_block_get_frame_base (...) at ../../gdb/dwarf2block.c:97 | |
12270 | +# 97 framefunc = block_linkage_function (get_frame_block (frame, NULL)); | |
12271 | +# #2 in execute_stack_op (...) at ../../gdb/dwarf2expr.c:496 | |
12272 | +# #3 in dwarf_block_exec_core () at ../../gdb/dwarf2block.c:156 | |
12273 | +# #4 dwarf_block_exec (...) at ../../gdb/dwarf2block.c:206 | |
12274 | +# #5 in range_type_count_bound_internal (...) at ../../gdb/gdbtypes.c:1430 | |
12275 | +# #6 in create_array_type (...) at ../../gdb/gdbtypes.c:840 | |
12276 | +# ... | |
12277 | +# #21 in psymtab_to_symtab (...) at ../../gdb/symfile.c:292 | |
12278 | +# ... | |
12279 | +# #29 in backtrace_command_1 () at ../../gdb/stack.c:1273 | |
12280 | + | |
12281 | +set testfile vla-overflow | |
12282 | +set shfile ${objdir}/${subdir}/${testfile}-gdb.sh | |
12283 | +set srcfile ${testfile}.c | |
12284 | +set binfile ${objdir}/${subdir}/${testfile} | |
12285 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
12286 | + untested "Couldn't compile test program" | |
12287 | + return -1 | |
12288 | +} | |
12289 | + | |
12290 | +set f [open "|getconf PAGESIZE" "r"] | |
12291 | +gets $f pagesize | |
12292 | +close $f | |
12293 | + | |
12294 | +gdb_exit | |
12295 | +gdb_start | |
12296 | +gdb_reinitialize_dir $srcdir/$subdir | |
12297 | +gdb_load ${binfile} | |
12298 | + | |
12299 | +set pid_of_gdb [exp_pid -i [board_info host fileid]] | |
12300 | + | |
12301 | +if { [runto_main] < 0 } { | |
12302 | + untested vla-overflow | |
12303 | + return -1 | |
12304 | +} | |
12305 | + | |
12306 | +# Get the GDB memory size when we stay at main. | |
12307 | + | |
12308 | +proc memory_v_pages_get {} { | |
12309 | + global pid_of_gdb pagesize | |
12310 | + set fd [open "/proc/$pid_of_gdb/statm"] | |
12311 | + gets $fd line | |
12312 | + close $fd | |
12313 | + # number of pages of virtual memory | |
12314 | + scan $line "%d" drs | |
12315 | + return $drs | |
12316 | +} | |
12317 | + | |
12318 | +set pages_found [memory_v_pages_get] | |
12319 | + | |
12320 | +# s390x with glibc-debuginfo.s390x installed used approx. 16MB. | |
12321 | +set mb_reserve 40 | |
12322 | +verbose -log "pages_found = $pages_found, mb_reserve = $mb_reserve" | |
12323 | +set kb_found [expr $pages_found * $pagesize / 1024] | |
12324 | +set kb_permit [expr $kb_found + 1 * 1024 + $mb_reserve * 1024] | |
12325 | +verbose -log "kb_found = $kb_found, kb_permit = $kb_permit" | |
12326 | + | |
12327 | +# Create the ulimit wrapper. | |
12328 | +set f [open $shfile "w"] | |
12329 | +puts $f "#! /bin/sh" | |
12330 | +puts $f "ulimit -v $kb_permit" | |
12331 | +puts $f "exec $GDB \"\$@\"" | |
12332 | +close $f | |
12333 | +remote_exec host "chmod +x $shfile" | |
12334 | + | |
12335 | +gdb_exit | |
12336 | +set GDBold $GDB | |
12337 | +set GDB "$shfile" | |
12338 | +gdb_start | |
12339 | +set GDB $GDBold | |
12340 | + | |
12341 | +gdb_reinitialize_dir $srcdir/$subdir | |
12342 | +gdb_load ${binfile} | |
12343 | + | |
12344 | +set pid_of_gdb [exp_pid -i [board_info host fileid]] | |
12345 | + | |
12346 | +# Check the size again after the second run. | |
12347 | +# We must not stop in main as it would cache `array' and never crash later. | |
3a58abaf | 12348 | + |
51a5ef0f | 12349 | +gdb_run_cmd |
3a58abaf | 12350 | + |
51a5ef0f | 12351 | +verbose -log "kb_found before abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" |
3a58abaf | 12352 | + |
51a5ef0f | 12353 | +gdb_test "" "Program received signal SIGABRT, Aborted..*" "Enter abort()" |
3a58abaf | 12354 | + |
51a5ef0f | 12355 | +verbose -log "kb_found in abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" |
3a58abaf | 12356 | + |
51a5ef0f PS |
12357 | +# `abort' can get expressed as `*__GI_abort'. |
12358 | +gdb_test "bt" "in \[^ \]*abort \\(.* in main \\(.*" "Backtrace after abort()" | |
3a58abaf | 12359 | + |
51a5ef0f | 12360 | +verbose -log "kb_found in bt after abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" |
f412e1b4 PS |
12361 | diff --git a/gdb/testsuite/gdb.base/vla.c b/gdb/testsuite/gdb.base/vla.c |
12362 | new file mode 100644 | |
12363 | index 0000000..e1f3ed1 | |
12364 | --- /dev/null | |
12365 | +++ b/gdb/testsuite/gdb.base/vla.c | |
51a5ef0f PS |
12366 | @@ -0,0 +1,55 @@ |
12367 | +/* This testcase is part of GDB, the GNU debugger. | |
3a58abaf | 12368 | + |
51a5ef0f | 12369 | + Copyright 2008 Free Software Foundation, Inc. |
3a58abaf | 12370 | + |
51a5ef0f PS |
12371 | + This program is free software; you can redistribute it and/or modify |
12372 | + it under the terms of the GNU General Public License as published by | |
12373 | + the Free Software Foundation; either version 3 of the License, or | |
12374 | + (at your option) any later version. | |
3a58abaf | 12375 | + |
51a5ef0f PS |
12376 | + This program is distributed in the hope that it will be useful, |
12377 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12378 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12379 | + GNU General Public License for more details. | |
3a58abaf | 12380 | + |
51a5ef0f PS |
12381 | + You should have received a copy of the GNU General Public License |
12382 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
3a58abaf | 12383 | + |
51a5ef0f | 12384 | +#include <string.h> |
3a58abaf | 12385 | + |
51a5ef0f PS |
12386 | +void |
12387 | +marker (void) | |
12388 | +{ | |
3a58abaf AM |
12389 | +} |
12390 | + | |
51a5ef0f PS |
12391 | +void |
12392 | +bar (char *a, char *b, char *c, int size) | |
12393 | +{ | |
12394 | + memset (a, '1', size); | |
12395 | + memset (b, '2', size); | |
12396 | + memset (c, '3', 48); | |
3a58abaf AM |
12397 | +} |
12398 | + | |
51a5ef0f PS |
12399 | +void |
12400 | +foo (int size) | |
12401 | +{ | |
12402 | + char temp1[size]; | |
12403 | + char temp3[48]; | |
3a58abaf | 12404 | + |
6ed6bacf AM |
12405 | + temp1[size - 1] = '\0'; |
12406 | + { | |
12407 | + char temp2[size]; | |
51a5ef0f | 12408 | + |
6ed6bacf AM |
12409 | + bar (temp1, temp2, temp3, size); |
12410 | + | |
12411 | + marker (); /* break-here */ | |
12412 | + } | |
3a58abaf | 12413 | +} |
51a5ef0f | 12414 | + |
6ed6bacf AM |
12415 | +int |
12416 | +main (void) | |
12417 | +{ | |
12418 | + foo (26); | |
12419 | + foo (78); | |
12420 | + return 0; | |
12421 | +} | |
f412e1b4 PS |
12422 | diff --git a/gdb/testsuite/gdb.base/vla.exp b/gdb/testsuite/gdb.base/vla.exp |
12423 | new file mode 100644 | |
12424 | index 0000000..5da7378 | |
12425 | --- /dev/null | |
12426 | +++ b/gdb/testsuite/gdb.base/vla.exp | |
6ed6bacf AM |
12427 | @@ -0,0 +1,62 @@ |
12428 | +# Copyright 2008 Free Software Foundation, Inc. | |
51a5ef0f | 12429 | + |
3a58abaf AM |
12430 | +# This program is free software; you can redistribute it and/or modify |
12431 | +# it under the terms of the GNU General Public License as published by | |
51a5ef0f | 12432 | +# the Free Software Foundation; either version 3 of the License, or |
3a58abaf AM |
12433 | +# (at your option) any later version. |
12434 | +# | |
12435 | +# This program is distributed in the hope that it will be useful, | |
12436 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12437 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12438 | +# GNU General Public License for more details. | |
12439 | +# | |
12440 | +# You should have received a copy of the GNU General Public License | |
51a5ef0f | 12441 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
3a58abaf | 12442 | + |
6ed6bacf AM |
12443 | +set testfile vla |
12444 | +set srcfile ${testfile}.c | |
12445 | +set binfile ${objdir}/${subdir}/${testfile} | |
12446 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
12447 | + untested "Couldn't compile test program" | |
51a5ef0f PS |
12448 | + return -1 |
12449 | +} | |
3a58abaf | 12450 | + |
51a5ef0f PS |
12451 | +gdb_exit |
12452 | +gdb_start | |
12453 | +gdb_reinitialize_dir $srcdir/$subdir | |
12454 | +gdb_load ${binfile} | |
3a58abaf | 12455 | + |
6ed6bacf AM |
12456 | +if ![runto_main] { |
12457 | + untested vla | |
7566401a | 12458 | + return -1 |
3a58abaf AM |
12459 | +} |
12460 | + | |
6ed6bacf | 12461 | +gdb_breakpoint [gdb_get_line_number "break-here"] |
51a5ef0f | 12462 | + |
6ed6bacf | 12463 | +gdb_continue_to_breakpoint "break-here" |
51a5ef0f | 12464 | + |
6ed6bacf AM |
12465 | +gdb_test "whatis temp1" "type = char \\\[variable\\\]" "first: whatis temp1" |
12466 | +gdb_test "whatis temp2" "type = char \\\[variable\\\]" "first: whatis temp2" | |
12467 | +gdb_test "whatis temp3" "type = char \\\[48\\\]" "first: whatis temp3" | |
3a58abaf | 12468 | + |
6ed6bacf AM |
12469 | +gdb_test "ptype temp1" "type = char \\\[26\\\]" "first: ptype temp1" |
12470 | +gdb_test "ptype temp2" "type = char \\\[26\\\]" "first: ptype temp2" | |
12471 | +gdb_test "ptype temp3" "type = char \\\[48\\\]" "first: ptype temp3" | |
3a58abaf | 12472 | + |
6ed6bacf AM |
12473 | +gdb_test "p temp1" " = '1' <repeats 26 times>" "first: print temp1" |
12474 | +gdb_test "p temp2" " = '2' <repeats 26 times>" "first: print temp2" | |
12475 | +gdb_test "p temp3" " = '3' <repeats 48 times>" "first: print temp3" | |
3a58abaf | 12476 | + |
6ed6bacf | 12477 | +gdb_continue_to_breakpoint "break-here" |
7566401a | 12478 | + |
6ed6bacf AM |
12479 | +gdb_test "whatis temp1" "type = char \\\[variable\\\]" "second: whatis temp1" |
12480 | +gdb_test "whatis temp2" "type = char \\\[variable\\\]" "second: whatis temp2" | |
12481 | +gdb_test "whatis temp3" "type = char \\\[48\\\]" "second: whatis temp3" | |
7566401a | 12482 | + |
6ed6bacf AM |
12483 | +gdb_test "ptype temp1" "type = char \\\[78\\\]" "second: ptype temp1" |
12484 | +gdb_test "ptype temp2" "type = char \\\[78\\\]" "second: ptype temp2" | |
12485 | +gdb_test "ptype temp3" "type = char \\\[48\\\]" "second: ptype temp3" | |
51a5ef0f | 12486 | + |
6ed6bacf AM |
12487 | +gdb_test "p temp1" " = '1' <repeats 78 times>" "second: print temp1" |
12488 | +gdb_test "p temp2" " = '2' <repeats 78 times>" "second: print temp2" | |
12489 | +gdb_test "p temp3" " = '3' <repeats 48 times>" "second: print temp3" | |
f412e1b4 PS |
12490 | diff --git a/gdb/testsuite/gdb.cp/nextoverthrow.exp b/gdb/testsuite/gdb.cp/nextoverthrow.exp |
12491 | index 7d4a0c5..2dafcab 100644 | |
12492 | --- a/gdb/testsuite/gdb.cp/nextoverthrow.exp | |
12493 | +++ b/gdb/testsuite/gdb.cp/nextoverthrow.exp | |
12494 | @@ -54,6 +54,17 @@ gdb_test_multiple "print _Unwind_DebugHook" "check for unwinder hook" { | |
6ed6bacf AM |
12495 | } |
12496 | } | |
12497 | if {!$ok} { | |
12498 | + gdb_test_multiple "info probe" "check for stap probe in unwinder" { | |
12499 | + -re ".*libgcc.*unwind.*\r\n$gdb_prompt $" { | |
12500 | + pass "check for stap probe in unwinder" | |
12501 | + set ok 1 | |
12502 | + } | |
12503 | + -re "\r\n$gdb_prompt $" { | |
12504 | + } | |
12505 | + } | |
12506 | +} | |
51a5ef0f | 12507 | + |
6ed6bacf AM |
12508 | +if {!$ok} { |
12509 | unsupported "nextoverthrow.exp could not find _Unwind_DebugHook" | |
12510 | return -1 | |
12511 | } | |
f412e1b4 PS |
12512 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S |
12513 | new file mode 100644 | |
12514 | index 0000000..aac3baa | |
12515 | --- /dev/null | |
12516 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S | |
6ed6bacf | 12517 | @@ -0,0 +1,246 @@ |
51a5ef0f | 12518 | +/* This testcase is part of GDB, the GNU debugger. |
7566401a | 12519 | + |
51a5ef0f | 12520 | + Copyright 2010 Free Software Foundation, Inc. |
7566401a | 12521 | + |
51a5ef0f PS |
12522 | + This program is free software; you can redistribute it and/or modify |
12523 | + it under the terms of the GNU General Public License as published by | |
12524 | + the Free Software Foundation; either version 3 of the License, or | |
12525 | + (at your option) any later version. | |
7566401a | 12526 | + |
51a5ef0f PS |
12527 | + This program is distributed in the hope that it will be useful, |
12528 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12529 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12530 | + GNU General Public License for more details. | |
7566401a | 12531 | + |
51a5ef0f PS |
12532 | + You should have received a copy of the GNU General Public License |
12533 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
7566401a | 12534 | + |
51a5ef0f | 12535 | +/* Debug information */ |
7566401a | 12536 | + |
51a5ef0f PS |
12537 | +/* We will `break *main' at the very first instruction. */ |
12538 | +#define main_length 1 | |
7566401a | 12539 | + |
51a5ef0f PS |
12540 | + .section .data |
12541 | +vardata: | |
12542 | + /* See DW_OP_lit3 + 1 (0-based). */ | |
12543 | + .string "seennotseen" | |
7566401a | 12544 | + |
51a5ef0f PS |
12545 | + .section .debug_info |
12546 | +.Lcu1_begin: | |
12547 | + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ | |
12548 | +.Lcu1_start: | |
12549 | + .2byte 2 /* DWARF version number */ | |
12550 | + .4byte .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ | |
12551 | + .byte 4 /* Pointer Size (in bytes) */ | |
3a58abaf | 12552 | + |
51a5ef0f PS |
12553 | + /* CU die */ |
12554 | + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ | |
12555 | + .4byte .Lproducer /* DW_AT_producer */ | |
12556 | + /* Use C++ to exploit a bug in parsing DW_AT_name "". */ | |
12557 | + .byte 4 /* DW_AT_language (C++) - */ | |
12558 | + .4byte main /* DW_AT_low_pc */ | |
12559 | + .byte main_length /* DW_AT_high_pc */ | |
12560 | + | |
12561 | +.Larray_type: | |
12562 | + .uleb128 2 /* Abbrev: DW_TAG_array_type */ | |
12563 | + .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */ | |
12564 | + | |
12565 | + .uleb128 3 /* Abbrev: DW_TAG_subrange_type */ | |
12566 | + .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */ | |
12567 | + .byte 0 /* DW_AT_lower_bound */ | |
12568 | + .4byte .Llen_var-.Lcu1_begin /* DW_AT_upper_bound */ | |
12569 | + .byte 0 /* End of children of die */ | |
12570 | + | |
12571 | + /* DW_AT_upper_bound is referencing an optimized-out variable. */ | |
12572 | +.Larrayb_type: | |
12573 | + .uleb128 2 /* Abbrev: DW_TAG_array_type */ | |
12574 | + .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */ | |
12575 | + | |
12576 | + .uleb128 3 /* Abbrev: DW_TAG_subrange_type */ | |
12577 | + .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */ | |
12578 | + .byte 0 /* DW_AT_lower_bound */ | |
12579 | + .4byte .Llenb_var-.Lcu1_begin /* DW_AT_upper_bound */ | |
12580 | + .byte 0 /* End of children of die */ | |
12581 | + | |
6ed6bacf AM |
12582 | + /* DW_AT_upper_bound is referencing register. */ |
12583 | +.Larrayreg_type: | |
12584 | + .uleb128 2 /* Abbrev: DW_TAG_array_type */ | |
12585 | + .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */ | |
12586 | + | |
12587 | + .uleb128 8 /* Abbrev: DW_TAG_subrange_type with block */ | |
12588 | + .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */ | |
12589 | + .byte 0 /* DW_AT_lower_bound */ | |
12590 | + .byte 2f - 1f /* DW_AT_upper_bound */ | |
12591 | +1: .byte 0x50 /* DW_OP_reg0 */ | |
12592 | +2: | |
12593 | + .byte 0 /* End of children of die */ | |
12594 | + | |
51a5ef0f PS |
12595 | +.Luint_type: |
12596 | + .uleb128 4 /* Abbrev: DW_TAG_base_type */ | |
12597 | + .4byte .Luint_str /* DW_AT_name */ | |
12598 | + .byte 4 /* DW_AT_byte_size */ | |
12599 | + .byte 7 /* DW_AT_encoding */ | |
12600 | + | |
12601 | +.Lchar_type: | |
12602 | + .uleb128 4 /* Abbrev: DW_TAG_base_type */ | |
12603 | + .4byte .Lchar_str /* DW_AT_name */ | |
12604 | + .byte 1 /* DW_AT_byte_size */ | |
12605 | + .byte 6 /* DW_AT_encoding */ | |
12606 | + | |
12607 | +.Llen_var: | |
12608 | + .uleb128 5 /* Abbrev: DW_TAG_variable artificial */ | |
12609 | + .byte 1 /* DW_AT_artificial */ | |
12610 | + .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */ | |
12611 | + .4byte .Llen_loclist-.Lloclist /* DW_AT_location */ | |
12612 | + | |
12613 | + /* optimized-out variable for b_string. */ | |
12614 | +.Llenb_var: | |
12615 | + .uleb128 7 /* Abbrev: DW_TAG_variable artificial no DW_AT_location */ | |
12616 | + .byte 1 /* DW_AT_artificial */ | |
12617 | + .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */ | |
12618 | + | |
12619 | + .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */ | |
12620 | + .string "a_string" /* DW_AT_name */ | |
12621 | + .4byte .Larray_type-.Lcu1_begin /* DW_AT_type */ | |
12622 | + .byte 2f - 1f /* DW_AT_location */ | |
12623 | +1: .byte 3 /* DW_OP_addr */ | |
12624 | + .4byte vardata /* <addr> */ | |
12625 | +2: | |
12626 | + | |
12627 | + /* DW_AT_upper_bound is referencing an optimized-out variable. */ | |
12628 | + .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */ | |
12629 | + .string "b_string" /* DW_AT_name */ | |
12630 | + .4byte .Larrayb_type-.Lcu1_begin /* DW_AT_type */ | |
12631 | + .byte 2f - 1f /* DW_AT_location */ | |
12632 | +1: .byte 3 /* DW_OP_addr */ | |
12633 | + .4byte vardata /* <addr> */ | |
12634 | +2: | |
3a58abaf | 12635 | + |
6ed6bacf AM |
12636 | + /* DW_AT_upper_bound is referencing register. */ |
12637 | + .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */ | |
12638 | + .string "reg_string" /* DW_AT_name */ | |
12639 | + .4byte .Larrayreg_type-.Lcu1_begin /* DW_AT_type */ | |
12640 | + .byte 2f - 1f /* DW_AT_location */ | |
12641 | +1: .byte 3 /* DW_OP_addr */ | |
12642 | + .4byte vardata /* <addr> */ | |
12643 | +2: | |
12644 | + | |
51a5ef0f PS |
12645 | + .byte 0 /* End of children of CU */ |
12646 | +.Lcu1_end: | |
3a58abaf | 12647 | + |
51a5ef0f PS |
12648 | + .section .debug_loc |
12649 | +.Lloclist: | |
12650 | +.Llen_loclist: | |
12651 | + .4byte 0 # Location list begin address | |
12652 | + .4byte main_length # Location list end address | |
12653 | + .value 2f-1f # Location expression size | |
12654 | +1: .byte 0x33 # DW_OP_lit3 | |
12655 | + .byte 0x9f # DW_OP_stack_value | |
12656 | +2: | |
12657 | + .quad 0x0 # Location list terminator begin (*.LLST2) | |
12658 | + .quad 0x0 # Location list terminator end (*.LLST2) | |
3a58abaf | 12659 | + |
51a5ef0f PS |
12660 | + .section .debug_abbrev |
12661 | +.Ldebug_abbrev0: | |
12662 | + .uleb128 1 /* Abbrev code */ | |
12663 | + .uleb128 0x11 /* DW_TAG_compile_unit */ | |
12664 | + .byte 0x1 /* has_children */ | |
12665 | + .uleb128 0x25 /* DW_AT_producer */ | |
12666 | + .uleb128 0xe /* DW_FORM_strp */ | |
12667 | + .uleb128 0x13 /* DW_AT_language */ | |
12668 | + .uleb128 0xb /* DW_FORM_data1 */ | |
12669 | + .uleb128 0x11 /* DW_AT_low_pc */ | |
12670 | + .uleb128 0x1 /* DW_FORM_addr */ | |
12671 | + .uleb128 0x12 /* DW_AT_high_pc */ | |
12672 | + .uleb128 0xb /* DW_FORM_data1 */ | |
12673 | + .byte 0x0 /* Terminator */ | |
12674 | + .byte 0x0 /* Terminator */ | |
12675 | + | |
12676 | + .uleb128 2 /* Abbrev code */ | |
12677 | + .uleb128 0x1 /* TAG: DW_TAG_array_type */ | |
12678 | + .byte 0x1 /* DW_children_yes */ | |
12679 | + .uleb128 0x49 /* DW_AT_type */ | |
12680 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
12681 | + .byte 0x0 /* Terminator */ | |
12682 | + .byte 0x0 /* Terminator */ | |
12683 | + | |
12684 | + .uleb128 3 /* Abbrev code */ | |
12685 | + .uleb128 0x21 /* DW_TAG_subrange_type */ | |
12686 | + .byte 0x0 /* no children */ | |
12687 | + .uleb128 0x49 /* DW_AT_type */ | |
12688 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
12689 | + .uleb128 0x22 /* DW_AT_lower_bound */ | |
12690 | + .uleb128 0xb /* DW_FORM_data1 */ | |
12691 | + .uleb128 0x2f /* DW_AT_upper_bound */ | |
12692 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
12693 | + .byte 0x0 /* Terminator */ | |
12694 | + .byte 0x0 /* Terminator */ | |
12695 | + | |
12696 | + .uleb128 4 /* Abbrev code */ | |
12697 | + .uleb128 0x24 /* DW_TAG_base_type */ | |
12698 | + .byte 0x0 /* no_children */ | |
12699 | + .uleb128 0x3 /* DW_AT_name */ | |
12700 | + .uleb128 0xe /* DW_FORM_strp */ | |
12701 | + .uleb128 0xb /* DW_AT_byte_size */ | |
12702 | + .uleb128 0xb /* DW_FORM_data1 */ | |
12703 | + .uleb128 0x3e /* DW_AT_encoding */ | |
12704 | + .uleb128 0xb /* DW_FORM_data1 */ | |
12705 | + .byte 0x0 /* Terminator */ | |
12706 | + .byte 0x0 /* Terminator */ | |
12707 | + | |
12708 | + .uleb128 5 /* Abbrev code */ | |
12709 | + .uleb128 0x34 /* DW_TAG_variable */ | |
12710 | + .byte 0x0 /* no_children */ | |
12711 | + .uleb128 0x34 /* DW_AT_artificial */ | |
12712 | + .uleb128 0x0c /* DW_FORM_flag */ | |
12713 | + .uleb128 0x49 /* DW_AT_type */ | |
12714 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
12715 | + .uleb128 0x02 /* DW_AT_location */ | |
12716 | + .uleb128 0x06 /* DW_FORM_data4 */ | |
12717 | + .byte 0x0 /* Terminator */ | |
12718 | + .byte 0x0 /* Terminator */ | |
12719 | + | |
12720 | + .uleb128 6 /* Abbrev code */ | |
12721 | + .uleb128 0x34 /* DW_TAG_variable */ | |
12722 | + .byte 0x0 /* no_children */ | |
12723 | + .uleb128 0x3 /* DW_AT_name */ | |
12724 | + .uleb128 0x8 /* DW_FORM_string */ | |
12725 | + .uleb128 0x49 /* DW_AT_type */ | |
12726 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
12727 | + .uleb128 0x2 /* DW_AT_location */ | |
12728 | + .uleb128 0xa /* DW_FORM_block1 */ | |
12729 | + .byte 0x0 /* Terminator */ | |
12730 | + .byte 0x0 /* Terminator */ | |
12731 | + | |
12732 | + .uleb128 7 /* Abbrev code */ | |
12733 | + .uleb128 0x34 /* DW_TAG_variable */ | |
12734 | + .byte 0x0 /* no_children */ | |
12735 | + .uleb128 0x34 /* DW_AT_artificial */ | |
12736 | + .uleb128 0x0c /* DW_FORM_flag */ | |
12737 | + .uleb128 0x49 /* DW_AT_type */ | |
12738 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
12739 | + .byte 0x0 /* Terminator */ | |
12740 | + .byte 0x0 /* Terminator */ | |
12741 | + | |
6ed6bacf AM |
12742 | + .uleb128 8 /* Abbrev code */ |
12743 | + .uleb128 0x21 /* DW_TAG_subrange_type with block */ | |
12744 | + .byte 0x0 /* no children */ | |
12745 | + .uleb128 0x49 /* DW_AT_type */ | |
12746 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
12747 | + .uleb128 0x22 /* DW_AT_lower_bound */ | |
12748 | + .uleb128 0xb /* DW_FORM_data1 */ | |
12749 | + .uleb128 0x2f /* DW_AT_upper_bound */ | |
12750 | + .uleb128 0xa /* DW_FORM_block1 */ | |
12751 | + .byte 0x0 /* Terminator */ | |
12752 | + .byte 0x0 /* Terminator */ | |
12753 | + | |
51a5ef0f PS |
12754 | + .byte 0x0 /* Terminator */ |
12755 | + | |
12756 | +/* String table */ | |
12757 | + .section .debug_str | |
12758 | +.Lproducer: | |
12759 | + .string "GNU C 3.3.3" | |
12760 | +.Lchar_str: | |
12761 | + .string "char" | |
12762 | +.Luint_str: | |
12763 | + .string "unsigned int" | |
f412e1b4 PS |
12764 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp |
12765 | new file mode 100644 | |
12766 | index 0000000..815ed93 | |
12767 | --- /dev/null | |
12768 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp | |
6ed6bacf | 12769 | @@ -0,0 +1,54 @@ |
51a5ef0f | 12770 | +# Copyright 2010 Free Software Foundation, Inc. |
3a58abaf | 12771 | + |
7566401a ER |
12772 | +# This program is free software; you can redistribute it and/or modify |
12773 | +# it under the terms of the GNU General Public License as published by | |
12774 | +# the Free Software Foundation; either version 3 of the License, or | |
12775 | +# (at your option) any later version. | |
12776 | +# | |
12777 | +# This program is distributed in the hope that it will be useful, | |
12778 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12779 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12780 | +# GNU General Public License for more details. | |
12781 | +# | |
12782 | +# You should have received a copy of the GNU General Public License | |
12783 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 12784 | + |
51a5ef0f PS |
12785 | +# Test printing variable with dynamic bounds which reference a different |
12786 | +# (artificial in the GCC case) variable containing loclist as its location. | |
12787 | +# This testcase uses value (not address) of the referenced variable: | |
12788 | +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43762 | |
7566401a | 12789 | + |
51a5ef0f PS |
12790 | +# This test can only be run on targets which support DWARF-2 and use gas. |
12791 | +# For now pick a sampling of likely targets. | |
12792 | +if {![istarget *-*-linux*] | |
12793 | + && ![istarget *-*-gnu*] | |
12794 | + && ![istarget *-*-elf*] | |
12795 | + && ![istarget *-*-openbsd*] | |
12796 | + && ![istarget arm-*-eabi*] | |
12797 | + && ![istarget powerpc-*-eabi*]} { | |
12798 | + return 0 | |
7566401a ER |
12799 | +} |
12800 | + | |
51a5ef0f PS |
12801 | +set testfile dw2-bound-loclist |
12802 | +if { [prepare_for_testing ${testfile}.exp ${testfile} [list ${testfile}.S main.c] {}] } { | |
7566401a ER |
12803 | + return -1 |
12804 | +} | |
12805 | + | |
51a5ef0f | 12806 | +# Verify it behaves at least as an unbound array without inferior. |
7566401a | 12807 | + |
51a5ef0f PS |
12808 | +gdb_test "p a_string" { = 0x[0-9a-f]+ "seennotseen"} |
12809 | +gdb_test "ptype a_string" {type = char \[\]} | |
7566401a | 12810 | + |
51a5ef0f PS |
12811 | +# Not runto_main as dw2-bound-loclist.S handles only the first byte of main. |
12812 | +if ![runto "*main"] { | |
12813 | + return -1 | |
7566401a ER |
12814 | +} |
12815 | + | |
51a5ef0f PS |
12816 | +gdb_test "p a_string" { = "seen"} |
12817 | +gdb_test "ptype a_string" {type = char \[4\]} | |
7566401a | 12818 | + |
51a5ef0f PS |
12819 | +gdb_test "p b_string" { = (0x[0-9a-f]+ )?"seennotseen"} |
12820 | +gdb_test "ptype b_string" {type = char \[\]} | |
6ed6bacf AM |
12821 | + |
12822 | +# The register contains unpredictable value - the array size. | |
12823 | +gdb_test "ptype reg_string" {type = char \[-?[0-9]+\]} | |
f412e1b4 PS |
12824 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.c b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c |
12825 | new file mode 100644 | |
12826 | index 0000000..1f02d90 | |
12827 | --- /dev/null | |
12828 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c | |
51a5ef0f PS |
12829 | @@ -0,0 +1,42 @@ |
12830 | +/* This testcase is part of GDB, the GNU debugger. | |
7566401a | 12831 | + |
51a5ef0f | 12832 | + Copyright 2004 Free Software Foundation, Inc. |
7566401a | 12833 | + |
51a5ef0f PS |
12834 | + This program is free software; you can redistribute it and/or modify |
12835 | + it under the terms of the GNU General Public License as published by | |
12836 | + the Free Software Foundation; either version 2 of the License, or | |
12837 | + (at your option) any later version. | |
7566401a | 12838 | + |
51a5ef0f PS |
12839 | + This program is distributed in the hope that it will be useful, |
12840 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12841 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12842 | + GNU General Public License for more details. | |
12843 | + | |
12844 | + You should have received a copy of the GNU General Public License | |
12845 | + along with this program; if not, write to the Free Software | |
12846 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
12847 | + USA. */ | |
7566401a | 12848 | + |
7566401a | 12849 | + |
51a5ef0f PS |
12850 | +/* The function `func1' traced into must have debug info on offset > 0; |
12851 | + (DW_UNSND (attr)). This is the reason of `func0' existence. */ | |
7566401a | 12852 | + |
51a5ef0f PS |
12853 | +void |
12854 | +func0(int a, int b) | |
12855 | +{ | |
12856 | +} | |
7566401a | 12857 | + |
51a5ef0f | 12858 | +/* `func1' being traced into must have some arguments to dump. */ |
7566401a | 12859 | + |
51a5ef0f PS |
12860 | +void |
12861 | +func1(int a, int b) | |
12862 | +{ | |
12863 | + func0 (a,b); | |
12864 | +} | |
7566401a | 12865 | + |
51a5ef0f PS |
12866 | +int |
12867 | +main(void) | |
12868 | +{ | |
12869 | + func1 (1, 2); | |
12870 | + return 0; | |
12871 | +} | |
f412e1b4 PS |
12872 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp |
12873 | new file mode 100644 | |
12874 | index 0000000..1c6e84a | |
12875 | --- /dev/null | |
12876 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp | |
51a5ef0f PS |
12877 | @@ -0,0 +1,79 @@ |
12878 | +# Copyright 2006 Free Software Foundation, Inc. | |
7566401a | 12879 | + |
51a5ef0f PS |
12880 | +# This program is free software; you can redistribute it and/or modify |
12881 | +# it under the terms of the GNU General Public License as published by | |
12882 | +# the Free Software Foundation; either version 2 of the License, or | |
12883 | +# (at your option) any later version. | |
12884 | +# | |
12885 | +# This program is distributed in the hope that it will be useful, | |
12886 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12887 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12888 | +# GNU General Public License for more details. | |
12889 | +# | |
12890 | +# You should have received a copy of the GNU General Public License | |
12891 | +# along with this program; if not, write to the Free Software | |
12892 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
7566401a | 12893 | + |
51a5ef0f | 12894 | +# Minimal DWARF-2 unit test |
7566401a | 12895 | + |
51a5ef0f PS |
12896 | +# This test can only be run on targets which support DWARF-2. |
12897 | +# For now pick a sampling of likely targets. | |
12898 | +if {![istarget *-*-linux*] | |
12899 | + && ![istarget *-*-gnu*] | |
12900 | + && ![istarget *-*-elf*] | |
12901 | + && ![istarget *-*-openbsd*] | |
12902 | + && ![istarget arm-*-eabi*] | |
12903 | + && ![istarget powerpc-*-eabi*]} { | |
12904 | + return 0 | |
12905 | +} | |
7566401a | 12906 | + |
51a5ef0f PS |
12907 | +set testfile "dw2-stripped" |
12908 | +set srcfile ${testfile}.c | |
12909 | +set binfile ${objdir}/${subdir}/${testfile}.x | |
7566401a | 12910 | + |
51a5ef0f | 12911 | +remote_exec build "rm -f ${binfile}" |
7566401a | 12912 | + |
51a5ef0f PS |
12913 | +# get the value of gcc_compiled |
12914 | +if [get_compiler_info ${binfile}] { | |
12915 | + return -1 | |
12916 | +} | |
7566401a | 12917 | + |
51a5ef0f PS |
12918 | +# This test can only be run on gcc as we use additional_flags=FIXME |
12919 | +if {$gcc_compiled == 0} { | |
12920 | + return 0 | |
12921 | +} | |
7566401a | 12922 | + |
51a5ef0f PS |
12923 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-ggdb3}] != "" } { |
12924 | + return -1 | |
12925 | +} | |
7566401a | 12926 | + |
51a5ef0f PS |
12927 | +remote_exec build "objcopy -R .debug_loc ${binfile}" |
12928 | +set strip_output [remote_exec build "objdump -h ${binfile}"] | |
7566401a | 12929 | + |
51a5ef0f PS |
12930 | +set test "stripping test file preservation" |
12931 | +if [ regexp ".debug_info " $strip_output] { | |
12932 | + pass "$test (.debug_info preserved)" | |
12933 | +} else { | |
12934 | + fail "$test (.debug_info got also stripped)" | |
12935 | +} | |
7566401a | 12936 | + |
51a5ef0f PS |
12937 | +set test "stripping test file functionality" |
12938 | +if [ regexp ".debug_loc " $strip_output] { | |
12939 | + fail "$test (.debug_loc still present)" | |
12940 | +} else { | |
12941 | + pass "$test (.debug_loc stripped)" | |
12942 | +} | |
7566401a | 12943 | + |
51a5ef0f PS |
12944 | +gdb_exit |
12945 | +gdb_start | |
12946 | +gdb_reinitialize_dir $srcdir/$subdir | |
12947 | +gdb_load ${binfile} | |
7566401a | 12948 | + |
51a5ef0f | 12949 | +# For C programs, "start" should stop in main(). |
7566401a | 12950 | + |
51a5ef0f PS |
12951 | +gdb_test "start" \ |
12952 | + ".*main \\(\\) at .*" \ | |
12953 | + "start" | |
12954 | +gdb_test "step" \ | |
12955 | + "func.* \\(.*\\) at .*" \ | |
12956 | + "step" | |
f412e1b4 PS |
12957 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S |
12958 | new file mode 100644 | |
12959 | index 0000000..5fcdd84 | |
12960 | --- /dev/null | |
12961 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S | |
51a5ef0f PS |
12962 | @@ -0,0 +1,83 @@ |
12963 | +/* This testcase is part of GDB, the GNU debugger. | |
7566401a | 12964 | + |
51a5ef0f | 12965 | + Copyright 2009 Free Software Foundation, Inc. |
7566401a | 12966 | + |
51a5ef0f PS |
12967 | + This program is free software; you can redistribute it and/or modify |
12968 | + it under the terms of the GNU General Public License as published by | |
12969 | + the Free Software Foundation; either version 3 of the License, or | |
12970 | + (at your option) any later version. | |
7566401a | 12971 | + |
51a5ef0f PS |
12972 | + This program is distributed in the hope that it will be useful, |
12973 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12974 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12975 | + GNU General Public License for more details. | |
7566401a | 12976 | + |
51a5ef0f PS |
12977 | + You should have received a copy of the GNU General Public License |
12978 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
7566401a | 12979 | + |
51a5ef0f | 12980 | +/* Debug information */ |
7566401a | 12981 | + |
51a5ef0f PS |
12982 | + .section .debug_info |
12983 | +.Lcu1_begin: | |
12984 | + /* CU header */ | |
12985 | + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ | |
12986 | +.Lcu1_start: | |
12987 | + .2byte 2 /* DWARF Version */ | |
12988 | + .4byte .Labbrev1_begin /* Offset into abbrev section */ | |
12989 | + .byte 4 /* Pointer size */ | |
7566401a | 12990 | + |
51a5ef0f PS |
12991 | + /* CU die */ |
12992 | + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ | |
12993 | + .ascii "dw2-struct-member-data-location.c\0" /* DW_AT_name */ | |
12994 | + .ascii "GNU C 4.3.2\0" /* DW_AT_producer */ | |
12995 | + .byte 1 /* DW_AT_language (C) */ | |
3a58abaf | 12996 | + |
51a5ef0f PS |
12997 | +.Ltype_uchar: |
12998 | + .uleb128 2 /* Abbrev: DW_TAG_structure_type */ | |
12999 | + .ascii "some_struct\0" /* DW_AT_name */ | |
3a58abaf | 13000 | + |
51a5ef0f PS |
13001 | + .uleb128 3 /* Abbrev: DW_TAG_member */ |
13002 | + .ascii "field\0" /* DW_AT_name */ | |
13003 | + .byte 0 /* DW_AT_data_member_location */ | |
3a58abaf | 13004 | + |
51a5ef0f | 13005 | + .byte 0 /* End of children of some_struct */ |
3a58abaf | 13006 | + |
51a5ef0f | 13007 | + .byte 0 /* End of children of CU */ |
3a58abaf | 13008 | + |
51a5ef0f | 13009 | +.Lcu1_end: |
3a58abaf | 13010 | + |
51a5ef0f PS |
13011 | +/* Abbrev table */ |
13012 | + .section .debug_abbrev | |
13013 | +.Labbrev1_begin: | |
13014 | + .uleb128 1 /* Abbrev code */ | |
13015 | + .uleb128 0x11 /* DW_TAG_compile_unit */ | |
13016 | + .byte 1 /* has_children */ | |
13017 | + .uleb128 0x3 /* DW_AT_name */ | |
13018 | + .uleb128 0x8 /* DW_FORM_string */ | |
13019 | + .uleb128 0x25 /* DW_AT_producer */ | |
13020 | + .uleb128 0x8 /* DW_FORM_string */ | |
13021 | + .uleb128 0x13 /* DW_AT_language */ | |
13022 | + .uleb128 0xb /* DW_FORM_data1 */ | |
13023 | + .byte 0x0 /* Terminator */ | |
13024 | + .byte 0x0 /* Terminator */ | |
3a58abaf | 13025 | + |
51a5ef0f PS |
13026 | + .uleb128 2 /* Abbrev code */ |
13027 | + .uleb128 0x13 /* DW_TAG_structure_type */ | |
13028 | + .byte 1 /* has_children */ | |
13029 | + .uleb128 0x3 /* DW_AT_name */ | |
13030 | + .uleb128 0x8 /* DW_FORM_string */ | |
13031 | + .byte 0x0 /* Terminator */ | |
13032 | + .byte 0x0 /* Terminator */ | |
3a58abaf | 13033 | + |
51a5ef0f PS |
13034 | + .uleb128 3 /* Abbrev code */ |
13035 | + .uleb128 0x0d /* DW_TAG_member */ | |
13036 | + .byte 0 /* has_children */ | |
13037 | + .uleb128 0x3 /* DW_AT_name */ | |
13038 | + .uleb128 0x8 /* DW_FORM_string */ | |
13039 | + .uleb128 0x38 /* DW_AT_data_member_location */ | |
13040 | + .uleb128 0x0b /* DW_FORM_data1 */ | |
13041 | + .byte 0x0 /* Terminator */ | |
13042 | + .byte 0x0 /* Terminator */ | |
3a58abaf | 13043 | + |
51a5ef0f PS |
13044 | + .byte 0x0 /* Terminator */ |
13045 | + .byte 0x0 /* Terminator */ | |
f412e1b4 PS |
13046 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp |
13047 | new file mode 100644 | |
13048 | index 0000000..c41151c | |
13049 | --- /dev/null | |
13050 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp | |
51a5ef0f PS |
13051 | @@ -0,0 +1,37 @@ |
13052 | +# Copyright 2009 Free Software Foundation, Inc. | |
3a58abaf | 13053 | + |
7566401a ER |
13054 | +# This program is free software; you can redistribute it and/or modify |
13055 | +# it under the terms of the GNU General Public License as published by | |
13056 | +# the Free Software Foundation; either version 3 of the License, or | |
13057 | +# (at your option) any later version. | |
13058 | +# | |
13059 | +# This program is distributed in the hope that it will be useful, | |
13060 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13061 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13062 | +# GNU General Public License for more details. | |
13063 | +# | |
13064 | +# You should have received a copy of the GNU General Public License | |
13065 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 13066 | + |
51a5ef0f PS |
13067 | +# This test can only be run on targets which support DWARF-2 and use gas. |
13068 | +# For now pick a sampling of likely targets. | |
13069 | +if {![istarget *-*-linux*] | |
13070 | + && ![istarget *-*-gnu*] | |
13071 | + && ![istarget *-*-elf*] | |
13072 | + && ![istarget *-*-openbsd*] | |
13073 | + && ![istarget arm-*-eabi*] | |
13074 | + && ![istarget powerpc-*-eabi*]} { | |
13075 | + return 0 | |
13076 | +} | |
3a58abaf | 13077 | + |
51a5ef0f PS |
13078 | +set testfile "dw2-struct-member-data-location" |
13079 | +set srcfile ${testfile}.S | |
13080 | +set binfile ${testfile}.x | |
13081 | + | |
13082 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${binfile}" object {nodebug}] != "" } { | |
7566401a ER |
13083 | + return -1 |
13084 | +} | |
13085 | + | |
51a5ef0f | 13086 | +clean_restart $binfile |
7566401a | 13087 | + |
51a5ef0f | 13088 | +gdb_test "ptype struct some_struct" "type = struct some_struct {\[\r\n \t\]*void field;\[\r\n \t\]*}" |
f412e1b4 PS |
13089 | diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.exp b/gdb/testsuite/gdb.fortran/dwarf-stride.exp |
13090 | new file mode 100644 | |
13091 | index 0000000..d7b8bea | |
13092 | --- /dev/null | |
13093 | +++ b/gdb/testsuite/gdb.fortran/dwarf-stride.exp | |
51a5ef0f PS |
13094 | @@ -0,0 +1,42 @@ |
13095 | +# Copyright 2009 Free Software Foundation, Inc. | |
3a58abaf | 13096 | + |
51a5ef0f PS |
13097 | +# This program is free software; you can redistribute it and/or modify |
13098 | +# it under the terms of the GNU General Public License as published by | |
13099 | +# the Free Software Foundation; either version 2 of the License, or | |
13100 | +# (at your option) any later version. | |
13101 | +# | |
13102 | +# This program is distributed in the hope that it will be useful, | |
13103 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13104 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13105 | +# GNU General Public License for more details. | |
13106 | +# | |
13107 | +# You should have received a copy of the GNU General Public License | |
13108 | +# along with this program; if not, write to the Free Software | |
13109 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
3a58abaf | 13110 | + |
51a5ef0f | 13111 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. |
3a58abaf | 13112 | + |
51a5ef0f PS |
13113 | +# This file is part of the gdb testsuite. Array element stride must not be |
13114 | +# specified in the number of elements but in a number of bytes instead. | |
13115 | +# Original problem: | |
13116 | +# (gdb) p c40pt(1) | |
13117 | +# $1 = '0-hello', ' ' <repeats 33 times> | |
13118 | +# (gdb) p c40pt(2) | |
13119 | +# warning: Fortran array stride not divisible by the element size | |
3a58abaf | 13120 | + |
51a5ef0f PS |
13121 | +set testfile dwarf-stride |
13122 | +set srcfile ${testfile}.f90 | |
7566401a | 13123 | + |
f412e1b4 | 13124 | +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}] } { |
51a5ef0f | 13125 | + return -1 |
3a58abaf AM |
13126 | +} |
13127 | + | |
51a5ef0f PS |
13128 | +if ![runto MAIN__] then { |
13129 | + perror "couldn't run to breakpoint MAIN__" | |
13130 | + continue | |
13131 | +} | |
7566401a | 13132 | + |
51a5ef0f PS |
13133 | +gdb_breakpoint [gdb_get_line_number "break-here"] |
13134 | +gdb_continue_to_breakpoint "break-here" ".*break-here.*" | |
13135 | +gdb_test "p c40pt(1)" " = '0-hello.*" | |
13136 | +gdb_test "p c40pt(2)" " = '1-hello.*" | |
f412e1b4 PS |
13137 | diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.f90 b/gdb/testsuite/gdb.fortran/dwarf-stride.f90 |
13138 | new file mode 100644 | |
13139 | index 0000000..e492b3a | |
13140 | --- /dev/null | |
13141 | +++ b/gdb/testsuite/gdb.fortran/dwarf-stride.f90 | |
51a5ef0f PS |
13142 | @@ -0,0 +1,40 @@ |
13143 | +! Copyright 2009 Free Software Foundation, Inc. | |
13144 | +! | |
13145 | +! This program is free software; you can redistribute it and/or modify | |
13146 | +! it under the terms of the GNU General Public License as published by | |
13147 | +! the Free Software Foundation; either version 2 of the License, or | |
13148 | +! (at your option) any later version. | |
13149 | +! | |
13150 | +! This program is distributed in the hope that it will be useful, | |
13151 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13152 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13153 | +! GNU General Public License for more details. | |
13154 | +! | |
13155 | +! You should have received a copy of the GNU General Public License | |
13156 | +! along with this program; if not, write to the Free Software | |
13157 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
13158 | +! | |
13159 | +! File written by Alan Matsuoka. | |
7566401a | 13160 | + |
51a5ef0f | 13161 | +program repro |
7566401a | 13162 | + |
51a5ef0f PS |
13163 | + type small_stride |
13164 | + character*40 long_string | |
13165 | + integer small_pad | |
13166 | + end type small_stride | |
7566401a | 13167 | + |
51a5ef0f PS |
13168 | + type(small_stride), dimension (20), target :: unpleasant |
13169 | + character*40, pointer, dimension(:):: c40pt | |
7566401a | 13170 | + |
51a5ef0f | 13171 | + integer i |
7566401a | 13172 | + |
51a5ef0f PS |
13173 | + do i = 0,19 |
13174 | + unpleasant(i+1)%small_pad = i+1 | |
13175 | + unpleasant(i+1)%long_string = char (ichar('0') + i) // '-hello' | |
13176 | + end do | |
7566401a | 13177 | + |
51a5ef0f | 13178 | + c40pt => unpleasant%long_string |
7566401a | 13179 | + |
51a5ef0f | 13180 | + print *, c40pt ! break-here |
7566401a | 13181 | + |
51a5ef0f | 13182 | +end program repro |
f412e1b4 PS |
13183 | diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90 b/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90 |
13184 | new file mode 100644 | |
13185 | index 0000000..261ce17 | |
13186 | --- /dev/null | |
13187 | +++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90 | |
6ed6bacf AM |
13188 | @@ -0,0 +1,24 @@ |
13189 | +! Copyright 2010 Free Software Foundation, Inc. | |
13190 | +! | |
13191 | +! This program is free software; you can redistribute it and/or modify | |
13192 | +! it under the terms of the GNU General Public License as published by | |
13193 | +! the Free Software Foundation; either version 2 of the License, or | |
13194 | +! (at your option) any later version. | |
13195 | +! | |
13196 | +! This program is distributed in the hope that it will be useful, | |
13197 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13198 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13199 | +! GNU General Public License for more details. | |
13200 | +! | |
13201 | +! You should have received a copy of the GNU General Public License | |
13202 | +! along with this program; if not, write to the Free Software | |
13203 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
13204 | +! | |
13205 | +! Ihis file is the Fortran source file for dynamic.exp. | |
13206 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
13207 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
13208 | + | |
13209 | +subroutine bar | |
13210 | + real :: dummy | |
13211 | + dummy = 1 | |
13212 | +end subroutine bar | |
f412e1b4 PS |
13213 | diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp b/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp |
13214 | new file mode 100644 | |
13215 | index 0000000..fa41b80 | |
13216 | --- /dev/null | |
13217 | +++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp | |
6ed6bacf AM |
13218 | @@ -0,0 +1,37 @@ |
13219 | +# Copyright 2010 Free Software Foundation, Inc. | |
13220 | + | |
13221 | +# This program is free software; you can redistribute it and/or modify | |
13222 | +# it under the terms of the GNU General Public License as published by | |
13223 | +# the Free Software Foundation; either version 2 of the License, or | |
13224 | +# (at your option) any later version. | |
13225 | +# | |
13226 | +# This program is distributed in the hope that it will be useful, | |
13227 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13228 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13229 | +# GNU General Public License for more details. | |
13230 | +# | |
13231 | +# You should have received a copy of the GNU General Public License | |
13232 | +# along with this program; if not, write to the Free Software | |
13233 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
13234 | + | |
13235 | +set testfile "dynamic-other-frame" | |
13236 | +set srcfile1 ${testfile}.f90 | |
13237 | +set srcfile2 ${testfile}-stub.f90 | |
13238 | +set objfile2 ${objdir}/${subdir}/${testfile}-stub.o | |
13239 | +set executable ${testfile} | |
13240 | +set binfile ${objdir}/${subdir}/${executable} | |
13241 | + | |
f412e1b4 PS |
13242 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${objfile2}" object {f90}] != "" |
13243 | + || [gdb_compile "${srcdir}/${subdir}/${srcfile1} ${objfile2}" "${binfile}" executable {debug f90}] != "" } { | |
6ed6bacf AM |
13244 | + untested "Couldn't compile ${srcfile1} or ${srcfile2}" |
13245 | + return -1 | |
13246 | +} | |
13247 | + | |
13248 | +clean_restart ${executable} | |
13249 | + | |
13250 | +if ![runto bar_] then { | |
13251 | + perror "couldn't run to bar_" | |
13252 | + continue | |
13253 | +} | |
13254 | + | |
13255 | +gdb_test "bt" {foo \(string='hello'.*} | |
f412e1b4 PS |
13256 | diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90 b/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90 |
13257 | new file mode 100644 | |
13258 | index 0000000..2bc637d | |
13259 | --- /dev/null | |
13260 | +++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90 | |
6ed6bacf AM |
13261 | @@ -0,0 +1,36 @@ |
13262 | +! Copyright 2010 Free Software Foundation, Inc. | |
13263 | +! | |
13264 | +! This program is free software; you can redistribute it and/or modify | |
13265 | +! it under the terms of the GNU General Public License as published by | |
13266 | +! the Free Software Foundation; either version 2 of the License, or | |
13267 | +! (at your option) any later version. | |
13268 | +! | |
13269 | +! This program is distributed in the hope that it will be useful, | |
13270 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13271 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13272 | +! GNU General Public License for more details. | |
13273 | +! | |
13274 | +! You should have received a copy of the GNU General Public License | |
13275 | +! along with this program; if not, write to the Free Software | |
13276 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
13277 | +! | |
13278 | +! Ihis file is the Fortran source file for dynamic.exp. | |
13279 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
13280 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
13281 | + | |
13282 | +subroutine foo (string) | |
13283 | + interface | |
13284 | + subroutine bar | |
13285 | + end subroutine | |
13286 | + end interface | |
13287 | + character string*(*) | |
13288 | + call bar ! stop-here | |
13289 | +end subroutine foo | |
13290 | +program test | |
13291 | + interface | |
13292 | + subroutine foo (string) | |
13293 | + character string*(*) | |
13294 | + end subroutine | |
13295 | + end interface | |
13296 | + call foo ('hello') | |
13297 | +end | |
f412e1b4 PS |
13298 | diff --git a/gdb/testsuite/gdb.fortran/dynamic.exp b/gdb/testsuite/gdb.fortran/dynamic.exp |
13299 | new file mode 100644 | |
13300 | index 0000000..e79e94a | |
13301 | --- /dev/null | |
13302 | +++ b/gdb/testsuite/gdb.fortran/dynamic.exp | |
13303 | @@ -0,0 +1,152 @@ | |
51a5ef0f | 13304 | +# Copyright 2007 Free Software Foundation, Inc. |
3a58abaf | 13305 | + |
51a5ef0f PS |
13306 | +# This program is free software; you can redistribute it and/or modify |
13307 | +# it under the terms of the GNU General Public License as published by | |
13308 | +# the Free Software Foundation; either version 2 of the License, or | |
13309 | +# (at your option) any later version. | |
13310 | +# | |
13311 | +# This program is distributed in the hope that it will be useful, | |
13312 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13313 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13314 | +# GNU General Public License for more details. | |
13315 | +# | |
13316 | +# You should have received a copy of the GNU General Public License | |
13317 | +# along with this program; if not, write to the Free Software | |
13318 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
7566401a | 13319 | + |
51a5ef0f | 13320 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. |
7566401a | 13321 | + |
51a5ef0f PS |
13322 | +# This file is part of the gdb testsuite. It contains tests for dynamically |
13323 | +# allocated Fortran arrays. | |
13324 | +# It depends on the GCC dynamic Fortran arrays DWARF support: | |
13325 | +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22244 | |
7566401a | 13326 | + |
51a5ef0f PS |
13327 | +set testfile "dynamic" |
13328 | +set srcfile ${testfile}.f90 | |
13329 | +set binfile ${objdir}/${subdir}/${testfile} | |
7566401a | 13330 | + |
f412e1b4 | 13331 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f90 quiet}] != "" } { |
51a5ef0f PS |
13332 | + untested "Couldn't compile ${srcfile}" |
13333 | + return -1 | |
13334 | +} | |
7566401a | 13335 | + |
51a5ef0f PS |
13336 | +gdb_exit |
13337 | +gdb_start | |
13338 | +gdb_reinitialize_dir $srcdir/$subdir | |
13339 | +gdb_load ${binfile} | |
7566401a | 13340 | + |
51a5ef0f PS |
13341 | +if ![runto MAIN__] then { |
13342 | + perror "couldn't run to breakpoint MAIN__" | |
13343 | + continue | |
13344 | +} | |
7566401a | 13345 | + |
51a5ef0f PS |
13346 | +gdb_breakpoint [gdb_get_line_number "varx-init"] |
13347 | +gdb_continue_to_breakpoint "varx-init" | |
13348 | +gdb_test "p varx" "\\$\[0-9\]* = <(object|the array) is not allocated>" "p varx unallocated" | |
13349 | +gdb_test "ptype varx" "type = <(object|the array) is not allocated>" "ptype varx unallocated" | |
13350 | +gdb_test "p varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "p varx(1,5,17) unallocated" | |
13351 | +gdb_test "p varx(1,5,17)=1" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "p varx(1,5,17)=1 unallocated" | |
13352 | +gdb_test "ptype varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "ptype varx(1,5,17) unallocated" | |
7566401a | 13353 | + |
51a5ef0f PS |
13354 | +gdb_breakpoint [gdb_get_line_number "varx-allocated"] |
13355 | +gdb_continue_to_breakpoint "varx-allocated" | |
13356 | +# $1 = (( ( 0, 0, 0, 0, 0, 0) ( 0, 0, 0, 0, 0, 0) --- , 0) ) ( ( 0, 0, ...) ...) ...) | |
13357 | +gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)" "ptype varx allocated" | |
13358 | +# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1. | |
13359 | +gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varx allocated" | |
7566401a | 13360 | + |
51a5ef0f PS |
13361 | +gdb_breakpoint [gdb_get_line_number "varx-filled"] |
13362 | +gdb_continue_to_breakpoint "varx-filled" | |
13363 | +gdb_test "p varx(2, 5, 17)" "\\$\[0-9\]* = 6" | |
13364 | +gdb_test "p varx(1, 5, 17)" "\\$\[0-9\]* = 7" | |
13365 | +gdb_test "p varx(2, 6, 18)" "\\$\[0-9\]* = 8" | |
13366 | +gdb_test "p varx(6, 15, 28)" "\\$\[0-9\]* = 9" | |
13367 | +# The latter one is for the Intel Fortran Compiler 10.1.008 pointer type. | |
13368 | +gdb_test "p varv" "\\$\[0-9\]* = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "p varv unassociated" | |
13369 | +gdb_test "ptype varv" "type = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "ptype varv unassociated" | |
7566401a | 13370 | + |
f412e1b4 PS |
13371 | +set test "output varx" |
13372 | +gdb_test_multiple $test $test { | |
13373 | + -re "^output varx\r\n\[() ,6789.\]*$gdb_prompt $" { | |
13374 | + pass $test | |
13375 | + } | |
13376 | +} | |
13377 | + | |
51a5ef0f PS |
13378 | +gdb_breakpoint [gdb_get_line_number "varv-associated"] |
13379 | +gdb_continue_to_breakpoint "varv-associated" | |
13380 | +gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 6" "p varx(3, 7, 19) with varv associated" | |
13381 | +gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 6" "p varv(3, 7, 19) associated" | |
13382 | +# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1. | |
13383 | +gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varv associated" | |
13384 | +gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)" "ptype varx with varv associated" | |
13385 | +# Intel Fortran Compiler 10.1.008 uses the pointer type. | |
13386 | +gdb_test "ptype varv" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)\\)?" "ptype varv associated" | |
7566401a | 13387 | + |
51a5ef0f PS |
13388 | +gdb_breakpoint [gdb_get_line_number "varv-filled"] |
13389 | +gdb_continue_to_breakpoint "varv-filled" | |
13390 | +gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 10" "p varx(3, 7, 19) with varv filled" | |
13391 | +gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 10" "p varv(3, 7, 19) filled" | |
7566401a | 13392 | + |
51a5ef0f PS |
13393 | +gdb_breakpoint [gdb_get_line_number "varv-deassociated"] |
13394 | +gdb_continue_to_breakpoint "varv-deassociated" | |
13395 | +# The latter one is for the Intel Fortran Compiler 10.1.008 pointer type. | |
13396 | +gdb_test "p varv" "\\$\[0-9\]* = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "p varv deassociated" | |
13397 | +gdb_test "ptype varv" "type = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "ptype varv deassociated" | |
13398 | +gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varv deassociated" | |
13399 | +gdb_test "p varv(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not associated\\." | |
13400 | +gdb_test "ptype varv(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not associated\\." | |
7566401a | 13401 | + |
51a5ef0f PS |
13402 | +gdb_breakpoint [gdb_get_line_number "varx-deallocated"] |
13403 | +gdb_continue_to_breakpoint "varx-deallocated" | |
13404 | +gdb_test "p varx" "\\$\[0-9\]* = <(object|the array) is not allocated>" "p varx deallocated" | |
13405 | +gdb_test "ptype varx" "type = <(object|the array) is not allocated>" "ptype varx deallocated" | |
13406 | +gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varx deallocated" | |
13407 | +gdb_test "p varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "p varx(1,5,17) deallocated" | |
13408 | +gdb_test "ptype varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "ptype varx(1,5,17) deallocated" | |
7566401a | 13409 | + |
51a5ef0f PS |
13410 | +gdb_breakpoint [gdb_get_line_number "vary-passed"] |
13411 | +gdb_continue_to_breakpoint "vary-passed" | |
13412 | +# $1 = (( ( 1, 1, 1, 1, 1, 1) ( 1, 1, 1, 1, 1, 1) --- , 1) ) ( ( 1, 1, ...) ...) ...) | |
13413 | +gdb_test "p vary" "\\$\[0-9\]* = \\(\[()1, .\]*\\)" | |
7566401a | 13414 | + |
51a5ef0f PS |
13415 | +gdb_breakpoint [gdb_get_line_number "vary-filled"] |
13416 | +gdb_continue_to_breakpoint "vary-filled" | |
13417 | +gdb_test "ptype vary" "type = real(\\(kind=4\\)|\\*4) \\(10,10\\)" | |
13418 | +gdb_test "p vary(1, 1)" "\\$\[0-9\]* = 8" | |
13419 | +gdb_test "p vary(2, 2)" "\\$\[0-9\]* = 9" | |
13420 | +gdb_test "p vary(1, 3)" "\\$\[0-9\]* = 10" | |
13421 | +# $1 = (( ( 3, 3, 3, 3, 3, 3) ( 3, 3, 3, 3, 3, 3) --- , 3) ) ( ( 3, 3, ...) ...) ...) | |
13422 | +gdb_test "p varw" "\\$\[0-9\]* = \\(\[()3, .\]*\\)" | |
7566401a | 13423 | + |
51a5ef0f PS |
13424 | +gdb_breakpoint [gdb_get_line_number "varw-almostfilled"] |
13425 | +gdb_continue_to_breakpoint "varw-almostfilled" | |
13426 | +gdb_test "ptype varw" "type = real(\\(kind=4\\)|\\*4) \\(5,4,3\\)" | |
13427 | +gdb_test "p varw(3,1,1)=1" "\\$\[0-9\]* = 1" | |
13428 | +# $1 = (( ( 6, 5, 1, 5, 5, 5) ( 5, 5, 5, 5, 5, 5) --- , 5) ) ( ( 5, 5, ...) ...) ...) | |
13429 | +gdb_test "p varw" "\\$\[0-9\]* = \\( *\\( *\\( *6, *5, *1,\[()5, .\]*\\)" "p varw filled" | |
13430 | +# "up" works with GCC but other Fortran compilers may copy the values into the | |
13431 | +# outer function only on the exit of the inner function. | |
13432 | +# We need both variants as depending on the arch we optionally may still be | |
13433 | +# executing the caller line or not after `finish'. | |
13434 | +gdb_test "finish" ".*(call bar \\(y, x\\)|call foo \\(x, z\\(2:6, 4:7, 6:8\\)\\))" | |
13435 | +gdb_test "p z(2,4,5)" "\\$\[0-9\]* = 3" | |
13436 | +gdb_test "p z(2,4,6)" "\\$\[0-9\]* = 6" | |
13437 | +gdb_test "p z(2,4,7)" "\\$\[0-9\]* = 5" | |
13438 | +gdb_test "p z(4,4,6)" "\\$\[0-9\]* = 1" | |
7566401a | 13439 | + |
51a5ef0f PS |
13440 | +gdb_breakpoint [gdb_get_line_number "varz-almostfilled"] |
13441 | +gdb_continue_to_breakpoint "varz-almostfilled" | |
13442 | +# GCC uses the pointer type here, Intel Fortran Compiler 10.1.008 does not. | |
13443 | +gdb_test "ptype varz" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(\\*\\)\\)?" | |
13444 | +# Intel Fortran Compiler 10.1.008 has a bug here - (2:11,7:7) | |
13445 | +# as it produces DW_AT_lower_bound == DW_AT_upper_bound == 7. | |
13446 | +gdb_test "ptype vart" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(2:11,7:\\*\\)\\)?" | |
13447 | +gdb_test "p varz" "\\$\[0-9\]* = \\(\\)" | |
13448 | +gdb_test "p vart" "\\$\[0-9\]* = \\(\\)" | |
13449 | +gdb_test "p varz(3)" "\\$\[0-9\]* = 4" | |
13450 | +# maps to foo::vary(1,1) | |
13451 | +gdb_test "p vart(2,7)" "\\$\[0-9\]* = 8" | |
13452 | +# maps to foo::vary(2,2) | |
13453 | +gdb_test "p vart(3,8)" "\\$\[0-9\]* = 9" | |
13454 | +# maps to foo::vary(1,3) | |
13455 | +gdb_test "p vart(2,9)" "\\$\[0-9\]* = 10" | |
f412e1b4 PS |
13456 | diff --git a/gdb/testsuite/gdb.fortran/dynamic.f90 b/gdb/testsuite/gdb.fortran/dynamic.f90 |
13457 | new file mode 100644 | |
13458 | index 0000000..0f43564 | |
13459 | --- /dev/null | |
13460 | +++ b/gdb/testsuite/gdb.fortran/dynamic.f90 | |
51a5ef0f PS |
13461 | @@ -0,0 +1,98 @@ |
13462 | +! Copyright 2007 Free Software Foundation, Inc. | |
13463 | +! | |
13464 | +! This program is free software; you can redistribute it and/or modify | |
13465 | +! it under the terms of the GNU General Public License as published by | |
13466 | +! the Free Software Foundation; either version 2 of the License, or | |
13467 | +! (at your option) any later version. | |
13468 | +! | |
13469 | +! This program is distributed in the hope that it will be useful, | |
13470 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13471 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13472 | +! GNU General Public License for more details. | |
13473 | +! | |
13474 | +! You should have received a copy of the GNU General Public License | |
13475 | +! along with this program; if not, write to the Free Software | |
13476 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
13477 | +! | |
13478 | +! Ihis file is the Fortran source file for dynamic.exp. | |
13479 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
13480 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
7566401a | 13481 | + |
51a5ef0f PS |
13482 | +subroutine baz |
13483 | + real, target, allocatable :: varx (:, :, :) | |
13484 | + real, pointer :: varv (:, :, :) | |
13485 | + real, target :: varu (1, 2, 3) | |
13486 | + logical :: l | |
13487 | + allocate (varx (1:6, 5:15, 17:28)) ! varx-init | |
13488 | + l = allocated (varx) | |
13489 | + varx(:, :, :) = 6 ! varx-allocated | |
13490 | + varx(1, 5, 17) = 7 | |
13491 | + varx(2, 6, 18) = 8 | |
13492 | + varx(6, 15, 28) = 9 | |
13493 | + varv => varx ! varx-filled | |
13494 | + l = associated (varv) | |
13495 | + varv(3, 7, 19) = 10 ! varv-associated | |
13496 | + varv => null () ! varv-filled | |
13497 | + l = associated (varv) | |
13498 | + deallocate (varx) ! varv-deassociated | |
13499 | + l = allocated (varx) | |
13500 | + varu(:, :, :) = 10 ! varx-deallocated | |
13501 | + allocate (varv (1:6, 5:15, 17:28)) | |
13502 | + l = associated (varv) | |
13503 | + varv(:, :, :) = 6 | |
13504 | + varv(1, 5, 17) = 7 | |
13505 | + varv(2, 6, 18) = 8 | |
13506 | + varv(6, 15, 28) = 9 | |
13507 | + deallocate (varv) | |
13508 | + l = associated (varv) | |
13509 | + varv => varu | |
13510 | + varv(1, 1, 1) = 6 | |
13511 | + varv(1, 2, 3) = 7 | |
13512 | + l = associated (varv) | |
13513 | +end subroutine baz | |
13514 | +subroutine foo (vary, varw) | |
13515 | + real :: vary (:, :) | |
13516 | + real :: varw (:, :, :) | |
13517 | + vary(:, :) = 4 ! vary-passed | |
13518 | + vary(1, 1) = 8 | |
13519 | + vary(2, 2) = 9 | |
13520 | + vary(1, 3) = 10 | |
13521 | + varw(:, :, :) = 5 ! vary-filled | |
13522 | + varw(1, 1, 1) = 6 | |
13523 | + varw(2, 2, 2) = 7 ! varw-almostfilled | |
13524 | +end subroutine foo | |
13525 | +subroutine bar (varz, vart) | |
13526 | + real :: varz (*) | |
13527 | + real :: vart (2:11, 7:*) | |
13528 | + varz(1:3) = 4 | |
13529 | + varz(2) = 5 ! varz-almostfilled | |
13530 | + vart(2,7) = vart(2,7) | |
13531 | +end subroutine bar | |
13532 | +program test | |
13533 | + interface | |
13534 | + subroutine foo (vary, varw) | |
13535 | + real :: vary (:, :) | |
13536 | + real :: varw (:, :, :) | |
13537 | + end subroutine | |
13538 | + end interface | |
13539 | + interface | |
13540 | + subroutine bar (varz, vart) | |
13541 | + real :: varz (*) | |
13542 | + real :: vart (2:11, 7:*) | |
13543 | + end subroutine | |
13544 | + end interface | |
13545 | + real :: x (10, 10), y (5), z(8, 8, 8) | |
13546 | + x(:,:) = 1 | |
13547 | + y(:) = 2 | |
13548 | + z(:,:,:) = 3 | |
13549 | + call baz | |
13550 | + call foo (x, z(2:6, 4:7, 6:8)) | |
13551 | + call bar (y, x) | |
13552 | + if (x (1, 1) .ne. 8 .or. x (2, 2) .ne. 9 .or. x (1, 2) .ne. 4) call abort | |
13553 | + if (x (1, 3) .ne. 10) call abort | |
13554 | + if (z (2, 4, 6) .ne. 6 .or. z (3, 5, 7) .ne. 7 .or. z (2, 4, 7) .ne. 5) call abort | |
13555 | + if (any (y .ne. (/4, 5, 4, 2, 2/))) call abort | |
13556 | + call foo (transpose (x), z) | |
13557 | + if (x (1, 1) .ne. 8 .or. x (2, 2) .ne. 9 .or. x (1, 2) .ne. 4) call abort | |
13558 | + if (x (3, 1) .ne. 10) call abort | |
13559 | +end | |
f412e1b4 PS |
13560 | diff --git a/gdb/testsuite/gdb.fortran/string.exp b/gdb/testsuite/gdb.fortran/string.exp |
13561 | new file mode 100644 | |
13562 | index 0000000..39de2c4 | |
13563 | --- /dev/null | |
13564 | +++ b/gdb/testsuite/gdb.fortran/string.exp | |
51a5ef0f PS |
13565 | @@ -0,0 +1,59 @@ |
13566 | +# Copyright 2008 Free Software Foundation, Inc. | |
7566401a | 13567 | + |
51a5ef0f PS |
13568 | +# This program is free software; you can redistribute it and/or modify |
13569 | +# it under the terms of the GNU General Public License as published by | |
13570 | +# the Free Software Foundation; either version 2 of the License, or | |
13571 | +# (at your option) any later version. | |
13572 | +# | |
13573 | +# This program is distributed in the hope that it will be useful, | |
13574 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13575 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13576 | +# GNU General Public License for more details. | |
13577 | +# | |
13578 | +# You should have received a copy of the GNU General Public License | |
13579 | +# along with this program; if not, write to the Free Software | |
13580 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
3a58abaf | 13581 | + |
51a5ef0f | 13582 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. |
3a58abaf | 13583 | + |
51a5ef0f PS |
13584 | +# This file is part of the gdb testsuite. It contains tests for Fortran |
13585 | +# strings with dynamic length. | |
3a58abaf | 13586 | + |
51a5ef0f PS |
13587 | +set testfile "string" |
13588 | +set srcfile ${testfile}.f90 | |
13589 | +set binfile ${objdir}/${subdir}/${testfile} | |
3a58abaf | 13590 | + |
f412e1b4 | 13591 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f90 quiet}] != "" } { |
51a5ef0f PS |
13592 | + untested "Couldn't compile ${srcfile}" |
13593 | + return -1 | |
13594 | +} | |
3a58abaf | 13595 | + |
51a5ef0f PS |
13596 | +gdb_exit |
13597 | +gdb_start | |
13598 | +gdb_reinitialize_dir $srcdir/$subdir | |
13599 | +gdb_load ${binfile} | |
3a58abaf | 13600 | + |
51a5ef0f PS |
13601 | +if ![runto MAIN__] then { |
13602 | + perror "couldn't run to breakpoint MAIN__" | |
13603 | + continue | |
13604 | +} | |
7566401a | 13605 | + |
51a5ef0f PS |
13606 | +gdb_breakpoint [gdb_get_line_number "var-init"] |
13607 | +gdb_continue_to_breakpoint "var-init" | |
13608 | +gdb_test "ptype c" "type = character(\\(kind=1\\)|\\*1)" | |
13609 | +gdb_test "ptype d" "type = character(\\(kind=8\\)|\\*8)" | |
13610 | +gdb_test "ptype e" "type = character(\\(kind=4\\)|\\*4)" | |
13611 | +gdb_test "ptype f" "type = character(\\(kind=4\\)|\\*4) \\(7,8:10\\)" | |
13612 | +gdb_test "ptype *e" "Attempt to take contents of a non-pointer value." | |
13613 | +gdb_test "ptype *f" "type = character(\\(kind=4\\)|\\*4) \\(7\\)" | |
13614 | +gdb_test "p c" "\\$\[0-9\]* = 'c'" | |
13615 | +gdb_test "p d" "\\$\[0-9\]* = 'd '" | |
13616 | +gdb_test "p e" "\\$\[0-9\]* = 'g '" | |
13617 | +gdb_test "p f" "\\$\[0-9\]* = \\(\\( 'h ', 'h ', 'h ', 'h ', 'h ', 'h ', 'h '\\) \\( 'h ', 'h ', 'h ', 'h ', 'h ', 'h ', 'h '\\) \\( 'h ', 'h ', 'h ', 'h ', 'h ', 'h ', 'h '\\) \\)" | |
13618 | +gdb_test "p *e" "Attempt to take contents of a non-pointer value." | |
13619 | +gdb_test "p *f" "Attempt to take contents of a non-pointer value." | |
7566401a | 13620 | + |
51a5ef0f PS |
13621 | +gdb_breakpoint [gdb_get_line_number "var-finish"] |
13622 | +gdb_continue_to_breakpoint "var-finish" | |
13623 | +gdb_test "p e" "\\$\[0-9\]* = 'e '" "p e re-set" | |
13624 | +gdb_test "p f" "\\$\[0-9\]* = \\(\\( 'f ', 'f ', 'f ', 'f ', 'f ', 'f ', 'f '\\) \\( 'f2 ', 'f ', 'f ', 'f ', 'f ', 'f ', 'f '\\) \\( 'f ', 'f ', 'f ', 'f ', 'f ', 'f ', 'f '\\) \\)" "p *f re-set" | |
f412e1b4 PS |
13625 | diff --git a/gdb/testsuite/gdb.fortran/string.f90 b/gdb/testsuite/gdb.fortran/string.f90 |
13626 | new file mode 100644 | |
13627 | index 0000000..226dc5d | |
13628 | --- /dev/null | |
13629 | +++ b/gdb/testsuite/gdb.fortran/string.f90 | |
51a5ef0f PS |
13630 | @@ -0,0 +1,37 @@ |
13631 | +! Copyright 2008 Free Software Foundation, Inc. | |
13632 | +! | |
13633 | +! This program is free software; you can redistribute it and/or modify | |
13634 | +! it under the terms of the GNU General Public License as published by | |
13635 | +! the Free Software Foundation; either version 2 of the License, or | |
13636 | +! (at your option) any later version. | |
13637 | +! | |
13638 | +! This program is distributed in the hope that it will be useful, | |
13639 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13640 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13641 | +! GNU General Public License for more details. | |
13642 | +! | |
13643 | +! You should have received a copy of the GNU General Public License | |
13644 | +! along with this program; if not, write to the Free Software | |
13645 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
13646 | +! | |
13647 | +! Ihis file is the Fortran source file for dynamic.exp. | |
13648 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
13649 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
7566401a | 13650 | + |
51a5ef0f PS |
13651 | +subroutine foo (e, f) |
13652 | + character (len=1) :: c | |
13653 | + character (len=8) :: d | |
13654 | + character (len=*) :: e | |
13655 | + character (len=*) :: f (1:7, 8:10) | |
13656 | + c = 'c' | |
13657 | + d = 'd' | |
13658 | + e = 'e' ! var-init | |
13659 | + f = 'f' | |
13660 | + f(1,9) = 'f2' | |
13661 | + c = 'c' ! var-finish | |
13662 | +end subroutine foo | |
13663 | + character (len=4) :: g, h (1:7, 8:10) | |
13664 | + g = 'g' | |
13665 | + h = 'h' | |
13666 | + call foo (g, h) | |
13667 | +end | |
f412e1b4 PS |
13668 | diff --git a/gdb/testsuite/gdb.fortran/subrange.exp b/gdb/testsuite/gdb.fortran/subrange.exp |
13669 | new file mode 100644 | |
13670 | index 0000000..c819e23 | |
13671 | --- /dev/null | |
13672 | +++ b/gdb/testsuite/gdb.fortran/subrange.exp | |
6ed6bacf AM |
13673 | @@ -0,0 +1,60 @@ |
13674 | +# Copyright 2011 Free Software Foundation, Inc. | |
13675 | + | |
13676 | +# This program is free software; you can redistribute it and/or modify | |
13677 | +# it under the terms of the GNU General Public License as published by | |
13678 | +# the Free Software Foundation; either version 3 of the License, or | |
13679 | +# (at your option) any later version. | |
13680 | +# | |
13681 | +# This program is distributed in the hope that it will be useful, | |
13682 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13683 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13684 | +# GNU General Public License for more details. | |
13685 | +# | |
13686 | +# You should have received a copy of the GNU General Public License | |
13687 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13688 | + | |
13689 | +if { [skip_fortran_tests] } { return -1 } | |
13690 | + | |
13691 | +set testfile "subrange" | |
13692 | +set srcfile ${testfile}.f90 | |
f412e1b4 | 13693 | +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}] } { |
6ed6bacf AM |
13694 | + return -1 |
13695 | +} | |
13696 | + | |
13697 | +if ![runto MAIN__] { | |
13698 | + perror "Couldn't run to MAIN__" | |
13699 | + continue | |
13700 | +} | |
13701 | + | |
13702 | +# Depending on the compiler version being used, the name of the 4-byte integer | |
13703 | +# and real types can be printed differently. For instance, gfortran-4.1 uses | |
13704 | +# "int4" whereas gfortran-4.3 uses "int(kind=4)". | |
13705 | +set int4 "(int4|integer\\(kind=4\\))" | |
13706 | + | |
13707 | +gdb_breakpoint [gdb_get_line_number "break-static"] | |
13708 | +gdb_continue_to_breakpoint "break-static" ".*break-static.*" | |
13709 | + | |
13710 | +foreach var {a alloc ptr} { | |
13711 | + global pf_prefix | |
13712 | + set old_prefix $pf_prefix | |
13713 | + lappend pf_prefix "$var:" | |
13714 | + | |
13715 | + gdb_test "p $var (2, 2:3)" { = \(22, 32\)} | |
13716 | + gdb_test "p $var (2:3, 3)" { = \(32, 33\)} | |
13717 | + gdb_test "p $var (1, 2:)" { = \(21, 31\)} | |
13718 | + gdb_test "p $var (2, :2)" { = \(12, 22\)} | |
13719 | + gdb_test "p $var (3, 2:2)" { = \(23\)} | |
13720 | + gdb_test "ptype $var (3, 2:2)" " = $int4 \\(2:2\\)" | |
13721 | + gdb_test "p $var (4, :)" { = \(14, 24, 34\)} | |
13722 | + gdb_test "p $var (:, :)" { = \(\( *11, 12, 13, 14\) \( *21, 22, 23, 24\) \( *31, 32, 33, 34\) *\)} | |
13723 | + gdb_test "ptype $var (:, :)" " = $int4 \\(4,3\\)" | |
13724 | + gdb_test "p $var (:)" "Wrong number of subscripts" | |
13725 | + gdb_test "p $var (:, :, :)" "Wrong number of subscripts" | |
13726 | + | |
13727 | + set pf_prefix $old_prefix | |
13728 | +} | |
13729 | + | |
13730 | +gdb_test_no_output {set $a=a} | |
13731 | +delete_breakpoints | |
13732 | +gdb_unload | |
13733 | +gdb_test {p $a (3, 2:2)} { = \(23\)} | |
f412e1b4 PS |
13734 | diff --git a/gdb/testsuite/gdb.fortran/subrange.f90 b/gdb/testsuite/gdb.fortran/subrange.f90 |
13735 | new file mode 100644 | |
13736 | index 0000000..4747ea9 | |
13737 | --- /dev/null | |
13738 | +++ b/gdb/testsuite/gdb.fortran/subrange.f90 | |
6ed6bacf AM |
13739 | @@ -0,0 +1,28 @@ |
13740 | +! Copyright 2011 Free Software Foundation, Inc. | |
13741 | +! | |
13742 | +! This program is free software; you can redistribute it and/or modify | |
13743 | +! it under the terms of the GNU General Public License as published by | |
13744 | +! the Free Software Foundation; either version 3 of the License, or | |
13745 | +! (at your option) any later version. | |
13746 | +! | |
13747 | +! This program is distributed in the hope that it will be useful, | |
13748 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13749 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13750 | +! GNU General Public License for more details. | |
13751 | +! | |
13752 | +! You should have received a copy of the GNU General Public License | |
13753 | +! along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13754 | + | |
13755 | +program test | |
13756 | + integer, target :: a (4, 3) | |
13757 | + integer, allocatable :: alloc (:, :) | |
13758 | + integer, pointer :: ptr (:, :) | |
13759 | + do 1 i = 1, 4 | |
13760 | + do 1 j = 1, 3 | |
13761 | + a (i, j) = j * 10 + i | |
13762 | +1 continue | |
13763 | + allocate (alloc (4, 3)) | |
13764 | + alloc = a | |
13765 | + ptr => a | |
13766 | + write (*,*) a ! break-static | |
13767 | +end | |
f412e1b4 PS |
13768 | diff --git a/gdb/testsuite/gdb.gdb/selftest.exp b/gdb/testsuite/gdb.gdb/selftest.exp |
13769 | index 21798bc..111f692 100644 | |
13770 | --- a/gdb/testsuite/gdb.gdb/selftest.exp | |
13771 | +++ b/gdb/testsuite/gdb.gdb/selftest.exp | |
13772 | @@ -88,6 +88,10 @@ proc do_steps_and_nexts {} { | |
51a5ef0f PS |
13773 | set description "step over ttyarg initialization" |
13774 | set command "step" | |
13775 | } | |
13776 | + -re ".*python_script = 0.*$gdb_prompt $" { | |
13777 | + set description "step over python_script initialization" | |
13778 | + set command "step" | |
13779 | + } | |
13780 | -re ".*pre_stat_chain = make_command_stats_cleanup.*$gdb_prompt $" { | |
13781 | set description "next over make_command_stats_cleanup and everything it calls" | |
13782 | set command "next" | |
f412e1b4 PS |
13783 | diff --git a/gdb/testsuite/gdb.mi/mi2-var-stale-type.c b/gdb/testsuite/gdb.mi/mi2-var-stale-type.c |
13784 | new file mode 100644 | |
13785 | index 0000000..ebced3c | |
13786 | --- /dev/null | |
13787 | +++ b/gdb/testsuite/gdb.mi/mi2-var-stale-type.c | |
6ed6bacf AM |
13788 | @@ -0,0 +1,26 @@ |
13789 | +/* Copyright 2011 Free Software Foundation, Inc. | |
13790 | + | |
13791 | + This file is part of GDB. | |
13792 | + | |
13793 | + This program is free software; you can redistribute it and/or modify | |
13794 | + it under the terms of the GNU General Public License as published by | |
13795 | + the Free Software Foundation; either version 3 of the License, or | |
13796 | + (at your option) any later version. | |
13797 | + | |
13798 | + This program is distributed in the hope that it will be useful, | |
13799 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13800 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13801 | + GNU General Public License for more details. | |
13802 | + | |
13803 | + You should have received a copy of the GNU General Public License | |
13804 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
13805 | + | |
13806 | +int | |
13807 | +main (int argc, char **argv) | |
13808 | +{ | |
13809 | + char vla[argc]; | |
7566401a | 13810 | + |
6ed6bacf AM |
13811 | + vla[0] = 0; /* break-here */ |
13812 | + | |
13813 | + return 0; | |
13814 | +} | |
f412e1b4 PS |
13815 | diff --git a/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp b/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp |
13816 | new file mode 100644 | |
13817 | index 0000000..74a104e | |
13818 | --- /dev/null | |
13819 | +++ b/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp | |
6ed6bacf AM |
13820 | @@ -0,0 +1,57 @@ |
13821 | +# Copyright 2011 Free Software Foundation, Inc. | |
13822 | +# | |
51a5ef0f PS |
13823 | +# This program is free software; you can redistribute it and/or modify |
13824 | +# it under the terms of the GNU General Public License as published by | |
13825 | +# the Free Software Foundation; either version 3 of the License, or | |
13826 | +# (at your option) any later version. | |
13827 | +# | |
13828 | +# This program is distributed in the hope that it will be useful, | |
13829 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13830 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13831 | +# GNU General Public License for more details. | |
13832 | +# | |
13833 | +# You should have received a copy of the GNU General Public License | |
13834 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 13835 | + |
6ed6bacf AM |
13836 | +load_lib mi-support.exp |
13837 | +set MIFLAGS "-i=mi2" | |
7566401a | 13838 | + |
6ed6bacf AM |
13839 | +gdb_exit |
13840 | +if [mi_gdb_start] { | |
13841 | + continue | |
13842 | +} | |
7566401a | 13843 | + |
6ed6bacf AM |
13844 | +set testfile "mi2-var-stale-type" |
13845 | +set srcfile ${testfile}.c | |
51a5ef0f | 13846 | +set binfile ${objdir}/${subdir}/${testfile} |
6ed6bacf | 13847 | +if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} { |
51a5ef0f PS |
13848 | + return -1 |
13849 | +} | |
7566401a | 13850 | + |
6ed6bacf AM |
13851 | +mi_delete_breakpoints |
13852 | +mi_gdb_reinitialize_dir $srcdir/$subdir | |
13853 | +mi_gdb_load ${binfile} | |
7566401a | 13854 | + |
6ed6bacf AM |
13855 | +mi_gdb_test {-interpreter-exec console "maintenance set internal-error quit yes"} \ |
13856 | + {\^done} \ | |
13857 | + "maintenance set internal-error quit yes" | |
7566401a | 13858 | + |
6ed6bacf AM |
13859 | +mi_gdb_test {-interpreter-exec console "maintenance set internal-error corefile yes"} \ |
13860 | + {\^done} \ | |
13861 | + "maintenance set internal-error corefile yes" | |
7566401a | 13862 | + |
6ed6bacf AM |
13863 | +set line [gdb_get_line_number "break-here"] |
13864 | +set func "main" | |
7566401a | 13865 | + |
6ed6bacf AM |
13866 | +mi_gdb_test "-break-insert -t $srcfile:$line" \ |
13867 | + "\\^done,bkpt=\{number=\"\[0-9\]+\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"$func\(\\\(.*\\\)\)?\",file=\".*\",line=\"$line\",times=\"0\",original-location=\".*\"\}" \ | |
13868 | + "breakpoint at $func" | |
13869 | + | |
13870 | +if { [mi_run_cmd] < 0 } { | |
51a5ef0f PS |
13871 | + return -1 |
13872 | +} | |
6ed6bacf | 13873 | +mi_expect_stop "breakpoint-hit" $func ".*" ".*" "\[0-9\]+" { "" "disp=\"del\"" } "stop after initializing vla" |
3a58abaf | 13874 | + |
6ed6bacf | 13875 | +mi_create_varobj "vla" "vla" "create local variable vla" |
3a58abaf | 13876 | + |
6ed6bacf | 13877 | +mi_gdb_test "-var-update *" "\\^done,changelist=.*" "-var-update *" |
f412e1b4 PS |
13878 | diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi.c b/gdb/testsuite/gdb.multi/watchpoint-multi.c |
13879 | new file mode 100644 | |
13880 | index 0000000..51697b0 | |
13881 | --- /dev/null | |
13882 | +++ b/gdb/testsuite/gdb.multi/watchpoint-multi.c | |
13883 | @@ -0,0 +1,51 @@ | |
51a5ef0f | 13884 | +/* This testcase is part of GDB, the GNU debugger. |
7566401a | 13885 | + |
f412e1b4 | 13886 | + Copyright 2012 Free Software Foundation, Inc. |
7566401a | 13887 | + |
51a5ef0f PS |
13888 | + This program is free software; you can redistribute it and/or modify |
13889 | + it under the terms of the GNU General Public License as published by | |
13890 | + the Free Software Foundation; either version 3 of the License, or | |
13891 | + (at your option) any later version. | |
7566401a | 13892 | + |
51a5ef0f PS |
13893 | + This program is distributed in the hope that it will be useful, |
13894 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13895 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13896 | + GNU General Public License for more details. | |
7566401a | 13897 | + |
51a5ef0f | 13898 | + You should have received a copy of the GNU General Public License |
6ed6bacf AM |
13899 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
13900 | + | |
13901 | +#include <pthread.h> | |
13902 | +#include <assert.h> | |
7566401a | 13903 | + |
6ed6bacf AM |
13904 | +static volatile int a, b, c; |
13905 | + | |
13906 | +static void | |
f412e1b4 | 13907 | +marker_exit (void) |
6ed6bacf AM |
13908 | +{ |
13909 | + a = 1; | |
13910 | +} | |
13911 | + | |
13912 | +static void * | |
13913 | +start (void *arg) | |
13914 | +{ | |
13915 | + b = 2; | |
13916 | + c = 3; | |
13917 | + | |
13918 | + return NULL; | |
13919 | +} | |
13920 | + | |
13921 | +int | |
13922 | +main (void) | |
13923 | +{ | |
13924 | + pthread_t thread; | |
13925 | + int i; | |
13926 | + | |
13927 | + i = pthread_create (&thread, NULL, start, NULL); | |
13928 | + assert (i == 0); | |
13929 | + i = pthread_join (thread, NULL); | |
13930 | + assert (i == 0); | |
13931 | + | |
f412e1b4 | 13932 | + marker_exit (); |
6ed6bacf AM |
13933 | + return 0; |
13934 | +} | |
f412e1b4 PS |
13935 | diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi.exp b/gdb/testsuite/gdb.multi/watchpoint-multi.exp |
13936 | new file mode 100644 | |
13937 | index 0000000..d7daeec | |
13938 | --- /dev/null | |
13939 | +++ b/gdb/testsuite/gdb.multi/watchpoint-multi.exp | |
13940 | @@ -0,0 +1,92 @@ | |
13941 | +# Copyright 2012 Free Software Foundation, Inc. | |
13942 | +# | |
6ed6bacf AM |
13943 | +# This program is free software; you can redistribute it and/or modify |
13944 | +# it under the terms of the GNU General Public License as published by | |
13945 | +# the Free Software Foundation; either version 3 of the License, or | |
13946 | +# (at your option) any later version. | |
13947 | +# | |
13948 | +# This program is distributed in the hope that it will be useful, | |
13949 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13950 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13951 | +# GNU General Public License for more details. | |
13952 | +# | |
13953 | +# You should have received a copy of the GNU General Public License | |
13954 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13955 | + | |
f412e1b4 PS |
13956 | +if [is_remote target] { |
13957 | + # It is KFAIL. | |
6ed6bacf AM |
13958 | + continue |
13959 | +} | |
13960 | + | |
13961 | +set testfile "watchpoint-multi" | |
13962 | + | |
13963 | +set executable ${testfile} | |
13964 | +set srcfile ${testfile}.c | |
13965 | +set binfile ${objdir}/${subdir}/${executable} | |
13966 | + | |
13967 | +if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
13968 | + untested ${testfile}.exp | |
13969 | + return -1 | |
13970 | +} | |
13971 | + | |
13972 | +clean_restart $executable | |
13973 | + | |
13974 | +if ![runto_main] { | |
13975 | + return | |
13976 | +} | |
13977 | +# Never keep/use any non-hw breakpoints to workaround a multi-inferior bug. | |
13978 | +delete_breakpoints | |
13979 | + | |
13980 | +gdb_test "add-inferior" "Added inferior 2" | |
13981 | +gdb_test "inferior 2" "witching to inferior 2 .*" | |
13982 | +gdb_load $binfile | |
13983 | + | |
13984 | +if ![runto_main] { | |
13985 | + return | |
13986 | +} | |
13987 | +delete_breakpoints | |
13988 | + | |
13989 | +# Simulate non-stop+target-async which also uses breakpoint always-inserted. | |
13990 | +gdb_test_no_output "set breakpoint always-inserted on" | |
13991 | +# displaced-stepping is also needed as other GDB sometimes still removes the | |
13992 | +# breakpoints, even with always-inserted on. | |
13993 | +gdb_test_no_output "set displaced-stepping on" | |
13994 | + | |
13995 | +# Debugging of this testcase: | |
13996 | +#gdb_test_no_output "maintenance set show-debug-regs on" | |
13997 | +#gdb_test_no_output "set debug infrun 1" | |
13998 | + | |
13999 | +# Do not use simple hardware watchpoint ("watch") as its false hit may be | |
14000 | +# unnoticed by GDB if it reads it still has the same value. | |
14001 | +gdb_test "awatch c" "Hardware access \\(read/write\\) watchpoint \[0-9\]+: c" | |
f412e1b4 PS |
14002 | + |
14003 | +gdb_breakpoint "marker_exit" | |
14004 | + | |
14005 | +gdb_test "inferior 1" "witching to inferior 1 .*" | |
14006 | + | |
14007 | +set have_awatch_b 0 | |
14008 | +set test "awatch b" | |
6ed6bacf | 14009 | +gdb_test_multiple $test $test { |
f412e1b4 | 14010 | + -re "Hardware access \\(read/write\\) watchpoint \[0-9\]+: b\r\n$gdb_prompt $" { |
6ed6bacf | 14011 | + pass $test |
f412e1b4 | 14012 | + set have_awatch_b 1 |
6ed6bacf | 14013 | + } |
f412e1b4 PS |
14014 | + -re "There are not enough available hardware resources for this watchpoint\\.\r\n$gdb_prompt $" { |
14015 | + untested $test | |
6ed6bacf AM |
14016 | + return |
14017 | + } | |
14018 | +} | |
14019 | + | |
6ed6bacf AM |
14020 | +gdb_test "inferior 2" "witching to inferior 2 .*" |
14021 | + | |
14022 | +# FAIL would be a hit on watchpoint for `b' - that one is for the other | |
14023 | +# inferior. | |
14024 | +gdb_test "continue" "Hardware access \\(read/write\\) watchpoint \[0-9\]+: c\r\n\r\nOld value = 0\r\nNew value = 3\r\n.*" "catch c" | |
14025 | + | |
f412e1b4 | 14026 | +gdb_test "continue" "Breakpoint \[0-9\]+, marker_exit .*" "catch marker_exit in inferior 2" |
6ed6bacf AM |
14027 | + |
14028 | +gdb_test "inferior 1" "witching to inferior 1 .*" | |
14029 | + | |
14030 | +gdb_test "continue" "Hardware access \\(read/write\\) watchpoint \[0-9\]+: b\r\n\r\nOld value = 0\r\nNew value = 2\r\n.*" "catch b" | |
14031 | + | |
f412e1b4 PS |
14032 | +gdb_test "continue" "Breakpoint \[0-9\]+, marker_exit .*" "catch marker_exit in inferior 1" |
14033 | diff --git a/gdb/testsuite/gdb.opt/array-from-register-func.c b/gdb/testsuite/gdb.opt/array-from-register-func.c | |
14034 | new file mode 100644 | |
14035 | index 0000000..729f457 | |
14036 | --- /dev/null | |
14037 | +++ b/gdb/testsuite/gdb.opt/array-from-register-func.c | |
51a5ef0f PS |
14038 | @@ -0,0 +1,22 @@ |
14039 | +/* This file is part of GDB, the GNU debugger. | |
7566401a | 14040 | + |
51a5ef0f | 14041 | + Copyright 2009 Free Software Foundation, Inc. |
7566401a | 14042 | + |
51a5ef0f PS |
14043 | + This program is free software; you can redistribute it and/or modify |
14044 | + it under the terms of the GNU General Public License as published by | |
14045 | + the Free Software Foundation; either version 3 of the License, or | |
14046 | + (at your option) any later version. | |
7566401a | 14047 | + |
51a5ef0f PS |
14048 | + This program is distributed in the hope that it will be useful, |
14049 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14050 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14051 | + GNU General Public License for more details. | |
7566401a | 14052 | + |
51a5ef0f PS |
14053 | + You should have received a copy of the GNU General Public License |
14054 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
14055 | + | |
14056 | +int | |
14057 | +func (int *arr) | |
14058 | +{ | |
14059 | + return arr[0]; | |
3a58abaf | 14060 | +} |
f412e1b4 PS |
14061 | diff --git a/gdb/testsuite/gdb.opt/array-from-register.c b/gdb/testsuite/gdb.opt/array-from-register.c |
14062 | new file mode 100644 | |
14063 | index 0000000..3090e7e | |
14064 | --- /dev/null | |
14065 | +++ b/gdb/testsuite/gdb.opt/array-from-register.c | |
51a5ef0f PS |
14066 | @@ -0,0 +1,28 @@ |
14067 | +/* This file is part of GDB, the GNU debugger. | |
7566401a | 14068 | + |
51a5ef0f | 14069 | + Copyright 2009 Free Software Foundation, Inc. |
7566401a ER |
14070 | + |
14071 | + This program is free software; you can redistribute it and/or modify | |
14072 | + it under the terms of the GNU General Public License as published by | |
51a5ef0f | 14073 | + the Free Software Foundation; either version 3 of the License, or |
7566401a ER |
14074 | + (at your option) any later version. |
14075 | + | |
14076 | + This program is distributed in the hope that it will be useful, | |
14077 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14078 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14079 | + GNU General Public License for more details. | |
14080 | + | |
14081 | + You should have received a copy of the GNU General Public License | |
51a5ef0f | 14082 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
7566401a | 14083 | + |
51a5ef0f | 14084 | +extern int func (int *arr); |
3a58abaf | 14085 | + |
51a5ef0f PS |
14086 | +int |
14087 | +main (void) | |
3a58abaf | 14088 | +{ |
51a5ef0f PS |
14089 | + int arr[] = { 42 }; |
14090 | + | |
14091 | + func (arr); | |
14092 | + | |
14093 | + return 0; | |
3a58abaf | 14094 | +} |
f412e1b4 PS |
14095 | diff --git a/gdb/testsuite/gdb.opt/array-from-register.exp b/gdb/testsuite/gdb.opt/array-from-register.exp |
14096 | new file mode 100644 | |
14097 | index 0000000..f2de718 | |
14098 | --- /dev/null | |
14099 | +++ b/gdb/testsuite/gdb.opt/array-from-register.exp | |
51a5ef0f PS |
14100 | @@ -0,0 +1,33 @@ |
14101 | +# Copyright 2009 Free Software Foundation, Inc. | |
14102 | +# | |
14103 | +# This program is free software; you can redistribute it and/or modify | |
14104 | +# it under the terms of the GNU General Public License as published by | |
14105 | +# the Free Software Foundation; either version 2 of the License, or | |
14106 | +# (at your option) any later version. | |
14107 | +# | |
14108 | +# This program is distributed in the hope that it will be useful, | |
14109 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14110 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14111 | +# GNU General Public License for more details. | |
14112 | +# | |
14113 | +# You should have received a copy of the GNU General Public License | |
14114 | +# along with this program; if not, write to the Free Software | |
14115 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
14116 | +# | |
14117 | +# This file is part of the gdb testsuite. | |
3a58abaf | 14118 | + |
51a5ef0f PS |
14119 | +if { [prepare_for_testing array-from-register.exp "array-from-register" \ |
14120 | + {array-from-register.c array-from-register-func.c} \ | |
14121 | + {debug optimize=-O2}] } { | |
14122 | + return -1 | |
14123 | +} | |
7566401a | 14124 | + |
51a5ef0f PS |
14125 | +if ![runto func] then { |
14126 | + return -1 | |
14127 | +} | |
7566401a | 14128 | + |
51a5ef0f | 14129 | +gdb_test "p arr" "\\$\[0-9\]+ = \\(int \\*\\) *0x\[0-9a-f\]+" |
7566401a | 14130 | + |
51a5ef0f PS |
14131 | +# Seen regression: |
14132 | +# Address requested for identifier "arr" which is in register $rdi | |
14133 | +gdb_test "p arr\[0\]" "\\$\[0-9\]+ = 42" | |
f412e1b4 PS |
14134 | diff --git a/gdb/testsuite/gdb.pascal/arrays.exp b/gdb/testsuite/gdb.pascal/arrays.exp |
14135 | new file mode 100644 | |
14136 | index 0000000..ccc6e1e | |
14137 | --- /dev/null | |
14138 | +++ b/gdb/testsuite/gdb.pascal/arrays.exp | |
51a5ef0f | 14139 | @@ -0,0 +1,104 @@ |
7566401a | 14140 | +# Copyright 2008, 2009 Free Software Foundation, Inc. |
51a5ef0f | 14141 | +# |
7566401a ER |
14142 | +# This program is free software; you can redistribute it and/or modify |
14143 | +# it under the terms of the GNU General Public License as published by | |
14144 | +# the Free Software Foundation; either version 3 of the License, or | |
14145 | +# (at your option) any later version. | |
14146 | +# | |
14147 | +# This program is distributed in the hope that it will be useful, | |
14148 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14149 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14150 | +# GNU General Public License for more details. | |
14151 | +# | |
14152 | +# You should have received a copy of the GNU General Public License | |
14153 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
14154 | + | |
51a5ef0f PS |
14155 | +if $tracelevel then { |
14156 | + strace $tracelevel | |
14157 | +} | |
7566401a | 14158 | + |
51a5ef0f | 14159 | +load_lib "pascal.exp" |
3a58abaf | 14160 | + |
51a5ef0f PS |
14161 | +set testfile "arrays" |
14162 | +set srcfile ${testfile}.pas | |
14163 | +set binfile ${objdir}/${subdir}/${testfile}$EXEEXT | |
3a58abaf | 14164 | + |
51a5ef0f PS |
14165 | +# These tests only work with fpc, using the -gw3 compile-option |
14166 | +pascal_init | |
14167 | +if { $pascal_compiler_is_fpc != 1 } { | |
14168 | + return -1 | |
14169 | +} | |
3a58abaf | 14170 | + |
51a5ef0f PS |
14171 | +# Detect if the fpc version is below 2.3.0 |
14172 | +set fpc_generates_dwarf_for_dynamic_arrays 1 | |
14173 | +if { ($fpcversion_major < 2) || ( ($fpcversion_major == 2) && ($fpcversion_minor < 3))} { | |
14174 | + set fpc_generates_dwarf_for_dynamic_arrays 0 | |
14175 | +} | |
7566401a | 14176 | + |
7566401a | 14177 | + |
51a5ef0f PS |
14178 | +if {[gdb_compile_pascal "-gw3 ${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug ]] != "" } { |
14179 | + return -1 | |
14180 | +} | |
7566401a | 14181 | + |
51a5ef0f PS |
14182 | +gdb_exit |
14183 | +gdb_start | |
14184 | +gdb_reinitialize_dir $srcdir/$subdir | |
14185 | +gdb_load ${binfile} | |
14186 | +set bp_location1 [gdb_get_line_number "set breakpoint 1 here"] | |
14187 | +set bp_location2 [gdb_get_line_number "set breakpoint 2 here"] | |
7566401a | 14188 | + |
3a58abaf | 14189 | + |
51a5ef0f PS |
14190 | +if { [gdb_breakpoint ${srcfile}:${bp_location1}] } { |
14191 | + pass "setting breakpoint 1" | |
14192 | +} | |
14193 | +if { [gdb_breakpoint ${srcfile}:${bp_location2}] } { | |
14194 | + pass "setting breakpoint 2" | |
14195 | +} | |
3a58abaf | 14196 | + |
51a5ef0f PS |
14197 | +# Verify that "start" lands inside the right procedure. |
14198 | +if { [gdb_start_cmd] < 0 } { | |
14199 | + untested start | |
14200 | + return -1 | |
14201 | +} | |
3a58abaf | 14202 | + |
51a5ef0f | 14203 | +gdb_test "" ".* at .*${srcfile}.*" "start" |
3a58abaf | 14204 | + |
51a5ef0f | 14205 | +gdb_test "cont" "Breakpoint .*:${bp_location1}.*" "Going to first breakpoint" |
3a58abaf | 14206 | + |
51a5ef0f PS |
14207 | +gdb_test "print StatArrInt" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61\\}" "Print static array of integer type" |
14208 | +gdb_test "print StatArrInt_" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61\\}" "Print static array of integer" | |
7566401a | 14209 | + |
51a5ef0f | 14210 | +gdb_test "cont" "Breakpoint .*:${bp_location2}.*" "Going to second breakpoint" |
7566401a | 14211 | + |
51a5ef0f PS |
14212 | +gdb_test "print StatArrChar" ".* = 'abcdefghijkl'" "Print static array of char" |
14213 | +gdb_test "print Stat2dArrInt" ".* = \\{\\{0, 1, 2, 3, 4\\}, \\{1, 2, 3, 4, 5\\}, \\{2, 3, 4, 5, 6\\}, \\{3, 4, 5, 6, 7\\}, \\{4, 5, 6, 7, 8\\}, \\{5, 6, 7, 8, 9\\}, \\{6, 7, 8, 9, 10\\}, \\{7, 8, 9, 10, 11\\}, \\{8, 9, 10, 11, 12\\}, \\{9, 10, 11, 12, 13\\}, \\{10, 11, 12, 13, 14\\}, \\{11, 12, 13, 14, 15\\}\\}" "Print static 2-dimensional array of integer" | |
3a58abaf | 14214 | + |
51a5ef0f PS |
14215 | +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { |
14216 | + setup_xfail "*-*-*" | |
14217 | +} | |
14218 | +gdb_test "print DynArrInt" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62\\}" "Print dynamic array of integer type" | |
14219 | +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { | |
14220 | + setup_xfail "*-*-*" | |
14221 | +} | |
14222 | +gdb_test "print DynArrInt_" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62\\}" "Print dynamic array of integer" | |
3a58abaf | 14223 | + |
51a5ef0f PS |
14224 | +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { |
14225 | + setup_xfail "*-*-*" | |
14226 | +} | |
14227 | +gdb_test "print s" ".* = 'test'#0'string'" "Print string containing null-char" | |
3a58abaf | 14228 | + |
51a5ef0f PS |
14229 | +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { |
14230 | + setup_xfail "*-*-*" | |
14231 | +} | |
14232 | +gdb_test "print DynArrStr" ".* = \\{'dstr0', 'dstr1', 'dstr2', 'dstr3', 'dstr4', 'dstr5', 'dstr6', 'dstr7', 'dstr8', 'dstr9', 'dstr10', 'dstr11', 'dstr12'\\}" "Print dynamic array of string" | |
3a58abaf | 14233 | + |
51a5ef0f PS |
14234 | +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { |
14235 | + setup_xfail "*-*-*" | |
14236 | +} | |
14237 | +gdb_test "print StatArrStr" ".* = \\{'str0', 'str1', 'str2', 'str3', 'str4', 'str5', 'str6', 'str7', 'str8', 'str9', 'str10', 'str11', 'str12'\\}" "Print static array of string" | |
3a58abaf | 14238 | + |
51a5ef0f PS |
14239 | +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { |
14240 | + setup_xfail "*-*-*" | |
14241 | +} | |
14242 | +gdb_test "print DynArrChar" ".* = 'abcdefghijklm'" "Print dynamic array of char" | |
14243 | + | |
f412e1b4 PS |
14244 | diff --git a/gdb/testsuite/gdb.pascal/arrays.pas b/gdb/testsuite/gdb.pascal/arrays.pas |
14245 | new file mode 100644 | |
14246 | index 0000000..295602d | |
14247 | --- /dev/null | |
14248 | +++ b/gdb/testsuite/gdb.pascal/arrays.pas | |
51a5ef0f PS |
14249 | @@ -0,0 +1,82 @@ |
14250 | +{ | |
14251 | + Copyright 2008, 2009 Free Software Foundation, Inc. | |
3a58abaf | 14252 | + |
51a5ef0f PS |
14253 | + This program is free software; you can redistribute it and/or modify |
14254 | + it under the terms of the GNU General Public License as published by | |
14255 | + the Free Software Foundation; either version 3 of the License, or | |
14256 | + (at your option) any later version. | |
3a58abaf | 14257 | + |
51a5ef0f PS |
14258 | + This program is distributed in the hope that it will be useful, |
14259 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14260 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14261 | + GNU General Public License for more details. | |
3a58abaf | 14262 | + |
51a5ef0f PS |
14263 | + You should have received a copy of the GNU General Public License |
14264 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
7566401a | 14265 | +} |
3a58abaf | 14266 | + |
51a5ef0f | 14267 | +program arrays; |
3a58abaf | 14268 | + |
51a5ef0f PS |
14269 | +{$mode objfpc}{$h+} |
14270 | + | |
14271 | +uses sysutils; | |
14272 | + | |
14273 | +type TStatArrInt= array[0..11] of integer; | |
14274 | + TDynArrInt= array of integer; | |
14275 | + TStatArrStr= array[0..12] of string; | |
14276 | + TDynArrStr= array of string; | |
14277 | + TDynArrChar = array of char; | |
14278 | + TStatArrChar = array [0..11] of char; | |
14279 | + | |
14280 | + TStat2dArrInt = array[0..11,0..4] of integer; | |
14281 | + | |
14282 | +var StatArrInt: TStatArrInt; | |
14283 | + StatArrInt_: Array[0..11] of integer; | |
14284 | + DynArrInt: TDynArrInt; | |
14285 | + DynArrInt_: Array of integer; | |
14286 | + StatArrStr: TStatArrStr; | |
14287 | + DynArrStr: TDynArrStr; | |
14288 | + StatArrChar: TStatArrChar; | |
14289 | + DynArrChar: TDynArrChar; | |
14290 | + | |
14291 | + Stat2dArrInt: TStat2dArrInt; | |
14292 | + | |
14293 | + s: string; | |
14294 | + | |
14295 | + i,j : integer; | |
14296 | + | |
14297 | +begin | |
14298 | + for i := 0 to 11 do | |
14299 | + begin | |
14300 | + StatArrInt[i]:= i+50; | |
14301 | + StatArrInt_[i]:= i+50; | |
14302 | + StatArrChar[i]:= chr(ord('a')+i); | |
14303 | + for j := 0 to 4 do | |
14304 | + Stat2dArrInt[i,j]:=i+j; | |
14305 | + end; | |
14306 | + writeln(StatArrInt_[0]); | |
14307 | + writeln(StatArrInt[0]); { set breakpoint 1 here } | |
14308 | + writeln(StatArrChar[0]); | |
14309 | + writeln(Stat2dArrInt[0,0]); | |
14310 | + | |
14311 | + setlength(DynArrInt,13); | |
14312 | + setlength(DynArrInt_,13); | |
14313 | + setlength(DynArrStr,13); | |
14314 | + setlength(DynArrChar,13); | |
14315 | + for i := 0 to 12 do | |
14316 | + begin | |
14317 | + DynArrInt[i]:= i+50; | |
14318 | + DynArrInt_[i]:= i+50; | |
14319 | + DynArrChar[i]:= chr(ord('a')+i); | |
14320 | + StatArrStr[i]:='str'+inttostr(i); | |
14321 | + DynArrStr[i]:='dstr'+inttostr(i); | |
14322 | + end; | |
14323 | + writeln(DynArrInt_[1]); | |
14324 | + writeln(DynArrInt[1]); | |
14325 | + writeln(DynArrStr[1]); | |
14326 | + writeln(StatArrStr[1]); | |
14327 | + writeln(DynArrChar[1]); | |
14328 | + | |
14329 | + s := 'test'#0'string'; | |
14330 | + writeln(s); { set breakpoint 2 here } | |
14331 | +end. | |
f412e1b4 PS |
14332 | diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp |
14333 | index 83ff8fe..bddbf9f 100644 | |
14334 | --- a/gdb/testsuite/gdb.python/py-frame.exp | |
14335 | +++ b/gdb/testsuite/gdb.python/py-frame.exp | |
14336 | @@ -74,8 +74,6 @@ gdb_test "python print bframe == gdb.newest_frame()" True \ | |
51a5ef0f PS |
14337 | |
14338 | gdb_test "python print 'result =', f0 == f1" " = False" "test equality comparison (false)" | |
14339 | gdb_test "python print 'result =', f0 == f0" " = True" "test equality comparison (true)" | |
14340 | -gdb_test "python print 'result =', f0 != f1" " = True" "test inequality comparison (true)" | |
14341 | -gdb_test "python print 'result =', f0 != f0" " = False" "test inequality comparison (false)" | |
14342 | gdb_test "python print 'result =', f0.is_valid ()" " = True" "test Frame.is_valid" | |
14343 | gdb_test "python print 'result =', f0.name ()" " = f2" "test Frame.name" | |
14344 | gdb_test "python print 'result =', f0.type () == gdb.NORMAL_FRAME" " = True" "test Frame.type" | |
f412e1b4 | 14345 | @@ -90,3 +88,5 @@ gdb_test "python print 'result =', f0.read_var ('variable_which_surely_doesnt_ex |
51a5ef0f PS |
14346 | gdb_test "python print 'result =', f0.read_var ('a')" " = 1" "test Frame.read_var - success" |
14347 | ||
14348 | gdb_test "python print 'result =', gdb.selected_frame () == f1" " = True" "test gdb.selected_frame" | |
14349 | + | |
14350 | +gdb_test "python print 'result =', f0.block ()" "<gdb.Block object at 0x\[\[:xdigit:\]\]+>" "test Frame.block" | |
f412e1b4 PS |
14351 | diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp |
14352 | index c9d8c97..4324db0 100644 | |
14353 | --- a/gdb/testsuite/gdb.python/py-value.exp | |
14354 | +++ b/gdb/testsuite/gdb.python/py-value.exp | |
14355 | @@ -360,6 +360,15 @@ proc test_value_after_death {} { | |
51a5ef0f PS |
14356 | "print value's type" |
14357 | } | |
14358 | ||
14359 | +# Regression test for a cast failure. The bug was that if we cast a | |
14360 | +# value to its own type, gdb could crash. This happened because we | |
14361 | +# could end up double-freeing a struct value. | |
14362 | +proc test_cast_regression {} { | |
14363 | + gdb_test "python v = gdb.Value(5)" "" "create value for cast test" | |
14364 | + gdb_test "python v = v.cast(v.type)" "" "cast value for cast test" | |
14365 | + gdb_test "python print v" "5" "print value for cast test" | |
7566401a | 14366 | +} |
51a5ef0f PS |
14367 | + |
14368 | # Regression test for invalid subscript operations. The bug was that | |
14369 | # the type of the value was not being checked before allowing a | |
14370 | # subscript operation to proceed. | |
f412e1b4 | 14371 | @@ -496,6 +505,7 @@ test_value_in_inferior |
6ed6bacf | 14372 | test_inferior_function_call |
51a5ef0f PS |
14373 | test_lazy_strings |
14374 | test_value_after_death | |
14375 | +test_cast_regression | |
14376 | ||
f412e1b4 PS |
14377 | # Test either C or C++ values. |
14378 | test_subscript_regression "${binfile}" "c" | |
14379 | diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-child.c b/gdb/testsuite/gdb.threads/watchpoint-fork-child.c | |
14380 | new file mode 100644 | |
14381 | index 0000000..7a7e07f | |
14382 | --- /dev/null | |
14383 | +++ b/gdb/testsuite/gdb.threads/watchpoint-fork-child.c | |
14384 | @@ -0,0 +1,129 @@ | |
51a5ef0f | 14385 | +/* Test case for forgotten hw-watchpoints after fork()-off of a process. |
3a58abaf | 14386 | + |
f412e1b4 | 14387 | + Copyright 2012 Free Software Foundation, Inc. |
51a5ef0f PS |
14388 | + |
14389 | + This file is part of GDB. | |
3a58abaf | 14390 | + |
7566401a ER |
14391 | + This program is free software; you can redistribute it and/or modify |
14392 | + it under the terms of the GNU General Public License as published by | |
51a5ef0f | 14393 | + the Free Software Foundation; either version 2 of the License, or |
7566401a | 14394 | + (at your option) any later version. |
3a58abaf | 14395 | + |
7566401a ER |
14396 | + This program is distributed in the hope that it will be useful, |
14397 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14398 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14399 | + GNU General Public License for more details. | |
3a58abaf | 14400 | + |
7566401a | 14401 | + You should have received a copy of the GNU General Public License |
51a5ef0f PS |
14402 | + along with this program; if not, write to the Free Software |
14403 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
14404 | + Boston, MA 02111-1307, USA. */ | |
3a58abaf | 14405 | + |
6ed6bacf AM |
14406 | +#include <string.h> |
14407 | +#include <errno.h> | |
14408 | +#include <unistd.h> | |
14409 | +#include <assert.h> | |
14410 | +#include <signal.h> | |
14411 | +#include <stdio.h> | |
3a58abaf | 14412 | + |
6ed6bacf | 14413 | +#include "watchpoint-fork.h" |
3a58abaf | 14414 | + |
f412e1b4 PS |
14415 | +/* `pid_t' may not be available. */ |
14416 | + | |
51a5ef0f | 14417 | +static volatile int usr1_got; |
3a58abaf | 14418 | + |
51a5ef0f PS |
14419 | +static void |
14420 | +handler_usr1 (int signo) | |
14421 | +{ | |
14422 | + usr1_got++; | |
14423 | +} | |
3a58abaf | 14424 | + |
6ed6bacf | 14425 | +void |
51a5ef0f | 14426 | +forkoff (int nr) |
3a58abaf | 14427 | +{ |
f412e1b4 | 14428 | + int child, save_parent = getpid (); |
6ed6bacf | 14429 | + int i; |
51a5ef0f PS |
14430 | + struct sigaction act, oldact; |
14431 | +#ifdef THREAD | |
14432 | + void *thread_result; | |
14433 | +#endif | |
3a58abaf | 14434 | + |
51a5ef0f PS |
14435 | + memset (&act, 0, sizeof act); |
14436 | + act.sa_flags = SA_RESTART; | |
14437 | + act.sa_handler = handler_usr1; | |
14438 | + sigemptyset (&act.sa_mask); | |
14439 | + i = sigaction (SIGUSR1, &act, &oldact); | |
7566401a ER |
14440 | + assert (i == 0); |
14441 | + | |
51a5ef0f PS |
14442 | + child = fork (); |
14443 | + switch (child) | |
3a58abaf | 14444 | + { |
51a5ef0f PS |
14445 | + case -1: |
14446 | + assert (0); | |
14447 | + default: | |
14448 | + printf ("parent%d: %d\n", nr, (int) child); | |
14449 | + | |
14450 | + /* Sleep for a while to possibly get incorrectly ATTACH_THREADed by GDB | |
14451 | + tracing the child fork with no longer valid thread/lwp entries of the | |
14452 | + parent. */ | |
3a58abaf | 14453 | + |
51a5ef0f | 14454 | + i = sleep (2); |
7566401a | 14455 | + assert (i == 0); |
3a58abaf | 14456 | + |
51a5ef0f | 14457 | + /* We must not get caught here (against a forgotten breakpoint). */ |
3a58abaf | 14458 | + |
51a5ef0f | 14459 | + var++; |
6ed6bacf | 14460 | + marker (); |
3a58abaf | 14461 | + |
51a5ef0f PS |
14462 | +#ifdef THREAD |
14463 | + /* And neither got caught our thread. */ | |
3a58abaf | 14464 | + |
51a5ef0f PS |
14465 | + step = 99; |
14466 | + i = pthread_join (thread, &thread_result); | |
14467 | + assert (i == 0); | |
14468 | + assert (thread_result == (void *) 99UL); | |
14469 | +#endif | |
3a58abaf | 14470 | + |
51a5ef0f | 14471 | + /* Be sure our child knows we did not get caught above. */ |
3a58abaf | 14472 | + |
51a5ef0f PS |
14473 | + i = kill (child, SIGUSR1); |
14474 | + assert (i == 0); | |
7566401a | 14475 | + |
51a5ef0f PS |
14476 | + /* Sleep for a while to check GDB's `info threads' no longer tracks us in |
14477 | + the child fork. */ | |
7566401a | 14478 | + |
51a5ef0f PS |
14479 | + i = sleep (2); |
14480 | + assert (i == 0); | |
3a58abaf | 14481 | + |
51a5ef0f PS |
14482 | + _exit (0); |
14483 | + case 0: | |
14484 | + printf ("child%d: %d\n", nr, (int) getpid ()); | |
3a58abaf | 14485 | + |
51a5ef0f PS |
14486 | + /* Let the parent signal us about its success. Be careful of races. */ |
14487 | + | |
6ed6bacf | 14488 | + for (;;) |
51a5ef0f PS |
14489 | + { |
14490 | + /* Parent either died (and USR1_GOT is zero) or it succeeded. */ | |
6ed6bacf AM |
14491 | + if (getppid () != save_parent) |
14492 | + break; | |
51a5ef0f PS |
14493 | + if (kill (getppid (), 0) != 0) |
14494 | + break; | |
14495 | + /* Parent succeeded? */ | |
14496 | + if (usr1_got) | |
14497 | + break; | |
3a58abaf | 14498 | + |
6ed6bacf AM |
14499 | +#ifdef THREAD |
14500 | + i = pthread_yield (); | |
14501 | + assert (i == 0); | |
14502 | +#endif | |
51a5ef0f PS |
14503 | + } |
14504 | + assert (usr1_got); | |
3a58abaf | 14505 | + |
51a5ef0f | 14506 | + /* We must get caught here (against a false watchpoint removal). */ |
3a58abaf | 14507 | + |
6ed6bacf | 14508 | + marker (); |
51a5ef0f PS |
14509 | + } |
14510 | + | |
14511 | + i = sigaction (SIGUSR1, &oldact, NULL); | |
14512 | + assert (i == 0); | |
7566401a | 14513 | +} |
f412e1b4 PS |
14514 | diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c b/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c |
14515 | new file mode 100644 | |
14516 | index 0000000..bfdd89f | |
14517 | --- /dev/null | |
14518 | +++ b/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c | |
6ed6bacf | 14519 | @@ -0,0 +1,174 @@ |
51a5ef0f | 14520 | +/* Test case for forgotten hw-watchpoints after fork()-off of a process. |
3a58abaf | 14521 | + |
f412e1b4 | 14522 | + Copyright 2012 Free Software Foundation, Inc. |
3a58abaf | 14523 | + |
51a5ef0f | 14524 | + This file is part of GDB. |
3a58abaf | 14525 | + |
51a5ef0f PS |
14526 | + This program is free software; you can redistribute it and/or modify |
14527 | + it under the terms of the GNU General Public License as published by | |
14528 | + the Free Software Foundation; either version 2 of the License, or | |
14529 | + (at your option) any later version. | |
3a58abaf | 14530 | + |
51a5ef0f PS |
14531 | + This program is distributed in the hope that it will be useful, |
14532 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14533 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14534 | + GNU General Public License for more details. | |
3a58abaf | 14535 | + |
51a5ef0f PS |
14536 | + You should have received a copy of the GNU General Public License |
14537 | + along with this program; if not, write to the Free Software | |
14538 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
14539 | + Boston, MA 02111-1307, USA. */ | |
7566401a | 14540 | + |
51a5ef0f PS |
14541 | +#include <assert.h> |
14542 | +#include <unistd.h> | |
14543 | +#include <sys/wait.h> | |
14544 | +#include <stdio.h> | |
14545 | +#include <stdlib.h> | |
14546 | +#include <pthread.h> | |
7566401a | 14547 | + |
51a5ef0f PS |
14548 | +#include <asm/unistd.h> |
14549 | +#include <unistd.h> | |
14550 | +#define gettid() syscall (__NR_gettid) | |
14551 | + | |
6ed6bacf AM |
14552 | +#include "watchpoint-fork.h" |
14553 | + | |
51a5ef0f PS |
14554 | +/* Non-atomic `var++' should not hurt as we synchronize the threads by the STEP |
14555 | + variable. Hit-comments need to be duplicite there to catch both at-stops | |
14556 | + and behind-stops, depending on the target. */ | |
14557 | + | |
6ed6bacf | 14558 | +volatile int var; |
3a58abaf | 14559 | + |
6ed6bacf AM |
14560 | +void |
14561 | +marker (void) | |
7566401a | 14562 | +{ |
51a5ef0f | 14563 | +} |
3a58abaf | 14564 | + |
51a5ef0f | 14565 | +static void |
6ed6bacf | 14566 | +empty (void) |
51a5ef0f PS |
14567 | +{ |
14568 | +} | |
3a58abaf | 14569 | + |
6ed6bacf AM |
14570 | +static void |
14571 | +mark_exit (void) | |
14572 | +{ | |
14573 | +} | |
7566401a | 14574 | + |
6ed6bacf AM |
14575 | +pthread_t thread; |
14576 | +volatile int step; | |
7566401a | 14577 | + |
51a5ef0f PS |
14578 | +static void * |
14579 | +start (void *arg) | |
14580 | +{ | |
6ed6bacf AM |
14581 | + int i; |
14582 | + | |
51a5ef0f PS |
14583 | + if (step >= 3) |
14584 | + goto step_3; | |
3a58abaf | 14585 | + |
51a5ef0f | 14586 | + while (step != 1) |
6ed6bacf AM |
14587 | + { |
14588 | + i = pthread_yield (); | |
14589 | + assert (i == 0); | |
14590 | + } | |
3a58abaf | 14591 | + |
51a5ef0f | 14592 | + var++; /* validity-thread-B */ |
6ed6bacf | 14593 | + empty (); /* validity-thread-B */ |
51a5ef0f PS |
14594 | + step = 2; |
14595 | + while (step != 3) | |
14596 | + { | |
14597 | + if (step == 99) | |
14598 | + goto step_99; | |
6ed6bacf AM |
14599 | + |
14600 | + i = pthread_yield (); | |
14601 | + assert (i == 0); | |
51a5ef0f | 14602 | + } |
7566401a | 14603 | + |
51a5ef0f PS |
14604 | +step_3: |
14605 | + if (step >= 5) | |
14606 | + goto step_5; | |
3a58abaf | 14607 | + |
51a5ef0f | 14608 | + var++; /* after-fork1-B */ |
6ed6bacf | 14609 | + empty (); /* after-fork1-B */ |
51a5ef0f PS |
14610 | + step = 4; |
14611 | + while (step != 5) | |
7566401a | 14612 | + { |
51a5ef0f PS |
14613 | + if (step == 99) |
14614 | + goto step_99; | |
6ed6bacf AM |
14615 | + |
14616 | + i = pthread_yield (); | |
14617 | + assert (i == 0); | |
51a5ef0f | 14618 | + } |
3a58abaf | 14619 | + |
51a5ef0f PS |
14620 | +step_5: |
14621 | + var++; /* after-fork2-B */ | |
6ed6bacf | 14622 | + empty (); /* after-fork2-B */ |
51a5ef0f | 14623 | + return (void *) 5UL; |
3a58abaf | 14624 | + |
51a5ef0f PS |
14625 | +step_99: |
14626 | + /* We must not get caught here (against a forgotten breakpoint). */ | |
14627 | + var++; | |
6ed6bacf | 14628 | + marker (); |
51a5ef0f | 14629 | + return (void *) 99UL; |
3a58abaf AM |
14630 | +} |
14631 | + | |
7566401a | 14632 | +int |
51a5ef0f | 14633 | +main (void) |
3a58abaf | 14634 | +{ |
7566401a | 14635 | + int i; |
51a5ef0f | 14636 | + void *thread_result; |
3a58abaf | 14637 | + |
7566401a | 14638 | + setbuf (stdout, NULL); |
51a5ef0f | 14639 | + printf ("main: %d\n", (int) gettid ()); |
7566401a | 14640 | + |
6ed6bacf AM |
14641 | + /* General hardware breakpoints and watchpoints validity. */ |
14642 | + marker (); | |
51a5ef0f | 14643 | + var++; /* validity-first */ |
6ed6bacf | 14644 | + empty (); /* validity-first */ |
7566401a | 14645 | + |
51a5ef0f | 14646 | + i = pthread_create (&thread, NULL, start, NULL); |
7566401a ER |
14647 | + assert (i == 0); |
14648 | + | |
51a5ef0f | 14649 | + var++; /* validity-thread-A */ |
6ed6bacf | 14650 | + empty (); /* validity-thread-A */ |
51a5ef0f PS |
14651 | + step = 1; |
14652 | + while (step != 2) | |
6ed6bacf AM |
14653 | + { |
14654 | + i = pthread_yield (); | |
14655 | + assert (i == 0); | |
14656 | + } | |
3a58abaf | 14657 | + |
51a5ef0f PS |
14658 | + /* Hardware watchpoints got disarmed here. */ |
14659 | + forkoff (1); | |
3a58abaf | 14660 | + |
51a5ef0f | 14661 | + var++; /* after-fork1-A */ |
6ed6bacf | 14662 | + empty (); /* after-fork1-A */ |
51a5ef0f PS |
14663 | + step = 3; |
14664 | +#ifdef FOLLOW_CHILD | |
14665 | + /* Spawn new thread as it was deleted in the child of FORK. */ | |
14666 | + i = pthread_create (&thread, NULL, start, NULL); | |
7566401a | 14667 | + assert (i == 0); |
51a5ef0f PS |
14668 | +#endif |
14669 | + while (step != 4) | |
6ed6bacf AM |
14670 | + { |
14671 | + i = pthread_yield (); | |
14672 | + assert (i == 0); | |
14673 | + } | |
3a58abaf | 14674 | + |
51a5ef0f PS |
14675 | + /* A sanity check for double hardware watchpoints removal. */ |
14676 | + forkoff (2); | |
3a58abaf | 14677 | + |
51a5ef0f | 14678 | + var++; /* after-fork2-A */ |
6ed6bacf | 14679 | + empty (); /* after-fork2-A */ |
51a5ef0f PS |
14680 | + step = 5; |
14681 | +#ifdef FOLLOW_CHILD | |
14682 | + /* Spawn new thread as it was deleted in the child of FORK. */ | |
14683 | + i = pthread_create (&thread, NULL, start, NULL); | |
14684 | + assert (i == 0); | |
14685 | +#endif | |
7566401a | 14686 | + |
51a5ef0f PS |
14687 | + i = pthread_join (thread, &thread_result); |
14688 | + assert (i == 0); | |
14689 | + assert (thread_result == (void *) 5UL); | |
7566401a | 14690 | + |
6ed6bacf | 14691 | + mark_exit (); |
51a5ef0f PS |
14692 | + return 0; |
14693 | +} | |
f412e1b4 PS |
14694 | diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-parent.c b/gdb/testsuite/gdb.threads/watchpoint-fork-parent.c |
14695 | new file mode 100644 | |
14696 | index 0000000..9bbf438 | |
14697 | --- /dev/null | |
14698 | +++ b/gdb/testsuite/gdb.threads/watchpoint-fork-parent.c | |
6ed6bacf AM |
14699 | @@ -0,0 +1,74 @@ |
14700 | +/* Test case for forgotten hw-watchpoints after fork()-off of a process. | |
14701 | + | |
f412e1b4 | 14702 | + Copyright 2012 Free Software Foundation, Inc. |
6ed6bacf AM |
14703 | + |
14704 | + This file is part of GDB. | |
14705 | + | |
14706 | + This program is free software; you can redistribute it and/or modify | |
14707 | + it under the terms of the GNU General Public License as published by | |
14708 | + the Free Software Foundation; either version 2 of the License, or | |
14709 | + (at your option) any later version. | |
14710 | + | |
14711 | + This program is distributed in the hope that it will be useful, | |
14712 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14713 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14714 | + GNU General Public License for more details. | |
14715 | + | |
14716 | + You should have received a copy of the GNU General Public License | |
14717 | + along with this program; if not, write to the Free Software | |
14718 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
14719 | + Boston, MA 02111-1307, USA. */ | |
14720 | + | |
14721 | +#include <string.h> | |
14722 | +#include <errno.h> | |
14723 | +#include <sys/types.h> | |
14724 | +#include <unistd.h> | |
14725 | +#include <assert.h> | |
14726 | +#include <stdio.h> | |
14727 | +#include <sys/wait.h> | |
14728 | + | |
14729 | +#include "watchpoint-fork.h" | |
14730 | + | |
14731 | +void | |
14732 | +forkoff (int nr) | |
14733 | +{ | |
14734 | + pid_t child, pid_got; | |
14735 | + int exit_code = 42 + nr; | |
14736 | + int status, i; | |
14737 | + | |
14738 | + child = fork (); | |
14739 | + switch (child) | |
14740 | + { | |
14741 | + case -1: | |
14742 | + assert (0); | |
14743 | + case 0: | |
14744 | + printf ("child%d: %d\n", nr, (int) getpid ()); | |
14745 | + /* Delay to get both the "child%d" and "parent%d" message printed without | |
14746 | + a race breaking expect by its endless wait on `$gdb_prompt$': | |
14747 | + Breakpoint 3, marker () at ../../../gdb/testsuite/gdb.threads/watchpoint-fork.c:33 | |
14748 | + 33 } | |
14749 | + (gdb) parent2: 14223 */ | |
14750 | + i = sleep (1); | |
14751 | + assert (i == 0); | |
14752 | + | |
14753 | + /* We must not get caught here (against a forgotten breakpoint). */ | |
14754 | + var++; | |
14755 | + marker (); | |
14756 | + | |
14757 | + _exit (exit_code); | |
14758 | + default: | |
14759 | + printf ("parent%d: %d\n", nr, (int) child); | |
14760 | + /* Delay to get both the "child%d" and "parent%d" message printed, see | |
14761 | + above. */ | |
14762 | + i = sleep (1); | |
14763 | + assert (i == 0); | |
14764 | + | |
14765 | + pid_got = wait (&status); | |
14766 | + assert (pid_got == child); | |
14767 | + assert (WIFEXITED (status)); | |
14768 | + assert (WEXITSTATUS (status) == exit_code); | |
14769 | + | |
14770 | + /* We must get caught here (against a false watchpoint removal). */ | |
14771 | + marker (); | |
14772 | + } | |
14773 | +} | |
f412e1b4 PS |
14774 | diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-st.c b/gdb/testsuite/gdb.threads/watchpoint-fork-st.c |
14775 | new file mode 100644 | |
14776 | index 0000000..17cc058 | |
14777 | --- /dev/null | |
14778 | +++ b/gdb/testsuite/gdb.threads/watchpoint-fork-st.c | |
6ed6bacf | 14779 | @@ -0,0 +1,61 @@ |
51a5ef0f | 14780 | +/* Test case for forgotten hw-watchpoints after fork()-off of a process. |
3a58abaf | 14781 | + |
f412e1b4 | 14782 | + Copyright 2012 Free Software Foundation, Inc. |
7566401a | 14783 | + |
51a5ef0f | 14784 | + This file is part of GDB. |
3a58abaf | 14785 | + |
51a5ef0f PS |
14786 | + This program is free software; you can redistribute it and/or modify |
14787 | + it under the terms of the GNU General Public License as published by | |
14788 | + the Free Software Foundation; either version 2 of the License, or | |
14789 | + (at your option) any later version. | |
7566401a | 14790 | + |
51a5ef0f PS |
14791 | + This program is distributed in the hope that it will be useful, |
14792 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14793 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14794 | + GNU General Public License for more details. | |
7566401a | 14795 | + |
51a5ef0f PS |
14796 | + You should have received a copy of the GNU General Public License |
14797 | + along with this program; if not, write to the Free Software | |
14798 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
14799 | + Boston, MA 02111-1307, USA. */ | |
3a58abaf | 14800 | + |
51a5ef0f PS |
14801 | +#include <assert.h> |
14802 | +#include <unistd.h> | |
14803 | +#include <sys/wait.h> | |
14804 | +#include <stdio.h> | |
14805 | +#include <stdlib.h> | |
7566401a | 14806 | + |
6ed6bacf | 14807 | +#include "watchpoint-fork.h" |
7566401a | 14808 | + |
6ed6bacf AM |
14809 | +volatile int var; |
14810 | + | |
14811 | +void | |
14812 | +marker (void) | |
51a5ef0f PS |
14813 | +{ |
14814 | +} | |
7566401a | 14815 | + |
6ed6bacf AM |
14816 | +static void |
14817 | +mark_exit (void) | |
14818 | +{ | |
14819 | +} | |
7566401a | 14820 | + |
51a5ef0f PS |
14821 | +int |
14822 | +main (void) | |
14823 | +{ | |
14824 | + setbuf (stdout, NULL); | |
14825 | + printf ("main: %d\n", (int) getpid ()); | |
7566401a | 14826 | + |
6ed6bacf AM |
14827 | + /* General hardware breakpoints and watchpoints validity. */ |
14828 | + marker (); | |
51a5ef0f PS |
14829 | + var++; |
14830 | + /* Hardware watchpoints got disarmed here. */ | |
14831 | + forkoff (1); | |
14832 | + /* This watchpoint got lost before. */ | |
14833 | + var++; | |
14834 | + /* A sanity check for double hardware watchpoints removal. */ | |
14835 | + forkoff (2); | |
14836 | + var++; | |
7566401a | 14837 | + |
6ed6bacf | 14838 | + mark_exit (); |
51a5ef0f | 14839 | + return 0; |
7566401a | 14840 | +} |
f412e1b4 PS |
14841 | diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork.exp b/gdb/testsuite/gdb.threads/watchpoint-fork.exp |
14842 | new file mode 100644 | |
14843 | index 0000000..2e01344 | |
14844 | --- /dev/null | |
14845 | +++ b/gdb/testsuite/gdb.threads/watchpoint-fork.exp | |
6ed6bacf | 14846 | @@ -0,0 +1,149 @@ |
f412e1b4 PS |
14847 | +# Copyright 2012 Free Software Foundation, Inc. |
14848 | +# | |
7566401a ER |
14849 | +# This program is free software; you can redistribute it and/or modify |
14850 | +# it under the terms of the GNU General Public License as published by | |
14851 | +# the Free Software Foundation; either version 3 of the License, or | |
14852 | +# (at your option) any later version. | |
14853 | +# | |
14854 | +# This program is distributed in the hope that it will be useful, | |
14855 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14856 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14857 | +# GNU General Public License for more details. | |
14858 | +# | |
14859 | +# You should have received a copy of the GNU General Public License | |
14860 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
14861 | + | |
51a5ef0f | 14862 | +# Test case for forgotten hw-watchpoints after fork()-off of a process. |
7566401a | 14863 | + |
51a5ef0f | 14864 | +proc test {type symbol} { |
6ed6bacf | 14865 | + global objdir subdir srcdir gdb_prompt |
7566401a | 14866 | + |
6ed6bacf | 14867 | + set testfile watchpoint-fork |
7566401a ER |
14868 | + |
14869 | + global pf_prefix | |
14870 | + set prefix_test $pf_prefix | |
51a5ef0f PS |
14871 | + lappend pf_prefix "$type:" |
14872 | + set prefix_mt $pf_prefix | |
7566401a | 14873 | + |
6ed6bacf AM |
14874 | + set srcfile_type ${srcdir}/${subdir}/${testfile}-${type}.c |
14875 | + | |
14876 | + | |
51a5ef0f | 14877 | + # no threads |
7566401a | 14878 | + |
51a5ef0f PS |
14879 | + set pf_prefix $prefix_mt |
14880 | + lappend pf_prefix "singlethreaded:" | |
7566401a | 14881 | + |
6ed6bacf AM |
14882 | + set executable ${testfile}-${type}-st |
14883 | + set srcfile_main ${srcdir}/${subdir}/${testfile}-st.c | |
14884 | + if { [gdb_compile "${srcfile_main} ${srcfile_type}" ${objdir}/${subdir}/${executable} executable [list debug additional_flags=-D$symbol]] != "" } { | |
14885 | + untested ${testfile}.exp | |
14886 | + return | |
3a58abaf | 14887 | + } |
51a5ef0f | 14888 | + clean_restart $executable |
3a58abaf | 14889 | + |
6ed6bacf AM |
14890 | + gdb_test "show detach-on-fork" "Whether gdb will detach the child of a fork is on\\." |
14891 | + gdb_test_no_output "set follow-fork-mode $type" | |
14892 | + gdb_test "show follow-fork-mode" "Debugger response to a program call of fork or vfork is \"$type\"\\." | |
51a5ef0f | 14893 | + # Testcase uses it for the `follow-fork-mode child' type. |
6ed6bacf | 14894 | + gdb_test "handle SIGUSR1 nostop noprint pass" "No\[ \t\]+No\[ \t\]+Yes.*" |
51a5ef0f | 14895 | + |
6ed6bacf | 14896 | + if ![runto_main] { |
51a5ef0f | 14897 | + return |
7566401a | 14898 | + } |
7566401a | 14899 | + |
6ed6bacf | 14900 | + gdb_test "watch var" "atchpoint \[0-9\]+: var" "Set the watchpoint" |
51a5ef0f PS |
14901 | + |
14902 | + # It is never hit but it should not be left over in the fork()ed-off child. | |
6ed6bacf AM |
14903 | + set hbreak "hbreak" |
14904 | + set test "hbreak marker" | |
14905 | + gdb_test_multiple $test $test { | |
14906 | + -re "Hardware assisted breakpoint \[0-9\]+ at .*\r\n$gdb_prompt $" { | |
14907 | + pass $test | |
14908 | + } | |
14909 | + -re "(No hardware breakpoint support in the target\\.|Hardware breakpoints used exceeds limit\\.)\r\n$gdb_prompt $" { | |
14910 | + pass $test | |
14911 | + set hbreak "break" | |
14912 | + gdb_test "break marker" | |
14913 | + } | |
14914 | + } | |
14915 | + | |
14916 | + gdb_breakpoint "mark_exit" | |
7566401a ER |
14917 | + |
14918 | + gdb_test "continue" \ | |
6ed6bacf | 14919 | + "reakpoint \[0-9\]+, marker.*" "hardware breakpoints work" |
51a5ef0f | 14920 | + gdb_test "continue" \ |
6ed6bacf | 14921 | + "atchpoint \[0-9\]+: var.*Old value = 0.*New value = 1.*forkoff *\\(1\\).*" "watchpoints work" |
51a5ef0f | 14922 | + gdb_test "continue" \ |
6ed6bacf | 14923 | + "reakpoint \[0-9\]+, marker.*" "breakpoint after the first fork" |
51a5ef0f | 14924 | + gdb_test "continue" \ |
6ed6bacf | 14925 | + "atchpoint \[0-9\]+: var.*Old value = 1.*New value = 2.*forkoff *\\(2\\).*" "watchpoint after the first fork" |
51a5ef0f | 14926 | + gdb_test "continue" \ |
6ed6bacf AM |
14927 | + "reakpoint \[0-9\]+, marker.*" "breakpoint after the second fork" |
14928 | + gdb_test "continue" \ | |
14929 | + "atchpoint \[0-9\]+: var.*Old value = 2.*New value = 3.*mark_exit \\(\\);" "watchpoint after the second fork" | |
14930 | + gdb_test "continue" "Continuing\\..*\r\nBreakpoint \[0-9\]+, mark_exit .*" "finish" | |
14931 | + | |
14932 | + | |
14933 | + # threads | |
14934 | + | |
14935 | + set pf_prefix $prefix_mt | |
14936 | + lappend pf_prefix "multithreaded:" | |
14937 | + | |
14938 | + set executable ${testfile}-${type}-mt | |
14939 | + set srcfile_main ${srcdir}/${subdir}/${testfile}-mt.c | |
14940 | + if { [gdb_compile_pthreads "${srcfile_main} ${srcfile_type}" ${objdir}/${subdir}/${executable} executable [list debug "additional_flags=-D$symbol -DTHREAD"]] != "" } { | |
14941 | + untested ${testfile}.exp | |
14942 | + return | |
14943 | + } | |
14944 | + clean_restart $executable | |
14945 | + | |
14946 | + gdb_test_no_output "set follow-fork-mode $type" | |
14947 | + # Testcase uses it for the `follow-fork-mode child' type. | |
14948 | + gdb_test "handle SIGUSR1 nostop noprint pass" "No\[ \t\]+No\[ \t\]+Yes.*" | |
14949 | + | |
14950 | + if ![runto_main] { | |
14951 | + return | |
14952 | + } | |
14953 | + | |
14954 | + gdb_test "watch var" "atchpoint \[0-9\]+: var" "Set the watchpoint" | |
14955 | + | |
14956 | + # It should not be left over in the fork()ed-off child. | |
14957 | + gdb_test "$hbreak marker" {reakpoint [0-9]+.*} | |
14958 | + | |
14959 | + gdb_breakpoint "mark_exit" | |
14960 | + | |
14961 | + gdb_test "continue" \ | |
14962 | + "reakpoint \[0-9\]+, marker.*" "hardware breakpoints work" | |
14963 | + gdb_test "continue" \ | |
14964 | + "atchpoint \[0-9\]+: var.*Old value = 0.*New value = 1.*validity-first.*" "singlethread watchpoints work" | |
14965 | + gdb_test "continue" \ | |
14966 | + "atchpoint \[0-9\]+: var.*Old value = 1.*New value = 2.*validity-thread-A.*" "multithreaded watchpoints work at A" | |
14967 | + gdb_test "continue" \ | |
14968 | + "atchpoint \[0-9\]+: var.*Old value = 2.*New value = 3.*validity-thread-B.*" "multithreaded watchpoints work at B" | |
14969 | + gdb_test "continue" \ | |
14970 | + "reakpoint \[0-9\]+, marker.*" "breakpoint (A) after the first fork" | |
14971 | + gdb_test "continue" \ | |
14972 | + "atchpoint \[0-9\]+: var.*Old value = 3.*New value = 4.*after-fork1-A.*" "watchpoint A after the first fork" | |
14973 | + gdb_test "continue" \ | |
14974 | + "atchpoint \[0-9\]+: var.*Old value = 4.*New value = 5.*after-fork1-B.*" "watchpoint B after the first fork" | |
14975 | + gdb_test "continue" \ | |
14976 | + "reakpoint \[0-9\]+, marker.*" "breakpoint (A) after the second fork" | |
14977 | + gdb_test "continue" \ | |
14978 | + "atchpoint \[0-9\]+: var.*Old value = 5.*New value = 6.*after-fork2-A.*" "watchpoint A after the second fork" | |
14979 | + gdb_test "continue" \ | |
14980 | + "atchpoint \[0-9\]+: var.*Old value = 6.*New value = 7.*after-fork2-B.*" "watchpoint B after the second fork" | |
14981 | + gdb_test "continue" "Continuing\\..*\r\nBreakpoint \[0-9\]+, mark_exit .*" "finish" | |
14982 | + | |
14983 | + | |
14984 | + # cleanup | |
14985 | + set pf_prefix $prefix_test | |
14986 | +} | |
14987 | + | |
14988 | +test parent FOLLOW_PARENT | |
14989 | + | |
14990 | +# Only GNU/Linux is known to support `set follow-fork-mode child'. | |
14991 | +if {[istarget "*-*-linux*"] && ![is_remote target]} { | |
14992 | + test child FOLLOW_CHILD | |
14993 | +} else { | |
14994 | + untested "child" | |
14995 | +} | |
f412e1b4 PS |
14996 | diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork.h b/gdb/testsuite/gdb.threads/watchpoint-fork.h |
14997 | new file mode 100644 | |
14998 | index 0000000..cb109fa | |
14999 | --- /dev/null | |
15000 | +++ b/gdb/testsuite/gdb.threads/watchpoint-fork.h | |
6ed6bacf AM |
15001 | @@ -0,0 +1,32 @@ |
15002 | +/* Test case for forgotten hw-watchpoints after fork()-off of a process. | |
15003 | + | |
f412e1b4 | 15004 | + Copyright 2012 Free Software Foundation, Inc. |
6ed6bacf AM |
15005 | + |
15006 | + This file is part of GDB. | |
15007 | + | |
15008 | + This program is free software; you can redistribute it and/or modify | |
15009 | + it under the terms of the GNU General Public License as published by | |
15010 | + the Free Software Foundation; either version 2 of the License, or | |
15011 | + (at your option) any later version. | |
15012 | + | |
15013 | + This program is distributed in the hope that it will be useful, | |
15014 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15015 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15016 | + GNU General Public License for more details. | |
15017 | + | |
15018 | + You should have received a copy of the GNU General Public License | |
15019 | + along with this program; if not, write to the Free Software | |
15020 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
15021 | + Boston, MA 02111-1307, USA. */ | |
15022 | + | |
15023 | +#ifdef THREAD | |
15024 | +#include <pthread.h> | |
15025 | + | |
15026 | +extern volatile int step; | |
15027 | +extern pthread_t thread; | |
15028 | +#endif /* THREAD */ | |
15029 | + | |
15030 | +extern volatile int var; | |
15031 | + | |
15032 | +extern void marker (void); | |
15033 | +extern void forkoff (int nr); | |
f412e1b4 PS |
15034 | diff --git a/gdb/testsuite/gdb.trace/stap-trace.c b/gdb/testsuite/gdb.trace/stap-trace.c |
15035 | new file mode 100644 | |
15036 | index 0000000..27f317e | |
15037 | --- /dev/null | |
15038 | +++ b/gdb/testsuite/gdb.trace/stap-trace.c | |
6ed6bacf AM |
15039 | @@ -0,0 +1,71 @@ |
15040 | +/* This testcase is part of GDB, the GNU debugger. | |
15041 | + | |
15042 | + Copyright 2011 Free Software Foundation, Inc. | |
15043 | + | |
15044 | + This program is free software; you can redistribute it and/or modify | |
15045 | + it under the terms of the GNU General Public License as published by | |
15046 | + the Free Software Foundation; either version 3 of the License, or | |
15047 | + (at your option) any later version. | |
15048 | + | |
15049 | + This program is distributed in the hope that it will be useful, | |
15050 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15051 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15052 | + GNU General Public License for more details. | |
15053 | + | |
15054 | + You should have received a copy of the GNU General Public License | |
15055 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
15056 | + | |
15057 | +#if USE_PROBES | |
15058 | + | |
15059 | +#define _SDT_HAS_SEMAPHORES | |
15060 | +__extension__ unsigned short teste_user_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes"))); | |
15061 | +#define TEST teste_user_semaphore | |
15062 | + | |
15063 | +__extension__ unsigned short teste_two_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes"))); | |
15064 | +#define TEST2 teste_two_semaphore | |
15065 | + | |
15066 | +#else | |
15067 | + | |
15068 | +#define TEST 1 | |
15069 | +#define TEST2 1 | |
15070 | + | |
15071 | +#endif /* USE_PROBES */ | |
15072 | + | |
15073 | +#include <sys/sdt.h> | |
15074 | + | |
15075 | +/* We only support SystemTap and only the v3 form. */ | |
15076 | +#if _SDT_NOTE_TYPE != 3 | |
15077 | +#error "not using SystemTap v3 probes" | |
15078 | +#endif | |
15079 | + | |
15080 | +void | |
15081 | +m1 (int x) | |
15082 | +{ | |
15083 | + if (TEST2) | |
15084 | + STAP_PROBE1 (teste, two, x); | |
15085 | +} | |
15086 | + | |
15087 | +int | |
15088 | +f (int x) | |
15089 | +{ | |
15090 | + if (TEST) | |
15091 | + STAP_PROBE1(teste, user, x); | |
15092 | + return x+5; | |
15093 | +} | |
15094 | + | |
15095 | +void | |
15096 | +nothing (void) | |
15097 | +{ | |
15098 | + int a = 1 + 1; | |
15099 | + return; | |
15100 | +} | |
15101 | + | |
15102 | +int | |
15103 | +main() | |
15104 | +{ | |
15105 | + f (f (23)); | |
15106 | + m1 (46); | |
15107 | + nothing (); /* end-here */ | |
15108 | + | |
15109 | + return 0; | |
15110 | +} | |
f412e1b4 PS |
15111 | diff --git a/gdb/testsuite/gdb.trace/stap-trace.exp b/gdb/testsuite/gdb.trace/stap-trace.exp |
15112 | new file mode 100644 | |
15113 | index 0000000..b0f1d7d | |
15114 | --- /dev/null | |
15115 | +++ b/gdb/testsuite/gdb.trace/stap-trace.exp | |
6ed6bacf AM |
15116 | @@ -0,0 +1,129 @@ |
15117 | +# Copyright 2011 | |
15118 | +# Free Software Foundation, Inc. | |
15119 | + | |
15120 | +# This program is free software; you can redistribute it and/or modify | |
15121 | +# it under the terms of the GNU General Public License as published by | |
15122 | +# the Free Software Foundation; either version 3 of the License, or | |
15123 | +# (at your option) any later version. | |
15124 | +# | |
15125 | +# This program is distributed in the hope that it will be useful, | |
15126 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15127 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15128 | +# GNU General Public License for more details. | |
15129 | +# | |
15130 | +# You should have received a copy of the GNU General Public License | |
15131 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
15132 | + | |
15133 | +load_lib "trace-support.exp" | |
15134 | + | |
15135 | +if $tracelevel then { | |
15136 | + strace $tracelevel | |
15137 | +} | |
51a5ef0f | 15138 | + |
6ed6bacf AM |
15139 | +set testfile "stap-trace" |
15140 | +set srcfile ${testfile}.c | |
15141 | +set executable $testfile | |
15142 | +set binfile $objdir/$subdir/$executable | |
51a5ef0f | 15143 | + |
6ed6bacf AM |
15144 | +set ws "\[\r\n\t \]+" |
15145 | +set cr "\[\r\n\]+" | |
51a5ef0f | 15146 | + |
6ed6bacf AM |
15147 | +# Only x86 and x86_64 targets are supported for now. |
15148 | + | |
15149 | +if { ![istarget "x86_64-*"] && ![istarget "i?86-*"] } { | |
15150 | + continue | |
15151 | +} | |
15152 | + | |
15153 | +proc compile_stap_bin {{ arg "" }} { | |
15154 | + global srcfile | |
15155 | + global binfile | |
15156 | + global srcdir | |
15157 | + global subdir | |
7566401a | 15158 | + |
6ed6bacf AM |
15159 | + if { $arg != "" } { |
15160 | + set arg "additional_flags=$arg" | |
15161 | + } | |
15162 | + | |
15163 | + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ | |
15164 | + executable [concat $arg debug nowarnings]] != "" } { | |
15165 | + untested "Could not compile ${srcfile}" | |
51a5ef0f PS |
15166 | + return -1 |
15167 | + } | |
6ed6bacf | 15168 | +} |
7566401a | 15169 | + |
6ed6bacf AM |
15170 | +proc prepare_for_trace_test {} { |
15171 | + global executable | |
7566401a | 15172 | + |
6ed6bacf AM |
15173 | + clean_restart $executable |
15174 | + | |
15175 | + if { ![runto_main] } { | |
15176 | + perror "Could not run to `main'." | |
15177 | + continue | |
7566401a ER |
15178 | + } |
15179 | + | |
6ed6bacf AM |
15180 | + gdb_breakpoint [gdb_get_line_number "end-here"] |
15181 | +} | |
51a5ef0f | 15182 | + |
6ed6bacf AM |
15183 | +proc run_trace_experiment { test_probe msg } { |
15184 | + global gdb_prompt | |
15185 | + | |
15186 | + set test "collect $msg: start trace experiment" | |
15187 | + gdb_test_multiple "tstart" "$test" { | |
15188 | + -re "^tstart\r\n$gdb_prompt $" { | |
15189 | + pass "$test" | |
15190 | + } | |
15191 | + } | |
51a5ef0f PS |
15192 | + |
15193 | + gdb_test "continue" \ | |
6ed6bacf AM |
15194 | + "Continuing.*Breakpoint \[0-9\]+.*" \ |
15195 | + "collect $msg: run trace experiment" | |
15196 | + gdb_test "tstop" \ | |
15197 | + "\[\r\n\]+" \ | |
15198 | + "collect $msg: stop trace experiment" | |
15199 | + gdb_test "tfind start" \ | |
15200 | + "#0 .*" \ | |
15201 | + "collect $msg: tfind test frame" | |
15202 | +} | |
15203 | + | |
15204 | +proc gdb_collect_probe_arg { msg probe val_arg0 } { | |
15205 | + global gdb_prompt | |
15206 | + global cr | |
7566401a | 15207 | + |
6ed6bacf | 15208 | + prepare_for_trace_test |
ab050a48 | 15209 | + |
6ed6bacf AM |
15210 | + gdb_test "trace $probe" \ |
15211 | + "Tracepoint \[0-9\]+ at .*" \ | |
15212 | + "collect $msg: set tracepoint" | |
15213 | + gdb_trace_setactions "collect $msg: define actions" \ | |
15214 | + "" \ | |
15215 | + "collect \$_probe_arg0" "^$" | |
7566401a | 15216 | + |
6ed6bacf AM |
15217 | + # Begin the test. |
15218 | + run_trace_experiment $msg $probe | |
15219 | + | |
15220 | + gdb_test "print \$_probe_arg0" \ | |
15221 | + "\\$\[0-9\]+ = $val_arg0$cr" \ | |
15222 | + "collect $msg: collected probe arg0" | |
7566401a | 15223 | +} |
51a5ef0f | 15224 | + |
6ed6bacf | 15225 | +compile_stap_bin "" |
51a5ef0f | 15226 | + |
6ed6bacf AM |
15227 | +clean_restart $executable |
15228 | +if { ![runto_main] } { | |
15229 | + perror "Could not run to `main'." | |
15230 | + continue | |
51a5ef0f | 15231 | +} |
6ed6bacf AM |
15232 | + |
15233 | +if { ![gdb_target_supports_trace] } { | |
15234 | + # Test cannot run on this target. | |
15235 | + return 1; | |
15236 | +} | |
15237 | + | |
f412e1b4 | 15238 | +gdb_collect_probe_arg "probe args without semaphore" "-p user" "23" |
6ed6bacf AM |
15239 | +gdb_exit |
15240 | + | |
15241 | +compile_stap_bin "-DUSE_PROBES" | |
f412e1b4 | 15242 | +gdb_collect_probe_arg "probe args with semaphore" "-p two" "46" |
6ed6bacf AM |
15243 | + |
15244 | +# Finished! | |
15245 | +gdb_test "tfind none" ".*" "" | |
f412e1b4 PS |
15246 | diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp |
15247 | index 00fe71c..5ca9563 100644 | |
15248 | --- a/gdb/testsuite/lib/gdb.exp | |
15249 | +++ b/gdb/testsuite/lib/gdb.exp | |
15250 | @@ -139,6 +139,11 @@ proc gdb_unload {} { | |
6ed6bacf AM |
15251 | send_gdb "y\n" |
15252 | exp_continue | |
15253 | } | |
15254 | + -re "A program is being debugged already..*Are you sure you want to change the file.*y or n. $"\ | |
15255 | + { send_gdb "y\n" | |
15256 | + verbose "\t\tUnloading symbols for program being debugged" | |
15257 | + exp_continue | |
15258 | + } | |
15259 | -re "Discard symbol table from .*y or n.*$" { | |
15260 | send_gdb "y\n" | |
15261 | exp_continue | |
f412e1b4 PS |
15262 | diff --git a/gdb/testsuite/lib/pascal.exp b/gdb/testsuite/lib/pascal.exp |
15263 | index dd18d37..f973485 100644 | |
15264 | --- a/gdb/testsuite/lib/pascal.exp | |
15265 | +++ b/gdb/testsuite/lib/pascal.exp | |
51a5ef0f PS |
15266 | @@ -37,6 +37,9 @@ proc pascal_init {} { |
15267 | global pascal_compiler_is_fpc | |
15268 | global gpc_compiler | |
15269 | global fpc_compiler | |
15270 | + global fpcversion_major | |
15271 | + global fpcversion_minor | |
15272 | + global fpcversion_release | |
15273 | global env | |
15274 | ||
15275 | if { $pascal_init_done == 1 } { | |
15276 | @@ -64,6 +67,20 @@ proc pascal_init {} { | |
15277 | set pascal_compiler_is_fpc 1 | |
15278 | verbose -log "Free Pascal compiler found" | |
15279 | } | |
15280 | + | |
15281 | + # Detect the fpc-version | |
15282 | + if { $pascal_compiler_is_fpc == 1 } { | |
15283 | + set fpcversion_major 1 | |
15284 | + set fpcversion_minor 0 | |
15285 | + set fpcversion_release 0 | |
15286 | + set fpcversion [ remote_exec host $fpc_compiler "-iV" ] | |
15287 | + if [regexp {.*([0-9]+)\.([0-9]+)\.([0-9]+).?} $fpcversion] { | |
15288 | + regsub {.*([0-9]+)\.([0-9]+)\.([0-9]+).?\n?.?} $fpcversion {\1} fpcversion_major | |
15289 | + regsub {.*([0-9]+)\.([0-9]+)\.([0-9]+).?\n?.?} $fpcversion {\2} fpcversion_minor | |
15290 | + regsub {.*([0-9]+)\.([0-9]+)\.([0-9]+).?\n?.?} $fpcversion {\3} fpcversion_release | |
15291 | + } | |
15292 | + verbose -log "Freepascal version: $fpcversion_major.$fpcversion_minor.$fpcversion_release" | |
15293 | + } | |
15294 | } | |
15295 | set pascal_init_done 1 | |
15296 | } | |
f412e1b4 PS |
15297 | diff --git a/gdb/thread.c b/gdb/thread.c |
15298 | index 9a29383..1a49b00 100644 | |
15299 | --- a/gdb/thread.c | |
15300 | +++ b/gdb/thread.c | |
15301 | @@ -1431,7 +1431,8 @@ update_thread_list (void) | |
6ed6bacf | 15302 | no thread is selected, or no threads exist. */ |
3a58abaf | 15303 | |
6ed6bacf AM |
15304 | static struct value * |
15305 | -thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var) | |
15306 | +thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var, | |
15307 | + void *ignore) | |
15308 | { | |
15309 | struct thread_info *tp = find_thread_ptid (inferior_ptid); | |
15310 | ||
f412e1b4 | 15311 | @@ -1442,6 +1443,15 @@ thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var) |
6ed6bacf AM |
15312 | /* Commands with a prefix of `thread'. */ |
15313 | struct cmd_list_element *thread_cmd_list = NULL; | |
15314 | ||
15315 | +/* Implementation of `thread' variable. */ | |
15316 | + | |
15317 | +static struct internalvar_funcs thread_funcs = | |
51a5ef0f | 15318 | +{ |
6ed6bacf AM |
15319 | + thread_id_make_value, |
15320 | + NULL, | |
15321 | + NULL | |
15322 | +}; | |
51a5ef0f | 15323 | + |
6ed6bacf AM |
15324 | void |
15325 | _initialize_thread (void) | |
15326 | { | |
f412e1b4 | 15327 | @@ -1487,5 +1497,5 @@ Show printing of thread events (such as thread start and exit)."), NULL, |
6ed6bacf AM |
15328 | show_print_thread_events, |
15329 | &setprintlist, &showprintlist); | |
15330 | ||
15331 | - create_internalvar_type_lazy ("_thread", thread_id_make_value); | |
15332 | + create_internalvar_type_lazy ("_thread", &thread_funcs, NULL); | |
15333 | } | |
f412e1b4 PS |
15334 | diff --git a/gdb/top.c b/gdb/top.c |
15335 | index c4e913d..5b79983 100644 | |
15336 | --- a/gdb/top.c | |
15337 | +++ b/gdb/top.c | |
15338 | @@ -349,6 +349,9 @@ prepare_execute_command (void) | |
15339 | ||
15340 | mark = value_mark (); | |
15341 | cleanup = make_cleanup_value_free_to_mark (mark); | |
6ed6bacf AM |
15342 | +#if 0 |
15343 | + free_all_types (); | |
15344 | +#endif | |
15345 | ||
15346 | /* With multiple threads running while the one we're examining is | |
15347 | stopped, the dcache can get stale without us being able to detect | |
f412e1b4 PS |
15348 | diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c |
15349 | index ede3742..b20f733 100644 | |
15350 | --- a/gdb/tracepoint.c | |
15351 | +++ b/gdb/tracepoint.c | |
15352 | @@ -683,7 +683,7 @@ validate_actionline (char **line, struct breakpoint *b) | |
15353 | struct cleanup *old_chain = NULL; | |
15354 | char *p, *tmp_p; | |
15355 | struct bp_location *loc; | |
15356 | - struct agent_expr *aexpr; | |
15357 | + struct agent_expr *aexpr = NULL; | |
15358 | struct tracepoint *t = (struct tracepoint *) b; | |
15359 | ||
15360 | /* If EOF is typed, *line is NULL. */ | |
15361 | @@ -1352,7 +1352,7 @@ encode_actions_1 (struct command_line *action, | |
15362 | int i; | |
15363 | struct value *tempval; | |
15364 | struct cmd_list_element *cmd; | |
15365 | - struct agent_expr *aexpr; | |
15366 | + struct agent_expr *aexpr = NULL; | |
6ed6bacf | 15367 | |
f412e1b4 PS |
15368 | for (; action; action = action->next) |
15369 | { | |
15370 | @@ -1716,6 +1716,7 @@ start_tracing (char *notes) | |
15371 | for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++) | |
6ed6bacf | 15372 | { |
f412e1b4 | 15373 | struct tracepoint *t = (struct tracepoint *) b; |
6ed6bacf | 15374 | + struct bp_location *loc; |
f412e1b4 PS |
15375 | |
15376 | if (b->enable_state == bp_enabled) | |
15377 | any_enabled = 1; | |
15378 | @@ -1778,6 +1779,9 @@ start_tracing (char *notes) | |
15379 | } | |
15380 | ||
15381 | t->number_on_target = b->number; | |
6ed6bacf | 15382 | + |
f412e1b4 | 15383 | + for (loc = b->loc; loc; loc = loc->next) |
6ed6bacf | 15384 | + modify_semaphore (loc, 1); |
7566401a | 15385 | } |
6ed6bacf | 15386 | VEC_free (breakpoint_p, tp_vec); |
3a58abaf | 15387 | |
f412e1b4 PS |
15388 | @@ -1850,9 +1854,28 @@ void |
15389 | stop_tracing (char *note) | |
6ed6bacf | 15390 | { |
f412e1b4 | 15391 | int ret; |
6ed6bacf AM |
15392 | + VEC(breakpoint_p) *tp_vec = NULL; |
15393 | + int ix; | |
15394 | + struct breakpoint *t; | |
f412e1b4 | 15395 | |
6ed6bacf | 15396 | target_trace_stop (); |
f412e1b4 | 15397 | |
6ed6bacf AM |
15398 | + tp_vec = all_tracepoints (); |
15399 | + for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++) | |
51a5ef0f | 15400 | + { |
6ed6bacf AM |
15401 | + struct bp_location *loc; |
15402 | + | |
15403 | + if ((t->type == bp_fast_tracepoint | |
15404 | + ? !may_insert_fast_tracepoints | |
15405 | + : !may_insert_tracepoints)) | |
15406 | + continue; | |
15407 | + | |
15408 | + for (loc = t->loc; loc; loc = loc->next) | |
15409 | + modify_semaphore (loc, 0); | |
51a5ef0f PS |
15410 | + } |
15411 | + | |
6ed6bacf AM |
15412 | + VEC_free (breakpoint_p, tp_vec); |
15413 | + | |
f412e1b4 PS |
15414 | if (!note) |
15415 | note = trace_stop_notes; | |
15416 | ret = target_set_trace_notes (NULL, NULL, note); | |
15417 | @@ -4924,7 +4947,8 @@ info_static_tracepoint_markers_command (char *arg, int from_tty) | |
6ed6bacf | 15418 | available. */ |
51a5ef0f | 15419 | |
6ed6bacf AM |
15420 | static struct value * |
15421 | -sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var) | |
15422 | +sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var, | |
15423 | + void *ignore) | |
7566401a | 15424 | { |
6ed6bacf AM |
15425 | LONGEST size; |
15426 | gdb_byte *buf; | |
f412e1b4 | 15427 | @@ -5103,6 +5127,15 @@ traceframe_available_memory (VEC(mem_range_s) **result, |
6ed6bacf AM |
15428 | return 0; |
15429 | } | |
7566401a | 15430 | |
6ed6bacf AM |
15431 | +/* Implementation of `sdata' variable. */ |
15432 | + | |
15433 | +static const struct internalvar_funcs sdata_funcs = | |
15434 | +{ | |
15435 | + sdata_make_value, | |
15436 | + NULL, | |
15437 | + NULL | |
15438 | +}; | |
15439 | + | |
15440 | /* module initialization */ | |
15441 | void | |
15442 | _initialize_tracepoint (void) | |
f412e1b4 | 15443 | @@ -5113,7 +5146,7 @@ _initialize_tracepoint (void) |
6ed6bacf AM |
15444 | value with a void typed value, and when we get here, gdbarch |
15445 | isn't initialized yet. At this point, we're quite sure there | |
15446 | isn't another convenience variable of the same name. */ | |
15447 | - create_internalvar_type_lazy ("_sdata", sdata_make_value); | |
15448 | + create_internalvar_type_lazy ("_sdata", &sdata_funcs, NULL); | |
15449 | ||
15450 | traceframe_number = -1; | |
15451 | tracepoint_number = -1; | |
f412e1b4 PS |
15452 | diff --git a/gdb/typeprint.c b/gdb/typeprint.c |
15453 | index de96fd5..75485ff 100644 | |
15454 | --- a/gdb/typeprint.c | |
15455 | +++ b/gdb/typeprint.c | |
15456 | @@ -35,6 +35,7 @@ | |
7566401a ER |
15457 | #include "gdb_string.h" |
15458 | #include "exceptions.h" | |
15459 | #include "valprint.h" | |
15460 | +#include "dwarf2loc.h" | |
7566401a | 15461 | #include <errno.h> |
3a58abaf | 15462 | |
7566401a | 15463 | extern void _initialize_typeprint (void); |
f412e1b4 | 15464 | @@ -76,6 +77,9 @@ void |
7566401a ER |
15465 | type_print (struct type *type, char *varstring, struct ui_file *stream, |
15466 | int show) | |
15467 | { | |
f412e1b4 | 15468 | + if (show >= 0 && current_language->la_language != language_ada) |
7566401a | 15469 | + type = check_typedef (type); |
3a58abaf | 15470 | + |
7566401a | 15471 | LA_PRINT_TYPE (type, varstring, stream, show, 0); |
3a58abaf | 15472 | } |
7566401a | 15473 | |
f412e1b4 | 15474 | @@ -114,7 +118,8 @@ whatis_exp (char *exp, int show) |
3a58abaf | 15475 | { |
7566401a ER |
15476 | struct expression *expr; |
15477 | struct value *val; | |
15478 | - struct cleanup *old_chain = NULL; | |
15479 | + /* Required at least for the object_address_set call. */ | |
15480 | + struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); | |
15481 | struct type *real_type = NULL; | |
15482 | struct type *type; | |
15483 | int full = 0; | |
f412e1b4 | 15484 | @@ -125,12 +130,13 @@ whatis_exp (char *exp, int show) |
7566401a ER |
15485 | if (exp) |
15486 | { | |
15487 | expr = parse_expression (exp); | |
15488 | - old_chain = make_cleanup (free_current_contents, &expr); | |
15489 | + make_cleanup (free_current_contents, &expr); | |
15490 | val = evaluate_type (expr); | |
3a58abaf | 15491 | } |
7566401a ER |
15492 | else |
15493 | val = access_value_history (0); | |
3a58abaf | 15494 | |
7566401a ER |
15495 | + object_address_set (value_raw_address (val)); |
15496 | type = value_type (val); | |
15497 | ||
15498 | get_user_print_options (&opts); | |
f412e1b4 | 15499 | @@ -167,8 +173,7 @@ whatis_exp (char *exp, int show) |
7566401a ER |
15500 | type_print (type, "", gdb_stdout, show); |
15501 | printf_filtered ("\n"); | |
15502 | ||
15503 | - if (exp) | |
15504 | - do_cleanups (old_chain); | |
15505 | + do_cleanups (old_chain); | |
15506 | } | |
15507 | ||
15508 | static void | |
f412e1b4 PS |
15509 | diff --git a/gdb/utils.c b/gdb/utils.c |
15510 | index 4863e41..c1fec82 100644 | |
15511 | --- a/gdb/utils.c | |
15512 | +++ b/gdb/utils.c | |
15513 | @@ -1904,6 +1904,36 @@ set_batch_flag_and_make_cleanup_restore_page_info (void) | |
6ed6bacf | 15514 | return back_to; |
7566401a | 15515 | } |
3a58abaf | 15516 | |
6ed6bacf AM |
15517 | +/* Helper for make_cleanup_restore_page_info. */ |
15518 | + | |
15519 | +static void | |
15520 | +do_restore_selected_frame_cleanup (void *arg) | |
15521 | +{ | |
15522 | + struct frame_id *frame_idp = arg; | |
15523 | + | |
15524 | + select_frame (frame_find_by_id (*frame_idp)); | |
15525 | + | |
15526 | + xfree (frame_idp); | |
15527 | +} | |
15528 | + | |
15529 | +/* Provide cleanup for restoring currently selected frame. Use frame_id for | |
15530 | + the case the current frame becomes stale in the meantime. */ | |
15531 | + | |
15532 | +struct cleanup * | |
15533 | +make_cleanup_restore_selected_frame (void) | |
15534 | +{ | |
15535 | + struct frame_id *frame_idp; | |
15536 | + | |
15537 | + /* get_selected_frame->get_current_frame would error otherwise. */ | |
15538 | + if (!has_stack_frames ()) | |
15539 | + return make_cleanup (null_cleanup, NULL); | |
15540 | + | |
15541 | + frame_idp = xmalloc (sizeof (*frame_idp)); | |
15542 | + *frame_idp = get_frame_id (get_selected_frame (NULL)); | |
15543 | + | |
15544 | + return make_cleanup (do_restore_selected_frame_cleanup, frame_idp); | |
15545 | +} | |
15546 | + | |
15547 | /* Set the screen size based on LINES_PER_PAGE and CHARS_PER_LINE. */ | |
3a58abaf | 15548 | |
6ed6bacf | 15549 | static void |
f412e1b4 PS |
15550 | diff --git a/gdb/valarith.c b/gdb/valarith.c |
15551 | index b8bcc6b..fb83c70 100644 | |
15552 | --- a/gdb/valarith.c | |
15553 | +++ b/gdb/valarith.c | |
15554 | @@ -197,7 +197,10 @@ value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound) | |
7566401a ER |
15555 | struct type *array_type = check_typedef (value_type (array)); |
15556 | struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type)); | |
6ed6bacf | 15557 | unsigned int elt_size = TYPE_LENGTH (elt_type); |
7566401a | 15558 | - unsigned int elt_offs = elt_size * longest_to_int (index - lowerbound); |
6ed6bacf AM |
15559 | + unsigned int elt_stride |
15560 | + = (TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (array_type)) == 0 | |
15561 | + ? elt_size : TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (array_type))); | |
15562 | + unsigned int elt_offs = elt_stride * longest_to_int (index - lowerbound); | |
7566401a | 15563 | struct value *v; |
3a58abaf | 15564 | |
6ed6bacf | 15565 | if (index < lowerbound || (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type) |
f412e1b4 | 15566 | @@ -297,6 +300,10 @@ int |
51a5ef0f PS |
15567 | binop_user_defined_p (enum exp_opcode op, |
15568 | struct value *arg1, struct value *arg2) | |
15569 | { | |
15570 | + /* FIXME: We should support user defined ops for dynamic types. */ | |
15571 | + if (TYPE_DYNAMIC (value_type (arg1)) || TYPE_DYNAMIC (value_type (arg2))) | |
15572 | + return 0; | |
15573 | + | |
15574 | return binop_types_user_defined_p (op, value_type (arg1), value_type (arg2)); | |
15575 | } | |
15576 | ||
f412e1b4 PS |
15577 | diff --git a/gdb/valops.c b/gdb/valops.c |
15578 | index 5453b1a..5a4a8fa 100644 | |
15579 | --- a/gdb/valops.c | |
15580 | +++ b/gdb/valops.c | |
15581 | @@ -45,6 +45,7 @@ | |
6ed6bacf AM |
15582 | #include "objfiles.h" |
15583 | #include "symtab.h" | |
15584 | #include "exceptions.h" | |
7566401a | 15585 | +#include "dwarf2loc.h" |
3a58abaf | 15586 | |
6ed6bacf AM |
15587 | extern int overload_debug; |
15588 | /* Local functions. */ | |
f412e1b4 | 15589 | @@ -915,6 +916,65 @@ value_one (struct type *type) |
7566401a ER |
15590 | return val; |
15591 | } | |
3a58abaf | 15592 | |
7566401a | 15593 | +/* object_address_set must be already called before this function. */ |
3a58abaf AM |
15594 | + |
15595 | +const char * | |
7566401a | 15596 | +object_address_data_not_valid (struct type *type) |
3a58abaf | 15597 | +{ |
7566401a ER |
15598 | + /* Attributes are present only at the target type of a typedef. Make the |
15599 | + call conditional as it would otherwise loop through type_length_get. */ | |
15600 | + if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) | |
15601 | + CHECK_TYPEDEF (type); | |
3a58abaf | 15602 | + |
7566401a ER |
15603 | + /* DW_AT_associated has a preference over DW_AT_allocated. */ |
15604 | + if (TYPE_NOT_ASSOCIATED (type) | |
15605 | + || (TYPE_ASSOCIATED (type) != NULL | |
15606 | + && 0 == dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (type)))) | |
15607 | + return N_("object is not associated"); | |
15608 | + | |
15609 | + if (TYPE_NOT_ALLOCATED (type) | |
15610 | + || (TYPE_ALLOCATED (type) != NULL | |
15611 | + && 0 == dwarf_locexpr_baton_eval (TYPE_ALLOCATED (type)))) | |
15612 | + return N_("object is not allocated"); | |
3a58abaf | 15613 | + |
3a58abaf AM |
15614 | + return NULL; |
15615 | +} | |
15616 | + | |
51a5ef0f PS |
15617 | +/* Return non-NULL check_typedef result on TYPE if the variable is valid. If |
15618 | + it is valid the function may store the data address (DW_AT_DATA_LOCATION) of | |
15619 | + TYPE at *ADDRESS_RETURN. You must set *ADDRESS_RETURN from | |
15620 | + value_raw_address (VAL) before calling this function. If no | |
15621 | + DW_AT_DATA_LOCATION is present for TYPE the address at *ADDRESS_RETURN is | |
15622 | + left unchanged. ADDRESS_RETURN must not be NULL, use | |
7566401a | 15623 | + object_address_data_not_valid () for just the data validity check. */ |
3a58abaf | 15624 | + |
51a5ef0f | 15625 | +struct type * |
7566401a | 15626 | +object_address_get_data (struct type *type, CORE_ADDR *address_return) |
3a58abaf | 15627 | +{ |
7566401a | 15628 | + gdb_assert (address_return != NULL); |
3a58abaf | 15629 | + |
7566401a | 15630 | + object_address_set (*address_return); |
3a58abaf | 15631 | + |
7566401a ER |
15632 | + /* TYPE_DATA_LOCATION_DWARF_BLOCK / TYPE_DATA_LOCATION_ADDR are present only |
15633 | + at the target type of a typedef. */ | |
15634 | + CHECK_TYPEDEF (type); | |
3a58abaf | 15635 | + |
7566401a ER |
15636 | + if (object_address_data_not_valid (type) != NULL) |
15637 | + { | |
15638 | + /* Do not try to evaluate DW_AT_data_location as it may even crash | |
15639 | + (it would just return the value zero in the gfortran case). */ | |
51a5ef0f | 15640 | + return NULL; |
7566401a | 15641 | + } |
3a58abaf | 15642 | + |
7566401a ER |
15643 | + if (TYPE_DATA_LOCATION_IS_ADDR (type)) |
15644 | + *address_return = TYPE_DATA_LOCATION_ADDR (type); | |
15645 | + else if (TYPE_DATA_LOCATION_DWARF_BLOCK (type) != NULL) | |
15646 | + *address_return | |
15647 | + = dwarf_locexpr_baton_eval (TYPE_DATA_LOCATION_DWARF_BLOCK (type)); | |
3a58abaf | 15648 | + |
51a5ef0f | 15649 | + return type; |
7566401a | 15650 | +} |
3a58abaf | 15651 | + |
7566401a ER |
15652 | /* Helper function for value_at, value_at_lazy, and value_at_lazy_stack. */ |
15653 | ||
15654 | static struct value * | |
6ed6bacf | 15655 | @@ -1011,12 +1071,20 @@ value_fetch_lazy (struct value *val) |
7566401a ER |
15656 | } |
15657 | else if (VALUE_LVAL (val) == lval_memory) | |
15658 | { | |
15659 | - CORE_ADDR addr = value_address (val); | |
15660 | - int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val))); | |
15661 | + CORE_ADDR addr = value_raw_address (val); | |
15662 | ||
15663 | - if (length) | |
6ed6bacf AM |
15664 | - read_value_memory (val, 0, value_stack (val), |
15665 | - addr, value_contents_all_raw (val), length); | |
7566401a | 15666 | + if (object_address_get_data (value_type (val), &addr)) |
6ed6bacf | 15667 | + { |
7566401a ER |
15668 | + struct type *type = value_enclosing_type (val); |
15669 | + int length = TYPE_LENGTH (check_typedef (type)); | |
3a58abaf | 15670 | + |
7566401a ER |
15671 | + if (length) |
15672 | + { | |
15673 | + addr += value_offset (val); | |
6ed6bacf AM |
15674 | + read_value_memory (val, 0, value_stack (val), |
15675 | + addr, value_contents_all_raw (val), length); | |
7566401a | 15676 | + } |
6ed6bacf | 15677 | + } |
7566401a ER |
15678 | } |
15679 | else if (VALUE_LVAL (val) == lval_register) | |
6ed6bacf | 15680 | { |
f412e1b4 | 15681 | @@ -1528,7 +1596,18 @@ address_of_variable (struct symbol *var, struct block *b) |
7566401a ER |
15682 | if ((VALUE_LVAL (val) == lval_memory && value_lazy (val)) |
15683 | || TYPE_CODE (type) == TYPE_CODE_FUNC) | |
15684 | { | |
15685 | - CORE_ADDR addr = value_address (val); | |
15686 | + CORE_ADDR addr; | |
3a58abaf | 15687 | + |
7566401a ER |
15688 | + if (VALUE_LVAL (val) == lval_memory) |
15689 | + { | |
15690 | + addr = value_raw_address (val); | |
15691 | + if (!object_address_get_data (type, &addr)) | |
15692 | + error (_("Can't take address of memory lvalue \"%s\"."), | |
15693 | + SYMBOL_PRINT_NAME (var)); | |
15694 | + set_value_address (val, addr); | |
15695 | + } | |
3a58abaf | 15696 | + |
7566401a | 15697 | + addr = value_address (val); |
51a5ef0f | 15698 | |
7566401a ER |
15699 | return value_from_pointer (lookup_pointer_type (type), addr); |
15700 | } | |
6ed6bacf | 15701 | @@ -1635,6 +1714,7 @@ struct value * |
7566401a ER |
15702 | value_coerce_array (struct value *arg1) |
15703 | { | |
15704 | struct type *type = check_typedef (value_type (arg1)); | |
15705 | + CORE_ADDR address; | |
15706 | ||
15707 | /* If the user tries to do something requiring a pointer with an | |
15708 | array that has not yet been pushed to the target, then this would | |
6ed6bacf | 15709 | @@ -1644,8 +1724,12 @@ value_coerce_array (struct value *arg1) |
7566401a ER |
15710 | if (VALUE_LVAL (arg1) != lval_memory) |
15711 | error (_("Attempt to take address of value not located in memory.")); | |
15712 | ||
15713 | + address = value_raw_address (arg1); | |
15714 | + if (!object_address_get_data (type, &address)) | |
15715 | + error (_("Attempt to take address of non-valid value.")); | |
3a58abaf | 15716 | + |
7566401a ER |
15717 | return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)), |
15718 | - value_address (arg1)); | |
15719 | + address + value_offset (arg1)); | |
15720 | } | |
15721 | ||
15722 | /* Given a value which is a function, return a value which is a pointer | |
f412e1b4 | 15723 | @@ -3694,6 +3778,8 @@ value_slice (struct value *array, int lowbound, int length) |
6ed6bacf AM |
15724 | TYPE_TARGET_TYPE (range_type), |
15725 | lowbound, | |
15726 | lowbound + length - 1); | |
15727 | + TYPE_BYTE_STRIDE (slice_range_type) = TYPE_BYTE_STRIDE (range_type); | |
15728 | + | |
15729 | if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING) | |
15730 | { | |
15731 | int i; | |
f412e1b4 PS |
15732 | diff --git a/gdb/valprint.c b/gdb/valprint.c |
15733 | index 325cf40..70a98c2 100644 | |
15734 | --- a/gdb/valprint.c | |
15735 | +++ b/gdb/valprint.c | |
15736 | @@ -37,6 +37,7 @@ | |
15737 | #include "gdb_obstack.h" | |
15738 | #include "charset.h" | |
15739 | #include <ctype.h> | |
51a5ef0f | 15740 | +#include "dwarf2loc.h" |
7566401a | 15741 | |
51a5ef0f | 15742 | #include <errno.h> |
7566401a | 15743 | |
f412e1b4 | 15744 | @@ -240,7 +241,6 @@ scalar_type_p (struct type *type) |
7566401a ER |
15745 | case TYPE_CODE_STRUCT: |
15746 | case TYPE_CODE_UNION: | |
51a5ef0f PS |
15747 | case TYPE_CODE_SET: |
15748 | - case TYPE_CODE_STRING: | |
15749 | case TYPE_CODE_BITSTRING: | |
15750 | return 0; | |
15751 | default: | |
f412e1b4 | 15752 | @@ -1198,6 +1198,7 @@ val_print_array_elements (struct type *type, |
51a5ef0f PS |
15753 | { |
15754 | unsigned int things_printed = 0; | |
15755 | unsigned len; | |
15756 | + struct type *saved_type = type; | |
15757 | struct type *elttype, *index_type; | |
15758 | unsigned eltlen; | |
15759 | /* Position of the array element we are examining to see | |
f412e1b4 | 15760 | @@ -1206,9 +1207,33 @@ val_print_array_elements (struct type *type, |
51a5ef0f PS |
15761 | /* Number of repetitions we have detected so far. */ |
15762 | unsigned int reps; | |
6ed6bacf | 15763 | LONGEST low_bound, high_bound; |
51a5ef0f PS |
15764 | + struct cleanup *back_to; |
15765 | + CORE_ADDR saved_address = address; | |
15766 | + | |
15767 | + back_to = make_cleanup (null_cleanup, 0); | |
15768 | + type = object_address_get_data (type, &address); | |
15769 | + if (!type) | |
3a58abaf | 15770 | + { |
51a5ef0f PS |
15771 | + fputs_filtered (object_address_data_not_valid (type), stream); |
15772 | + do_cleanups (back_to); | |
15773 | + return; | |
3a58abaf | 15774 | + } |
51a5ef0f | 15775 | + if (address != saved_address) |
3a58abaf | 15776 | + { |
51a5ef0f | 15777 | + size_t length = TYPE_LENGTH (type); |
7566401a | 15778 | |
51a5ef0f PS |
15779 | - elttype = TYPE_TARGET_TYPE (type); |
15780 | - eltlen = TYPE_LENGTH (check_typedef (elttype)); | |
15781 | + valaddr = xmalloc (length); | |
15782 | + make_cleanup (xfree, (gdb_byte *) valaddr); | |
15783 | + read_memory (address, (gdb_byte *) valaddr, length); | |
15784 | + } | |
3a58abaf | 15785 | + |
51a5ef0f PS |
15786 | + /* Skip typedefs but do not resolve TYPE_DYNAMIC. */ |
15787 | + elttype = saved_type; | |
15788 | + while (TYPE_CODE (elttype) == TYPE_CODE_TYPEDEF) | |
15789 | + elttype = TYPE_TARGET_TYPE (elttype); | |
15790 | + elttype = TYPE_TARGET_TYPE (elttype); | |
3a58abaf | 15791 | + |
51a5ef0f PS |
15792 | + eltlen = TYPE_ARRAY_BYTE_STRIDE_VALUE (type); |
15793 | index_type = TYPE_INDEX_TYPE (type); | |
7566401a | 15794 | |
6ed6bacf | 15795 | if (get_array_bounds (type, &low_bound, &high_bound)) |
f412e1b4 | 15796 | @@ -1295,6 +1320,8 @@ val_print_array_elements (struct type *type, |
7566401a | 15797 | { |
51a5ef0f PS |
15798 | fprintf_filtered (stream, "..."); |
15799 | } | |
15800 | + | |
15801 | + do_cleanups (back_to); | |
15802 | } | |
15803 | ||
15804 | /* Read LEN bytes of target memory at address MEMADDR, placing the | |
f412e1b4 PS |
15805 | diff --git a/gdb/value.c b/gdb/value.c |
15806 | index 583be33..cb73eda 100644 | |
15807 | --- a/gdb/value.c | |
15808 | +++ b/gdb/value.c | |
15809 | @@ -41,6 +41,7 @@ | |
6ed6bacf AM |
15810 | #include "python/python.h" |
15811 | #include <ctype.h> | |
15812 | #include "tracepoint.h" | |
7566401a ER |
15813 | +#include "observer.h" |
15814 | ||
6ed6bacf | 15815 | /* Prototypes for exported functions. */ |
7566401a | 15816 | |
f412e1b4 | 15817 | @@ -1385,12 +1386,15 @@ void |
51a5ef0f PS |
15818 | set_value_component_location (struct value *component, |
15819 | const struct value *whole) | |
7566401a ER |
15820 | { |
15821 | + CORE_ADDR addr; | |
3a58abaf | 15822 | + |
51a5ef0f | 15823 | if (whole->lval == lval_internalvar) |
7566401a ER |
15824 | VALUE_LVAL (component) = lval_internalvar_component; |
15825 | else | |
51a5ef0f | 15826 | VALUE_LVAL (component) = whole->lval; |
7566401a ER |
15827 | |
15828 | component->location = whole->location; | |
3a58abaf | 15829 | + |
51a5ef0f | 15830 | if (whole->lval == lval_computed) |
7566401a | 15831 | { |
f412e1b4 PS |
15832 | const struct lval_funcs *funcs = whole->location.computed.funcs; |
15833 | @@ -1398,6 +1402,12 @@ set_value_component_location (struct value *component, | |
7566401a ER |
15834 | if (funcs->copy_closure) |
15835 | component->location.computed.closure = funcs->copy_closure (whole); | |
15836 | } | |
3a58abaf | 15837 | + |
7566401a ER |
15838 | + addr = value_raw_address (component); |
15839 | + object_address_get_data (value_type (whole), &addr); | |
51a5ef0f PS |
15840 | + if (component->lval != lval_internalvar |
15841 | + && component->lval != lval_internalvar_component) | |
15842 | + set_value_address (component, addr); | |
7566401a ER |
15843 | } |
15844 | ||
15845 | \f | |
f412e1b4 | 15846 | @@ -1531,6 +1541,31 @@ show_values (char *num_exp, int from_tty) |
7566401a ER |
15847 | num_exp[1] = '\0'; |
15848 | } | |
15849 | } | |
3a58abaf | 15850 | + |
7566401a | 15851 | +/* Sanity check for memory leaks and proper types reference counting. */ |
3a58abaf | 15852 | + |
7566401a ER |
15853 | +static void |
15854 | +value_history_cleanup (void *unused) | |
3a58abaf | 15855 | +{ |
7566401a ER |
15856 | + while (value_history_chain) |
15857 | + { | |
15858 | + struct value_history_chunk *chunk = value_history_chain; | |
15859 | + int i; | |
3a58abaf | 15860 | + |
7566401a ER |
15861 | + for (i = 0; i < ARRAY_SIZE (chunk->values); i++) |
15862 | + value_free (chunk->values[i]); | |
3a58abaf | 15863 | + |
7566401a ER |
15864 | + value_history_chain = chunk->next; |
15865 | + xfree (chunk); | |
15866 | + } | |
15867 | + value_history_count = 0; | |
3a58abaf | 15868 | + |
7566401a ER |
15869 | + /* Free the unreferenced types above. */ |
15870 | + free_all_values (); | |
6ed6bacf | 15871 | +#if 0 |
7566401a | 15872 | + free_all_types (); |
6ed6bacf | 15873 | +#endif |
3a58abaf | 15874 | +} |
7566401a ER |
15875 | \f |
15876 | /* Internal variables. These are variables within the debugger | |
15877 | that hold values assigned by debugger commands. | |
f412e1b4 | 15878 | @@ -1576,7 +1611,14 @@ struct internalvar |
6ed6bacf AM |
15879 | struct value *value; |
15880 | ||
15881 | /* The call-back routine used with INTERNALVAR_MAKE_VALUE. */ | |
15882 | - internalvar_make_value make_value; | |
15883 | + struct | |
15884 | + { | |
15885 | + /* The functions to call. */ | |
15886 | + const struct internalvar_funcs *functions; | |
15887 | + | |
15888 | + /* The function's user-data. */ | |
15889 | + void *data; | |
15890 | + } make_value; | |
15891 | ||
15892 | /* The internal function used with INTERNALVAR_FUNCTION. */ | |
15893 | struct | |
f412e1b4 | 15894 | @@ -1675,18 +1717,39 @@ create_internalvar (const char *name) |
6ed6bacf AM |
15895 | /* Create an internal variable with name NAME and register FUN as the |
15896 | function that value_of_internalvar uses to create a value whenever | |
15897 | this variable is referenced. NAME should not normally include a | |
15898 | - dollar sign. */ | |
15899 | + dollar sign. DATA is passed uninterpreted to FUN when it is | |
15900 | + called. CLEANUP, if not NULL, is called when the internal variable | |
15901 | + is destroyed. It is passed DATA as its only argument. */ | |
15902 | ||
15903 | struct internalvar * | |
15904 | -create_internalvar_type_lazy (char *name, internalvar_make_value fun) | |
15905 | +create_internalvar_type_lazy (const char *name, | |
15906 | + const struct internalvar_funcs *funcs, | |
15907 | + void *data) | |
15908 | { | |
15909 | struct internalvar *var = create_internalvar (name); | |
15910 | ||
15911 | var->kind = INTERNALVAR_MAKE_VALUE; | |
15912 | - var->u.make_value = fun; | |
15913 | + var->u.make_value.functions = funcs; | |
15914 | + var->u.make_value.data = data; | |
15915 | return var; | |
15916 | } | |
15917 | ||
15918 | +/* See documentation in value.h. */ | |
15919 | + | |
15920 | +int | |
15921 | +compile_internalvar_to_ax (struct internalvar *var, | |
15922 | + struct agent_expr *expr, | |
15923 | + struct axs_value *value) | |
15924 | +{ | |
15925 | + if (var->kind != INTERNALVAR_MAKE_VALUE | |
15926 | + || var->u.make_value.functions->compile_to_ax == NULL) | |
15927 | + return 0; | |
15928 | + | |
15929 | + var->u.make_value.functions->compile_to_ax (var, expr, value, | |
15930 | + var->u.make_value.data); | |
15931 | + return 1; | |
15932 | +} | |
15933 | + | |
15934 | /* Look up an internal variable with name NAME. NAME should not | |
15935 | normally include a dollar sign. | |
15936 | ||
f412e1b4 | 15937 | @@ -1759,7 +1822,8 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var) |
6ed6bacf AM |
15938 | break; |
15939 | ||
15940 | case INTERNALVAR_MAKE_VALUE: | |
15941 | - val = (*var->u.make_value) (gdbarch, var); | |
15942 | + val = (*var->u.make_value.functions->make_value) (gdbarch, var, | |
15943 | + var->u.make_value.data); | |
15944 | break; | |
15945 | ||
15946 | default: | |
f412e1b4 | 15947 | @@ -1955,6 +2019,11 @@ clear_internalvar (struct internalvar *var) |
6ed6bacf AM |
15948 | xfree (var->u.string); |
15949 | break; | |
15950 | ||
15951 | + case INTERNALVAR_MAKE_VALUE: | |
15952 | + if (var->u.make_value.functions->destroy != NULL) | |
15953 | + var->u.make_value.functions->destroy (var->u.make_value.data); | |
15954 | + break; | |
15955 | + | |
15956 | default: | |
15957 | break; | |
15958 | } | |
f412e1b4 | 15959 | @@ -2009,6 +2078,38 @@ call_internal_function (struct gdbarch *gdbarch, |
7566401a ER |
15960 | return (*ifn->handler) (gdbarch, language, ifn->cookie, argc, argv); |
15961 | } | |
15962 | ||
6ed6bacf | 15963 | +#if 0 |
7566401a | 15964 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ |
3a58abaf | 15965 | + |
7566401a ER |
15966 | +static void |
15967 | +value_types_mark_used (void) | |
3a58abaf | 15968 | +{ |
7566401a ER |
15969 | + struct internalvar *var; |
15970 | + struct value_history_chunk *chunk; | |
3a58abaf | 15971 | + |
7566401a ER |
15972 | + for (var = internalvars; var != NULL; var = var->next) |
15973 | + switch (var->kind) | |
15974 | + { | |
15975 | + case INTERNALVAR_VALUE: | |
15976 | + type_mark_used (value_type (var->u.value)); | |
15977 | + break; | |
3a58abaf | 15978 | + |
7566401a ER |
15979 | + case INTERNALVAR_INTEGER: |
15980 | + type_mark_used (var->u.integer.type); | |
15981 | + break; | |
7566401a | 15982 | + } |
3a58abaf | 15983 | + |
7566401a ER |
15984 | + for (chunk = value_history_chain; chunk != NULL; chunk = chunk->next) |
15985 | + { | |
15986 | + int i; | |
3a58abaf | 15987 | + |
7566401a ER |
15988 | + for (i = 0; i < ARRAY_SIZE (chunk->values); i++) |
15989 | + if (chunk->values[i]) | |
15990 | + type_mark_used (value_type (chunk->values[i])); | |
15991 | + } | |
3a58abaf | 15992 | +} |
6ed6bacf | 15993 | +#endif |
3a58abaf | 15994 | + |
7566401a ER |
15995 | /* The 'function' command. This does nothing -- it is just a |
15996 | placeholder to let "help function NAME" work. This is also used as | |
15997 | the implementation of the sub-command that is created when | |
f412e1b4 | 15998 | @@ -2056,11 +2157,10 @@ preserve_one_value (struct value *value, struct objfile *objfile, |
7566401a ER |
15999 | htab_t copied_types) |
16000 | { | |
16001 | if (TYPE_OBJFILE (value->type) == objfile) | |
16002 | - value->type = copy_type_recursive (objfile, value->type, copied_types); | |
16003 | + value->type = copy_type_recursive (value->type, copied_types); | |
16004 | ||
16005 | if (TYPE_OBJFILE (value->enclosing_type) == objfile) | |
16006 | - value->enclosing_type = copy_type_recursive (objfile, | |
16007 | - value->enclosing_type, | |
16008 | + value->enclosing_type = copy_type_recursive (value->enclosing_type, | |
16009 | copied_types); | |
16010 | } | |
16011 | ||
f412e1b4 | 16012 | @@ -2075,7 +2175,7 @@ preserve_one_internalvar (struct internalvar *var, struct objfile *objfile, |
7566401a ER |
16013 | case INTERNALVAR_INTEGER: |
16014 | if (var->u.integer.type && TYPE_OBJFILE (var->u.integer.type) == objfile) | |
16015 | var->u.integer.type | |
16016 | - = copy_type_recursive (objfile, var->u.integer.type, copied_types); | |
16017 | + = copy_type_recursive (var->u.integer.type, copied_types); | |
16018 | break; | |
16019 | ||
7566401a | 16020 | case INTERNALVAR_VALUE: |
f412e1b4 | 16021 | @@ -3137,9 +3237,26 @@ coerce_ref_if_computed (const struct value *arg) |
51a5ef0f PS |
16022 | struct value * |
16023 | coerce_ref (struct value *arg) | |
16024 | { | |
16025 | - struct type *value_type_arg_tmp = check_typedef (value_type (arg)); | |
16026 | + struct type *value_type_arg_tmp; | |
f412e1b4 PS |
16027 | struct value *retval; |
16028 | ||
51a5ef0f | 16029 | + if (TYPE_DYNAMIC (value_type (arg))) |
7566401a | 16030 | + { |
51a5ef0f PS |
16031 | + struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); |
16032 | + CORE_ADDR address; | |
3a58abaf | 16033 | + |
51a5ef0f PS |
16034 | + value_type_arg_tmp = value_type (arg); |
16035 | + address = value_raw_address (arg); | |
16036 | + value_type_arg_tmp = object_address_get_data (value_type_arg_tmp, | |
16037 | + &address); | |
16038 | + if (! value_type_arg_tmp) | |
16039 | + error (_("Attempt to coerce non-valid value.")); | |
16040 | + arg = value_at_lazy (value_type_arg_tmp, address); | |
16041 | + do_cleanups (cleanups); | |
7566401a | 16042 | + } |
51a5ef0f PS |
16043 | + else |
16044 | + value_type_arg_tmp = check_typedef (value_type (arg)); | |
f412e1b4 PS |
16045 | + |
16046 | retval = coerce_ref_if_computed (arg); | |
16047 | if (retval) | |
16048 | return retval; | |
16049 | @@ -3241,4 +3358,10 @@ VARIABLE is already initialized.")); | |
7566401a ER |
16050 | add_prefix_cmd ("function", no_class, function_command, _("\ |
16051 | Placeholder command for showing help on convenience functions."), | |
16052 | &functionlist, "function ", 0, &cmdlist); | |
d566d21e | 16053 | + |
7566401a | 16054 | + make_final_cleanup (value_history_cleanup, NULL); |
d566d21e | 16055 | + |
6ed6bacf | 16056 | +#if 0 |
7566401a | 16057 | + observer_attach_mark_used (value_types_mark_used); |
6ed6bacf | 16058 | +#endif |
7566401a | 16059 | } |
f412e1b4 PS |
16060 | diff --git a/gdb/value.h b/gdb/value.h |
16061 | index 4727755..d8d22c8 100644 | |
16062 | --- a/gdb/value.h | |
16063 | +++ b/gdb/value.h | |
16064 | @@ -488,6 +488,10 @@ extern struct value *value_from_decfloat (struct type *type, | |
7566401a | 16065 | const gdb_byte *decbytes); |
6ed6bacf | 16066 | extern struct value *value_from_history_ref (char *, char **); |
7566401a ER |
16067 | |
16068 | +extern const char *object_address_data_not_valid (struct type *type); | |
51a5ef0f PS |
16069 | +extern struct type *object_address_get_data (struct type *type, |
16070 | + CORE_ADDR *address_return); | |
d566d21e | 16071 | + |
7566401a ER |
16072 | extern struct value *value_at (struct type *type, CORE_ADDR addr); |
16073 | extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr); | |
16074 | ||
f412e1b4 | 16075 | @@ -717,10 +721,52 @@ extern struct internalvar *lookup_only_internalvar (const char *name); |
6ed6bacf AM |
16076 | |
16077 | extern struct internalvar *create_internalvar (const char *name); | |
3a58abaf | 16078 | |
6ed6bacf AM |
16079 | -typedef struct value * (*internalvar_make_value) (struct gdbarch *, |
16080 | - struct internalvar *); | |
16081 | +/* An internalvar can be dynamically computed by supplying a vector of | |
16082 | + function pointers to perform various operations. */ | |
16083 | + | |
16084 | +struct internalvar_funcs | |
16085 | +{ | |
16086 | + /* Compute the value of the variable. The DATA argument passed to | |
16087 | + the function is the same argument that was passed to | |
16088 | + `create_internalvar_type_lazy'. */ | |
16089 | + | |
16090 | + struct value *(*make_value) (struct gdbarch *arch, | |
16091 | + struct internalvar *var, | |
16092 | + void *data); | |
16093 | + | |
16094 | + /* Update the agent expression EXPR with bytecode to compute the | |
16095 | + value. VALUE is the agent value we are updating. The DATA | |
16096 | + argument passed to this function is the same argument that was | |
16097 | + passed to `create_internalvar_type_lazy'. If this pointer is | |
16098 | + NULL, then the internalvar cannot be compiled to an agent | |
16099 | + expression. */ | |
16100 | + | |
16101 | + void (*compile_to_ax) (struct internalvar *var, | |
16102 | + struct agent_expr *expr, | |
16103 | + struct axs_value *value, | |
16104 | + void *data); | |
16105 | + | |
16106 | + /* If non-NULL, this is called to destroy DATA. The DATA argument | |
16107 | + passed to this function is the same argument that was passed to | |
16108 | + `create_internalvar_type_lazy'. */ | |
16109 | + | |
16110 | + void (*destroy) (void *data); | |
16111 | +}; | |
16112 | + | |
16113 | extern struct internalvar * | |
16114 | - create_internalvar_type_lazy (char *name, internalvar_make_value fun); | |
16115 | +create_internalvar_type_lazy (const char *name, | |
16116 | + const struct internalvar_funcs *funcs, | |
16117 | + void *data); | |
16118 | + | |
16119 | +/* Compile an internal variable to an agent expression. VAR is the | |
16120 | + variable to compile; EXPR and VALUE are the agent expression we are | |
16121 | + updating. This will return 0 if there is no known way to compile | |
16122 | + VAR, and 1 if VAR was successfully compiled. It may also throw an | |
16123 | + exception on error. */ | |
16124 | + | |
16125 | +extern int compile_internalvar_to_ax (struct internalvar *var, | |
16126 | + struct agent_expr *expr, | |
16127 | + struct axs_value *value); | |
3a58abaf | 16128 | |
6ed6bacf | 16129 | extern struct internalvar *lookup_internalvar (const char *name); |
3a58abaf | 16130 | |
f412e1b4 PS |
16131 | diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c |
16132 | index e111d41..18e3180 100644 | |
16133 | --- a/gdb/windows-tdep.c | |
16134 | +++ b/gdb/windows-tdep.c | |
16135 | @@ -268,7 +268,7 @@ static const struct lval_funcs tlb_value_funcs = | |
6ed6bacf AM |
16136 | if there's no object available. */ |
16137 | ||
16138 | static struct value * | |
16139 | -tlb_make_value (struct gdbarch *gdbarch, struct internalvar *var) | |
16140 | +tlb_make_value (struct gdbarch *gdbarch, struct internalvar *var, void *ignore) | |
16141 | { | |
16142 | if (target_has_stack && !ptid_equal (inferior_ptid, null_ptid)) | |
16143 | { | |
16144 | @@ -425,6 +425,15 @@ init_w32_command_list (void) | |
16145 | } | |
16146 | } | |
16147 | ||
16148 | +/* Implementation of `tlb' variable. */ | |
16149 | + | |
16150 | +static const struct internalvar_funcs tlb_funcs = | |
16151 | +{ | |
16152 | + tlb_make_value, | |
16153 | + NULL, | |
16154 | + NULL | |
16155 | +}; | |
16156 | + | |
16157 | void | |
16158 | _initialize_windows_tdep (void) | |
16159 | { | |
16160 | @@ -451,5 +460,5 @@ even if their meaning is unknown."), | |
16161 | value with a void typed value, and when we get here, gdbarch | |
16162 | isn't initialized yet. At this point, we're quite sure there | |
16163 | isn't another convenience variable of the same name. */ | |
16164 | - create_internalvar_type_lazy ("_tlb", tlb_make_value); | |
16165 | + create_internalvar_type_lazy ("_tlb", &tlb_funcs, NULL); | |
16166 | } | |
f412e1b4 PS |
16167 | diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c |
16168 | index 1a2bb14..d43e946 100644 | |
16169 | --- a/gdb/xcoffread.c | |
16170 | +++ b/gdb/xcoffread.c | |
16171 | @@ -3123,6 +3123,7 @@ static const struct sym_fns xcoff_sym_fns = | |
6ed6bacf AM |
16172 | default_symfile_segments, /* Get segment information from a file. */ |
16173 | aix_process_linenos, | |
16174 | default_symfile_relocate, /* Relocate a debug section. */ | |
16175 | + NULL, /* sym_probe_fns */ | |
16176 | &psym_functions | |
16177 | }; | |
3a58abaf | 16178 |