]>
Commit | Line | Data |
---|---|---|
3a58abaf AM |
1 | http://sourceware.org/gdb/wiki/ProjectArcher |
2 | http://sourceware.org/gdb/wiki/ArcherBranchManagement | |
3 | ||
4 | GIT snapshot: | |
ab050a48 | 5 | commit 16276c1aad1366b92e687c72cab30192280e1906 |
3a58abaf AM |
6 | |
7 | branch `archer' - the merge of branches: | |
7566401a | 8 | archer-tromey-call-frame-cfa |
3a58abaf | 9 | archer-tromey-delayed-symfile |
7566401a ER |
10 | archer-tromey-dw-op-value |
11 | archer-jankratochvil-vla | |
12 | archer-jankratochvil-misc | |
13 | archer-keiths-expr-cumulative | |
14 | archer-tromey-python | |
15 | archer-jankratochvil-fortran-module | |
16 | archer-jankratochvil-watchpoint | |
17 | archer-jankratochvil-bp_location-accel | |
18 | archer-pmuldoon-next-over-throw | |
3a58abaf AM |
19 | |
20 | ||
21 | diff --git a/gdb/Makefile.in b/gdb/Makefile.in | |
ab050a48 | 22 | index 7d53205..319fac4 100644 |
3a58abaf AM |
23 | --- a/gdb/Makefile.in |
24 | +++ b/gdb/Makefile.in | |
7566401a ER |
25 | @@ -169,6 +169,10 @@ TARGET_SYSTEM_ROOT_DEFINE = @TARGET_SYSTEM_ROOT_DEFINE@ |
26 | # Did the user give us a --with-gdb-datadir option? | |
ab050a48 | 27 | GDB_DATADIR = @GDB_DATADIR@ |
3a58abaf | 28 | |
3a58abaf AM |
29 | +# The argument to --with-pythondir. If not given, this is |
30 | +# GDB_DATADIR_PATH/python. | |
31 | +pythondir = @pythondir@ | |
32 | + | |
33 | # Helper code from gnulib. | |
34 | LIBGNU = gnulib/libgnu.a | |
35 | INCGNU = -I$(srcdir)/gnulib -Ignulib | |
7566401a | 36 | @@ -267,21 +271,37 @@ SUBDIR_TUI_CFLAGS= \ |
3a58abaf AM |
37 | # |
38 | SUBDIR_PYTHON_OBS = \ | |
39 | python.o \ | |
7566401a ER |
40 | + py-block.o \ |
41 | + py-breakpoint.o \ | |
42 | py-cmd.o \ | |
43 | py-frame.o \ | |
44 | py-function.o \ | |
45 | + py-hooks.o \ | |
46 | + py-inferior.o \ | |
47 | + py-infthread.o \ | |
48 | py-objfile.o \ | |
49 | + py-param.o \ | |
50 | py-prettyprint.o \ | |
51 | + py-symbol.o \ | |
52 | + py-symtab.o \ | |
53 | py-type.o \ | |
54 | py-utils.o \ | |
55 | py-value.o | |
3a58abaf AM |
56 | SUBDIR_PYTHON_SRCS = \ |
57 | python/python.c \ | |
7566401a ER |
58 | + python/py-block.c \ |
59 | + python/py-breakpoint.c \ | |
60 | python/py-cmd.c \ | |
61 | python/py-frame.c \ | |
62 | python/py-function.c \ | |
63 | + python/py-hooks.c \ | |
64 | + python/py-inferior.c \ | |
65 | + python/py-infthread.c \ | |
66 | python/py-objfile.c \ | |
67 | + python/py-param.c \ | |
68 | python/py-prettyprint.c \ | |
69 | + python/py-symbol.c \ | |
70 | + python/py-symtab.c \ | |
71 | python/py-type.c \ | |
72 | python/py-utils.c \ | |
73 | python/py-value.c | |
74 | @@ -750,7 +770,7 @@ config/rs6000/nm-rs6000.h top.h bsd-kvm.h gdb-stabs.h reggroups.h \ | |
3a58abaf AM |
75 | annotate.h sim-regno.h dictionary.h dfp.h main.h frame-unwind.h \ |
76 | remote-fileio.h i386-linux-tdep.h vax-tdep.h objc-lang.h \ | |
7566401a ER |
77 | sentinel-frame.h bcache.h symfile.h windows-tdep.h linux-tdep.h \ |
78 | -gdb_usleep.h jit.h xml-syscall.h ada-operator.inc | |
79 | +gdb_usleep.h jit.h xml-syscall.h ada-operator.inc python/python.h python/python-internal.h | |
3a58abaf AM |
80 | |
81 | # Header files that already have srcdir in them, or which are in objdir. | |
82 | ||
7566401a | 83 | @@ -874,7 +894,7 @@ generated_files = config.h observer.h observer.inc ada-lex.c \ |
3a58abaf AM |
84 | $(COMPILE) $< |
85 | $(POSTCOMPILE) | |
86 | ||
7566401a ER |
87 | -all: gdb$(EXEEXT) $(CONFIG_ALL) xml-syscall-copy |
88 | +all: gdb$(EXEEXT) $(CONFIG_ALL) xml-syscall-copy .gdbinit | |
3a58abaf AM |
89 | @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do |
90 | .PHONY: all-tui | |
91 | all-tui: $(TUI)$(EXEEXT) | |
7566401a | 92 | @@ -1264,6 +1284,12 @@ stamp-h: $(srcdir)/config.in config.status |
3a58abaf AM |
93 | CONFIG_LINKS= \ |
94 | $(SHELL) config.status | |
95 | ||
7566401a | 96 | +.gdbinit: $(srcdir)/gdbinit.in config.status |
3a58abaf AM |
97 | + CONFIG_FILES=".gdbinit:gdbinit.in" \ |
98 | + CONFIG_COMMANDS= \ | |
99 | + CONFIG_HEADERS= \ | |
100 | + $(SHELL) config.status | |
101 | + | |
7566401a | 102 | config.status: $(srcdir)/configure configure.tgt configure.host |
3a58abaf AM |
103 | $(SHELL) config.status --recheck |
104 | ||
7566401a | 105 | @@ -1963,6 +1989,14 @@ python.o: $(srcdir)/python/python.c |
3a58abaf AM |
106 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c |
107 | $(POSTCOMPILE) | |
108 | ||
7566401a ER |
109 | +py-block.o: $(srcdir)/python/py-block.c |
110 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-block.c | |
3a58abaf AM |
111 | + $(POSTCOMPILE) |
112 | + | |
7566401a ER |
113 | +py-breakpoint.o: $(srcdir)/python/py-breakpoint.c |
114 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-breakpoint.c | |
3a58abaf AM |
115 | + $(POSTCOMPILE) |
116 | + | |
7566401a ER |
117 | py-cmd.o: $(srcdir)/python/py-cmd.c |
118 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-cmd.c | |
119 | $(POSTCOMPILE) | |
120 | @@ -1975,14 +2009,38 @@ py-function.o: $(srcdir)/python/py-function.c | |
121 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-function.c | |
3a58abaf AM |
122 | $(POSTCOMPILE) |
123 | ||
7566401a ER |
124 | +py-hooks.o: $(srcdir)/python/py-hooks.c |
125 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-hooks.c | |
3a58abaf AM |
126 | + $(POSTCOMPILE) |
127 | + | |
7566401a ER |
128 | +py-inferior.o: $(srcdir)/python/py-inferior.c |
129 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-inferior.c | |
3a58abaf AM |
130 | + $(POSTCOMPILE) |
131 | + | |
7566401a ER |
132 | +py-infthread.o: $(srcdir)/python/py-infthread.c |
133 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-infthread.c | |
3a58abaf AM |
134 | + $(POSTCOMPILE) |
135 | + | |
7566401a ER |
136 | py-objfile.o: $(srcdir)/python/py-objfile.c |
137 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-objfile.c | |
138 | $(POSTCOMPILE) | |
139 | ||
140 | +py-param.o: $(srcdir)/python/py-param.c | |
141 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-param.c | |
3a58abaf AM |
142 | + $(POSTCOMPILE) |
143 | + | |
7566401a ER |
144 | py-prettyprint.o: $(srcdir)/python/py-prettyprint.c |
145 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-prettyprint.c | |
146 | $(POSTCOMPILE) | |
147 | ||
148 | +py-symbol.o: $(srcdir)/python/py-symbol.c | |
149 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symbol.c | |
3a58abaf AM |
150 | + $(POSTCOMPILE) |
151 | + | |
7566401a ER |
152 | +py-symtab.o: $(srcdir)/python/py-symtab.c |
153 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symtab.c | |
3a58abaf AM |
154 | + $(POSTCOMPILE) |
155 | + | |
7566401a ER |
156 | py-type.o: $(srcdir)/python/py-type.c |
157 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-type.c | |
3a58abaf | 158 | $(POSTCOMPILE) |
7566401a ER |
159 | @@ -1995,6 +2053,36 @@ py-value.o: $(srcdir)/python/py-value.c |
160 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-value.c | |
3a58abaf AM |
161 | $(POSTCOMPILE) |
162 | ||
163 | +# All python library files, with the "python/lib" stripped off. | |
164 | +# Note that we should only install files in the "gdb" module. | |
7566401a | 165 | +PY_FILES = gdb/FrameIterator.py gdb/FrameWrapper.py gdb/command/alias.py \ |
3a58abaf | 166 | + gdb/command/backtrace.py gdb/command/require.py \ |
7566401a | 167 | + gdb/command/pahole.py gdb/command/upto.py gdb/command/__init__.py \ |
3a58abaf | 168 | + gdb/command/ignore_errors.py gdb/command/save_breakpoints.py \ |
7566401a ER |
169 | + gdb/function/caller_is.py gdb/function/in_scope.py \ |
170 | + gdb/function/__init__.py gdb/backtrace.py gdb/__init__.py | |
3a58abaf AM |
171 | + |
172 | +# Install the Python library. Python library files go under | |
173 | +# $(pythondir). | |
174 | +install-python: | |
175 | + files='$(PY_FILES)'; for file in $$files; do \ | |
176 | + dir=`echo "$$file" | sed 's,/[^/]*$$,,'`; \ | |
177 | + $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(pythondir)/$$dir; \ | |
178 | + $(INSTALL_DATA) $(srcdir)/python/lib/$$file $(DESTDIR)$(pythondir)/$$file; \ | |
179 | + done | |
180 | + | |
181 | +# Other packages may have their files installed in $(pythondir). | |
182 | +uninstall-python: | |
183 | + files='$(PY_FILES)'; for file in $$files; do \ | |
184 | + slashdir=`echo "/$$file" | sed 's,/[^/]*$$,,'`; \ | |
185 | + rm -f $(DESTDIR)$(pythondir)/$$file; \ | |
186 | + while test "x$$file" != "x$$slashdir"; do \ | |
187 | + rmdir 2>/dev/null "$(DESTDIR)$(pythondir)$$slashdir"; \ | |
188 | + file="$$slashdir"; \ | |
189 | + slashdir=`echo "$$file" | sed 's,/[^/]*$$,,'`; \ | |
190 | + done \ | |
191 | + done | |
192 | + | |
193 | # | |
194 | # Dependency tracking. Most of this is conditional on GNU Make being | |
195 | # found by configure; if GNU Make is not found, we fall back to a | |
196 | diff --git a/gdb/NEWS b/gdb/NEWS | |
ab050a48 | 197 | index 8d32c34..f7ea21b 100644 |
3a58abaf AM |
198 | --- a/gdb/NEWS |
199 | +++ b/gdb/NEWS | |
ab050a48 | 200 | @@ -476,6 +476,13 @@ x86/x86_64 Darwin i[34567]86-*-darwin* |
7566401a ER |
201 | |
202 | x86_64 MinGW x86_64-*-mingw* | |
203 | ||
204 | +* New native configurations | |
3a58abaf | 205 | + |
7566401a ER |
206 | +x86/x86_64 Darwin i[34567]86-*-darwin* |
207 | + | |
208 | +info os processes | |
209 | + Show operating system information about processes. | |
210 | + | |
211 | * New targets | |
3a58abaf | 212 | |
7566401a | 213 | Lattice Mico32 lm32-* |
3a58abaf | 214 | diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c |
7566401a | 215 | index 9b5d2c6..61676a9 100644 |
3a58abaf AM |
216 | --- a/gdb/ada-lang.c |
217 | +++ b/gdb/ada-lang.c | |
7566401a | 218 | @@ -1621,7 +1621,7 @@ ada_type_of_array (struct value *arr, int bounds) |
3a58abaf AM |
219 | return NULL; |
220 | while (arity > 0) | |
221 | { | |
7566401a ER |
222 | - struct type *range_type = alloc_type_copy (value_type (arr)); |
223 | + struct type *range_type = alloc_type_copy (value_type (arr)); | |
224 | struct type *array_type = alloc_type_copy (value_type (arr)); | |
3a58abaf AM |
225 | struct value *low = desc_one_bound (descriptor, arity, 0); |
226 | struct value *high = desc_one_bound (descriptor, arity, 1); | |
7566401a | 227 | @@ -4727,14 +4727,10 @@ ada_lookup_symbol (const char *name, const struct block *block0, |
3a58abaf | 228 | |
7566401a ER |
229 | static struct symbol * |
230 | ada_lookup_symbol_nonlocal (const char *name, | |
231 | - const char *linkage_name, | |
232 | const struct block *block, | |
233 | const domain_enum domain) | |
3a58abaf | 234 | { |
7566401a ER |
235 | - if (linkage_name == NULL) |
236 | - linkage_name = name; | |
237 | - return ada_lookup_symbol (linkage_name, block_static_block (block), domain, | |
238 | - NULL); | |
239 | + return ada_lookup_symbol (name, block_static_block (block), domain, NULL); | |
240 | } | |
3a58abaf | 241 | |
3a58abaf | 242 | |
7566401a | 243 | @@ -10839,6 +10835,40 @@ ada_operator_length (struct expression *exp, int pc, int *oplenp, int *argsp) |
3a58abaf | 244 | } |
3a58abaf AM |
245 | } |
246 | ||
7566401a ER |
247 | +/* Implementation of the exp_descriptor method operator_check. */ |
248 | + | |
249 | +static int | |
250 | +ada_operator_check (struct expression *exp, int pos, | |
251 | + int (*type_func) (struct type *type, void *data), | |
252 | + int (*objfile_func) (struct objfile *objfile, void *data), | |
253 | + void *data) | |
254 | +{ | |
255 | + const union exp_element *const elts = exp->elts; | |
256 | + struct type *type = NULL; | |
257 | + | |
258 | + switch (elts[pos].opcode) | |
259 | + { | |
260 | + case UNOP_IN_RANGE: | |
261 | + case UNOP_QUAL: | |
262 | + type = elts[pos + 1].type; | |
263 | + break; | |
264 | + | |
265 | + default: | |
266 | + return operator_check_standard (exp, pos, type_func, objfile_func, | |
267 | + data); | |
268 | + } | |
269 | + | |
270 | + /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL. */ | |
271 | + | |
272 | + if (type && type_func && (*type_func) (type, data)) | |
273 | + return 1; | |
274 | + if (type && TYPE_OBJFILE (type) && objfile_func | |
275 | + && (*objfile_func) (TYPE_OBJFILE (type), data)) | |
276 | + return 1; | |
277 | + | |
278 | + return 0; | |
279 | +} | |
280 | + | |
281 | static char * | |
282 | ada_op_name (enum exp_opcode opcode) | |
283 | { | |
284 | @@ -11227,6 +11257,7 @@ parse (void) | |
285 | static const struct exp_descriptor ada_exp_descriptor = { | |
286 | ada_print_subexp, | |
287 | ada_operator_length, | |
288 | + ada_operator_check, | |
289 | ada_op_name, | |
290 | ada_dump_subexp_body, | |
291 | ada_evaluate_subexp | |
292 | diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c | |
ab050a48 | 293 | index 7d8461c..fc4b3e0 100644 |
7566401a ER |
294 | --- a/gdb/amd64-linux-nat.c |
295 | +++ b/gdb/amd64-linux-nat.c | |
296 | @@ -270,6 +270,8 @@ amd64_linux_dr_get (ptid_t ptid, int regnum) | |
297 | return value; | |
3a58abaf | 298 | } |
3a58abaf | 299 | |
7566401a ER |
300 | +/* Set debug register REGNUM to VALUE in only the one LWP of PTID. */ |
301 | + | |
3a58abaf | 302 | static void |
7566401a | 303 | amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value) |
3a58abaf | 304 | { |
7566401a ER |
305 | @@ -286,6 +288,8 @@ amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value) |
306 | perror_with_name (_("Couldn't write debug register")); | |
3a58abaf AM |
307 | } |
308 | ||
7566401a | 309 | +/* Set DR_CONTROL to ADDR in all LWPs of LWP_LIST. */ |
3a58abaf | 310 | + |
7566401a ER |
311 | static void |
312 | amd64_linux_dr_set_control (unsigned long control) | |
3a58abaf | 313 | { |
7566401a ER |
314 | @@ -297,6 +301,8 @@ amd64_linux_dr_set_control (unsigned long control) |
315 | amd64_linux_dr_set (ptid, DR_CONTROL, control); | |
3a58abaf AM |
316 | } |
317 | ||
7566401a ER |
318 | +/* Set address REGNUM (zero based) to ADDR in all LWPs of LWP_LIST. */ |
319 | + | |
320 | static void | |
321 | amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr) | |
3a58abaf | 322 | { |
7566401a ER |
323 | @@ -310,18 +316,55 @@ amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr) |
324 | amd64_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr); | |
3a58abaf AM |
325 | } |
326 | ||
7566401a ER |
327 | +/* Set address REGNUM (zero based) to zero in all LWPs of LWP_LIST. */ |
328 | + | |
3a58abaf | 329 | static void |
7566401a | 330 | amd64_linux_dr_reset_addr (int regnum) |
3a58abaf | 331 | { |
7566401a | 332 | amd64_linux_dr_set_addr (regnum, 0); |
3a58abaf AM |
333 | } |
334 | ||
7566401a ER |
335 | +/* Get DR_STATUS from only the one LWP of INFERIOR_PTID. */ |
336 | + | |
337 | static unsigned long | |
338 | amd64_linux_dr_get_status (void) | |
3a58abaf | 339 | { |
7566401a | 340 | return amd64_linux_dr_get (inferior_ptid, DR_STATUS); |
3a58abaf AM |
341 | } |
342 | ||
ab050a48 | 343 | +/* Unset MASK bits in DR_STATUS in all LWPs of LWP_LIST. */ |
7566401a ER |
344 | + |
345 | +static void | |
346 | +amd64_linux_dr_unset_status (unsigned long mask) | |
347 | +{ | |
348 | + struct lwp_info *lp; | |
349 | + ptid_t ptid; | |
350 | + | |
351 | + ALL_LWPS (lp, ptid) | |
352 | + { | |
353 | + unsigned long value; | |
354 | + | |
355 | + value = amd64_linux_dr_get (ptid, DR_STATUS); | |
356 | + value &= ~mask; | |
357 | + amd64_linux_dr_set (ptid, DR_STATUS, value); | |
358 | + } | |
359 | +} | |
360 | + | |
361 | +/* See i386_dr_low_type.detach. Do not use wrappers amd64_linux_dr_set_control | |
362 | + or amd64_linux_dr_reset_addr as they would modify the register cache | |
363 | + (amd64_linux_dr). */ | |
364 | + | |
365 | +static void | |
366 | +amd64_linux_dr_detach (void) | |
367 | +{ | |
368 | + int regnum; | |
369 | + | |
370 | + amd64_linux_dr_set (inferior_ptid, DR_CONTROL, 0); | |
371 | + amd64_linux_dr_unset_status (~0UL); | |
372 | + for (regnum = DR_FIRSTADDR; regnum <= DR_LASTADDR; regnum++) | |
373 | + amd64_linux_dr_set (inferior_ptid, regnum, 0); | |
374 | +} | |
375 | + | |
376 | static void | |
377 | amd64_linux_new_thread (ptid_t ptid) | |
3a58abaf | 378 | { |
7566401a ER |
379 | @@ -672,6 +715,8 @@ _initialize_amd64_linux_nat (void) |
380 | i386_dr_low.set_addr = amd64_linux_dr_set_addr; | |
381 | i386_dr_low.reset_addr = amd64_linux_dr_reset_addr; | |
382 | i386_dr_low.get_status = amd64_linux_dr_get_status; | |
383 | + i386_dr_low.unset_status = amd64_linux_dr_unset_status; | |
384 | + i386_dr_low.detach = amd64_linux_dr_detach; | |
385 | i386_set_debug_register_length (8); | |
386 | ||
387 | /* Override the GNU/Linux inferior startup hook. */ | |
3a58abaf | 388 | diff --git a/gdb/block.c b/gdb/block.c |
7566401a | 389 | index 97ea67a..b20beeb 100644 |
3a58abaf AM |
390 | --- a/gdb/block.c |
391 | +++ b/gdb/block.c | |
7566401a ER |
392 | @@ -227,8 +227,9 @@ block_set_scope (struct block *block, const char *scope, |
393 | BLOCK_NAMESPACE (block)->scope = scope; | |
3a58abaf AM |
394 | } |
395 | ||
7566401a | 396 | -/* This returns the using directives list associated with BLOCK, if |
3a58abaf | 397 | - any. */ |
7566401a | 398 | +/* This returns the first using directives associated with BLOCK, if |
3a58abaf AM |
399 | + any. Each BLOCK_NAMESPACE()->USING already contains all the namespaces |
400 | + imported at that code point - even those from its parent blocks. */ | |
401 | ||
402 | struct using_direct * | |
403 | block_using (const struct block *block) | |
7566401a ER |
404 | @@ -318,6 +319,25 @@ allocate_block (struct obstack *obstack) |
405 | BLOCK_SUPERBLOCK (bl) = NULL; | |
406 | BLOCK_DICT (bl) = NULL; | |
407 | BLOCK_NAMESPACE (bl) = NULL; | |
408 | + BLOCK_FORTRAN_USE (bl) = NULL; | |
3a58abaf | 409 | |
7566401a | 410 | return bl; |
3a58abaf | 411 | } |
3a58abaf | 412 | + |
7566401a ER |
413 | +/* Return OBJFILE in which BLOCK is located or NULL if we cannot find it for |
414 | + whatever reason. */ | |
415 | + | |
416 | +struct objfile * | |
417 | +block_objfile (const struct block *block) | |
3a58abaf | 418 | +{ |
7566401a | 419 | + struct symbol *func; |
3a58abaf | 420 | + |
7566401a ER |
421 | + if (block == NULL) |
422 | + return NULL; | |
3a58abaf | 423 | + |
7566401a ER |
424 | + func = block_linkage_function (block); |
425 | + if (func == NULL) | |
426 | + return NULL; | |
427 | + | |
428 | + return SYMBOL_SYMTAB (func)->objfile; | |
429 | +} | |
430 | diff --git a/gdb/block.h b/gdb/block.h | |
431 | index 53e7371..d373f8a 100644 | |
432 | --- a/gdb/block.h | |
433 | +++ b/gdb/block.h | |
434 | @@ -96,6 +96,15 @@ struct block | |
435 | cplus_specific; | |
436 | } | |
437 | language_specific; | |
438 | + | |
439 | + /* FIXME: It should be in the LANGUAGE_SPECIFIC region but the | |
440 | + BLOCK_NAMESPACE accessor is not protected by the C language check. */ | |
441 | + | |
442 | + struct | |
443 | + { | |
444 | + struct fortran_using *use; | |
445 | + } | |
446 | + fortran_specific; | |
447 | }; | |
448 | ||
449 | #define BLOCK_START(bl) (bl)->startaddr | |
450 | @@ -104,6 +113,7 @@ struct block | |
451 | #define BLOCK_SUPERBLOCK(bl) (bl)->superblock | |
452 | #define BLOCK_DICT(bl) (bl)->dict | |
453 | #define BLOCK_NAMESPACE(bl) (bl)->language_specific.cplus_specific.namespace | |
454 | +#define BLOCK_FORTRAN_USE(bl) (bl)->fortran_specific.use | |
455 | ||
456 | /* Macro to loop through all symbols in a block BL, in no particular | |
457 | order. ITER helps keep track of the iteration, and should be a | |
458 | @@ -166,4 +176,6 @@ extern const struct block *block_global_block (const struct block *block); | |
459 | ||
460 | extern struct block *allocate_block (struct obstack *obstack); | |
461 | ||
462 | +extern struct objfile *block_objfile (const struct block *block); | |
463 | + | |
464 | #endif /* BLOCK_H */ | |
465 | diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c | |
ab050a48 | 466 | index 811cdfb..0f35101 100644 |
7566401a ER |
467 | --- a/gdb/breakpoint.c |
468 | +++ b/gdb/breakpoint.c | |
469 | @@ -61,6 +61,7 @@ | |
470 | #include "valprint.h" | |
471 | #include "jit.h" | |
472 | #include "xml-syscall.h" | |
473 | +#include "parser-defs.h" | |
474 | ||
475 | /* readline include files */ | |
476 | #include "readline/readline.h" | |
477 | @@ -112,8 +113,6 @@ struct breakpoint *set_raw_breakpoint (struct gdbarch *gdbarch, | |
478 | struct symtab_and_line, | |
479 | enum bptype); | |
480 | ||
481 | -static void check_duplicates (struct breakpoint *); | |
482 | - | |
483 | static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int); | |
484 | ||
485 | static CORE_ADDR adjust_breakpoint_address (struct gdbarch *gdbarch, | |
486 | @@ -337,14 +336,14 @@ static int executing_startup; | |
487 | B ? (TMP=B->next, 1): 0; \ | |
488 | B = TMP) | |
489 | ||
490 | -/* Similar iterators for the low-level breakpoints. */ | |
491 | - | |
492 | -#define ALL_BP_LOCATIONS(B) for (B = bp_location_chain; B; B = B->global_next) | |
493 | +/* Similar iterator for the low-level breakpoints. SAFE variant is not | |
494 | + provided so update_global_location_list must not be called while executing | |
495 | + the block of ALL_BP_LOCATIONS. */ | |
496 | ||
497 | -#define ALL_BP_LOCATIONS_SAFE(B,TMP) \ | |
498 | - for (B = bp_location_chain; \ | |
499 | - B ? (TMP=B->global_next, 1): 0; \ | |
500 | - B = TMP) | |
501 | +#define ALL_BP_LOCATIONS(B,BP_TMP) \ | |
502 | + for (BP_TMP = bp_location; \ | |
503 | + BP_TMP < bp_location + bp_location_count && (B = *BP_TMP); \ | |
504 | + BP_TMP++) | |
505 | ||
506 | /* Iterator for tracepoints only. */ | |
507 | ||
508 | @@ -356,10 +355,31 @@ static int executing_startup; | |
509 | ||
510 | struct breakpoint *breakpoint_chain; | |
511 | ||
512 | -struct bp_location *bp_location_chain; | |
513 | +/* Array is sorted by bp_location_compare - primarily by the ADDRESS. */ | |
514 | + | |
515 | +static struct bp_location **bp_location; | |
516 | + | |
517 | +/* Number of elements of BP_LOCATION. */ | |
518 | + | |
519 | +static unsigned bp_location_count; | |
520 | + | |
521 | +/* Maximum alignment offset between bp_target_info.PLACED_ADDRESS and ADDRESS | |
522 | + for the current elements of BP_LOCATION which get a valid result from | |
523 | + bp_location_has_shadow. You can use it for roughly limiting the subrange of | |
524 | + BP_LOCATION to scan for shadow bytes for an address you need to read. */ | |
525 | + | |
526 | +static CORE_ADDR bp_location_placed_address_before_address_max; | |
527 | + | |
528 | +/* Maximum offset plus alignment between | |
529 | + bp_target_info.PLACED_ADDRESS + bp_target_info.SHADOW_LEN and ADDRESS for | |
530 | + the current elements of BP_LOCATION which get a valid result from | |
531 | + bp_location_has_shadow. You can use it for roughly limiting the subrange of | |
532 | + BP_LOCATION to scan for shadow bytes for an address you need to read. */ | |
533 | + | |
534 | +static CORE_ADDR bp_location_shadow_len_after_address_max; | |
535 | ||
536 | /* The locations that no longer correspond to any breakpoint, | |
537 | - unlinked from bp_location_chain, but for which a hit | |
538 | + unlinked from bp_location array, but for which a hit | |
539 | may still be reported by a target. */ | |
540 | VEC(bp_location_p) *moribund_locations = NULL; | |
3a58abaf | 541 | |
7566401a ER |
542 | @@ -582,6 +602,53 @@ get_breakpoint (int num) |
543 | } | |
3a58abaf AM |
544 | |
545 | \f | |
546 | +/* Set break condition of breakpoint B to EXP. */ | |
547 | + | |
548 | +void | |
549 | +set_breakpoint_condition (struct breakpoint *b, char *exp, int from_tty) | |
550 | +{ | |
551 | + struct bp_location *loc = b->loc; | |
552 | + | |
553 | + for (; loc; loc = loc->next) | |
554 | + { | |
555 | + if (loc->cond) | |
556 | + { | |
557 | + xfree (loc->cond); | |
558 | + loc->cond = 0; | |
559 | + } | |
560 | + } | |
561 | + | |
562 | + if (b->cond_string != NULL) | |
563 | + xfree (b->cond_string); | |
564 | + | |
565 | + if (*exp == 0) | |
566 | + { | |
567 | + b->cond_string = NULL; | |
568 | + if (from_tty) | |
569 | + printf_filtered (_("Breakpoint %d now unconditional.\n"), b->number); | |
570 | + } | |
571 | + else | |
572 | + { | |
573 | + char *arg = exp; | |
574 | + | |
575 | + /* I don't know if it matters whether this is the string the user | |
576 | + typed in or the decompiled expression. */ | |
7566401a | 577 | + b->cond_string = xstrdup (arg); |
3a58abaf AM |
578 | + b->condition_not_parsed = 0; |
579 | + for (loc = b->loc; loc; loc = loc->next) | |
580 | + { | |
581 | + arg = exp; | |
582 | + loc->cond = | |
583 | + parse_exp_1 (&arg, block_for_pc (loc->address), 0); | |
584 | + if (*arg) | |
585 | + error (_("Junk at end of expression")); | |
586 | + } | |
587 | + } | |
588 | + | |
589 | + breakpoints_changed (); | |
590 | + observer_notify_breakpoint_modified (b->number); | |
591 | +} | |
592 | + | |
593 | /* condition N EXP -- set break condition of breakpoint N to EXP. */ | |
594 | ||
595 | static void | |
7566401a | 596 | @@ -602,42 +669,7 @@ condition_command (char *arg, int from_tty) |
3a58abaf AM |
597 | ALL_BREAKPOINTS (b) |
598 | if (b->number == bnum) | |
599 | { | |
600 | - struct bp_location *loc = b->loc; | |
601 | - for (; loc; loc = loc->next) | |
602 | - { | |
603 | - if (loc->cond) | |
604 | - { | |
605 | - xfree (loc->cond); | |
606 | - loc->cond = 0; | |
607 | - } | |
608 | - } | |
609 | - if (b->cond_string != NULL) | |
610 | - xfree (b->cond_string); | |
611 | - | |
612 | - if (*p == 0) | |
613 | - { | |
614 | - b->cond_string = NULL; | |
615 | - if (from_tty) | |
616 | - printf_filtered (_("Breakpoint %d now unconditional.\n"), bnum); | |
617 | - } | |
618 | - else | |
619 | - { | |
620 | - arg = p; | |
621 | - /* I don't know if it matters whether this is the string the user | |
622 | - typed in or the decompiled expression. */ | |
7566401a | 623 | - b->cond_string = xstrdup (arg); |
3a58abaf AM |
624 | - b->condition_not_parsed = 0; |
625 | - for (loc = b->loc; loc; loc = loc->next) | |
626 | - { | |
627 | - arg = p; | |
628 | - loc->cond = | |
629 | - parse_exp_1 (&arg, block_for_pc (loc->address), 0); | |
630 | - if (*arg) | |
631 | - error (_("Junk at end of expression")); | |
632 | - } | |
633 | - } | |
634 | - breakpoints_changed (); | |
635 | - observer_notify_breakpoint_modified (b->number); | |
636 | + set_breakpoint_condition (b, p, from_tty); | |
637 | return; | |
638 | } | |
639 | ||
7566401a ER |
640 | @@ -735,35 +767,88 @@ commands_from_control_command (char *arg, struct command_line *cmd) |
641 | } | |
642 | error (_("No breakpoint number %d."), bnum); | |
643 | } | |
644 | -\f | |
3a58abaf | 645 | + |
7566401a | 646 | +/* Return non-zero if BL->TARGET_INFO contains valid information. */ |
3a58abaf AM |
647 | + |
648 | +static int | |
7566401a | 649 | +bp_location_has_shadow (struct bp_location *bl) |
3a58abaf | 650 | +{ |
7566401a ER |
651 | + if (bl->loc_type != bp_loc_software_breakpoint) |
652 | + return 0; | |
653 | + if (!bl->inserted) | |
654 | + return 0; | |
655 | + if (bl->target_info.shadow_len == 0) | |
656 | + /* bp isn't valid, or doesn't shadow memory. */ | |
3a58abaf | 657 | + return 0; |
3a58abaf AM |
658 | + return 1; |
659 | +} | |
660 | + | |
7566401a ER |
661 | /* Update BUF, which is LEN bytes read from the target address MEMADDR, |
662 | - by replacing any memory breakpoints with their shadowed contents. */ | |
663 | + by replacing any memory breakpoints with their shadowed contents. | |
3a58abaf | 664 | + |
7566401a ER |
665 | + The range of shadowed area by each bp_location is: |
666 | + b->address - bp_location_placed_address_before_address_max | |
667 | + up to b->address + bp_location_shadow_len_after_address_max | |
668 | + The range we were requested to resolve shadows for is: | |
669 | + memaddr ... memaddr + le | |
670 | + Thus the safe cutoff boundaries for performance optimization are | |
671 | + memaddr + len <= b->address - bp_location_placed_address_before_address_max | |
672 | + and: | |
673 | + b->address + bp_location_shadow_len_after_address_max <= memaddr */ | |
674 | ||
675 | void | |
676 | breakpoint_restore_shadows (gdb_byte *buf, ULONGEST memaddr, LONGEST len) | |
677 | { | |
678 | - struct bp_location *b; | |
679 | - CORE_ADDR bp_addr = 0; | |
680 | - int bp_size = 0; | |
681 | - int bptoffset = 0; | |
682 | + /* Left boundary, right boundary and media element of our binary search. */ | |
683 | + unsigned bc_l, bc_r, bc; | |
3a58abaf | 684 | + |
7566401a ER |
685 | + /* Find BC_L which is a leftmost element which may affect BUF content. It is |
686 | + safe to report lower value but a failure to report higher one. */ | |
ab050a48 BZ |
687 | |
688 | - ALL_BP_LOCATIONS (b) | |
7566401a ER |
689 | + bc_l = 0; |
690 | + bc_r = bp_location_count; | |
691 | + while (bc_l + 1 < bc_r) | |
3a58abaf | 692 | + { |
7566401a | 693 | + struct bp_location *b; |
ab050a48 | 694 | + |
7566401a ER |
695 | + bc = (bc_l + bc_r) / 2; |
696 | + b = bp_location[bc]; | |
3a58abaf | 697 | + |
7566401a ER |
698 | + if (b->address + bp_location_shadow_len_after_address_max >= b->address |
699 | + && b->address + bp_location_shadow_len_after_address_max <= memaddr) | |
700 | + bc_l = bc; | |
701 | + else | |
702 | + bc_r = bc; | |
3a58abaf | 703 | + } |
3a58abaf | 704 | + |
7566401a | 705 | + /* Now do full processing of the found relevant range of elements. */ |
3a58abaf | 706 | + |
7566401a ER |
707 | + for (bc = bc_l; bc < bp_location_count; bc++) |
708 | { | |
709 | + struct bp_location *b = bp_location[bc]; | |
710 | + CORE_ADDR bp_addr = 0; | |
711 | + int bp_size = 0; | |
712 | + int bptoffset = 0; | |
713 | + | |
714 | if (b->owner->type == bp_none) | |
715 | warning (_("reading through apparently deleted breakpoint #%d?"), | |
716 | b->owner->number); | |
717 | ||
718 | - if (b->loc_type != bp_loc_software_breakpoint) | |
719 | - continue; | |
720 | - if (!b->inserted) | |
721 | + /* Performance optimization: any futher element can no longer affect BUF | |
722 | + content. */ | |
723 | + | |
724 | + if (b->address >= bp_location_placed_address_before_address_max | |
725 | + && memaddr + len <= b->address | |
726 | + - bp_location_placed_address_before_address_max) | |
727 | + break; | |
3a58abaf | 728 | + |
7566401a ER |
729 | + if (!bp_location_has_shadow (b)) |
730 | continue; | |
731 | + | |
732 | /* Addresses and length of the part of the breakpoint that | |
733 | we need to copy. */ | |
734 | bp_addr = b->target_info.placed_address; | |
735 | bp_size = b->target_info.shadow_len; | |
736 | - if (bp_size == 0) | |
737 | - /* bp isn't valid, or doesn't shadow memory. */ | |
738 | - continue; | |
739 | ||
740 | if (bp_addr + bp_size <= memaddr) | |
741 | /* The breakpoint is entirely before the chunk of memory we | |
742 | @@ -912,7 +997,7 @@ update_watchpoint (struct breakpoint *b, int reparse) | |
743 | struct bp_location *loc; | |
744 | bpstat bs; | |
745 | ||
746 | - /* We don't free locations. They are stored in bp_location_chain and | |
747 | + /* We don't free locations. They are stored in bp_location array and | |
748 | update_global_locations will eventually delete them and remove | |
749 | breakpoints if needed. */ | |
750 | b->loc = NULL; | |
751 | @@ -1347,7 +1432,7 @@ static void | |
752 | insert_breakpoint_locations (void) | |
3a58abaf | 753 | { |
7566401a ER |
754 | struct breakpoint *bpt; |
755 | - struct bp_location *b, *temp; | |
756 | + struct bp_location *b, **bp_tmp; | |
757 | int error = 0; | |
758 | int val = 0; | |
759 | int disabled_breaks = 0; | |
760 | @@ -1360,7 +1445,7 @@ insert_breakpoint_locations (void) | |
761 | there was an error. */ | |
762 | fprintf_unfiltered (tmp_error_stream, "Warning:\n"); | |
763 | ||
764 | - ALL_BP_LOCATIONS_SAFE (b, temp) | |
765 | + ALL_BP_LOCATIONS (b, bp_tmp) | |
766 | { | |
767 | if (!should_be_inserted (b) || b->inserted) | |
768 | continue; | |
769 | @@ -1434,10 +1519,10 @@ You may have requested too many hardware breakpoints/watchpoints.\n"); | |
770 | int | |
771 | remove_breakpoints (void) | |
772 | { | |
773 | - struct bp_location *b; | |
774 | + struct bp_location *b, **bp_tmp; | |
775 | int val = 0; | |
3a58abaf | 776 | |
7566401a ER |
777 | - ALL_BP_LOCATIONS (b) |
778 | + ALL_BP_LOCATIONS (b, bp_tmp) | |
779 | { | |
780 | if (b->inserted) | |
781 | val |= remove_breakpoint (b, mark_uninserted); | |
782 | @@ -1448,10 +1533,10 @@ remove_breakpoints (void) | |
783 | int | |
784 | remove_hw_watchpoints (void) | |
785 | { | |
786 | - struct bp_location *b; | |
787 | + struct bp_location *b, **bp_tmp; | |
788 | int val = 0; | |
3a58abaf | 789 | |
7566401a ER |
790 | - ALL_BP_LOCATIONS (b) |
791 | + ALL_BP_LOCATIONS (b, bp_tmp) | |
792 | { | |
793 | if (b->inserted && b->loc_type == bp_loc_hardware_watchpoint) | |
794 | val |= remove_breakpoint (b, mark_uninserted); | |
795 | @@ -1462,7 +1547,7 @@ remove_hw_watchpoints (void) | |
796 | int | |
797 | reattach_breakpoints (int pid) | |
798 | { | |
799 | - struct bp_location *b; | |
800 | + struct bp_location *b, **bp_tmp; | |
801 | int val; | |
802 | struct cleanup *old_chain = save_inferior_ptid (); | |
803 | struct ui_file *tmp_error_stream = mem_fileopen (); | |
804 | @@ -1471,7 +1556,7 @@ reattach_breakpoints (int pid) | |
805 | make_cleanup_ui_file_delete (tmp_error_stream); | |
806 | ||
807 | inferior_ptid = pid_to_ptid (pid); | |
808 | - ALL_BP_LOCATIONS (b) | |
809 | + ALL_BP_LOCATIONS (b, bp_tmp) | |
810 | { | |
811 | if (b->inserted) | |
812 | { | |
813 | @@ -1569,12 +1654,42 @@ create_longjmp_master_breakpoint (char *func_name) | |
814 | update_global_location_list (1); | |
815 | } | |
3a58abaf | 816 | |
7566401a | 817 | +/* Install a master breakpoint on the unwinder's debug hook. */ |
3a58abaf | 818 | + |
7566401a ER |
819 | +void |
820 | +create_exception_master_breakpoint (void) | |
3a58abaf | 821 | +{ |
7566401a | 822 | + struct objfile *objfile; |
3a58abaf | 823 | + |
7566401a ER |
824 | + ALL_OBJFILES (objfile) |
825 | + { | |
826 | + struct minimal_symbol *debug_hook; | |
3a58abaf | 827 | + |
7566401a ER |
828 | + debug_hook = lookup_minimal_symbol_text ("_Unwind_DebugHook", objfile); |
829 | + if (debug_hook != NULL) | |
830 | + { | |
831 | + CORE_ADDR pc; | |
832 | + struct breakpoint *b; | |
833 | + | |
834 | + pc = find_function_start_pc (get_objfile_arch (objfile), | |
835 | + SYMBOL_VALUE_ADDRESS (debug_hook), | |
836 | + SYMBOL_OBJ_SECTION (debug_hook)); | |
837 | + b = create_internal_breakpoint (get_objfile_arch (objfile), | |
838 | + pc, bp_exception_master); | |
839 | + b->addr_string = xstrdup ("_Unwind_DebugHook"); | |
840 | + b->enable_state = bp_disabled; | |
841 | + } | |
842 | + } | |
3a58abaf | 843 | + |
3a58abaf AM |
844 | + update_global_location_list (1); |
845 | +} | |
846 | + | |
7566401a ER |
847 | void |
848 | update_breakpoints_after_exec (void) | |
3a58abaf | 849 | { |
7566401a ER |
850 | struct breakpoint *b; |
851 | struct breakpoint *temp; | |
852 | - struct bp_location *bploc; | |
853 | + struct bp_location *bploc, **bplocp_tmp; | |
854 | ||
855 | /* We're about to delete breakpoints from GDB's lists. If the | |
856 | INSERTED flag is true, GDB will try to lift the breakpoints by | |
857 | @@ -1584,7 +1699,7 @@ update_breakpoints_after_exec (void) | |
858 | breakpoints out as soon as it detects an exec. We don't do that | |
859 | here instead, because there may be other attempts to delete | |
860 | breakpoints after detecting an exec and before reaching here. */ | |
861 | - ALL_BP_LOCATIONS (bploc) | |
862 | + ALL_BP_LOCATIONS (bploc, bplocp_tmp) | |
863 | gdb_assert (!bploc->inserted); | |
864 | ||
865 | ALL_BREAKPOINTS_SAFE (b, temp) | |
866 | @@ -1606,7 +1721,7 @@ update_breakpoints_after_exec (void) | |
867 | /* Thread event breakpoints must be set anew after an exec(), | |
868 | as must overlay event and longjmp master breakpoints. */ | |
869 | if (b->type == bp_thread_event || b->type == bp_overlay_event | |
870 | - || b->type == bp_longjmp_master) | |
871 | + || b->type == bp_longjmp_master || b->type == bp_exception_master) | |
872 | { | |
873 | delete_breakpoint (b); | |
874 | continue; | |
875 | @@ -1621,7 +1736,8 @@ update_breakpoints_after_exec (void) | |
3a58abaf | 876 | |
7566401a ER |
877 | /* Longjmp and longjmp-resume breakpoints are also meaningless |
878 | after an exec. */ | |
879 | - if (b->type == bp_longjmp || b->type == bp_longjmp_resume) | |
880 | + if (b->type == bp_longjmp || b->type == bp_longjmp_resume | |
881 | + || b->type == bp_exception || b->type == bp_exception_resume) | |
882 | { | |
883 | delete_breakpoint (b); | |
884 | continue; | |
885 | @@ -1682,12 +1798,13 @@ update_breakpoints_after_exec (void) | |
886 | create_longjmp_master_breakpoint ("_longjmp"); | |
887 | create_longjmp_master_breakpoint ("siglongjmp"); | |
888 | create_longjmp_master_breakpoint ("_siglongjmp"); | |
889 | + create_exception_master_breakpoint (); | |
890 | } | |
3a58abaf | 891 | |
7566401a ER |
892 | int |
893 | detach_breakpoints (int pid) | |
894 | { | |
895 | - struct bp_location *b; | |
896 | + struct bp_location *b, **bp_tmp; | |
897 | int val = 0; | |
898 | struct cleanup *old_chain = save_inferior_ptid (); | |
899 | ||
900 | @@ -1696,11 +1813,12 @@ detach_breakpoints (int pid) | |
3a58abaf | 901 | |
7566401a ER |
902 | /* Set inferior_ptid; remove_breakpoint uses this global. */ |
903 | inferior_ptid = pid_to_ptid (pid); | |
904 | - ALL_BP_LOCATIONS (b) | |
905 | + ALL_BP_LOCATIONS (b, bp_tmp) | |
906 | { | |
907 | if (b->inserted) | |
908 | val |= remove_breakpoint (b, mark_inserted); | |
909 | } | |
910 | + val |= target_detach_watchpoints (); | |
911 | do_cleanups (old_chain); | |
912 | return val; | |
913 | } | |
914 | @@ -1793,12 +1911,14 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) | |
915 | return val; | |
916 | b->inserted = (is == mark_inserted); | |
3a58abaf | 917 | } |
7566401a ER |
918 | - else if (b->loc_type == bp_loc_hardware_watchpoint) |
919 | + /* bp_loc_hardware_watchpoint with mark_inserted is being handled by | |
920 | + target_detach_watchpoints. */ | |
921 | + else if (b->loc_type == bp_loc_hardware_watchpoint && is == mark_uninserted) | |
922 | { | |
923 | struct value *v; | |
924 | struct value *n; | |
925 | ||
926 | - b->inserted = (is == mark_inserted); | |
927 | + b->inserted = 0; | |
928 | val = target_remove_watchpoint (b->address, b->length, | |
929 | b->watchpoint_type); | |
930 | ||
931 | @@ -1827,9 +1947,9 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) | |
932 | void | |
933 | mark_breakpoints_out (void) | |
934 | { | |
935 | - struct bp_location *bpt; | |
936 | + struct bp_location *bpt, **bptp_tmp; | |
937 | ||
938 | - ALL_BP_LOCATIONS (bpt) | |
939 | + ALL_BP_LOCATIONS (bpt, bptp_tmp) | |
940 | bpt->inserted = 0; | |
3a58abaf AM |
941 | } |
942 | ||
7566401a ER |
943 | @@ -1849,7 +1969,7 @@ void |
944 | breakpoint_init_inferior (enum inf_context context) | |
945 | { | |
946 | struct breakpoint *b, *temp; | |
947 | - struct bp_location *bpt; | |
948 | + struct bp_location *bpt, **bptp_tmp; | |
949 | int ix; | |
3a58abaf | 950 | |
7566401a ER |
951 | /* If breakpoint locations are shared across processes, then there's |
952 | @@ -1857,7 +1977,7 @@ breakpoint_init_inferior (enum inf_context context) | |
953 | if (gdbarch_has_global_breakpoints (target_gdbarch)) | |
954 | return; | |
955 | ||
956 | - ALL_BP_LOCATIONS (bpt) | |
957 | + ALL_BP_LOCATIONS (bpt, bptp_tmp) | |
958 | if (bpt->owner->enable_state != bp_permanent) | |
959 | bpt->inserted = 0; | |
960 | ||
961 | @@ -1918,10 +2038,10 @@ breakpoint_init_inferior (enum inf_context context) | |
962 | enum breakpoint_here | |
963 | breakpoint_here_p (CORE_ADDR pc) | |
964 | { | |
965 | - const struct bp_location *bpt; | |
966 | + struct bp_location *bpt, **bptp_tmp; | |
967 | int any_breakpoint_here = 0; | |
968 | ||
969 | - ALL_BP_LOCATIONS (bpt) | |
970 | + ALL_BP_LOCATIONS (bpt, bptp_tmp) | |
971 | { | |
972 | if (bpt->loc_type != bp_loc_software_breakpoint | |
973 | && bpt->loc_type != bp_loc_hardware_breakpoint) | |
974 | @@ -1961,16 +2081,16 @@ moribund_breakpoint_here_p (CORE_ADDR pc) | |
975 | } | |
976 | ||
977 | /* Returns non-zero if there's a breakpoint inserted at PC, which is | |
978 | - inserted using regular breakpoint_chain/bp_location_chain mechanism. | |
979 | + inserted using regular breakpoint_chain / bp_location array mechanism. | |
980 | This does not check for single-step breakpoints, which are | |
981 | inserted and removed using direct target manipulation. */ | |
982 | ||
983 | int | |
984 | regular_breakpoint_inserted_here_p (CORE_ADDR pc) | |
985 | { | |
986 | - const struct bp_location *bpt; | |
987 | + struct bp_location *bpt, **bptp_tmp; | |
988 | ||
989 | - ALL_BP_LOCATIONS (bpt) | |
990 | + ALL_BP_LOCATIONS (bpt, bptp_tmp) | |
991 | { | |
992 | if (bpt->loc_type != bp_loc_software_breakpoint | |
993 | && bpt->loc_type != bp_loc_hardware_breakpoint) | |
994 | @@ -2011,10 +2131,10 @@ breakpoint_inserted_here_p (CORE_ADDR pc) | |
995 | int | |
996 | software_breakpoint_inserted_here_p (CORE_ADDR pc) | |
997 | { | |
998 | - const struct bp_location *bpt; | |
999 | + struct bp_location *bpt, **bptp_tmp; | |
1000 | int any_breakpoint_here = 0; | |
1001 | ||
1002 | - ALL_BP_LOCATIONS (bpt) | |
1003 | + ALL_BP_LOCATIONS (bpt, bptp_tmp) | |
1004 | { | |
1005 | if (bpt->loc_type != bp_loc_software_breakpoint) | |
1006 | continue; | |
1007 | @@ -2044,12 +2164,12 @@ software_breakpoint_inserted_here_p (CORE_ADDR pc) | |
1008 | int | |
1009 | breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid) | |
1010 | { | |
1011 | - const struct bp_location *bpt; | |
1012 | + struct bp_location *bpt, **bptp_tmp; | |
1013 | /* The thread and task IDs associated to PTID, computed lazily. */ | |
1014 | int thread = -1; | |
1015 | int task = 0; | |
3a58abaf | 1016 | |
7566401a ER |
1017 | - ALL_BP_LOCATIONS (bpt) |
1018 | + ALL_BP_LOCATIONS (bpt, bptp_tmp) | |
1019 | { | |
1020 | if (bpt->loc_type != bp_loc_software_breakpoint | |
1021 | && bpt->loc_type != bp_loc_hardware_breakpoint) | |
1022 | @@ -2503,6 +2623,12 @@ print_it_typical (bpstat bs) | |
1023 | result = PRINT_NOTHING; | |
1024 | break; | |
1025 | ||
1026 | + case bp_exception_master: | |
1027 | + /* These should never be enabled. */ | |
1028 | + printf_filtered (_("Exception Master Breakpoint: gdb should not stop!\n")); | |
1029 | + result = PRINT_NOTHING; | |
1030 | + break; | |
3a58abaf | 1031 | + |
7566401a ER |
1032 | case bp_watchpoint: |
1033 | case bp_hardware_watchpoint: | |
1034 | annotate_watchpoint (b->number); | |
1035 | @@ -2590,6 +2716,8 @@ print_it_typical (bpstat bs) | |
1036 | case bp_none: | |
1037 | case bp_longjmp: | |
1038 | case bp_longjmp_resume: | |
1039 | + case bp_exception: | |
1040 | + case bp_exception_resume: | |
1041 | case bp_step_resume: | |
1042 | case bp_watchpoint_scope: | |
1043 | case bp_call_dummy: | |
1044 | @@ -2973,8 +3101,12 @@ bpstat_check_location (const struct bp_location *bl, CORE_ADDR bp_addr) | |
1045 | ||
1046 | /* If BS refers to a watchpoint, determine if the watched values | |
1047 | has actually changed, and we should stop. If not, set BS->stop | |
1048 | - to 0. */ | |
1049 | -static void | |
1050 | + to 0. | |
1051 | + Return 0 for watchpoints which could not be the cause of this trap. | |
1052 | + In such case PRINT_IT will be print_it_noop and STOP will be 0. | |
1053 | + Otherwise return 1 but in such case it is not guaranteed whether this | |
1054 | + breakpoint did or did not trigger this trap. */ | |
1055 | +static int | |
1056 | bpstat_check_watchpoint (bpstat bs) | |
1057 | { | |
1058 | const struct bp_location *bl = bs->breakpoint_at; | |
1059 | @@ -3063,8 +3195,10 @@ bpstat_check_watchpoint (bpstat bs) | |
1060 | anything for this watchpoint. */ | |
1061 | bs->print_it = print_it_noop; | |
1062 | bs->stop = 0; | |
1063 | + return 0; | |
1064 | } | |
1065 | } | |
1066 | + return 1; | |
3a58abaf AM |
1067 | } |
1068 | ||
3a58abaf | 1069 | |
7566401a ER |
1070 | @@ -3157,17 +3291,19 @@ bpstat |
1071 | bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid) | |
1072 | { | |
1073 | struct breakpoint *b = NULL; | |
1074 | - const struct bp_location *bl; | |
1075 | + struct bp_location *bl, **blp_tmp; | |
1076 | struct bp_location *loc; | |
1077 | /* Root of the chain of bpstat's */ | |
1078 | struct bpstats root_bs[1]; | |
1079 | /* Pointer to the last thing in the chain currently. */ | |
1080 | bpstat bs = root_bs; | |
1081 | int ix; | |
1082 | - int need_remove_insert; | |
1083 | + int need_remove_insert, update_locations = 0; | |
3a58abaf | 1084 | |
7566401a ER |
1085 | - ALL_BP_LOCATIONS (bl) |
1086 | + ALL_BP_LOCATIONS (bl, blp_tmp) | |
1087 | { | |
1088 | + bpstat bs_prev = bs; | |
1089 | + | |
1090 | b = bl->owner; | |
1091 | gdb_assert (b); | |
1092 | if (!breakpoint_enabled (b) && b->enable_state != bp_permanent) | |
1093 | @@ -3188,6 +3324,7 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid) | |
1094 | /* Come here if it's a watchpoint, or if the break address matches */ | |
1095 | ||
1096 | bs = bpstat_alloc (bl, bs); /* Alloc a bpstat to explain stop */ | |
1097 | + gdb_assert (bs_prev->next == bs); | |
1098 | ||
1099 | /* Assume we stop. Should we find watchpoint that is not actually | |
1100 | triggered, or if condition of breakpoint is false, we'll reset | |
1101 | @@ -3195,12 +3332,21 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid) | |
1102 | bs->stop = 1; | |
1103 | bs->print = 1; | |
1104 | ||
1105 | - bpstat_check_watchpoint (bs); | |
1106 | - if (!bs->stop) | |
1107 | - continue; | |
1108 | + if (!bpstat_check_watchpoint (bs)) | |
1109 | + { | |
1110 | + /* Ensure bpstat_explains_signal stays false if this BL could not be | |
1111 | + the cause of this trap. */ | |
1112 | + | |
1113 | + gdb_assert (bs->print_it == print_it_noop); | |
1114 | + gdb_assert (!bs->stop); | |
1115 | + xfree (bs); | |
1116 | + bs = bs_prev; | |
1117 | + bs->next = NULL; | |
1118 | + continue; | |
1119 | + } | |
1120 | ||
1121 | if (b->type == bp_thread_event || b->type == bp_overlay_event | |
1122 | - || b->type == bp_longjmp_master) | |
1123 | + || b->type == bp_longjmp_master || b->type == bp_exception_master) | |
1124 | /* We do not stop for these. */ | |
1125 | bs->stop = 0; | |
1126 | else | |
1127 | @@ -3208,14 +3354,15 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid) | |
1128 | ||
1129 | if (bs->stop) | |
1130 | { | |
1131 | - ++(b->hit_count); | |
1132 | + if (b->enable_state != bp_disabled) | |
1133 | + ++(b->hit_count); | |
1134 | ||
1135 | /* We will stop here */ | |
1136 | if (b->disposition == disp_disable) | |
1137 | { | |
1138 | if (b->enable_state != bp_permanent) | |
1139 | b->enable_state = bp_disabled; | |
1140 | - update_global_location_list (0); | |
1141 | + update_locations = 1; | |
1142 | } | |
1143 | if (b->silent) | |
1144 | bs->print = 0; | |
1145 | @@ -3235,6 +3382,10 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid) | |
1146 | bs->print_it = print_it_noop; | |
1147 | } | |
1148 | ||
1149 | + /* Delay this call which would break the ALL_BP_LOCATIONS iteration above. */ | |
1150 | + if (update_locations) | |
1151 | + update_global_location_list (0); | |
3a58abaf | 1152 | + |
7566401a ER |
1153 | for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix) |
1154 | { | |
1155 | if (loc->address == bp_addr) | |
1156 | @@ -3412,6 +3563,7 @@ bpstat_what (bpstat bs) | |
1157 | struct bpstat_what retval; | |
1158 | ||
1159 | retval.call_dummy = 0; | |
1160 | + retval.is_longjmp = 0; | |
1161 | for (; bs != NULL; bs = bs->next) | |
1162 | { | |
1163 | enum class bs_class = no_effect; | |
1164 | @@ -3458,10 +3610,15 @@ bpstat_what (bpstat bs) | |
1165 | bs_class = no_effect; | |
1166 | break; | |
1167 | case bp_longjmp: | |
1168 | + case bp_exception: | |
1169 | bs_class = long_jump; | |
1170 | + retval.is_longjmp = bs->breakpoint_at->owner->type == bp_longjmp; | |
1171 | break; | |
1172 | case bp_longjmp_resume: | |
1173 | + case bp_exception_resume: | |
1174 | bs_class = long_resume; | |
1175 | + retval.is_longjmp | |
1176 | + = bs->breakpoint_at->owner->type == bp_longjmp_resume; | |
1177 | break; | |
1178 | case bp_step_resume: | |
1179 | if (bs->stop) | |
1180 | @@ -3484,6 +3641,7 @@ bpstat_what (bpstat bs) | |
1181 | case bp_thread_event: | |
1182 | case bp_overlay_event: | |
1183 | case bp_longjmp_master: | |
1184 | + case bp_exception_master: | |
1185 | bs_class = bp_nostop; | |
1186 | break; | |
1187 | case bp_catchpoint: | |
1188 | @@ -3605,6 +3763,8 @@ print_one_breakpoint_location (struct breakpoint *b, | |
1189 | {bp_access_watchpoint, "acc watchpoint"}, | |
1190 | {bp_longjmp, "longjmp"}, | |
1191 | {bp_longjmp_resume, "longjmp resume"}, | |
1192 | + {bp_exception, "exception"}, | |
1193 | + {bp_exception_resume, "exception resume"}, | |
1194 | {bp_step_resume, "step resume"}, | |
1195 | {bp_watchpoint_scope, "watchpoint scope"}, | |
1196 | {bp_call_dummy, "call dummy"}, | |
1197 | @@ -3612,6 +3772,7 @@ print_one_breakpoint_location (struct breakpoint *b, | |
1198 | {bp_thread_event, "thread events"}, | |
1199 | {bp_overlay_event, "overlay events"}, | |
1200 | {bp_longjmp_master, "longjmp master"}, | |
1201 | + {bp_exception_master, "exception master"}, | |
1202 | {bp_catchpoint, "catchpoint"}, | |
1203 | {bp_tracepoint, "tracepoint"}, | |
1204 | {bp_jit_event, "jit events"}, | |
1205 | @@ -3735,6 +3896,8 @@ print_one_breakpoint_location (struct breakpoint *b, | |
1206 | case bp_finish: | |
1207 | case bp_longjmp: | |
1208 | case bp_longjmp_resume: | |
1209 | + case bp_exception: | |
1210 | + case bp_exception_resume: | |
1211 | case bp_step_resume: | |
1212 | case bp_watchpoint_scope: | |
1213 | case bp_call_dummy: | |
1214 | @@ -3742,6 +3905,7 @@ print_one_breakpoint_location (struct breakpoint *b, | |
1215 | case bp_thread_event: | |
1216 | case bp_overlay_event: | |
1217 | case bp_longjmp_master: | |
1218 | + case bp_exception_master: | |
1219 | case bp_tracepoint: | |
1220 | case bp_jit_event: | |
1221 | if (opts.addressprint) | |
1222 | @@ -4197,9 +4361,8 @@ set_default_breakpoint (int valid, CORE_ADDR addr, struct symtab *symtab, | |
1223 | (or use it for any other purpose either). | |
1224 | ||
1225 | More specifically, each of the following breakpoint types will always | |
1226 | - have a zero valued address and we don't want check_duplicates() to mark | |
1227 | - breakpoints of any of these types to be a duplicate of an actual | |
1228 | - breakpoint at address zero: | |
1229 | + have a zero valued address and we don't want to mark breakpoints of any of | |
1230 | + these types to be a duplicate of an actual breakpoint at address zero: | |
1231 | ||
1232 | bp_watchpoint | |
1233 | bp_hardware_watchpoint | |
1234 | @@ -4219,88 +4382,6 @@ breakpoint_address_is_meaningful (struct breakpoint *bpt) | |
1235 | && type != bp_catchpoint); | |
1236 | } | |
1237 | ||
1238 | -/* Rescan breakpoints at the same address and section as BPT, | |
1239 | - marking the first one as "first" and any others as "duplicates". | |
1240 | - This is so that the bpt instruction is only inserted once. | |
1241 | - If we have a permanent breakpoint at the same place as BPT, make | |
1242 | - that one the official one, and the rest as duplicates. */ | |
1243 | - | |
1244 | -static void | |
1245 | -check_duplicates_for (CORE_ADDR address, struct obj_section *section) | |
1246 | -{ | |
1247 | - struct bp_location *b; | |
1248 | - int count = 0; | |
1249 | - struct bp_location *perm_bp = 0; | |
1250 | - | |
1251 | - ALL_BP_LOCATIONS (b) | |
1252 | - if (b->owner->enable_state != bp_disabled | |
1253 | - && b->owner->enable_state != bp_call_disabled | |
1254 | - && b->owner->enable_state != bp_startup_disabled | |
1255 | - && b->enabled | |
1256 | - && !b->shlib_disabled | |
1257 | - && b->address == address /* address / overlay match */ | |
1258 | - && (!overlay_debugging || b->section == section) | |
1259 | - && breakpoint_address_is_meaningful (b->owner)) | |
1260 | - { | |
1261 | - /* Have we found a permanent breakpoint? */ | |
1262 | - if (b->owner->enable_state == bp_permanent) | |
1263 | - { | |
1264 | - perm_bp = b; | |
1265 | - break; | |
1266 | - } | |
1267 | - | |
1268 | - count++; | |
1269 | - b->duplicate = count > 1; | |
1270 | - } | |
1271 | - | |
1272 | - /* If we found a permanent breakpoint at this address, go over the | |
1273 | - list again and declare all the other breakpoints there (except | |
1274 | - other permanent breakpoints) to be the duplicates. */ | |
1275 | - if (perm_bp) | |
1276 | - { | |
1277 | - perm_bp->duplicate = 0; | |
1278 | - | |
1279 | - /* Permanent breakpoint should always be inserted. */ | |
1280 | - if (! perm_bp->inserted) | |
1281 | - internal_error (__FILE__, __LINE__, | |
1282 | - _("allegedly permanent breakpoint is not " | |
1283 | - "actually inserted")); | |
1284 | - | |
1285 | - ALL_BP_LOCATIONS (b) | |
1286 | - if (b != perm_bp) | |
1287 | - { | |
1288 | - if (b->owner->enable_state != bp_permanent | |
1289 | - && b->owner->enable_state != bp_disabled | |
1290 | - && b->owner->enable_state != bp_call_disabled | |
1291 | - && b->owner->enable_state != bp_startup_disabled | |
1292 | - && b->enabled && !b->shlib_disabled | |
1293 | - && b->address == address /* address / overlay match */ | |
1294 | - && (!overlay_debugging || b->section == section) | |
1295 | - && breakpoint_address_is_meaningful (b->owner)) | |
1296 | - { | |
1297 | - if (b->inserted) | |
1298 | - internal_error (__FILE__, __LINE__, | |
1299 | - _("another breakpoint was inserted on top of " | |
1300 | - "a permanent breakpoint")); | |
1301 | - | |
1302 | - b->duplicate = 1; | |
1303 | - } | |
1304 | - } | |
1305 | - } | |
1306 | -} | |
1307 | - | |
1308 | -static void | |
1309 | -check_duplicates (struct breakpoint *bpt) | |
1310 | -{ | |
1311 | - struct bp_location *bl = bpt->loc; | |
1312 | - | |
1313 | - if (! breakpoint_address_is_meaningful (bpt)) | |
1314 | - return; | |
1315 | - | |
1316 | - for (; bl; bl = bl->next) | |
1317 | - check_duplicates_for (bl->address, bl->section); | |
1318 | -} | |
1319 | - | |
1320 | static void | |
1321 | breakpoint_adjustment_warning (CORE_ADDR from_addr, CORE_ADDR to_addr, | |
1322 | int bnum, int have_bnum) | |
1323 | @@ -4382,6 +4463,8 @@ allocate_bp_location (struct breakpoint *bpt) | |
1324 | case bp_finish: | |
1325 | case bp_longjmp: | |
1326 | case bp_longjmp_resume: | |
1327 | + case bp_exception: | |
1328 | + case bp_exception_resume: | |
1329 | case bp_step_resume: | |
1330 | case bp_watchpoint_scope: | |
1331 | case bp_call_dummy: | |
1332 | @@ -4390,6 +4473,7 @@ allocate_bp_location (struct breakpoint *bpt) | |
1333 | case bp_overlay_event: | |
1334 | case bp_jit_event: | |
1335 | case bp_longjmp_master: | |
1336 | + case bp_exception_master: | |
1337 | loc->loc_type = bp_loc_software_breakpoint; | |
1338 | break; | |
1339 | case bp_hardware_breakpoint: | |
1340 | @@ -4568,8 +4652,7 @@ make_breakpoint_permanent (struct breakpoint *b) | |
1341 | } | |
1342 | ||
1343 | /* Call this routine when stepping and nexting to enable a breakpoint | |
1344 | - if we do a longjmp() in THREAD. When we hit that breakpoint, call | |
1345 | - set_longjmp_resume_breakpoint() to figure out where we are going. */ | |
1346 | + if we do a longjmp() or 'throw' in THREAD. */ | |
1347 | ||
1348 | void | |
1349 | set_longjmp_breakpoint (int thread) | |
1350 | @@ -4581,10 +4664,10 @@ set_longjmp_breakpoint (int thread) | |
1351 | longjmp "master" breakpoints. Here, we simply create momentary | |
1352 | clones of those and enable them for the requested thread. */ | |
1353 | ALL_BREAKPOINTS_SAFE (b, temp) | |
1354 | - if (b->type == bp_longjmp_master) | |
1355 | + if (b->type == bp_longjmp_master || b->type == bp_exception_master) | |
1356 | { | |
1357 | struct breakpoint *clone = clone_momentary_breakpoint (b); | |
1358 | - clone->type = bp_longjmp; | |
1359 | + clone->type = b->type == bp_longjmp_master ? bp_longjmp : bp_exception; | |
1360 | clone->thread = thread; | |
1361 | } | |
1362 | } | |
1363 | @@ -4596,7 +4679,7 @@ delete_longjmp_breakpoint (int thread) | |
1364 | struct breakpoint *b, *temp; | |
1365 | ||
1366 | ALL_BREAKPOINTS_SAFE (b, temp) | |
1367 | - if (b->type == bp_longjmp) | |
1368 | + if (b->type == bp_longjmp || b->type == bp_exception) | |
1369 | { | |
1370 | if (b->thread == thread) | |
1371 | delete_breakpoint (b); | |
1372 | @@ -4710,9 +4793,9 @@ create_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address) | |
1373 | void | |
1374 | disable_breakpoints_in_shlibs (void) | |
1375 | { | |
1376 | - struct bp_location *loc; | |
1377 | + struct bp_location *loc, **locp_tmp; | |
1378 | ||
1379 | - ALL_BP_LOCATIONS (loc) | |
1380 | + ALL_BP_LOCATIONS (loc, locp_tmp) | |
1381 | { | |
1382 | struct breakpoint *b = loc->owner; | |
1383 | /* We apply the check to all breakpoints, including disabled | |
1384 | @@ -4742,7 +4825,7 @@ disable_breakpoints_in_shlibs (void) | |
1385 | static void | |
1386 | disable_breakpoints_in_unloaded_shlib (struct so_list *solib) | |
1387 | { | |
1388 | - struct bp_location *loc; | |
1389 | + struct bp_location *loc, **locp_tmp; | |
1390 | int disabled_shlib_breaks = 0; | |
1391 | ||
1392 | /* SunOS a.out shared libraries are always mapped, so do not | |
1393 | @@ -4753,7 +4836,7 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib) | |
1394 | && bfd_get_flavour (exec_bfd) == bfd_target_aout_flavour) | |
1395 | return; | |
1396 | ||
1397 | - ALL_BP_LOCATIONS (loc) | |
1398 | + ALL_BP_LOCATIONS (loc, locp_tmp) | |
1399 | { | |
1400 | struct breakpoint *b = loc->owner; | |
1401 | if ((loc->loc_type == bp_loc_hardware_breakpoint | |
1402 | @@ -5648,6 +5731,8 @@ mention (struct breakpoint *b) | |
1403 | case bp_finish: | |
1404 | case bp_longjmp: | |
1405 | case bp_longjmp_resume: | |
1406 | + case bp_exception: | |
1407 | + case bp_exception_resume: | |
1408 | case bp_step_resume: | |
1409 | case bp_call_dummy: | |
1410 | case bp_watchpoint_scope: | |
1411 | @@ -5656,6 +5741,7 @@ mention (struct breakpoint *b) | |
1412 | case bp_overlay_event: | |
1413 | case bp_jit_event: | |
1414 | case bp_longjmp_master: | |
1415 | + case bp_exception_master: | |
1416 | break; | |
1417 | } | |
1418 | ||
1419 | @@ -6958,6 +7044,7 @@ struct until_break_command_continuation_args | |
1420 | { | |
1421 | struct breakpoint *breakpoint; | |
1422 | struct breakpoint *breakpoint2; | |
1423 | + int thread_num; | |
1424 | }; | |
1425 | ||
1426 | /* This function is called by fetch_inferior_event via the | |
1427 | @@ -6972,6 +7059,7 @@ until_break_command_continuation (void *arg) | |
1428 | delete_breakpoint (a->breakpoint); | |
1429 | if (a->breakpoint2) | |
1430 | delete_breakpoint (a->breakpoint2); | |
1431 | + delete_longjmp_breakpoint (a->thread_num); | |
1432 | } | |
1433 | ||
1434 | void | |
1435 | @@ -6983,6 +7071,8 @@ until_break_command (char *arg, int from_tty, int anywhere) | |
1436 | struct breakpoint *breakpoint; | |
1437 | struct breakpoint *breakpoint2 = NULL; | |
1438 | struct cleanup *old_chain; | |
1439 | + int thread; | |
1440 | + struct thread_info *tp; | |
1441 | ||
1442 | clear_proceed_status (); | |
1443 | ||
1444 | @@ -7021,6 +7111,9 @@ until_break_command (char *arg, int from_tty, int anywhere) | |
1445 | ||
1446 | old_chain = make_cleanup_delete_breakpoint (breakpoint); | |
1447 | ||
1448 | + tp = inferior_thread (); | |
1449 | + thread = tp->num; | |
3a58abaf | 1450 | + |
7566401a ER |
1451 | /* Keep within the current frame, or in frames called by the current |
1452 | one. */ | |
1453 | ||
1454 | @@ -7033,6 +7126,10 @@ until_break_command (char *arg, int from_tty, int anywhere) | |
1455 | frame_unwind_caller_id (frame), | |
1456 | bp_until); | |
1457 | make_cleanup_delete_breakpoint (breakpoint2); | |
3a58abaf | 1458 | + |
7566401a ER |
1459 | + set_longjmp_breakpoint (thread); |
1460 | + tp->initiating_frame = frame_unwind_caller_id (frame); | |
1461 | + make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); | |
1462 | } | |
1463 | ||
1464 | proceed (-1, TARGET_SIGNAL_DEFAULT, 0); | |
1465 | @@ -7049,6 +7146,7 @@ until_break_command (char *arg, int from_tty, int anywhere) | |
1466 | ||
1467 | args->breakpoint = breakpoint; | |
1468 | args->breakpoint2 = breakpoint2; | |
1469 | + args->thread_num = thread; | |
1470 | ||
1471 | discard_cleanups (old_chain); | |
1472 | add_continuation (inferior_thread (), | |
1473 | @@ -7758,6 +7856,82 @@ do_vec_free (void *p) | |
1474 | VEC_free (bp_location_p, *vec); | |
1475 | } | |
1476 | ||
1477 | +/* A comparison function for bp_location A and B being interfaced to qsort. | |
1478 | + Sort elements primarily by their ADDRESS (no matter what does | |
1479 | + breakpoint_address_is_meaningful say for its OWNER), secondarily by ordering | |
1480 | + first bp_permanent OWNERed elements and terciarily just ensuring the array | |
1481 | + is sorted stable way despite qsort being an instable algorithm. */ | |
3a58abaf | 1482 | + |
7566401a ER |
1483 | +static int |
1484 | +bp_location_compare (struct bp_location *a, struct bp_location *b) | |
3a58abaf | 1485 | +{ |
7566401a ER |
1486 | + int a_perm = a->owner->enable_state == bp_permanent; |
1487 | + int b_perm = b->owner->enable_state == bp_permanent; | |
3a58abaf | 1488 | + |
7566401a ER |
1489 | + if (a->address != b->address) |
1490 | + return (a->address > b->address) - (a->address < b->address); | |
3a58abaf | 1491 | + |
7566401a ER |
1492 | + /* Sort permanent breakpoints first. */ |
1493 | + if (a_perm != b_perm) | |
1494 | + return (a_perm < b_perm) - (a_perm > b_perm); | |
3a58abaf | 1495 | + |
7566401a ER |
1496 | + /* Make the user-visible order stable across GDB runs. Locations of the same |
1497 | + breakpoint can be sorted in arbitrary order. */ | |
3a58abaf | 1498 | + |
7566401a ER |
1499 | + if (a->owner->number != b->owner->number) |
1500 | + return (a->owner->number > b->owner->number) | |
1501 | + - (a->owner->number < b->owner->number); | |
3a58abaf | 1502 | + |
7566401a | 1503 | + return (a > b) - (a < b); |
3a58abaf AM |
1504 | +} |
1505 | + | |
7566401a ER |
1506 | +/* Interface bp_location_compare as the COMPAR parameter of qsort function. */ |
1507 | + | |
3a58abaf | 1508 | +static int |
7566401a | 1509 | +bp_location_compare_for_qsort (const void *ap, const void *bp) |
3a58abaf | 1510 | +{ |
7566401a ER |
1511 | + struct bp_location *a = *(void **) ap; |
1512 | + struct bp_location *b = *(void **) bp; | |
3a58abaf | 1513 | + |
7566401a | 1514 | + return bp_location_compare (a, b); |
3a58abaf AM |
1515 | +} |
1516 | + | |
7566401a ER |
1517 | +/* Set bp_location_placed_address_before_address_max and |
1518 | + bp_location_shadow_len_after_address_max according to the current content of | |
1519 | + the bp_location array. */ | |
1520 | + | |
1521 | +static void | |
1522 | +bp_location_target_extensions_update (void) | |
3a58abaf | 1523 | +{ |
7566401a | 1524 | + struct bp_location *bl, **blp_tmp; |
3a58abaf | 1525 | + |
7566401a ER |
1526 | + bp_location_placed_address_before_address_max = 0; |
1527 | + bp_location_shadow_len_after_address_max = 0; | |
3a58abaf | 1528 | + |
7566401a ER |
1529 | + ALL_BP_LOCATIONS (bl, blp_tmp) |
1530 | + { | |
1531 | + CORE_ADDR start, end, addr; | |
3a58abaf | 1532 | + |
7566401a ER |
1533 | + if (!bp_location_has_shadow (bl)) |
1534 | + continue; | |
3a58abaf | 1535 | + |
7566401a ER |
1536 | + start = bl->target_info.placed_address; |
1537 | + end = start + bl->target_info.shadow_len; | |
3a58abaf | 1538 | + |
7566401a ER |
1539 | + gdb_assert (bl->address >= start); |
1540 | + addr = bl->address - start; | |
1541 | + if (addr > bp_location_placed_address_before_address_max) | |
1542 | + bp_location_placed_address_before_address_max = addr; | |
3a58abaf | 1543 | + |
7566401a | 1544 | + /* Zero SHADOW_LEN would not pass bp_location_has_shadow. */ |
3a58abaf | 1545 | + |
7566401a ER |
1546 | + gdb_assert (bl->address < end); |
1547 | + addr = end - bl->address; | |
1548 | + if (addr > bp_location_shadow_len_after_address_max) | |
1549 | + bp_location_shadow_len_after_address_max = addr; | |
1550 | + } | |
1551 | +} | |
1552 | + | |
1553 | /* If SHOULD_INSERT is false, do not insert any breakpoint locations | |
1554 | into the inferior, only remove already-inserted locations that no | |
1555 | longer should be inserted. Functions that delete a breakpoint or | |
ab050a48 | 1556 | @@ -7777,49 +7951,78 @@ static void |
7566401a ER |
1557 | update_global_location_list (int should_insert) |
1558 | { | |
1559 | struct breakpoint *b; | |
1560 | - struct bp_location **next = &bp_location_chain; | |
1561 | - struct bp_location *loc; | |
1562 | - struct bp_location *loc2; | |
1563 | - VEC(bp_location_p) *old_locations = NULL; | |
1564 | - int ret; | |
1565 | - int ix; | |
1566 | + struct bp_location **locp, *loc; | |
1567 | struct cleanup *cleanups; | |
1568 | ||
1569 | - cleanups = make_cleanup (do_vec_free, &old_locations); | |
1570 | - /* Store old locations for future reference. */ | |
1571 | - for (loc = bp_location_chain; loc; loc = loc->global_next) | |
1572 | - VEC_safe_push (bp_location_p, old_locations, loc); | |
1573 | + /* The first bp_location being the only one non-DUPLICATE for the current run | |
1574 | + of the same ADDRESS. */ | |
1575 | + struct bp_location *loc_first; | |
1576 | + | |
1577 | + /* Saved former bp_location array which we compare against the newly built | |
1578 | + bp_location from the current state of ALL_BREAKPOINTS. */ | |
1579 | + struct bp_location **old_location, **old_locp; | |
1580 | + unsigned old_location_count; | |
1581 | + | |
1582 | + old_location = bp_location; | |
1583 | + old_location_count = bp_location_count; | |
1584 | + bp_location = NULL; | |
1585 | + bp_location_count = 0; | |
1586 | + cleanups = make_cleanup (xfree, old_location); | |
1587 | ||
1588 | - bp_location_chain = NULL; | |
1589 | ALL_BREAKPOINTS (b) | |
1590 | - { | |
1591 | - for (loc = b->loc; loc; loc = loc->next) | |
1592 | - { | |
1593 | - *next = loc; | |
1594 | - next = &(loc->global_next); | |
1595 | - *next = NULL; | |
1596 | - } | |
1597 | - } | |
1598 | + for (loc = b->loc; loc; loc = loc->next) | |
1599 | + bp_location_count++; | |
3a58abaf | 1600 | + |
7566401a ER |
1601 | + bp_location = xmalloc (sizeof (*bp_location) * bp_location_count); |
1602 | + locp = bp_location; | |
1603 | + ALL_BREAKPOINTS (b) | |
1604 | + for (loc = b->loc; loc; loc = loc->next) | |
1605 | + *locp++ = loc; | |
1606 | + qsort (bp_location, bp_location_count, sizeof (*bp_location), | |
1607 | + bp_location_compare_for_qsort); | |
1608 | + | |
1609 | + bp_location_target_extensions_update (); | |
1610 | ||
1611 | /* Identify bp_location instances that are no longer present in the new | |
1612 | list, and therefore should be freed. Note that it's not necessary that | |
1613 | those locations should be removed from inferior -- if there's another | |
1614 | location at the same address (previously marked as duplicate), | |
1615 | - we don't need to remove/insert the location. */ | |
1616 | - for (ix = 0; VEC_iterate(bp_location_p, old_locations, ix, loc); ++ix) | |
1617 | + we don't need to remove/insert the location. | |
1618 | + | |
1619 | + LOCP is kept in sync with OLD_LOCP, each pointing to the current and | |
1620 | + former bp_location array state respectively. */ | |
3a58abaf | 1621 | + |
7566401a ER |
1622 | + locp = bp_location; |
1623 | + for (old_locp = old_location; old_locp < old_location + old_location_count; | |
1624 | + old_locp++) | |
1625 | { | |
1626 | - /* Tells if 'loc' is found amoung the new locations. If not, we | |
1627 | + struct bp_location *old_loc = *old_locp; | |
ab050a48 | 1628 | + struct bp_location **loc2p; |
7566401a ER |
1629 | + |
1630 | + /* Tells if 'old_loc' is found amoung the new locations. If not, we | |
1631 | have to free it. */ | |
ab050a48 | 1632 | int found_object = 0; |
7566401a ER |
1633 | /* Tells if the location should remain inserted in the target. */ |
1634 | int keep_in_target = 0; | |
1635 | int removed = 0; | |
1636 | - for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next) | |
1637 | - if (loc2 == loc) | |
1638 | - { | |
1639 | - found_object = 1; | |
1640 | - break; | |
1641 | - } | |
3a58abaf | 1642 | + |
7566401a ER |
1643 | + /* Skip LOCP entries which will definitely never be needed. Stop either |
1644 | + at or being the one matching OLD_LOC. */ | |
1645 | + while (locp < bp_location + bp_location_count | |
ab050a48 | 1646 | + && (*locp)->address < old_loc->address) |
7566401a | 1647 | + locp++; |
ab050a48 BZ |
1648 | + |
1649 | + for (loc2p = locp; | |
1650 | + (loc2p < bp_location + bp_location_count | |
1651 | + && (*loc2p)->address == old_loc->address); | |
1652 | + loc2p++) | |
1653 | + { | |
1654 | + if (*loc2p == old_loc) | |
1655 | + { | |
1656 | + found_object = 1; | |
1657 | + break; | |
1658 | + } | |
1659 | + } | |
7566401a ER |
1660 | |
1661 | /* If this location is no longer present, and inserted, look if there's | |
1662 | maybe a new location at the same address. If so, mark that one | |
ab050a48 | 1663 | @@ -7827,11 +8030,11 @@ update_global_location_list (int should_insert) |
7566401a ER |
1664 | don't have a time window where a breakpoint at certain location is not |
1665 | inserted. */ | |
1666 | ||
1667 | - if (loc->inserted) | |
1668 | + if (old_loc->inserted) | |
1669 | { | |
1670 | /* If the location is inserted now, we might have to remove it. */ | |
3a58abaf | 1671 | |
7566401a ER |
1672 | - if (found_object && should_be_inserted (loc)) |
1673 | + if (found_object && should_be_inserted (old_loc)) | |
1674 | { | |
1675 | /* The location is still present in the location list, and still | |
1676 | should be inserted. Don't do anything. */ | |
ab050a48 | 1677 | @@ -7842,37 +8045,46 @@ update_global_location_list (int should_insert) |
7566401a ER |
1678 | /* The location is either no longer present, or got disabled. |
1679 | See if there's another location at the same address, in which | |
1680 | case we don't need to remove this one from the target. */ | |
1681 | - if (breakpoint_address_is_meaningful (loc->owner)) | |
1682 | - for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next) | |
1683 | - { | |
1684 | - /* For the sake of should_insert_location. The | |
1685 | - call to check_duplicates will fix up this later. */ | |
1686 | - loc2->duplicate = 0; | |
1687 | - if (should_be_inserted (loc2) | |
1688 | - && loc2 != loc && loc2->address == loc->address) | |
1689 | - { | |
1690 | - loc2->inserted = 1; | |
1691 | - loc2->target_info = loc->target_info; | |
1692 | - keep_in_target = 1; | |
1693 | - break; | |
1694 | - } | |
1695 | - } | |
1696 | + | |
1697 | + if (breakpoint_address_is_meaningful (old_loc->owner)) | |
1698 | + { | |
7566401a | 1699 | + for (loc2p = locp; |
ab050a48 BZ |
1700 | + (loc2p < bp_location + bp_location_count |
1701 | + && (*loc2p)->address == old_loc->address); | |
7566401a ER |
1702 | + loc2p++) |
1703 | + { | |
1704 | + struct bp_location *loc2 = *loc2p; | |
1705 | + | |
ab050a48 BZ |
1706 | + { |
1707 | + /* For the sake of should_be_inserted. | |
1708 | + Duplicates check below will fix up this later. */ | |
1709 | + loc2->duplicate = 0; | |
1710 | + if (loc2 != old_loc && should_be_inserted (loc2)) | |
1711 | + { | |
1712 | + loc2->inserted = 1; | |
1713 | + loc2->target_info = old_loc->target_info; | |
1714 | + keep_in_target = 1; | |
1715 | + break; | |
1716 | + } | |
7566401a ER |
1717 | + } |
1718 | + } | |
1719 | + } | |
1720 | } | |
3a58abaf | 1721 | |
7566401a ER |
1722 | if (!keep_in_target) |
1723 | { | |
1724 | - if (remove_breakpoint (loc, mark_uninserted)) | |
1725 | + if (remove_breakpoint (old_loc, mark_uninserted)) | |
1726 | { | |
1727 | /* This is just about all we can do. We could keep this | |
1728 | location on the global list, and try to remove it next | |
1729 | time, but there's no particular reason why we will | |
1730 | succeed next time. | |
1731 | ||
1732 | - Note that at this point, loc->owner is still valid, | |
1733 | + Note that at this point, old_loc->owner is still valid, | |
1734 | as delete_breakpoint frees the breakpoint only | |
1735 | after calling us. */ | |
1736 | printf_filtered (_("warning: Error removing breakpoint %d\n"), | |
1737 | - loc->owner->number); | |
1738 | + old_loc->owner->number); | |
1739 | } | |
1740 | removed = 1; | |
1741 | } | |
ab050a48 | 1742 | @@ -7894,19 +8106,59 @@ update_global_location_list (int should_insert) |
7566401a ER |
1743 | longer need to keep this breakpoint. This is just a |
1744 | heuristic, but if it's wrong, we'll report unexpected SIGTRAP, | |
1745 | which is usability issue, but not a correctness problem. */ | |
1746 | - loc->events_till_retirement = 3 * (thread_count () + 1); | |
1747 | - loc->owner = NULL; | |
1748 | + old_loc->events_till_retirement = 3 * (thread_count () + 1); | |
1749 | + old_loc->owner = NULL; | |
1750 | ||
1751 | - VEC_safe_push (bp_location_p, moribund_locations, loc); | |
1752 | + VEC_safe_push (bp_location_p, moribund_locations, old_loc); | |
1753 | } | |
1754 | else | |
1755 | - free_bp_location (loc); | |
1756 | + free_bp_location (old_loc); | |
1757 | } | |
1758 | } | |
3a58abaf | 1759 | |
7566401a ER |
1760 | - ALL_BREAKPOINTS (b) |
1761 | + /* Rescan breakpoints at the same address and section, | |
1762 | + marking the first one as "first" and any others as "duplicates". | |
1763 | + This is so that the bpt instruction is only inserted once. | |
1764 | + If we have a permanent breakpoint at the same place as BPT, make | |
1765 | + that one the official one, and the rest as duplicates. Permanent | |
1766 | + breakpoints are sorted first for the same address. */ | |
3a58abaf | 1767 | + |
7566401a ER |
1768 | + loc_first = NULL; |
1769 | + ALL_BP_LOCATIONS (loc, locp) | |
1770 | { | |
1771 | - check_duplicates (b); | |
1772 | + struct breakpoint *b = loc->owner; | |
1773 | + | |
1774 | + if (b->enable_state == bp_disabled | |
1775 | + || b->enable_state == bp_call_disabled | |
1776 | + || b->enable_state == bp_startup_disabled | |
1777 | + || !loc->enabled | |
1778 | + || loc->shlib_disabled | |
1779 | + || !breakpoint_address_is_meaningful (b)) | |
1780 | + continue; | |
3a58abaf | 1781 | + |
7566401a ER |
1782 | + /* Permanent breakpoint should always be inserted. */ |
1783 | + if (b->enable_state == bp_permanent && ! loc->inserted) | |
1784 | + internal_error (__FILE__, __LINE__, | |
1785 | + _("allegedly permanent breakpoint is not " | |
1786 | + "actually inserted")); | |
3a58abaf | 1787 | + |
7566401a ER |
1788 | + if (loc_first == NULL |
1789 | + /* address / overlay match */ | |
1790 | + || loc->address != loc_first->address | |
1791 | + || (overlay_debugging && loc->section != loc_first->section)) | |
1792 | + { | |
1793 | + loc_first = loc; | |
1794 | + loc->duplicate = 0; | |
1795 | + continue; | |
1796 | + } | |
3a58abaf | 1797 | + |
7566401a ER |
1798 | + loc->duplicate = 1; |
1799 | + | |
1800 | + if (loc_first->owner->enable_state == bp_permanent && loc->inserted | |
1801 | + && b->enable_state != bp_permanent) | |
1802 | + internal_error (__FILE__, __LINE__, | |
1803 | + _("another breakpoint was inserted on top of " | |
1804 | + "a permanent breakpoint")); | |
3a58abaf AM |
1805 | } |
1806 | ||
7566401a | 1807 | if (breakpoints_always_inserted_mode () && should_insert |
ab050a48 | 1808 | @@ -8083,6 +8335,7 @@ delete_command (char *arg, int from_tty) |
7566401a ER |
1809 | && b->type != bp_thread_event |
1810 | && b->type != bp_overlay_event | |
1811 | && b->type != bp_longjmp_master | |
1812 | + && b->type != bp_exception_master | |
1813 | && b->number >= 0) | |
1814 | { | |
1815 | breaks_to_delete = 1; | |
ab050a48 | 1816 | @@ -8102,6 +8355,7 @@ delete_command (char *arg, int from_tty) |
7566401a ER |
1817 | && b->type != bp_jit_event |
1818 | && b->type != bp_overlay_event | |
1819 | && b->type != bp_longjmp_master | |
1820 | + && b->type != bp_exception_master | |
1821 | && b->number >= 0) | |
1822 | delete_breakpoint (b); | |
1823 | } | |
ab050a48 | 1824 | @@ -8404,6 +8658,7 @@ breakpoint_re_set_one (void *bint) |
7566401a ER |
1825 | reset later by breakpoint_re_set. */ |
1826 | case bp_overlay_event: | |
1827 | case bp_longjmp_master: | |
1828 | + case bp_exception_master: | |
1829 | delete_breakpoint (b); | |
1830 | break; | |
3a58abaf | 1831 | |
ab050a48 | 1832 | @@ -8427,6 +8682,8 @@ breakpoint_re_set_one (void *bint) |
7566401a ER |
1833 | case bp_longjmp: |
1834 | case bp_longjmp_resume: | |
1835 | case bp_jit_event: | |
1836 | + case bp_exception: | |
1837 | + case bp_exception_resume: | |
1838 | break; | |
1839 | } | |
3a58abaf | 1840 | |
ab050a48 | 1841 | @@ -8462,6 +8719,7 @@ breakpoint_re_set (void) |
7566401a ER |
1842 | create_longjmp_master_breakpoint ("_longjmp"); |
1843 | create_longjmp_master_breakpoint ("siglongjmp"); | |
1844 | create_longjmp_master_breakpoint ("_siglongjmp"); | |
1845 | + create_exception_master_breakpoint (); | |
1846 | } | |
1847 | \f | |
1848 | /* Reset the thread number of this breakpoint: | |
ab050a48 | 1849 | @@ -9327,6 +9585,22 @@ all_tracepoints () |
7566401a | 1850 | return tp_vec; |
3a58abaf | 1851 | } |
3a58abaf | 1852 | |
7566401a ER |
1853 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ |
1854 | + | |
1855 | +static void | |
1856 | +breakpoint_types_mark_used (void) | |
1857 | +{ | |
1858 | + struct breakpoint *b; | |
3a58abaf | 1859 | + |
7566401a ER |
1860 | + ALL_BREAKPOINTS (b) |
1861 | + { | |
1862 | + if (b->exp) | |
1863 | + exp_types_mark_used (b->exp); | |
1864 | + if (b->val) | |
1865 | + type_mark_used (value_type (b->val)); | |
1866 | + } | |
1867 | +} | |
3a58abaf | 1868 | + |
7566401a ER |
1869 | \f |
1870 | /* This help string is used for the break, hbreak, tbreak and thbreak commands. | |
1871 | It is defined as a macro to prevent duplication. | |
ab050a48 | 1872 | @@ -9850,4 +10124,5 @@ inferior in all-stop mode, gdb behaves as if always-inserted mode is off."), |
7566401a | 1873 | automatic_hardware_breakpoints = 1; |
3a58abaf | 1874 | |
7566401a ER |
1875 | observer_attach_about_to_proceed (breakpoint_about_to_proceed); |
1876 | + observer_attach_mark_used (breakpoint_types_mark_used); | |
1877 | } | |
1878 | diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h | |
1879 | index ba499c6..80f702f 100644 | |
1880 | --- a/gdb/breakpoint.h | |
1881 | +++ b/gdb/breakpoint.h | |
1882 | @@ -56,6 +56,13 @@ enum bptype | |
1883 | bp_longjmp, /* secret breakpoint to find longjmp() */ | |
1884 | bp_longjmp_resume, /* secret breakpoint to escape longjmp() */ | |
1885 | ||
1886 | + /* An internal breakpoint that is installed on the unwinder's | |
1887 | + debug hook. */ | |
1888 | + bp_exception, | |
1889 | + /* An internal breakpoint that is set at the point where an | |
1890 | + exception will land. */ | |
1891 | + bp_exception_resume, | |
1892 | + | |
1893 | /* Used by wait_for_inferior for stepping over subroutine calls, for | |
1894 | stepping over signal handlers, and for skipping prologues. */ | |
1895 | bp_step_resume, | |
1896 | @@ -118,6 +125,9 @@ enum bptype | |
1897 | ||
1898 | bp_longjmp_master, | |
1899 | ||
1900 | + /* Like bp_longjmp_master, but for exceptions. */ | |
1901 | + bp_exception_master, | |
1902 | + | |
1903 | bp_catchpoint, | |
1904 | ||
1905 | bp_tracepoint, | |
1906 | @@ -228,10 +238,6 @@ struct bp_location | |
1907 | the same parent breakpoint. */ | |
1908 | struct bp_location *next; | |
1909 | ||
1910 | - /* Pointer to the next breakpoint location, in a global | |
1911 | - list of all breakpoint locations. */ | |
1912 | - struct bp_location *global_next; | |
1913 | - | |
1914 | /* Type of this breakpoint location. */ | |
1915 | enum bp_loc_type loc_type; | |
1916 | ||
1917 | @@ -583,6 +589,10 @@ struct bpstat_what | |
1918 | continuing from a call dummy without popping the frame is not a | |
1919 | useful one). */ | |
1920 | int call_dummy; | |
1921 | + | |
1922 | + /* Used for BPSTAT_WHAT_SET_LONGJMP_RESUME. True if we are | |
1923 | + handling a longjmp, false if we are handling an exception. */ | |
1924 | + int is_longjmp; | |
1925 | }; | |
3a58abaf | 1926 | |
7566401a ER |
1927 | /* The possible return values for print_bpstat, print_it_normal, |
1928 | @@ -946,6 +956,9 @@ extern int catching_syscall_number (int syscall_number); | |
1929 | /* Tell a breakpoint to be quiet. */ | |
1930 | extern void make_breakpoint_silent (struct breakpoint *); | |
3a58abaf | 1931 | |
7566401a ER |
1932 | +/* Set break condition of breakpoint B to EXP. */ |
1933 | +extern void set_breakpoint_condition (struct breakpoint *b, char *exp, int from_tty); | |
3a58abaf | 1934 | + |
7566401a ER |
1935 | /* Return a tracepoint with the given number if found. */ |
1936 | extern struct breakpoint *get_tracepoint (int num); | |
3a58abaf | 1937 | |
3a58abaf | 1938 | diff --git a/gdb/c-exp.y b/gdb/c-exp.y |
7566401a | 1939 | index f8e4f12..5b47e2e 100644 |
3a58abaf AM |
1940 | --- a/gdb/c-exp.y |
1941 | +++ b/gdb/c-exp.y | |
7566401a | 1942 | @@ -117,6 +117,8 @@ static int yylex (void); |
3a58abaf AM |
1943 | |
1944 | void yyerror (char *); | |
1945 | ||
1946 | +/* Cleanup for 'nonempty_typelist' */ | |
1947 | +static struct cleanup *typelist_cleanup; | |
1948 | %} | |
1949 | ||
1950 | /* Although the yacc "value" of an expression is not used, | |
7566401a ER |
1951 | @@ -157,6 +159,7 @@ void yyerror (char *); |
1952 | %{ | |
1953 | /* YYSTYPE gets defined by %union */ | |
1954 | static int parse_number (char *, int, int, YYSTYPE *); | |
1955 | +static struct stoken operator_stoken (const char *); | |
1956 | %} | |
1957 | ||
1958 | %type <voidval> exp exp1 type_exp start variable qualified_name lcurly | |
1959 | @@ -199,9 +202,12 @@ static int parse_number (char *, int, int, YYSTYPE *); | |
1960 | ||
1961 | %token <ssym> NAME_OR_INT | |
1962 | ||
1963 | +%token OPERATOR | |
1964 | %token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON | |
1965 | %token TEMPLATE | |
1966 | %token ERROR | |
1967 | +%token NEW DELETE | |
1968 | +%type <sval> operator | |
1969 | ||
1970 | /* Special type cases, put in to allow the parser to distinguish different | |
1971 | legal basetypes. */ | |
1972 | @@ -401,6 +407,36 @@ arglist : arglist ',' exp %prec ABOVE_COMMA | |
3a58abaf AM |
1973 | { arglist_len++; } |
1974 | ; | |
1975 | ||
7566401a | 1976 | +exp : exp '(' nonempty_typelist ')' const_or_volatile |
3a58abaf | 1977 | + { int i; |
3a58abaf AM |
1978 | + write_exp_elt_opcode (TYPE_INSTANCE); |
1979 | + write_exp_elt_longcst ((LONGEST) $<ivec>3[0]); | |
1980 | + for (i = 0; i < $<ivec>3[0]; ++i) | |
1981 | + write_exp_elt_type ($<tvec>3[i + 1]); | |
1982 | + write_exp_elt_longcst((LONGEST) $<ivec>3[0]); | |
1983 | + write_exp_elt_opcode (TYPE_INSTANCE); | |
1984 | + do_cleanups (typelist_cleanup); | |
1985 | + } | |
1986 | + ; | |
1987 | + | |
1988 | +/* | |
1989 | +exp : BLOCKNAME '(' nonempty_typelist ')' | |
1990 | + { int i; | |
1991 | + write_exp_elt_opcode (TYPE_INSTANCE_LOOKUP); | |
1992 | + write_exp_elt_sym ($1.sym); | |
1993 | + write_exp_elt_opcode (TYPE_INSTANCE_LOOKUP); | |
1994 | + | |
1995 | + write_exp_elt_opcode (TYPE_INSTANCE); | |
1996 | + write_exp_elt_longcst ((LONGEST) $<ivec>3[0]); | |
1997 | + for (i = 0; i < $<ivec>3[0]; ++i) | |
1998 | + write_exp_elt_type ($<tvec>3[i + 1]); | |
1999 | + write_exp_elt_longcst((LONGEST) $<ivec>3[0]); | |
2000 | + write_exp_elt_opcode (TYPE_INSTANCE); | |
2001 | + do_cleanups (typelist_cleanup); | |
2002 | + } | |
2003 | + ; | |
2004 | +*/ | |
2005 | + | |
2006 | rcurly : '}' | |
2007 | { $$ = end_arglist () - 1; } | |
2008 | ; | |
7566401a ER |
2009 | @@ -703,6 +739,7 @@ variable: block COLONCOLON name |
2010 | qualified_name: typebase COLONCOLON name | |
3a58abaf | 2011 | { |
7566401a ER |
2012 | struct type *type = $1; |
2013 | + CHECK_TYPEDEF (type); | |
2014 | if (TYPE_CODE (type) != TYPE_CODE_STRUCT | |
2015 | && TYPE_CODE (type) != TYPE_CODE_UNION | |
2016 | && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) | |
2017 | @@ -718,6 +755,7 @@ qualified_name: typebase COLONCOLON name | |
2018 | { | |
2019 | struct type *type = $1; | |
2020 | struct stoken tmp_token; | |
2021 | + CHECK_TYPEDEF (type); | |
2022 | if (TYPE_CODE (type) != TYPE_CODE_STRUCT | |
2023 | && TYPE_CODE (type) != TYPE_CODE_UNION | |
2024 | && TYPE_CODE (type) != TYPE_CODE_NAMESPACE) | |
2025 | @@ -740,12 +778,13 @@ qualified_name: typebase COLONCOLON name | |
3a58abaf AM |
2026 | ; |
2027 | ||
2028 | variable: qualified_name | |
2029 | + | COLONCOLON qualified_name | |
2030 | | COLONCOLON name | |
2031 | { | |
2032 | char *name = copy_name ($2); | |
2033 | struct symbol *sym; | |
2034 | struct minimal_symbol *msymbol; | |
2035 | - | |
2036 | + | |
2037 | sym = | |
2038 | lookup_symbol (name, (const struct block *) NULL, | |
2039 | VAR_DOMAIN, (int *) NULL); | |
7566401a | 2040 | @@ -883,7 +922,7 @@ array_mod: '[' ']' |
3a58abaf AM |
2041 | func_mod: '(' ')' |
2042 | { $$ = 0; } | |
2043 | | '(' nonempty_typelist ')' | |
2044 | - { free ($2); $$ = 0; } | |
2045 | + { do_cleanups (typelist_cleanup); $$ = 0; } | |
2046 | ; | |
2047 | ||
2048 | /* We used to try to recognize pointer to member types here, but | |
7566401a | 2049 | @@ -1088,12 +1127,15 @@ typename: TYPENAME |
3a58abaf AM |
2050 | nonempty_typelist |
2051 | : type | |
2052 | { $$ = (struct type **) malloc (sizeof (struct type *) * 2); | |
2053 | + typelist_cleanup = make_cleanup (free, $$); | |
2054 | $<ivec>$[0] = 1; /* Number of types in vector */ | |
2055 | $$[1] = $1; | |
2056 | } | |
2057 | | nonempty_typelist ',' type | |
2058 | { int len = sizeof (struct type *) * (++($<ivec>1[0]) + 1); | |
2059 | $$ = (struct type **) realloc ((char *) $1, len); | |
2060 | + discard_cleanups (typelist_cleanup); | |
2061 | + typelist_cleanup = make_cleanup (free, $$); | |
2062 | $$[$<ivec>$[0]] = $3; | |
2063 | } | |
2064 | ; | |
7566401a ER |
2065 | @@ -1117,10 +1159,135 @@ const_or_volatile_noopt: const_and_volatile |
2066 | { push_type (tp_volatile); } | |
2067 | ; | |
3a58abaf | 2068 | |
7566401a ER |
2069 | +operator: OPERATOR NEW |
2070 | + { $$ = operator_stoken (" new"); } | |
2071 | + | OPERATOR DELETE | |
2072 | + { $$ = operator_stoken (" delete"); } | |
2073 | + | OPERATOR NEW '[' ']' | |
2074 | + { $$ = operator_stoken (" new[]"); } | |
2075 | + | OPERATOR DELETE '[' ']' | |
2076 | + { $$ = operator_stoken (" delete[]"); } | |
2077 | + | OPERATOR '+' | |
2078 | + { $$ = operator_stoken ("+"); } | |
2079 | + | OPERATOR '-' | |
2080 | + { $$ = operator_stoken ("-"); } | |
2081 | + | OPERATOR '*' | |
2082 | + { $$ = operator_stoken ("*"); } | |
2083 | + | OPERATOR '/' | |
2084 | + { $$ = operator_stoken ("/"); } | |
2085 | + | OPERATOR '%' | |
2086 | + { $$ = operator_stoken ("%"); } | |
2087 | + | OPERATOR '^' | |
2088 | + { $$ = operator_stoken ("^"); } | |
2089 | + | OPERATOR '&' | |
2090 | + { $$ = operator_stoken ("&"); } | |
2091 | + | OPERATOR '|' | |
2092 | + { $$ = operator_stoken ("|"); } | |
2093 | + | OPERATOR '~' | |
2094 | + { $$ = operator_stoken ("~"); } | |
2095 | + | OPERATOR '!' | |
2096 | + { $$ = operator_stoken ("!"); } | |
2097 | + | OPERATOR '=' | |
2098 | + { $$ = operator_stoken ("="); } | |
2099 | + | OPERATOR '<' | |
2100 | + { $$ = operator_stoken ("<"); } | |
2101 | + | OPERATOR '>' | |
2102 | + { $$ = operator_stoken (">"); } | |
2103 | + | OPERATOR ASSIGN_MODIFY | |
2104 | + { const char *op = "unknown"; | |
2105 | + switch ($2) | |
2106 | + { | |
2107 | + case BINOP_RSH: | |
2108 | + op = ">>="; | |
2109 | + break; | |
2110 | + case BINOP_LSH: | |
2111 | + op = "<<="; | |
2112 | + break; | |
2113 | + case BINOP_ADD: | |
2114 | + op = "+="; | |
2115 | + break; | |
2116 | + case BINOP_SUB: | |
2117 | + op = "-="; | |
2118 | + break; | |
2119 | + case BINOP_MUL: | |
2120 | + op = "*="; | |
2121 | + break; | |
2122 | + case BINOP_DIV: | |
2123 | + op = "/="; | |
2124 | + break; | |
2125 | + case BINOP_REM: | |
2126 | + op = "%="; | |
2127 | + break; | |
2128 | + case BINOP_BITWISE_IOR: | |
2129 | + op = "|="; | |
2130 | + break; | |
2131 | + case BINOP_BITWISE_AND: | |
2132 | + op = "&="; | |
2133 | + break; | |
2134 | + case BINOP_BITWISE_XOR: | |
2135 | + op = "^="; | |
2136 | + break; | |
2137 | + default: | |
2138 | + break; | |
2139 | + } | |
2140 | + | |
2141 | + $$ = operator_stoken (op); | |
2142 | + } | |
2143 | + | OPERATOR LSH | |
2144 | + { $$ = operator_stoken ("<<"); } | |
2145 | + | OPERATOR RSH | |
2146 | + { $$ = operator_stoken (">>"); } | |
2147 | + | OPERATOR EQUAL | |
2148 | + { $$ = operator_stoken ("=="); } | |
2149 | + | OPERATOR NOTEQUAL | |
2150 | + { $$ = operator_stoken ("!="); } | |
2151 | + | OPERATOR LEQ | |
2152 | + { $$ = operator_stoken ("<="); } | |
2153 | + | OPERATOR GEQ | |
2154 | + { $$ = operator_stoken (">="); } | |
2155 | + | OPERATOR ANDAND | |
2156 | + { $$ = operator_stoken ("&&"); } | |
2157 | + | OPERATOR OROR | |
2158 | + { $$ = operator_stoken ("||"); } | |
2159 | + | OPERATOR INCREMENT | |
2160 | + { $$ = operator_stoken ("++"); } | |
2161 | + | OPERATOR DECREMENT | |
2162 | + { $$ = operator_stoken ("--"); } | |
2163 | + | OPERATOR ',' | |
2164 | + { $$ = operator_stoken (","); } | |
2165 | + | OPERATOR ARROW_STAR | |
2166 | + { $$ = operator_stoken ("->*"); } | |
2167 | + | OPERATOR ARROW | |
2168 | + { $$ = operator_stoken ("->"); } | |
2169 | + | OPERATOR '(' ')' | |
2170 | + { $$ = operator_stoken ("()"); } | |
2171 | + | OPERATOR '[' ']' | |
2172 | + { $$ = operator_stoken ("[]"); } | |
2173 | + | OPERATOR ptype | |
2174 | + { char *name, *canon; | |
2175 | + long length; | |
2176 | + struct ui_file *buf = mem_fileopen (); | |
2177 | + | |
2178 | + c_print_type ($2, NULL, buf, -1, 0); | |
2179 | + name = ui_file_xstrdup (buf, &length); | |
2180 | + canon = cp_canonicalize_string (name); | |
2181 | + if (canon != NULL) | |
2182 | + { | |
2183 | + xfree (name); | |
2184 | + name = canon; | |
2185 | + } | |
2186 | + ui_file_delete (buf); | |
2187 | + $$ = operator_stoken (name); | |
2188 | + } | |
2189 | + ; | |
3a58abaf | 2190 | + |
3a58abaf | 2191 | + |
7566401a ER |
2192 | + |
2193 | name : NAME { $$ = $1.stoken; } | |
2194 | | BLOCKNAME { $$ = $1.stoken; } | |
2195 | | TYPENAME { $$ = $1.stoken; } | |
2196 | | NAME_OR_INT { $$ = $1.stoken; } | |
2197 | + | operator { $$ = $1; } | |
2198 | ; | |
2199 | ||
2200 | name_not_typename : NAME | |
2201 | @@ -1136,6 +1303,20 @@ name_not_typename : NAME | |
2202 | ||
2203 | %% | |
2204 | ||
2205 | +/* Returns a stoken of the operator name given by OP (which does not | |
2206 | + include the string "operator"). The result is xmalloc'd. */ | |
2207 | +static struct stoken | |
2208 | +operator_stoken (const char *op) | |
3a58abaf | 2209 | +{ |
7566401a ER |
2210 | + static const char *operator_string = "operator"; |
2211 | + struct stoken st = { NULL, 0 }; | |
2212 | + st.length = strlen (operator_string) + strlen (op); | |
2213 | + st.ptr = xmalloc (st.length + 1); | |
2214 | + strcpy (st.ptr, operator_string); | |
2215 | + strcat (st.ptr, op); | |
2216 | + return st; | |
2217 | +}; | |
3a58abaf | 2218 | + |
7566401a ER |
2219 | /* Take care of parsing a number (anything that starts with a digit). |
2220 | Set yylval and return the token type; update lexptr. | |
2221 | LEN is the number of characters in it. */ | |
2222 | @@ -1714,6 +1895,9 @@ static const struct token ident_tokens[] = | |
2223 | {"long", LONG, OP_NULL, 0}, | |
2224 | {"true", TRUEKEYWORD, OP_NULL, 1}, | |
2225 | {"int", INT_KEYWORD, OP_NULL, 0}, | |
2226 | + {"new", NEW, OP_NULL, 1}, | |
2227 | + {"delete", DELETE, OP_NULL, 1}, | |
2228 | + {"operator", OPERATOR, OP_NULL, 1}, | |
2229 | ||
2230 | {"and", ANDAND, BINOP_END, 1}, | |
2231 | {"and_eq", ASSIGN_MODIFY, BINOP_BITWISE_AND, 1}, | |
2232 | @@ -1822,6 +2006,13 @@ static int last_was_structop; | |
3a58abaf | 2233 | static int |
7566401a | 2234 | yylex (void) |
3a58abaf AM |
2235 | { |
2236 | + /* name_prefix stores the full qualification of a variable that is | |
2237 | + specified in the expression. It is used to eleminate confusion | |
2238 | + during lookup.*/ | |
7566401a | 2239 | + static char *name_prefix = NULL; |
3a58abaf AM |
2240 | + static int name_prefix_len = 0; |
2241 | + static int terminate_prefix = 0; | |
2242 | + | |
2243 | int c; | |
2244 | int namelen; | |
2245 | unsigned int i; | |
7566401a | 2246 | @@ -1830,9 +2021,19 @@ yylex (void) |
3a58abaf AM |
2247 | char *copy; |
2248 | ||
2249 | last_was_structop = 0; | |
2250 | - | |
2251 | + | |
2252 | retry: | |
2253 | - | |
2254 | + | |
7566401a ER |
2255 | + if (terminate_prefix |
2256 | + || lexptr != name_prefix + name_prefix_len) | |
2257 | + { | |
2258 | + /* Some token was skipped, so clear name_prefix. */ | |
2259 | + name_prefix = NULL; | |
2260 | + name_prefix_len = 0; | |
2261 | + } | |
3a58abaf AM |
2262 | + |
2263 | + terminate_prefix = 1; | |
2264 | + | |
2265 | /* Check if this is a macro invocation that we need to expand. */ | |
2266 | if (! scanning_macro_expansion ()) | |
2267 | { | |
7566401a ER |
2268 | @@ -1868,10 +2069,19 @@ yylex (void) |
2269 | && parse_language->la_language != language_cplus) | |
2270 | break; | |
2271 | ||
2272 | + if (tokentab2[i].token == COLONCOLON) | |
2273 | + { | |
2274 | + name_prefix_len += 2; | |
2275 | + terminate_prefix = 0; | |
2276 | + if (name_prefix == NULL) | |
2277 | + name_prefix = lexptr; | |
2278 | + } | |
2279 | + | |
3a58abaf AM |
2280 | lexptr += 2; |
2281 | yylval.opcode = tokentab2[i].opcode; | |
2282 | if (in_parse_field && tokentab2[i].token == ARROW) | |
2283 | last_was_structop = 1; | |
2284 | + | |
2285 | return tokentab2[i].token; | |
2286 | } | |
2287 | ||
7566401a | 2288 | @@ -1900,6 +2110,8 @@ yylex (void) |
3a58abaf AM |
2289 | return 0; |
2290 | ||
2291 | case ' ': | |
2292 | + name_prefix_len++; | |
2293 | + terminate_prefix = 0; | |
2294 | case '\t': | |
2295 | case '\n': | |
2296 | lexptr++; | |
7566401a | 2297 | @@ -2057,11 +2269,13 @@ yylex (void) |
3a58abaf AM |
2298 | error ("Invalid character '%c' in expression.", c); |
2299 | ||
2300 | /* It's a name. See how long it is. */ | |
2301 | + | |
2302 | namelen = 0; | |
2303 | for (c = tokstart[namelen]; | |
2304 | (c == '_' || c == '$' || (c >= '0' && c <= '9') | |
2305 | || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');) | |
2306 | { | |
2307 | + | |
2308 | /* Template parameter lists are part of the name. | |
2309 | FIXME: This mishandles `print $a<4&&$a>3'. */ | |
2310 | ||
7566401a | 2311 | @@ -2125,14 +2339,29 @@ yylex (void) |
3a58abaf AM |
2312 | currently as names of types; NAME for other symbols. |
2313 | The caller is not constrained to care about the distinction. */ | |
2314 | { | |
2315 | + char *tmp = copy; | |
2316 | struct symbol *sym; | |
2317 | int is_a_field_of_this = 0; | |
2318 | int hextype; | |
2319 | ||
2320 | - sym = lookup_symbol (copy, expression_context_block, | |
7566401a | 2321 | + if (name_prefix != NULL) |
3a58abaf | 2322 | + tmp = savestring (name_prefix, name_prefix_len+namelen); |
3a58abaf AM |
2323 | + |
2324 | + sym = lookup_symbol (tmp, expression_context_block, | |
2325 | VAR_DOMAIN, | |
2326 | parse_language->la_language == language_cplus | |
2327 | ? &is_a_field_of_this : (int *) NULL); | |
2328 | + | |
7566401a ER |
2329 | + /* Keep this name as the prefix for the next name. */ |
2330 | + if (sym) | |
2331 | + { | |
2332 | + if (name_prefix == NULL) | |
2333 | + name_prefix = tokstart; | |
2334 | + | |
2335 | + name_prefix_len += namelen; | |
2336 | + terminate_prefix = 0; | |
3a58abaf | 2337 | + } |
3a58abaf AM |
2338 | + |
2339 | /* Call lookup_symtab, not lookup_partial_symtab, in case there are | |
2340 | no psymtabs (coff, xcoff, or some future change to blow away the | |
2341 | psymtabs once once symbols are read). */ | |
7566401a | 2342 | @@ -2191,6 +2420,7 @@ yylex (void) |
3a58abaf AM |
2343 | yylval.ssym.is_a_field_of_this = is_a_field_of_this; |
2344 | if (in_parse_field && *lexptr == '\0') | |
2345 | saw_name_at_eof = 1; | |
2346 | + | |
2347 | return NAME; | |
2348 | } | |
2349 | } | |
2350 | diff --git a/gdb/c-lang.c b/gdb/c-lang.c | |
7566401a | 2351 | index d01490c..bc35a3e 100644 |
3a58abaf AM |
2352 | --- a/gdb/c-lang.c |
2353 | +++ b/gdb/c-lang.c | |
7566401a ER |
2354 | @@ -715,7 +715,7 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length, |
2355 | If length returned from read_string was > 0, return the number of | |
2356 | characters read by dividing the number of bytes by width. */ | |
2357 | if (*length != 0) | |
2358 | - *length = *length / width; | |
2359 | + *length = *length / width; | |
3a58abaf | 2360 | |
7566401a | 2361 | *charset = target_charset (); |
3a58abaf | 2362 | |
7566401a ER |
2363 | @@ -1038,6 +1038,9 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp, |
2364 | return evaluate_subexp_standard (expect_type, exp, pos, noside); | |
2365 | } | |
3a58abaf | 2366 | |
7566401a ER |
2367 | +\f |
2368 | +/* Preprocessing and parsing C and C++ expressions. */ | |
2369 | + | |
2370 | ||
2371 | \f | |
2372 | /* Table mapping opcodes into strings for printing operators | |
2373 | @@ -1138,6 +1141,7 @@ static const struct exp_descriptor exp_descriptor_c = | |
3a58abaf | 2374 | { |
7566401a ER |
2375 | print_subexp_standard, |
2376 | operator_length_standard, | |
2377 | + operator_check_standard, | |
2378 | op_name_standard, | |
2379 | dump_subexp_body_standard, | |
2380 | evaluate_subexp_c | |
2381 | diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c | |
2382 | index b193080..04cf3bc 100644 | |
2383 | --- a/gdb/c-typeprint.c | |
2384 | +++ b/gdb/c-typeprint.c | |
2385 | @@ -32,6 +32,7 @@ | |
2386 | #include "c-lang.h" | |
2387 | #include "typeprint.h" | |
2388 | #include "cp-abi.h" | |
2389 | +#include "jv-lang.h" | |
3a58abaf | 2390 | |
7566401a ER |
2391 | #include "gdb_string.h" |
2392 | #include <errno.h> | |
2393 | @@ -40,8 +41,6 @@ static void cp_type_print_method_args (struct type *mtype, char *prefix, | |
2394 | char *varstring, int staticp, | |
2395 | struct ui_file *stream); | |
3a58abaf | 2396 | |
7566401a ER |
2397 | -static void c_type_print_args (struct type *, struct ui_file *); |
2398 | - | |
2399 | static void cp_type_print_derivation_info (struct ui_file *, struct type *); | |
2400 | ||
2401 | static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int, | |
2402 | @@ -199,6 +198,23 @@ cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring, | |
2403 | fprintf_filtered (stream, "void"); | |
2404 | ||
2405 | fprintf_filtered (stream, ")"); | |
3a58abaf | 2406 | + |
7566401a ER |
2407 | + /* For non-static methods, read qualifiers from the type of |
2408 | + THIS. */ | |
2409 | + if (!staticp) | |
2410 | + { | |
2411 | + struct type *domain; | |
3a58abaf | 2412 | + |
7566401a ER |
2413 | + gdb_assert (nargs > 0); |
2414 | + gdb_assert (TYPE_CODE (args[0].type) == TYPE_CODE_PTR); | |
2415 | + domain = TYPE_TARGET_TYPE (args[0].type); | |
3a58abaf | 2416 | + |
7566401a ER |
2417 | + if (TYPE_CONST (domain)) |
2418 | + fprintf_filtered (stream, " const"); | |
3a58abaf | 2419 | + |
7566401a ER |
2420 | + if (TYPE_VOLATILE (domain)) |
2421 | + fprintf_filtered (stream, " volatile"); | |
3a58abaf | 2422 | + } |
3a58abaf AM |
2423 | } |
2424 | ||
3a58abaf | 2425 | |
7566401a | 2426 | @@ -355,10 +371,14 @@ c_type_print_modifier (struct type *type, struct ui_file *stream, |
3a58abaf AM |
2427 | |
2428 | /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD | |
2429 | or TYPE_CODE_FUNC, to STREAM. Artificial arguments, such as "this" | |
2430 | - in non-static methods, are displayed. */ | |
2431 | + in non-static methods, are displayed if SHOW_ARTIFICIAL is | |
7566401a ER |
2432 | + non-zero. LANGUAGE is the language in which TYPE was defined. This is |
2433 | + a necessary evil since this code is used by the C, C++, and Java | |
2434 | + backends. */ | |
3a58abaf AM |
2435 | |
2436 | -static void | |
2437 | -c_type_print_args (struct type *type, struct ui_file *stream) | |
2438 | +void | |
2439 | +c_type_print_args (struct type *type, struct ui_file *stream, | |
7566401a | 2440 | + int show_artificial, enum language language) |
3a58abaf AM |
2441 | { |
2442 | int i, len; | |
2443 | struct field *args; | |
7566401a | 2444 | @@ -370,13 +390,19 @@ c_type_print_args (struct type *type, struct ui_file *stream) |
3a58abaf AM |
2445 | |
2446 | for (i = 0; i < TYPE_NFIELDS (type); i++) | |
2447 | { | |
2448 | + if (TYPE_FIELD_ARTIFICIAL (type, i) && !show_artificial) | |
2449 | + continue; | |
2450 | + | |
2451 | if (printed_any) | |
2452 | { | |
2453 | fprintf_filtered (stream, ", "); | |
7566401a ER |
2454 | wrap_here (" "); |
2455 | } | |
2456 | ||
2457 | - c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); | |
2458 | + if (language == language_java) | |
2459 | + java_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); | |
2460 | + else | |
2461 | + c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); | |
2462 | printed_any = 1; | |
2463 | } | |
2464 | ||
2465 | @@ -560,7 +586,12 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, | |
3a58abaf AM |
2466 | fprintf_filtered (stream, ")"); |
2467 | ||
2468 | fprintf_filtered (stream, "["); | |
2469 | - if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0 | |
2470 | + if (TYPE_ARRAY_BOUND_IS_DWARF_BLOCK (type, 1)) | |
2471 | + { | |
2472 | + /* No _() - printed sources should not be locale dependent. */ | |
2473 | + fprintf_filtered (stream, "variable"); | |
2474 | + } | |
2475 | + else if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0 | |
2476 | && !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)) | |
2477 | fprintf_filtered (stream, "%d", | |
2478 | (TYPE_LENGTH (type) | |
7566401a | 2479 | @@ -593,7 +624,7 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, |
3a58abaf AM |
2480 | if (passed_a_ptr) |
2481 | fprintf_filtered (stream, ")"); | |
2482 | if (!demangled_args) | |
2483 | - c_type_print_args (type, stream); | |
7566401a | 2484 | + c_type_print_args (type, stream, 1, language_c); |
3a58abaf AM |
2485 | c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, |
2486 | passed_a_ptr, 0); | |
2487 | break; | |
7566401a ER |
2488 | diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c |
2489 | index ce7c2a6..6380fec 100644 | |
2490 | --- a/gdb/cli/cli-cmds.c | |
2491 | +++ b/gdb/cli/cli-cmds.c | |
2492 | @@ -46,6 +46,8 @@ | |
2493 | #include "cli/cli-setshow.h" | |
2494 | #include "cli/cli-cmds.h" | |
3a58abaf | 2495 | |
7566401a | 2496 | +#include "python/python.h" |
3a58abaf | 2497 | + |
7566401a ER |
2498 | #ifdef TUI |
2499 | #include "tui/tui.h" /* For tui_active et.al. */ | |
2500 | #endif | |
2501 | @@ -183,6 +185,7 @@ struct cmd_list_element *showchecklist; | |
3a58abaf | 2502 | |
7566401a | 2503 | /* Command tracing state. */ |
3a58abaf | 2504 | |
7566401a ER |
2505 | +static int source_python = 0; |
2506 | int source_verbose = 0; | |
2507 | int trace_commands = 0; | |
2508 | \f | |
2509 | @@ -444,6 +447,7 @@ source_script (char *file, int from_tty) | |
2510 | struct cleanup *old_cleanups; | |
2511 | char *full_pathname = NULL; | |
2512 | int fd; | |
2513 | + int is_python; | |
3a58abaf | 2514 | |
7566401a ER |
2515 | if (file == NULL || *file == 0) |
2516 | { | |
2517 | @@ -476,8 +480,16 @@ source_script (char *file, int from_tty) | |
3a58abaf | 2518 | } |
7566401a | 2519 | } |
3a58abaf | 2520 | |
7566401a ER |
2521 | + is_python = source_python; |
2522 | + if (strlen (file) > 3 && !strcmp (&file[strlen (file) - 3], ".py")) | |
2523 | + is_python = 1; | |
2524 | + | |
2525 | stream = fdopen (fd, FOPEN_RT); | |
2526 | - script_from_file (stream, file); | |
2527 | + | |
2528 | + if (is_python) | |
2529 | + source_python_script (stream, file); | |
2530 | + else | |
2531 | + script_from_file (stream, file); | |
3a58abaf | 2532 | |
7566401a ER |
2533 | do_cleanups (old_cleanups); |
2534 | } | |
2535 | @@ -491,15 +503,30 @@ source_verbose_cleanup (void *old_value) | |
2536 | xfree (old_value); | |
2537 | } | |
3a58abaf | 2538 | |
7566401a ER |
2539 | +/* A helper for source_command. Look for an argument in *ARGS. |
2540 | + Update *ARGS by stripping leading whitespace. If an argument is | |
2541 | + found, return it (a character). Otherwise, return 0. */ | |
2542 | +static int | |
2543 | +find_argument (char **args) | |
2544 | +{ | |
2545 | + int result = 0; | |
2546 | + while (isspace ((*args)[0])) | |
2547 | + ++*args; | |
2548 | + if ((*args)[0] == '-' && isalpha ((*args)[1])) | |
2549 | + { | |
2550 | + result = (*args)[1]; | |
2551 | + *args += 3; | |
2552 | + } | |
2553 | + return result; | |
2554 | +} | |
2555 | + | |
2556 | static void | |
2557 | source_command (char *args, int from_tty) | |
3a58abaf | 2558 | { |
7566401a ER |
2559 | struct cleanup *old_cleanups; |
2560 | - char *file = args; | |
2561 | - int *old_source_verbose = xmalloc (sizeof(int)); | |
2562 | ||
2563 | - *old_source_verbose = source_verbose; | |
2564 | - old_cleanups = make_cleanup (source_verbose_cleanup, old_source_verbose); | |
2565 | + old_cleanups = make_cleanup_restore_integer (&source_verbose); | |
2566 | + make_cleanup_restore_integer (&source_python); | |
2567 | ||
2568 | /* -v causes the source command to run in verbose mode. | |
2569 | We still have to be able to handle filenames with spaces in a | |
2570 | @@ -507,23 +534,28 @@ source_command (char *args, int from_tty) | |
2571 | ||
2572 | if (args) | |
2573 | { | |
2574 | - /* Make sure leading white space does not break the comparisons. */ | |
2575 | - while (isspace(args[0])) | |
2576 | - args++; | |
2577 | - | |
2578 | - /* Is -v the first thing in the string? */ | |
2579 | - if (args[0] == '-' && args[1] == 'v' && isspace (args[2])) | |
2580 | + while (1) | |
3a58abaf | 2581 | { |
7566401a ER |
2582 | - source_verbose = 1; |
2583 | - | |
2584 | - /* Trim -v and whitespace from the filename. */ | |
2585 | - file = &args[3]; | |
2586 | - while (isspace (file[0])) | |
2587 | - file++; | |
2588 | + int arg = find_argument (&args); | |
2589 | + if (!arg) | |
2590 | + break; | |
2591 | + switch (arg) | |
2592 | + { | |
2593 | + case 'v': | |
2594 | + source_verbose = 1; | |
2595 | + break; | |
2596 | + case 'p': | |
2597 | + source_python = 1; | |
2598 | + break; | |
2599 | + default: | |
2600 | + error (_("unrecognized option -%c"), arg); | |
2601 | + } | |
3a58abaf | 2602 | } |
3a58abaf AM |
2603 | } |
2604 | ||
7566401a ER |
2605 | - source_script (file, from_tty); |
2606 | + source_script (args, from_tty); | |
2607 | + | |
2608 | + do_cleanups (old_cleanups); | |
3a58abaf | 2609 | } |
7566401a ER |
2610 | |
2611 | ||
2612 | @@ -1307,7 +1339,9 @@ Read commands from a file named FILE.\n\ | |
2613 | Optional -v switch (before the filename) causes each command in\n\ | |
2614 | FILE to be echoed as it is executed.\n\ | |
2615 | Note that the file \"%s\" is read automatically in this way\n\ | |
2616 | -when GDB is started."), gdbinit); | |
2617 | +when GDB is started.\n\ | |
2618 | +Optional -p switch (before the filename) causes FILE to be evaluated\n\ | |
2619 | +as Python code."), gdbinit); | |
2620 | c = add_cmd ("source", class_support, source_command, | |
2621 | source_help_text, &cmdlist); | |
2622 | set_cmd_completer (c, filename_completer); | |
2623 | diff --git a/gdb/coffread.c b/gdb/coffread.c | |
2624 | index 888f8b4..65494b8 100644 | |
2625 | --- a/gdb/coffread.c | |
2626 | +++ b/gdb/coffread.c | |
2627 | @@ -346,7 +346,7 @@ coff_alloc_type (int index) | |
2628 | We will fill it in later if we find out how. */ | |
2629 | if (type == NULL) | |
2630 | { | |
2631 | - type = alloc_type (current_objfile); | |
2632 | + type = alloc_type (current_objfile, NULL); | |
2633 | *type_addr = type; | |
2634 | } | |
2635 | return type; | |
2636 | @@ -2121,6 +2121,7 @@ static struct sym_fns coff_sym_fns = | |
2637 | coff_new_init, /* sym_new_init: init anything gbl to entire symtab */ | |
2638 | coff_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
2639 | coff_symfile_read, /* sym_read: read a symbol file into symtab */ | |
2640 | + NULL, /* sym_read_psymbols */ | |
2641 | coff_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
2642 | default_symfile_offsets, /* sym_offsets: xlate external to internal form */ | |
2643 | default_symfile_segments, /* sym_segments: Get segment information from | |
2644 | diff --git a/gdb/config.in b/gdb/config.in | |
2645 | index 4716524..0745c65 100644 | |
2646 | --- a/gdb/config.in | |
2647 | +++ b/gdb/config.in | |
2648 | @@ -46,11 +46,10 @@ | |
2649 | language is requested. */ | |
2650 | #undef ENABLE_NLS | |
2651 | ||
2652 | -/* look for global separate data files in this path [DATADIR/gdb] */ | |
2653 | +/* Global directory for GDB data files. */ | |
2654 | #undef GDB_DATADIR | |
2655 | ||
2656 | -/* Define if the gdb-datadir directory should be relocated when GDB is moved. | |
2657 | - */ | |
2658 | +/* Define if GDB datadir should be relocated when GDB is moved. */ | |
2659 | #undef GDB_DATADIR_RELOCATABLE | |
2660 | ||
2661 | /* Define to be a string naming the default host character set. */ | |
2662 | @@ -647,6 +646,9 @@ | |
2663 | 'ptrdiff_t'. */ | |
2664 | #undef PTRDIFF_T_SUFFIX | |
2665 | ||
2666 | +/* Define to install path for Python sources */ | |
2667 | +#undef PYTHONDIR | |
2668 | + | |
2669 | /* Relocated directory for source files. */ | |
2670 | #undef RELOC_SRCDIR | |
2671 | ||
2672 | diff --git a/gdb/config/i386/nm-i386.h b/gdb/config/i386/nm-i386.h | |
3a58abaf | 2673 | new file mode 100644 |
7566401a | 2674 | index 0000000..5f237cc |
3a58abaf | 2675 | --- /dev/null |
7566401a ER |
2676 | +++ b/gdb/config/i386/nm-i386.h |
2677 | @@ -0,0 +1,125 @@ | |
2678 | +/* Native macro definitions for GDB on an Intel i[3456]86. | |
2679 | + Copyright 2001, 2004, 2007, 2008, 2009 Free Software Foundation, Inc. | |
3a58abaf AM |
2680 | + |
2681 | + This file is part of GDB. | |
2682 | + | |
2683 | + This program is free software; you can redistribute it and/or modify | |
2684 | + it under the terms of the GNU General Public License as published by | |
2685 | + the Free Software Foundation; either version 3 of the License, or | |
2686 | + (at your option) any later version. | |
2687 | + | |
2688 | + This program is distributed in the hope that it will be useful, | |
2689 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
2690 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
2691 | + GNU General Public License for more details. | |
2692 | + | |
2693 | + You should have received a copy of the GNU General Public License | |
2694 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
2695 | + | |
7566401a ER |
2696 | +#ifndef NM_I386_H |
2697 | +#define NM_I386_H 1 | |
3a58abaf | 2698 | + |
7566401a | 2699 | +/* Hardware-assisted breakpoints and watchpoints. */ |
3a58abaf | 2700 | + |
7566401a ER |
2701 | +/* Targets should define this to use the generic x86 watchpoint support. */ |
2702 | +#ifdef I386_USE_GENERIC_WATCHPOINTS | |
3a58abaf | 2703 | + |
7566401a ER |
2704 | +/* Add watchpoint methods to the provided target_ops. Targets which call |
2705 | + this should also define I386_WATCHPOINTS_IN_TARGET_VECTOR. */ | |
2706 | +struct target_ops; | |
2707 | +void i386_use_watchpoints (struct target_ops *); | |
3a58abaf | 2708 | + |
7566401a ER |
2709 | +/* Clear the reference counts and forget everything we knew about DRi. */ |
2710 | +extern void i386_cleanup_dregs (void); | |
3a58abaf | 2711 | + |
7566401a ER |
2712 | +/* Insert a watchpoint to watch a memory region which starts at |
2713 | + address ADDR and whose length is LEN bytes. Watch memory accesses | |
2714 | + of the type TYPE. Return 0 on success, -1 on failure. */ | |
2715 | +extern int i386_insert_watchpoint (CORE_ADDR addr, int len, int type); | |
3a58abaf | 2716 | + |
7566401a ER |
2717 | +/* Remove a watchpoint that watched the memory region which starts at |
2718 | + address ADDR, whose length is LEN bytes, and for accesses of the | |
2719 | + type TYPE. Return 0 on success, -1 on failure. */ | |
2720 | +extern int i386_remove_watchpoint (CORE_ADDR addr, int len, int type); | |
3a58abaf | 2721 | + |
7566401a ER |
2722 | +/* Return non-zero if we can watch a memory region that starts at |
2723 | + address ADDR and whose length is LEN bytes. */ | |
2724 | +extern int i386_region_ok_for_watchpoint (CORE_ADDR addr, int len); | |
3a58abaf | 2725 | + |
7566401a ER |
2726 | +/* Return non-zero if the inferior has some break/watchpoint that |
2727 | + triggered. */ | |
2728 | +extern int i386_stopped_by_hwbp (void); | |
3a58abaf | 2729 | + |
7566401a ER |
2730 | +/* If the inferior has some break/watchpoint that triggered, set |
2731 | + the address associated with that break/watchpoint and return | |
2732 | + true. Otherwise, return false. */ | |
2733 | +extern int i386_stopped_data_address (struct target_ops *, CORE_ADDR *); | |
3a58abaf | 2734 | + |
7566401a ER |
2735 | +/* Insert a hardware-assisted breakpoint at BP_TGT->placed_address. |
2736 | + Return 0 on success, EBUSY on failure. */ | |
2737 | +struct bp_target_info; | |
2738 | +extern int i386_insert_hw_breakpoint (struct bp_target_info *bp_tgt); | |
3a58abaf | 2739 | + |
7566401a ER |
2740 | +/* Remove a hardware-assisted breakpoint at BP_TGT->placed_address. |
2741 | + Return 0 on success, -1 on failure. */ | |
2742 | +extern int i386_remove_hw_breakpoint (struct bp_target_info *bp_tgt); | |
3a58abaf | 2743 | + |
7566401a | 2744 | +extern int i386_stopped_by_watchpoint (void); |
3a58abaf | 2745 | + |
7566401a | 2746 | +#ifndef I386_WATCHPOINTS_IN_TARGET_VECTOR |
3a58abaf | 2747 | + |
7566401a ER |
2748 | +/* Returns the number of hardware watchpoints of type TYPE that we can |
2749 | + set. Value is positive if we can set CNT watchpoints, zero if | |
2750 | + setting watchpoints of type TYPE is not supported, and negative if | |
2751 | + CNT is more than the maximum number of watchpoints of type TYPE | |
2752 | + that we can support. TYPE is one of bp_hardware_watchpoint, | |
2753 | + bp_read_watchpoint, bp_write_watchpoint, or bp_hardware_breakpoint. | |
2754 | + CNT is the number of such watchpoints used so far (including this | |
2755 | + one). OTHERTYPE is non-zero if other types of watchpoints are | |
2756 | + currently enabled. | |
3a58abaf | 2757 | + |
7566401a ER |
2758 | + We always return 1 here because we don't have enough information |
2759 | + about possible overlap of addresses that they want to watch. As an | |
2760 | + extreme example, consider the case where all the watchpoints watch | |
2761 | + the same address and the same region length: then we can handle a | |
2762 | + virtually unlimited number of watchpoints, due to debug register | |
2763 | + sharing implemented via reference counts in i386-nat.c. */ | |
3a58abaf | 2764 | + |
7566401a | 2765 | +#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1 |
3a58abaf | 2766 | + |
7566401a ER |
2767 | +/* Returns non-zero if we can use hardware watchpoints to watch a |
2768 | + region whose address is ADDR and whose length is LEN. */ | |
3a58abaf | 2769 | + |
7566401a ER |
2770 | +#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(addr, len) \ |
2771 | + i386_region_ok_for_watchpoint (addr, len) | |
3a58abaf | 2772 | + |
7566401a ER |
2773 | +/* After a watchpoint trap, the PC points to the instruction after the |
2774 | + one that caused the trap. Therefore we don't need to step over it. | |
2775 | + But we do need to reset the status register to avoid another trap. */ | |
3a58abaf | 2776 | + |
7566401a | 2777 | +#define HAVE_CONTINUABLE_WATCHPOINT 1 |
3a58abaf | 2778 | + |
7566401a | 2779 | +#define STOPPED_BY_WATCHPOINT(W) (i386_stopped_by_watchpoint () != 0) |
3a58abaf | 2780 | + |
7566401a ER |
2781 | +#define target_stopped_data_address(target, x) \ |
2782 | + i386_stopped_data_address(target, x) | |
3a58abaf | 2783 | + |
7566401a | 2784 | +/* Use these macros for watchpoint insertion/removal. */ |
3a58abaf | 2785 | + |
7566401a ER |
2786 | +#define target_insert_watchpoint(addr, len, type) \ |
2787 | + i386_insert_watchpoint (addr, len, type) | |
3a58abaf | 2788 | + |
7566401a ER |
2789 | +#define target_remove_watchpoint(addr, len, type) \ |
2790 | + i386_remove_watchpoint (addr, len, type) | |
3a58abaf | 2791 | + |
7566401a ER |
2792 | +#define target_insert_hw_breakpoint(bp_tgt) \ |
2793 | + i386_insert_hw_breakpoint (bp_tgt) | |
3a58abaf | 2794 | + |
7566401a ER |
2795 | +#define target_remove_hw_breakpoint(bp_tgt) \ |
2796 | + i386_remove_hw_breakpoint (bp_tgt) | |
3a58abaf | 2797 | + |
7566401a | 2798 | +#endif /* I386_WATCHPOINTS_IN_TARGET_VECTOR */ |
3a58abaf | 2799 | + |
7566401a | 2800 | +#endif /* I386_USE_GENERIC_WATCHPOINTS */ |
3a58abaf | 2801 | + |
7566401a ER |
2802 | +#endif /* NM_I386_H */ |
2803 | diff --git a/gdb/config/i386/nm-linux64.h b/gdb/config/i386/nm-linux64.h | |
2804 | new file mode 100644 | |
2805 | index 0000000..19d710a | |
2806 | --- /dev/null | |
2807 | +++ b/gdb/config/i386/nm-linux64.h | |
2808 | @@ -0,0 +1,54 @@ | |
2809 | +/* Native support for GNU/Linux x86-64. | |
3a58abaf | 2810 | + |
7566401a ER |
2811 | + Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 |
2812 | + Free Software Foundation, Inc. | |
3a58abaf | 2813 | + |
7566401a | 2814 | + Contributed by Jiri Smid, SuSE Labs. |
3a58abaf | 2815 | + |
7566401a | 2816 | + This file is part of GDB. |
3a58abaf | 2817 | + |
7566401a ER |
2818 | + This program is free software; you can redistribute it and/or modify |
2819 | + it under the terms of the GNU General Public License as published by | |
2820 | + the Free Software Foundation; either version 3 of the License, or | |
2821 | + (at your option) any later version. | |
3a58abaf | 2822 | + |
7566401a ER |
2823 | + This program is distributed in the hope that it will be useful, |
2824 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
2825 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
2826 | + GNU General Public License for more details. | |
3a58abaf | 2827 | + |
7566401a ER |
2828 | + You should have received a copy of the GNU General Public License |
2829 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
3a58abaf | 2830 | + |
7566401a ER |
2831 | +#ifndef NM_LINUX64_H |
2832 | +#define NM_LINUX64_H | |
3a58abaf | 2833 | + |
7566401a ER |
2834 | +/* GNU/Linux supports the i386 hardware debugging registers. */ |
2835 | +#define I386_USE_GENERIC_WATCHPOINTS | |
2836 | +#define I386_WATCHPOINTS_IN_TARGET_VECTOR | |
3a58abaf | 2837 | + |
7566401a ER |
2838 | +#include "i386/nm-i386.h" |
2839 | +#include "config/nm-linux.h" | |
3a58abaf | 2840 | + |
7566401a ER |
2841 | +/* Support for 8-byte wide hardware watchpoints. */ |
2842 | +#define TARGET_HAS_DR_LEN_8 1 | |
3a58abaf | 2843 | + |
7566401a | 2844 | +/* Provide access to the i386 hardware debugging registers. */ |
3a58abaf | 2845 | + |
7566401a ER |
2846 | +extern void amd64_linux_dr_set_control (unsigned long control); |
2847 | +#define I386_DR_LOW_SET_CONTROL(control) \ | |
2848 | + amd64_linux_dr_set_control (control) | |
3a58abaf | 2849 | + |
7566401a ER |
2850 | +extern void amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr); |
2851 | +#define I386_DR_LOW_SET_ADDR(regnum, addr) \ | |
2852 | + amd64_linux_dr_set_addr (regnum, addr) | |
3a58abaf | 2853 | + |
7566401a ER |
2854 | +extern void amd64_linux_dr_reset_addr (int regnum); |
2855 | +#define I386_DR_LOW_RESET_ADDR(regnum) \ | |
2856 | + amd64_linux_dr_reset_addr (regnum) | |
2857 | + | |
2858 | +extern unsigned long amd64_linux_dr_get_status (void); | |
2859 | +#define I386_DR_LOW_GET_STATUS() \ | |
2860 | + amd64_linux_dr_get_status () | |
2861 | + | |
2862 | +#endif /* nm-linux64.h */ | |
2863 | diff --git a/gdb/config/mips/nm-irix5.h b/gdb/config/mips/nm-irix5.h | |
2864 | new file mode 100644 | |
2865 | index 0000000..49ac420 | |
2866 | --- /dev/null | |
2867 | +++ b/gdb/config/mips/nm-irix5.h | |
2868 | @@ -0,0 +1,44 @@ | |
2869 | +/* Definitions for native support of irix5. | |
2870 | + | |
2871 | + Copyright 1993, 1996, 1998, 1999, 2000, 2007, 2008, 2009 | |
2872 | + Free Software Foundation, Inc. | |
2873 | + | |
2874 | + This file is part of GDB. | |
2875 | + | |
2876 | + This program is free software; you can redistribute it and/or modify | |
2877 | + it under the terms of the GNU General Public License as published by | |
2878 | + the Free Software Foundation; either version 3 of the License, or | |
2879 | + (at your option) any later version. | |
2880 | + | |
2881 | + This program is distributed in the hope that it will be useful, | |
2882 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
2883 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
2884 | + GNU General Public License for more details. | |
2885 | + | |
2886 | + You should have received a copy of the GNU General Public License | |
2887 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
2888 | + | |
2889 | +#define TARGET_HAS_HARDWARE_WATCHPOINTS | |
2890 | + | |
2891 | +/* TARGET_CAN_USE_HARDWARE_WATCHPOINT is now defined to go through | |
2892 | + the target vector. For Irix5, procfs_can_use_hw_watchpoint() | |
2893 | + should be invoked. */ | |
2894 | + | |
2895 | +/* When a hardware watchpoint fires off the PC will be left at the | |
2896 | + instruction which caused the watchpoint. It will be necessary for | |
2897 | + GDB to step over the watchpoint. */ | |
2898 | + | |
2899 | +#define STOPPED_BY_WATCHPOINT(W) \ | |
2900 | + procfs_stopped_by_watchpoint(inferior_ptid) | |
2901 | +extern int procfs_stopped_by_watchpoint (ptid_t); | |
2902 | + | |
2903 | +/* Use these macros for watchpoint insertion/deletion. */ | |
2904 | +/* type can be 0: write watch, 1: read watch, 2: access watch (read/write) */ | |
2905 | +#define target_insert_watchpoint(ADDR, LEN, TYPE) \ | |
2906 | + procfs_set_watchpoint (inferior_ptid, ADDR, LEN, TYPE, 0) | |
2907 | +#define target_remove_watchpoint(ADDR, LEN, TYPE) \ | |
2908 | + procfs_set_watchpoint (inferior_ptid, ADDR, 0, 0, 0) | |
2909 | +extern int procfs_set_watchpoint (ptid_t, CORE_ADDR, int, int, int); | |
2910 | + | |
2911 | +#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(SIZE) 1 | |
3a58abaf | 2912 | + |
3a58abaf | 2913 | diff --git a/gdb/configure b/gdb/configure |
ab050a48 | 2914 | index 46e7bfe..ea667f0 100755 |
3a58abaf AM |
2915 | --- a/gdb/configure |
2916 | +++ b/gdb/configure | |
7566401a ER |
2917 | @@ -676,6 +676,8 @@ REPORT_BUGS_TO |
2918 | PKGVERSION | |
2919 | TARGET_OBS | |
2920 | subdirs | |
2921 | +pythondir | |
2922 | +GDB_DATADIR_PATH | |
2923 | GDB_DATADIR | |
2924 | DEBUGDIR | |
2925 | am__fastdepCC_FALSE | |
2926 | @@ -883,6 +885,7 @@ enable_dependency_tracking | |
2927 | with_separate_debug_dir | |
2928 | with_gdb_datadir | |
2929 | with_relocated_sources | |
2930 | +with_pythondir | |
2931 | enable_targets | |
2932 | enable_64_bit_bfd | |
2933 | enable_gdbcli | |
2934 | @@ -1581,6 +1584,10 @@ Optional Packages: | |
2935 | [DATADIR/gdb] | |
2936 | --with-relocated-sources=PATH | |
2937 | automatically relocate this path for source files | |
3a58abaf AM |
2938 | + --with-gdb-datadir look for global separate data files in this path |
2939 | + [DATADIR/gdb] | |
2940 | + --with-pythondir install Python data files in this path | |
2941 | + [DATADIR/gdb/python] | |
7566401a ER |
2942 | --with-libunwind use libunwind frame unwinding support |
2943 | --with-curses use the curses library instead of the termcap | |
2944 | library | |
2945 | @@ -6602,6 +6609,73 @@ _ACEOF | |
2946 | fi | |
2947 | ||
3a58abaf AM |
2948 | |
2949 | +# GDB's datadir relocation | |
2950 | + | |
2951 | +gdbdatadir=${datadir}/gdb | |
2952 | + | |
2953 | + | |
7566401a ER |
2954 | +# Check whether --with-gdb-datadir was given. |
2955 | +if test "${with_gdb_datadir+set}" = set; then : | |
2956 | + withval=$with_gdb_datadir; gdbdatadir="${withval}" | |
2957 | +fi | |
2958 | + | |
3a58abaf AM |
2959 | + |
2960 | + | |
2961 | + test "x$prefix" = xNONE && prefix="$ac_default_prefix" | |
2962 | + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' | |
2963 | + ac_define_dir=`eval echo $gdbdatadir` | |
2964 | + ac_define_dir=`eval echo $ac_define_dir` | |
2965 | + | |
2966 | +cat >>confdefs.h <<_ACEOF | |
2967 | +#define GDB_DATADIR "$ac_define_dir" | |
2968 | +_ACEOF | |
2969 | + | |
2970 | + | |
2971 | + | |
2972 | +if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then | |
2973 | + if test "x$prefix" = xNONE; then | |
2974 | + test_prefix=/usr/local | |
2975 | + else | |
2976 | + test_prefix=$prefix | |
2977 | + fi | |
2978 | +else | |
2979 | + test_prefix=$exec_prefix | |
2980 | +fi | |
2981 | + | |
2982 | +case ${gdbdatadir} in | |
2983 | + "${test_prefix}"|"${test_prefix}/"*|\ | |
2984 | + '${exec_prefix}'|'${exec_prefix}/'*) | |
2985 | + | |
7566401a | 2986 | +$as_echo "#define GDB_DATADIR_RELOCATABLE 1" >>confdefs.h |
3a58abaf AM |
2987 | + |
2988 | + ;; | |
2989 | +esac | |
2990 | +GDB_DATADIR_PATH=${gdbdatadir} | |
2991 | + | |
2992 | + | |
2993 | + | |
7566401a ER |
2994 | +# Check whether --with-pythondir was given. |
2995 | +if test "${with_pythondir+set}" = set; then : | |
2996 | + withval=$with_pythondir; pythondir="${withval}" | |
3a58abaf AM |
2997 | +else |
2998 | + pythondir=no | |
7566401a ER |
2999 | +fi |
3000 | + | |
3a58abaf AM |
3001 | + |
3002 | +# If the user passed in a path, define it. Otherwise, compute it at | |
3003 | +# runtime based on the possibly-relocatable datadir. | |
3004 | +if test "$pythondir" = "no"; then | |
3005 | + pythondir='$(GDB_DATADIR_PATH)/python' | |
3006 | +else | |
3007 | + | |
3008 | +cat >>confdefs.h <<_ACEOF | |
3009 | +#define PYTHONDIR "$pythondir" | |
3010 | +_ACEOF | |
3011 | + | |
3012 | +fi | |
3013 | + | |
3014 | + | |
3015 | + | |
3016 | ||
3017 | ||
3018 | subdirs="$subdirs doc testsuite" | |
7566401a ER |
3019 | @@ -9282,6 +9356,8 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h |
3020 | CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_PYTHON_OBS)" | |
3021 | CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_PYTHON_DEPS)" | |
3022 | CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_PYTHON_SRCS)" | |
3023 | + CONFIG_INSTALL="$CONFIG_INSTALL install-python" | |
3024 | + CONFIG_UNINSTALL="$CONFIG_UNINSTALL uninstall-python" | |
3025 | ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_PYTHON_CFLAGS)" | |
3a58abaf | 3026 | |
7566401a ER |
3027 | # Flags needed to compile Python code (taken from python-config --cflags). |
3028 | diff --git a/gdb/configure.ac b/gdb/configure.ac | |
ab050a48 | 3029 | index 0e42182..e7f97cf 100644 |
7566401a ER |
3030 | --- a/gdb/configure.ac |
3031 | +++ b/gdb/configure.ac | |
3032 | @@ -107,6 +107,51 @@ AS_HELP_STRING([--with-relocated-sources=PATH], [automatically relocate this pat | |
3033 | [Relocated directory for source files. ]) | |
3034 | ]) | |
3a58abaf | 3035 | |
7566401a | 3036 | +# GDB's datadir relocation |
3a58abaf | 3037 | + |
7566401a | 3038 | +gdbdatadir=${datadir}/gdb |
3a58abaf | 3039 | + |
7566401a ER |
3040 | +AC_ARG_WITH([gdb-datadir], |
3041 | + [AS_HELP_STRING([--with-gdb-datadir], | |
3042 | + [look for global separate data files in this path [DATADIR/gdb]])], [gdbdatadir="${withval}"]) | |
3a58abaf | 3043 | + |
7566401a ER |
3044 | +AC_DEFINE_DIR(GDB_DATADIR, gdbdatadir, |
3045 | + [Global directory for GDB data files. ]) | |
3a58abaf | 3046 | + |
7566401a ER |
3047 | +if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then |
3048 | + if test "x$prefix" = xNONE; then | |
3049 | + test_prefix=/usr/local | |
3050 | + else | |
3051 | + test_prefix=$prefix | |
3052 | + fi | |
3a58abaf | 3053 | +else |
7566401a | 3054 | + test_prefix=$exec_prefix |
3a58abaf | 3055 | +fi |
3a58abaf | 3056 | + |
7566401a ER |
3057 | +case ${gdbdatadir} in |
3058 | + "${test_prefix}"|"${test_prefix}/"*|\ | |
3059 | + '${exec_prefix}'|'${exec_prefix}/'*) | |
3060 | + AC_DEFINE(GDB_DATADIR_RELOCATABLE, 1, [Define if GDB datadir should be relocated when GDB is moved.]) | |
3061 | + ;; | |
3062 | +esac | |
3063 | +GDB_DATADIR_PATH=${gdbdatadir} | |
3064 | +AC_SUBST(GDB_DATADIR_PATH) | |
3a58abaf | 3065 | + |
7566401a ER |
3066 | +AC_ARG_WITH([pythondir], |
3067 | + [AS_HELP_STRING([--with-pythondir], | |
3068 | + [install Python data files in this path [DATADIR/gdb/python]])], [pythondir="${withval}"], [pythondir=no]) | |
3a58abaf | 3069 | + |
7566401a ER |
3070 | +# If the user passed in a path, define it. Otherwise, compute it at |
3071 | +# runtime based on the possibly-relocatable datadir. | |
3072 | +if test "$pythondir" = "no"; then | |
3073 | + pythondir='$(GDB_DATADIR_PATH)/python' | |
3a58abaf | 3074 | +else |
7566401a ER |
3075 | + AC_DEFINE_UNQUOTED(PYTHONDIR, "$pythondir", |
3076 | + [Define to install path for Python sources]) | |
3a58abaf | 3077 | +fi |
7566401a | 3078 | +AC_SUBST(pythondir) |
3a58abaf AM |
3079 | + |
3080 | + | |
7566401a ER |
3081 | AC_CONFIG_SUBDIRS(doc testsuite) |
3082 | ||
3083 | # Check whether to support alternative target configurations | |
3084 | @@ -658,6 +703,8 @@ if test "${have_libpython}" = yes; then | |
3a58abaf AM |
3085 | CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_PYTHON_OBS)" |
3086 | CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_PYTHON_DEPS)" | |
3087 | CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_PYTHON_SRCS)" | |
3088 | + CONFIG_INSTALL="$CONFIG_INSTALL install-python" | |
3089 | + CONFIG_UNINSTALL="$CONFIG_UNINSTALL uninstall-python" | |
3090 | ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_PYTHON_CFLAGS)" | |
3091 | ||
3092 | # Flags needed to compile Python code (taken from python-config --cflags). | |
7566401a ER |
3093 | diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y |
3094 | index 62800b8..97d587b 100644 | |
3095 | --- a/gdb/cp-name-parser.y | |
3096 | +++ b/gdb/cp-name-parser.y | |
3097 | @@ -1,7 +1,6 @@ | |
3098 | /* YACC parser for C++ names, for GDB. | |
3a58abaf | 3099 | |
7566401a ER |
3100 | - Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 |
3101 | - Free Software Foundation, Inc. | |
3102 | + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. | |
3a58abaf | 3103 | |
7566401a | 3104 | Parts of the lexer are based on c-exp.y from GDB. |
3a58abaf | 3105 | |
7566401a ER |
3106 | @@ -389,7 +388,7 @@ function |
3107 | | colon_ext_only function_arglist start_opt | |
3108 | { $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp); | |
3109 | if ($3) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); } | |
3110 | - | |
3111 | + | colon_ext_only | |
3112 | | conversion_op_name start_opt | |
3113 | { $$ = $1.comp; | |
3114 | if ($2) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $2); } | |
3115 | diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c | |
ab050a48 | 3116 | index d2d8f2e..db26a01 100644 |
7566401a ER |
3117 | --- a/gdb/cp-namespace.c |
3118 | +++ b/gdb/cp-namespace.c | |
3119 | @@ -36,14 +36,17 @@ static struct using_direct *cp_copy_usings (struct using_direct *using, | |
3120 | struct obstack *obstack); | |
3a58abaf | 3121 | |
7566401a ER |
3122 | static struct symbol *lookup_namespace_scope (const char *name, |
3123 | - const char *linkage_name, | |
3124 | const struct block *block, | |
3125 | const domain_enum domain, | |
3126 | const char *scope, | |
3127 | int scope_len); | |
3a58abaf | 3128 | |
7566401a ER |
3129 | +static struct symbol *cp_lookup_symbol_in_namespace (const char *namespace, |
3130 | + const char *name, | |
3131 | + const struct block *block, | |
3132 | + const domain_enum domain); | |
3a58abaf | 3133 | + |
3a58abaf | 3134 | static struct symbol *lookup_symbol_file (const char *name, |
7566401a | 3135 | - const char *linkage_name, |
3a58abaf | 3136 | const struct block *block, |
7566401a ER |
3137 | const domain_enum domain, |
3138 | int anonymous_namespace); | |
3139 | @@ -119,7 +122,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol) | |
3a58abaf AM |
3140 | anonymous namespace. So add symbols in it to the |
3141 | namespace given by the previous component if there is | |
3142 | one, or to the global namespace if there isn't. */ | |
7566401a ER |
3143 | - cp_add_using_directive (dest, src); |
3144 | + cp_add_using_directive (dest, src, "", "", 0); | |
3a58abaf AM |
3145 | } |
3146 | /* The "+ 2" is for the "::". */ | |
3147 | previous_component = next_component + 2; | |
7566401a ER |
3148 | @@ -134,7 +137,8 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol) |
3149 | has already been added, don't add it twice. */ | |
3a58abaf AM |
3150 | |
3151 | void | |
7566401a ER |
3152 | -cp_add_using_directive (const char *dest, const char *src) |
3153 | +cp_add_using_directive (const char *dest, const char *src, const char* alias, | |
3154 | + const char *declaration, const int line_number) | |
3a58abaf AM |
3155 | { |
3156 | struct using_direct *current; | |
3157 | struct using_direct *new; | |
7566401a | 3158 | @@ -148,7 +152,8 @@ cp_add_using_directive (const char *dest, const char *src) |
3a58abaf AM |
3159 | return; |
3160 | } | |
3161 | ||
7566401a ER |
3162 | - using_directives = cp_add_using (dest, src, using_directives); |
3163 | + using_directives = cp_add_using (dest, src, alias, declaration, | |
3164 | + line_number, using_directives); | |
3165 | ||
3a58abaf AM |
3166 | } |
3167 | ||
7566401a | 3168 | @@ -201,7 +206,10 @@ cp_is_anonymous (const char *namespace) |
3a58abaf AM |
3169 | } |
3170 | ||
7566401a ER |
3171 | /* Create a new struct using direct which imports the namespace SRC |
3172 | - into the scope DEST. | |
3173 | + into the scope DEST. ALIAS is the name of the imported namespace | |
3174 | + in the current scope. If ALIAS is an empty string then the | |
3a58abaf | 3175 | + namespace is known by its original name. |
7566401a | 3176 | + |
3a58abaf AM |
3177 | Set its next member in the linked list to NEXT; allocate all memory |
3178 | using xmalloc. It copies the strings, so NAME can be a temporary | |
3179 | string. */ | |
7566401a ER |
3180 | @@ -209,14 +217,21 @@ cp_is_anonymous (const char *namespace) |
3181 | struct using_direct * | |
3182 | cp_add_using (const char *dest, | |
3183 | const char *src, | |
3a58abaf AM |
3184 | + const char *alias, |
3185 | + const char *declaration, | |
3186 | + const int line_number, | |
3187 | struct using_direct *next) | |
3188 | { | |
3189 | struct using_direct *retval; | |
3190 | ||
3a58abaf | 3191 | retval = xmalloc (sizeof (struct using_direct)); |
7566401a ER |
3192 | - retval->import_src = savestring (src, strlen(src)); |
3193 | - retval->import_dest = savestring (dest, strlen(dest)); | |
3194 | + retval->import_src = savestring (src, strlen (src)); | |
3195 | + retval->import_dest = savestring (dest, strlen (dest)); | |
3196 | + retval->alias = savestring (alias, strlen (alias)); | |
3197 | + retval->declaration = savestring (declaration, strlen (declaration)); | |
3a58abaf | 3198 | + retval->line_number = line_number; |
3a58abaf | 3199 | retval->next = next; |
7566401a | 3200 | + retval->searched = 0; |
3a58abaf AM |
3201 | |
3202 | return retval; | |
7566401a ER |
3203 | } |
3204 | @@ -241,10 +256,18 @@ cp_copy_usings (struct using_direct *using, | |
3205 | obstack); | |
3206 | retval->import_dest = obsavestring (using->import_dest, strlen (using->import_dest), | |
3a58abaf | 3207 | obstack); |
3a58abaf AM |
3208 | + retval->alias = obsavestring (using->alias, strlen (using->alias), |
3209 | + obstack); | |
3210 | + retval->declaration = obsavestring (using->declaration, strlen (using->declaration), | |
3211 | + obstack); | |
3212 | retval->next = cp_copy_usings (using->next, obstack); | |
3213 | ||
7566401a ER |
3214 | + retval->searched = using->searched; |
3215 | + | |
3216 | xfree (using->import_src); | |
3217 | xfree (using->import_dest); | |
d566d21e | 3218 | + xfree (using->alias); |
3219 | + xfree (using->declaration); | |
3220 | xfree (using); | |
3221 | ||
3222 | return retval; | |
7566401a ER |
3223 | @@ -261,12 +284,48 @@ cp_copy_usings (struct using_direct *using, |
3224 | ||
3225 | struct symbol * | |
3226 | cp_lookup_symbol_nonlocal (const char *name, | |
3227 | - const char *linkage_name, | |
3a58abaf AM |
3228 | const struct block *block, |
3229 | const domain_enum domain) | |
3230 | { | |
3231 | - return lookup_namespace_scope (name, linkage_name, block, domain, | |
3232 | - block_scope (block), 0); | |
7566401a ER |
3233 | + struct symbol *sym; |
3234 | + const char *scope = block_scope (block); | |
3a58abaf | 3235 | + |
7566401a | 3236 | + sym = lookup_namespace_scope (name, block, domain, scope, 0); |
3a58abaf AM |
3237 | + if (sym != NULL) |
3238 | + return sym; | |
3239 | + | |
7566401a ER |
3240 | + return cp_lookup_symbol_namespace(scope, name, block, domain); |
3241 | +} | |
3242 | + | |
3243 | +/* Searches for NAME in the current namespace, and by applying relevant import | |
3244 | + statements belonging to BLOCK and its parents. SCOPE is the namespace | |
3245 | + scope of the context in which the search is being evaluated. */ | |
3246 | + | |
3247 | +struct symbol* | |
3248 | +cp_lookup_symbol_namespace (const char *scope, | |
3249 | + const char *name, | |
3250 | + const struct block *block, | |
3251 | + const domain_enum domain) | |
3252 | +{ | |
3253 | + struct symbol *sym; | |
3254 | + | |
3255 | + /* First, try to find the symbol in the given namespace. */ | |
3256 | + sym = cp_lookup_symbol_in_namespace (scope, name, block, domain); | |
3257 | + if ( sym != NULL) | |
3258 | + return sym; | |
3259 | + | |
3260 | + /* Search for name in namespaces imported to this and parent blocks. */ | |
3261 | + while (block != NULL) | |
3262 | + { | |
3263 | + sym = cp_lookup_symbol_imports(scope,name, block, domain,0,1); | |
3264 | + | |
3265 | + if (sym) | |
3266 | + return sym; | |
3267 | + | |
3268 | + block = BLOCK_SUPERBLOCK(block); | |
3269 | + } | |
3270 | + | |
3271 | + return NULL; | |
3a58abaf AM |
3272 | } |
3273 | ||
3274 | /* Lookup NAME at namespace scope (or, in C terms, in static and | |
7566401a | 3275 | @@ -284,9 +343,8 @@ cp_lookup_symbol_nonlocal (const char *name, |
3a58abaf AM |
3276 | "A::x", and if that call fails, then the first call looks for |
3277 | "x". */ | |
3278 | ||
3279 | -static struct symbol * | |
3280 | +struct symbol * | |
3281 | lookup_namespace_scope (const char *name, | |
7566401a | 3282 | - const char *linkage_name, |
3a58abaf | 3283 | const struct block *block, |
7566401a ER |
3284 | const domain_enum domain, |
3285 | const char *scope, | |
3286 | @@ -308,8 +366,7 @@ lookup_namespace_scope (const char *name, | |
3287 | new_scope_len += 2; | |
3288 | } | |
3289 | new_scope_len += cp_find_first_component (scope + new_scope_len); | |
3290 | - sym = lookup_namespace_scope (name, linkage_name, block, | |
3291 | - domain, scope, new_scope_len); | |
3292 | + sym = lookup_namespace_scope (name, block, domain, scope, new_scope_len); | |
3293 | if (sym != NULL) | |
3294 | return sym; | |
3295 | } | |
ab050a48 | 3296 | @@ -320,25 +377,98 @@ lookup_namespace_scope (const char *name, |
3a58abaf AM |
3297 | namespace = alloca (scope_len + 1); |
3298 | strncpy (namespace, scope, scope_len); | |
3299 | namespace[scope_len] = '\0'; | |
3300 | - return cp_lookup_symbol_namespace (namespace, name, linkage_name, | |
7566401a ER |
3301 | - block, domain); |
3302 | + return cp_lookup_symbol_in_namespace (namespace, name,block, domain); | |
3a58abaf AM |
3303 | } |
3304 | ||
7566401a ER |
3305 | -/* Look up NAME in the C++ namespace NAMESPACE, applying the using |
3306 | - directives that are active in BLOCK. Other arguments are as in | |
3307 | +/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in | |
3308 | cp_lookup_symbol_nonlocal. */ | |
3309 | ||
3310 | +static struct symbol * | |
3311 | +cp_lookup_symbol_in_namespace (const char *namespace, | |
3312 | + const char *name, | |
3313 | + const struct block *block, | |
3314 | + const domain_enum domain) | |
3a58abaf | 3315 | +{ |
3a58abaf | 3316 | + |
7566401a | 3317 | + if (namespace[0] == '\0') |
3a58abaf | 3318 | + { |
7566401a | 3319 | + return lookup_symbol_file (name, block,domain, 0); |
3a58abaf | 3320 | + } |
7566401a ER |
3321 | + else |
3322 | + { | |
3323 | + char *concatenated_name | |
3324 | + = alloca (strlen (namespace) + 2 + strlen (name) + 1); | |
3325 | + strcpy (concatenated_name, namespace); | |
3326 | + strcat (concatenated_name, "::"); | |
3327 | + strcat (concatenated_name, name); | |
3328 | + return lookup_symbol_file (concatenated_name, block, domain, | |
3329 | + cp_is_anonymous (namespace)); | |
3330 | + } | |
3331 | +} | |
3a58abaf | 3332 | + |
ab050a48 BZ |
3333 | +/* Used for cleanups to reset the "searched" flag incase |
3334 | + of an error. */ | |
3335 | + | |
3336 | +static void | |
3337 | +reset_directive_searched (void *data) | |
3338 | +{ | |
3339 | + struct using_direct *direct = data; | |
3340 | + direct->searched = 0; | |
3341 | +} | |
3342 | + | |
7566401a ER |
3343 | +/* Search for NAME by applying all import statements belonging |
3344 | + to BLOCK which are applicable in SCOPE. If DECLARATION_ONLY the search | |
3345 | + is restricted to using declarations. | |
3346 | + Example: | |
3a58abaf | 3347 | + |
7566401a ER |
3348 | + namespace A{ |
3349 | + int x; | |
3350 | + } | |
3351 | + using A::x; | |
3a58abaf | 3352 | + |
7566401a ER |
3353 | + If SEARCH_PARENTS the search will include imports which are applicable in |
3354 | + parents of scopes. | |
3355 | + Example: | |
3a58abaf | 3356 | + |
7566401a ER |
3357 | + namespace A{ |
3358 | + using namespace X; | |
3359 | + namespace B{ | |
3360 | + using namespace Y; | |
3361 | + } | |
3362 | + } | |
3363 | + | |
3364 | + If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X | |
3365 | + and Y will be considered. If SEARCH_PARENTS is false only the import of Y | |
3366 | + is considered. */ | |
3367 | + | |
3368 | struct symbol * | |
3369 | -cp_lookup_symbol_namespace (const char *namespace, | |
3370 | - const char *name, | |
3371 | - const char *linkage_name, | |
3372 | - const struct block *block, | |
3373 | - const domain_enum domain) | |
3374 | +cp_lookup_symbol_imports (const char *scope, | |
ab050a48 BZ |
3375 | + const char *name, |
3376 | + const struct block *block, | |
3377 | + const domain_enum domain, | |
3378 | + int declaration_only, | |
3379 | + int search_parents) | |
3a58abaf | 3380 | { |
7566401a | 3381 | - const struct using_direct *current; |
3a58abaf | 3382 | - struct symbol *sym; |
7566401a | 3383 | + struct using_direct *current; |
3a58abaf | 3384 | + struct symbol *sym = NULL; |
7566401a ER |
3385 | + int directive_match; |
3386 | + int current_line; | |
ab050a48 | 3387 | + struct cleanup *searched_cleanup; |
7566401a ER |
3388 | + |
3389 | + if(!declaration_only) | |
3390 | + /* First, try to find the symbol in the given namespace. */ | |
3391 | + sym = cp_lookup_symbol_in_namespace (scope, name, block, domain); | |
3a58abaf | 3392 | |
7566401a ER |
3393 | - /* First, go through the using directives. If any of them add new |
3394 | + if ( sym != NULL) | |
3395 | + return sym; | |
3396 | + | |
3397 | + if (has_stack_frames ()) | |
3398 | + current_line = find_pc_line (get_frame_pc (get_selected_frame (NULL)), | |
3399 | + 0).line; | |
3400 | + else | |
3401 | + current_line = 0; | |
3402 | + | |
3403 | + /* Go through the using directives. If any of them add new | |
3a58abaf | 3404 | names to the namespace we're searching in, see if we can find a |
7566401a ER |
3405 | match by applying them. */ |
3406 | ||
ab050a48 | 3407 | @@ -346,39 +476,78 @@ cp_lookup_symbol_namespace (const char *namespace, |
3a58abaf AM |
3408 | current != NULL; |
3409 | current = current->next) | |
3410 | { | |
7566401a ER |
3411 | - if (strcmp (namespace, current->import_dest) == 0) |
3412 | + | |
3413 | + /* If the import destination is the current scope or one of its ancestors then | |
3414 | + it is applicable. */ | |
3415 | + directive_match = search_parents ? | |
3416 | + strncmp (scope, current->import_dest, | |
3417 | + strlen(current->import_dest)) == 0 : | |
3418 | + strcmp (scope, current->import_dest) == 0; | |
3419 | + | |
3420 | + if (directive_match && | |
3421 | + current->line_number < current_line && | |
3422 | + !current->searched) | |
3a58abaf | 3423 | { |
7566401a | 3424 | - sym = cp_lookup_symbol_namespace (current->import_src, |
3a58abaf AM |
3425 | - name, |
3426 | - linkage_name, | |
3427 | - block, | |
3428 | - domain); | |
7566401a | 3429 | + current->searched = 1; |
ab050a48 BZ |
3430 | + searched_cleanup = make_cleanup (reset_directive_searched, current); |
3431 | + | |
d566d21e | 3432 | + /* If there is an import of a single declaration, compare the imported |
3433 | + declaration with the sought out name. If there is a match pass | |
7566401a | 3434 | + current->import_src as NAMESPACE to direct the search towards the |
d566d21e | 3435 | + imported namespace. */ |
3436 | + if (strcmp ("", current->declaration) != 0) | |
3437 | + { | |
7566401a ER |
3438 | + if (strcmp (name, current->declaration) == 0) |
3439 | + { | |
ab050a48 BZ |
3440 | + sym = cp_lookup_symbol_in_namespace (current->import_src, |
3441 | + name, | |
3442 | + block, | |
3443 | + domain); | |
7566401a | 3444 | + } |
ab050a48 BZ |
3445 | + |
3446 | + current->searched = 0; | |
3447 | + if (sym) | |
3448 | + return sym; | |
3449 | + | |
3450 | + continue; | |
3a58abaf AM |
3451 | + } |
3452 | + | |
7566401a | 3453 | + if (declaration_only) |
ab050a48 BZ |
3454 | + { |
3455 | + current->searched = 0; | |
3456 | + discard_cleanups (searched_cleanup); | |
3457 | + continue; | |
3458 | + } | |
7566401a ER |
3459 | + |
3460 | + if (strcmp (name, current->alias) == 0) | |
d566d21e | 3461 | + /* If the import is creating an alias and the alias matches the |
3462 | + sought name. Pass current->inner as the NAME to direct the | |
3463 | + search towards the aliased namespace */ | |
3464 | + { | |
7566401a | 3465 | + sym = cp_lookup_symbol_in_namespace (scope, |
ab050a48 BZ |
3466 | + current->import_src, |
3467 | + block, | |
3468 | + domain); | |
7566401a | 3469 | + } else if (strcmp ("", current->alias) == 0){ |
d566d21e | 3470 | + /* If this import statement creates no alias, pass current->inner as |
3471 | + NAMESPACE to direct the search towards the imported namespace. */ | |
7566401a | 3472 | + sym = cp_lookup_symbol_imports (current->import_src, |
ab050a48 BZ |
3473 | + name, |
3474 | + block, | |
3475 | + domain, | |
3476 | + 0, | |
3477 | + 0); | |
3a58abaf | 3478 | + } |
d566d21e | 3479 | + |
7566401a | 3480 | + current->searched = 0; |
ab050a48 BZ |
3481 | + discard_cleanups (searched_cleanup); |
3482 | + | |
7566401a | 3483 | if (sym != NULL) |
ab050a48 | 3484 | return sym; |
3a58abaf AM |
3485 | } |
3486 | } | |
3487 | ||
7566401a ER |
3488 | - /* We didn't find anything by applying any of the using directives |
3489 | - that are still applicable; so let's see if we've got a match | |
3490 | - using the current namespace. */ | |
3491 | - | |
3492 | - if (namespace[0] == '\0') | |
3493 | - { | |
3a58abaf AM |
3494 | - return lookup_symbol_file (name, linkage_name, block, |
3495 | - domain, 0); | |
7566401a ER |
3496 | - } |
3497 | - else | |
3498 | - { | |
3499 | - char *concatenated_name | |
3500 | - = alloca (strlen (namespace) + 2 + strlen (name) + 1); | |
3501 | - strcpy (concatenated_name, namespace); | |
3502 | - strcat (concatenated_name, "::"); | |
3503 | - strcat (concatenated_name, name); | |
3504 | - sym = lookup_symbol_file (concatenated_name, linkage_name, | |
3505 | - block, domain, | |
3506 | - cp_is_anonymous (namespace)); | |
3507 | - return sym; | |
3508 | - } | |
3509 | + return NULL; | |
3510 | } | |
3511 | ||
3512 | /* Look up NAME in BLOCK's static block and in global blocks. If | |
ab050a48 | 3513 | @@ -388,17 +557,15 @@ cp_lookup_symbol_namespace (const char *namespace, |
7566401a ER |
3514 | |
3515 | static struct symbol * | |
3516 | lookup_symbol_file (const char *name, | |
3517 | - const char *linkage_name, | |
3518 | const struct block *block, | |
3519 | const domain_enum domain, | |
3520 | int anonymous_namespace) | |
3521 | { | |
3522 | struct symbol *sym = NULL; | |
3523 | ||
3524 | - sym = lookup_symbol_static (name, linkage_name, block, domain); | |
3525 | + sym = lookup_symbol_static (name, block, domain); | |
3526 | if (sym != NULL) | |
3527 | return sym; | |
3528 | - | |
3529 | if (anonymous_namespace) | |
3530 | { | |
3531 | /* Symbols defined in anonymous namespaces have external linkage | |
ab050a48 | 3532 | @@ -408,12 +575,11 @@ lookup_symbol_file (const char *name, |
7566401a ER |
3533 | const struct block *global_block = block_global_block (block); |
3534 | ||
3535 | if (global_block != NULL) | |
3536 | - sym = lookup_symbol_aux_block (name, linkage_name, global_block, | |
3537 | - domain); | |
3538 | + sym = lookup_symbol_aux_block (name, global_block, domain); | |
3539 | } | |
3540 | else | |
3541 | { | |
3542 | - sym = lookup_symbol_global (name, linkage_name, block, domain); | |
3543 | + sym = lookup_symbol_global (name, block, domain); | |
3544 | } | |
3545 | ||
3546 | if (sym != NULL) | |
ab050a48 | 3547 | @@ -434,6 +600,7 @@ lookup_symbol_file (const char *name, |
7566401a ER |
3548 | sym = lookup_possible_namespace_symbol (name); |
3549 | if (sym != NULL) | |
3550 | return sym; | |
3551 | + | |
3552 | } | |
3553 | ||
3554 | return NULL; | |
ab050a48 | 3555 | @@ -461,9 +628,8 @@ cp_lookup_nested_type (struct type *parent_type, |
7566401a ER |
3556 | lookup_symbol_namespace works when looking them up. */ |
3557 | ||
3558 | const char *parent_name = TYPE_TAG_NAME (parent_type); | |
3559 | - struct symbol *sym = cp_lookup_symbol_namespace (parent_name, | |
3560 | + struct symbol *sym = cp_lookup_symbol_in_namespace (parent_name, | |
3561 | nested_name, | |
3562 | - NULL, | |
3563 | block, | |
3564 | VAR_DOMAIN); | |
3565 | if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF) | |
ab050a48 | 3566 | @@ -709,7 +875,7 @@ check_one_possible_namespace_symbol (const char *name, int len, |
7566401a ER |
3567 | |
3568 | memcpy (name_copy, name, len); | |
3569 | name_copy[len] = '\0'; | |
3570 | - sym = lookup_block_symbol (block, name_copy, NULL, VAR_DOMAIN); | |
3571 | + sym = lookup_block_symbol (block, name_copy, VAR_DOMAIN); | |
3572 | ||
3573 | if (sym == NULL) | |
3574 | { | |
ab050a48 | 3575 | @@ -749,7 +915,7 @@ lookup_possible_namespace_symbol (const char *name) |
7566401a ER |
3576 | struct symbol *sym; |
3577 | ||
3578 | sym = lookup_block_symbol (get_possible_namespace_block (objfile), | |
3579 | - name, NULL, VAR_DOMAIN); | |
3580 | + name, VAR_DOMAIN); | |
3581 | ||
3582 | if (sym != NULL) | |
3583 | return sym; | |
3584 | diff --git a/gdb/cp-support.c b/gdb/cp-support.c | |
3585 | index f12d785..23b34c1 100644 | |
3586 | --- a/gdb/cp-support.c | |
3587 | +++ b/gdb/cp-support.c | |
3588 | @@ -32,6 +32,9 @@ | |
3589 | #include "block.h" | |
3590 | #include "complaints.h" | |
3591 | #include "gdbtypes.h" | |
3592 | +#include "exceptions.h" | |
3593 | +#include "expression.h" | |
3594 | +#include "value.h" | |
3595 | ||
3596 | #include "safe-ctype.h" | |
3597 | ||
3598 | @@ -70,6 +73,18 @@ struct cmd_list_element *maint_cplus_cmd_list = NULL; | |
3599 | static void maint_cplus_command (char *arg, int from_tty); | |
3600 | static void first_component_command (char *arg, int from_tty); | |
3601 | ||
3602 | +/* Operator validation. | |
3603 | + NOTE: Multi-byte operators (usually the assignment variety operator) | |
3604 | + must appear before the single byte version, i.e., "+=" before "+". */ | |
3605 | +static const char *operator_tokens[] = | |
3606 | + { | |
3607 | + "++", "+=", "+", "->*", "->", "--", "-=", "-", "*=", "*", "/=", "/", | |
3608 | + "%=", "%", "!=", "==", "!", "&&", "<<=", "<<", ">>=", ">>", | |
3609 | + "<=", "<", ">=", ">", "~", "&=", "&", "|=", "||", "|", "^=", "^", | |
3610 | + "=", "()", "[]", ",", "new", "delete" | |
3611 | + /* new[] and delete[] require special whitespace handling */ | |
3612 | + }; | |
3613 | + | |
3614 | /* Return 1 if STRING is clearly already in canonical form. This | |
3615 | function is conservative; things which it does not recognize are | |
3616 | assumed to be non-canonical, and the parser will sort them out | |
3617 | @@ -175,7 +190,8 @@ mangled_name_to_comp (const char *mangled_name, int options, | |
3618 | return ret; | |
3619 | } | |
3620 | ||
3a58abaf AM |
3621 | -/* Return the name of the class containing method PHYSNAME. */ |
3622 | +/* Return the name of the class or namespace containing | |
3623 | + function, method, or variable PHYSNAME. */ | |
3624 | ||
3625 | char * | |
3626 | cp_class_name_from_physname (const char *physname) | |
7566401a ER |
3627 | @@ -825,9 +841,9 @@ read_in_psymtabs (const char *func_name) |
3628 | if (ps->readin) | |
3629 | continue; | |
3630 | ||
3631 | - if ((lookup_partial_symbol (ps, func_name, NULL, 1, VAR_DOMAIN) | |
3632 | + if ((lookup_partial_symbol (ps, func_name, 1, VAR_DOMAIN) | |
3633 | != NULL) | |
3634 | - || (lookup_partial_symbol (ps, func_name, NULL, 0, VAR_DOMAIN) | |
3635 | + || (lookup_partial_symbol (ps, func_name, 0, VAR_DOMAIN) | |
3636 | != NULL)) | |
3637 | psymtab_to_symtab (ps); | |
3638 | } | |
3639 | @@ -909,6 +925,107 @@ first_component_command (char *arg, int from_tty) | |
3640 | ||
3641 | extern initialize_file_ftype _initialize_cp_support; /* -Wmissing-prototypes */ | |
3642 | ||
3643 | +#define SKIP_SPACE(P) \ | |
3644 | + do \ | |
3645 | + { \ | |
3646 | + while (*(P) == ' ' || *(P) == '\t') \ | |
3647 | + ++(P); \ | |
3648 | + } \ | |
3649 | + while (0) | |
3650 | + | |
3651 | +/* Returns the length of the operator name or 0 if INPUT does not | |
3652 | + point to a valid C++ operator. INPUT should start with "operator". */ | |
3653 | +int | |
3654 | +cp_validate_operator (const char *input) | |
3655 | +{ | |
3656 | + int i; | |
3657 | + char *copy; | |
3658 | + const char *p; | |
3659 | + struct expression *expr; | |
3660 | + struct value *val; | |
3661 | + struct gdb_exception except; | |
3662 | + struct cleanup *old_chain; | |
3663 | + | |
3664 | + p = input; | |
3665 | + | |
3666 | + if (strncmp (p, "operator", 8) == 0) | |
3667 | + { | |
3668 | + int valid = 0; | |
3669 | + p += 8; | |
3670 | + | |
3671 | + SKIP_SPACE (p); | |
3672 | + for (i = 0; i < sizeof (operator_tokens) / sizeof (operator_tokens[0]); | |
3673 | + ++i) | |
3674 | + { | |
3675 | + int length = strlen (operator_tokens[i]); | |
3676 | + /* By using strncmp here, we MUST have operator_tokens ordered! | |
3677 | + See additional notes where operator_tokens is defined above. */ | |
3678 | + if (strncmp (p, operator_tokens[i], length) == 0) | |
3679 | + { | |
3680 | + const char *op = p; | |
3681 | + valid = 1; | |
3682 | + p += length; | |
3683 | + | |
3684 | + if (strncmp (op, "new", 3) == 0 | |
3685 | + || strncmp (op, "delete", 6) == 0) | |
3686 | + { | |
3687 | + | |
3688 | + /* Special case: new[] and delete[]. We must be careful | |
3689 | + to swallow whitespace before/in "[]". */ | |
3690 | + SKIP_SPACE (p); | |
3691 | + | |
3692 | + if (*p == '[') | |
3693 | + { | |
3694 | + ++p; | |
3695 | + SKIP_SPACE (p); | |
3696 | + if (*p == ']') | |
3697 | + ++p; | |
3698 | + else | |
3699 | + valid = 0; | |
3700 | + } | |
3701 | + } | |
3702 | + | |
3703 | + if (valid) | |
3704 | + return (p - input); | |
3705 | + } | |
3706 | + } | |
3707 | + | |
3708 | + /* Check input for a conversion operator. */ | |
3709 | + | |
3710 | + /* Skip past base typename */ | |
3711 | + while (*p != '*' && *p != '&' && *p != 0 && *p != ' ') | |
3712 | + ++p; | |
3713 | + SKIP_SPACE (p); | |
3714 | + | |
3715 | + /* Add modifiers '*'/'&' */ | |
3716 | + while (*p == '*' || *p == '&') | |
3717 | + { | |
3718 | + ++p; | |
3719 | + SKIP_SPACE (p); | |
3720 | + } | |
3721 | + | |
3722 | + /* Check for valid type. [Remember: input starts with | |
3723 | + "operator".] */ | |
3724 | + copy = savestring (input + 8, p - input - 8); | |
3725 | + expr = NULL; | |
3726 | + val = NULL; | |
3727 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
3728 | + { | |
3729 | + expr = parse_expression (copy); | |
3730 | + val = evaluate_type (expr); | |
3731 | + } | |
3732 | + | |
3733 | + xfree (copy); | |
3734 | + if (expr) | |
3735 | + xfree (expr); | |
3736 | + | |
3737 | + if (val != NULL && value_type (val) != NULL) | |
3738 | + return (p - input); | |
3739 | + } | |
3740 | + | |
3741 | + return 0; | |
3742 | +} | |
3743 | + | |
3744 | void | |
3745 | _initialize_cp_support (void) | |
3746 | { | |
3a58abaf | 3747 | diff --git a/gdb/cp-support.h b/gdb/cp-support.h |
7566401a | 3748 | index b5a5c5f..3f48f98 100644 |
3a58abaf AM |
3749 | --- a/gdb/cp-support.h |
3750 | +++ b/gdb/cp-support.h | |
7566401a | 3751 | @@ -38,15 +38,33 @@ struct demangle_component; |
3a58abaf AM |
3752 | |
3753 | /* This struct is designed to store data from using directives. It | |
7566401a ER |
3754 | says that names from namespace IMPORT_SRC should be visible within |
3755 | - namespace IMPORT_DEST. IMPORT_DEST should always be a strict initial | |
3756 | - substring of IMPORT_SRC. These form a linked list; NEXT is the next element | |
3757 | - of the list. */ | |
3758 | + namespace IMPORT_DEST. IMPORT_DEST should always be a strict initial | |
3759 | + substring of IMPORT_SRC. These form a linked list; NEXT is the next | |
3760 | + element of the list. ALIAS is set to a non empty string if the imported | |
3761 | + namespace has been aliased.Eg: | |
3a58abaf AM |
3762 | + namespace C=A::B; |
3763 | + ALIAS = "C" | |
3764 | + DECLARATION is the name of the imported declaration, if this import | |
3765 | + statement represents one. Eg: | |
3766 | + using A::x; | |
3767 | + Where x is variable in namespace A. declaration is set to x. | |
3768 | +*/ | |
3769 | ||
3770 | struct using_direct | |
3771 | { | |
7566401a ER |
3772 | char *import_src; |
3773 | char *import_dest; | |
3774 | + | |
3a58abaf | 3775 | + char *alias; |
7566401a | 3776 | + |
3a58abaf | 3777 | + char *declaration; |
7566401a | 3778 | + |
3a58abaf | 3779 | + int line_number; |
7566401a | 3780 | + |
3a58abaf | 3781 | struct using_direct *next; |
7566401a ER |
3782 | + |
3783 | + /* Used during import search to temporarly mark this node as searced. */ | |
3784 | + int searched; | |
3a58abaf AM |
3785 | }; |
3786 | ||
7566401a ER |
3787 | |
3788 | @@ -54,6 +72,7 @@ struct using_direct | |
3a58abaf AM |
3789 | |
3790 | extern char *cp_canonicalize_string (const char *string); | |
3791 | ||
3792 | + | |
3793 | extern char *cp_class_name_from_physname (const char *physname); | |
3794 | ||
3795 | extern char *method_name_from_physname (const char *physname); | |
7566401a ER |
3796 | @@ -72,15 +91,23 @@ extern struct symbol **make_symbol_overload_list (const char *, |
3797 | extern struct type *cp_lookup_rtti_type (const char *name, | |
3798 | struct block *block); | |
3799 | ||
3800 | +extern int cp_validate_operator (const char *input); | |
3801 | + | |
3802 | /* Functions/variables from cp-namespace.c. */ | |
3a58abaf AM |
3803 | |
3804 | extern int cp_is_anonymous (const char *namespace); | |
3805 | ||
7566401a ER |
3806 | extern void cp_add_using_directive (const char *dest, |
3807 | - const char *src); | |
3808 | + const char *src, | |
3a58abaf AM |
3809 | + const char *alias, |
3810 | + const char *declaration, | |
3811 | + const int line_number); | |
7566401a ER |
3812 | |
3813 | extern struct using_direct *cp_add_using (const char *dest, | |
3814 | const char *src, | |
3a58abaf AM |
3815 | + const char *alias, |
3816 | + const char *declaration, | |
3817 | + const int line_number, | |
7566401a | 3818 | struct using_direct *next); |
3a58abaf AM |
3819 | |
3820 | extern void cp_initialize_namespace (void); | |
7566401a ER |
3821 | @@ -97,15 +124,20 @@ extern void cp_set_block_scope (const struct symbol *symbol, |
3822 | extern void cp_scan_for_anonymous_namespaces (const struct symbol *symbol); | |
3a58abaf | 3823 | |
7566401a ER |
3824 | extern struct symbol *cp_lookup_symbol_nonlocal (const char *name, |
3825 | - const char *linkage_name, | |
3a58abaf AM |
3826 | const struct block *block, |
3827 | const domain_enum domain); | |
3828 | ||
7566401a ER |
3829 | +struct symbol *cp_lookup_symbol_imports (const char *scope, |
3830 | + const char *name, | |
3831 | + const struct block *block, | |
3832 | + const domain_enum domain, | |
3833 | + int declaration_only, | |
3834 | + int search_parents); | |
3a58abaf AM |
3835 | + |
3836 | extern struct symbol *cp_lookup_symbol_namespace (const char *namespace, | |
7566401a ER |
3837 | - const char *name, |
3838 | - const char *linkage_name, | |
3839 | - const struct block *block, | |
3840 | - const domain_enum domain); | |
3841 | + const char *name, | |
3842 | + const struct block *block, | |
3843 | + const domain_enum domain); | |
3844 | ||
3845 | extern struct type *cp_lookup_nested_type (struct type *parent_type, | |
3846 | const char *nested_name, | |
3a58abaf | 3847 | diff --git a/gdb/dbxread.c b/gdb/dbxread.c |
7566401a | 3848 | index 7cb016d..bb9e35a 100644 |
3a58abaf AM |
3849 | --- a/gdb/dbxread.c |
3850 | +++ b/gdb/dbxread.c | |
7566401a | 3851 | @@ -3581,6 +3581,7 @@ static struct sym_fns aout_sym_fns = |
3a58abaf AM |
3852 | dbx_new_init, /* sym_new_init: init anything gbl to entire symtab */ |
3853 | dbx_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
3854 | dbx_symfile_read, /* sym_read: read a symbol file into symtab */ | |
3855 | + NULL, /* sym_read_psymbols */ | |
3856 | dbx_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
3857 | default_symfile_offsets, /* sym_offsets: parse user's offsets to | |
3858 | internal form */ | |
3a58abaf | 3859 | diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo |
ab050a48 | 3860 | index 1f98fa5..9e24482 100644 |
3a58abaf AM |
3861 | --- a/gdb/doc/gdb.texinfo |
3862 | +++ b/gdb/doc/gdb.texinfo | |
7566401a | 3863 | @@ -959,8 +959,10 @@ Connect to process ID @var{number}, as with the @code{attach} command. |
3a58abaf AM |
3864 | @itemx -x @var{file} |
3865 | @cindex @code{--command} | |
3866 | @cindex @code{-x} | |
3867 | -Execute @value{GDBN} commands from file @var{file}. @xref{Command | |
3868 | -Files,, Command files}. | |
3869 | +Execute commands from file @var{file}. If @var{file} ends in | |
3870 | +@samp{.py}, then the file is evaluated as Python code. If Python | |
3871 | +support is not enabled in this @value{GDBN}, then an error occurs. | |
3872 | +@xref{Command Files,, Command files}. | |
3873 | ||
3874 | @item -eval-command @var{command} | |
3875 | @itemx -ex @var{command} | |
7566401a | 3876 | @@ -1152,6 +1154,16 @@ for remote debugging. |
3a58abaf AM |
3877 | Run using @var{device} for your program's standard input and output. |
3878 | @c FIXME: kingdon thinks there is more to -tty. Investigate. | |
3879 | ||
3880 | +@item -P | |
3881 | +@cindex @code{-P} | |
3882 | +@itemx --python | |
3883 | +@cindex @code{--python} | |
3884 | +Change interpretation of command line so that the argument immediately | |
3885 | +following this switch is taken to be the name of a Python script file. | |
3886 | +This option stops option processing; subsequent options are passed to | |
3887 | +Python as @code{sys.argv}. This option is only available if Python | |
3888 | +scripting support was enabled when @value{GDBN} was configured. | |
3889 | + | |
3890 | @c resolve the situation of these eventually | |
3891 | @item -tui | |
3892 | @cindex @code{--tui} | |
ab050a48 | 3893 | @@ -18660,7 +18672,7 @@ command: |
3a58abaf AM |
3894 | @table @code |
3895 | @kindex source | |
3896 | @cindex execute commands from a file | |
3897 | -@item source [@code{-v}] @var{filename} | |
3898 | +@item source [@code{-v}] [@code{-p}] @var{filename} | |
3899 | Execute the command file @var{filename}. | |
3900 | @end table | |
3901 | ||
ab050a48 | 3902 | @@ -18677,6 +18689,11 @@ If @code{-v}, for verbose mode, is given then @value{GDBN} displays |
3a58abaf AM |
3903 | each command as it is executed. The option must be given before |
3904 | @var{filename}, and is interpreted as part of the filename anywhere else. | |
3905 | ||
3906 | +If @var{filename} ends in @samp{.py}, or if @code{-p}, for Python, is | |
3907 | +given then @value{GDBN} evaluates the contents of the file as Python | |
3908 | +code. If Python support is not compiled in to @value{GDBN}, then an | |
3909 | +error occurs. | |
3910 | + | |
3911 | Commands that would ask for confirmation if used interactively proceed | |
3912 | without asking when used in a command file. Many @value{GDBN} commands that | |
3913 | normally print messages to say what they are doing omit the messages | |
ab050a48 | 3914 | @@ -18938,8 +18955,6 @@ containing @code{end}. For example: |
3a58abaf AM |
3915 | |
3916 | @smallexample | |
3917 | (@value{GDBP}) python | |
3918 | -Type python script | |
3919 | -End with a line saying just "end". | |
3920 | >print 23 | |
3921 | >end | |
3922 | 23 | |
ab050a48 | 3923 | @@ -18952,6 +18967,14 @@ in a Python script. This can be controlled using @code{maint set |
3a58abaf AM |
3924 | python print-stack}: if @code{on}, the default, then Python stack |
3925 | printing is enabled; if @code{off}, then Python stack printing is | |
3926 | disabled. | |
3927 | + | |
3928 | +@kindex maint set python auto-load | |
3929 | +@item maint set python auto-load | |
3930 | +By default, @value{GDBN} will attempt to automatically load Python | |
3931 | +code when an object file is opened. This can be controlled using | |
3932 | +@code{maint set python auto-load}: if @code{on}, the default, then | |
3933 | +Python auto-loading is enabled; if @code{off}, then Python | |
3934 | +auto-loading is disabled. | |
3935 | @end table | |
3936 | ||
3937 | @node Python API | |
ab050a48 | 3938 | @@ -18959,6 +18982,14 @@ disabled. |
3a58abaf AM |
3939 | @cindex python api |
3940 | @cindex programming in python | |
3941 | ||
3942 | +You can get quick online help for @value{GDBN}'s Python API by issuing | |
3943 | +the command @w{@kbd{python help (gdb)}}. | |
3944 | + | |
3945 | +Functions and methods which have two or more optional arguments allow | |
3946 | +them to be specified using keyword syntax. This allows passing some | |
3947 | +optional arguments while skipping others. Example: | |
3948 | +@w{@code{gdb.some_function ('foo', bar = 1, baz = 2)}}. | |
3949 | + | |
3950 | @cindex python stdout | |
3951 | @cindex python pagination | |
3952 | At startup, @value{GDBN} overrides Python's @code{sys.stdout} and | |
ab050a48 | 3953 | @@ -18971,13 +19002,17 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown. |
3a58abaf AM |
3954 | * Basic Python:: Basic Python Functions. |
3955 | * Exception Handling:: | |
7566401a | 3956 | * Auto-loading:: Automatically loading Python code. |
3a58abaf | 3957 | -* Values From Inferior:: |
3a58abaf | 3958 | +* Values From Inferior:: Python representation of values. |
7566401a ER |
3959 | * Types In Python:: Python representation of types. |
3960 | * Pretty Printing:: Pretty-printing values. | |
3961 | * Selecting Pretty-Printers:: How GDB chooses a pretty-printer. | |
3962 | +* Inferiors In Python:: Python representation of inferiors (processes) | |
3a58abaf AM |
3963 | +* Threads In Python:: Accessing inferior threads from Python. |
3964 | * Commands In Python:: Implementing new commands in Python. | |
3965 | +* Parameters In Python:: Adding new @value{GDBN} parameters. | |
7566401a ER |
3966 | * Functions In Python:: Writing new convenience functions. |
3967 | * Objfiles In Python:: Object files. | |
3a58abaf | 3968 | +* Breakpoints In Python:: Manipulating breakpoints using Python. |
7566401a | 3969 | * Frames In Python:: Acessing inferior stack frames from Python. |
3a58abaf AM |
3970 | @end menu |
3971 | ||
ab050a48 | 3972 | @@ -19004,6 +19039,12 @@ command as having originated from the user invoking it interactively. |
3a58abaf AM |
3973 | It must be a boolean value. If omitted, it defaults to @code{False}. |
3974 | @end defun | |
3975 | ||
3a58abaf AM |
3976 | +@findex gdb.breakpoints |
3977 | +@defun breakpoints | |
3978 | +Return a sequence holding all of @value{GDBN}'s breakpoints. | |
3979 | +@xref{Breakpoints In Python}, for more information. | |
3980 | +@end defun | |
3981 | + | |
7566401a ER |
3982 | @findex gdb.parameter |
3983 | @defun parameter parameter | |
3984 | Return the value of a @value{GDBN} parameter. @var{parameter} is a | |
ab050a48 | 3985 | @@ -19020,6 +19061,7 @@ a Python value of the appropriate type, and returned. |
7566401a ER |
3986 | @defun history number |
3987 | Return a value from @value{GDBN}'s value history (@pxref{Value | |
3988 | History}). @var{number} indicates which history element to return. | |
3989 | + | |
3990 | If @var{number} is negative, then @value{GDBN} will take its absolute value | |
3991 | and count backward from the last element (i.e., the most recent element) to | |
3992 | find the value to return. If @var{number} is zero, then @value{GDBN} will | |
ab050a48 | 3993 | @@ -19031,6 +19073,28 @@ If no exception is raised, the return value is always an instance of |
3a58abaf AM |
3994 | @code{gdb.Value} (@pxref{Values From Inferior}). |
3995 | @end defun | |
3996 | ||
3997 | +@findex gdb.parse_and_eval | |
3998 | +@defun parse_and_eval expression | |
3999 | +Parse @var{expression} as an expression in the current language, | |
4000 | +evaluate it, and return the result as a @code{gdb.Value}. | |
4001 | +@var{expression} must be a string. | |
4002 | +@end defun | |
4003 | + | |
4004 | +@findex gdb.post_event | |
4005 | +@defun post_event event | |
4006 | +Put @var{event}, a callable object taking no arguments, into | |
4007 | +@value{GDBN}'s internal event queue. This callable will be invoked at | |
4008 | +some later point, during @value{GDBN}'s event processing. Events | |
4009 | +posted using @code{post_event} will be run in the order in which they | |
4010 | +were posted; however, there is no way to know when they will be | |
4011 | +processed relative to other events inside @value{GDBN}. | |
4012 | + | |
4013 | +@value{GDBN} is not thread-safe. If your Python program uses multiple | |
4014 | +threads, you must be careful to only call @value{GDBN}-specific | |
4015 | +functions in the main @value{GDBN} thread. @code{post_event} ensures | |
4016 | +this. | |
4017 | +@end defun | |
4018 | + | |
4019 | @findex gdb.write | |
4020 | @defun write string | |
4021 | Print a string to @value{GDBN}'s paginated standard output stream. | |
ab050a48 | 4022 | @@ -19045,6 +19109,11 @@ Flush @value{GDBN}'s paginated standard output stream. Flushing |
3a58abaf AM |
4023 | function. |
4024 | @end defun | |
4025 | ||
3a58abaf AM |
4026 | +@findex gdb.solib_address |
4027 | +@defun solib_address @var{address} | |
4028 | +Return the name of the shared library holding the given address, or None. | |
4029 | +@end defun | |
4030 | + | |
4031 | @node Exception Handling | |
4032 | @subsubsection Exception Handling | |
4033 | @cindex python exceptions | |
ab050a48 | 4034 | @@ -19181,6 +19250,13 @@ The type of this @code{gdb.Value}. The value of this attribute is a |
7566401a ER |
4035 | The following methods are provided: |
4036 | ||
4037 | @table @code | |
3a58abaf AM |
4038 | +@defmethod Value cast type |
4039 | +Cast the @code{gdb.Value} to the type represented by @var{type}, and | |
4040 | +return a new @code{gdb.Value}. @var{type} must be a @code{gdb.Type} | |
4041 | +object. If the cast cannot be performed for some reason, an exception | |
4042 | +is thrown. | |
4043 | +@end defmethod | |
7566401a | 4044 | + |
3a58abaf | 4045 | @defmethod Value dereference |
7566401a ER |
4046 | For pointer data types, this method returns a new @code{gdb.Value} object |
4047 | whose contents is the object pointed to by the pointer. For example, if | |
ab050a48 | 4048 | @@ -19252,6 +19328,9 @@ module: |
7566401a ER |
4049 | This function looks up a type by name. @var{name} is the name of the |
4050 | type to look up. It must be a string. | |
4051 | ||
4052 | +If @var{block} is given, then @var{name} is looked up in that scope. | |
4053 | +Otherwise, it is searched for globally. | |
4054 | + | |
4055 | Ordinarily, this function will return an instance of @code{gdb.Type}. | |
4056 | If the named type cannot be found, it will throw an exception. | |
4057 | @end defun | |
ab050a48 | 4058 | @@ -19304,6 +19383,12 @@ This is @code{True} if the field is artificial, usually meaning that |
7566401a ER |
4059 | it was provided by the compiler and not the user. This attribute is |
4060 | always provided, and is @code{False} if the field is not artificial. | |
4061 | ||
4062 | +@item is_base_class | |
4063 | +This is @code{True} if the field represents a base class of a C@t{++} | |
4064 | +structure. This attribute is always provided, and is @code{False} | |
4065 | +if the field is not a base class of the type on which @code{fields} was | |
4066 | +called, or if that type was not a C@t{++} class. | |
4067 | + | |
4068 | @item bitsize | |
4069 | If the field is packed, or is a bitfield, then this will have a | |
4070 | non-zero value, which is the size of the field in bits. Otherwise, | |
ab050a48 | 4071 | @@ -19356,7 +19441,7 @@ If the type does not have a target, this method will throw an |
7566401a | 4072 | exception. |
3a58abaf AM |
4073 | @end defmethod |
4074 | ||
7566401a ER |
4075 | -@defmethod Type template_argument n |
4076 | +@defmethod Type template_argument n [block] | |
4077 | If this @code{gdb.Type} is an instantiation of a template, this will | |
4078 | return a new @code{gdb.Type} which represents the type of the | |
4079 | @var{n}th template argument. | |
ab050a48 | 4080 | @@ -19364,7 +19449,8 @@ return a new @code{gdb.Type} which represents the type of the |
7566401a ER |
4081 | If this @code{gdb.Type} is not a template type, this will throw an |
4082 | exception. Ordinarily, only C@t{++} code will have template types. | |
4083 | ||
4084 | -@var{name} is searched for globally. | |
4085 | +If @var{block} is given, then @var{name} is looked up in that scope. | |
4086 | +Otherwise, it is searched for globally. | |
3a58abaf | 4087 | @end defmethod |
7566401a | 4088 | @end table |
3a58abaf | 4089 | |
ab050a48 | 4090 | @@ -19718,6 +19804,121 @@ import gdb.libstdcxx.v6 |
7566401a ER |
4091 | gdb.libstdcxx.v6.register_printers (gdb.current_objfile ()) |
4092 | @end smallexample | |
4093 | ||
4094 | +@node Inferiors In Python | |
4095 | +@subsubsection Inferiors In Python | |
3a58abaf | 4096 | + |
7566401a ER |
4097 | +Programs which are being run under @value{GDBN} are called inferiors |
4098 | +(@pxref{Inferiors}). Python scripts can access information about and | |
4099 | +manipulate inferiors controlled by @value{GDBN} via objects of the | |
4100 | +@code{gdb.Inferior} class. | |
3a58abaf | 4101 | + |
7566401a ER |
4102 | +The following inferior-related functions are available in the @code{gdb} |
4103 | +module: | |
4104 | + | |
4105 | +@defun inferiors | |
4106 | +Return a tuple containing all inferior objects. | |
4107 | +@end defun | |
3a58abaf | 4108 | + |
7566401a | 4109 | +A @code{gdb.Inferior} object has the following attributes: |
3a58abaf AM |
4110 | + |
4111 | +@table @code | |
7566401a ER |
4112 | +@defivar Inferior num |
4113 | +ID of inferior, as assigned by GDB. | |
4114 | +@end defivar | |
3a58abaf | 4115 | + |
7566401a ER |
4116 | +@defivar Inferior pid |
4117 | +Process ID of the inferior, assigned by the underlying OS. | |
4118 | +@end defivar | |
3a58abaf | 4119 | + |
7566401a ER |
4120 | +@defivar Inferior was_attached |
4121 | +Boolean signaling whether the inferior was created using `attach', or | |
4122 | +started by @value{GDBN} itself. | |
4123 | +@end defivar | |
4124 | +@end table | |
3a58abaf | 4125 | + |
7566401a ER |
4126 | +A @code{gdb.Inferior} object has the following methods: |
4127 | + | |
4128 | +@table @code | |
4129 | +@defmethod Inferior threads | |
4130 | +This method returns a tuple holding all the threads which are valid | |
4131 | +when it is called. If there are no valid threads, the method will | |
4132 | +return an empty list. | |
3a58abaf AM |
4133 | +@end defmethod |
4134 | + | |
7566401a ER |
4135 | +@findex gdb.read_memory |
4136 | +@defmethod Inferior read_memory @var{address} @var{length} | |
4137 | +Read @var{length} bytes of memory from the inferior, starting at | |
4138 | +@var{address}. Returns a buffer object, which behaves much like an array | |
4139 | +or a string. It can be modified and given to the @code{gdb.write_memory} | |
4140 | +function. | |
4141 | +@end defmethod | |
3a58abaf | 4142 | + |
7566401a ER |
4143 | +@findex gdb.write_memory |
4144 | +@defmethod Inferior write_memory @var{address} @var{buffer} @r{[}@var{length}@r{]} | |
4145 | +Write the contents of @var{buffer} (a Python object which supports the | |
4146 | +buffer protocol, i.e., a string, an array or the object returned from | |
4147 | +@code{gdb.read_memory}) to the inferior, starting at @var{address}. | |
4148 | +If given, @var{length} determines the number of bytes from @var{buffer} to | |
4149 | +be written. | |
4150 | +@end defmethod | |
3a58abaf | 4151 | + |
7566401a ER |
4152 | +@findex gdb.search_memory |
4153 | +@defmethod Inferior search_memory @var{address} @var{length} @var{pattern} @r{[}@var{size}@r{]} @r{[}@var{max_count}@r{]} | |
4154 | +Search a region of the inferior memory starting at @var{address} with the | |
4155 | +given @var{length}. @var{pattern} can be a string, a byte array, a buffer | |
4156 | +object, a number, a @code{gdb.Value} object (@pxref{Values From Inferior}) | |
4157 | +or a list or tuple with elements in any combination of those types. If | |
4158 | +@var{size} is given and is non-zero, it specifies the size in bytes of a | |
4159 | +Python scalar or @code{gdb.Value} in the search pattern. If @var{size} is | |
4160 | +zero or not specified, it is taken from the value's type in the current | |
4161 | +language. This is useful when one wants to specify the search pattern as | |
4162 | +a mixture of types. Note that this means, for example, that in the case of | |
4163 | +C-like languages a search for an untyped 0x42 will search for | |
4164 | +@samp{(int) 0x42} which is typically four bytes. @var{max_count} is the | |
4165 | +highest number of matches to search for. | |
4166 | +@end defmethod | |
4167 | +@end table | |
3a58abaf | 4168 | + |
7566401a ER |
4169 | +@node Threads In Python |
4170 | +@subsubsection Threads In Python | |
3a58abaf | 4171 | + |
7566401a ER |
4172 | +Python scripts can access information about and manipulate inferior threads |
4173 | +controlled by @value{GDBN} via objects of the @code{gdb.InferiorThread} class. | |
3a58abaf | 4174 | + |
7566401a ER |
4175 | +The following inferior-related functions are available in the @code{gdb} |
4176 | +module: | |
3a58abaf | 4177 | + |
7566401a ER |
4178 | +@findex gdb.selected_thread |
4179 | +@defun selected_thread | |
4180 | +This function returns the thread object for the selected thread. If there | |
4181 | +is no selected thread, this will return @code{None}. | |
4182 | +@end defun | |
3a58abaf | 4183 | + |
7566401a | 4184 | +A @code{gdb.InferiorThread} object has the following attributes: |
3a58abaf | 4185 | + |
7566401a ER |
4186 | +@table @code |
4187 | +@defivar InferiorThread num | |
4188 | +ID of the thread, as assigned by GDB. | |
4189 | +@end defivar | |
4190 | +@end table | |
3a58abaf | 4191 | + |
7566401a | 4192 | +A @code{gdb.InferiorThread} object has the following methods: |
3a58abaf | 4193 | + |
7566401a ER |
4194 | +@table @code |
4195 | +@defmethod InferiorThread frames | |
4196 | +Return a tuple containing all frames in the thread. | |
3a58abaf AM |
4197 | +@end defmethod |
4198 | + | |
7566401a ER |
4199 | +@defmethod InferiorThread newest_frame |
4200 | +Return the newest frame thread's stack. | |
3a58abaf AM |
4201 | +@end defmethod |
4202 | + | |
7566401a ER |
4203 | +@defmethod InferiorThread switch_to_thread |
4204 | +This changes @value{GDBN}'s currently selected thread to the one represented | |
4205 | +by this object. | |
3a58abaf | 4206 | +@end defmethod |
7566401a | 4207 | +@end table |
3a58abaf AM |
4208 | + |
4209 | @node Commands In Python | |
4210 | @subsubsection Commands In Python | |
4211 | ||
ab050a48 | 4212 | @@ -19970,6 +20171,135 @@ registration of the command with @value{GDBN}. Depending on how the |
3a58abaf AM |
4213 | Python code is read into @value{GDBN}, you may need to import the |
4214 | @code{gdb} module explicitly. | |
4215 | ||
3a58abaf AM |
4216 | +@node Parameters In Python |
4217 | +@subsubsection Parameters In Python | |
4218 | + | |
4219 | +@cindex parameters in python | |
4220 | +@cindex python parameters | |
4221 | +@tindex gdb.Parameter | |
4222 | +@tindex Parameter | |
4223 | +You can implement new @value{GDBN} parameters using Python. A new | |
4224 | +parameter is implemented as an instance of the @code{gdb.Parameter} | |
4225 | +class. Parameters are exposed to the user via the @code{set} and | |
4226 | +@code{show} commands. | |
4227 | + | |
4228 | +@defmethod Parameter __init__ name @var{command-class} @var{parameter-class} @r{[}@var{enum-sequence}@r{]} | |
4229 | +The object initializer for @code{Parameter} registers the new | |
4230 | +parameter with @value{GDBN}. This initializer is normally invoked | |
4231 | +from the subclass' own @code{__init__} method. | |
4232 | + | |
4233 | +@var{name} is the name of the new parameter. If @var{name} consists | |
4234 | +of multiple words, then the initial words are looked for as prefix | |
4235 | +commands. In this case, if one of the prefix commands does not exist, | |
4236 | +an exception is raised. | |
4237 | + | |
4238 | +@var{command-class} should be one of the @samp{COMMAND_} constants | |
4239 | +(@pxref{Commands In Python}). This argument tells @value{GDBN} how to | |
4240 | +categorize the new parameter in the help system. | |
4241 | + | |
4242 | +@var{parameter-class} should be one of the @samp{PARAM_} constants | |
4243 | +defined below. This argument tells @value{GDBN} the type of the new | |
4244 | +parameter; this information is used for input validation and | |
4245 | +completion. | |
4246 | + | |
4247 | +If @var{parameter-class} is @code{PARAM_ENUM}, then | |
4248 | +@var{enum-sequence} must be a sequence of strings. These strings | |
4249 | +represent the possible values for the parameter. | |
4250 | + | |
4251 | +If @var{parameter-class} is not @code{PARAM_ENUM}, then the presence | |
4252 | +of a fourth argument will cause an exception to be thrown. | |
4253 | + | |
4254 | +The help text for the new parameter is taken from the Python | |
4255 | +documentation string for the parameter's class, if there is one. If | |
4256 | +there is no documentation string, a default value is used. | |
4257 | +@end defmethod | |
4258 | + | |
4259 | +@defivar Parameter set_doc | |
4260 | +If this attribute exists, and is a string, then its value is used as | |
4261 | +the help text for this parameter's @code{set} command. The value is | |
4262 | +examined when @code{Parameter.__init__} is invoked; subsequent changes | |
4263 | +have no effect. | |
4264 | +@end defivar | |
4265 | + | |
4266 | +@defivar Parameter show_doc | |
4267 | +If this attribute exists, and is a string, then its value is used as | |
4268 | +the help text for this parameter's @code{show} command. The value is | |
4269 | +examined when @code{Parameter.__init__} is invoked; subsequent changes | |
4270 | +have no effect. | |
4271 | +@end defivar | |
4272 | + | |
4273 | +@defivar Parameter value | |
4274 | +The @code{value} attribute holds the underlying value of the | |
4275 | +parameter. It can be read and assigned to just as any other | |
4276 | +attribute. @value{GDBN} does validation when assignments are made. | |
4277 | +@end defivar | |
4278 | + | |
4279 | + | |
4280 | +When a new parameter is defined, its type must be specified. The | |
4281 | +available types are represented by constants defined in the @code{gdb} | |
4282 | +module: | |
4283 | + | |
4284 | +@table @code | |
4285 | +@findex PARAM_BOOLEAN | |
4286 | +@findex gdb.PARAM_BOOLEAN | |
4287 | +@item PARAM_BOOLEAN | |
4288 | +The value is a plain boolean. The Python boolean values, @code{True} | |
4289 | +and @code{False} are the only valid values. | |
4290 | + | |
4291 | +@findex PARAM_AUTO_BOOLEAN | |
4292 | +@findex gdb.PARAM_AUTO_BOOLEAN | |
4293 | +@item PARAM_AUTO_BOOLEAN | |
4294 | +The value has three possible states: true, false, and @samp{auto}. In | |
4295 | +Python, true and false are represented using boolean constants, and | |
4296 | +@samp{auto} is represented using @code{None}. | |
4297 | + | |
4298 | +@findex PARAM_UINTEGER | |
4299 | +@findex gdb.PARAM_UINTEGER | |
4300 | +@item PARAM_UINTEGER | |
4301 | +The value is an unsigned integer. The value of 0 should be | |
4302 | +interpreted to mean ``unlimited''. | |
4303 | + | |
4304 | +@findex PARAM_INTEGER | |
4305 | +@findex gdb.PARAM_INTEGER | |
4306 | +@item PARAM_INTEGER | |
4307 | +The value is a signed integer. The value of 0 should be interpreted | |
4308 | +to mean ``unlimited''. | |
4309 | + | |
4310 | +@findex PARAM_STRING | |
4311 | +@findex gdb.PARAM_STRING | |
4312 | +@item PARAM_STRING | |
4313 | +The value is a string. When the user modifies the string, escapes are | |
4314 | +translated. | |
4315 | + | |
4316 | +@findex PARAM_STRING_NOESCAPE | |
4317 | +@findex gdb.PARAM_STRING_NOESCAPE | |
4318 | +@item PARAM_STRING_NOESCAPE | |
4319 | +The value is a string. When the user modifies the string, escapes are | |
4320 | +passed through untranslated. | |
4321 | + | |
4322 | +@findex PARAM_OPTIONAL_FILENAME | |
4323 | +@findex gdb.PARAM_OPTIONAL_FILENAME | |
4324 | +@item PARAM_OPTIONAL_FILENAME | |
4325 | +The value is a either a filename (a string), or @code{None}. | |
4326 | + | |
4327 | +@findex PARAM_FILENAME | |
4328 | +@findex gdb.PARAM_FILENAME | |
4329 | +@item PARAM_FILENAME | |
4330 | +The value is a filename (a string). | |
4331 | + | |
4332 | +@findex PARAM_ZINTEGER | |
4333 | +@findex gdb.PARAM_ZINTEGER | |
4334 | +@item PARAM_ZINTEGER | |
4335 | +The value is an integer. This is like @code{PARAM_INTEGER}, except 0 | |
4336 | +is interpreted as itself. | |
4337 | + | |
4338 | +@findex PARAM_ENUM | |
4339 | +@findex gdb.PARAM_ENUM | |
4340 | +@item PARAM_ENUM | |
4341 | +The value is a string, which must be one of a collection string | |
4342 | +constants provided when the parameter is created. | |
4343 | +@end table | |
4344 | + | |
7566401a ER |
4345 | @node Functions In Python |
4346 | @subsubsection Writing new convenience functions | |
4347 | ||
ab050a48 | 4348 | @@ -20074,6 +20404,82 @@ which is used to format the value. @xref{Pretty Printing}, for more |
7566401a ER |
4349 | information. |
4350 | @end defivar | |
4351 | ||
3a58abaf AM |
4352 | +@node Breakpoints In Python |
4353 | +@subsubsection Manipulating breakpoints using Python | |
4354 | + | |
4355 | +@cindex breakpoints in python | |
4356 | +@cindex python breakpoints | |
4357 | +@tindex gdb.Breakpoint | |
4358 | +@tindex Breakpoint | |
4359 | +Python code can manipulate breakpoints via the @code{gdb.Breakpoint} | |
4360 | +class. | |
4361 | + | |
4362 | +@defmethod Breakpoint __init__ location | |
4363 | +Create a new breakpoint. @var{location} is a string naming the | |
4364 | +location of the breakpoint. The contents can be any location | |
4365 | +recognized by the @code{break} command. | |
4366 | +@end defmethod | |
4367 | + | |
4368 | +@defmethod Breakpoint is_valid | |
4369 | +Return @code{True} if this @code{Breakpoint} object is valid, | |
4370 | +@code{False} otherwise. A @code{Breakpoint} object can become invalid | |
4371 | +if the user deletes the breakpoint. In this case, the object still | |
4372 | +exists, but the underlying breakpoint does not. | |
4373 | +@end defmethod | |
4374 | + | |
4375 | +@defivar Breakpoint enabled | |
4376 | +This attribute is @code{True} if the breakpoint is enabled, and | |
4377 | +@code{False} otherwise. This attribute is writable. | |
4378 | +@end defivar | |
4379 | + | |
4380 | +@defivar Breakpoint silent | |
4381 | +This attribute is @code{True} if the breakpoint is silent, and | |
4382 | +@code{False} otherwise. This attribute is writable. | |
4383 | + | |
4384 | +Note that a breakpoint can also be silent if it has commands and the | |
4385 | +first command is @code{silent}. This is not reported by the | |
4386 | +@code{silent} attribute. | |
4387 | +@end defivar | |
4388 | + | |
4389 | +@defivar Breakpoint thread | |
4390 | +If the breakpoint is thread-specific, this attribute holds the thread | |
4391 | +id. If the breakpoint is not thread-specific, this attribute is | |
4392 | +@code{None}. This attribute is writable. | |
4393 | +@end defivar | |
4394 | + | |
4395 | +@defivar Breakpoint ignore_count | |
4396 | +This attribute holds the ignore count for the breakpoint, an integer. | |
4397 | +This attribute is writable. | |
4398 | +@end defivar | |
4399 | + | |
4400 | +@defivar Breakpoint number | |
4401 | +This attribute holds the breakpoint's number -- the identifier used by | |
4402 | +the user to manipulate the breakpoint. This attribute is not writable. | |
4403 | +@end defivar | |
4404 | + | |
4405 | +@defivar Breakpoint hit_count | |
4406 | +This attribute holds the hit count for the breakpoint, an integer. | |
4407 | +This attribute is writable, but currently it can only be set to zero. | |
4408 | +@end defivar | |
4409 | + | |
4410 | +@defivar Breakpoint location | |
4411 | +This attribute holds the location of the breakpoint, as specified by | |
4412 | +the user. It is a string. This attribute is not writable. | |
4413 | +@end defivar | |
4414 | + | |
4415 | +@defivar Breakpoint condition | |
4416 | +This attribute holds the condition of the breakpoint, as specified by | |
4417 | +the user. It is a string. If there is no condition, this attribute's | |
4418 | +value is @code{None}. This attribute is writable. | |
4419 | +@end defivar | |
4420 | + | |
4421 | +@defivar Breakpoint commands | |
4422 | +This attribute holds the commands attached to the breakpoint. If | |
4423 | +there are commands, this returns a string holding all the commands, | |
4424 | +separated by newlines. If there are no commands, this attribute is | |
4425 | +@code{None}. This attribute is not writable. | |
4426 | +@end defivar | |
4427 | + | |
7566401a ER |
4428 | @node Frames In Python |
4429 | @subsubsection Acessing inferior stack frames from Python. | |
4430 | ||
ab050a48 | 4431 | @@ -20138,6 +20544,14 @@ function to a string. |
7566401a ER |
4432 | Returns the frame's resume address. |
4433 | @end defmethod | |
4434 | ||
3a58abaf | 4435 | +@defmethod Frame block |
7566401a | 4436 | +Returns the frame's code block. @c (@pxref{Block,,Code Blocks and Scopes}). |
3a58abaf AM |
4437 | +@end defmethod |
4438 | + | |
7566401a ER |
4439 | +@defmethod Frame function |
4440 | +Returns the symbol for the function corresponding to this frame. @c (@pxref{Symbols In Python}). | |
3a58abaf AM |
4441 | +@end defmethod |
4442 | + | |
7566401a ER |
4443 | @defmethod Frame older |
4444 | Return the frame that called this frame. | |
4445 | @end defmethod | |
ab050a48 | 4446 | @@ -20146,10 +20560,18 @@ Return the frame that called this frame. |
7566401a ER |
4447 | Return the frame called by this frame. |
4448 | @end defmethod | |
4449 | ||
3a58abaf | 4450 | +@defmethod Frame find_sal |
7566401a | 4451 | +Return the frame's symtab and line object. @c (@pxref{Symtab_and_line,, Symtab and line}). |
3a58abaf AM |
4452 | +@end defmethod |
4453 | + | |
7566401a ER |
4454 | @defmethod Frame read_var variable |
4455 | Return the value of the given variable in this frame. @var{variable} must | |
4456 | be a string. | |
4457 | @end defmethod | |
3a58abaf | 4458 | + |
7566401a ER |
4459 | +@defmethod Frame select |
4460 | +Set this frame to be the user's selected frame. | |
4461 | +@end defmethod | |
4462 | @end table | |
4463 | ||
3a58abaf | 4464 | @node Interpreters |
7566401a ER |
4465 | diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo |
4466 | index c2be3f7..a7811ab 100644 | |
4467 | --- a/gdb/doc/gdbint.texinfo | |
4468 | +++ b/gdb/doc/gdbint.texinfo | |
4469 | @@ -2114,6 +2114,18 @@ time, and so we attempt to handle symbols incrementally. For instance, | |
4470 | we create @dfn{partial symbol tables} consisting of only selected | |
4471 | symbols, and only expand them to full symbol tables when necessary. | |
4472 | ||
4473 | +@menu | |
4474 | +* Symbol Reading:: | |
4475 | +* Partial Symbol Tables:: | |
4476 | +* Types:: | |
4477 | +* Object File Formats:: | |
4478 | +* Debugging File Formats:: | |
4479 | +* Adding a New Symbol Reader to GDB:: | |
4480 | +* Memory Management for Symbol Files:: | |
4481 | +* Memory Management for Types:: | |
4482 | +@end menu | |
4483 | + | |
4484 | +@node Symbol Reading | |
4485 | @section Symbol Reading | |
4486 | ||
4487 | @cindex symbol reading | |
4488 | @@ -2206,6 +2218,7 @@ symtab. Upon return, @code{pst->readin} should have been set to 1, and | |
4489 | zero if there were no symbols in that part of the symbol file. | |
4490 | @end table | |
3a58abaf | 4491 | |
7566401a ER |
4492 | +@node Partial Symbol Tables |
4493 | @section Partial Symbol Tables | |
4494 | ||
4495 | @value{GDBN} has three types of symbol tables: | |
4496 | @@ -2301,6 +2314,7 @@ and all the psymbols themselves are allocated in a pair of large arrays | |
4497 | on an obstack, so there is little to be gained by trying to free them | |
4498 | unless you want to do a lot more work. | |
4499 | ||
4500 | +@node Types | |
4501 | @section Types | |
4502 | ||
4503 | @unnumberedsubsec Fundamental Types (e.g., @code{FT_VOID}, @code{FT_BOOLEAN}). | |
4504 | @@ -2323,6 +2337,7 @@ types map to one @code{TYPE_CODE_*} type, and are distinguished by | |
4505 | other members of the type struct, such as whether the type is signed | |
4506 | or unsigned, and how many bits it uses. | |
4507 | ||
4508 | +@anchor{Builtin Types} | |
4509 | @unnumberedsubsec Builtin Types (e.g., @code{builtin_type_void}, @code{builtin_type_char}). | |
4510 | ||
4511 | These are instances of type structs that roughly correspond to | |
4512 | @@ -2337,6 +2352,7 @@ only one instance exists, while @file{c-lang.c} builds as many | |
4513 | @code{TYPE_CODE_INT} types as needed, with each one associated with | |
4514 | some particular objfile. | |
4515 | ||
4516 | +@node Object File Formats | |
4517 | @section Object File Formats | |
4518 | @cindex object file formats | |
4519 | ||
4520 | @@ -2422,6 +2438,7 @@ SOM, which is a cross-language ABI). | |
4521 | ||
4522 | The SOM reader is in @file{somread.c}. | |
4523 | ||
4524 | +@node Debugging File Formats | |
4525 | @section Debugging File Formats | |
4526 | ||
4527 | This section describes characteristics of debugging information that | |
4528 | @@ -2493,6 +2510,7 @@ DWARF 3 is an improved version of DWARF 2. | |
4529 | @cindex SOM debugging info | |
4530 | Like COFF, the SOM definition includes debugging information. | |
4531 | ||
4532 | +@node Adding a New Symbol Reader to GDB | |
4533 | @section Adding a New Symbol Reader to @value{GDBN} | |
4534 | ||
4535 | @cindex adding debugging info reader | |
4536 | @@ -2515,6 +2533,7 @@ will only ever be implemented by one object file format may be called | |
4537 | directly. This interface should be described in a file | |
4538 | @file{bfd/lib@var{xyz}.h}, which is included by @value{GDBN}. | |
4539 | ||
4540 | +@node Memory Management for Symbol Files | |
4541 | @section Memory Management for Symbol Files | |
4542 | ||
4543 | Most memory associated with a loaded symbol file is stored on | |
4544 | @@ -2526,10 +2545,45 @@ released when the objfile is unloaded or reloaded. Therefore one | |
4545 | objfile must not reference symbol or type data from another objfile; | |
4546 | they could be unloaded at different times. | |
4547 | ||
4548 | -User convenience variables, et cetera, have associated types. Normally | |
4549 | -these types live in the associated objfile. However, when the objfile | |
4550 | -is unloaded, those types are deep copied to global memory, so that | |
4551 | -the values of the user variables and history items are not lost. | |
4552 | +@node Memory Management for Types | |
4553 | +@section Memory Management for Types | |
4554 | +@cindex memory management for types | |
4555 | + | |
4556 | +@findex TYPE_OBJFILE | |
4557 | +@code{TYPE_OBJFILE} macro indicates the current memory owner of the type. | |
4558 | +Non-@code{NULL} value indicates it is owned by an objfile (specifically by its | |
4559 | +obstack) and in such case the type remains valid till the objfile is unloaded | |
4560 | +or reloaded. For such types with an associated objfile no reference counting | |
4561 | +is being made. | |
4562 | + | |
4563 | +User convenience variables, et cetera, have associated types. Normally these | |
4564 | +types live in the associated objfile. However, when the objfile is unloaded, | |
4565 | +those types are deep copied to global memory, so that the values of the user | |
4566 | +variables and history items are not lost. During the copy they will get their | |
4567 | +@code{TYPE_OBJFILE} set to @code{NULL} and become so-called @dfn{reclaimable} | |
4568 | +types. | |
4569 | + | |
4570 | +Types with null @code{TYPE_OBJFILE} can be either permanent types | |
4571 | +(@pxref{Builtin Types}) or reclaimable types which will be deallocated at the | |
4572 | +first idle @value{GDBN} moment if the last object referencing them is removed. | |
4573 | +Permanent types are allocated by the function @code{alloc_type} (and its | |
4574 | +derivations like @code{init_type}) specifying objfile as @code{NULL}. The | |
4575 | +reclaimable types are created the same way but moreover they need to have | |
4576 | +@code{type_init_group} called to start their tracking as being possibly | |
4577 | +deallocatable. | |
4578 | + | |
4579 | +@findex free_all_types | |
4580 | +When @value{GDBN} gets idle it always calls the @code{free_all_types} function | |
4581 | +which deallocates any unused types. All types currently not owned by an | |
4582 | +objfile must be marked as used on each @code{free_all_types} call as they would | |
4583 | +get deallocated as unused otherwise. | |
4584 | + | |
4585 | +@code{free_all_types} automatically checks for any cross-type references such | |
4586 | +as through @code{TYPE_TARGET_TYPE}, @code{TYPE_POINTER_TYPE} etc.@: and | |
4587 | +prevents early deallocation for any such existing references. Reclaimable | |
4588 | +types may reference any other reclaimable types or even permanent types. But | |
4589 | +permanent types must not reference reclaimable types (nor an objfile associated | |
4590 | +type). | |
4591 | ||
4592 | ||
4593 | @node Language Support | |
4594 | diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi | |
4595 | index 4984f31..fcf1b5d 100644 | |
4596 | --- a/gdb/doc/observer.texi | |
4597 | +++ b/gdb/doc/observer.texi | |
4598 | @@ -206,6 +206,11 @@ Either @value{GDBN} detached from the inferior, or the inferior | |
4599 | exited. The argument @var{pid} identifies the inferior. | |
4600 | @end deftypefun | |
4601 | ||
4602 | +@deftypefun void mark_used (void) | |
4603 | +Mark any possibly reclaimable objects as used during a mark-and-sweep garbage | |
4604 | +collector pass. Currently only @code{type_mark_used} marker is supported. | |
4605 | +@end deftypefun | |
4606 | + | |
4607 | @deftypefun void test_notification (int @var{somearg}) | |
4608 | This observer is used for internal testing. Do not use. | |
4609 | See testsuite/gdb.gdb/observer.exp. | |
3a58abaf | 4610 | diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c |
7566401a | 4611 | index 668c434..c29c3a5 100644 |
3a58abaf AM |
4612 | --- a/gdb/dwarf2-frame.c |
4613 | +++ b/gdb/dwarf2-frame.c | |
4614 | @@ -38,6 +38,7 @@ | |
4615 | ||
4616 | #include "complaints.h" | |
4617 | #include "dwarf2-frame.h" | |
4618 | +#include "addrmap.h" | |
4619 | ||
4620 | struct comp_unit; | |
4621 | ||
7566401a | 4622 | @@ -1574,6 +1575,14 @@ dwarf2_frame_find_fde (CORE_ADDR *pc) |
3a58abaf | 4623 | CORE_ADDR offset; |
7566401a | 4624 | CORE_ADDR seek_pc; |
3a58abaf AM |
4625 | |
4626 | + if (objfile->quick_addrmap) | |
4627 | + { | |
4628 | + if (!addrmap_find (objfile->quick_addrmap, *pc)) | |
4629 | + continue; | |
4630 | + } | |
4631 | + /* FIXME: Read-in only .debug_frame/.eh_frame without .debug_info? */ | |
4632 | + require_partial_symbols (objfile); | |
4633 | + | |
7566401a ER |
4634 | fde_table = objfile_data (objfile, dwarf2_frame_objfile_data); |
4635 | if (fde_table == NULL) | |
3a58abaf AM |
4636 | continue; |
4637 | diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c | |
7566401a | 4638 | index 46bc9d7..e675575 100644 |
3a58abaf AM |
4639 | --- a/gdb/dwarf2expr.c |
4640 | +++ b/gdb/dwarf2expr.c | |
7566401a | 4641 | @@ -848,6 +848,13 @@ execute_stack_op (struct dwarf_expr_context *ctx, |
3a58abaf AM |
4642 | ctx->initialized = 0; |
4643 | goto no_push; | |
4644 | ||
4645 | + case DW_OP_push_object_address: | |
4646 | + if (ctx->get_object_address == NULL) | |
4647 | + error (_("DWARF-2 expression error: DW_OP_push_object_address must " | |
4648 | + "have a value to push.")); | |
4649 | + result = (ctx->get_object_address) (ctx->baton); | |
4650 | + break; | |
4651 | + | |
4652 | default: | |
4653 | error (_("Unhandled dwarf expression opcode 0x%x"), op); | |
4654 | } | |
4655 | diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h | |
7566401a | 4656 | index a9a8a05..d449012 100644 |
3a58abaf AM |
4657 | --- a/gdb/dwarf2expr.h |
4658 | +++ b/gdb/dwarf2expr.h | |
7566401a | 4659 | @@ -102,10 +102,10 @@ struct dwarf_expr_context |
3a58abaf AM |
4660 | The result must be live until the current expression evaluation |
4661 | is complete. */ | |
4662 | unsigned char *(*get_subr) (void *baton, off_t offset, size_t *length); | |
4663 | +#endif | |
4664 | ||
4665 | /* Return the `object address' for DW_OP_push_object_address. */ | |
4666 | CORE_ADDR (*get_object_address) (void *baton); | |
4667 | -#endif | |
4668 | ||
4669 | /* The current depth of dwarf expression recursion, via DW_OP_call*, | |
4670 | DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum | |
4671 | diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c | |
7566401a | 4672 | index 3a81202..85f4487 100644 |
3a58abaf AM |
4673 | --- a/gdb/dwarf2loc.c |
4674 | +++ b/gdb/dwarf2loc.c | |
7566401a | 4675 | @@ -116,6 +116,9 @@ struct dwarf_expr_baton |
3a58abaf AM |
4676 | { |
4677 | struct frame_info *frame; | |
4678 | struct objfile *objfile; | |
4679 | + /* From DW_TAG_variable's DW_AT_location (not DW_TAG_type's | |
4680 | + DW_AT_data_location) for DW_OP_push_object_address. */ | |
4681 | + CORE_ADDR object_address; | |
4682 | }; | |
4683 | ||
4684 | /* Helper functions for dwarf2_evaluate_loc_desc. */ | |
7566401a | 4685 | @@ -177,22 +180,33 @@ dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length) |
3a58abaf AM |
4686 | *start = find_location_expression (symbaton, length, |
4687 | get_frame_address_in_block (frame)); | |
4688 | } | |
4689 | - else | |
7566401a | 4690 | + else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_locexpr_funcs) |
3a58abaf AM |
4691 | { |
4692 | struct dwarf2_locexpr_baton *symbaton; | |
4693 | + | |
4694 | symbaton = SYMBOL_LOCATION_BATON (framefunc); | |
4695 | - if (symbaton != NULL) | |
4696 | - { | |
4697 | - *length = symbaton->size; | |
4698 | - *start = symbaton->data; | |
4699 | - } | |
4700 | - else | |
4701 | - *start = NULL; | |
4702 | + gdb_assert (symbaton != NULL); | |
4703 | + *start = symbaton->data; | |
4704 | + *length = symbaton->size; | |
7566401a ER |
4705 | } |
4706 | + else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_missing_funcs) | |
3a58abaf AM |
4707 | + { |
4708 | + struct dwarf2_locexpr_baton *symbaton; | |
4709 | + | |
4710 | + symbaton = SYMBOL_LOCATION_BATON (framefunc); | |
4711 | + gdb_assert (symbaton == NULL); | |
4712 | + *start = NULL; | |
4713 | + *length = 0; /* unused */ | |
7566401a | 4714 | + } |
3a58abaf AM |
4715 | + else |
4716 | + internal_error (__FILE__, __LINE__, | |
7566401a ER |
4717 | + _("Unsupported SYMBOL_COMPUTED_OPS %p for \"%s\""), |
4718 | + SYMBOL_COMPUTED_OPS (framefunc), | |
4719 | + SYMBOL_PRINT_NAME (framefunc)); | |
3a58abaf AM |
4720 | |
4721 | if (*start == NULL) | |
4722 | error (_("Could not find the frame base for \"%s\"."), | |
4723 | - SYMBOL_NATURAL_NAME (framefunc)); | |
4724 | + SYMBOL_PRINT_NAME (framefunc)); | |
4725 | } | |
4726 | ||
7566401a ER |
4727 | /* Helper function for dwarf2_evaluate_loc_desc. Computes the CFA for |
4728 | @@ -215,6 +229,129 @@ dwarf_expr_tls_address (void *baton, CORE_ADDR offset) | |
3a58abaf AM |
4729 | return target_translate_tls_address (debaton->objfile, offset); |
4730 | } | |
4731 | ||
4732 | +static CORE_ADDR | |
4733 | +dwarf_expr_object_address (void *baton) | |
4734 | +{ | |
4735 | + struct dwarf_expr_baton *debaton = baton; | |
4736 | + | |
4737 | + /* The message is suppressed in DWARF_BLOCK_EXEC. */ | |
4738 | + if (debaton->object_address == 0) | |
4739 | + error (_("Cannot resolve DW_OP_push_object_address for a missing object")); | |
4740 | + | |
4741 | + return debaton->object_address; | |
4742 | +} | |
4743 | + | |
4744 | +/* Address of the variable we are currently referring to. It is set from | |
4745 | + DW_TAG_variable's DW_AT_location (not DW_TAG_type's DW_AT_data_location) for | |
4746 | + DW_OP_push_object_address. */ | |
4747 | + | |
4748 | +static CORE_ADDR object_address; | |
4749 | + | |
4750 | +/* Callers use object_address_set while their callers use the result set so we | |
4751 | + cannot run the cleanup at the local block of our direct caller. Still we | |
4752 | + should reset OBJECT_ADDRESS at least for the next GDB command. */ | |
4753 | + | |
4754 | +static void | |
4755 | +object_address_cleanup (void *prev_save_voidp) | |
4756 | +{ | |
4757 | + CORE_ADDR *prev_save = prev_save_voidp; | |
4758 | + | |
4759 | + object_address = *prev_save; | |
4760 | + xfree (prev_save); | |
4761 | +} | |
4762 | + | |
4763 | +/* Set the base address - DW_AT_location - of a variable. It is being later | |
4764 | + used to derive other object addresses by DW_OP_push_object_address. | |
4765 | + | |
4766 | + It would be useful to sanity check ADDRESS - such as for some objects with | |
7566401a | 4767 | + unset value_raw_address - but some valid addresses may be zero (such as first |
3a58abaf AM |
4768 | + objects in relocatable .o files). */ |
4769 | + | |
4770 | +void | |
4771 | +object_address_set (CORE_ADDR address) | |
4772 | +{ | |
4773 | + CORE_ADDR *prev_save; | |
4774 | + | |
4775 | + prev_save = xmalloc (sizeof *prev_save); | |
4776 | + *prev_save = object_address; | |
4777 | + make_cleanup (object_address_cleanup, prev_save); | |
4778 | + | |
4779 | + object_address = address; | |
4780 | +} | |
4781 | + | |
4782 | +/* Evaluate DWARF expression at DATA ... DATA + SIZE with its result readable | |
4783 | + by dwarf_expr_fetch (RETVAL, 0). FRAME parameter can be NULL to call | |
4784 | + get_selected_frame to find it. Returned dwarf_expr_context freeing is | |
4785 | + pushed on the cleanup chain. */ | |
4786 | + | |
4787 | +static struct dwarf_expr_context * | |
4788 | +dwarf_expr_prep_ctx (struct frame_info *frame, gdb_byte *data, | |
4789 | + unsigned short size, struct dwarf2_per_cu_data *per_cu) | |
4790 | +{ | |
4791 | + struct dwarf_expr_context *ctx; | |
4792 | + struct dwarf_expr_baton baton; | |
4793 | + | |
4794 | + if (!frame) | |
4795 | + frame = get_selected_frame (NULL); | |
4796 | + | |
4797 | + baton.frame = frame; | |
4798 | + baton.objfile = dwarf2_per_cu_objfile (per_cu); | |
4799 | + baton.object_address = object_address; | |
4800 | + | |
4801 | + ctx = new_dwarf_expr_context (); | |
7566401a ER |
4802 | + make_cleanup_free_dwarf_expr_context (ctx); |
4803 | + | |
3a58abaf AM |
4804 | + ctx->gdbarch = get_objfile_arch (baton.objfile); |
4805 | + ctx->addr_size = dwarf2_per_cu_addr_size (per_cu); | |
4806 | + ctx->baton = &baton; | |
4807 | + ctx->read_reg = dwarf_expr_read_reg; | |
4808 | + ctx->read_mem = dwarf_expr_read_mem; | |
4809 | + ctx->get_frame_base = dwarf_expr_frame_base; | |
7566401a | 4810 | + ctx->get_frame_cfa = dwarf_expr_frame_cfa; |
3a58abaf AM |
4811 | + ctx->get_tls_address = dwarf_expr_tls_address; |
4812 | + ctx->get_object_address = dwarf_expr_object_address; | |
4813 | + | |
3a58abaf AM |
4814 | + dwarf_expr_eval (ctx, data, size); |
4815 | + | |
4816 | + /* It was used only during dwarf_expr_eval. */ | |
4817 | + ctx->baton = NULL; | |
4818 | + | |
4819 | + return ctx; | |
4820 | +} | |
4821 | + | |
4822 | +/* Evaluate DWARF expression at DLBATON expecting it produces exactly one | |
4823 | + CORE_ADDR result on the DWARF stack stack. */ | |
4824 | + | |
4825 | +CORE_ADDR | |
4826 | +dwarf_locexpr_baton_eval (struct dwarf2_locexpr_baton *dlbaton) | |
4827 | +{ | |
4828 | + struct dwarf_expr_context *ctx; | |
4829 | + CORE_ADDR retval; | |
4830 | + struct cleanup *back_to = make_cleanup (null_cleanup, 0); | |
4831 | + | |
4832 | + ctx = dwarf_expr_prep_ctx (NULL, dlbaton->data, dlbaton->size, | |
4833 | + dlbaton->per_cu); | |
4834 | + if (ctx->num_pieces > 0) | |
4835 | + error (_("DW_OP_*piece is unsupported for DW_FORM_block")); | |
3a58abaf AM |
4836 | + |
4837 | + retval = dwarf_expr_fetch (ctx, 0); | |
4838 | + | |
7566401a ER |
4839 | + if (ctx->location == DWARF_VALUE_REGISTER) |
4840 | + { | |
4841 | + /* Inlined dwarf_expr_read_reg as we no longer have the baton. */ | |
4842 | + | |
4843 | + int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (ctx->gdbarch, retval); | |
4844 | + struct type *type = builtin_type (ctx->gdbarch)->builtin_data_ptr; | |
4845 | + struct frame_info *frame = get_selected_frame (NULL); | |
4846 | + | |
4847 | + retval = address_from_register (type, gdb_regnum, frame); | |
4848 | + } | |
4849 | + | |
3a58abaf AM |
4850 | + do_cleanups (back_to); |
4851 | + | |
4852 | + return retval; | |
4853 | +} | |
4854 | + | |
7566401a ER |
4855 | struct piece_closure |
4856 | { | |
4857 | /* The number of pieces used to describe this variable. */ | |
4858 | @@ -382,9 +519,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, | |
3a58abaf AM |
4859 | struct dwarf2_per_cu_data *per_cu) |
4860 | { | |
4861 | struct value *retval; | |
4862 | - struct dwarf_expr_baton baton; | |
4863 | struct dwarf_expr_context *ctx; | |
7566401a ER |
4864 | - struct cleanup *old_chain; |
4865 | + struct cleanup *old_chain = make_cleanup (null_cleanup, 0); | |
3a58abaf AM |
4866 | |
4867 | if (size == 0) | |
4868 | { | |
7566401a | 4869 | @@ -394,22 +530,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, |
3a58abaf AM |
4870 | return retval; |
4871 | } | |
4872 | ||
4873 | - baton.frame = frame; | |
4874 | - baton.objfile = dwarf2_per_cu_objfile (per_cu); | |
4875 | + ctx = dwarf_expr_prep_ctx (frame, data, size, per_cu); | |
4876 | ||
4877 | - ctx = new_dwarf_expr_context (); | |
7566401a ER |
4878 | - old_chain = make_cleanup_free_dwarf_expr_context (ctx); |
4879 | - | |
3a58abaf AM |
4880 | - ctx->gdbarch = get_objfile_arch (baton.objfile); |
4881 | - ctx->addr_size = dwarf2_per_cu_addr_size (per_cu); | |
4882 | - ctx->baton = &baton; | |
4883 | - ctx->read_reg = dwarf_expr_read_reg; | |
4884 | - ctx->read_mem = dwarf_expr_read_mem; | |
4885 | - ctx->get_frame_base = dwarf_expr_frame_base; | |
7566401a | 4886 | - ctx->get_frame_cfa = dwarf_expr_frame_cfa; |
3a58abaf AM |
4887 | - ctx->get_tls_address = dwarf_expr_tls_address; |
4888 | - | |
4889 | - dwarf_expr_eval (ctx, data, size); | |
4890 | if (ctx->num_pieces > 0) | |
4891 | { | |
7566401a ER |
4892 | struct piece_closure *c; |
4893 | @@ -439,6 +561,11 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, | |
4894 | CORE_ADDR address = dwarf_expr_fetch (ctx, 0); | |
4895 | int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); | |
4896 | ||
4897 | + /* object_address_set called here is required in ALLOCATE_VALUE's | |
4898 | + CHECK_TYPEDEF for the object's possible | |
4899 | + DW_OP_push_object_address. */ | |
4900 | + object_address_set (address); | |
4901 | + | |
4902 | retval = allocate_value (SYMBOL_TYPE (var)); | |
4903 | VALUE_LVAL (retval) = lval_memory; | |
4904 | set_value_lazy (retval, 1); | |
4905 | @@ -815,7 +942,7 @@ static int | |
3a58abaf AM |
4906 | loclist_describe_location (struct symbol *symbol, struct ui_file *stream) |
4907 | { | |
4908 | /* FIXME: Could print the entire list of locations. */ | |
4909 | - fprintf_filtered (stream, "a variable with multiple locations"); | |
4910 | + fprintf_filtered (stream, _("a variable with multiple locations")); | |
4911 | return 1; | |
4912 | } | |
4913 | ||
7566401a | 4914 | @@ -831,16 +958,56 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, |
3a58abaf AM |
4915 | |
4916 | data = find_location_expression (dlbaton, &size, ax->scope); | |
4917 | if (data == NULL) | |
4918 | - error (_("Variable \"%s\" is not available."), SYMBOL_NATURAL_NAME (symbol)); | |
4919 | + error (_("Variable \"%s\" is not available."), SYMBOL_PRINT_NAME (symbol)); | |
4920 | ||
7566401a | 4921 | dwarf2_tracepoint_var_ref (symbol, gdbarch, ax, value, data, size); |
3a58abaf AM |
4922 | } |
4923 | ||
4924 | -/* The set of location functions used with the DWARF-2 expression | |
4925 | - evaluator and location lists. */ | |
4926 | +/* The set of location functions used with the DWARF-2 location lists. */ | |
7566401a | 4927 | const struct symbol_computed_ops dwarf2_loclist_funcs = { |
3a58abaf AM |
4928 | loclist_read_variable, |
4929 | loclist_read_needs_frame, | |
4930 | loclist_describe_location, | |
4931 | loclist_tracepoint_var_ref | |
4932 | }; | |
4933 | + | |
4934 | +static struct value * | |
4935 | +missing_read_variable (struct symbol *symbol, struct frame_info *frame) | |
4936 | +{ | |
4937 | + struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); | |
4938 | + | |
4939 | + gdb_assert (dlbaton == NULL); | |
4940 | + error (_("Unable to resolve variable \"%s\""), SYMBOL_PRINT_NAME (symbol)); | |
4941 | +} | |
4942 | + | |
4943 | +static int | |
4944 | +missing_read_needs_frame (struct symbol *symbol) | |
4945 | +{ | |
4946 | + return 0; | |
4947 | +} | |
4948 | + | |
4949 | +static int | |
4950 | +missing_describe_location (struct symbol *symbol, struct ui_file *stream) | |
4951 | +{ | |
4952 | + fprintf_filtered (stream, _("a variable we are unable to resolve")); | |
4953 | + return 1; | |
4954 | +} | |
4955 | + | |
4956 | +static void | |
7566401a ER |
4957 | +missing_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, |
4958 | + struct agent_expr *ax, struct axs_value *value) | |
3a58abaf AM |
4959 | +{ |
4960 | + struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); | |
4961 | + | |
4962 | + gdb_assert (dlbaton == NULL); | |
4963 | + error (_("Unable to resolve variable \"%s\""), SYMBOL_PRINT_NAME (symbol)); | |
4964 | +} | |
4965 | + | |
4966 | +/* The set of location functions used with the DWARF-2 evaluator when we are | |
4967 | + unable to resolve the symbols. */ | |
7566401a | 4968 | +const struct symbol_computed_ops dwarf2_missing_funcs = { |
3a58abaf AM |
4969 | + missing_read_variable, |
4970 | + missing_read_needs_frame, | |
4971 | + missing_describe_location, | |
4972 | + missing_tracepoint_var_ref | |
4973 | +}; | |
4974 | diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h | |
7566401a | 4975 | index 0bfcfca..01018d6 100644 |
3a58abaf AM |
4976 | --- a/gdb/dwarf2loc.h |
4977 | +++ b/gdb/dwarf2loc.h | |
4978 | @@ -71,5 +71,11 @@ struct dwarf2_loclist_baton | |
4979 | ||
7566401a ER |
4980 | extern const struct symbol_computed_ops dwarf2_locexpr_funcs; |
4981 | extern const struct symbol_computed_ops dwarf2_loclist_funcs; | |
4982 | +extern const struct symbol_computed_ops dwarf2_missing_funcs; | |
3a58abaf AM |
4983 | + |
4984 | +extern void object_address_set (CORE_ADDR address); | |
4985 | + | |
4986 | +extern CORE_ADDR dwarf_locexpr_baton_eval | |
4987 | + (struct dwarf2_locexpr_baton *dlbaton); | |
4988 | ||
4989 | #endif /* dwarf2loc.h */ | |
4990 | diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c | |
ab050a48 | 4991 | index 4cce36b..fb0a693 100644 |
3a58abaf AM |
4992 | --- a/gdb/dwarf2read.c |
4993 | +++ b/gdb/dwarf2read.c | |
7566401a | 4994 | @@ -48,6 +48,12 @@ |
3a58abaf | 4995 | #include "gdbcmd.h" |
7566401a | 4996 | #include "block.h" |
3a58abaf AM |
4997 | #include "addrmap.h" |
4998 | +#include "f-lang.h" | |
4999 | +#include "c-lang.h" | |
5000 | +#include "typeprint.h" | |
7566401a ER |
5001 | +#include "jv-lang.h" |
5002 | +#include "vec.h" | |
5003 | +#include "block.h" | |
3a58abaf AM |
5004 | |
5005 | #include <fcntl.h> | |
5006 | #include "gdb_string.h" | |
7566401a | 5007 | @@ -93,7 +99,7 @@ typedef struct pubnames_header |
3a58abaf AM |
5008 | _PUBNAMES_HEADER; |
5009 | #define _ACTUAL_PUBNAMES_HEADER_SIZE 13 | |
5010 | ||
5011 | -/* .debug_pubnames header | |
5012 | +/* .debug_aranges header | |
5013 | Because of alignment constraints, this structure has padding and cannot | |
5014 | be mapped directly onto the beginning of the .debug_info section. */ | |
5015 | typedef struct aranges_header | |
7566401a ER |
5016 | @@ -150,7 +156,10 @@ struct dwarf2_section_info |
5017 | asection *asection; | |
5018 | gdb_byte *buffer; | |
5019 | bfd_size_type size; | |
5020 | - int was_mmapped; | |
5021 | + /* A function to call to deallocate BUFFER. If NULL, no | |
5022 | + deallocation is needed. A pointer to this structure is passed as | |
5023 | + the only argument. */ | |
5024 | + void (*destructor) (struct dwarf2_section_info *); | |
5025 | }; | |
3a58abaf | 5026 | |
7566401a ER |
5027 | struct dwarf2_per_objfile |
5028 | @@ -336,6 +345,19 @@ struct dwarf2_cu | |
5029 | ||
5030 | /* Field `ranges_offset' is filled in; flag as the value may be zero. */ | |
5031 | unsigned int has_ranges_offset : 1; | |
5032 | + | |
5033 | + /* Fields are valid according to the LANGUAGE field. */ | |
5034 | + union | |
5035 | + { | |
5036 | + /* language_fortran */ | |
5037 | + struct | |
5038 | + { | |
5039 | + /* Module names imported to the block being currently read in. */ | |
5040 | + struct fortran_using *use; | |
5041 | + } | |
5042 | + fortran; | |
5043 | + } | |
5044 | + language_specific; | |
3a58abaf AM |
5045 | }; |
5046 | ||
5047 | /* Persistent data held for a compilation unit, even when not | |
7566401a | 5048 | @@ -495,8 +517,7 @@ struct partial_die_info |
3a58abaf AM |
5049 | unsigned int has_byte_size : 1; |
5050 | ||
5051 | /* The name of this DIE. Normally the value of DW_AT_name, but | |
5052 | - sometimes DW_TAG_MIPS_linkage_name or a string computed in some | |
5053 | - other fashion. */ | |
5054 | + sometimes a default name for unnamed DIEs. */ | |
5055 | char *name; | |
7566401a | 5056 | char *dirname; |
3a58abaf | 5057 | |
7566401a ER |
5058 | @@ -689,6 +710,11 @@ struct field_info |
5059 | int nfnfields; | |
3a58abaf AM |
5060 | }; |
5061 | ||
7566401a ER |
5062 | +/* A vector used during linkage name generation. */ |
5063 | +typedef struct die_info *die_info_p; | |
5064 | +DEF_VEC_P (die_info_p); | |
5065 | +static VEC(die_info_p) *die_list; | |
3a58abaf | 5066 | + |
7566401a ER |
5067 | /* One item on the queue of compilation units to read in full symbols |
5068 | for. */ | |
5069 | struct dwarf2_queue_item | |
5070 | @@ -800,7 +826,10 @@ static void scan_partial_symbols (struct partial_die_info *, | |
3a58abaf AM |
5071 | static void add_partial_symbol (struct partial_die_info *, |
5072 | struct dwarf2_cu *); | |
5073 | ||
7566401a | 5074 | -static int pdi_needs_namespace (enum dwarf_tag tag); |
3a58abaf AM |
5075 | +static gdb_byte *read_comp_unit_head (struct comp_unit_head *, gdb_byte *, |
5076 | + bfd *); | |
5077 | + | |
7566401a | 5078 | +static int die_needs_namespace (struct die_info *, struct dwarf2_cu *); |
3a58abaf AM |
5079 | |
5080 | static void add_partial_namespace (struct partial_die_info *pdi, | |
7566401a ER |
5081 | CORE_ADDR *lowpc, CORE_ADDR *highpc, |
5082 | @@ -825,6 +854,10 @@ static void dwarf2_psymtab_to_symtab (struct partial_symtab *); | |
3a58abaf AM |
5083 | |
5084 | static void psymtab_to_symtab_1 (struct partial_symtab *); | |
5085 | ||
7566401a ER |
5086 | +static void dwarf2_read_section_1 (struct objfile *objfile, |
5087 | + struct obstack *obstack, | |
5088 | + struct dwarf2_section_info *info); | |
3a58abaf | 5089 | + |
3a58abaf | 5090 | static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu); |
7566401a ER |
5091 | |
5092 | static void dwarf2_free_abbrev_table (void *); | |
5093 | @@ -945,6 +978,11 @@ static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *); | |
5094 | ||
5095 | static struct type *read_type_die (struct die_info *, struct dwarf2_cu *); | |
5096 | ||
5097 | +static char *physname_prefix (struct die_info *die, struct dwarf2_cu *); | |
5098 | + | |
5099 | +static void physname_prefix_1 (struct ui_file *, struct die_info *, | |
5100 | + struct dwarf2_cu *); | |
5101 | + | |
5102 | static char *determine_prefix (struct die_info *die, struct dwarf2_cu *); | |
5103 | ||
5104 | static char *typename_concat (struct obstack *, | |
5105 | @@ -964,7 +1002,8 @@ static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *, | |
3a58abaf AM |
5106 | struct dwarf2_cu *, struct partial_symtab *); |
5107 | ||
5108 | static int dwarf2_get_pc_bounds (struct die_info *, | |
5109 | - CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *); | |
5110 | + CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *, | |
5111 | + struct partial_symtab *pst); | |
5112 | ||
5113 | static void get_scope_pc_bounds (struct die_info *, | |
5114 | CORE_ADDR *, CORE_ADDR *, | |
7566401a | 5115 | @@ -988,17 +1027,25 @@ static void dwarf2_attach_fn_fields_to_type (struct field_info *, |
3a58abaf | 5116 | |
7566401a ER |
5117 | static void process_structure_scope (struct die_info *, struct dwarf2_cu *); |
5118 | ||
5119 | -static const char *determine_class_name (struct die_info *die, | |
5120 | - struct dwarf2_cu *cu); | |
5121 | - | |
5122 | static void read_common_block (struct die_info *, struct dwarf2_cu *); | |
5123 | ||
5124 | static void read_namespace (struct die_info *die, struct dwarf2_cu *); | |
3a58abaf AM |
5125 | |
5126 | +static void read_import_statement (struct die_info *die, struct dwarf2_cu *); | |
7566401a ER |
5127 | + |
5128 | static void read_module (struct die_info *die, struct dwarf2_cu *cu); | |
5129 | ||
5130 | static void read_import_statement (struct die_info *die, struct dwarf2_cu *); | |
5131 | ||
5132 | +static struct type *read_module_type (struct die_info *die, | |
5133 | + struct dwarf2_cu *cu); | |
5134 | + | |
5135 | +static void read_fortran_imported_module (struct die_info *die, | |
5136 | + struct dwarf2_cu *cu); | |
5137 | + | |
5138 | +static void read_fortran_imported_declaration (struct die_info *die, | |
5139 | + struct dwarf2_cu *cu); | |
3a58abaf AM |
5140 | + |
5141 | static const char *namespace_name (struct die_info *die, | |
5142 | int *is_anonymous, struct dwarf2_cu *); | |
5143 | ||
7566401a | 5144 | @@ -1032,7 +1079,10 @@ static gdb_byte *read_full_die (const struct die_reader_specs *reader, |
3a58abaf | 5145 | |
7566401a | 5146 | static void process_die (struct die_info *, struct dwarf2_cu *); |
3a58abaf | 5147 | |
7566401a ER |
5148 | -static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *); |
5149 | +static char *dwarf2_physname (struct die_info *, struct dwarf2_cu *); | |
3a58abaf | 5150 | + |
7566401a ER |
5151 | +static char *fortran_module_linkage_name (struct die_info *die, |
5152 | + struct dwarf2_cu *cu); | |
3a58abaf | 5153 | |
7566401a ER |
5154 | static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *, |
5155 | struct obstack *); | |
5156 | @@ -1076,7 +1126,7 @@ static int is_ref_attr (struct attribute *); | |
3a58abaf AM |
5157 | |
5158 | static unsigned int dwarf2_get_ref_die_offset (struct attribute *); | |
5159 | ||
5160 | -static int dwarf2_get_attr_constant_value (struct attribute *, int); | |
7566401a | 5161 | +static CORE_ADDR dwarf2_get_attr_constant_value (struct attribute *, CORE_ADDR); |
3a58abaf | 5162 | |
7566401a ER |
5163 | static struct die_info *follow_die_ref_or_sig (struct die_info *, |
5164 | struct attribute *, | |
5165 | @@ -1148,6 +1198,9 @@ static void age_cached_comp_units (void); | |
3a58abaf AM |
5166 | |
5167 | static void free_one_cached_comp_unit (void *); | |
5168 | ||
5169 | +static void fetch_die_type_attrs (struct die_info *die, struct type *type, | |
5170 | + struct dwarf2_cu *cu); | |
5171 | + | |
5172 | static struct type *set_die_type (struct die_info *, struct type *, | |
5173 | struct dwarf2_cu *); | |
5174 | ||
7566401a | 5175 | @@ -1167,22 +1220,31 @@ static void dwarf2_clear_marks (struct dwarf2_per_cu_data *); |
3a58abaf AM |
5176 | |
5177 | static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu); | |
5178 | ||
7566401a ER |
5179 | +static void destroy_section (struct dwarf2_section_info *info); |
5180 | + | |
3a58abaf AM |
5181 | +static struct dwarf2_locexpr_baton *dwarf2_attr_to_locexpr_baton |
5182 | + (struct attribute *attr, struct dwarf2_cu *cu); | |
5183 | + | |
5184 | /* Try to locate the sections we need for DWARF 2 debugging | |
5185 | information and return true if we have enough to do something. */ | |
5186 | ||
5187 | int | |
5188 | dwarf2_has_info (struct objfile *objfile) | |
5189 | { | |
5190 | - struct dwarf2_per_objfile *data; | |
7566401a ER |
5191 | - |
5192 | - /* Initialize per-objfile state. */ | |
3a58abaf AM |
5193 | - data = obstack_alloc (&objfile->objfile_obstack, sizeof (*data)); |
5194 | - memset (data, 0, sizeof (*data)); | |
5195 | - set_objfile_data (objfile, dwarf2_objfile_data_key, data); | |
5196 | - dwarf2_per_objfile = data; | |
5197 | + dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key); | |
5198 | + if (!dwarf2_per_objfile) | |
5199 | + { | |
7566401a | 5200 | + /* Initialize per-objfile state. */ |
3a58abaf AM |
5201 | + struct dwarf2_per_objfile *data |
5202 | + = obstack_alloc (&objfile->objfile_obstack, sizeof (*data)); | |
5203 | + memset (data, 0, sizeof (*data)); | |
5204 | + set_objfile_data (objfile, dwarf2_objfile_data_key, data); | |
5205 | + dwarf2_per_objfile = data; | |
3a58abaf | 5206 | |
3a58abaf | 5207 | - bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL); |
7566401a ER |
5208 | - return (data->info.asection != NULL && data->abbrev.asection != NULL); |
5209 | + bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL); | |
5210 | + } | |
5211 | + return (dwarf2_per_objfile->info.asection != NULL | |
5212 | + && dwarf2_per_objfile->abbrev.asection != NULL); | |
5213 | } | |
5214 | ||
5215 | /* When loading sections, we can either look for ".<name>", or for | |
5216 | @@ -1275,10 +1337,13 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr) | |
3a58abaf AM |
5217 | } |
5218 | ||
7566401a ER |
5219 | /* Decompress a section that was compressed using zlib. Store the |
5220 | - decompressed buffer, and its size, in OUTBUF and OUTSIZE. */ | |
5221 | + decompressed buffer, and its size, in OUTBUF and OUTSIZE. The | |
5222 | + result is allocated on OBSTACK; if OBSTACK is NULL, xmalloc is | |
5223 | + used. */ | |
3a58abaf AM |
5224 | |
5225 | static void | |
7566401a ER |
5226 | -zlib_decompress_section (struct objfile *objfile, asection *sectp, |
5227 | +zlib_decompress_section (struct objfile *objfile, struct obstack *obstack, | |
5228 | + asection *sectp, | |
5229 | gdb_byte **outbuf, bfd_size_type *outsize) | |
3a58abaf | 5230 | { |
7566401a ER |
5231 | bfd *abfd = objfile->obfd; |
5232 | @@ -1295,6 +1360,7 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp, | |
5233 | z_stream strm; | |
5234 | int rc; | |
5235 | int header_size = 12; | |
5236 | + struct cleanup *old = NULL; | |
5237 | ||
5238 | if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 | |
5239 | || bfd_bread (compressed_buffer, compressed_size, abfd) != compressed_size) | |
5240 | @@ -1324,8 +1390,13 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp, | |
5241 | strm.avail_in = compressed_size - header_size; | |
5242 | strm.next_in = (Bytef*) compressed_buffer + header_size; | |
5243 | strm.avail_out = uncompressed_size; | |
5244 | - uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack, | |
5245 | - uncompressed_size); | |
5246 | + if (obstack) | |
5247 | + uncompressed_buffer = obstack_alloc (obstack, uncompressed_size); | |
5248 | + else | |
5249 | + { | |
5250 | + uncompressed_buffer = xmalloc (uncompressed_size); | |
5251 | + old = make_cleanup (xfree, uncompressed_buffer); | |
5252 | + } | |
5253 | rc = inflateInit (&strm); | |
5254 | while (strm.avail_in > 0) | |
3a58abaf | 5255 | { |
7566401a ER |
5256 | @@ -1346,26 +1417,176 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp, |
5257 | error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"), | |
5258 | bfd_get_filename (abfd), rc); | |
5259 | ||
5260 | + if (old) | |
5261 | + discard_cleanups (old); | |
5262 | do_cleanups (cleanup); | |
5263 | *outbuf = uncompressed_buffer; | |
5264 | *outsize = uncompressed_size; | |
5265 | #endif | |
3a58abaf AM |
5266 | } |
5267 | ||
7566401a ER |
5268 | -/* Read the contents of the section SECTP from object file specified by |
5269 | - OBJFILE, store info about the section into INFO. | |
5270 | - If the section is compressed, uncompress it before returning. */ | |
5271 | +/* A cleanup that calls destroy_section. */ | |
5272 | ||
5273 | static void | |
5274 | -dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) | |
5275 | +destroy_section_cleanup (void *arg) | |
3a58abaf | 5276 | +{ |
7566401a | 5277 | + destroy_section (arg); |
3a58abaf AM |
5278 | +} |
5279 | + | |
5280 | +/* Read the .debug_aranges section and construct an address map. */ | |
5281 | + | |
5282 | +void | |
5283 | +dwarf2_create_quick_addrmap (struct objfile *objfile) | |
5284 | +{ | |
5285 | + char *aranges_buffer, *aranges_ptr; | |
5286 | + bfd *abfd = objfile->obfd; | |
5287 | + CORE_ADDR baseaddr; | |
5288 | + struct cleanup *old; | |
5289 | + struct obstack temp_obstack; | |
5290 | + struct addrmap *mutable_map; | |
5291 | + | |
7566401a | 5292 | + if (!dwarf2_per_objfile->aranges.asection) |
3a58abaf AM |
5293 | + return; |
5294 | + | |
5295 | + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); | |
5296 | + | |
7566401a ER |
5297 | + dwarf2_read_section_1 (objfile, NULL, &dwarf2_per_objfile->aranges); |
5298 | + aranges_buffer = dwarf2_per_objfile->aranges.buffer; | |
3a58abaf | 5299 | + aranges_ptr = aranges_buffer; |
7566401a | 5300 | + old = make_cleanup (destroy_section_cleanup, &dwarf2_per_objfile->aranges); |
3a58abaf AM |
5301 | + |
5302 | + obstack_init (&temp_obstack); | |
7566401a | 5303 | + make_cleanup_obstack_free (&temp_obstack); |
3a58abaf AM |
5304 | + mutable_map = addrmap_create_mutable (&temp_obstack); |
5305 | + | |
7566401a | 5306 | + while ((aranges_ptr - aranges_buffer) < dwarf2_per_objfile->aranges.size) |
3a58abaf AM |
5307 | + { |
5308 | + struct comp_unit_head cu_header; | |
5309 | + unsigned int bytes_read, segment_size, delta; | |
5310 | + LONGEST info_offset; | |
5311 | + struct dwarf2_cu cu; | |
7566401a | 5312 | + char *end_ptr; |
3a58abaf AM |
5313 | + |
5314 | + cu_header.initial_length_size = 0; | |
7566401a | 5315 | + end_ptr = aranges_ptr; |
3a58abaf | 5316 | + aranges_ptr = read_comp_unit_head (&cu_header, aranges_ptr, abfd); |
7566401a ER |
5317 | + end_ptr += cu_header.initial_length_size + cu_header.length; |
5318 | + | |
5319 | + /* Sanity check. */ | |
5320 | + if (end_ptr - aranges_ptr >= dwarf2_per_objfile->aranges.size) | |
5321 | + { | |
5322 | + do_cleanups (old); | |
5323 | + complaint (&symfile_complaints, | |
5324 | + _("aranges entry runs off end of `.debug_aranges' section, ignored")); | |
5325 | + return; | |
5326 | + } | |
5327 | + if (cu_header.addr_size == 0) | |
5328 | + { | |
5329 | + do_cleanups (old); | |
5330 | + complaint (&symfile_complaints, | |
5331 | + _("aranges entry has zero addr_size, ignored")); | |
5332 | + return; | |
5333 | + } | |
3a58abaf AM |
5334 | + |
5335 | + segment_size = read_1_byte (abfd, aranges_ptr); | |
5336 | + aranges_ptr += 1; | |
5337 | + | |
5338 | + /* Align the pointer to twice the pointer size. I didn't see | |
5339 | + this in the spec but it appears to be required. */ | |
5340 | + delta = (aranges_ptr - aranges_buffer) % (2 * cu_header.addr_size); | |
5341 | + delta = (2 * cu_header.addr_size - delta) % (2 * cu_header.addr_size); | |
5342 | + aranges_ptr += delta; | |
5343 | + | |
5344 | + memset (&cu, 0, sizeof (cu)); | |
5345 | + cu.header.addr_size = cu_header.addr_size; | |
5346 | + | |
5347 | + while (1) | |
5348 | + { | |
5349 | + CORE_ADDR address, length; | |
5350 | + | |
5351 | + address = read_address (abfd, aranges_ptr, &cu, &bytes_read); | |
5352 | + aranges_ptr += bytes_read; | |
5353 | + | |
5354 | + length = read_address (abfd, aranges_ptr, &cu, &bytes_read); | |
5355 | + aranges_ptr += bytes_read; | |
5356 | + | |
5357 | + if (address == 0 && length == 0) | |
5358 | + break; | |
5359 | + | |
7566401a ER |
5360 | + if (length == 0) |
5361 | + { | |
5362 | + do_cleanups (old); | |
5363 | + complaint (&symfile_complaints, | |
5364 | + _("aranges entry has zero length, ignored")); | |
5365 | + return; | |
5366 | + } | |
5367 | + | |
3a58abaf AM |
5368 | + address += baseaddr; |
5369 | + | |
7566401a ER |
5370 | + addrmap_set_empty (mutable_map, address, address + length - 1, |
5371 | + objfile); | |
3a58abaf | 5372 | + } |
3a58abaf | 5373 | + |
7566401a ER |
5374 | + /* Some older versions of GCC incorrectly started the arange |
5375 | + with a (0,0) pair. If we encounter any oddity while reading | |
5376 | + the section, just abandon the attempt; falling back to the | |
5377 | + slower code is always safe. */ | |
5378 | + if (aranges_ptr != end_ptr) | |
5379 | + { | |
5380 | + do_cleanups (old); | |
5381 | + complaint (&symfile_complaints, | |
5382 | + _("aranges entry ends early, ignored")); | |
5383 | + return; | |
5384 | + } | |
5385 | + } | |
5386 | + | |
5387 | + objfile->quick_addrmap = addrmap_create_fixed (mutable_map, | |
5388 | + &objfile->objfile_obstack); | |
3a58abaf AM |
5389 | + do_cleanups (old); |
5390 | +} | |
5391 | + | |
7566401a ER |
5392 | +/* Free a section buffer allocated with xmalloc. */ |
5393 | + | |
5394 | +static void | |
5395 | +xfree_section_buffer (struct dwarf2_section_info *info) | |
5396 | +{ | |
5397 | + xfree (info->buffer); | |
5398 | +} | |
5399 | + | |
5400 | +/* If section described by INFO was mmapped, munmap it now. */ | |
5401 | + | |
5402 | +static void | |
5403 | +munmap_section_buffer (struct dwarf2_section_info *info) | |
5404 | +{ | |
5405 | +#ifdef HAVE_MMAP | |
5406 | + intptr_t begin = (intptr_t) info->buffer; | |
5407 | + intptr_t map_begin = begin & ~(pagesize - 1); | |
5408 | + size_t map_length = info->size + begin - map_begin; | |
5409 | + gdb_assert (munmap ((void *) map_begin, map_length) == 0); | |
5410 | +#else | |
5411 | + /* Without HAVE_MMAP, we should never be here to begin with. */ | |
5412 | + gdb_assert (0); | |
5413 | +#endif | |
5414 | +} | |
5415 | + | |
5416 | +/* Read the contents of the section at OFFSET and of size SIZE from | |
5417 | + the object file specified by OBJFILE into OBSTACK and store it into | |
5418 | + INFO. If OBSTACK is NULL, xmalloc is used instead. If the section | |
5419 | + is compressed, uncompress it before returning. */ | |
3a58abaf | 5420 | + |
7566401a ER |
5421 | +static void |
5422 | +dwarf2_read_section_1 (struct objfile *objfile, | |
5423 | + struct obstack *obstack, | |
5424 | + struct dwarf2_section_info *info) | |
5425 | { | |
5426 | bfd *abfd = objfile->obfd; | |
5427 | asection *sectp = info->asection; | |
5428 | gdb_byte *buf, *retbuf; | |
5429 | unsigned char header[4]; | |
5430 | + struct cleanup *old = NULL; | |
3a58abaf | 5431 | |
7566401a ER |
5432 | info->buffer = NULL; |
5433 | - info->was_mmapped = 0; | |
5434 | + info->destructor = 0; | |
3a58abaf | 5435 | |
7566401a ER |
5436 | if (info->asection == NULL || info->size == 0) |
5437 | return; | |
5438 | @@ -1378,7 +1599,7 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) | |
5439 | /* Upon decompression, update the buffer and its size. */ | |
5440 | if (strncmp (header, "ZLIB", sizeof (header)) == 0) | |
5441 | { | |
5442 | - zlib_decompress_section (objfile, sectp, &info->buffer, | |
5443 | + zlib_decompress_section (objfile, obstack, sectp, &info->buffer, | |
5444 | &info->size); | |
5445 | return; | |
5446 | } | |
5447 | @@ -1401,7 +1622,7 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) | |
3a58abaf | 5448 | |
7566401a ER |
5449 | if (retbuf != MAP_FAILED) |
5450 | { | |
5451 | - info->was_mmapped = 1; | |
5452 | + info->destructor = munmap_section_buffer; | |
5453 | info->buffer = retbuf + (sectp->filepos & (pagesize - 1)) ; | |
5454 | return; | |
5455 | } | |
5456 | @@ -1409,8 +1630,15 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) | |
5457 | #endif | |
3a58abaf | 5458 | |
7566401a ER |
5459 | /* If we get here, we are a normal, not-compressed section. */ |
5460 | - info->buffer = buf | |
5461 | - = obstack_alloc (&objfile->objfile_obstack, info->size); | |
5462 | + if (obstack) | |
5463 | + buf = obstack_alloc (obstack, info->size); | |
5464 | + else | |
3a58abaf | 5465 | + { |
7566401a ER |
5466 | + buf = xmalloc (info->size); |
5467 | + old = make_cleanup (xfree, buf); | |
5468 | + info->destructor = xfree_section_buffer; | |
3a58abaf | 5469 | + } |
7566401a ER |
5470 | + info->buffer = buf; |
5471 | ||
5472 | /* When debugging .o files, we may need to apply relocations; see | |
5473 | http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html . | |
5474 | @@ -1419,6 +1647,8 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) | |
5475 | retbuf = symfile_relocate_debug_section (abfd, sectp, buf); | |
5476 | if (retbuf != NULL) | |
5477 | { | |
5478 | + if (old) | |
5479 | + discard_cleanups (old); | |
5480 | info->buffer = retbuf; | |
5481 | return; | |
5482 | } | |
5483 | @@ -1427,6 +1657,19 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) | |
5484 | || bfd_bread (buf, info->size, abfd) != info->size) | |
5485 | error (_("Dwarf Error: Can't read DWARF data from '%s'"), | |
5486 | bfd_get_filename (abfd)); | |
5487 | + | |
5488 | + if (old) | |
5489 | + discard_cleanups (old); | |
5490 | +} | |
5491 | + | |
5492 | +/* Read the contents of the section SECTP from object file specified by | |
5493 | + OBJFILE, store info about the section into INFO. | |
5494 | + If the section is compressed, uncompress it before returning. */ | |
5495 | + | |
5496 | +static void | |
5497 | +dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) | |
5498 | +{ | |
5499 | + dwarf2_read_section_1 (objfile, &objfile->objfile_obstack, info); | |
5500 | } | |
3a58abaf | 5501 | |
7566401a ER |
5502 | /* Fill in SECTP, BUFP and SIZEP with section info, given OBJFILE and |
5503 | @@ -1810,6 +2053,37 @@ lookup_signatured_type (struct objfile *objfile, ULONGEST sig) | |
5504 | return entry; | |
3a58abaf AM |
5505 | } |
5506 | ||
5507 | +/* Find the base address of the compilation unit for range lists and | |
5508 | + location lists. It will normally be specified by DW_AT_low_pc. | |
5509 | + In DWARF-3 draft 4, the base address could be overridden by | |
5510 | + DW_AT_entry_pc. It's been removed, but GCC still uses this for | |
5511 | + compilation units with discontinuous ranges. */ | |
5512 | + | |
5513 | +static void | |
5514 | +dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu) | |
5515 | +{ | |
5516 | + struct attribute *attr; | |
5517 | + | |
5518 | + cu->base_known = 0; | |
5519 | + cu->base_address = 0; | |
5520 | + | |
5521 | + attr = dwarf2_attr (die, DW_AT_entry_pc, cu); | |
5522 | + if (attr) | |
5523 | + { | |
5524 | + cu->base_address = DW_ADDR (attr); | |
5525 | + cu->base_known = 1; | |
5526 | + } | |
5527 | + else | |
5528 | + { | |
5529 | + attr = dwarf2_attr (die, DW_AT_low_pc, cu); | |
5530 | + if (attr) | |
5531 | + { | |
5532 | + cu->base_address = DW_ADDR (attr); | |
5533 | + cu->base_known = 1; | |
5534 | + } | |
5535 | + } | |
5536 | +} | |
7566401a ER |
5537 | + |
5538 | /* Subroutine of process_type_comp_unit and dwarf2_build_psymtabs_hard | |
5539 | to combine the common parts. | |
5540 | Process a compilation unit for a psymtab. | |
5541 | @@ -2359,7 +2633,7 @@ partial_die_parent_scope (struct partial_die_info *pdi, | |
3a58abaf AM |
5542 | ignoring them. */ |
5543 | complaint (&symfile_complaints, | |
5544 | _("unhandled containing DIE tag %d for DIE at %d"), | |
5545 | - parent->tag, pdi->offset); | |
5546 | + parent->tag, real_pdi->offset); | |
5547 | parent->scope = grandparent_scope; | |
5548 | } | |
5549 | ||
7566401a | 5550 | @@ -2374,12 +2648,22 @@ partial_die_full_name (struct partial_die_info *pdi, |
3a58abaf AM |
5551 | struct dwarf2_cu *cu) |
5552 | { | |
5553 | char *parent_scope; | |
5554 | + struct partial_die_info *real_pdi; | |
5555 | ||
5556 | - parent_scope = partial_die_parent_scope (pdi, cu); | |
5557 | - if (parent_scope == NULL) | |
5558 | - return NULL; | |
5559 | - else | |
5560 | + /* We need to look at our parent DIE; if we have a DW_AT_specification, | |
5561 | + then this means the parent of the specification DIE. | |
5562 | + partial_die_parent_scope does this loop also, but we do it here | |
5563 | + since we need to examine real_pdi->parent ourselves. */ | |
5564 | + | |
5565 | + real_pdi = pdi; | |
5566 | + while (real_pdi->has_specification) | |
5567 | + real_pdi = find_partial_die (real_pdi->spec_offset, cu); | |
5568 | + | |
5569 | + parent_scope = partial_die_parent_scope (real_pdi, cu); | |
5570 | + if (parent_scope != NULL) | |
5571 | return typename_concat (NULL, parent_scope, pdi->name, cu); | |
5572 | + | |
3a58abaf AM |
5573 | + return NULL; |
5574 | } | |
5575 | ||
5576 | static void | |
7566401a | 5577 | @@ -2395,12 +2679,9 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) |
3a58abaf AM |
5578 | |
5579 | baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); | |
5580 | ||
5581 | - if (pdi_needs_namespace (pdi->tag)) | |
7566401a ER |
5582 | - { |
5583 | - actual_name = partial_die_full_name (pdi, cu); | |
5584 | - if (actual_name) | |
5585 | - built_actual_name = 1; | |
5586 | - } | |
5587 | + actual_name = partial_die_full_name (pdi, cu); | |
5588 | + if (actual_name) | |
5589 | + built_actual_name = 1; | |
5590 | ||
5591 | if (actual_name == NULL) | |
5592 | actual_name = pdi->name; | |
5593 | @@ -2491,6 +2772,12 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) | |
5594 | &objfile->global_psymbols, | |
5595 | 0, (CORE_ADDR) 0, cu->language, objfile); | |
5596 | break; | |
5597 | + case DW_TAG_module: | |
5598 | + add_psymbol_to_list (actual_name, strlen (actual_name), | |
5599 | + MODULE_DOMAIN, LOC_STATIC, | |
5600 | + &objfile->global_psymbols, | |
5601 | + 0, (CORE_ADDR) 0, cu->language, objfile); | |
5602 | + break; | |
5603 | case DW_TAG_class_type: | |
5604 | case DW_TAG_interface_type: | |
5605 | case DW_TAG_structure_type: | |
5606 | @@ -2532,34 +2819,17 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) | |
5607 | break; | |
5608 | } | |
5609 | ||
5610 | - /* Check to see if we should scan the name for possible namespace | |
5611 | - info. Only do this if this is C++, if we don't have namespace | |
5612 | - debugging info in the file, if the psym is of an appropriate type | |
5613 | - (otherwise we'll have psym == NULL), and if we actually had a | |
5614 | - mangled name to begin with. */ | |
5615 | - | |
5616 | - /* FIXME drow/2004-02-22: Why don't we do this for classes, i.e. the | |
5617 | - cases which do not set PSYM above? */ | |
5618 | - | |
5619 | - if (cu->language == language_cplus | |
5620 | - && cu->has_namespace_info == 0 | |
5621 | - && psym != NULL | |
3a58abaf AM |
5622 | - && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL) |
5623 | - cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym), | |
5624 | - objfile); | |
7566401a | 5625 | - |
3a58abaf AM |
5626 | if (built_actual_name) |
5627 | xfree (actual_name); | |
7566401a ER |
5628 | } |
5629 | ||
5630 | -/* Determine whether a die of type TAG living in a C++ class or | |
5631 | - namespace needs to have the name of the scope prepended to the | |
5632 | - name listed in the die. */ | |
5633 | +/* Determine whether DIE needs to have the name of the scope prepended | |
5634 | + to the name listed in the die. */ | |
5635 | ||
5636 | static int | |
5637 | -pdi_needs_namespace (enum dwarf_tag tag) | |
5638 | +die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu) | |
5639 | { | |
5640 | - switch (tag) | |
5641 | + switch (die->tag) | |
5642 | { | |
5643 | case DW_TAG_namespace: | |
5644 | case DW_TAG_typedef: | |
5645 | @@ -2569,7 +2839,23 @@ pdi_needs_namespace (enum dwarf_tag tag) | |
3a58abaf AM |
5646 | case DW_TAG_union_type: |
5647 | case DW_TAG_enumeration_type: | |
5648 | case DW_TAG_enumerator: | |
5649 | + case DW_TAG_subprogram: | |
3a58abaf | 5650 | + case DW_TAG_member: |
3a58abaf | 5651 | return 1; |
7566401a ER |
5652 | + |
5653 | + case DW_TAG_variable: | |
5654 | + { | |
5655 | + struct attribute *attr; | |
5656 | + attr = dwarf2_attr (die, DW_AT_specification, cu); | |
5657 | + if (attr) | |
5658 | + return 1; | |
5659 | + attr = dwarf2_attr (die, DW_AT_external, cu); | |
5660 | + if (attr == NULL && die->parent->tag != DW_TAG_namespace) | |
5661 | + return 0; | |
5662 | + return 1; | |
5663 | + } | |
5664 | + break; | |
5665 | + | |
3a58abaf AM |
5666 | default: |
5667 | return 0; | |
7566401a ER |
5668 | } |
5669 | @@ -2602,12 +2888,12 @@ static void | |
5670 | add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc, | |
5671 | CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu) | |
5672 | { | |
5673 | - /* Now scan partial symbols in that module. | |
5674 | + /* Add a symbol for the module. */ | |
3a58abaf | 5675 | |
7566401a ER |
5676 | - FIXME: Support the separate Fortran module namespaces. */ |
5677 | + add_partial_symbol (pdi, cu); | |
3a58abaf | 5678 | |
7566401a ER |
5679 | - if (pdi->has_children) |
5680 | - scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu); | |
5681 | + /* Partial symbols in that module are not scanned as they are never globally | |
5682 | + visible. They get imported to the specific scopes on the full read. */ | |
5683 | } | |
3a58abaf | 5684 | |
7566401a ER |
5685 | /* Read a partial die corresponding to a subprogram and create a partial |
5686 | @@ -2698,27 +2984,6 @@ guess_structure_name (struct partial_die_info *struct_pdi, | |
3a58abaf | 5687 | |
7566401a ER |
5688 | if (real_pdi->die_parent != NULL) |
5689 | return; | |
3a58abaf | 5690 | - |
7566401a | 5691 | - while (child_pdi != NULL) |
3a58abaf | 5692 | - { |
7566401a ER |
5693 | - if (child_pdi->tag == DW_TAG_subprogram) |
5694 | - { | |
5695 | - char *actual_class_name | |
5696 | - = language_class_name_from_physname (cu->language_defn, | |
5697 | - child_pdi->name); | |
5698 | - if (actual_class_name != NULL) | |
5699 | - { | |
5700 | - struct_pdi->name | |
5701 | - = obsavestring (actual_class_name, | |
5702 | - strlen (actual_class_name), | |
5703 | - &cu->comp_unit_obstack); | |
5704 | - xfree (actual_class_name); | |
5705 | - } | |
5706 | - break; | |
5707 | - } | |
5708 | - | |
5709 | - child_pdi = child_pdi->die_sibling; | |
3a58abaf | 5710 | - } |
7566401a ER |
5711 | } |
5712 | } | |
3a58abaf | 5713 | |
7566401a | 5714 | @@ -3295,6 +3560,14 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
5715 | case DW_TAG_imported_declaration: |
5716 | case DW_TAG_imported_module: | |
3a58abaf | 5717 | processing_has_namespace_info = 1; |
7566401a ER |
5718 | + if (cu->language == language_fortran) |
5719 | + { | |
5720 | + if (die->tag == DW_TAG_imported_declaration) | |
5721 | + read_fortran_imported_declaration (die, cu); | |
5722 | + else | |
5723 | + read_fortran_imported_module (die, cu); | |
5724 | + break; | |
5725 | + } | |
5726 | if (die->child != NULL && (die->tag == DW_TAG_imported_declaration | |
5727 | || cu->language != language_fortran)) | |
5728 | complaint (&symfile_complaints, _("Tag '%s' has unexpected children"), | |
ab050a48 | 5729 | @@ -3310,41 +3583,71 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
5730 | /* Return the fully qualified name of DIE, based on its DW_AT_name. |
5731 | If scope qualifiers are appropriate they will be added. The result | |
5732 | will be allocated on the objfile_obstack, or NULL if the DIE does | |
5733 | - not have a name. */ | |
5734 | + not have a name. | |
5735 | + | |
5736 | + The output string will be canonicalized (if C++/Java). */ | |
5737 | ||
5738 | static const char * | |
5739 | dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu) | |
5740 | { | |
5741 | - struct attribute *attr; | |
5742 | - char *prefix, *name; | |
5743 | - struct ui_file *buf = NULL; | |
5744 | + char *name; | |
5745 | ||
5746 | name = dwarf2_name (die, cu); | |
5747 | - if (!name) | |
5748 | - return NULL; | |
3a58abaf | 5749 | |
7566401a ER |
5750 | /* These are the only languages we know how to qualify names in. */ |
5751 | - if (cu->language != language_cplus | |
5752 | - && cu->language != language_java) | |
5753 | - return name; | |
5754 | + if (name != NULL | |
5755 | + && (cu->language == language_cplus || cu->language == language_java)) | |
5756 | + { | |
5757 | + if (die_needs_namespace (die, cu)) | |
5758 | + { | |
5759 | + long length; | |
5760 | + char *prefix; | |
5761 | + struct ui_file *buf; | |
5762 | ||
5763 | - /* If no prefix is necessary for this type of DIE, return the | |
3a58abaf AM |
5764 | - unqualified name. The other three tags listed could be handled |
5765 | - in pdi_needs_namespace, but that requires broader changes. */ | |
5766 | - if (!pdi_needs_namespace (die->tag) | |
5767 | - && die->tag != DW_TAG_subprogram | |
5768 | - && die->tag != DW_TAG_variable | |
5769 | - && die->tag != DW_TAG_member) | |
7566401a ER |
5770 | - return name; |
5771 | + buf = mem_fileopen (); | |
5772 | + prefix = determine_prefix (die, cu); | |
5773 | + if (*prefix != '\0') | |
5774 | + { | |
5775 | + char *prefixed_name = typename_concat (NULL, prefix, name, cu); | |
5776 | + fputs_unfiltered (prefixed_name, buf); | |
5777 | + xfree (prefixed_name); | |
5778 | + } | |
5779 | + else | |
5780 | + fputs_unfiltered (name, buf); | |
3a58abaf | 5781 | |
7566401a ER |
5782 | - prefix = determine_prefix (die, cu); |
5783 | - if (*prefix != '\0') | |
3a58abaf AM |
5784 | - name = typename_concat (&cu->objfile->objfile_obstack, prefix, |
5785 | - name, cu); | |
7566401a ER |
5786 | + name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, |
5787 | + &length); | |
5788 | + ui_file_delete (buf); | |
3a58abaf | 5789 | + |
7566401a ER |
5790 | + if (cu->language == language_cplus) |
5791 | + { | |
5792 | + char *cname | |
5793 | + = dwarf2_canonicalize_name (name, cu, | |
5794 | + &cu->objfile->objfile_obstack); | |
5795 | + if (cname != NULL) | |
5796 | + name = cname; | |
5797 | + } | |
3a58abaf | 5798 | + } |
3a58abaf AM |
5799 | + } |
5800 | ||
5801 | return name; | |
5802 | } | |
5803 | ||
ab050a48 BZ |
5804 | +/* Read the given DIE's DW_AT_decl_line number. Return -1 if in case of an |
5805 | + error. */ | |
5806 | + | |
5807 | +static int | |
5808 | +dwarf2_read_decl_line (struct die_info *die, struct dwarf2_cu *cu) | |
5809 | +{ | |
3a58abaf AM |
5810 | + struct attribute *line_attr; |
5811 | + | |
5812 | + line_attr = dwarf2_attr (die, DW_AT_decl_line, cu); | |
ab050a48 BZ |
5813 | + if (line_attr) |
5814 | + return DW_UNSND (line_attr); | |
3a58abaf AM |
5815 | + |
5816 | + return -1; | |
5817 | +} | |
5818 | + | |
7566401a ER |
5819 | /* Read the import statement specified by the given die and record it. */ |
5820 | ||
5821 | static void | |
ab050a48 | 5822 | @@ -3354,9 +3657,15 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
5823 | struct die_info *imported_die; |
5824 | const char *imported_name; | |
5825 | const char *imported_name_prefix; | |
5826 | - const char *import_prefix; | |
5827 | char *canonical_name; | |
5828 | - | |
3a58abaf AM |
5829 | + const char *import_alias; |
5830 | + const char *imported_declaration = ""; | |
5831 | + const char *import_prefix; | |
5832 | + | |
5833 | + int line_number = -1; | |
5834 | + | |
5835 | + int is_anonymous = 0; | |
5836 | + | |
7566401a ER |
5837 | import_attr = dwarf2_attr (die, DW_AT_import, cu); |
5838 | if (import_attr == NULL) | |
5839 | { | |
ab050a48 | 5840 | @@ -3404,17 +3713,27 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
5841 | return; |
5842 | } | |
5843 | ||
5844 | - /* FIXME: dwarf2_name (die); for the local name after import. */ | |
5845 | - | |
5846 | - /* Figure out where the statement is being imported to. */ | |
3a58abaf AM |
5847 | + /* Figure out the local name after import. */ |
5848 | + import_alias = dwarf2_name(die, cu); | |
5849 | + if(import_alias == NULL){ | |
5850 | + import_alias = ""; | |
5851 | + } | |
5852 | + | |
5853 | + /* Determine the line number at which the import was made */ | |
5854 | + line_number = dwarf2_read_decl_line(die, cu); | |
5855 | + | |
5856 | + /* Figure out where the statement is being imported to */ | |
7566401a ER |
5857 | import_prefix = determine_prefix (die, cu); |
5858 | ||
5859 | /* Figure out what the scope of the imported die is and prepend it | |
5860 | to the name of the imported die. */ | |
5861 | imported_name_prefix = determine_prefix (imported_die, cu); | |
5862 | - | |
5863 | - if (strlen (imported_name_prefix) > 0) | |
5864 | - { | |
3a58abaf AM |
5865 | + |
5866 | + if(imported_die->tag != DW_TAG_namespace){ | |
5867 | + imported_declaration = imported_name; | |
5868 | + canonical_name = (char*)imported_name_prefix; | |
5869 | + }else{ | |
5870 | + if(strlen (imported_name_prefix) > 0){ | |
7566401a ER |
5871 | canonical_name = alloca (strlen (imported_name_prefix) + 2 + strlen (imported_name) + 1); |
5872 | strcpy (canonical_name, imported_name_prefix); | |
5873 | strcat (canonical_name, "::"); | |
ab050a48 | 5874 | @@ -3425,8 +3744,14 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
5875 | canonical_name = alloca (strlen (imported_name) + 1); |
5876 | strcpy (canonical_name, imported_name); | |
5877 | } | |
5878 | - | |
5879 | - using_directives = cp_add_using (import_prefix,canonical_name, using_directives); | |
3a58abaf AM |
5880 | + } |
5881 | + | |
5882 | + using_directives = cp_add_using (import_prefix, | |
5883 | + canonical_name, | |
5884 | + import_alias, | |
5885 | + imported_declaration, | |
5886 | + line_number, | |
5887 | + using_directives); | |
3a58abaf AM |
5888 | } |
5889 | ||
7566401a | 5890 | static void |
ab050a48 | 5891 | @@ -3695,6 +4020,14 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
5892 | struct attribute *attr; |
5893 | ||
5894 | attr = dwarf2_attr (die, DW_AT_abstract_origin, cu); | |
3a58abaf | 5895 | + |
7566401a ER |
5896 | + /* GCC 4.3 incorrectly uses DW_AT_specification to indicate die inheritence |
5897 | + in the case of import statements. The following is to accommodate | |
5898 | + that. */ | |
3a58abaf AM |
5899 | + if(!attr){ |
5900 | + attr = dwarf2_attr (die, DW_AT_specification, cu); | |
5901 | + } | |
5902 | + | |
7566401a ER |
5903 | if (!attr) |
5904 | return; | |
5905 | ||
ab050a48 | 5906 | @@ -3793,6 +4126,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
5907 | char *name; |
5908 | CORE_ADDR baseaddr; | |
5909 | struct block *block; | |
5910 | + unsigned die_children = 0; | |
7566401a ER |
5911 | int inlined_func = (die->tag == DW_TAG_inlined_subroutine); |
5912 | ||
5913 | if (inlined_func) | |
ab050a48 | 5914 | @@ -3811,13 +4145,23 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
5915 | |
5916 | baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); | |
5917 | ||
5918 | - name = dwarf2_linkage_name (die, cu); | |
5919 | + name = dwarf2_name (die, cu); | |
5920 | ||
5921 | /* Ignore functions with missing or empty names and functions with | |
5922 | missing or invalid low and high pc attributes. */ | |
5923 | - if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu)) | |
5924 | + if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)){ | |
5925 | + /* explore abstract origins if present. They might contain useful information | |
5926 | + such as import statements. */ | |
5927 | + child_die = die->child; | |
5928 | + while (child_die && child_die->tag) | |
5929 | + { | |
5930 | + child_die = sibling_die (child_die); | |
5931 | + die_children++; | |
5932 | + } | |
7566401a | 5933 | + inherit_abstract_dies(die, cu); |
3a58abaf AM |
5934 | return; |
5935 | - | |
5936 | + } | |
5937 | + | |
5938 | lowpc += baseaddr; | |
5939 | highpc += baseaddr; | |
5940 | ||
ab050a48 | 5941 | @@ -3844,14 +4188,19 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
5942 | |
5943 | cu->list_in_scope = &local_symbols; | |
5944 | ||
5945 | - if (die->child != NULL) | |
7566401a ER |
5946 | + switch (cu->language) |
5947 | { | |
5948 | - child_die = die->child; | |
5949 | - while (child_die && child_die->tag) | |
5950 | - { | |
5951 | - process_die (child_die, cu); | |
5952 | - child_die = sibling_die (child_die); | |
5953 | - } | |
5954 | + case language_fortran: | |
5955 | + cu->language_specific.fortran.use = NULL; | |
5956 | + break; | |
5957 | + } | |
5958 | + | |
3a58abaf | 5959 | + child_die = die->child; |
3a58abaf | 5960 | + while (child_die && child_die->tag) |
d566d21e | 5961 | + { |
3a58abaf AM |
5962 | + process_die (child_die, cu); |
5963 | + child_die = sibling_die (child_die); | |
5964 | + die_children++; | |
3a58abaf AM |
5965 | } |
5966 | ||
7566401a | 5967 | inherit_abstract_dies (die, cu); |
ab050a48 | 5968 | @@ -3867,6 +4216,13 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
5969 | determine_prefix (die, cu), |
5970 | processing_has_namespace_info); | |
5971 | ||
5972 | + switch (cu->language) | |
5973 | + { | |
5974 | + case language_fortran: | |
5975 | + BLOCK_FORTRAN_USE (block) = cu->language_specific.fortran.use; | |
5976 | + break; | |
5977 | + } | |
3a58abaf | 5978 | + |
7566401a ER |
5979 | /* If we have address ranges, record them. */ |
5980 | dwarf2_record_block_ranges (die, block, baseaddr, cu); | |
5981 | ||
ab050a48 | 5982 | @@ -3903,7 +4259,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
5983 | as multiple lexical blocks? Handling children in a sane way would |
5984 | be nasty. Might be easier to properly extend generic blocks to | |
5985 | describe ranges. */ | |
5986 | - if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu)) | |
5987 | + if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)) | |
5988 | return; | |
5989 | lowpc += baseaddr; | |
5990 | highpc += baseaddr; | |
ab050a48 | 5991 | @@ -3920,7 +4276,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) |
d566d21e | 5992 | } |
5993 | new = pop_context (); | |
5994 | ||
5995 | - if (local_symbols != NULL) | |
7566401a | 5996 | + if (local_symbols != NULL || using_directives != NULL) |
d566d21e | 5997 | { |
5998 | struct block *block | |
5999 | = finish_block (0, &local_symbols, new->old_blocks, new->start_addr, | |
ab050a48 | 6000 | @@ -4075,7 +4431,8 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return, |
3a58abaf AM |
6001 | discontinuous, i.e. derived from DW_AT_ranges information. */ |
6002 | static int | |
6003 | dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, | |
6004 | - CORE_ADDR *highpc, struct dwarf2_cu *cu) | |
6005 | + CORE_ADDR *highpc, struct dwarf2_cu *cu, | |
6006 | + struct partial_symtab *pst) | |
6007 | { | |
6008 | struct attribute *attr; | |
6009 | CORE_ADDR low = 0; | |
ab050a48 | 6010 | @@ -4103,7 +4460,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, |
3a58abaf AM |
6011 | { |
6012 | /* Value of the DW_AT_ranges attribute is the offset in the | |
6013 | .debug_ranges section. */ | |
6014 | - if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, NULL)) | |
6015 | + if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, pst)) | |
6016 | return 0; | |
6017 | /* Found discontinuous range of addresses. */ | |
6018 | ret = -1; | |
ab050a48 | 6019 | @@ -4142,7 +4499,7 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die, |
3a58abaf AM |
6020 | CORE_ADDR low, high; |
6021 | struct die_info *child = die->child; | |
6022 | ||
6023 | - if (dwarf2_get_pc_bounds (die, &low, &high, cu)) | |
6024 | + if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL)) | |
6025 | { | |
6026 | *lowpc = min (*lowpc, low); | |
6027 | *highpc = max (*highpc, high); | |
ab050a48 | 6028 | @@ -4179,7 +4536,7 @@ get_scope_pc_bounds (struct die_info *die, |
3a58abaf AM |
6029 | CORE_ADDR best_high = (CORE_ADDR) 0; |
6030 | CORE_ADDR current_low, current_high; | |
6031 | ||
6032 | - if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu)) | |
6033 | + if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu, NULL)) | |
6034 | { | |
6035 | best_low = current_low; | |
6036 | best_high = current_high; | |
ab050a48 | 6037 | @@ -4474,7 +4831,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, |
3a58abaf AM |
6038 | return; |
6039 | ||
7566401a ER |
6040 | /* Get physical name. */ |
6041 | - physname = dwarf2_linkage_name (die, cu); | |
6042 | + physname = dwarf2_physname (die, cu); | |
3a58abaf AM |
6043 | |
6044 | /* The name is already allocated along with this objfile, so we don't | |
6045 | need to duplicate it for the type. */ | |
ab050a48 | 6046 | @@ -4617,7 +4974,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, |
3a58abaf AM |
6047 | return; |
6048 | ||
7566401a ER |
6049 | /* Get the mangled name. */ |
6050 | - physname = dwarf2_linkage_name (die, cu); | |
6051 | + physname = dwarf2_physname (die, cu); | |
3a58abaf AM |
6052 | |
6053 | /* Look up member function name in fieldlist. */ | |
6054 | for (i = 0; i < fip->nfnfields; i++) | |
ab050a48 | 6055 | @@ -4661,7 +5018,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, |
3a58abaf AM |
6056 | /* The name is already allocated along with this objfile, so we don't |
6057 | need to duplicate it for the type. */ | |
6058 | fnp->physname = physname ? physname : ""; | |
6059 | - fnp->type = alloc_type (objfile); | |
6060 | + fnp->type = alloc_type (objfile, NULL); | |
6061 | this_type = read_type_die (die, cu); | |
6062 | if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC) | |
6063 | { | |
ab050a48 | 6064 | @@ -4721,18 +5078,18 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, |
7566401a ER |
6065 | { |
6066 | /* Support the .debug_loc offsets */ | |
6067 | if (attr_form_is_block (attr)) | |
6068 | - { | |
6069 | - fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2; | |
6070 | - } | |
6071 | + { | |
6072 | + fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2; | |
6073 | + } | |
6074 | else if (attr_form_is_section_offset (attr)) | |
6075 | - { | |
6076 | + { | |
6077 | dwarf2_complex_location_expr_complaint (); | |
6078 | - } | |
6079 | + } | |
6080 | else | |
6081 | - { | |
6082 | + { | |
6083 | dwarf2_invalid_attrib_class_complaint ("DW_AT_vtable_elem_location", | |
6084 | fieldname); | |
6085 | - } | |
6086 | + } | |
6087 | } | |
6088 | } | |
6089 | ||
ab050a48 | 6090 | @@ -4845,7 +5202,7 @@ quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
6091 | return NULL; |
6092 | ||
6093 | domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0)); | |
6094 | - type = alloc_type (objfile); | |
6095 | + type = alloc_type (objfile, NULL); | |
6096 | smash_to_method_type (type, domain_type, TYPE_TARGET_TYPE (pfn_type), | |
6097 | TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type), | |
6098 | TYPE_VARARGS (pfn_type)); | |
ab050a48 | 6099 | @@ -4898,7 +5255,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
6100 | return set_die_type (die, type, cu); |
6101 | } | |
3a58abaf AM |
6102 | |
6103 | - type = alloc_type (objfile); | |
6104 | + type = alloc_type (objfile, NULL); | |
6105 | INIT_CPLUS_SPECIFIC (type); | |
7566401a | 6106 | |
3a58abaf | 6107 | name = dwarf2_name (die, cu); |
ab050a48 | 6108 | @@ -4907,14 +5264,18 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
6109 | if (cu->language == language_cplus |
6110 | || cu->language == language_java) | |
6111 | { | |
6112 | - const char *new_prefix = determine_class_name (die, cu); | |
6113 | - TYPE_TAG_NAME (type) = (char *) new_prefix; | |
6114 | + TYPE_TAG_NAME (type) = (char *) dwarf2_full_name (die, cu); | |
6115 | + if (die->tag == DW_TAG_structure_type | |
6116 | + || die->tag == DW_TAG_class_type) | |
6117 | + TYPE_NAME (type) = TYPE_TAG_NAME (type); | |
6118 | } | |
6119 | else | |
6120 | { | |
6121 | /* The name is already allocated along with this objfile, so | |
6122 | we don't need to duplicate it for the type. */ | |
6123 | - TYPE_TAG_NAME (type) = name; | |
6124 | + TYPE_TAG_NAME (type) = (char *) name; | |
6125 | + if (die->tag == DW_TAG_class_type) | |
6126 | + TYPE_NAME (type) = TYPE_TAG_NAME (type); | |
6127 | } | |
6128 | } | |
6129 | ||
ab050a48 | 6130 | @@ -5124,7 +5485,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
6131 | return set_die_type (die, type, cu); |
6132 | } | |
3a58abaf AM |
6133 | |
6134 | - type = alloc_type (objfile); | |
6135 | + type = alloc_type (objfile, NULL); | |
6136 | ||
6137 | TYPE_CODE (type) = TYPE_CODE_ENUM; | |
6138 | name = dwarf2_full_name (die, cu); | |
ab050a48 | 6139 | @@ -5152,51 +5513,6 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
6140 | return set_die_type (die, type, cu); |
6141 | } | |
6142 | ||
6143 | -/* Determine the name of the type represented by DIE, which should be | |
6144 | - a named C++ or Java compound type. Return the name in question, | |
6145 | - allocated on the objfile obstack. */ | |
6146 | - | |
6147 | -static const char * | |
6148 | -determine_class_name (struct die_info *die, struct dwarf2_cu *cu) | |
6149 | -{ | |
6150 | - const char *new_prefix = NULL; | |
6151 | - | |
6152 | - /* If we don't have namespace debug info, guess the name by trying | |
6153 | - to demangle the names of members, just like we did in | |
6154 | - guess_structure_name. */ | |
6155 | - if (!processing_has_namespace_info) | |
6156 | - { | |
6157 | - struct die_info *child; | |
6158 | - | |
6159 | - for (child = die->child; | |
6160 | - child != NULL && child->tag != 0; | |
6161 | - child = sibling_die (child)) | |
6162 | - { | |
6163 | - if (child->tag == DW_TAG_subprogram) | |
6164 | - { | |
3a58abaf | 6165 | - char *phys_prefix |
7566401a | 6166 | - = language_class_name_from_physname (cu->language_defn, |
3a58abaf AM |
6167 | - dwarf2_linkage_name |
6168 | - (child, cu)); | |
7566401a ER |
6169 | - |
6170 | - if (phys_prefix != NULL) | |
6171 | - { | |
6172 | - new_prefix | |
6173 | - = obsavestring (phys_prefix, strlen (phys_prefix), | |
6174 | - &cu->objfile->objfile_obstack); | |
6175 | - xfree (phys_prefix); | |
6176 | - break; | |
6177 | - } | |
6178 | - } | |
6179 | - } | |
6180 | - } | |
6181 | - | |
6182 | - if (new_prefix == NULL) | |
6183 | - new_prefix = dwarf2_full_name (die, cu); | |
6184 | - | |
6185 | - return new_prefix; | |
6186 | -} | |
6187 | - | |
6188 | /* Given a pointer to a die which begins an enumeration, process all | |
6189 | the dies that define the members of the enumeration, and create the | |
6190 | symbol for the enumeration type. | |
ab050a48 | 6191 | @@ -5274,6 +5590,29 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
6192 | new_symbol (die, this_type, cu); |
6193 | } | |
6194 | ||
6195 | +/* Create a new array dimension referencing its target type TYPE. | |
6196 | + | |
6197 | + Multidimensional arrays are internally represented as a stack of | |
6198 | + singledimensional arrays being referenced by their TYPE_TARGET_TYPE. */ | |
6199 | + | |
6200 | +static struct type * | |
6201 | +create_single_array_dimension (struct type *type, struct type *range_type, | |
6202 | + struct die_info *die, struct dwarf2_cu *cu) | |
6203 | +{ | |
6204 | + type = create_array_type (NULL, type, range_type); | |
6205 | + | |
6206 | + /* These generic type attributes need to be fetched by | |
6207 | + evaluate_subexp_standard <multi_f77_subscript>'s call of | |
6208 | + value_subscripted_rvalue only for the innermost array type. */ | |
6209 | + fetch_die_type_attrs (die, type, cu); | |
6210 | + | |
6211 | + /* These generic type attributes are checked for allocated/associated | |
6212 | + validity while accessing FIELD_LOC_KIND_DWARF_BLOCK. */ | |
6213 | + fetch_die_type_attrs (die, range_type, cu); | |
6214 | + | |
6215 | + return type; | |
6216 | +} | |
6217 | + | |
6218 | /* Extract all information from a DW_TAG_array_type DIE and put it in | |
6219 | the DIE's type field. For now, this only handles one dimensional | |
6220 | arrays. */ | |
ab050a48 | 6221 | @@ -5287,7 +5626,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
6222 | struct type *element_type, *range_type, *index_type; |
6223 | struct type **range_types = NULL; | |
6224 | struct attribute *attr; | |
6225 | - int ndim = 0; | |
6226 | + int ndim = 0, i; | |
6227 | struct cleanup *back_to; | |
6228 | char *name; | |
6229 | ||
ab050a48 | 6230 | @@ -5334,16 +5673,11 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
6231 | type = element_type; |
6232 | ||
6233 | if (read_array_order (die, cu) == DW_ORD_col_major) | |
6234 | - { | |
6235 | - int i = 0; | |
6236 | - while (i < ndim) | |
6237 | - type = create_array_type (NULL, type, range_types[i++]); | |
6238 | - } | |
6239 | - else | |
6240 | - { | |
6241 | - while (ndim-- > 0) | |
6242 | - type = create_array_type (NULL, type, range_types[ndim]); | |
6243 | - } | |
6244 | + for (i = 0; i < ndim; i++) | |
6245 | + type = create_single_array_dimension (type, range_types[i], die, cu); | |
6246 | + else /* (read_array_order (die, cu) == DW_ORD_row_major) */ | |
6247 | + for (i = ndim - 1; i >= 0; i--) | |
6248 | + type = create_single_array_dimension (type, range_types[i], die, cu); | |
6249 | ||
6250 | /* Understand Dwarf2 support for vector types (like they occur on | |
6251 | the PowerPC w/ AltiVec). Gcc just adds another attribute to the | |
ab050a48 | 6252 | @@ -5410,12 +5744,14 @@ read_set_type (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
6253 | return set_die_type (die, set_type, cu); |
6254 | } | |
6255 | ||
6256 | -/* First cut: install each common block member as a global variable. */ | |
6257 | +/* Create appropriate locally-scoped variables for all the DW_TAG_common_block | |
6258 | + entries. Create also TYPE_CODE_STRUCT listing all such variables to be | |
6259 | + available for `info common'. COMMON_BLOCK_DOMAIN is used to sepate the | |
6260 | + common blocks name namespace from regular variable names. */ | |
6261 | ||
6262 | static void | |
6263 | read_common_block (struct die_info *die, struct dwarf2_cu *cu) | |
6264 | { | |
6265 | - struct die_info *child_die; | |
6266 | struct attribute *attr; | |
6267 | struct symbol *sym; | |
6268 | CORE_ADDR base = (CORE_ADDR) 0; | |
ab050a48 | 6269 | @@ -5425,25 +5761,55 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
6270 | { |
6271 | /* Support the .debug_loc offsets */ | |
6272 | if (attr_form_is_block (attr)) | |
6273 | - { | |
6274 | - base = decode_locdesc (DW_BLOCK (attr), cu); | |
6275 | - } | |
6276 | + { | |
6277 | + base = decode_locdesc (DW_BLOCK (attr), cu); | |
6278 | + } | |
6279 | else if (attr_form_is_section_offset (attr)) | |
6280 | - { | |
6281 | + { | |
6282 | dwarf2_complex_location_expr_complaint (); | |
6283 | - } | |
6284 | + } | |
6285 | else | |
6286 | - { | |
6287 | + { | |
6288 | dwarf2_invalid_attrib_class_complaint ("DW_AT_location", | |
6289 | "common block member"); | |
6290 | - } | |
6291 | + } | |
3a58abaf AM |
6292 | } |
6293 | if (die->child != NULL) | |
6294 | { | |
6295 | + struct objfile *objfile = cu->objfile; | |
6296 | + struct die_info *child_die; | |
6297 | + struct type *type; | |
6298 | + struct field *field; | |
6299 | + char *name; | |
6300 | + struct symbol *sym; | |
6301 | + | |
6302 | + type = alloc_type (objfile, NULL); | |
6303 | + TYPE_CODE (type) = TYPE_CODE_STRUCT; | |
6304 | + /* Artificial type to be used only by `info common'. */ | |
6305 | + TYPE_NAME (type) = "<common>"; | |
6306 | + | |
6307 | child_die = die->child; | |
6308 | while (child_die && child_die->tag) | |
6309 | { | |
6310 | + TYPE_NFIELDS (type)++; | |
6311 | + child_die = sibling_die (child_die); | |
6312 | + } | |
6313 | + | |
6314 | + TYPE_FIELDS (type) = obstack_alloc (&objfile->objfile_obstack, | |
6315 | + sizeof (*TYPE_FIELDS (type)) | |
6316 | + * TYPE_NFIELDS (type)); | |
6317 | + memset (TYPE_FIELDS (type), 0, sizeof (*TYPE_FIELDS (type)) | |
6318 | + * TYPE_NFIELDS (type)); | |
6319 | + | |
6320 | + field = TYPE_FIELDS (type); | |
6321 | + child_die = die->child; | |
6322 | + while (child_die && child_die->tag) | |
6323 | + { | |
6324 | + /* Create the symbol in the DW_TAG_common_block block in the current | |
6325 | + symbol scope. */ | |
6326 | sym = new_symbol (child_die, NULL, cu); | |
6327 | + | |
6328 | + /* Undocumented in DWARF3, when it can be present? */ | |
6329 | attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu); | |
6330 | if (attr) | |
6331 | { | |
ab050a48 | 6332 | @@ -5461,8 +5827,25 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) |
7566401a | 6333 | SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset; |
3a58abaf AM |
6334 | add_symbol_to_list (sym, &global_symbols); |
6335 | } | |
6336 | + | |
6337 | + if (SYMBOL_CLASS (sym) == LOC_STATIC) | |
6338 | + SET_FIELD_PHYSADDR (*field, SYMBOL_VALUE_ADDRESS (sym)); | |
6339 | + else | |
6340 | + SET_FIELD_PHYSNAME (*field, SYMBOL_LINKAGE_NAME (sym)); | |
6341 | + FIELD_TYPE (*field) = SYMBOL_TYPE (sym); | |
6342 | + FIELD_NAME (*field) = SYMBOL_NATURAL_NAME (sym); | |
6343 | + field++; | |
6344 | child_die = sibling_die (child_die); | |
6345 | } | |
6346 | + | |
6347 | + /* TYPE_LENGTH (type) is left 0 - it is only a virtual structure even | |
6348 | + with no consecutive address space. */ | |
6349 | + | |
6350 | + sym = new_symbol (die, type, cu); | |
6351 | + /* SYMBOL_VALUE_ADDRESS never gets used as all its fields are static. */ | |
6352 | + SYMBOL_VALUE_ADDRESS (sym) = base; | |
6353 | + | |
6354 | + set_die_type (die, type, cu); | |
6355 | } | |
6356 | } | |
6357 | ||
ab050a48 | 6358 | @@ -5530,7 +5913,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
6359 | if (is_anonymous) |
6360 | { | |
6361 | const char *previous_prefix = determine_prefix (die, cu); | |
7566401a | 6362 | - cp_add_using_directive (previous_prefix, TYPE_NAME (type)); |
3a58abaf AM |
6363 | + cp_add_using_directive (previous_prefix, TYPE_NAME (type), "", "", dwarf2_read_decl_line(die, cu)); |
6364 | } | |
6365 | } | |
6366 | ||
ab050a48 | 6367 | @@ -5546,20 +5929,155 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
6368 | } |
6369 | } | |
6370 | ||
6371 | -/* Read a Fortran module. */ | |
6372 | +/* Read a Fortran module as global symbol which can be later looked up by | |
6373 | + f_lookup_symbol_nonlocal. */ | |
6374 | ||
6375 | static void | |
6376 | read_module (struct die_info *die, struct dwarf2_cu *cu) | |
6377 | { | |
6378 | - struct die_info *child_die = die->child; | |
6379 | + struct type *type; | |
6380 | + | |
6381 | + type = read_module_type (die, cu); | |
6382 | + | |
6383 | + if (type) | |
6384 | + new_symbol (die, type, cu); | |
6385 | +} | |
6386 | + | |
6387 | +/* Read a Fortran module as type. | |
6388 | + | |
6389 | + Modules present only as declarations - being used only for DW_AT_import of | |
6390 | + DW_TAG_imported_module - are ignored here. They are read in only in form of | |
6391 | + the module name by read_fortran_imported_module. */ | |
6392 | + | |
6393 | +static struct type * | |
6394 | +read_module_type (struct die_info *die, struct dwarf2_cu *cu) | |
6395 | +{ | |
6396 | + struct objfile *objfile = cu->objfile; | |
6397 | + struct die_info *child_die; | |
6398 | + struct type *type; | |
6399 | + char *module_name; | |
6400 | + struct context_stack *new; | |
6401 | + struct pending *save_file_symbols; | |
6402 | + struct pending *save_global_symbols; | |
6403 | + struct pending **save_list_in_scope; | |
6404 | + | |
6405 | + if (die_is_declaration (die, cu)) | |
6406 | + return NULL; | |
ab050a48 | 6407 | + |
7566401a ER |
6408 | + module_name = dwarf2_name (die, cu); |
6409 | + if (!module_name) | |
6410 | + complaint (&symfile_complaints, _("DW_TAG_module has no name, offset 0x%x"), | |
6411 | + die->offset); | |
6412 | + type = init_type (TYPE_CODE_MODULE, 0, 0, module_name, objfile); | |
7566401a | 6413 | + |
ab050a48 BZ |
6414 | + /* Create a context for reading the module variables. */ |
6415 | ||
6416 | - /* FIXME: Support the separate Fortran module namespaces. */ | |
7566401a | 6417 | + new = push_context (0, 0); |
ab050a48 | 6418 | |
7566401a ER |
6419 | + save_file_symbols = file_symbols; |
6420 | + file_symbols = NULL; | |
6421 | + save_global_symbols = global_symbols; | |
6422 | + global_symbols = NULL; | |
6423 | + save_list_in_scope = cu->list_in_scope; | |
6424 | + | |
6425 | + /* Process the child DIEs. */ | |
6426 | + | |
6427 | + child_die = die->child; | |
6428 | while (child_die && child_die->tag) | |
6429 | { | |
6430 | + /* Any DW_TAG_subprogram will reset LIST_IN_SCOPE to LOCAL_SYMBOLS. */ | |
6431 | + cu->list_in_scope = &global_symbols; | |
6432 | + | |
6433 | process_die (child_die, cu); | |
6434 | child_die = sibling_die (child_die); | |
6435 | } | |
6436 | + | |
6437 | + /* Finish this module and restore the context. */ | |
6438 | + | |
6439 | + TYPE_MODULE_BLOCK (type) = finish_block (NULL, &global_symbols, | |
6440 | + new->old_blocks, 0, 0, objfile); | |
6441 | + | |
6442 | + if (file_symbols) | |
6443 | + complaint (&symfile_complaints, _("DW_TAG_module contains static symbols")); | |
6444 | + if (local_symbols) | |
6445 | + complaint (&symfile_complaints, _("DW_TAG_module contains local symbols")); | |
6446 | + if (param_symbols) | |
6447 | + complaint (&symfile_complaints, _("DW_TAG_module contains function " | |
6448 | + "parameters")); | |
6449 | + | |
6450 | + file_symbols = save_file_symbols; | |
6451 | + global_symbols = save_global_symbols; | |
6452 | + cu->list_in_scope = save_list_in_scope; | |
6453 | + | |
6454 | + pop_context (); | |
6455 | + | |
6456 | + set_die_type (die, type, cu); | |
6457 | + | |
6458 | + return type; | |
6459 | +} | |
6460 | + | |
6461 | +/* Import a Fortran module. Only store the module name for its later lookup by | |
6462 | + f_lookup_symbol_nonlocal. */ | |
6463 | + | |
6464 | +static void | |
6465 | +read_fortran_imported_module (struct die_info *die, struct dwarf2_cu *cu) | |
6466 | +{ | |
6467 | + struct objfile *objfile = cu->objfile; | |
6468 | + struct attribute *attr; | |
6469 | + struct die_info *module_die; | |
6470 | + char *module_name; | |
6471 | + struct fortran_using *use; | |
6472 | + | |
6473 | + attr = dwarf2_attr (die, DW_AT_import, cu); | |
6474 | + if (attr == NULL) | |
6475 | + return; | |
6476 | + | |
6477 | + module_die = follow_die_ref (die, attr, &cu); | |
6478 | + module_name = dwarf2_name (module_die, cu); | |
6479 | + if (module_name == NULL) | |
6480 | + { | |
6481 | + complaint (&symfile_complaints, | |
6482 | + _("Imported DIE at offset 0x%x has no name"), die->offset); | |
6483 | + return; | |
6484 | + } | |
6485 | + | |
6486 | + /* Fortran does not allow any duplicity between local and any of the imported | |
6487 | + symbols. Therefore the order of the USE statements is not portant. | |
6488 | + gfortran prints: | |
6489 | + Error: Name 'X' at (1) is an ambiguous reference to 'X' from module 'Y' */ | |
6490 | + | |
6491 | + use = obstack_alloc (&objfile->objfile_obstack, sizeof (*use) | |
6492 | + + strlen (module_name)); | |
6493 | + strcpy (use->module_name, module_name); | |
6494 | + gdb_assert (cu->language == language_fortran); | |
6495 | + use->next = cu->language_specific.fortran.use; | |
6496 | + cu->language_specific.fortran.use = use; | |
6497 | +} | |
6498 | + | |
6499 | +/* Import a single Fortran declaration and possibly rename it. */ | |
6500 | + | |
6501 | +static void | |
6502 | +read_fortran_imported_declaration (struct die_info *die, struct dwarf2_cu *cu) | |
6503 | +{ | |
6504 | + struct attribute *attr; | |
6505 | + struct die_info *imported_die; | |
6506 | + struct symbol *sym; | |
6507 | + char *rename = dwarf2_name (die, cu); | |
6508 | + | |
6509 | + attr = dwarf2_attr (die, DW_AT_import, cu); | |
6510 | + if (attr == NULL) | |
6511 | + { | |
6512 | + complaint (&symfile_complaints, | |
6513 | + _("Fortran DW_TAG_imported_declaration is missing " | |
6514 | + "DW_AT_import at offset 0x%x"), die->offset); | |
6515 | + return; | |
6516 | + } | |
6517 | + imported_die = follow_die_ref (die, attr, &cu); | |
6518 | + | |
6519 | + sym = new_symbol (imported_die, NULL, cu); | |
6520 | + | |
6521 | + if (sym && rename) | |
6522 | + (sym)->ginfo.language_specific.cplus_specific.demangled_name = rename; | |
6523 | } | |
6524 | ||
6525 | /* Return the name of the namespace represented by DIE. Set | |
ab050a48 | 6526 | @@ -5724,29 +6242,113 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu) |
7566401a | 6527 | struct gdbarch *gdbarch = get_objfile_arch (objfile); |
3a58abaf AM |
6528 | struct type *type, *range_type, *index_type, *char_type; |
6529 | struct attribute *attr; | |
6530 | - unsigned int length; | |
6531 | + int length; | |
6532 | + | |
7566401a ER |
6533 | + index_type = objfile_type (objfile)->builtin_int; |
6534 | + /* RANGE_TYPE is allocated from OBJFILE, not as a permanent type. */ | |
6535 | + range_type = alloc_type (objfile, NULL); | |
3a58abaf AM |
6536 | + /* LOW_BOUND and HIGH_BOUND are set for real below. */ |
6537 | + range_type = create_range_type (range_type, index_type, 0, -1); | |
6538 | + | |
6539 | + /* C/C++ should probably have the low bound 0 but C/C++ does not use | |
6540 | + DW_TAG_string_type. */ | |
6541 | + TYPE_LOW_BOUND (range_type) = 1; | |
6542 | ||
6543 | attr = dwarf2_attr (die, DW_AT_string_length, cu); | |
6544 | - if (attr) | |
6545 | - { | |
6546 | - length = DW_UNSND (attr); | |
7566401a | 6547 | + if (attr && attr_form_is_block (attr)) |
3a58abaf | 6548 | + { |
7566401a ER |
6549 | + /* Security check for a size overflow. */ |
6550 | + if (DW_BLOCK (attr)->size + 2 < DW_BLOCK (attr)->size) | |
6551 | + TYPE_HIGH_BOUND (range_type) = 1; | |
6552 | + /* Extend the DWARF block by a new DW_OP_deref/DW_OP_deref_size | |
6553 | + instruction as DW_AT_string_length specifies the length location, not | |
6554 | + its value. */ | |
6555 | + else | |
6556 | + { | |
6557 | + struct dwarf2_locexpr_baton *length_baton = NULL; | |
6558 | + struct dwarf_block *blk = DW_BLOCK (attr); | |
6559 | + | |
6560 | + /* Turn any single DW_OP_reg* into DW_OP_breg*(0) but clearing | |
6561 | + DW_OP_deref* in such case. */ | |
6562 | + | |
6563 | + if (blk->size == 1 && blk->data[0] >= DW_OP_reg0 | |
6564 | + && blk->data[0] <= DW_OP_reg31) | |
6565 | + length_baton = dwarf2_attr_to_locexpr_baton (attr, cu); | |
6566 | + else if (blk->size > 1 && blk->data[0] == DW_OP_regx) | |
6567 | + { | |
6568 | + ULONGEST ulongest; | |
6569 | + gdb_byte *end; | |
6570 | + | |
6571 | + end = read_uleb128 (&blk->data[1], &blk->data[blk->size], | |
6572 | + &ulongest); | |
6573 | + if (end == &blk->data[blk->size]) | |
6574 | + length_baton = dwarf2_attr_to_locexpr_baton (attr, cu); | |
6575 | + } | |
6576 | + | |
6577 | + if (length_baton == NULL) | |
6578 | + { | |
6579 | + struct attribute *size_attr; | |
6580 | + | |
6581 | + length_baton = obstack_alloc (&cu->comp_unit_obstack, | |
6582 | + sizeof (*length_baton)); | |
6583 | + length_baton->per_cu = cu->per_cu; | |
6584 | + length_baton->size = DW_BLOCK (attr)->size + 2; | |
6585 | + length_baton->data = obstack_alloc (&cu->comp_unit_obstack, | |
6586 | + length_baton->size); | |
6587 | + memcpy (length_baton->data, DW_BLOCK (attr)->data, | |
6588 | + DW_BLOCK (attr)->size); | |
6589 | + | |
6590 | + /* DW_AT_BYTE_SIZE existing together with DW_AT_STRING_LENGTH | |
6591 | + specifies the size of an integer to fetch. */ | |
6592 | + size_attr = dwarf2_attr (die, DW_AT_byte_size, cu); | |
6593 | + if (size_attr) | |
6594 | + { | |
6595 | + length_baton->data[DW_BLOCK (attr)->size] = DW_OP_deref_size; | |
6596 | + length_baton->data[DW_BLOCK (attr)->size + 1] = | |
6597 | + DW_UNSND (size_attr); | |
6598 | + if (length_baton->data[DW_BLOCK (attr)->size + 1] | |
6599 | + != DW_UNSND (size_attr)) | |
6600 | + complaint (&symfile_complaints, | |
6601 | + _("DW_AT_string_length's DW_AT_byte_size " | |
6602 | + "integer exceeds the byte size storage")); | |
6603 | + } | |
6604 | + else | |
6605 | + { | |
6606 | + length_baton->data[DW_BLOCK (attr)->size] = DW_OP_deref; | |
6607 | + length_baton->data[DW_BLOCK (attr)->size + 1] = DW_OP_nop; | |
6608 | + } | |
6609 | + } | |
6610 | + | |
6611 | + TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 1); | |
6612 | + TYPE_FIELD_DWARF_BLOCK (range_type, 1) = length_baton; | |
6613 | + TYPE_DYNAMIC (range_type) = 1; | |
6614 | + } | |
6615 | } | |
6616 | else | |
6617 | { | |
6618 | - /* check for the DW_AT_byte_size attribute */ | |
6619 | + if (attr && attr_form_is_constant (attr)) | |
6620 | + { | |
6621 | + /* We currently do not support a constant address where the location | |
6622 | + should be read from - attr_form_is_block is expected instead. See | |
6623 | + DWARF for the DW_AT_STRING_LENGTH vs. DW_AT_BYTE_SIZE difference. | |
6624 | + */ | |
6625 | + /* PASSTHRU */ | |
6626 | + } | |
6627 | + | |
3a58abaf AM |
6628 | attr = dwarf2_attr (die, DW_AT_byte_size, cu); |
6629 | - if (attr) | |
6630 | - { | |
6631 | - length = DW_UNSND (attr); | |
6632 | - } | |
7566401a | 6633 | + if (attr && attr_form_is_block (attr)) |
3a58abaf | 6634 | + { |
3a58abaf AM |
6635 | + TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 1); |
6636 | + TYPE_FIELD_DWARF_BLOCK (range_type, 1) = | |
6637 | + dwarf2_attr_to_locexpr_baton (attr, cu); | |
6638 | + TYPE_DYNAMIC (range_type) = 1; | |
3a58abaf | 6639 | + } |
7566401a ER |
6640 | + else if (attr && attr_form_is_constant (attr)) |
6641 | + TYPE_HIGH_BOUND (range_type) = dwarf2_get_attr_constant_value (attr, 0); | |
6642 | else | |
6643 | - { | |
6644 | - length = 1; | |
6645 | - } | |
6646 | + TYPE_HIGH_BOUND (range_type) = 1; | |
3a58abaf AM |
6647 | } |
6648 | ||
7566401a | 6649 | - index_type = objfile_type (objfile)->builtin_int; |
3a58abaf | 6650 | - range_type = create_range_type (NULL, index_type, 1, length); |
7566401a ER |
6651 | char_type = language_string_char_type (cu->language_defn, gdbarch); |
6652 | type = create_string_type (NULL, char_type, range_type); | |
3a58abaf | 6653 | |
ab050a48 | 6654 | @@ -5841,7 +6443,6 @@ static struct type * |
3a58abaf AM |
6655 | read_typedef (struct die_info *die, struct dwarf2_cu *cu) |
6656 | { | |
6657 | struct objfile *objfile = cu->objfile; | |
6658 | - struct attribute *attr; | |
6659 | const char *name = NULL; | |
6660 | struct type *this_type; | |
6661 | ||
ab050a48 | 6662 | @@ -5949,8 +6550,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
6663 | struct type *base_type; |
6664 | struct type *range_type; | |
6665 | struct attribute *attr; | |
6666 | - int low = 0; | |
6667 | - int high = -1; | |
7566401a | 6668 | + int low; |
3a58abaf AM |
6669 | char *name; |
6670 | ||
6671 | base_type = die_type (die, cu); | |
ab050a48 | 6672 | @@ -5963,42 +6563,89 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
6673 | 0, NULL, cu->objfile); |
6674 | } | |
6675 | ||
6676 | - if (cu->language == language_fortran) | |
6677 | - { | |
6678 | - /* FORTRAN implies a lower bound of 1, if not given. */ | |
6679 | - low = 1; | |
6680 | - } | |
6681 | + /* LOW_BOUND and HIGH_BOUND are set for real below. */ | |
6682 | + range_type = create_range_type (NULL, base_type, 0, -1); | |
6683 | ||
6684 | - /* FIXME: For variable sized arrays either of these could be | |
6685 | - a variable rather than a constant value. We'll allow it, | |
6686 | - but we don't know how to handle it. */ | |
6687 | attr = dwarf2_attr (die, DW_AT_lower_bound, cu); | |
6688 | - if (attr) | |
6689 | - low = dwarf2_get_attr_constant_value (attr, 0); | |
7566401a | 6690 | + if (attr && attr_form_is_block (attr)) |
3a58abaf | 6691 | + { |
3a58abaf AM |
6692 | + TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 0); |
6693 | + TYPE_FIELD_DWARF_BLOCK (range_type, 0) = dwarf2_attr_to_locexpr_baton | |
6694 | + (attr, cu); | |
6695 | + TYPE_DYNAMIC (range_type) = 1; | |
6696 | + /* For setting a default if DW_AT_UPPER_BOUND would be missing. */ | |
6697 | + low = 0; | |
7566401a ER |
6698 | + } |
6699 | + else | |
6700 | + { | |
6701 | + if (attr && attr_form_is_constant (attr)) | |
6702 | + low = dwarf2_get_attr_constant_value (attr, 0); | |
6703 | + else | |
6704 | + { | |
6705 | + if (cu->language == language_fortran) | |
6706 | + { | |
6707 | + /* FORTRAN implies a lower bound of 1, if not given. */ | |
6708 | + low = 1; | |
6709 | + } | |
6710 | + else | |
6711 | + { | |
6712 | + /* According to DWARF we should assume the value 0 only for | |
6713 | + LANGUAGE_C and LANGUAGE_CPLUS. */ | |
6714 | + low = 0; | |
6715 | + } | |
6716 | + } | |
6717 | + TYPE_LOW_BOUND (range_type) = low; | |
6718 | + if (low >= 0) | |
6719 | + TYPE_UNSIGNED (range_type) = 1; | |
3a58abaf AM |
6720 | + } |
6721 | ||
6722 | attr = dwarf2_attr (die, DW_AT_upper_bound, cu); | |
6723 | - if (attr) | |
6724 | - { | |
6725 | - if (attr->form == DW_FORM_block1) | |
6726 | - { | |
6727 | - /* GCC encodes arrays with unspecified or dynamic length | |
6728 | - with a DW_FORM_block1 attribute. | |
6729 | - FIXME: GDB does not yet know how to handle dynamic | |
6730 | - arrays properly, treat them as arrays with unspecified | |
6731 | - length for now. | |
6732 | - | |
6733 | - FIXME: jimb/2003-09-22: GDB does not really know | |
6734 | - how to handle arrays of unspecified length | |
6735 | - either; we just represent them as zero-length | |
6736 | - arrays. Choose an appropriate upper bound given | |
6737 | - the lower bound we've computed above. */ | |
6738 | - high = low - 1; | |
6739 | - } | |
7566401a | 6740 | + if (!attr || (!attr_form_is_block (attr) && !attr_form_is_constant (attr))) |
3a58abaf AM |
6741 | + { |
6742 | + attr = dwarf2_attr (die, DW_AT_count, cu); | |
3a58abaf | 6743 | + /* It does not hurt but it is needlessly ineffective in check_typedef. */ |
7566401a | 6744 | + if (attr && (attr_form_is_block (attr) || attr_form_is_constant (attr))) |
3a58abaf AM |
6745 | + { |
6746 | + TYPE_RANGE_HIGH_BOUND_IS_COUNT (range_type) = 1; | |
6747 | + TYPE_DYNAMIC (range_type) = 1; | |
6748 | + } | |
6749 | + /* Pass it now as the regular DW_AT_upper_bound. */ | |
6750 | + } | |
7566401a ER |
6751 | + |
6752 | + if (attr && attr_form_is_block (attr)) | |
3a58abaf | 6753 | + { |
3a58abaf AM |
6754 | + TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 1); |
6755 | + TYPE_FIELD_DWARF_BLOCK (range_type, 1) = dwarf2_attr_to_locexpr_baton | |
6756 | + (attr, cu); | |
6757 | + TYPE_DYNAMIC (range_type) = 1; | |
7566401a ER |
6758 | + } |
6759 | + else | |
6760 | + { | |
6761 | + if (attr && attr_form_is_constant (attr)) | |
6762 | + TYPE_HIGH_BOUND (range_type) = dwarf2_get_attr_constant_value (attr, 0); | |
6763 | else | |
6764 | - high = dwarf2_get_attr_constant_value (attr, 1); | |
6765 | + { | |
6766 | + TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (range_type) = 1; | |
6767 | + TYPE_HIGH_BOUND (range_type) = low - 1; | |
6768 | + } | |
3a58abaf AM |
6769 | } |
6770 | ||
6771 | - range_type = create_range_type (NULL, base_type, low, high); | |
6772 | + /* DW_AT_bit_stride is currently unsupported as we count in bytes. */ | |
6773 | + attr = dwarf2_attr (die, DW_AT_byte_stride, cu); | |
7566401a | 6774 | + if (attr && attr_form_is_block (attr)) |
3a58abaf | 6775 | + { |
3a58abaf AM |
6776 | + TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 2); |
6777 | + TYPE_FIELD_DWARF_BLOCK (range_type, 2) = dwarf2_attr_to_locexpr_baton | |
6778 | + (attr, cu); | |
6779 | + TYPE_DYNAMIC (range_type) = 1; | |
3a58abaf | 6780 | + } |
7566401a | 6781 | + else if (attr && attr_form_is_constant (attr)) |
3a58abaf | 6782 | + { |
7566401a ER |
6783 | + TYPE_BYTE_STRIDE (range_type) = dwarf2_get_attr_constant_value (attr, 0); |
6784 | + if (TYPE_BYTE_STRIDE (range_type) == 0) | |
6785 | + complaint (&symfile_complaints, | |
6786 | + _("Found DW_AT_byte_stride with unsupported value 0")); | |
3a58abaf AM |
6787 | + } |
6788 | ||
7566401a ER |
6789 | name = dwarf2_name (die, cu); |
6790 | if (name) | |
ab050a48 | 6791 | @@ -6469,6 +7116,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, |
7566401a ER |
6792 | && abbrev->tag != DW_TAG_lexical_block |
6793 | && abbrev->tag != DW_TAG_variable | |
6794 | && abbrev->tag != DW_TAG_namespace | |
6795 | + && abbrev->tag != DW_TAG_module | |
6796 | && abbrev->tag != DW_TAG_member) | |
3a58abaf | 6797 | { |
7566401a | 6798 | /* Otherwise we skip to the next sibling, if any. */ |
ab050a48 | 6799 | @@ -6689,9 +7337,6 @@ read_partial_die (struct partial_die_info *part_die, |
7566401a ER |
6800 | if (part_die->dirname == NULL) |
6801 | part_die->dirname = DW_STRING (&attr); | |
3a58abaf | 6802 | break; |
7566401a | 6803 | - case DW_AT_MIPS_linkage_name: |
3a58abaf | 6804 | - part_die->name = DW_STRING (&attr); |
7566401a | 6805 | - break; |
3a58abaf AM |
6806 | case DW_AT_low_pc: |
6807 | has_low_pc_attr = 1; | |
6808 | part_die->lowpc = DW_ADDR (&attr); | |
ab050a48 | 6809 | @@ -6923,7 +7568,8 @@ fixup_partial_die (struct partial_die_info *part_die, |
3a58abaf AM |
6810 | /* If we found a reference attribute and the DIE has no name, try |
6811 | to find a name in the referred to DIE. */ | |
6812 | ||
6813 | - if (part_die->name == NULL && part_die->has_specification) | |
6814 | + if (part_die->has_specification | |
7566401a | 6815 | + && (part_die->name == NULL || !part_die->is_external)) |
3a58abaf AM |
6816 | { |
6817 | struct partial_die_info *spec_die; | |
6818 | ||
ab050a48 | 6819 | @@ -8265,10 +8911,12 @@ var_decode_location (struct attribute *attr, struct symbol *sym, |
3a58abaf AM |
6820 | (i.e. when the value of a register or memory location is |
6821 | referenced, or a thread-local block, etc.). Then again, it might | |
6822 | not be worthwhile. I'm assuming that it isn't unless performance | |
6823 | - or memory numbers show me otherwise. */ | |
6824 | + or memory numbers show me otherwise. | |
6825 | + | |
6826 | + SYMBOL_CLASS may get overriden by dwarf2_symbol_mark_computed. */ | |
6827 | ||
6828 | - dwarf2_symbol_mark_computed (attr, sym, cu); | |
6829 | SYMBOL_CLASS (sym) = LOC_COMPUTED; | |
6830 | + dwarf2_symbol_mark_computed (attr, sym, cu); | |
6831 | } | |
6832 | ||
6833 | /* Given a pointer to a DWARF information entry, figure out if we need | |
ab050a48 | 6834 | @@ -8290,21 +8938,30 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) |
7566401a | 6835 | |
3a58abaf AM |
6836 | baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); |
6837 | ||
7566401a | 6838 | - if (die->tag != DW_TAG_namespace) |
3a58abaf | 6839 | - name = dwarf2_linkage_name (die, cu); |
7566401a ER |
6840 | - else |
6841 | - name = TYPE_NAME (type); | |
6842 | - | |
6843 | + name = dwarf2_name (die, cu); | |
3a58abaf AM |
6844 | if (name) |
6845 | { | |
6846 | + const char *linkagename; | |
6847 | + | |
6848 | sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, | |
6849 | sizeof (struct symbol)); | |
6850 | OBJSTAT (objfile, n_syms++); | |
6851 | memset (sym, 0, sizeof (struct symbol)); | |
7566401a ER |
6852 | + /* Some methods are called w/o checking SYMBOL_COMPUTED_OPS validity. */ |
6853 | + SYMBOL_COMPUTED_OPS (sym) = &dwarf2_missing_funcs; | |
3a58abaf AM |
6854 | |
6855 | - /* Cache this symbol's name and the name's demangled form (if any). */ | |
6856 | SYMBOL_LANGUAGE (sym) = cu->language; | |
6857 | - SYMBOL_SET_NAMES (sym, name, strlen (name), objfile); | |
6858 | + | |
6859 | + /* Cache this symbol's name and the name's demangled form (if any). */ | |
6860 | + | |
7566401a ER |
6861 | + linkagename = dwarf2_physname (die, cu); |
6862 | + SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), objfile); | |
6863 | + if (cu->language == language_fortran) | |
3a58abaf | 6864 | + { |
7566401a ER |
6865 | + (sym)->ginfo.language_specific.cplus_specific.demangled_name = |
6866 | + SYMBOL_LINKAGE_NAME (sym); | |
6867 | + SYMBOL_LINKAGE_NAME (sym) = fortran_module_linkage_name (die, cu); | |
3a58abaf AM |
6868 | + } |
6869 | ||
6870 | /* Default assumptions. | |
6871 | Use the passed type or decode it from the die. */ | |
ab050a48 | 6872 | @@ -8402,9 +9059,28 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) |
3a58abaf AM |
6873 | if (attr) |
6874 | { | |
6875 | var_decode_location (attr, sym, cu); | |
7566401a ER |
6876 | + |
6877 | attr2 = dwarf2_attr (die, DW_AT_external, cu); | |
3a58abaf AM |
6878 | + |
6879 | + /* Fortran explicitely imports any global symbols to the local | |
7566401a ER |
6880 | + scope by DW_TAG_common_block. */ |
6881 | + if (cu->language == language_fortran && die->parent | |
6882 | + && die->parent->tag == DW_TAG_common_block) | |
6883 | + attr2 = NULL; | |
6884 | + | |
3a58abaf | 6885 | if (attr2 && (DW_UNSND (attr2) != 0)) |
7566401a ER |
6886 | - add_symbol_to_list (sym, &global_symbols); |
6887 | + { | |
6888 | + /* Workaround gfortran PR debug/40040 - it uses | |
6889 | + DW_AT_location for variables in -fPIC libraries which may | |
6890 | + get overriden by other libraries/executable and get | |
6891 | + a different address. Resolve it by .dynsym instead. */ | |
6892 | + | |
6893 | + if (cu->language == language_fortran && die->parent | |
6894 | + && die->parent->tag == DW_TAG_module) | |
6895 | + SYMBOL_CLASS (sym) = LOC_UNRESOLVED; | |
6896 | + | |
6897 | + add_symbol_to_list (sym, &global_symbols); | |
6898 | + } | |
3a58abaf | 6899 | else |
7566401a ER |
6900 | add_symbol_to_list (sym, cu->list_in_scope); |
6901 | } | |
ab050a48 | 6902 | @@ -8534,7 +9210,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) |
7566401a ER |
6903 | add_symbol_to_list (sym, cu->list_in_scope); |
6904 | break; | |
6905 | case DW_TAG_enumerator: | |
6906 | - SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_full_name (die, cu); | |
6907 | + SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_name (die, cu); | |
6908 | attr = dwarf2_attr (die, DW_AT_const_value, cu); | |
6909 | if (attr) | |
6910 | { | |
ab050a48 | 6911 | @@ -8558,6 +9234,16 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) |
3a58abaf AM |
6912 | SYMBOL_CLASS (sym) = LOC_TYPEDEF; |
6913 | add_symbol_to_list (sym, &global_symbols); | |
6914 | break; | |
6915 | + case DW_TAG_common_block: | |
6916 | + SYMBOL_CLASS (sym) = LOC_STATIC; | |
6917 | + SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN; | |
6918 | + add_symbol_to_list (sym, cu->list_in_scope); | |
7566401a ER |
6919 | + break; |
6920 | + case DW_TAG_module: | |
6921 | + SYMBOL_CLASS (sym) = LOC_STATIC; | |
6922 | + SYMBOL_DOMAIN (sym) = MODULE_DOMAIN; | |
6923 | + add_symbol_to_list (sym, &global_symbols); | |
3a58abaf AM |
6924 | + break; |
6925 | default: | |
6926 | /* Not a tag we recognize. Hopefully we aren't processing | |
6927 | trash data, but since we must specifically ignore things | |
ab050a48 | 6928 | @@ -8571,8 +9257,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) |
7566401a ER |
6929 | /* For the benefit of old versions of GCC, check for anonymous |
6930 | namespaces based on the demangled name. */ | |
6931 | if (!processing_has_namespace_info | |
6932 | - && cu->language == language_cplus | |
6933 | - && dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu) != NULL) | |
6934 | + && cu->language == language_cplus) | |
6935 | cp_scan_for_anonymous_namespaces (sym); | |
6936 | } | |
6937 | return (sym); | |
ab050a48 | 6938 | @@ -8823,12 +9508,18 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu) |
7566401a ER |
6939 | case DW_TAG_namespace: |
6940 | this_type = read_namespace_type (die, cu); | |
6941 | break; | |
6942 | + case DW_TAG_module: | |
6943 | + this_type = read_module_type (die, cu); | |
6944 | + break; | |
6945 | default: | |
6946 | complaint (&symfile_complaints, _("unexpected tag in read_type_die: '%s'"), | |
6947 | dwarf_tag_name (die->tag)); | |
3a58abaf AM |
6948 | break; |
6949 | } | |
6950 | ||
6951 | + if (this_type) | |
6952 | + finalize_type (this_type); | |
6953 | + | |
6954 | return this_type; | |
6955 | } | |
6956 | ||
ab050a48 | 6957 | @@ -8910,10 +9601,100 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu) |
3a58abaf AM |
6958 | So it does not need a prefix. */ |
6959 | return ""; | |
3a58abaf | 6960 | default: |
7566401a ER |
6961 | - return determine_prefix (parent, cu); |
6962 | + return determine_prefix (parent, cu); | |
3a58abaf | 6963 | } |
3a58abaf AM |
6964 | } |
6965 | ||
7566401a ER |
6966 | +/* Determines the prefix for a symbol's physname. Unlike determine_prefix, |
6967 | + this method does not simply look at the DIE's immediate parent. | |
6968 | + It will compute the symbol's physname by scanning through all parent | |
6969 | + DIEs until it gets to the compilation unit's DIE. */ | |
6970 | + | |
6971 | +static char * | |
6972 | +physname_prefix (struct die_info *die, struct dwarf2_cu *cu) | |
3a58abaf | 6973 | +{ |
7566401a ER |
6974 | + long length; |
6975 | + struct ui_file *buf; | |
6976 | + struct die_info *d, *spec_die; | |
6977 | + struct dwarf2_cu *spec_cu; | |
6978 | + char *name; | |
6979 | + | |
6980 | + /* Construct a stack containing all of the DIE's parents. Caution | |
6981 | + must be observed for dealing with DW_AT_specification. */ | |
6982 | + spec_cu = cu; | |
6983 | + spec_die = die_specification (die, &spec_cu); | |
6984 | + if (spec_die != NULL) | |
6985 | + d = spec_die->parent; | |
6986 | + else | |
6987 | + d = die->parent; | |
6988 | + while (d != NULL && d->tag != DW_TAG_compile_unit) | |
6989 | + { | |
6990 | + struct attribute *attr; | |
6991 | + | |
6992 | + spec_die = die_specification (d, &spec_cu); | |
6993 | + if (spec_die != NULL) | |
6994 | + d = spec_die; | |
6995 | + | |
6996 | + VEC_quick_push (die_info_p, die_list, d); | |
6997 | + d = d->parent; | |
6998 | + } | |
6999 | + | |
7000 | + /* Now pop all the elements, printing their names as we go. */ | |
7001 | + buf = mem_fileopen (); | |
7002 | + while (!VEC_empty (die_info_p, die_list)) | |
3a58abaf | 7003 | + { |
7566401a ER |
7004 | + d = VEC_pop (die_info_p, die_list); |
7005 | + physname_prefix_1 (buf, d, cu); | |
3a58abaf | 7006 | + |
7566401a | 7007 | + if (!VEC_empty (die_info_p, die_list)) |
3a58abaf | 7008 | + { |
7566401a ER |
7009 | + if (cu->language == language_cplus) |
7010 | + fputs_unfiltered ("::", buf); | |
7011 | + else | |
7012 | + fputs_unfiltered (".", buf); | |
3a58abaf AM |
7013 | + } |
7014 | + } | |
7015 | + | |
7566401a ER |
7016 | + name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, &length); |
7017 | + ui_file_delete (buf); | |
3a58abaf AM |
7018 | + return name; |
7019 | +} | |
7020 | + | |
7566401a ER |
7021 | +static void |
7022 | +physname_prefix_1 (struct ui_file *buf, struct die_info *die, | |
7023 | + struct dwarf2_cu *cu) | |
7024 | +{ | |
7025 | + const char *name = NULL; | |
7026 | + gdb_assert (buf != NULL); | |
3a58abaf | 7027 | + |
7566401a | 7028 | + if (die != NULL) |
3a58abaf | 7029 | + { |
7566401a | 7030 | + switch (die->tag) |
3a58abaf | 7031 | + { |
7566401a ER |
7032 | + case DW_TAG_namespace: |
7033 | + name = dwarf2_name (die, cu); | |
7034 | + if (name == NULL) | |
7035 | + name = "(anonymous namespace)"; | |
7036 | + break; | |
7037 | + | |
7038 | + case DW_TAG_class_type: | |
7039 | + case DW_TAG_structure_type: | |
7040 | + case DW_TAG_union_type: | |
7041 | + case DW_TAG_enumeration_type: | |
7042 | + case DW_TAG_interface_type: | |
7043 | + case DW_TAG_subprogram: | |
7044 | + name = dwarf2_name (die, cu); | |
7045 | + break; | |
7046 | + | |
7047 | + default: | |
7048 | + break; | |
7049 | + } | |
7050 | + } | |
7051 | + | |
7052 | + if (name != NULL) | |
7053 | + fputs_unfiltered (name, buf); | |
7054 | +} | |
7055 | + | |
7056 | /* Return a newly-allocated string formed by concatenating PREFIX and | |
7057 | SUFFIX with appropriate separator. If PREFIX or SUFFIX is NULL or empty, then | |
7058 | simply copy the SUFFIX or PREFIX, respectively. If OBS is non-null, | |
ab050a48 | 7059 | @@ -8963,17 +9744,111 @@ sibling_die (struct die_info *die) |
7566401a ER |
7060 | return die->sibling; |
7061 | } | |
7062 | ||
7063 | -/* Get linkage name of a die, return NULL if not found. */ | |
7064 | +/* Construct a physname for the given DIE in CU. */ | |
7065 | ||
7066 | static char * | |
7067 | -dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu) | |
7068 | +dwarf2_physname (struct die_info *die, struct dwarf2_cu *cu) | |
7069 | { | |
7070 | struct attribute *attr; | |
7071 | + char *name; | |
7072 | + | |
7073 | + name = dwarf2_name (die, cu); | |
7074 | + | |
7075 | + /* These are the only languages we know how to qualify names in. */ | |
7076 | + if (cu->language != language_cplus | |
7077 | + && cu->language != language_java) | |
7078 | + return name; | |
7079 | + | |
7080 | + if (die_needs_namespace (die, cu)) | |
7081 | + { | |
7082 | + long length; | |
7083 | + char *prefix; | |
7084 | + struct ui_file *buf; | |
7085 | + | |
7086 | + prefix = physname_prefix (die, cu); | |
7087 | + buf = mem_fileopen (); | |
7088 | + if (*prefix != '\0') | |
7089 | + { | |
7090 | + char *prefixed_name = typename_concat (NULL, prefix, name, cu); | |
7091 | + fputs_unfiltered (prefixed_name, buf); | |
7092 | + xfree (prefixed_name); | |
7093 | + } | |
7094 | + else | |
7095 | + fputs_unfiltered (name ? name : "", buf); | |
7096 | + | |
7097 | + /* For Java and C++ methods, append formal parameter type | |
7098 | + information. */ | |
7099 | + if ((cu->language == language_cplus || cu->language == language_java) | |
7100 | + && die->tag == DW_TAG_subprogram) | |
7101 | + { | |
7102 | + struct type *type = read_type_die (die, cu); | |
7103 | + | |
7104 | + c_type_print_args (type, buf, 0, cu->language); | |
7105 | + | |
7106 | + if (cu->language == language_java) | |
7107 | + { | |
7108 | + /* For java, we must append the return type to method names. */ | |
7109 | + if (die->tag == DW_TAG_subprogram) | |
7110 | + java_print_type (TYPE_TARGET_TYPE (type), "", buf, 0, 0); | |
7111 | + } | |
7112 | + else if (cu->language == language_cplus) | |
7113 | + { | |
7114 | + /* c_type_print_args adds argument types, but it does | |
7115 | + not add any necessary "const". */ | |
7116 | + if (TYPE_NFIELDS (type) > 0 && TYPE_FIELD_ARTIFICIAL (type, 0) | |
7117 | + && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0)))) | |
7118 | + fputs_unfiltered (" const", buf); | |
7119 | + } | |
7120 | + } | |
7121 | + | |
7122 | + name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, | |
7123 | + &length); | |
7124 | + ui_file_delete (buf); | |
7125 | + | |
7126 | + if (cu->language == language_cplus) | |
7127 | + { | |
7128 | + char *cname | |
7129 | + = dwarf2_canonicalize_name (name, cu, | |
7130 | + &cu->objfile->objfile_obstack); | |
7131 | + if (cname != NULL) | |
7132 | + name = cname; | |
7133 | + } | |
7134 | + } | |
7135 | + | |
7136 | + return name; | |
7137 | +} | |
7138 | + | |
7139 | +/* Return the fully qualified .symtab name for symbols contained in Fortran | |
7140 | + modules. Return DWARF2_NAME otherwise. */ | |
7141 | + | |
7142 | +static char * | |
7143 | +fortran_module_linkage_name (struct die_info *die, struct dwarf2_cu *cu) | |
7144 | +{ | |
7145 | + char *name; | |
7146 | + | |
7147 | + gdb_assert (cu->language == language_fortran); | |
7148 | + | |
7149 | + name = dwarf2_name (die, cu); | |
7150 | + | |
7151 | + if (name && die->parent && die->parent->tag == DW_TAG_module) | |
7152 | + { | |
7153 | + char *module_name = dwarf2_name (die->parent, cu); | |
7154 | + | |
7155 | + if (module_name) | |
7156 | + { | |
7157 | + char *retval; | |
7158 | ||
7159 | - attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); | |
7160 | - if (attr && DW_STRING (attr)) | |
7161 | - return DW_STRING (attr); | |
7162 | - return dwarf2_name (die, cu); | |
7163 | + /* `__modulename_MOD_variablename0'. */ | |
7164 | + retval = obstack_alloc (&cu->objfile->objfile_obstack, | |
7165 | + 2 + strlen (module_name) + 5 + strlen (name) | |
7166 | + + 1); | |
7167 | + sprintf (retval, "__%s_MOD_%s", module_name, name); | |
7168 | + | |
7169 | + return retval; | |
7170 | + } | |
7171 | + } | |
7172 | + | |
7173 | + return name; | |
7174 | } | |
7175 | ||
7176 | /* Get name of a die, return NULL if not found. */ | |
ab050a48 | 7177 | @@ -10200,11 +11075,11 @@ dwarf2_get_ref_die_offset (struct attribute *attr) |
7566401a | 7178 | return 0; |
3a58abaf AM |
7179 | } |
7180 | ||
7181 | -/* Return the constant value held by the given attribute. Return -1 | |
7566401a ER |
7182 | +/* Return the constant value held by the given attribute. Return DEFAULT_VALUE |
7183 | if the value held by the attribute is not constant. */ | |
3a58abaf AM |
7184 | |
7185 | -static int | |
7186 | -dwarf2_get_attr_constant_value (struct attribute *attr, int default_value) | |
7566401a ER |
7187 | +static CORE_ADDR |
7188 | +dwarf2_get_attr_constant_value (struct attribute *attr, CORE_ADDR default_value) | |
3a58abaf | 7189 | { |
3a58abaf | 7190 | if (attr->form == DW_FORM_sdata) |
7566401a | 7191 | return DW_SND (attr); |
ab050a48 | 7192 | @@ -11009,8 +11884,6 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, |
3a58abaf AM |
7193 | { |
7194 | gdb_byte *mac_ptr, *mac_end; | |
7195 | struct macro_source_file *current_file = 0; | |
7566401a ER |
7196 | - enum dwarf_macinfo_record_type macinfo_type; |
7197 | - int at_commandline; | |
3a58abaf | 7198 | |
7566401a | 7199 | if (dwarf2_per_objfile->macinfo.buffer == NULL) |
3a58abaf | 7200 | { |
ab050a48 | 7201 | @@ -11018,29 +11891,19 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, |
3a58abaf AM |
7202 | return; |
7203 | } | |
7204 | ||
7566401a ER |
7205 | - /* First pass: Find the name of the base filename. |
7206 | - This filename is needed in order to process all macros whose definition | |
7207 | - (or undefinition) comes from the command line. These macros are defined | |
7208 | - before the first DW_MACINFO_start_file entry, and yet still need to be | |
7209 | - associated to the base file. | |
7210 | - | |
7211 | - To determine the base file name, we scan the macro definitions until we | |
7212 | - reach the first DW_MACINFO_start_file entry. We then initialize | |
7213 | - CURRENT_FILE accordingly so that any macro definition found before the | |
7214 | - first DW_MACINFO_start_file can still be associated to the base file. */ | |
7215 | - | |
7216 | mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset; | |
7217 | mac_end = dwarf2_per_objfile->macinfo.buffer | |
7218 | + dwarf2_per_objfile->macinfo.size; | |
3a58abaf | 7219 | |
7566401a ER |
7220 | - do |
7221 | + for (;;) | |
3a58abaf | 7222 | { |
7566401a ER |
7223 | + enum dwarf_macinfo_record_type macinfo_type; |
7224 | + | |
3a58abaf AM |
7225 | /* Do we at least have room for a macinfo type byte? */ |
7226 | if (mac_ptr >= mac_end) | |
7227 | { | |
7566401a ER |
7228 | - /* Complaint is printed during the second pass as GDB will probably |
7229 | - stop the first pass earlier upon finding DW_MACINFO_start_file. */ | |
7230 | - break; | |
7231 | + dwarf2_macros_too_long_complaint (); | |
7232 | + return; | |
3a58abaf AM |
7233 | } |
7234 | ||
7235 | macinfo_type = read_1_byte (abfd, mac_ptr); | |
ab050a48 | 7236 | @@ -11051,92 +11914,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, |
3a58abaf AM |
7237 | /* A zero macinfo type indicates the end of the macro |
7238 | information. */ | |
7239 | case 0: | |
7566401a ER |
7240 | - break; |
7241 | - | |
7242 | - case DW_MACINFO_define: | |
7243 | - case DW_MACINFO_undef: | |
7244 | - /* Only skip the data by MAC_PTR. */ | |
7245 | - { | |
7246 | - unsigned int bytes_read; | |
7247 | - | |
7248 | - read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); | |
7249 | - mac_ptr += bytes_read; | |
7250 | - read_string (abfd, mac_ptr, &bytes_read); | |
7251 | - mac_ptr += bytes_read; | |
7252 | - } | |
7253 | - break; | |
7254 | - | |
7255 | - case DW_MACINFO_start_file: | |
7256 | - { | |
7257 | - unsigned int bytes_read; | |
7258 | - int line, file; | |
7259 | - | |
7260 | - line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); | |
7261 | - mac_ptr += bytes_read; | |
7262 | - file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); | |
7263 | - mac_ptr += bytes_read; | |
7264 | - | |
7265 | - current_file = macro_start_file (file, line, current_file, comp_dir, | |
7266 | - lh, cu->objfile); | |
7267 | - } | |
7268 | - break; | |
7269 | - | |
7270 | - case DW_MACINFO_end_file: | |
7271 | - /* No data to skip by MAC_PTR. */ | |
7272 | - break; | |
7273 | - | |
7274 | - case DW_MACINFO_vendor_ext: | |
7275 | - /* Only skip the data by MAC_PTR. */ | |
7276 | - { | |
7277 | - unsigned int bytes_read; | |
7278 | - | |
7279 | - read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); | |
7280 | - mac_ptr += bytes_read; | |
7281 | - read_string (abfd, mac_ptr, &bytes_read); | |
7282 | - mac_ptr += bytes_read; | |
7283 | - } | |
7284 | - break; | |
7285 | - | |
7286 | - default: | |
7287 | - break; | |
7288 | - } | |
7289 | - } while (macinfo_type != 0 && current_file == NULL); | |
7290 | - | |
7291 | - /* Second pass: Process all entries. | |
7292 | - | |
7293 | - Use the AT_COMMAND_LINE flag to determine whether we are still processing | |
7294 | - command-line macro definitions/undefinitions. This flag is unset when we | |
7295 | - reach the first DW_MACINFO_start_file entry. */ | |
7296 | - | |
7297 | - mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset; | |
7298 | - | |
7299 | - /* Determines if GDB is still before first DW_MACINFO_start_file. If true | |
7300 | - GDB is still reading the definitions from command line. First | |
7301 | - DW_MACINFO_start_file will need to be ignored as it was already executed | |
7302 | - to create CURRENT_FILE for the main source holding also the command line | |
7303 | - definitions. On first met DW_MACINFO_start_file this flag is reset to | |
7304 | - normally execute all the remaining DW_MACINFO_start_file macinfos. */ | |
7305 | - | |
7306 | - at_commandline = 1; | |
7307 | - | |
7308 | - do | |
7309 | - { | |
7310 | - /* Do we at least have room for a macinfo type byte? */ | |
7311 | - if (mac_ptr >= mac_end) | |
7312 | - { | |
7313 | - dwarf2_macros_too_long_complaint (); | |
7314 | - break; | |
7315 | - } | |
7316 | - | |
7317 | - macinfo_type = read_1_byte (abfd, mac_ptr); | |
7318 | - mac_ptr++; | |
7319 | - | |
7320 | - switch (macinfo_type) | |
7321 | - { | |
7322 | - /* A zero macinfo type indicates the end of the macro | |
7323 | - information. */ | |
7324 | - case 0: | |
7325 | - break; | |
7326 | + return; | |
3a58abaf AM |
7327 | |
7328 | case DW_MACINFO_define: | |
7329 | case DW_MACINFO_undef: | |
ab050a48 | 7330 | @@ -11151,31 +11929,19 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, |
3a58abaf AM |
7331 | mac_ptr += bytes_read; |
7332 | ||
7333 | if (! current_file) | |
7566401a ER |
7334 | - { |
7335 | - /* DWARF violation as no main source is present. */ | |
7336 | - complaint (&symfile_complaints, | |
7337 | - _("debug info with no main source gives macro %s " | |
7338 | - "on line %d: %s"), | |
7339 | - macinfo_type == | |
7340 | - DW_MACINFO_define ? _("definition") : macinfo_type == | |
7341 | - DW_MACINFO_undef ? _("undefinition") : | |
7342 | - "something-or-other", line, body); | |
7343 | - break; | |
7344 | - } | |
7345 | - if ((line == 0 && !at_commandline) || (line != 0 && at_commandline)) | |
3a58abaf | 7346 | complaint (&symfile_complaints, |
7566401a ER |
7347 | - _("debug info gives %s macro %s with %s line %d: %s"), |
7348 | - at_commandline ? _("command-line") : _("in-file"), | |
7349 | + _("debug info gives macro %s outside of any file: %s"), | |
3a58abaf | 7350 | macinfo_type == |
7566401a ER |
7351 | - DW_MACINFO_define ? _("definition") : macinfo_type == |
7352 | - DW_MACINFO_undef ? _("undefinition") : | |
7353 | - "something-or-other", | |
7354 | - line == 0 ? _("zero") : _("non-zero"), line, body); | |
7355 | - | |
7356 | - if (macinfo_type == DW_MACINFO_define) | |
7357 | - parse_macro_definition (current_file, line, body); | |
7358 | - else if (macinfo_type == DW_MACINFO_undef) | |
7359 | - macro_undef (current_file, line, body); | |
7360 | + DW_MACINFO_define ? "definition" : macinfo_type == | |
7361 | + DW_MACINFO_undef ? "undefinition" : | |
7362 | + "something-or-other", body); | |
7363 | + else | |
7364 | + { | |
7365 | + if (macinfo_type == DW_MACINFO_define) | |
7366 | + parse_macro_definition (current_file, line, body); | |
7367 | + else if (macinfo_type == DW_MACINFO_undef) | |
7368 | + macro_undef (current_file, line, body); | |
7369 | + } | |
3a58abaf AM |
7370 | } |
7371 | break; | |
7372 | ||
ab050a48 | 7373 | @@ -11189,22 +11955,9 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, |
3a58abaf AM |
7374 | file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); |
7375 | mac_ptr += bytes_read; | |
7376 | ||
7566401a ER |
7377 | - if ((line == 0 && !at_commandline) || (line != 0 && at_commandline)) |
7378 | - complaint (&symfile_complaints, | |
7379 | - _("debug info gives source %d included " | |
7380 | - "from %s at %s line %d"), | |
7381 | - file, at_commandline ? _("command-line") : _("file"), | |
7382 | - line == 0 ? _("zero") : _("non-zero"), line); | |
7383 | - | |
7384 | - if (at_commandline) | |
7385 | - { | |
7386 | - /* This DW_MACINFO_start_file was executed in the pass one. */ | |
7387 | - at_commandline = 0; | |
7388 | - } | |
7389 | - else | |
7390 | - current_file = macro_start_file (file, line, | |
7391 | - current_file, comp_dir, | |
7392 | - lh, cu->objfile); | |
7393 | + current_file = macro_start_file (file, line, | |
7394 | + current_file, comp_dir, | |
7395 | + lh, cu->objfile); | |
3a58abaf AM |
7396 | } |
7397 | break; | |
7398 | ||
ab050a48 | 7399 | @@ -11258,7 +12011,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, |
3a58abaf AM |
7400 | } |
7401 | break; | |
7402 | } | |
7566401a ER |
7403 | - } while (macinfo_type != 0); |
7404 | + } | |
3a58abaf AM |
7405 | } |
7406 | ||
7407 | /* Check if the attribute's form is a DW_FORM_block* | |
ab050a48 | 7408 | @@ -11318,6 +12071,34 @@ attr_form_is_constant (struct attribute *attr) |
3a58abaf AM |
7409 | } |
7410 | } | |
7411 | ||
7412 | +/* Convert DW_BLOCK into struct dwarf2_locexpr_baton. ATTR must be a DW_BLOCK | |
7413 | + attribute type. */ | |
7414 | + | |
7415 | +static struct dwarf2_locexpr_baton * | |
7416 | +dwarf2_attr_to_locexpr_baton (struct attribute *attr, struct dwarf2_cu *cu) | |
7417 | +{ | |
7418 | + struct dwarf2_locexpr_baton *baton; | |
7419 | + | |
7420 | + gdb_assert (attr_form_is_block (attr)); | |
7421 | + | |
7422 | + baton = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (*baton)); | |
7423 | + baton->per_cu = cu->per_cu; | |
7424 | + gdb_assert (baton->per_cu); | |
7425 | + | |
7426 | + /* Note that we're just copying the block's data pointer | |
7427 | + here, not the actual data. We're still pointing into the | |
7428 | + info_buffer for SYM's objfile; right now we never release | |
7429 | + that buffer, but when we do clean up properly this may | |
7430 | + need to change. */ | |
7431 | + baton->size = DW_BLOCK (attr)->size; | |
7432 | + baton->data = DW_BLOCK (attr)->data; | |
7433 | + gdb_assert (baton->size == 0 || baton->data != NULL); | |
7434 | + | |
7435 | + return baton; | |
7436 | +} | |
7437 | + | |
7438 | +/* SYM may get its SYMBOL_CLASS overriden on invalid ATTR content. */ | |
7439 | + | |
7440 | static void | |
7441 | dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, | |
7442 | struct dwarf2_cu *cu) | |
ab050a48 | 7443 | @@ -11347,35 +12128,25 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, |
7566401a | 7444 | SYMBOL_COMPUTED_OPS (sym) = &dwarf2_loclist_funcs; |
3a58abaf AM |
7445 | SYMBOL_LOCATION_BATON (sym) = baton; |
7446 | } | |
7447 | + else if (attr_form_is_block (attr)) | |
7448 | + { | |
7566401a | 7449 | + SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs; |
3a58abaf AM |
7450 | + SYMBOL_LOCATION_BATON (sym) = dwarf2_attr_to_locexpr_baton (attr, cu); |
7451 | + } | |
7452 | else | |
7453 | { | |
7454 | - struct dwarf2_locexpr_baton *baton; | |
7455 | + dwarf2_invalid_attrib_class_complaint ("location description", | |
7456 | + SYMBOL_NATURAL_NAME (sym)); | |
7457 | ||
7458 | - baton = obstack_alloc (&cu->objfile->objfile_obstack, | |
7459 | - sizeof (struct dwarf2_locexpr_baton)); | |
7460 | - baton->per_cu = cu->per_cu; | |
7461 | - gdb_assert (baton->per_cu); | |
7566401a | 7462 | + /* Some methods are called w/o checking SYMBOL_COMPUTED_OPS validity. */ |
3a58abaf AM |
7463 | |
7464 | - if (attr_form_is_block (attr)) | |
7465 | - { | |
7466 | - /* Note that we're just copying the block's data pointer | |
7467 | - here, not the actual data. We're still pointing into the | |
7468 | - info_buffer for SYM's objfile; right now we never release | |
7469 | - that buffer, but when we do clean up properly this may | |
7470 | - need to change. */ | |
7471 | - baton->size = DW_BLOCK (attr)->size; | |
7472 | - baton->data = DW_BLOCK (attr)->data; | |
7473 | - } | |
7474 | - else | |
7475 | - { | |
7476 | - dwarf2_invalid_attrib_class_complaint ("location description", | |
7477 | - SYMBOL_NATURAL_NAME (sym)); | |
7478 | - baton->size = 0; | |
7479 | - baton->data = NULL; | |
7480 | - } | |
7481 | - | |
7566401a | 7482 | - SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs; |
3a58abaf | 7483 | - SYMBOL_LOCATION_BATON (sym) = baton; |
7566401a ER |
7484 | + SYMBOL_COMPUTED_OPS (sym) = &dwarf2_missing_funcs; |
7485 | + SYMBOL_LOCATION_BATON (sym) = NULL; | |
7486 | + | |
3a58abaf AM |
7487 | + /* For functions a missing DW_AT_frame_base does not optimize out the |
7488 | + whole function definition, only its frame base resolving. */ | |
7489 | + if (attr->name == DW_AT_location) | |
7490 | + SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; | |
7491 | } | |
7492 | } | |
7493 | ||
ab050a48 | 7494 | @@ -11663,6 +12434,31 @@ offset_and_type_eq (const void *item_lhs, const void *item_rhs) |
3a58abaf AM |
7495 | return ofs_lhs->offset == ofs_rhs->offset; |
7496 | } | |
7497 | ||
7498 | +/* Fill in generic attributes applicable for type DIEs. */ | |
7499 | + | |
7500 | +static void | |
7501 | +fetch_die_type_attrs (struct die_info *die, struct type *type, | |
7502 | + struct dwarf2_cu *cu) | |
7503 | +{ | |
7504 | + struct attribute *attr; | |
7505 | + | |
7506 | + attr = dwarf2_attr (die, DW_AT_data_location, cu); | |
7507 | + if (attr_form_is_block (attr)) | |
7508 | + TYPE_DATA_LOCATION_DWARF_BLOCK (type) = dwarf2_attr_to_locexpr_baton (attr, | |
7509 | + cu); | |
7510 | + gdb_assert (!TYPE_DATA_LOCATION_IS_ADDR (type)); | |
7511 | + | |
7512 | + attr = dwarf2_attr (die, DW_AT_allocated, cu); | |
7513 | + if (attr_form_is_block (attr)) | |
7514 | + TYPE_ALLOCATED (type) = dwarf2_attr_to_locexpr_baton (attr, cu); | |
7515 | + gdb_assert (!TYPE_NOT_ALLOCATED (type)); | |
7516 | + | |
7517 | + attr = dwarf2_attr (die, DW_AT_associated, cu); | |
7518 | + if (attr_form_is_block (attr)) | |
7519 | + TYPE_ASSOCIATED (type) = dwarf2_attr_to_locexpr_baton (attr, cu); | |
7520 | + gdb_assert (!TYPE_NOT_ASSOCIATED (type)); | |
7521 | +} | |
7522 | + | |
7523 | /* Set the type associated with DIE to TYPE. Save it in CU's hash | |
7524 | table if necessary. For convenience, return TYPE. */ | |
7525 | ||
ab050a48 | 7526 | @@ -11671,6 +12467,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) |
3a58abaf AM |
7527 | { |
7528 | struct dwarf2_offset_and_type **slot, ofs; | |
7529 | ||
7530 | + fetch_die_type_attrs (die, type, cu); | |
7531 | + | |
7532 | if (cu->type_hash == NULL) | |
7533 | { | |
7534 | gdb_assert (cu->per_cu != NULL); | |
ab050a48 | 7535 | @@ -11813,23 +12611,13 @@ show_dwarf2_cmd (char *args, int from_tty) |
7566401a ER |
7536 | cmd_show_list (show_dwarf2_cmdlist, from_tty, ""); |
7537 | } | |
7538 | ||
7539 | -/* If section described by INFO was mmapped, munmap it now. */ | |
7540 | +/* A helper function to destroy a debug section. */ | |
7541 | ||
7542 | static void | |
7543 | -munmap_section_buffer (struct dwarf2_section_info *info) | |
7544 | +destroy_section (struct dwarf2_section_info *info) | |
7545 | { | |
7546 | - if (info->was_mmapped) | |
7547 | - { | |
7548 | -#ifdef HAVE_MMAP | |
7549 | - intptr_t begin = (intptr_t) info->buffer; | |
7550 | - intptr_t map_begin = begin & ~(pagesize - 1); | |
7551 | - size_t map_length = info->size + begin - map_begin; | |
7552 | - gdb_assert (munmap ((void *) map_begin, map_length) == 0); | |
7553 | -#else | |
7554 | - /* Without HAVE_MMAP, we should never be here to begin with. */ | |
7555 | - gdb_assert (0); | |
7556 | -#endif | |
7557 | - } | |
7558 | + if (info->destructor) | |
7559 | + (*info->destructor) (info); | |
7560 | } | |
7561 | ||
7562 | /* munmap debug sections for OBJFILE, if necessary. */ | |
ab050a48 | 7563 | @@ -11838,15 +12626,15 @@ static void |
7566401a ER |
7564 | dwarf2_per_objfile_free (struct objfile *objfile, void *d) |
7565 | { | |
7566 | struct dwarf2_per_objfile *data = d; | |
7567 | - munmap_section_buffer (&data->info); | |
7568 | - munmap_section_buffer (&data->abbrev); | |
7569 | - munmap_section_buffer (&data->line); | |
7570 | - munmap_section_buffer (&data->str); | |
7571 | - munmap_section_buffer (&data->macinfo); | |
7572 | - munmap_section_buffer (&data->ranges); | |
7573 | - munmap_section_buffer (&data->loc); | |
7574 | - munmap_section_buffer (&data->frame); | |
7575 | - munmap_section_buffer (&data->eh_frame); | |
7576 | + destroy_section (&data->info); | |
7577 | + destroy_section (&data->abbrev); | |
7578 | + destroy_section (&data->line); | |
7579 | + destroy_section (&data->str); | |
7580 | + destroy_section (&data->macinfo); | |
7581 | + destroy_section (&data->ranges); | |
7582 | + destroy_section (&data->loc); | |
7583 | + destroy_section (&data->frame); | |
7584 | + destroy_section (&data->eh_frame); | |
7585 | } | |
7586 | ||
7587 | void _initialize_dwarf2_read (void); | |
ab050a48 | 7588 | @@ -11854,6 +12642,7 @@ void _initialize_dwarf2_read (void); |
7566401a ER |
7589 | void |
7590 | _initialize_dwarf2_read (void) | |
7591 | { | |
7592 | + die_list = VEC_alloc (die_info_p, 32); | |
7593 | dwarf2_objfile_data_key | |
7594 | = register_objfile_data_with_cleanup (NULL, dwarf2_per_objfile_free); | |
7595 | ||
3a58abaf | 7596 | diff --git a/gdb/elfread.c b/gdb/elfread.c |
7566401a | 7597 | index 6e79d4a..198bae3 100644 |
3a58abaf AM |
7598 | --- a/gdb/elfread.c |
7599 | +++ b/gdb/elfread.c | |
7566401a | 7600 | @@ -728,10 +728,18 @@ elf_symfile_read (struct objfile *objfile, int mainline) |
3a58abaf AM |
7601 | str_sect->filepos, |
7602 | bfd_section_size (abfd, str_sect)); | |
7603 | } | |
7604 | + | |
7605 | + if (dwarf2_has_info (objfile)) | |
7606 | + dwarf2_create_quick_addrmap (objfile); | |
7607 | +} | |
7608 | + | |
7609 | +static void | |
7610 | +read_psyms (struct objfile *objfile) | |
7611 | +{ | |
7612 | if (dwarf2_has_info (objfile)) | |
7613 | { | |
7614 | /* DWARF 2 sections */ | |
7615 | - dwarf2_build_psymtabs (objfile, mainline); | |
7616 | + dwarf2_build_psymtabs (objfile, 0); | |
7617 | } | |
7618 | ||
7619 | /* FIXME: kettenis/20030504: This still needs to be integrated with | |
7566401a | 7620 | @@ -881,6 +889,7 @@ static struct sym_fns elf_sym_fns = |
3a58abaf AM |
7621 | elf_new_init, /* sym_new_init: init anything gbl to entire symtab */ |
7622 | elf_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
7623 | elf_symfile_read, /* sym_read: read a symbol file into symtab */ | |
7624 | + read_psyms, /* sym_read_psymbols */ | |
7625 | elf_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
7626 | default_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */ | |
7627 | elf_symfile_segments, /* sym_segments: Get segment information from | |
7628 | diff --git a/gdb/eval.c b/gdb/eval.c | |
7566401a | 7629 | index 2926465..4c6de78 100644 |
3a58abaf AM |
7630 | --- a/gdb/eval.c |
7631 | +++ b/gdb/eval.c | |
7566401a | 7632 | @@ -39,8 +39,12 @@ |
3a58abaf AM |
7633 | #include "exceptions.h" |
7634 | #include "regcache.h" | |
7635 | #include "user-regs.h" | |
7636 | +#include "python/python.h" | |
7637 | #include "valprint.h" | |
3a58abaf AM |
7638 | +#include "gdb_obstack.h" |
7639 | +#include "objfiles.h" | |
7566401a ER |
7640 | #include "python/python.h" |
7641 | +#include "dwarf2loc.h" | |
3a58abaf AM |
7642 | |
7643 | #include "gdb_assert.h" | |
7644 | ||
7566401a | 7645 | @@ -651,6 +655,36 @@ ptrmath_type_p (struct type *type) |
3a58abaf AM |
7646 | } |
7647 | } | |
7648 | ||
3a58abaf | 7649 | +/* Constructs a fake method with the given parameter types. */ |
7566401a ER |
7650 | +static void |
7651 | +free_param_types (void *arg) | |
7652 | +{ | |
7653 | + struct type *type = (struct type *) arg; | |
7654 | + xfree (TYPE_FIELDS (type)); | |
7655 | + xfree (TYPE_MAIN_TYPE (type)); | |
7656 | + xfree (type); | |
7657 | +} | |
3a58abaf AM |
7658 | + |
7659 | +static struct type * | |
7660 | +make_params (int num_types, struct type **param_types) | |
7661 | +{ | |
7566401a ER |
7662 | + struct type *type = XZALLOC (struct type); |
7663 | + TYPE_MAIN_TYPE (type) = XZALLOC (struct main_type); | |
3a58abaf AM |
7664 | + TYPE_LENGTH (type) = 1; |
7665 | + TYPE_CODE (type) = TYPE_CODE_METHOD; | |
7566401a ER |
7666 | + TYPE_VPTR_FIELDNO (type) = -1; |
7667 | + TYPE_CHAIN (type) = type; | |
3a58abaf AM |
7668 | + TYPE_NFIELDS (type) = num_types; |
7669 | + TYPE_FIELDS (type) = (struct field *) | |
7566401a | 7670 | + TYPE_ZALLOC (type, sizeof (struct field) * num_types); |
3a58abaf AM |
7671 | + |
7672 | + while (num_types-- > 0) | |
7673 | + TYPE_FIELD_TYPE (type, num_types) = param_types[num_types]; | |
7674 | + | |
7566401a | 7675 | + make_cleanup (free_param_types, type); |
3a58abaf AM |
7676 | + return type; |
7677 | +} | |
7678 | + | |
7679 | struct value * | |
7680 | evaluate_subexp_standard (struct type *expect_type, | |
7681 | struct expression *exp, int *pos, | |
7566401a | 7682 | @@ -671,6 +705,7 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7683 | long mem_offset; |
7684 | struct type **arg_types; | |
7685 | int save_pos1; | |
7686 | + struct cleanup *old_chain; | |
7687 | ||
7688 | pc = (*pos)++; | |
7689 | op = exp->elts[pc].opcode; | |
7566401a | 7690 | @@ -684,7 +719,7 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7691 | goto nosideret; |
7692 | arg1 = value_aggregate_elt (exp->elts[pc + 1].type, | |
7693 | &exp->elts[pc + 3].string, | |
7694 | - 0, noside); | |
7695 | + expect_type, 0, noside); | |
7696 | if (arg1 == NULL) | |
7697 | error (_("There is no field named %s"), &exp->elts[pc + 3].string); | |
7698 | return arg1; | |
7566401a | 7699 | @@ -1293,7 +1328,6 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7700 | argvec = (struct value **) alloca (sizeof (struct value *) * (nargs + 3)); |
7701 | if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) | |
7702 | { | |
7703 | - nargs++; | |
7704 | /* First, evaluate the structure into arg2 */ | |
7705 | pc2 = (*pos)++; | |
7706 | ||
7566401a | 7707 | @@ -1317,21 +1351,40 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7708 | |
7709 | arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); | |
7710 | ||
7711 | - if (TYPE_CODE (check_typedef (value_type (arg1))) | |
7712 | - != TYPE_CODE_METHODPTR) | |
7713 | - error (_("Non-pointer-to-member value used in pointer-to-member " | |
7714 | - "construct")); | |
7715 | - | |
7716 | - if (noside == EVAL_AVOID_SIDE_EFFECTS) | |
7717 | + type = check_typedef (value_type (arg1)); | |
7718 | + switch (TYPE_CODE (type)) | |
7719 | { | |
7720 | - struct type *method_type = check_typedef (value_type (arg1)); | |
7721 | - arg1 = value_zero (method_type, not_lval); | |
7722 | + case TYPE_CODE_METHODPTR: | |
7723 | + if (noside == EVAL_AVOID_SIDE_EFFECTS) | |
7724 | + arg1 = value_zero (TYPE_TARGET_TYPE (type), not_lval); | |
7725 | + else | |
7726 | + arg1 = cplus_method_ptr_to_value (&arg2, arg1); | |
7727 | + | |
7728 | + /* Now, say which argument to start evaluating from */ | |
7729 | + nargs++; | |
7730 | + tem = 2; | |
7731 | + argvec[1] = arg2; | |
7732 | + break; | |
7733 | + | |
7734 | + case TYPE_CODE_MEMBERPTR: | |
7735 | + /* Now, convert these values to an address. */ | |
7736 | + arg2 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)), | |
7737 | + arg2); | |
7738 | + | |
7739 | + mem_offset = value_as_long (arg1); | |
7740 | + | |
7741 | + arg1 = value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)), | |
7742 | + value_as_long (arg2) + mem_offset); | |
7743 | + arg1 = value_ind (arg1); | |
7744 | + tem = 1; | |
7745 | + break; | |
7746 | + | |
7747 | + default: | |
7748 | + error (_("Non-pointer-to-member value used in pointer-to-member " | |
7749 | + "construct")); | |
7750 | } | |
7751 | - else | |
7752 | - arg1 = cplus_method_ptr_to_value (&arg2, arg1); | |
7753 | ||
7754 | - /* Now, say which argument to start evaluating from */ | |
7755 | - tem = 2; | |
7756 | + argvec[0] = arg1; | |
7757 | } | |
7758 | else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) | |
7759 | { | |
7566401a | 7760 | @@ -1457,8 +1510,7 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7761 | } |
7762 | else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) | |
7763 | { | |
7764 | - argvec[1] = arg2; | |
7765 | - argvec[0] = arg1; | |
7766 | + /* Pointer to member. argvec is already set up. */ | |
7767 | } | |
7768 | else if (op == OP_VAR_VALUE) | |
7769 | { | |
7566401a | 7770 | @@ -1549,7 +1601,10 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7771 | |
7772 | /* First determine the type code we are dealing with. */ | |
7773 | arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); | |
7774 | + old_chain = make_cleanup (null_cleanup, 0); | |
7566401a | 7775 | + object_address_set (value_raw_address (arg1)); |
3a58abaf AM |
7776 | type = check_typedef (value_type (arg1)); |
7777 | + do_cleanups (old_chain); | |
7778 | code = TYPE_CODE (type); | |
7779 | ||
7780 | if (code == TYPE_CODE_PTR) | |
7566401a | 7781 | @@ -1716,6 +1771,37 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7782 | error (_("non-pointer-to-member value used in pointer-to-member construct")); |
7783 | } | |
7784 | ||
7785 | + case TYPE_INSTANCE: | |
7786 | + nargs = longest_to_int (exp->elts[pc + 1].longconst); | |
7787 | + arg_types = (struct type **) alloca (nargs * sizeof (struct type *)); | |
7788 | + for (ix = 0; ix < nargs; ++ix) | |
7789 | + arg_types[ix] = exp->elts[pc + 1 + ix + 1].type; | |
7790 | + | |
7791 | + expect_type = make_params (nargs, arg_types); | |
7792 | + *(pos) += 3 + nargs; | |
7793 | + return evaluate_subexp_standard (expect_type, exp, pos, noside); | |
7794 | + | |
7795 | + case TYPE_INSTANCE_LOOKUP: | |
7796 | + { | |
7797 | + int i; | |
7798 | + struct symbol *sym; | |
7799 | + struct type **arg_types; | |
7800 | + (*pos) += 3; | |
7801 | + printf ("TYPE_INSTANCE_LOOKUP\n"); | |
7802 | + arg_types = (struct type **) alloca (TYPE_NFIELDS (expect_type) | |
7803 | + * sizeof (struct type *)); | |
7804 | + for (i = 0; i < TYPE_NFIELDS (expect_type); ++i) | |
7805 | + arg_types[i] = TYPE_FIELD_TYPE (expect_type, i); | |
7806 | + (void) find_overload_match (arg_types, TYPE_NFIELDS (expect_type), | |
7807 | + NULL /* no need for name */, | |
7808 | + 0 /* not method */, | |
7809 | + 0 /* strict match */, | |
7810 | + NULL, exp->elts[pc + 1].symbol, NULL, | |
7811 | + &sym, NULL); | |
7812 | + i = 0; | |
7813 | + } | |
7814 | + break; | |
7815 | + | |
7816 | case BINOP_CONCAT: | |
7817 | arg1 = evaluate_subexp_with_coercion (exp, pos, noside); | |
7818 | arg2 = evaluate_subexp_with_coercion (exp, pos, noside); | |
7566401a | 7819 | @@ -1987,13 +2073,19 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7820 | { |
7821 | int subscript_array[MAX_FORTRAN_DIMS]; | |
7822 | int array_size_array[MAX_FORTRAN_DIMS]; | |
7823 | + int byte_stride_array[MAX_FORTRAN_DIMS]; | |
7824 | int ndimensions = 1, i; | |
7825 | struct type *tmp_type; | |
7826 | int offset_item; /* The array offset where the item lives */ | |
7827 | + CORE_ADDR offset_byte; /* byte_stride based offset */ | |
7828 | + unsigned element_size; | |
7829 | ||
7830 | if (nargs > MAX_FORTRAN_DIMS) | |
7831 | error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS); | |
7832 | ||
7833 | + old_chain = make_cleanup (null_cleanup, 0); | |
7566401a | 7834 | + object_address_set (value_raw_address (arg1)); |
3a58abaf AM |
7835 | + |
7836 | tmp_type = check_typedef (value_type (arg1)); | |
7837 | ndimensions = calc_f77_array_dims (type); | |
7838 | ||
7566401a | 7839 | @@ -2023,6 +2115,9 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7840 | upper = f77_get_upperbound (tmp_type); |
7841 | lower = f77_get_lowerbound (tmp_type); | |
7842 | ||
7843 | + byte_stride_array[nargs - i - 1] = | |
7844 | + TYPE_ARRAY_BYTE_STRIDE_VALUE (tmp_type); | |
7845 | + | |
7846 | array_size_array[nargs - i - 1] = upper - lower + 1; | |
7847 | ||
7848 | /* Zero-normalize subscripts so that offsetting will work. */ | |
7566401a | 7849 | @@ -2041,13 +2136,25 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7850 | tmp_type = check_typedef (TYPE_TARGET_TYPE (tmp_type)); |
7851 | } | |
7852 | ||
3a58abaf AM |
7853 | + /* Kept for the f77_get_upperbound / f77_get_lowerbound calls above. */ |
7854 | + do_cleanups (old_chain); | |
7566401a ER |
7855 | + |
7856 | /* Now let us calculate the offset for this item */ | |
3a58abaf AM |
7857 | |
7858 | - offset_item = subscript_array[ndimensions - 1]; | |
3a58abaf AM |
7859 | + offset_item = 0; |
7860 | + offset_byte = 0; | |
7566401a | 7861 | + |
3a58abaf AM |
7862 | + for (i = ndimensions - 1; i >= 0; --i) |
7863 | + { | |
7864 | + offset_item *= array_size_array[i]; | |
7865 | + if (byte_stride_array[i] == 0) | |
7866 | + offset_item += subscript_array[i]; | |
7867 | + else | |
7868 | + offset_byte += subscript_array[i] * byte_stride_array[i]; | |
7869 | + } | |
7870 | ||
7566401a ER |
7871 | - for (i = ndimensions - 1; i > 0; --i) |
7872 | - offset_item = | |
7873 | - array_size_array[i - 1] * offset_item + subscript_array[i - 1]; | |
3a58abaf AM |
7874 | + element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tmp_type)); |
7875 | + offset_byte += offset_item * element_size; | |
7876 | ||
7877 | /* Let us now play a dirty trick: we will take arg1 | |
7878 | which is a value node pointing to the topmost level | |
7566401a | 7879 | @@ -2057,7 +2164,7 @@ evaluate_subexp_standard (struct type *expect_type, |
3a58abaf AM |
7880 | returns the correct type value */ |
7881 | ||
7882 | deprecated_set_value_type (arg1, tmp_type); | |
7566401a | 7883 | - return value_subscripted_rvalue (arg1, offset_item, 0); |
3a58abaf AM |
7884 | + return value_subscripted_rvalue (arg1, offset_byte); |
7885 | } | |
7886 | ||
7887 | case BINOP_LOGICAL_AND: | |
7566401a | 7888 | @@ -2598,7 +2705,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos, |
3a58abaf AM |
7889 | (*pos) += 5 + BYTES_TO_EXP_ELEM (tem + 1); |
7890 | x = value_aggregate_elt (exp->elts[pc + 1].type, | |
7891 | &exp->elts[pc + 3].string, | |
7892 | - 1, noside); | |
7893 | + NULL, 1, noside); | |
7894 | if (x == NULL) | |
7895 | error (_("There is no field named %s"), &exp->elts[pc + 3].string); | |
7896 | return x; | |
7566401a | 7897 | @@ -2643,7 +2750,7 @@ evaluate_subexp_with_coercion (struct expression *exp, |
3a58abaf AM |
7898 | { |
7899 | enum exp_opcode op; | |
7900 | int pc; | |
7901 | - struct value *val; | |
7902 | + struct value *val = NULL; | |
7903 | struct symbol *var; | |
7904 | struct type *type; | |
7905 | ||
7566401a | 7906 | @@ -2654,12 +2761,17 @@ evaluate_subexp_with_coercion (struct expression *exp, |
3a58abaf AM |
7907 | { |
7908 | case OP_VAR_VALUE: | |
7909 | var = exp->elts[pc + 2].symbol; | |
7910 | + /* address_of_variable will call object_address_set for check_typedef. | |
7911 | + Call it only if required as it can error-out on VAR in register. */ | |
7912 | + if (TYPE_DYNAMIC (SYMBOL_TYPE (var))) | |
7913 | + val = address_of_variable (var, exp->elts[pc + 1].block); | |
7914 | type = check_typedef (SYMBOL_TYPE (var)); | |
7915 | if (TYPE_CODE (type) == TYPE_CODE_ARRAY | |
7916 | && CAST_IS_CONVERSION) | |
7917 | { | |
7918 | (*pos) += 4; | |
7919 | - val = address_of_variable (var, exp->elts[pc + 1].block); | |
7920 | + if (!val) | |
7921 | + val = address_of_variable (var, exp->elts[pc + 1].block); | |
7922 | return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)), | |
7923 | val); | |
7924 | } | |
7566401a | 7925 | @@ -2711,9 +2823,13 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos) |
3a58abaf AM |
7926 | |
7927 | case OP_VAR_VALUE: | |
7928 | (*pos) += 4; | |
7929 | - type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol)); | |
7930 | - return | |
7931 | - value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); | |
7932 | + /* We do not need to call read_var_value but the object evaluation may | |
7933 | + need to have executed object_address_set which needs valid | |
7934 | + SYMBOL_VALUE_ADDRESS of the symbol. Still VALUE returned by | |
7935 | + read_var_value we left as lazy. */ | |
7936 | + type = value_type (read_var_value (exp->elts[pc + 2].symbol, | |
7937 | + deprecated_safe_get_selected_frame ())); | |
7938 | + return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); | |
7939 | ||
7940 | default: | |
7941 | val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); | |
3a58abaf | 7942 | diff --git a/gdb/expression.h b/gdb/expression.h |
7566401a | 7943 | index effe1f0..3e083ca 100644 |
3a58abaf AM |
7944 | --- a/gdb/expression.h |
7945 | +++ b/gdb/expression.h | |
7946 | @@ -88,6 +88,16 @@ enum exp_opcode | |
7947 | when X is a pointer instead of an aggregate. */ | |
7948 | STRUCTOP_MPTR, | |
7949 | ||
7950 | + /* TYPE_INSTANCE is used when the user specifies a specific | |
7951 | + type instantiation for overloaded methods/functions. The format | |
7952 | + is: TYPE_INSTANCE num_types type0 ... typeN num_types TYPE_INSTANCE*/ | |
7953 | + TYPE_INSTANCE, | |
7954 | + | |
7955 | + /* TYPE_INSTANCE_LOOKUP is used when the user specifies a specific | |
7956 | + type instantiation of a function (not a method). In this case, | |
7957 | + we must toss the results of the parser and manually do the lookup. */ | |
7958 | + TYPE_INSTANCE_LOOKUP, | |
7959 | + | |
7960 | /* end of C++. */ | |
7961 | ||
7962 | /* For Modula-2 integer division DIV */ | |
7566401a | 7963 | @@ -438,4 +448,5 @@ extern char *op_string (enum exp_opcode); |
3a58abaf AM |
7964 | extern void dump_raw_expression (struct expression *, struct ui_file *, char *); |
7965 | extern void dump_prefix_expression (struct expression *, struct ui_file *); | |
7966 | ||
7967 | + | |
7968 | #endif /* !defined (EXPRESSION_H) */ | |
7969 | diff --git a/gdb/f-exp.y b/gdb/f-exp.y | |
7566401a | 7970 | index c04c8f4..ddcd460 100644 |
3a58abaf AM |
7971 | --- a/gdb/f-exp.y |
7972 | +++ b/gdb/f-exp.y | |
7566401a | 7973 | @@ -196,6 +196,7 @@ static int parse_number (char *, int, int, YYSTYPE *); |
3a58abaf AM |
7974 | /* Special type cases, put in to allow the parser to distinguish different |
7975 | legal basetypes. */ | |
7976 | %token INT_KEYWORD INT_S2_KEYWORD LOGICAL_S1_KEYWORD LOGICAL_S2_KEYWORD | |
7977 | +%token LOGICAL_S8_KEYWORD | |
7978 | %token LOGICAL_KEYWORD REAL_KEYWORD REAL_S8_KEYWORD REAL_S16_KEYWORD | |
7979 | %token COMPLEX_S8_KEYWORD COMPLEX_S16_KEYWORD COMPLEX_S32_KEYWORD | |
7980 | %token BOOL_AND BOOL_OR BOOL_NOT | |
7566401a | 7981 | @@ -606,6 +607,8 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ |
3a58abaf AM |
7982 | { $$ = parse_f_type->builtin_integer_s2; } |
7983 | | CHARACTER | |
7984 | { $$ = parse_f_type->builtin_character; } | |
7985 | + | LOGICAL_S8_KEYWORD | |
7986 | + { $$ = parse_f_type->builtin_logical_s8;} | |
7987 | | LOGICAL_KEYWORD | |
7988 | { $$ = parse_f_type->builtin_logical; } | |
7989 | | LOGICAL_S2_KEYWORD | |
7566401a | 7990 | @@ -858,6 +861,7 @@ static const struct token f77_keywords[] = |
3a58abaf AM |
7991 | { "integer_2", INT_S2_KEYWORD, BINOP_END }, |
7992 | { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END }, | |
7993 | { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END }, | |
7994 | + { "logical_8", LOGICAL_S8_KEYWORD, BINOP_END }, | |
7995 | { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END }, | |
7996 | { "integer", INT_KEYWORD, BINOP_END }, | |
7997 | { "logical", LOGICAL_KEYWORD, BINOP_END }, | |
7998 | diff --git a/gdb/f-lang.c b/gdb/f-lang.c | |
7566401a | 7999 | index 19c1316..4cc2a40 100644 |
3a58abaf AM |
8000 | --- a/gdb/f-lang.c |
8001 | +++ b/gdb/f-lang.c | |
7566401a ER |
8002 | @@ -31,6 +31,8 @@ |
8003 | #include "f-lang.h" | |
8004 | #include "valprint.h" | |
8005 | #include "value.h" | |
8006 | +#include "block.h" | |
8007 | +#include "gdb_assert.h" | |
8008 | ||
8009 | ||
8010 | /* Following is dubious stuff that had been in the xcoff reader. */ | |
8011 | @@ -55,20 +57,6 @@ typedef struct saved_bf_symnum SAVED_BF, *SAVED_BF_PTR; | |
3a58abaf AM |
8012 | /* Local functions */ |
8013 | ||
8014 | extern void _initialize_f_language (void); | |
8015 | -#if 0 | |
8016 | -static void clear_function_list (void); | |
8017 | -static long get_bf_for_fcn (long); | |
8018 | -static void clear_bf_list (void); | |
8019 | -static void patch_all_commons_by_name (char *, CORE_ADDR, int); | |
8020 | -static SAVED_F77_COMMON_PTR find_first_common_named (char *); | |
8021 | -static void add_common_entry (struct symbol *); | |
8022 | -static void add_common_block (char *, CORE_ADDR, int, char *); | |
8023 | -static SAVED_FUNCTION *allocate_saved_function_node (void); | |
8024 | -static SAVED_BF_PTR allocate_saved_bf_node (void); | |
8025 | -static COMMON_ENTRY_PTR allocate_common_entry_node (void); | |
8026 | -static SAVED_F77_COMMON_PTR allocate_saved_f77_common_node (void); | |
8027 | -static void patch_common_entries (SAVED_F77_COMMON_PTR, CORE_ADDR, int); | |
8028 | -#endif | |
3a58abaf | 8029 | |
7566401a ER |
8030 | static void f_printchar (int c, struct type *type, struct ui_file * stream); |
8031 | static void f_emit_char (int c, struct type *type, | |
8032 | @@ -259,6 +247,7 @@ enum f_primitive_types { | |
3a58abaf AM |
8033 | f_primitive_type_logical, |
8034 | f_primitive_type_logical_s1, | |
8035 | f_primitive_type_logical_s2, | |
8036 | + f_primitive_type_logical_s8, | |
8037 | f_primitive_type_integer, | |
8038 | f_primitive_type_integer_s2, | |
8039 | f_primitive_type_real, | |
7566401a | 8040 | @@ -289,6 +278,8 @@ f_language_arch_info (struct gdbarch *gdbarch, |
3a58abaf AM |
8041 | = builtin->builtin_logical_s1; |
8042 | lai->primitive_type_vector [f_primitive_type_logical_s2] | |
8043 | = builtin->builtin_logical_s2; | |
8044 | + lai->primitive_type_vector [f_primitive_type_logical_s8] | |
8045 | + = builtin->builtin_logical_s8; | |
8046 | lai->primitive_type_vector [f_primitive_type_real] | |
8047 | = builtin->builtin_real; | |
8048 | lai->primitive_type_vector [f_primitive_type_real_s8] | |
7566401a ER |
8049 | @@ -306,6 +297,46 @@ f_language_arch_info (struct gdbarch *gdbarch, |
8050 | lai->bool_type_default = builtin->builtin_logical_s2; | |
8051 | } | |
3a58abaf | 8052 | |
7566401a ER |
8053 | +/* Find if NAME is not contained in any of the Fortran modules imported by the |
8054 | + Fortran USE statement. | |
8055 | + | |
8056 | + As Fortran has no nested blocks such lookup can be processed from | |
8057 | + lookup_symbol_nonlocal - when no local blocks could satisfy the lookup. */ | |
8058 | + | |
8059 | +static struct symbol * | |
8060 | +f_lookup_symbol_nonlocal (const char *name, | |
8061 | + const struct block *block, | |
8062 | + const domain_enum domain) | |
8063 | +{ | |
8064 | + struct fortran_using *use; | |
8065 | + | |
8066 | + if (!block) | |
8067 | + return NULL; | |
8068 | + | |
8069 | + for (use = BLOCK_FORTRAN_USE (block); use; use = use->next) | |
8070 | + { | |
8071 | + struct symbol *sym; | |
8072 | + struct type *type; | |
8073 | + struct symbol *retval; | |
8074 | + | |
8075 | + sym = lookup_symbol_global (use->module_name, block, MODULE_DOMAIN); | |
8076 | + | |
8077 | + /* Module name lookup should not fail with correct debug info. */ | |
8078 | + if (sym == NULL) | |
8079 | + continue; | |
8080 | + | |
8081 | + type = SYMBOL_TYPE (sym); | |
8082 | + gdb_assert (TYPE_CODE (type) == TYPE_CODE_MODULE); | |
8083 | + gdb_assert (TYPE_MODULE_BLOCK (type) != NULL); | |
3a58abaf | 8084 | + |
7566401a ER |
8085 | + retval = lookup_block_symbol (TYPE_MODULE_BLOCK (type), name, domain); |
8086 | + if (retval) | |
8087 | + return retval; | |
8088 | + } | |
8089 | + | |
8090 | + return NULL; | |
8091 | +} | |
8092 | + | |
8093 | /* This is declared in c-lang.h but it is silly to import that file for what | |
8094 | is already just a hack. */ | |
8095 | extern int c_value_print (struct value *, struct ui_file *, | |
8096 | @@ -333,7 +364,7 @@ const struct language_defn f_language_defn = | |
8097 | c_value_print, /* FIXME */ | |
8098 | NULL, /* Language specific skip_trampoline */ | |
8099 | NULL, /* name_of_this */ | |
8100 | - basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ | |
8101 | + f_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ | |
8102 | basic_lookup_transparent_type,/* lookup_transparent_type */ | |
8103 | NULL, /* Language specific symbol demangler */ | |
8104 | NULL, /* Language specific class_name_from_physname */ | |
8105 | @@ -372,6 +403,10 @@ build_fortran_types (struct gdbarch *gdbarch) | |
8106 | = arch_boolean_type (gdbarch, gdbarch_short_bit (gdbarch), 1, | |
8107 | "logical*2"); | |
8108 | ||
8109 | + builtin_f_type->builtin_logical_s8 | |
8110 | + = arch_boolean_type (gdbarch, gdbarch_long_long_bit (gdbarch), 1, | |
8111 | + "logical*8"); | |
8112 | + | |
8113 | builtin_f_type->builtin_integer | |
8114 | = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0, | |
8115 | "integer"); | |
8116 | @@ -418,395 +453,3 @@ _initialize_f_language (void) | |
3a58abaf AM |
8117 | |
8118 | add_language (&f_language_defn); | |
8119 | } | |
8120 | - | |
8121 | -#if 0 | |
8122 | -static SAVED_BF_PTR | |
8123 | -allocate_saved_bf_node (void) | |
8124 | -{ | |
8125 | - SAVED_BF_PTR new; | |
8126 | - | |
8127 | - new = (SAVED_BF_PTR) xmalloc (sizeof (SAVED_BF)); | |
8128 | - return (new); | |
8129 | -} | |
8130 | - | |
8131 | -static SAVED_FUNCTION * | |
8132 | -allocate_saved_function_node (void) | |
8133 | -{ | |
8134 | - SAVED_FUNCTION *new; | |
8135 | - | |
8136 | - new = (SAVED_FUNCTION *) xmalloc (sizeof (SAVED_FUNCTION)); | |
8137 | - return (new); | |
8138 | -} | |
8139 | - | |
8140 | -static SAVED_F77_COMMON_PTR | |
8141 | -allocate_saved_f77_common_node (void) | |
8142 | -{ | |
8143 | - SAVED_F77_COMMON_PTR new; | |
8144 | - | |
8145 | - new = (SAVED_F77_COMMON_PTR) xmalloc (sizeof (SAVED_F77_COMMON)); | |
8146 | - return (new); | |
8147 | -} | |
8148 | - | |
8149 | -static COMMON_ENTRY_PTR | |
8150 | -allocate_common_entry_node (void) | |
8151 | -{ | |
8152 | - COMMON_ENTRY_PTR new; | |
8153 | - | |
8154 | - new = (COMMON_ENTRY_PTR) xmalloc (sizeof (COMMON_ENTRY)); | |
8155 | - return (new); | |
8156 | -} | |
8157 | -#endif | |
8158 | - | |
8159 | -SAVED_F77_COMMON_PTR head_common_list = NULL; /* Ptr to 1st saved COMMON */ | |
8160 | -SAVED_F77_COMMON_PTR tail_common_list = NULL; /* Ptr to last saved COMMON */ | |
8161 | -SAVED_F77_COMMON_PTR current_common = NULL; /* Ptr to current COMMON */ | |
8162 | - | |
8163 | -#if 0 | |
8164 | -static SAVED_BF_PTR saved_bf_list = NULL; /* Ptr to (.bf,function) | |
8165 | - list */ | |
8166 | -static SAVED_BF_PTR saved_bf_list_end = NULL; /* Ptr to above list's end */ | |
8167 | -static SAVED_BF_PTR current_head_bf_list = NULL; /* Current head of above list | |
8168 | - */ | |
8169 | - | |
8170 | -static SAVED_BF_PTR tmp_bf_ptr; /* Generic temporary for use | |
8171 | - in macros */ | |
8172 | - | |
8173 | -/* The following function simply enters a given common block onto | |
8174 | - the global common block chain */ | |
8175 | - | |
8176 | -static void | |
8177 | -add_common_block (char *name, CORE_ADDR offset, int secnum, char *func_stab) | |
8178 | -{ | |
8179 | - SAVED_F77_COMMON_PTR tmp; | |
8180 | - char *c, *local_copy_func_stab; | |
8181 | - | |
8182 | - /* If the COMMON block we are trying to add has a blank | |
8183 | - name (i.e. "#BLNK_COM") then we set it to __BLANK | |
8184 | - because the darn "#" character makes GDB's input | |
8185 | - parser have fits. */ | |
8186 | - | |
8187 | - | |
8188 | - if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0 | |
8189 | - || strcmp (name, BLANK_COMMON_NAME_MF77) == 0) | |
8190 | - { | |
8191 | - | |
8192 | - xfree (name); | |
8193 | - name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1); | |
8194 | - strcpy (name, BLANK_COMMON_NAME_LOCAL); | |
8195 | - } | |
8196 | - | |
8197 | - tmp = allocate_saved_f77_common_node (); | |
8198 | - | |
8199 | - local_copy_func_stab = xmalloc (strlen (func_stab) + 1); | |
8200 | - strcpy (local_copy_func_stab, func_stab); | |
8201 | - | |
8202 | - tmp->name = xmalloc (strlen (name) + 1); | |
8203 | - | |
8204 | - /* local_copy_func_stab is a stabstring, let us first extract the | |
8205 | - function name from the stab by NULLing out the ':' character. */ | |
8206 | - | |
8207 | - | |
8208 | - c = NULL; | |
8209 | - c = strchr (local_copy_func_stab, ':'); | |
8210 | - | |
8211 | - if (c) | |
8212 | - *c = '\0'; | |
8213 | - else | |
8214 | - error (_("Malformed function STAB found in add_common_block()")); | |
8215 | - | |
8216 | - | |
8217 | - tmp->owning_function = xmalloc (strlen (local_copy_func_stab) + 1); | |
8218 | - | |
8219 | - strcpy (tmp->owning_function, local_copy_func_stab); | |
8220 | - | |
8221 | - strcpy (tmp->name, name); | |
8222 | - tmp->offset = offset; | |
8223 | - tmp->next = NULL; | |
8224 | - tmp->entries = NULL; | |
8225 | - tmp->secnum = secnum; | |
8226 | - | |
8227 | - current_common = tmp; | |
8228 | - | |
8229 | - if (head_common_list == NULL) | |
8230 | - { | |
8231 | - head_common_list = tail_common_list = tmp; | |
8232 | - } | |
8233 | - else | |
8234 | - { | |
8235 | - tail_common_list->next = tmp; | |
8236 | - tail_common_list = tmp; | |
8237 | - } | |
8238 | -} | |
8239 | -#endif | |
8240 | - | |
8241 | -/* The following function simply enters a given common entry onto | |
8242 | - the "current_common" block that has been saved away. */ | |
8243 | - | |
8244 | -#if 0 | |
8245 | -static void | |
8246 | -add_common_entry (struct symbol *entry_sym_ptr) | |
8247 | -{ | |
8248 | - COMMON_ENTRY_PTR tmp; | |
8249 | - | |
8250 | - | |
8251 | - | |
8252 | - /* The order of this list is important, since | |
8253 | - we expect the entries to appear in decl. | |
8254 | - order when we later issue "info common" calls */ | |
8255 | - | |
8256 | - tmp = allocate_common_entry_node (); | |
8257 | - | |
8258 | - tmp->next = NULL; | |
8259 | - tmp->symbol = entry_sym_ptr; | |
8260 | - | |
8261 | - if (current_common == NULL) | |
8262 | - error (_("Attempt to add COMMON entry with no block open!")); | |
8263 | - else | |
8264 | - { | |
8265 | - if (current_common->entries == NULL) | |
8266 | - { | |
8267 | - current_common->entries = tmp; | |
8268 | - current_common->end_of_entries = tmp; | |
8269 | - } | |
8270 | - else | |
8271 | - { | |
8272 | - current_common->end_of_entries->next = tmp; | |
8273 | - current_common->end_of_entries = tmp; | |
8274 | - } | |
8275 | - } | |
8276 | -} | |
8277 | -#endif | |
8278 | - | |
8279 | -/* This routine finds the first encountred COMMON block named "name" */ | |
8280 | - | |
8281 | -#if 0 | |
8282 | -static SAVED_F77_COMMON_PTR | |
8283 | -find_first_common_named (char *name) | |
8284 | -{ | |
8285 | - | |
8286 | - SAVED_F77_COMMON_PTR tmp; | |
8287 | - | |
8288 | - tmp = head_common_list; | |
8289 | - | |
8290 | - while (tmp != NULL) | |
8291 | - { | |
8292 | - if (strcmp (tmp->name, name) == 0) | |
8293 | - return (tmp); | |
8294 | - else | |
8295 | - tmp = tmp->next; | |
8296 | - } | |
8297 | - return (NULL); | |
8298 | -} | |
8299 | -#endif | |
8300 | - | |
8301 | -/* This routine finds the first encountred COMMON block named "name" | |
8302 | - that belongs to function funcname */ | |
8303 | - | |
8304 | -SAVED_F77_COMMON_PTR | |
8305 | -find_common_for_function (char *name, char *funcname) | |
8306 | -{ | |
8307 | - | |
8308 | - SAVED_F77_COMMON_PTR tmp; | |
8309 | - | |
8310 | - tmp = head_common_list; | |
8311 | - | |
8312 | - while (tmp != NULL) | |
8313 | - { | |
8314 | - if (strcmp (tmp->name, name) == 0 | |
8315 | - && strcmp (tmp->owning_function, funcname) == 0) | |
8316 | - return (tmp); | |
8317 | - else | |
8318 | - tmp = tmp->next; | |
8319 | - } | |
8320 | - return (NULL); | |
8321 | -} | |
8322 | - | |
8323 | - | |
8324 | -#if 0 | |
8325 | - | |
8326 | -/* The following function is called to patch up the offsets | |
8327 | - for the statics contained in the COMMON block named | |
8328 | - "name." */ | |
8329 | - | |
8330 | -static void | |
8331 | -patch_common_entries (SAVED_F77_COMMON_PTR blk, CORE_ADDR offset, int secnum) | |
8332 | -{ | |
8333 | - COMMON_ENTRY_PTR entry; | |
8334 | - | |
8335 | - blk->offset = offset; /* Keep this around for future use. */ | |
8336 | - | |
8337 | - entry = blk->entries; | |
8338 | - | |
8339 | - while (entry != NULL) | |
8340 | - { | |
8341 | - SYMBOL_VALUE (entry->symbol) += offset; | |
8342 | - SYMBOL_SECTION (entry->symbol) = secnum; | |
8343 | - | |
8344 | - entry = entry->next; | |
8345 | - } | |
8346 | - blk->secnum = secnum; | |
8347 | -} | |
8348 | - | |
8349 | -/* Patch all commons named "name" that need patching.Since COMMON | |
8350 | - blocks occur with relative infrequency, we simply do a linear scan on | |
8351 | - the name. Eventually, the best way to do this will be a | |
8352 | - hashed-lookup. Secnum is the section number for the .bss section | |
8353 | - (which is where common data lives). */ | |
8354 | - | |
8355 | -static void | |
8356 | -patch_all_commons_by_name (char *name, CORE_ADDR offset, int secnum) | |
8357 | -{ | |
8358 | - | |
8359 | - SAVED_F77_COMMON_PTR tmp; | |
8360 | - | |
8361 | - /* For blank common blocks, change the canonical reprsentation | |
8362 | - of a blank name */ | |
8363 | - | |
8364 | - if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0 | |
8365 | - || strcmp (name, BLANK_COMMON_NAME_MF77) == 0) | |
8366 | - { | |
8367 | - xfree (name); | |
8368 | - name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1); | |
8369 | - strcpy (name, BLANK_COMMON_NAME_LOCAL); | |
8370 | - } | |
8371 | - | |
8372 | - tmp = head_common_list; | |
8373 | - | |
8374 | - while (tmp != NULL) | |
8375 | - { | |
8376 | - if (COMMON_NEEDS_PATCHING (tmp)) | |
8377 | - if (strcmp (tmp->name, name) == 0) | |
8378 | - patch_common_entries (tmp, offset, secnum); | |
8379 | - | |
8380 | - tmp = tmp->next; | |
8381 | - } | |
8382 | -} | |
8383 | -#endif | |
8384 | - | |
8385 | -/* This macro adds the symbol-number for the start of the function | |
8386 | - (the symbol number of the .bf) referenced by symnum_fcn to a | |
8387 | - list. This list, in reality should be a FIFO queue but since | |
8388 | - #line pragmas sometimes cause line ranges to get messed up | |
8389 | - we simply create a linear list. This list can then be searched | |
8390 | - first by a queueing algorithm and upon failure fall back to | |
8391 | - a linear scan. */ | |
8392 | - | |
8393 | -#if 0 | |
8394 | -#define ADD_BF_SYMNUM(bf_sym,fcn_sym) \ | |
8395 | - \ | |
8396 | - if (saved_bf_list == NULL) \ | |
8397 | -{ \ | |
8398 | - tmp_bf_ptr = allocate_saved_bf_node(); \ | |
8399 | - \ | |
8400 | - tmp_bf_ptr->symnum_bf = (bf_sym); \ | |
8401 | - tmp_bf_ptr->symnum_fcn = (fcn_sym); \ | |
8402 | - tmp_bf_ptr->next = NULL; \ | |
8403 | - \ | |
8404 | - current_head_bf_list = saved_bf_list = tmp_bf_ptr; \ | |
8405 | - saved_bf_list_end = tmp_bf_ptr; \ | |
8406 | - } \ | |
8407 | -else \ | |
8408 | -{ \ | |
8409 | - tmp_bf_ptr = allocate_saved_bf_node(); \ | |
8410 | - \ | |
8411 | - tmp_bf_ptr->symnum_bf = (bf_sym); \ | |
8412 | - tmp_bf_ptr->symnum_fcn = (fcn_sym); \ | |
8413 | - tmp_bf_ptr->next = NULL; \ | |
8414 | - \ | |
8415 | - saved_bf_list_end->next = tmp_bf_ptr; \ | |
8416 | - saved_bf_list_end = tmp_bf_ptr; \ | |
8417 | - } | |
8418 | -#endif | |
8419 | - | |
8420 | -/* This function frees the entire (.bf,function) list */ | |
8421 | - | |
8422 | -#if 0 | |
8423 | -static void | |
8424 | -clear_bf_list (void) | |
8425 | -{ | |
8426 | - | |
8427 | - SAVED_BF_PTR tmp = saved_bf_list; | |
8428 | - SAVED_BF_PTR next = NULL; | |
8429 | - | |
8430 | - while (tmp != NULL) | |
8431 | - { | |
8432 | - next = tmp->next; | |
8433 | - xfree (tmp); | |
8434 | - tmp = next; | |
8435 | - } | |
8436 | - saved_bf_list = NULL; | |
8437 | -} | |
8438 | -#endif | |
8439 | - | |
8440 | -int global_remote_debug; | |
8441 | - | |
8442 | -#if 0 | |
8443 | - | |
8444 | -static long | |
8445 | -get_bf_for_fcn (long the_function) | |
8446 | -{ | |
8447 | - SAVED_BF_PTR tmp; | |
8448 | - int nprobes = 0; | |
8449 | - | |
8450 | - /* First use a simple queuing algorithm (i.e. look and see if the | |
8451 | - item at the head of the queue is the one you want) */ | |
8452 | - | |
8453 | - if (saved_bf_list == NULL) | |
8454 | - internal_error (__FILE__, __LINE__, | |
8455 | - _("cannot get .bf node off empty list")); | |
8456 | - | |
8457 | - if (current_head_bf_list != NULL) | |
8458 | - if (current_head_bf_list->symnum_fcn == the_function) | |
8459 | - { | |
8460 | - if (global_remote_debug) | |
8461 | - fprintf_unfiltered (gdb_stderr, "*"); | |
8462 | - | |
8463 | - tmp = current_head_bf_list; | |
8464 | - current_head_bf_list = current_head_bf_list->next; | |
8465 | - return (tmp->symnum_bf); | |
8466 | - } | |
8467 | - | |
8468 | - /* If the above did not work (probably because #line directives were | |
8469 | - used in the sourcefile and they messed up our internal tables) we now do | |
8470 | - the ugly linear scan */ | |
8471 | - | |
8472 | - if (global_remote_debug) | |
8473 | - fprintf_unfiltered (gdb_stderr, "\ndefaulting to linear scan\n"); | |
8474 | - | |
8475 | - nprobes = 0; | |
8476 | - tmp = saved_bf_list; | |
8477 | - while (tmp != NULL) | |
8478 | - { | |
8479 | - nprobes++; | |
8480 | - if (tmp->symnum_fcn == the_function) | |
8481 | - { | |
8482 | - if (global_remote_debug) | |
8483 | - fprintf_unfiltered (gdb_stderr, "Found in %d probes\n", nprobes); | |
8484 | - current_head_bf_list = tmp->next; | |
8485 | - return (tmp->symnum_bf); | |
8486 | - } | |
8487 | - tmp = tmp->next; | |
8488 | - } | |
8489 | - | |
8490 | - return (-1); | |
8491 | -} | |
8492 | - | |
8493 | -static SAVED_FUNCTION_PTR saved_function_list = NULL; | |
8494 | -static SAVED_FUNCTION_PTR saved_function_list_end = NULL; | |
8495 | - | |
8496 | -static void | |
8497 | -clear_function_list (void) | |
8498 | -{ | |
8499 | - SAVED_FUNCTION_PTR tmp = saved_function_list; | |
8500 | - SAVED_FUNCTION_PTR next = NULL; | |
8501 | - | |
8502 | - while (tmp != NULL) | |
8503 | - { | |
8504 | - next = tmp->next; | |
8505 | - xfree (tmp); | |
8506 | - tmp = next; | |
8507 | - } | |
8508 | - | |
8509 | - saved_function_list = NULL; | |
8510 | -} | |
8511 | -#endif | |
8512 | diff --git a/gdb/f-lang.h b/gdb/f-lang.h | |
7566401a | 8513 | index 711bdba..9d7d92b 100644 |
3a58abaf AM |
8514 | --- a/gdb/f-lang.h |
8515 | +++ b/gdb/f-lang.h | |
8516 | @@ -28,6 +28,10 @@ extern void f_error (char *); /* Defined in f-exp.y */ | |
8517 | extern void f_print_type (struct type *, char *, struct ui_file *, int, | |
8518 | int); | |
8519 | ||
8520 | +extern const char *f_object_address_data_valid_print_to_stream | |
8521 | + (struct type *type, struct ui_file *stream); | |
8522 | +extern void f_object_address_data_valid_or_error (struct type *type); | |
8523 | + | |
8524 | extern int f_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, | |
8525 | struct ui_file *, int, | |
8526 | const struct value_print_options *); | |
8527 | @@ -47,41 +51,8 @@ enum f90_range_type | |
8528 | NONE_BOUND_DEFAULT /* "(low:high)" */ | |
8529 | }; | |
8530 | ||
8531 | -struct common_entry | |
8532 | - { | |
8533 | - struct symbol *symbol; /* The symbol node corresponding | |
8534 | - to this component */ | |
8535 | - struct common_entry *next; /* The next component */ | |
8536 | - }; | |
8537 | - | |
8538 | -struct saved_f77_common | |
8539 | - { | |
8540 | - char *name; /* Name of COMMON */ | |
8541 | - char *owning_function; /* Name of parent function */ | |
8542 | - int secnum; /* Section # of .bss */ | |
8543 | - CORE_ADDR offset; /* Offset from .bss for | |
8544 | - this block */ | |
8545 | - struct common_entry *entries; /* List of block's components */ | |
8546 | - struct common_entry *end_of_entries; /* ptr. to end of components */ | |
8547 | - struct saved_f77_common *next; /* Next saved COMMON block */ | |
8548 | - }; | |
8549 | - | |
8550 | -typedef struct saved_f77_common SAVED_F77_COMMON, *SAVED_F77_COMMON_PTR; | |
8551 | - | |
8552 | -typedef struct common_entry COMMON_ENTRY, *COMMON_ENTRY_PTR; | |
8553 | - | |
8554 | -extern SAVED_F77_COMMON_PTR head_common_list; /* Ptr to 1st saved COMMON */ | |
8555 | -extern SAVED_F77_COMMON_PTR tail_common_list; /* Ptr to last saved COMMON */ | |
8556 | -extern SAVED_F77_COMMON_PTR current_common; /* Ptr to current COMMON */ | |
8557 | - | |
8558 | -extern SAVED_F77_COMMON_PTR find_common_for_function (char *, char *); | |
8559 | - | |
8560 | -#define UNINITIALIZED_SECNUM -1 | |
8561 | -#define COMMON_NEEDS_PATCHING(blk) ((blk)->secnum == UNINITIALIZED_SECNUM) | |
8562 | - | |
8563 | #define BLANK_COMMON_NAME_ORIGINAL "#BLNK_COM" /* XLF assigned */ | |
8564 | #define BLANK_COMMON_NAME_MF77 "__BLNK__" /* MF77 assigned */ | |
8565 | -#define BLANK_COMMON_NAME_LOCAL "__BLANK" /* Local GDB */ | |
8566 | ||
8567 | /* When reasonable array bounds cannot be fetched, such as when | |
8568 | you ask to 'mt print symbols' and there is no stack frame and | |
8569 | @@ -113,6 +84,7 @@ struct builtin_f_type | |
8570 | struct type *builtin_logical; | |
8571 | struct type *builtin_logical_s1; | |
8572 | struct type *builtin_logical_s2; | |
8573 | + struct type *builtin_logical_s8; | |
8574 | struct type *builtin_real; | |
8575 | struct type *builtin_real_s8; | |
8576 | struct type *builtin_real_s16; | |
7566401a ER |
8577 | @@ -125,3 +97,10 @@ struct builtin_f_type |
8578 | /* Return the Fortran type table for the specified architecture. */ | |
8579 | extern const struct builtin_f_type *builtin_f_type (struct gdbarch *gdbarch); | |
8580 | ||
8581 | +/* List of module names being imported by a block though BLOCK_FORTRAN_USE. */ | |
8582 | + | |
8583 | +struct fortran_using | |
8584 | + { | |
8585 | + struct fortran_using *next; | |
8586 | + char module_name[1]; | |
8587 | + }; | |
3a58abaf AM |
8588 | diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c |
8589 | index 6c9668f..852b9a8 100644 | |
8590 | --- a/gdb/f-typeprint.c | |
8591 | +++ b/gdb/f-typeprint.c | |
8592 | @@ -31,7 +31,7 @@ | |
8593 | #include "gdbcore.h" | |
8594 | #include "target.h" | |
8595 | #include "f-lang.h" | |
8596 | - | |
8597 | +#include "dwarf2loc.h" | |
8598 | #include "gdb_string.h" | |
8599 | #include <errno.h> | |
8600 | ||
8601 | @@ -48,6 +48,34 @@ void f_type_print_varspec_prefix (struct type *, struct ui_file *, | |
8602 | void f_type_print_base (struct type *, struct ui_file *, int, int); | |
8603 | \f | |
8604 | ||
8605 | +const char * | |
8606 | +f_object_address_data_valid_print_to_stream (struct type *type, | |
8607 | + struct ui_file *stream) | |
8608 | +{ | |
8609 | + const char *msg; | |
8610 | + | |
8611 | + msg = object_address_data_not_valid (type); | |
8612 | + if (msg != NULL) | |
8613 | + { | |
8614 | + /* Assuming the content printed to STREAM should not be localized. */ | |
8615 | + fprintf_filtered (stream, "<%s>", msg); | |
8616 | + } | |
8617 | + | |
8618 | + return msg; | |
8619 | +} | |
8620 | + | |
8621 | +void | |
8622 | +f_object_address_data_valid_or_error (struct type *type) | |
8623 | +{ | |
8624 | + const char *msg; | |
8625 | + | |
8626 | + msg = object_address_data_not_valid (type); | |
8627 | + if (msg != NULL) | |
8628 | + { | |
8629 | + error (_("Cannot access it because the %s."), _(msg)); | |
8630 | + } | |
8631 | +} | |
8632 | + | |
8633 | /* LEVEL is the depth to indent lines by. */ | |
8634 | ||
8635 | void | |
8636 | @@ -57,6 +85,9 @@ f_print_type (struct type *type, char *varstring, struct ui_file *stream, | |
8637 | enum type_code code; | |
8638 | int demangled_args; | |
8639 | ||
8640 | + if (f_object_address_data_valid_print_to_stream (type, stream) != NULL) | |
8641 | + return; | |
8642 | + | |
8643 | f_type_print_base (type, stream, show, level); | |
8644 | code = TYPE_CODE (type); | |
8645 | if ((varstring != NULL && *varstring != '\0') | |
8646 | @@ -166,6 +197,9 @@ f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, | |
8647 | ||
8648 | QUIT; | |
8649 | ||
8650 | + if (TYPE_CODE (type) != TYPE_CODE_TYPEDEF) | |
8651 | + CHECK_TYPEDEF (type); | |
8652 | + | |
8653 | switch (TYPE_CODE (type)) | |
8654 | { | |
8655 | case TYPE_CODE_ARRAY: | |
8656 | diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c | |
7566401a | 8657 | index 0a57404..a9ccc77 100644 |
3a58abaf AM |
8658 | --- a/gdb/f-valprint.c |
8659 | +++ b/gdb/f-valprint.c | |
8660 | @@ -34,10 +34,8 @@ | |
8661 | #include "gdbcore.h" | |
8662 | #include "command.h" | |
8663 | #include "block.h" | |
8664 | - | |
8665 | -#if 0 | |
8666 | -static int there_is_a_visible_common_named (char *); | |
8667 | -#endif | |
8668 | +#include "dictionary.h" | |
8669 | +#include "gdb_assert.h" | |
8670 | ||
8671 | extern void _initialize_f_valprint (void); | |
8672 | static void info_common_command (char *, int); | |
8673 | @@ -54,15 +52,17 @@ int f77_array_offset_tbl[MAX_FORTRAN_DIMS + 1][2]; | |
8674 | /* The following macro gives us the size of the nth dimension, Where | |
8675 | n is 1 based. */ | |
8676 | ||
8677 | -#define F77_DIM_SIZE(n) (f77_array_offset_tbl[n][1]) | |
8678 | +#define F77_DIM_COUNT(n) (f77_array_offset_tbl[n][1]) | |
8679 | ||
8680 | -/* The following gives us the offset for row n where n is 1-based. */ | |
8681 | +/* The following gives us the element size for row n where n is 1-based. */ | |
8682 | ||
8683 | -#define F77_DIM_OFFSET(n) (f77_array_offset_tbl[n][0]) | |
8684 | +#define F77_DIM_BYTE_STRIDE(n) (f77_array_offset_tbl[n][0]) | |
8685 | ||
8686 | int | |
8687 | f77_get_lowerbound (struct type *type) | |
8688 | { | |
8689 | + f_object_address_data_valid_or_error (type); | |
8690 | + | |
8691 | if (TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED (type)) | |
8692 | error (_("Lower bound may not be '*' in F77")); | |
8693 | ||
8694 | @@ -72,14 +72,17 @@ f77_get_lowerbound (struct type *type) | |
8695 | int | |
8696 | f77_get_upperbound (struct type *type) | |
8697 | { | |
8698 | + f_object_address_data_valid_or_error (type); | |
8699 | + | |
8700 | if (TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)) | |
8701 | { | |
8702 | - /* We have an assumed size array on our hands. Assume that | |
8703 | - upper_bound == lower_bound so that we show at least 1 element. | |
8704 | - If the user wants to see more elements, let him manually ask for 'em | |
8705 | - and we'll subscript the array and show him. */ | |
8706 | + /* We have an assumed size array on our hands. As type_length_get | |
8707 | + already assumes a length zero of arrays with underfined bounds VALADDR | |
8708 | + passed to the Fortran functions does not contained the real inferior | |
8709 | + memory content. User should request printing of specific array | |
8710 | + elements instead. */ | |
8711 | ||
8712 | - return f77_get_lowerbound (type); | |
8713 | + return f77_get_lowerbound (type) - 1; | |
8714 | } | |
8715 | ||
8716 | return TYPE_ARRAY_UPPER_BOUND_VALUE (type); | |
8717 | @@ -135,24 +138,29 @@ f77_create_arrayprint_offset_tbl (struct type *type, struct ui_file *stream) | |
8718 | upper = f77_get_upperbound (tmp_type); | |
8719 | lower = f77_get_lowerbound (tmp_type); | |
8720 | ||
8721 | - F77_DIM_SIZE (ndimen) = upper - lower + 1; | |
8722 | + F77_DIM_COUNT (ndimen) = upper - lower + 1; | |
8723 | + | |
8724 | + F77_DIM_BYTE_STRIDE (ndimen) = | |
8725 | + TYPE_ARRAY_BYTE_STRIDE_VALUE (tmp_type); | |
8726 | ||
8727 | tmp_type = TYPE_TARGET_TYPE (tmp_type); | |
8728 | ndimen++; | |
8729 | } | |
8730 | ||
8731 | - /* Now we multiply eltlen by all the offsets, so that later we | |
8732 | + /* Now we multiply eltlen by all the BYTE_STRIDEs, so that later we | |
8733 | can print out array elements correctly. Up till now we | |
8734 | - know an offset to apply to get the item but we also | |
8735 | + know an eltlen to apply to get the item but we also | |
8736 | have to know how much to add to get to the next item */ | |
8737 | ||
8738 | ndimen--; | |
8739 | eltlen = TYPE_LENGTH (tmp_type); | |
8740 | - F77_DIM_OFFSET (ndimen) = eltlen; | |
8741 | + if (F77_DIM_BYTE_STRIDE (ndimen) == 0) | |
8742 | + F77_DIM_BYTE_STRIDE (ndimen) = eltlen; | |
8743 | while (--ndimen > 0) | |
8744 | { | |
8745 | - eltlen *= F77_DIM_SIZE (ndimen + 1); | |
8746 | - F77_DIM_OFFSET (ndimen) = eltlen; | |
8747 | + eltlen *= F77_DIM_COUNT (ndimen + 1); | |
8748 | + if (F77_DIM_BYTE_STRIDE (ndimen) == 0) | |
8749 | + F77_DIM_BYTE_STRIDE (ndimen) = eltlen; | |
8750 | } | |
8751 | } | |
8752 | ||
8753 | @@ -172,34 +180,34 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type, | |
8754 | ||
8755 | if (nss != ndimensions) | |
8756 | { | |
8757 | - for (i = 0; (i < F77_DIM_SIZE (nss) && (*elts) < options->print_max); i++) | |
8758 | + for (i = 0; (i < F77_DIM_COUNT (nss) && (*elts) < options->print_max); i++) | |
8759 | { | |
8760 | fprintf_filtered (stream, "( "); | |
8761 | f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type), | |
8762 | - valaddr + i * F77_DIM_OFFSET (nss), | |
8763 | - address + i * F77_DIM_OFFSET (nss), | |
8764 | + valaddr + i * F77_DIM_BYTE_STRIDE (nss), | |
8765 | + address + i * F77_DIM_BYTE_STRIDE (nss), | |
8766 | stream, recurse, options, elts); | |
8767 | fprintf_filtered (stream, ") "); | |
8768 | } | |
8769 | - if (*elts >= options->print_max && i < F77_DIM_SIZE (nss)) | |
8770 | + if (*elts >= options->print_max && i < F77_DIM_COUNT (nss)) | |
8771 | fprintf_filtered (stream, "..."); | |
8772 | } | |
8773 | else | |
8774 | { | |
8775 | - for (i = 0; i < F77_DIM_SIZE (nss) && (*elts) < options->print_max; | |
8776 | + for (i = 0; i < F77_DIM_COUNT (nss) && (*elts) < options->print_max; | |
8777 | i++, (*elts)++) | |
8778 | { | |
8779 | val_print (TYPE_TARGET_TYPE (type), | |
8780 | - valaddr + i * F77_DIM_OFFSET (ndimensions), | |
8781 | + valaddr + i * F77_DIM_BYTE_STRIDE (ndimensions), | |
8782 | 0, | |
8783 | - address + i * F77_DIM_OFFSET (ndimensions), | |
8784 | + address + i * F77_DIM_BYTE_STRIDE (ndimensions), | |
8785 | stream, recurse, options, current_language); | |
8786 | ||
8787 | - if (i != (F77_DIM_SIZE (nss) - 1)) | |
8788 | + if (i != (F77_DIM_COUNT (nss) - 1)) | |
8789 | fprintf_filtered (stream, ", "); | |
8790 | ||
8791 | if ((*elts == options->print_max - 1) | |
8792 | - && (i != (F77_DIM_SIZE (nss) - 1))) | |
8793 | + && (i != (F77_DIM_COUNT (nss) - 1))) | |
8794 | fprintf_filtered (stream, "..."); | |
8795 | } | |
8796 | } | |
7566401a | 8797 | @@ -253,6 +261,9 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, |
3a58abaf AM |
8798 | CORE_ADDR addr; |
8799 | int index; | |
8800 | ||
8801 | + if (f_object_address_data_valid_print_to_stream (type, stream) != NULL) | |
8802 | + return 0; | |
8803 | + | |
8804 | CHECK_TYPEDEF (type); | |
8805 | switch (TYPE_CODE (type)) | |
8806 | { | |
7566401a | 8807 | @@ -467,22 +478,54 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, |
3a58abaf AM |
8808 | return 0; |
8809 | } | |
8810 | ||
8811 | -static void | |
8812 | -list_all_visible_commons (char *funname) | |
8813 | +static int | |
8814 | +info_common_command_for_block (struct block *block, struct frame_info *frame, | |
8815 | + const char *comname) | |
8816 | { | |
8817 | - SAVED_F77_COMMON_PTR tmp; | |
8818 | - | |
8819 | - tmp = head_common_list; | |
8820 | - | |
8821 | - printf_filtered (_("All COMMON blocks visible at this level:\n\n")); | |
8822 | - | |
8823 | - while (tmp != NULL) | |
8824 | - { | |
8825 | - if (strcmp (tmp->owning_function, funname) == 0) | |
8826 | - printf_filtered ("%s\n", tmp->name); | |
8827 | - | |
8828 | - tmp = tmp->next; | |
8829 | - } | |
8830 | + struct dict_iterator iter; | |
8831 | + struct symbol *sym; | |
8832 | + int values_printed = 0; | |
8833 | + const char *name; | |
8834 | + struct value_print_options opts; | |
8835 | + | |
8836 | + get_user_print_options (&opts); | |
8837 | + | |
8838 | + ALL_BLOCK_SYMBOLS (block, iter, sym) | |
8839 | + if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN) | |
8840 | + { | |
8841 | + struct type *type = SYMBOL_TYPE (sym); | |
8842 | + int index; | |
8843 | + | |
8844 | + gdb_assert (SYMBOL_CLASS (sym) == LOC_STATIC); | |
8845 | + gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT); | |
8846 | + | |
8847 | + if (comname && (!SYMBOL_LINKAGE_NAME (sym) | |
8848 | + || strcmp (comname, SYMBOL_LINKAGE_NAME (sym)) != 0)) | |
8849 | + continue; | |
8850 | + | |
8851 | + values_printed = 1; | |
8852 | + if (SYMBOL_PRINT_NAME (sym)) | |
8853 | + printf_filtered (_("Contents of F77 COMMON block '%s':\n"), | |
8854 | + SYMBOL_PRINT_NAME (sym)); | |
8855 | + else | |
8856 | + printf_filtered (_("Contents of blank COMMON block:\n")); | |
8857 | + | |
8858 | + for (index = 0; index < TYPE_NFIELDS (type); index++) | |
8859 | + { | |
8860 | + struct value *val; | |
8861 | + | |
8862 | + gdb_assert (field_is_static (&TYPE_FIELD (type, index))); | |
8863 | + val = value_static_field (type, index); | |
8864 | + | |
8865 | + printf_filtered ("%s = ", TYPE_FIELD_NAME (type, index)); | |
8866 | + value_print (val, gdb_stdout, &opts); | |
8867 | + putchar_filtered ('\n'); | |
8868 | + } | |
8869 | + | |
8870 | + putchar_filtered ('\n'); | |
8871 | + } | |
8872 | + | |
8873 | + return values_printed; | |
8874 | } | |
8875 | ||
8876 | /* This function is used to print out the values in a given COMMON | |
7566401a | 8877 | @@ -492,11 +535,9 @@ list_all_visible_commons (char *funname) |
3a58abaf AM |
8878 | static void |
8879 | info_common_command (char *comname, int from_tty) | |
8880 | { | |
8881 | - SAVED_F77_COMMON_PTR the_common; | |
8882 | - COMMON_ENTRY_PTR entry; | |
8883 | struct frame_info *fi; | |
8884 | - char *funname = 0; | |
8885 | - struct symbol *func; | |
8886 | + struct block *block; | |
8887 | + int values_printed = 0; | |
8888 | ||
8889 | /* We have been told to display the contents of F77 COMMON | |
8890 | block supposedly visible in this function. Let us | |
7566401a | 8891 | @@ -508,136 +549,32 @@ info_common_command (char *comname, int from_tty) |
3a58abaf AM |
8892 | /* The following is generally ripped off from stack.c's routine |
8893 | print_frame_info() */ | |
8894 | ||
8895 | - func = find_pc_function (get_frame_pc (fi)); | |
8896 | - if (func) | |
8897 | - { | |
8898 | - /* In certain pathological cases, the symtabs give the wrong | |
8899 | - function (when we are in the first function in a file which | |
8900 | - is compiled without debugging symbols, the previous function | |
8901 | - is compiled with debugging symbols, and the "foo.o" symbol | |
8902 | - that is supposed to tell us where the file with debugging symbols | |
8903 | - ends has been truncated by ar because it is longer than 15 | |
8904 | - characters). | |
8905 | - | |
8906 | - So look in the minimal symbol tables as well, and if it comes | |
8907 | - up with a larger address for the function use that instead. | |
8908 | - I don't think this can ever cause any problems; there shouldn't | |
8909 | - be any minimal symbols in the middle of a function. | |
8910 | - FIXME: (Not necessarily true. What about text labels) */ | |
8911 | - | |
8912 | - struct minimal_symbol *msymbol = | |
8913 | - lookup_minimal_symbol_by_pc (get_frame_pc (fi)); | |
8914 | - | |
8915 | - if (msymbol != NULL | |
8916 | - && (SYMBOL_VALUE_ADDRESS (msymbol) | |
8917 | - > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) | |
8918 | - funname = SYMBOL_LINKAGE_NAME (msymbol); | |
8919 | - else | |
8920 | - funname = SYMBOL_LINKAGE_NAME (func); | |
8921 | - } | |
8922 | - else | |
8923 | - { | |
8924 | - struct minimal_symbol *msymbol = | |
8925 | - lookup_minimal_symbol_by_pc (get_frame_pc (fi)); | |
8926 | - | |
8927 | - if (msymbol != NULL) | |
8928 | - funname = SYMBOL_LINKAGE_NAME (msymbol); | |
8929 | - else /* Got no 'funname', code below will fail. */ | |
8930 | - error (_("No function found for frame.")); | |
8931 | - } | |
8932 | - | |
8933 | - /* If comname is NULL, we assume the user wishes to see the | |
8934 | - which COMMON blocks are visible here and then return */ | |
8935 | - | |
8936 | - if (comname == 0) | |
8937 | + block = get_frame_block (fi, 0); | |
8938 | + if (block == NULL) | |
8939 | { | |
8940 | - list_all_visible_commons (funname); | |
8941 | + printf_filtered (_("No symbol table info available.\n")); | |
8942 | return; | |
8943 | } | |
8944 | ||
8945 | - the_common = find_common_for_function (comname, funname); | |
8946 | - | |
8947 | - if (the_common) | |
8948 | + while (block) | |
8949 | { | |
8950 | - if (strcmp (comname, BLANK_COMMON_NAME_LOCAL) == 0) | |
8951 | - printf_filtered (_("Contents of blank COMMON block:\n")); | |
8952 | - else | |
8953 | - printf_filtered (_("Contents of F77 COMMON block '%s':\n"), comname); | |
8954 | - | |
8955 | - printf_filtered ("\n"); | |
8956 | - entry = the_common->entries; | |
8957 | - | |
8958 | - while (entry != NULL) | |
8959 | - { | |
8960 | - print_variable_and_value (NULL, entry->symbol, fi, gdb_stdout, 0); | |
8961 | - entry = entry->next; | |
8962 | - } | |
8963 | + if (info_common_command_for_block (block, fi, comname)) | |
8964 | + values_printed = 1; | |
8965 | + /* After handling the function's top-level block, stop. Don't | |
8966 | + continue to its superblock, the block of per-file symbols. */ | |
8967 | + if (BLOCK_FUNCTION (block)) | |
8968 | + break; | |
8969 | + block = BLOCK_SUPERBLOCK (block); | |
8970 | } | |
8971 | - else | |
8972 | - printf_filtered (_("Cannot locate the common block %s in function '%s'\n"), | |
8973 | - comname, funname); | |
8974 | -} | |
8975 | - | |
8976 | -/* This function is used to determine whether there is a | |
8977 | - F77 common block visible at the current scope called 'comname'. */ | |
8978 | - | |
8979 | -#if 0 | |
8980 | -static int | |
8981 | -there_is_a_visible_common_named (char *comname) | |
8982 | -{ | |
8983 | - SAVED_F77_COMMON_PTR the_common; | |
8984 | - struct frame_info *fi; | |
8985 | - char *funname = 0; | |
8986 | - struct symbol *func; | |
8987 | - | |
8988 | - if (comname == NULL) | |
8989 | - error (_("Cannot deal with NULL common name!")); | |
8990 | ||
8991 | - fi = get_selected_frame (_("No frame selected")); | |
8992 | - | |
8993 | - /* The following is generally ripped off from stack.c's routine | |
8994 | - print_frame_info() */ | |
8995 | - | |
8996 | - func = find_pc_function (fi->pc); | |
8997 | - if (func) | |
8998 | + if (!values_printed) | |
8999 | { | |
9000 | - /* In certain pathological cases, the symtabs give the wrong | |
9001 | - function (when we are in the first function in a file which | |
9002 | - is compiled without debugging symbols, the previous function | |
9003 | - is compiled with debugging symbols, and the "foo.o" symbol | |
9004 | - that is supposed to tell us where the file with debugging symbols | |
9005 | - ends has been truncated by ar because it is longer than 15 | |
9006 | - characters). | |
9007 | - | |
9008 | - So look in the minimal symbol tables as well, and if it comes | |
9009 | - up with a larger address for the function use that instead. | |
9010 | - I don't think this can ever cause any problems; there shouldn't | |
9011 | - be any minimal symbols in the middle of a function. | |
9012 | - FIXME: (Not necessarily true. What about text labels) */ | |
9013 | - | |
9014 | - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); | |
9015 | - | |
9016 | - if (msymbol != NULL | |
9017 | - && (SYMBOL_VALUE_ADDRESS (msymbol) | |
9018 | - > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) | |
9019 | - funname = SYMBOL_LINKAGE_NAME (msymbol); | |
9020 | + if (comname) | |
9021 | + printf_filtered (_("No common block '%s'.\n"), comname); | |
9022 | else | |
9023 | - funname = SYMBOL_LINKAGE_NAME (func); | |
9024 | + printf_filtered (_("No common blocks.\n")); | |
9025 | } | |
9026 | - else | |
9027 | - { | |
9028 | - struct minimal_symbol *msymbol = | |
9029 | - lookup_minimal_symbol_by_pc (fi->pc); | |
9030 | - | |
9031 | - if (msymbol != NULL) | |
9032 | - funname = SYMBOL_LINKAGE_NAME (msymbol); | |
9033 | - } | |
9034 | - | |
9035 | - the_common = find_common_for_function (comname, funname); | |
9036 | - | |
9037 | - return (the_common ? 1 : 0); | |
9038 | } | |
9039 | -#endif | |
9040 | ||
9041 | void | |
9042 | _initialize_f_valprint (void) | |
9043 | diff --git a/gdb/findcmd.c b/gdb/findcmd.c | |
7566401a | 9044 | index 1d28914..d176341 100644 |
3a58abaf AM |
9045 | --- a/gdb/findcmd.c |
9046 | +++ b/gdb/findcmd.c | |
7566401a | 9047 | @@ -27,7 +27,7 @@ |
3a58abaf AM |
9048 | |
9049 | /* Copied from bfd_put_bits. */ | |
9050 | ||
9051 | -static void | |
9052 | +void | |
9053 | put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p) | |
9054 | { | |
9055 | int i; | |
7566401a | 9056 | @@ -45,6 +45,41 @@ put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p) |
3a58abaf AM |
9057 | } |
9058 | } | |
9059 | ||
9060 | +/* Allocates a buffer in *PATTERN_BUF, with a hard-coded initial size which | |
9061 | + will be returned in *PATTERN_BUF_SIZE. *PATTERN_BUF_END points to the same | |
9062 | + place as *PATTERN_BUF, indicating that the buffer is initially empty. */ | |
9063 | + | |
9064 | +void | |
9065 | +allocate_pattern_buffer (char **pattern_buf, char **pattern_buf_end, | |
9066 | + ULONGEST *pattern_buf_size) | |
9067 | +{ | |
9068 | +#define INITIAL_PATTERN_BUF_SIZE 100 | |
9069 | + *pattern_buf_size = INITIAL_PATTERN_BUF_SIZE; | |
9070 | + *pattern_buf = xmalloc (*pattern_buf_size); | |
9071 | + *pattern_buf_end = *pattern_buf; | |
9072 | +} | |
9073 | + | |
9074 | +/* Grows *PATTERN_BUF by a factor of two if it's not large enough to hold | |
9075 | + VAL_BYTES more bytes or a 64-bit value, whichever is larger. | |
9076 | + *PATTERN_BUF_END is updated as necessary. */ | |
9077 | + | |
9078 | +void | |
9079 | +increase_pattern_buffer (char **pattern_buf, char **pattern_buf_end, | |
9080 | + ULONGEST *pattern_buf_size, int val_bytes) | |
9081 | +{ | |
9082 | + /* Keep it simple and assume size == 'g' when watching for when we | |
9083 | + need to grow the pattern buf. */ | |
9084 | + if ((*pattern_buf_end - *pattern_buf + max (val_bytes, sizeof (int64_t))) | |
9085 | + > *pattern_buf_size) | |
9086 | + { | |
9087 | + size_t current_offset = *pattern_buf_end - *pattern_buf; | |
9088 | + | |
9089 | + *pattern_buf_size *= 2; | |
9090 | + *pattern_buf = xrealloc (*pattern_buf, *pattern_buf_size); | |
9091 | + *pattern_buf_end = *pattern_buf + current_offset; | |
9092 | + } | |
9093 | +} | |
9094 | + | |
9095 | /* Subroutine of find_command to simplify it. | |
9096 | Parse the arguments of the "find" command. */ | |
9097 | ||
7566401a | 9098 | @@ -61,8 +96,7 @@ parse_find_args (char *args, ULONGEST *max_countp, |
3a58abaf AM |
9099 | char *pattern_buf; |
9100 | /* Current size of search pattern buffer. | |
9101 | We realloc space as needed. */ | |
9102 | -#define INITIAL_PATTERN_BUF_SIZE 100 | |
9103 | - ULONGEST pattern_buf_size = INITIAL_PATTERN_BUF_SIZE; | |
9104 | + ULONGEST pattern_buf_size; | |
9105 | /* Pointer to one past the last in-use part of pattern_buf. */ | |
9106 | char *pattern_buf_end; | |
9107 | ULONGEST pattern_len; | |
7566401a | 9108 | @@ -75,8 +109,7 @@ parse_find_args (char *args, ULONGEST *max_countp, |
3a58abaf AM |
9109 | if (args == NULL) |
9110 | error (_("Missing search parameters.")); | |
9111 | ||
9112 | - pattern_buf = xmalloc (pattern_buf_size); | |
9113 | - pattern_buf_end = pattern_buf; | |
9114 | + allocate_pattern_buffer (&pattern_buf, &pattern_buf_end, &pattern_buf_size); | |
9115 | old_cleanups = make_cleanup (free_current_contents, &pattern_buf); | |
9116 | ||
9117 | /* Get search granularity and/or max count if specified. | |
7566401a | 9118 | @@ -173,16 +206,8 @@ parse_find_args (char *args, ULONGEST *max_countp, |
3a58abaf AM |
9119 | v = parse_to_comma_and_eval (&s); |
9120 | val_bytes = TYPE_LENGTH (value_type (v)); | |
9121 | ||
9122 | - /* Keep it simple and assume size == 'g' when watching for when we | |
9123 | - need to grow the pattern buf. */ | |
9124 | - if ((pattern_buf_end - pattern_buf + max (val_bytes, sizeof (int64_t))) | |
9125 | - > pattern_buf_size) | |
9126 | - { | |
9127 | - size_t current_offset = pattern_buf_end - pattern_buf; | |
9128 | - pattern_buf_size *= 2; | |
9129 | - pattern_buf = xrealloc (pattern_buf, pattern_buf_size); | |
9130 | - pattern_buf_end = pattern_buf + current_offset; | |
9131 | - } | |
9132 | + increase_pattern_buffer (&pattern_buf, &pattern_buf_end, | |
9133 | + &pattern_buf_size, val_bytes); | |
9134 | ||
9135 | if (size != '\0') | |
9136 | { | |
7566401a | 9137 | @@ -237,6 +262,45 @@ parse_find_args (char *args, ULONGEST *max_countp, |
3a58abaf AM |
9138 | discard_cleanups (old_cleanups); |
9139 | } | |
9140 | ||
9141 | +/* Drives target_search_memory to sweep through the specified search space, | |
9142 | + possibly in several iterations (with one call to this function for each | |
9143 | + iteration). *START_ADDR is the address where the search starts, and is | |
9144 | + updated to the next starting address to continue the search. | |
9145 | + *SEARCH_SPACE_LEN is the amount of bytes which will be searched, and is | |
9146 | + updated for the next iteration. PATTERN_BUF holds the pattern to be searched | |
9147 | + for, PATTERN_LEN is the size of the pattern in bytes. If a match is found, | |
9148 | + it's address is put in *FOUND_ADDR. | |
9149 | + | |
9150 | + Returns 1 if found, 0 if not found, and -1 if there was an error requiring | |
9151 | + halting of the search (e.g. memory read error). */ | |
9152 | + | |
9153 | +int | |
9154 | +search_memory (CORE_ADDR *start_addr, ULONGEST *search_space_len, | |
9155 | + const char *pattern_buf, ULONGEST pattern_len, | |
9156 | + CORE_ADDR *found_addr) | |
9157 | +{ | |
9158 | + /* Offset from start of this iteration to the next iteration. */ | |
9159 | + ULONGEST next_iter_incr; | |
9160 | + int found; | |
9161 | + | |
9162 | + found = target_search_memory (*start_addr, *search_space_len, | |
9163 | + pattern_buf, pattern_len, found_addr); | |
9164 | + if (found <= 0) | |
9165 | + return found; | |
9166 | + | |
9167 | + /* Begin next iteration at one byte past this match. */ | |
9168 | + next_iter_incr = (*found_addr - *start_addr) + 1; | |
9169 | + | |
9170 | + /* For robustness, we don't let search_space_len go -ve here. */ | |
9171 | + if (*search_space_len >= next_iter_incr) | |
9172 | + *search_space_len -= next_iter_incr; | |
9173 | + else | |
9174 | + *search_space_len = 0; | |
9175 | + *start_addr += next_iter_incr; | |
9176 | + | |
9177 | + return found; | |
9178 | +} | |
9179 | + | |
9180 | static void | |
9181 | find_command (char *args, int from_tty) | |
9182 | { | |
7566401a | 9183 | @@ -267,12 +331,11 @@ find_command (char *args, int from_tty) |
3a58abaf AM |
9184 | while (search_space_len >= pattern_len |
9185 | && found_count < max_count) | |
9186 | { | |
9187 | - /* Offset from start of this iteration to the next iteration. */ | |
9188 | - ULONGEST next_iter_incr; | |
9189 | CORE_ADDR found_addr; | |
9190 | - int found = target_search_memory (start_addr, search_space_len, | |
9191 | - pattern_buf, pattern_len, &found_addr); | |
9192 | + int found; | |
9193 | ||
9194 | + found = search_memory (&start_addr, &search_space_len, pattern_buf, | |
9195 | + pattern_len, &found_addr); | |
9196 | if (found <= 0) | |
9197 | break; | |
9198 | ||
7566401a | 9199 | @@ -280,16 +343,6 @@ find_command (char *args, int from_tty) |
3a58abaf AM |
9200 | printf_filtered ("\n"); |
9201 | ++found_count; | |
9202 | last_found_addr = found_addr; | |
9203 | - | |
9204 | - /* Begin next iteration at one byte past this match. */ | |
9205 | - next_iter_incr = (found_addr - start_addr) + 1; | |
9206 | - | |
9207 | - /* For robustness, we don't let search_space_len go -ve here. */ | |
9208 | - if (search_space_len >= next_iter_incr) | |
9209 | - search_space_len -= next_iter_incr; | |
9210 | - else | |
9211 | - search_space_len = 0; | |
9212 | - start_addr += next_iter_incr; | |
9213 | } | |
9214 | ||
9215 | /* Record and print the results. */ | |
9216 | diff --git a/gdb/findvar.c b/gdb/findvar.c | |
7566401a | 9217 | index 8c027c9..d201f76 100644 |
3a58abaf AM |
9218 | --- a/gdb/findvar.c |
9219 | +++ b/gdb/findvar.c | |
9220 | @@ -35,6 +35,7 @@ | |
9221 | #include "user-regs.h" | |
9222 | #include "block.h" | |
9223 | #include "objfiles.h" | |
9224 | +#include "dwarf2loc.h" | |
9225 | ||
9226 | /* Basic byte-swapping routines. GDB has needed these for a long time... | |
9227 | All extract a target-format integer at ADDR which is LEN bytes long. */ | |
7566401a | 9228 | @@ -394,27 +395,16 @@ symbol_read_needs_frame (struct symbol *sym) |
3a58abaf AM |
9229 | /* Given a struct symbol for a variable, |
9230 | and a stack frame id, read the value of the variable | |
9231 | and return a (pointer to a) struct value containing the value. | |
9232 | - If the variable cannot be found, return a zero pointer. */ | |
9233 | + If the variable cannot be found, return a zero pointer. | |
9234 | + We have to first find the address of the variable before allocating struct | |
9235 | + value to return as its size may depend on DW_OP_PUSH_OBJECT_ADDRESS possibly | |
9236 | + used by its type. */ | |
9237 | ||
9238 | struct value * | |
9239 | read_var_value (struct symbol *var, struct frame_info *frame) | |
9240 | { | |
9241 | - struct value *v; | |
9242 | struct type *type = SYMBOL_TYPE (var); | |
9243 | CORE_ADDR addr; | |
9244 | - int len; | |
9245 | - | |
9246 | - if (SYMBOL_CLASS (var) == LOC_COMPUTED | |
9247 | - || SYMBOL_CLASS (var) == LOC_REGISTER) | |
9248 | - /* These cases do not use V. */ | |
9249 | - v = NULL; | |
9250 | - else | |
9251 | - { | |
9252 | - v = allocate_value (type); | |
9253 | - VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */ | |
9254 | - } | |
9255 | - | |
9256 | - len = TYPE_LENGTH (type); | |
9257 | ||
9258 | if (symbol_read_needs_frame (var)) | |
9259 | gdb_assert (frame); | |
7566401a | 9260 | @@ -422,32 +412,40 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
3a58abaf AM |
9261 | switch (SYMBOL_CLASS (var)) |
9262 | { | |
9263 | case LOC_CONST: | |
9264 | - /* Put the constant back in target format. */ | |
9265 | - store_signed_integer (value_contents_raw (v), len, | |
7566401a | 9266 | - gdbarch_byte_order (get_type_arch (type)), |
3a58abaf AM |
9267 | - (LONGEST) SYMBOL_VALUE (var)); |
9268 | - VALUE_LVAL (v) = not_lval; | |
9269 | - return v; | |
9270 | + { | |
9271 | + /* Put the constant back in target format. */ | |
9272 | + struct value *v = allocate_value (type); | |
9273 | + VALUE_LVAL (v) = not_lval; | |
9274 | + store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type), | |
7566401a | 9275 | + gdbarch_byte_order (get_type_arch (type)), |
3a58abaf AM |
9276 | + (LONGEST) SYMBOL_VALUE (var)); |
9277 | + return v; | |
9278 | + } | |
9279 | ||
9280 | case LOC_LABEL: | |
9281 | - /* Put the constant back in target format. */ | |
9282 | - if (overlay_debugging) | |
9283 | - { | |
9284 | - CORE_ADDR addr | |
9285 | - = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), | |
9286 | - SYMBOL_OBJ_SECTION (var)); | |
9287 | - store_typed_address (value_contents_raw (v), type, addr); | |
9288 | - } | |
9289 | - else | |
9290 | - store_typed_address (value_contents_raw (v), type, | |
9291 | - SYMBOL_VALUE_ADDRESS (var)); | |
9292 | - VALUE_LVAL (v) = not_lval; | |
9293 | - return v; | |
9294 | + { | |
9295 | + /* Put the constant back in target format. */ | |
9296 | + struct value *v = allocate_value (type); | |
9297 | + VALUE_LVAL (v) = not_lval; | |
9298 | + if (overlay_debugging) | |
9299 | + { | |
9300 | + CORE_ADDR addr | |
9301 | + = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), | |
9302 | + SYMBOL_OBJ_SECTION (var)); | |
9303 | + store_typed_address (value_contents_raw (v), type, addr); | |
9304 | + } | |
9305 | + else | |
9306 | + store_typed_address (value_contents_raw (v), type, | |
9307 | + SYMBOL_VALUE_ADDRESS (var)); | |
9308 | + return v; | |
9309 | + } | |
9310 | ||
9311 | case LOC_CONST_BYTES: | |
9312 | { | |
9313 | - memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), len); | |
9314 | + struct value *v = allocate_value (type); | |
9315 | VALUE_LVAL (v) = not_lval; | |
9316 | + memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), | |
9317 | + TYPE_LENGTH (type)); | |
9318 | return v; | |
9319 | } | |
9320 | ||
7566401a | 9321 | @@ -489,12 +487,23 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
3a58abaf AM |
9322 | break; |
9323 | ||
9324 | case LOC_BLOCK: | |
9325 | - if (overlay_debugging) | |
7566401a ER |
9326 | - set_value_address (v, symbol_overlayed_address |
9327 | - (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var))); | |
3a58abaf | 9328 | - else |
7566401a | 9329 | - set_value_address (v, BLOCK_START (SYMBOL_BLOCK_VALUE (var))); |
3a58abaf AM |
9330 | - return v; |
9331 | + { | |
9332 | + CORE_ADDR addr; | |
9333 | + struct value *v; | |
9334 | + | |
9335 | + if (overlay_debugging) | |
9336 | + addr = symbol_overlayed_address | |
9337 | + (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var)); | |
9338 | + else | |
9339 | + addr = BLOCK_START (SYMBOL_BLOCK_VALUE (var)); | |
9340 | + /* ADDR is set here for ALLOCATE_VALUE's CHECK_TYPEDEF for | |
9341 | + DW_OP_push_object_address. */ | |
9342 | + object_address_set (addr); | |
9343 | + v = allocate_value (type); | |
3a58abaf | 9344 | + VALUE_LVAL (v) = lval_memory; |
7566401a | 9345 | + set_value_address (v, addr); |
3a58abaf AM |
9346 | + return v; |
9347 | + } | |
9348 | ||
9349 | case LOC_REGISTER: | |
9350 | case LOC_REGPARM_ADDR: | |
7566401a | 9351 | @@ -513,7 +522,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
3a58abaf AM |
9352 | error (_("Value of register variable not available.")); |
9353 | ||
9354 | addr = value_as_address (regval); | |
9355 | - VALUE_LVAL (v) = lval_memory; | |
9356 | } | |
9357 | else | |
9358 | { | |
7566401a | 9359 | @@ -556,18 +564,33 @@ read_var_value (struct symbol *var, struct frame_info *frame) |
3a58abaf AM |
9360 | break; |
9361 | ||
9362 | case LOC_OPTIMIZED_OUT: | |
9363 | - VALUE_LVAL (v) = not_lval; | |
9364 | - set_value_optimized_out (v, 1); | |
9365 | - return v; | |
9366 | + { | |
9367 | + struct value *v = allocate_value (type); | |
9368 | + | |
9369 | + VALUE_LVAL (v) = not_lval; | |
9370 | + set_value_optimized_out (v, 1); | |
9371 | + return v; | |
9372 | + } | |
9373 | ||
9374 | default: | |
9375 | error (_("Cannot look up value of a botched symbol.")); | |
9376 | break; | |
9377 | } | |
9378 | ||
7566401a | 9379 | - set_value_address (v, addr); |
3a58abaf AM |
9380 | - set_value_lazy (v, 1); |
9381 | - return v; | |
9382 | + { | |
9383 | + struct value *v; | |
9384 | + | |
9385 | + /* ADDR is set here for ALLOCATE_VALUE's CHECK_TYPEDEF for | |
9386 | + DW_OP_PUSH_OBJECT_ADDRESS. */ | |
9387 | + object_address_set (addr); | |
9388 | + v = allocate_value (type); | |
3a58abaf | 9389 | + VALUE_LVAL (v) = lval_memory; |
7566401a | 9390 | + set_value_address (v, addr); |
3a58abaf AM |
9391 | + |
9392 | + set_value_lazy (v, 1); | |
9393 | + | |
9394 | + return v; | |
9395 | + } | |
9396 | } | |
9397 | ||
9398 | /* Install default attributes for register values. */ | |
7566401a | 9399 | @@ -604,10 +627,11 @@ struct value * |
3a58abaf AM |
9400 | value_from_register (struct type *type, int regnum, struct frame_info *frame) |
9401 | { | |
9402 | struct gdbarch *gdbarch = get_frame_arch (frame); | |
9403 | - struct type *type1 = check_typedef (type); | |
9404 | struct value *v; | |
9405 | ||
9406 | - if (gdbarch_convert_register_p (gdbarch, regnum, type1)) | |
9407 | + type = check_typedef (type); | |
9408 | + | |
9409 | + if (gdbarch_convert_register_p (gdbarch, regnum, type)) | |
9410 | { | |
9411 | /* The ISA/ABI need to something weird when obtaining the | |
9412 | specified value from this register. It might need to | |
7566401a | 9413 | @@ -621,7 +645,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) |
3a58abaf AM |
9414 | VALUE_FRAME_ID (v) = get_frame_id (frame); |
9415 | VALUE_REGNUM (v) = regnum; | |
9416 | gdbarch_register_to_value (gdbarch, | |
9417 | - frame, regnum, type1, value_contents_raw (v)); | |
9418 | + frame, regnum, type, value_contents_raw (v)); | |
9419 | } | |
9420 | else | |
9421 | { | |
9422 | diff --git a/gdb/frame.c b/gdb/frame.c | |
7566401a | 9423 | index 7932b48..4e7c434 100644 |
3a58abaf AM |
9424 | --- a/gdb/frame.c |
9425 | +++ b/gdb/frame.c | |
7566401a ER |
9426 | @@ -1171,6 +1171,14 @@ has_stack_frames (void) |
9427 | if (ptid_equal (inferior_ptid, null_ptid)) | |
9428 | return 0; | |
3a58abaf | 9429 | |
7566401a ER |
9430 | + /* FIXME: Workaround archer-tromey-python crash in |
9431 | + add_inferior_object->get_current_arch on FSF GDB update: | |
9432 | + is_thread_state would assertion check here as | |
9433 | + remote_start_remote->add_inferior_silent->observer_notify_new_inferior is | |
9434 | + before remote_start_remote->add_thread_silent. */ | |
9435 | + if (find_thread_ptid (inferior_ptid) == NULL) | |
9436 | + return 0; | |
9437 | + | |
9438 | /* Don't try to read from a dead thread. */ | |
9439 | if (is_exited (inferior_ptid)) | |
9440 | return 0; | |
9441 | diff --git a/gdb/gdbinit.in b/gdb/gdbinit.in | |
9442 | index ffb7f53..a2e7e94 100644 | |
9443 | --- a/gdb/gdbinit.in | |
9444 | +++ b/gdb/gdbinit.in | |
9445 | @@ -1,5 +1,15 @@ | |
9446 | echo Setting up the environment for debugging gdb.\n | |
3a58abaf | 9447 | |
7566401a ER |
9448 | +# Set up the Python library and "require" command. |
9449 | +python | |
9450 | +from os.path import abspath | |
9451 | +gdb.datadir = abspath ('@srcdir@/python/lib') | |
9452 | +gdb.pythonlibdir = gdb.datadir | |
9453 | +gdb.__path__ = [gdb.datadir + '/gdb'] | |
9454 | +sys.path.insert(0, gdb.datadir) | |
9455 | +end | |
9456 | +source @srcdir@/python/lib/gdb/__init__.py | |
9457 | + | |
9458 | set complaints 1 | |
3a58abaf | 9459 | |
7566401a ER |
9460 | b internal_error |
9461 | diff --git a/gdb/gdbserver/linux-i386-low.c b/gdb/gdbserver/linux-i386-low.c | |
9462 | new file mode 100644 | |
9463 | index 0000000..b95c1b1 | |
9464 | --- /dev/null | |
9465 | +++ b/gdb/gdbserver/linux-i386-low.c | |
9466 | @@ -0,0 +1,210 @@ | |
9467 | +/* GNU/Linux/i386 specific low level interface, for the remote server for GDB. | |
9468 | + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, | |
9469 | + 2007, 2008, 2009 Free Software Foundation, Inc. | |
9470 | + | |
9471 | + This file is part of GDB. | |
9472 | + | |
9473 | + This program is free software; you can redistribute it and/or modify | |
9474 | + it under the terms of the GNU General Public License as published by | |
9475 | + the Free Software Foundation; either version 3 of the License, or | |
9476 | + (at your option) any later version. | |
9477 | + | |
9478 | + This program is distributed in the hope that it will be useful, | |
9479 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9480 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
9481 | + GNU General Public License for more details. | |
9482 | + | |
9483 | + You should have received a copy of the GNU General Public License | |
9484 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
9485 | + | |
9486 | +#include "server.h" | |
9487 | +#include "linux-low.h" | |
9488 | +#include "i387-fp.h" | |
9489 | + | |
9490 | +#include "gdb_proc_service.h" | |
9491 | + | |
9492 | +#include <sys/ptrace.h> | |
9493 | + | |
9494 | +#ifdef HAVE_SYS_REG_H | |
9495 | +#include <sys/reg.h> | |
3a58abaf AM |
9496 | +#endif |
9497 | + | |
7566401a ER |
9498 | +#ifndef PTRACE_GET_THREAD_AREA |
9499 | +#define PTRACE_GET_THREAD_AREA 25 | |
9500 | +#endif | |
3a58abaf | 9501 | + |
7566401a ER |
9502 | +/* Defined in auto-generated file reg-i386-linux.c. */ |
9503 | +void init_registers_i386_linux (void); | |
3a58abaf | 9504 | + |
3a58abaf | 9505 | + |
7566401a ER |
9506 | +/* This module only supports access to the general purpose registers. */ |
9507 | + | |
9508 | +#define i386_num_regs 16 | |
9509 | + | |
9510 | +/* This stuff comes from i386-linux-nat.c. */ | |
9511 | + | |
9512 | +/* Mapping between the general-purpose registers in `struct user' | |
9513 | + format and GDB's register array layout. */ | |
9514 | +static int i386_regmap[] = | |
3a58abaf | 9515 | +{ |
7566401a ER |
9516 | + EAX * 4, ECX * 4, EDX * 4, EBX * 4, |
9517 | + UESP * 4, EBP * 4, ESI * 4, EDI * 4, | |
9518 | + EIP * 4, EFL * 4, CS * 4, SS * 4, | |
9519 | + DS * 4, ES * 4, FS * 4, GS * 4 | |
9520 | +}; | |
3a58abaf | 9521 | + |
7566401a ER |
9522 | +/* Called by libthread_db. */ |
9523 | + | |
9524 | +ps_err_e | |
9525 | +ps_get_thread_area (const struct ps_prochandle *ph, | |
9526 | + lwpid_t lwpid, int idx, void **base) | |
3a58abaf | 9527 | +{ |
7566401a ER |
9528 | + unsigned int desc[4]; |
9529 | + | |
9530 | + if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, | |
9531 | + (void *) idx, (unsigned long) &desc) < 0) | |
9532 | + return PS_ERR; | |
9533 | + | |
9534 | + *(int *)base = desc[1]; | |
9535 | + return PS_OK; | |
3a58abaf AM |
9536 | +} |
9537 | + | |
7566401a ER |
9538 | +static int |
9539 | +i386_cannot_store_register (int regno) | |
3a58abaf | 9540 | +{ |
7566401a | 9541 | + return (regno >= i386_num_regs); |
3a58abaf AM |
9542 | +} |
9543 | + | |
7566401a ER |
9544 | +static int |
9545 | +i386_cannot_fetch_register (int regno) | |
3a58abaf | 9546 | +{ |
7566401a | 9547 | + return (regno >= i386_num_regs); |
3a58abaf AM |
9548 | +} |
9549 | + | |
7566401a ER |
9550 | + |
9551 | +#ifdef HAVE_PTRACE_GETREGS | |
9552 | +#include <sys/procfs.h> | |
9553 | +#include <sys/ptrace.h> | |
9554 | + | |
9555 | +static void | |
9556 | +i386_fill_gregset (void *buf) | |
3a58abaf | 9557 | +{ |
7566401a ER |
9558 | + int i; |
9559 | + | |
9560 | + for (i = 0; i < i386_num_regs; i++) | |
9561 | + collect_register (i, ((char *) buf) + i386_regmap[i]); | |
9562 | + | |
9563 | + collect_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4); | |
3a58abaf AM |
9564 | +} |
9565 | + | |
7566401a ER |
9566 | +static void |
9567 | +i386_store_gregset (const void *buf) | |
3a58abaf | 9568 | +{ |
7566401a ER |
9569 | + int i; |
9570 | + | |
9571 | + for (i = 0; i < i386_num_regs; i++) | |
9572 | + supply_register (i, ((char *) buf) + i386_regmap[i]); | |
9573 | + | |
9574 | + supply_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4); | |
3a58abaf AM |
9575 | +} |
9576 | + | |
7566401a ER |
9577 | +static void |
9578 | +i386_fill_fpregset (void *buf) | |
3a58abaf | 9579 | +{ |
7566401a | 9580 | + i387_cache_to_fsave (buf); |
3a58abaf AM |
9581 | +} |
9582 | + | |
7566401a ER |
9583 | +static void |
9584 | +i386_store_fpregset (const void *buf) | |
3a58abaf | 9585 | +{ |
7566401a | 9586 | + i387_fsave_to_cache (buf); |
3a58abaf AM |
9587 | +} |
9588 | + | |
7566401a ER |
9589 | +static void |
9590 | +i386_fill_fpxregset (void *buf) | |
3a58abaf | 9591 | +{ |
7566401a | 9592 | + i387_cache_to_fxsave (buf); |
3a58abaf AM |
9593 | +} |
9594 | + | |
7566401a ER |
9595 | +static void |
9596 | +i386_store_fpxregset (const void *buf) | |
9597 | +{ | |
9598 | + i387_fxsave_to_cache (buf); | |
9599 | +} | |
9600 | + | |
9601 | +#endif /* HAVE_PTRACE_GETREGS */ | |
9602 | + | |
9603 | +struct regset_info target_regsets[] = { | |
9604 | +#ifdef HAVE_PTRACE_GETREGS | |
9605 | + { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t), | |
9606 | + GENERAL_REGS, | |
9607 | + i386_fill_gregset, i386_store_gregset }, | |
9608 | +# ifdef HAVE_PTRACE_GETFPXREGS | |
9609 | + { PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t), | |
9610 | + EXTENDED_REGS, | |
9611 | + i386_fill_fpxregset, i386_store_fpxregset }, | |
9612 | +# endif | |
9613 | + { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t), | |
9614 | + FP_REGS, | |
9615 | + i386_fill_fpregset, i386_store_fpregset }, | |
9616 | +#endif /* HAVE_PTRACE_GETREGS */ | |
9617 | + { 0, 0, -1, -1, NULL, NULL } | |
9618 | +}; | |
9619 | + | |
9620 | +static const unsigned char i386_breakpoint[] = { 0xCC }; | |
9621 | +#define i386_breakpoint_len 1 | |
9622 | + | |
9623 | +extern int debug_threads; | |
9624 | + | |
9625 | +static CORE_ADDR | |
9626 | +i386_get_pc () | |
3a58abaf | 9627 | +{ |
7566401a ER |
9628 | + unsigned long pc; |
9629 | + | |
9630 | + collect_register_by_name ("eip", &pc); | |
9631 | + | |
9632 | + if (debug_threads) | |
9633 | + fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc); | |
9634 | + return pc; | |
3a58abaf AM |
9635 | +} |
9636 | + | |
7566401a ER |
9637 | +static void |
9638 | +i386_set_pc (CORE_ADDR newpc) | |
3a58abaf | 9639 | +{ |
7566401a ER |
9640 | + if (debug_threads) |
9641 | + fprintf (stderr, "set pc to %08lx\n", (long) newpc); | |
9642 | + supply_register_by_name ("eip", &newpc); | |
3a58abaf AM |
9643 | +} |
9644 | + | |
7566401a ER |
9645 | +static int |
9646 | +i386_breakpoint_at (CORE_ADDR pc) | |
3a58abaf | 9647 | +{ |
7566401a ER |
9648 | + unsigned char c; |
9649 | + | |
9650 | + read_inferior_memory (pc, &c, 1); | |
9651 | + if (c == 0xCC) | |
9652 | + return 1; | |
9653 | + | |
9654 | + return 0; | |
3a58abaf AM |
9655 | +} |
9656 | + | |
7566401a ER |
9657 | +struct linux_target_ops the_low_target = { |
9658 | + init_registers_i386_linux, | |
9659 | + i386_num_regs, | |
9660 | + i386_regmap, | |
9661 | + i386_cannot_fetch_register, | |
9662 | + i386_cannot_store_register, | |
9663 | + i386_get_pc, | |
9664 | + i386_set_pc, | |
9665 | + i386_breakpoint, | |
9666 | + i386_breakpoint_len, | |
9667 | + NULL, | |
9668 | + 1, | |
9669 | + i386_breakpoint_at, | |
9670 | + NULL, | |
9671 | + NULL, | |
9672 | + NULL, | |
9673 | + NULL, | |
9674 | + NULL, | |
9675 | + NULL, | |
9676 | +}; | |
9677 | diff --git a/gdb/gdbserver/linux-x86-64-low.c b/gdb/gdbserver/linux-x86-64-low.c | |
9678 | new file mode 100644 | |
9679 | index 0000000..b8213f5 | |
9680 | --- /dev/null | |
9681 | +++ b/gdb/gdbserver/linux-x86-64-low.c | |
9682 | @@ -0,0 +1,184 @@ | |
9683 | +/* GNU/Linux/x86-64 specific low level interface, for the remote server | |
9684 | + for GDB. | |
9685 | + Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009 | |
9686 | + Free Software Foundation, Inc. | |
3a58abaf | 9687 | + |
7566401a | 9688 | + This file is part of GDB. |
3a58abaf | 9689 | + |
7566401a ER |
9690 | + This program is free software; you can redistribute it and/or modify |
9691 | + it under the terms of the GNU General Public License as published by | |
9692 | + the Free Software Foundation; either version 3 of the License, or | |
9693 | + (at your option) any later version. | |
3a58abaf | 9694 | + |
7566401a ER |
9695 | + This program is distributed in the hope that it will be useful, |
9696 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9697 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
9698 | + GNU General Public License for more details. | |
3a58abaf | 9699 | + |
7566401a ER |
9700 | + You should have received a copy of the GNU General Public License |
9701 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
3a58abaf | 9702 | + |
7566401a ER |
9703 | +#include "server.h" |
9704 | +#include "linux-low.h" | |
9705 | +#include "i387-fp.h" | |
3a58abaf | 9706 | + |
7566401a | 9707 | +#include "gdb_proc_service.h" |
3a58abaf | 9708 | + |
7566401a ER |
9709 | +/* Defined in auto-generated file reg-x86-64-linux.c. */ |
9710 | +void init_registers_x86_64_linux (void); | |
3a58abaf | 9711 | + |
7566401a ER |
9712 | +#include <sys/reg.h> |
9713 | +#include <sys/procfs.h> | |
9714 | +#include <sys/ptrace.h> | |
3a58abaf | 9715 | + |
7566401a ER |
9716 | +/* This definition comes from prctl.h, but some kernels may not have it. */ |
9717 | +#ifndef PTRACE_ARCH_PRCTL | |
9718 | +#define PTRACE_ARCH_PRCTL 30 | |
9719 | +#endif | |
3a58abaf | 9720 | + |
7566401a ER |
9721 | +/* The following definitions come from prctl.h, but may be absent |
9722 | + for certain configurations. */ | |
9723 | +#ifndef ARCH_GET_FS | |
9724 | +#define ARCH_SET_GS 0x1001 | |
9725 | +#define ARCH_SET_FS 0x1002 | |
9726 | +#define ARCH_GET_FS 0x1003 | |
9727 | +#define ARCH_GET_GS 0x1004 | |
9728 | +#endif | |
3a58abaf | 9729 | + |
7566401a ER |
9730 | +static int x86_64_regmap[] = { |
9731 | + RAX * 8, RBX * 8, RCX * 8, RDX * 8, | |
9732 | + RSI * 8, RDI * 8, RBP * 8, RSP * 8, | |
9733 | + R8 * 8, R9 * 8, R10 * 8, R11 * 8, | |
9734 | + R12 * 8, R13 * 8, R14 * 8, R15 * 8, | |
9735 | + RIP * 8, EFLAGS * 8, CS * 8, SS * 8, | |
9736 | + DS * 8, ES * 8, FS * 8, GS * 8, | |
9737 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
9738 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
9739 | + -1, -1, -1, -1, -1, -1, -1, -1, | |
9740 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
9741 | + ORIG_RAX * 8 | |
9742 | +}; | |
3a58abaf | 9743 | + |
7566401a | 9744 | +#define X86_64_NUM_GREGS (sizeof(x86_64_regmap)/sizeof(int)) |
3a58abaf | 9745 | + |
7566401a | 9746 | +/* Called by libthread_db. */ |
3a58abaf | 9747 | + |
7566401a ER |
9748 | +ps_err_e |
9749 | +ps_get_thread_area (const struct ps_prochandle *ph, | |
9750 | + lwpid_t lwpid, int idx, void **base) | |
9751 | +{ | |
9752 | + switch (idx) | |
9753 | + { | |
9754 | + case FS: | |
9755 | + if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0) | |
9756 | + return PS_OK; | |
9757 | + break; | |
9758 | + case GS: | |
9759 | + if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0) | |
9760 | + return PS_OK; | |
9761 | + break; | |
9762 | + default: | |
9763 | + return PS_BADADDR; | |
9764 | + } | |
9765 | + return PS_ERR; | |
9766 | +} | |
3a58abaf | 9767 | + |
7566401a ER |
9768 | +static void |
9769 | +x86_64_fill_gregset (void *buf) | |
9770 | +{ | |
9771 | + int i; | |
3a58abaf | 9772 | + |
7566401a ER |
9773 | + for (i = 0; i < X86_64_NUM_GREGS; i++) |
9774 | + if (x86_64_regmap[i] != -1) | |
9775 | + collect_register (i, ((char *) buf) + x86_64_regmap[i]); | |
9776 | +} | |
3a58abaf | 9777 | + |
7566401a ER |
9778 | +static void |
9779 | +x86_64_store_gregset (const void *buf) | |
9780 | +{ | |
9781 | + int i; | |
3a58abaf | 9782 | + |
7566401a ER |
9783 | + for (i = 0; i < X86_64_NUM_GREGS; i++) |
9784 | + if (x86_64_regmap[i] != -1) | |
9785 | + supply_register (i, ((char *) buf) + x86_64_regmap[i]); | |
9786 | +} | |
3a58abaf | 9787 | + |
7566401a ER |
9788 | +static void |
9789 | +x86_64_fill_fpregset (void *buf) | |
9790 | +{ | |
9791 | + i387_cache_to_fxsave (buf); | |
9792 | +} | |
3a58abaf | 9793 | + |
7566401a ER |
9794 | +static void |
9795 | +x86_64_store_fpregset (const void *buf) | |
9796 | +{ | |
9797 | + i387_fxsave_to_cache (buf); | |
9798 | +} | |
3a58abaf | 9799 | + |
7566401a ER |
9800 | +struct regset_info target_regsets[] = { |
9801 | + { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t), | |
9802 | + GENERAL_REGS, | |
9803 | + x86_64_fill_gregset, x86_64_store_gregset }, | |
9804 | + { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t), | |
9805 | + FP_REGS, | |
9806 | + x86_64_fill_fpregset, x86_64_store_fpregset }, | |
9807 | + { 0, 0, -1, -1, NULL, NULL } | |
9808 | +}; | |
3a58abaf | 9809 | + |
7566401a ER |
9810 | +static const unsigned char x86_64_breakpoint[] = { 0xCC }; |
9811 | +#define x86_64_breakpoint_len 1 | |
9812 | + | |
9813 | +extern int debug_threads; | |
3a58abaf | 9814 | + |
7566401a ER |
9815 | +static CORE_ADDR |
9816 | +x86_64_get_pc () | |
9817 | +{ | |
9818 | + unsigned long pc; | |
3a58abaf | 9819 | + |
7566401a ER |
9820 | + collect_register_by_name ("rip", &pc); |
9821 | + | |
9822 | + if (debug_threads) | |
9823 | + fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc); | |
9824 | + return pc; | |
9825 | +} | |
9826 | + | |
9827 | +static void | |
9828 | +x86_64_set_pc (CORE_ADDR newpc) | |
9829 | +{ | |
9830 | + if (debug_threads) | |
9831 | + fprintf (stderr, "set pc to %08lx\n", (long) newpc); | |
9832 | + supply_register_by_name ("rip", &newpc); | |
9833 | +} | |
9834 | + | |
9835 | +static int | |
9836 | +x86_64_breakpoint_at (CORE_ADDR pc) | |
9837 | +{ | |
9838 | + unsigned char c; | |
9839 | + | |
9840 | + read_inferior_memory (pc, &c, 1); | |
9841 | + if (c == 0xCC) | |
9842 | + return 1; | |
9843 | + | |
9844 | + return 0; | |
9845 | +} | |
9846 | + | |
9847 | +struct linux_target_ops the_low_target = { | |
9848 | + init_registers_x86_64_linux, | |
9849 | + -1, | |
9850 | + NULL, | |
9851 | + NULL, | |
9852 | + NULL, | |
9853 | + x86_64_get_pc, | |
9854 | + x86_64_set_pc, | |
9855 | + x86_64_breakpoint, | |
9856 | + x86_64_breakpoint_len, | |
9857 | + NULL, | |
9858 | + 1, | |
9859 | + x86_64_breakpoint_at, | |
9860 | + NULL, | |
9861 | + NULL, | |
9862 | + NULL, | |
9863 | + NULL, | |
9864 | + NULL, | |
9865 | + NULL, | |
9866 | +}; | |
9867 | diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h | |
9868 | index 79d33fe..d3b4fa1 100644 | |
9869 | --- a/gdb/gdbthread.h | |
9870 | +++ b/gdb/gdbthread.h | |
9871 | @@ -185,6 +185,10 @@ struct thread_info | |
9872 | /* True if this thread has been explicitly requested to stop. */ | |
9873 | int stop_requested; | |
9874 | ||
9875 | + /* The initiating frame of a nexting operation, used for deciding | |
9876 | + which exceptions to intercept. */ | |
9877 | + struct frame_id initiating_frame; | |
9878 | + | |
9879 | /* Private data used by the target vector implementation. */ | |
9880 | struct private_thread_info *private; | |
9881 | }; | |
9882 | @@ -249,6 +253,9 @@ extern struct thread_info *any_thread_of_process (int pid); | |
9883 | /* Change the ptid of thread OLD_PTID to NEW_PTID. */ | |
9884 | void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid); | |
9885 | ||
9886 | +/* Prune dead threads from the list of threads. */ | |
9887 | +extern void prune_threads (void); | |
9888 | + | |
9889 | /* Iterator function to call a user-provided callback function | |
9890 | once for each known thread. */ | |
9891 | typedef int (*thread_callback_func) (struct thread_info *, void *); | |
3a58abaf | 9892 | diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c |
7566401a | 9893 | index 2f77dca..90abf2c 100644 |
3a58abaf AM |
9894 | --- a/gdb/gdbtypes.c |
9895 | +++ b/gdb/gdbtypes.c | |
7566401a | 9896 | @@ -38,6 +38,9 @@ |
3a58abaf AM |
9897 | #include "cp-abi.h" |
9898 | #include "gdb_assert.h" | |
9899 | #include "hashtab.h" | |
7566401a | 9900 | +#include "observer.h" |
3a58abaf AM |
9901 | +#include "dwarf2expr.h" |
9902 | +#include "dwarf2loc.h" | |
9903 | ||
7566401a ER |
9904 | |
9905 | /* Floatformat pairs. */ | |
9906 | @@ -118,13 +121,31 @@ static void print_arg_types (struct field *, int, int); | |
3a58abaf AM |
9907 | static void dump_fn_fieldlists (struct type *, int); |
9908 | static void print_cplus_stuff (struct type *, int); | |
7566401a | 9909 | |
3a58abaf AM |
9910 | +/* A reference count structure for the type reference count map. Each |
9911 | + type in a hierarchy of types is mapped to the same reference | |
9912 | + count. */ | |
9913 | +struct type_refc_entry | |
9914 | +{ | |
9915 | + /* One type in the hierarchy. Each type in the hierarchy gets its | |
9916 | + own slot. */ | |
9917 | + struct type *type; | |
9918 | + | |
9919 | + /* A pointer to the shared reference count. */ | |
9920 | + int *refc; | |
9921 | +}; | |
9922 | + | |
7566401a ER |
9923 | +/* The hash table holding all discardable `struct type *' references. */ |
9924 | +static htab_t type_discardable_table; | |
9925 | + | |
9926 | +/* Current type_discardable_check pass used for TYPE_DISCARDABLE_AGE. */ | |
9927 | +static int type_discardable_age_current; | |
3a58abaf | 9928 | |
7566401a ER |
9929 | /* Allocate a new OBJFILE-associated type structure and fill it |
9930 | with some defaults. Space for the type structure is allocated | |
9931 | on the objfile's objfile_obstack. */ | |
3a58abaf AM |
9932 | |
9933 | struct type * | |
9934 | -alloc_type (struct objfile *objfile) | |
9935 | +alloc_type (struct objfile *objfile, struct type *parent) | |
9936 | { | |
9937 | struct type *type; | |
9938 | ||
7566401a ER |
9939 | @@ -148,6 +169,39 @@ alloc_type (struct objfile *objfile) |
9940 | return type; | |
3a58abaf AM |
9941 | } |
9942 | ||
7566401a ER |
9943 | +/* Declare TYPE as discardable on next garbage collection by free_all_types. |
9944 | + You must call type_mark_used during each free_all_types to protect TYPE from | |
9945 | + being deallocated. */ | |
3a58abaf | 9946 | + |
7566401a ER |
9947 | +static void |
9948 | +set_type_as_discardable (struct type *type) | |
9949 | +{ | |
9950 | + void **slot; | |
3a58abaf | 9951 | + |
7566401a ER |
9952 | + gdb_assert (!TYPE_DISCARDABLE (type)); |
9953 | + | |
9954 | + TYPE_DISCARDABLE (type) = 1; | |
9955 | + TYPE_DISCARDABLE_AGE (type) = type_discardable_age_current; | |
9956 | + | |
9957 | + slot = htab_find_slot (type_discardable_table, type, INSERT); | |
9958 | + gdb_assert (!*slot); | |
9959 | + *slot = type; | |
9960 | +} | |
9961 | + | |
9962 | +/* Allocate a new type like alloc_type but preserve for it the discardability | |
9963 | + state of PARENT_TYPE. */ | |
9964 | + | |
9965 | +static struct type * | |
9966 | +alloc_type_as_parent (struct type *parent_type) | |
9967 | +{ | |
9968 | + struct type *new_type = alloc_type_copy (parent_type); | |
9969 | + | |
9970 | + if (TYPE_DISCARDABLE (parent_type)) | |
9971 | + set_type_as_discardable (new_type); | |
9972 | + | |
9973 | + return new_type; | |
9974 | +} | |
9975 | + | |
9976 | /* Allocate a new GDBARCH-associated type structure and fill it | |
9977 | with some defaults. Space for the type structure is allocated | |
9978 | on the heap. */ | |
9979 | @@ -184,7 +238,7 @@ struct type * | |
9980 | alloc_type_copy (const struct type *type) | |
9981 | { | |
9982 | if (TYPE_OBJFILE_OWNED (type)) | |
9983 | - return alloc_type (TYPE_OWNER (type).objfile); | |
9984 | + return alloc_type (TYPE_OWNER (type).objfile, (struct type *) type); | |
9985 | else | |
9986 | return alloc_type_arch (TYPE_OWNER (type).gdbarch); | |
9987 | } | |
9988 | @@ -273,7 +327,7 @@ make_pointer_type (struct type *type, struct type **typeptr) | |
3a58abaf AM |
9989 | |
9990 | if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ | |
9991 | { | |
7566401a ER |
9992 | - ntype = alloc_type_copy (type); |
9993 | + ntype = alloc_type_as_parent (type); | |
3a58abaf AM |
9994 | if (typeptr) |
9995 | *typeptr = ntype; | |
9996 | } | |
7566401a | 9997 | @@ -350,7 +404,7 @@ make_reference_type (struct type *type, struct type **typeptr) |
3a58abaf AM |
9998 | |
9999 | if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ | |
10000 | { | |
7566401a ER |
10001 | - ntype = alloc_type_copy (type); |
10002 | + ntype = alloc_type_as_parent (type); | |
3a58abaf AM |
10003 | if (typeptr) |
10004 | *typeptr = ntype; | |
10005 | } | |
7566401a | 10006 | @@ -721,12 +775,13 @@ create_range_type (struct type *result_type, struct type *index_type, |
3a58abaf AM |
10007 | TYPE_TARGET_STUB (result_type) = 1; |
10008 | else | |
10009 | TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type)); | |
10010 | - TYPE_NFIELDS (result_type) = 2; | |
10011 | + TYPE_NFIELDS (result_type) = 3; | |
10012 | TYPE_FIELDS (result_type) = TYPE_ZALLOC (result_type, | |
10013 | TYPE_NFIELDS (result_type) | |
10014 | * sizeof (struct field)); | |
10015 | TYPE_LOW_BOUND (result_type) = low_bound; | |
10016 | TYPE_HIGH_BOUND (result_type) = high_bound; | |
10017 | + TYPE_BYTE_STRIDE (result_type) = 0; | |
10018 | ||
10019 | if (low_bound >= 0) | |
10020 | TYPE_UNSIGNED (result_type) = 1; | |
7566401a | 10021 | @@ -826,26 +881,45 @@ create_array_type (struct type *result_type, |
3a58abaf | 10022 | |
3a58abaf AM |
10023 | TYPE_CODE (result_type) = TYPE_CODE_ARRAY; |
10024 | TYPE_TARGET_TYPE (result_type) = element_type; | |
10025 | - if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) | |
10026 | - low_bound = high_bound = 0; | |
10027 | - CHECK_TYPEDEF (element_type); | |
10028 | - /* Be careful when setting the array length. Ada arrays can be | |
10029 | - empty arrays with the high_bound being smaller than the low_bound. | |
10030 | - In such cases, the array length should be zero. */ | |
10031 | - if (high_bound < low_bound) | |
10032 | - TYPE_LENGTH (result_type) = 0; | |
10033 | - else | |
10034 | - TYPE_LENGTH (result_type) = | |
10035 | - TYPE_LENGTH (element_type) * (high_bound - low_bound + 1); | |
10036 | TYPE_NFIELDS (result_type) = 1; | |
10037 | TYPE_FIELDS (result_type) = | |
10038 | (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field)); | |
3a58abaf AM |
10039 | TYPE_INDEX_TYPE (result_type) = range_type; |
10040 | TYPE_VPTR_FIELDNO (result_type) = -1; | |
10041 | ||
10042 | - /* TYPE_FLAG_TARGET_STUB will take care of zero length arrays */ | |
10043 | + /* DWARF blocks may depend on runtime information like | |
10044 | + DW_OP_PUSH_OBJECT_ADDRESS not being available during the | |
10045 | + CREATE_ARRAY_TYPE time. */ | |
10046 | + if (TYPE_RANGE_BOUND_IS_DWARF_BLOCK (range_type, 0) | |
10047 | + || TYPE_RANGE_BOUND_IS_DWARF_BLOCK (range_type, 1) | |
10048 | + || TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (range_type) | |
10049 | + || TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED (range_type) | |
10050 | + || get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) | |
10051 | + { | |
10052 | + low_bound = 0; | |
10053 | + high_bound = -1; | |
10054 | + } | |
10055 | + | |
10056 | + /* Be careful when setting the array length. Ada arrays can be | |
10057 | + empty arrays with the high_bound being smaller than the low_bound. | |
10058 | + In such cases, the array length should be zero. TYPE_TARGET_STUB needs to | |
10059 | + be checked as it may have dependencies on DWARF blocks depending on | |
10060 | + runtime information not available during the CREATE_ARRAY_TYPE time. */ | |
10061 | + if (high_bound < low_bound || TYPE_TARGET_STUB (element_type)) | |
10062 | + TYPE_LENGTH (result_type) = 0; | |
10063 | + else | |
10064 | + { | |
10065 | + CHECK_TYPEDEF (element_type); | |
10066 | + TYPE_LENGTH (result_type) = | |
10067 | + TYPE_LENGTH (element_type) * (high_bound - low_bound + 1); | |
10068 | + } | |
10069 | + | |
10070 | if (TYPE_LENGTH (result_type) == 0) | |
10071 | - TYPE_TARGET_STUB (result_type) = 1; | |
10072 | + { | |
10073 | + /* The real size will be computed for specific instances by | |
10074 | + CHECK_TYPEDEF. */ | |
10075 | + TYPE_TARGET_STUB (result_type) = 1; | |
10076 | + } | |
10077 | ||
7566401a | 10078 | return result_type; |
3a58abaf | 10079 | } |
7566401a | 10080 | @@ -1331,6 +1405,84 @@ stub_noname_complaint (void) |
3a58abaf AM |
10081 | complaint (&symfile_complaints, _("stub type has NULL name")); |
10082 | } | |
10083 | ||
10084 | +/* Calculate the memory length of array TYPE. | |
10085 | + | |
10086 | + TARGET_TYPE should be set to `check_typedef (TYPE_TARGET_TYPE (type))' as | |
10087 | + a performance hint. Feel free to pass NULL. Set FULL_SPAN to return the | |
10088 | + size incl. the possible padding of the last element - it may differ from the | |
10089 | + cleared FULL_SPAN return value (the expected SIZEOF) for non-zero | |
10090 | + TYPE_BYTE_STRIDE values. */ | |
10091 | + | |
10092 | +static CORE_ADDR | |
10093 | +type_length_get (struct type *type, struct type *target_type, int full_span) | |
10094 | +{ | |
10095 | + struct type *range_type; | |
10096 | + int count; | |
10097 | + CORE_ADDR byte_stride = 0; /* `= 0' for a false GCC warning. */ | |
10098 | + CORE_ADDR element_size; | |
10099 | + | |
10100 | + if (TYPE_CODE (type) != TYPE_CODE_ARRAY | |
10101 | + && TYPE_CODE (type) != TYPE_CODE_STRING) | |
10102 | + return TYPE_LENGTH (type); | |
10103 | + | |
10104 | + /* Avoid executing TYPE_HIGH_BOUND for invalid (unallocated/unassociated) | |
10105 | + Fortran arrays. The allocated data will never be used so they can be | |
10106 | + zero-length. */ | |
10107 | + if (object_address_data_not_valid (type)) | |
10108 | + return 0; | |
10109 | + | |
10110 | + range_type = TYPE_INDEX_TYPE (type); | |
10111 | + if (TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED (range_type) | |
10112 | + || TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (range_type)) | |
10113 | + return 0; | |
10114 | + count = TYPE_HIGH_BOUND (range_type) - TYPE_LOW_BOUND (range_type) + 1; | |
10115 | + /* It may happen for wrong DWARF annotations returning garbage data. */ | |
10116 | + if (count < 0) | |
10117 | + warning (_("Range for type %s has invalid bounds %d..%d"), | |
10118 | + TYPE_NAME (type), TYPE_LOW_BOUND (range_type), | |
10119 | + TYPE_HIGH_BOUND (range_type)); | |
10120 | + /* The code below does not handle count == 0 right. */ | |
10121 | + if (count <= 0) | |
10122 | + return 0; | |
10123 | + if (full_span || count > 1) | |
10124 | + { | |
10125 | + /* We do not use TYPE_ARRAY_BYTE_STRIDE_VALUE (type) here as we want to | |
10126 | + force FULL_SPAN to 1. */ | |
10127 | + byte_stride = TYPE_BYTE_STRIDE (range_type); | |
10128 | + if (byte_stride == 0) | |
10129 | + { | |
10130 | + if (target_type == NULL) | |
10131 | + target_type = check_typedef (TYPE_TARGET_TYPE (type)); | |
10132 | + byte_stride = type_length_get (target_type, NULL, 1); | |
10133 | + } | |
10134 | + } | |
10135 | + if (full_span) | |
10136 | + return count * byte_stride; | |
10137 | + if (target_type == NULL) | |
10138 | + target_type = check_typedef (TYPE_TARGET_TYPE (type)); | |
10139 | + element_size = type_length_get (target_type, NULL, 1); | |
10140 | + return (count - 1) * byte_stride + element_size; | |
10141 | +} | |
10142 | + | |
10143 | +/* Prepare TYPE after being read in by the backend. Currently this function | |
10144 | + only propagates the TYPE_DYNAMIC flag. */ | |
10145 | + | |
10146 | +void | |
10147 | +finalize_type (struct type *type) | |
10148 | +{ | |
10149 | + int i; | |
10150 | + | |
10151 | + for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
10152 | + if (TYPE_FIELD_TYPE (type, i) && TYPE_DYNAMIC (TYPE_FIELD_TYPE (type, i))) | |
10153 | + break; | |
10154 | + | |
10155 | + /* FIXME: cplus_stuff is ignored here. */ | |
10156 | + if (i < TYPE_NFIELDS (type) | |
10157 | + || (TYPE_VPTR_BASETYPE (type) && TYPE_DYNAMIC (TYPE_VPTR_BASETYPE (type))) | |
10158 | + || (TYPE_TARGET_TYPE (type) && TYPE_DYNAMIC (TYPE_TARGET_TYPE (type)))) | |
10159 | + TYPE_DYNAMIC (type) = 1; | |
10160 | +} | |
10161 | + | |
10162 | /* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989. | |
10163 | ||
10164 | If this is a stubbed struct (i.e. declared as struct foo *), see if | |
7566401a | 10165 | @@ -1347,7 +1499,8 @@ stub_noname_complaint (void) |
3a58abaf AM |
10166 | /* Find the real type of TYPE. This function returns the real type, |
10167 | after removing all layers of typedefs and completing opaque or stub | |
10168 | types. Completion changes the TYPE argument, but stripping of | |
10169 | - typedefs does not. */ | |
10170 | + typedefs does not. Still original passed TYPE will have TYPE_LENGTH | |
10171 | + updated. FIXME: Remove this dependency (only ada_to_fixed_type?). */ | |
10172 | ||
10173 | struct type * | |
10174 | check_typedef (struct type *type) | |
7566401a | 10175 | @@ -1457,34 +1610,37 @@ check_typedef (struct type *type) |
3a58abaf AM |
10176 | } |
10177 | } | |
10178 | ||
10179 | - if (TYPE_TARGET_STUB (type)) | |
10180 | + /* copy_type_recursive automatically makes the resulting type containing only | |
10181 | + constant values expected by the callers of this function. */ | |
10182 | + if (TYPE_DYNAMIC (type)) | |
10183 | + { | |
10184 | + htab_t copied_types; | |
10185 | + struct type *type_old = type; | |
10186 | + | |
10187 | + copied_types = create_copied_types_hash (NULL); | |
10188 | + type = copy_type_recursive (type, copied_types); | |
10189 | + htab_delete (copied_types); | |
10190 | + | |
10191 | + gdb_assert (TYPE_DYNAMIC (type) == 0); | |
10192 | + } | |
10193 | + | |
10194 | + if (!currently_reading_symtab | |
10195 | + && (TYPE_TARGET_STUB (type) || TYPE_DYNAMIC (type))) | |
10196 | { | |
10197 | - struct type *range_type; | |
10198 | struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type)); | |
10199 | ||
10200 | + if (TYPE_DYNAMIC (type)) | |
10201 | + TYPE_TARGET_TYPE (type) = target_type; | |
10202 | if (TYPE_STUB (target_type) || TYPE_TARGET_STUB (target_type)) | |
10203 | { | |
10204 | /* Empty. */ | |
10205 | } | |
10206 | else if (TYPE_CODE (type) == TYPE_CODE_ARRAY | |
10207 | - && TYPE_NFIELDS (type) == 1 | |
10208 | - && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type)) | |
10209 | - == TYPE_CODE_RANGE)) | |
10210 | + || TYPE_CODE (type) == TYPE_CODE_STRING) | |
10211 | { | |
10212 | /* Now recompute the length of the array type, based on its | |
10213 | - number of elements and the target type's length. | |
10214 | - Watch out for Ada null Ada arrays where the high bound | |
10215 | - is smaller than the low bound. */ | |
10216 | - const int low_bound = TYPE_LOW_BOUND (range_type); | |
10217 | - const int high_bound = TYPE_HIGH_BOUND (range_type); | |
10218 | - int nb_elements; | |
10219 | - | |
10220 | - if (high_bound < low_bound) | |
10221 | - nb_elements = 0; | |
10222 | - else | |
10223 | - nb_elements = high_bound - low_bound + 1; | |
10224 | - | |
10225 | - TYPE_LENGTH (type) = nb_elements * TYPE_LENGTH (target_type); | |
10226 | + number of elements and the target type's length. */ | |
10227 | + TYPE_LENGTH (type) = type_length_get (type, target_type, 0); | |
10228 | TYPE_TARGET_STUB (type) = 0; | |
10229 | } | |
10230 | else if (TYPE_CODE (type) == TYPE_CODE_RANGE) | |
7566401a | 10231 | @@ -1492,9 +1648,12 @@ check_typedef (struct type *type) |
3a58abaf AM |
10232 | TYPE_LENGTH (type) = TYPE_LENGTH (target_type); |
10233 | TYPE_TARGET_STUB (type) = 0; | |
10234 | } | |
10235 | + TYPE_DYNAMIC (type) = 0; | |
10236 | } | |
10237 | + | |
10238 | /* Cache TYPE_LENGTH for future use. */ | |
10239 | TYPE_LENGTH (orig_type) = TYPE_LENGTH (type); | |
10240 | + | |
10241 | return type; | |
10242 | } | |
10243 | ||
7566401a | 10244 | @@ -1716,7 +1875,7 @@ init_type (enum type_code code, int length, int flags, |
3a58abaf AM |
10245 | { |
10246 | struct type *type; | |
10247 | ||
10248 | - type = alloc_type (objfile); | |
10249 | + type = alloc_type (objfile, NULL); | |
10250 | TYPE_CODE (type) = code; | |
10251 | TYPE_LENGTH (type) = length; | |
10252 | ||
7566401a | 10253 | @@ -1760,6 +1919,10 @@ init_type (enum type_code code, int length, int flags, |
3a58abaf AM |
10254 | { |
10255 | INIT_CPLUS_SPECIFIC (type); | |
10256 | } | |
10257 | + | |
10258 | + if (!objfile) | |
10259 | + type_incref (type); | |
10260 | + | |
7566401a | 10261 | return type; |
3a58abaf AM |
10262 | } |
10263 | ||
7566401a ER |
10264 | @@ -2004,7 +2167,8 @@ rank_one_type (struct type *parm, struct type *arg) |
10265 | switch (TYPE_CODE (arg)) | |
10266 | { | |
10267 | case TYPE_CODE_PTR: | |
10268 | - if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID) | |
10269 | + if (TYPE_CODE (TYPE_TARGET_TYPE (parm)) == TYPE_CODE_VOID | |
10270 | + && TYPE_CODE (TYPE_TARGET_TYPE (arg)) != TYPE_CODE_VOID) | |
10271 | return VOID_PTR_CONVERSION_BADNESS; | |
10272 | else | |
10273 | return rank_one_type (TYPE_TARGET_TYPE (parm), | |
10274 | @@ -2820,33 +2984,42 @@ type_pair_eq (const void *item_lhs, const void *item_rhs) | |
3a58abaf AM |
10275 | } |
10276 | ||
10277 | /* Allocate the hash table used by copy_type_recursive to walk | |
10278 | - types without duplicates. We use OBJFILE's obstack, because | |
10279 | - OBJFILE is about to be deleted. */ | |
10280 | + types without duplicates. */ | |
10281 | ||
10282 | htab_t | |
10283 | create_copied_types_hash (struct objfile *objfile) | |
10284 | { | |
10285 | - return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq, | |
10286 | - NULL, &objfile->objfile_obstack, | |
10287 | - hashtab_obstack_allocate, | |
10288 | - dummy_obstack_deallocate); | |
10289 | + if (objfile == NULL) | |
10290 | + { | |
10291 | + /* NULL OBJFILE is for TYPE_DYNAMIC types already contained in | |
10292 | + OBJFILE_MALLOC memory, such as those from VALUE_HISTORY_CHAIN. Table | |
10293 | + element entries get allocated by xmalloc - so use xfree. */ | |
10294 | + return htab_create (1, type_pair_hash, type_pair_eq, xfree); | |
10295 | + } | |
10296 | + else | |
10297 | + { | |
10298 | + /* Use OBJFILE's obstack, because OBJFILE is about to be deleted. Table | |
10299 | + element entries get allocated by xmalloc - so use xfree. */ | |
10300 | + return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq, | |
10301 | + xfree, &objfile->objfile_obstack, | |
10302 | + hashtab_obstack_allocate, | |
10303 | + dummy_obstack_deallocate); | |
10304 | + } | |
10305 | } | |
10306 | ||
10307 | -/* Recursively copy (deep copy) TYPE, if it is associated with | |
10308 | - OBJFILE. Return a new type allocated using malloc, a saved type if | |
10309 | - we have already visited TYPE (using COPIED_TYPES), or TYPE if it is | |
10310 | - not associated with OBJFILE. */ | |
7566401a ER |
10311 | +/* A helper for copy_type_recursive. This does all the work. OBJFILE is used |
10312 | + only for an assertion checking. */ | |
3a58abaf AM |
10313 | |
10314 | -struct type * | |
10315 | -copy_type_recursive (struct objfile *objfile, | |
10316 | - struct type *type, | |
10317 | - htab_t copied_types) | |
10318 | +static struct type * | |
10319 | +copy_type_recursive_1 (struct objfile *objfile, | |
10320 | + struct type *type, | |
7566401a | 10321 | + htab_t copied_types) |
3a58abaf AM |
10322 | { |
10323 | struct type_pair *stored, pair; | |
10324 | void **slot; | |
10325 | struct type *new_type; | |
10326 | ||
7566401a ER |
10327 | - if (! TYPE_OBJFILE_OWNED (type)) |
10328 | + if (! TYPE_OBJFILE_OWNED (type) && !TYPE_DYNAMIC (type)) | |
3a58abaf AM |
10329 | return type; |
10330 | ||
10331 | /* This type shouldn't be pointing to any types in other objfiles; | |
7566401a ER |
10332 | @@ -2861,8 +3034,10 @@ copy_type_recursive (struct objfile *objfile, |
10333 | new_type = alloc_type_arch (get_type_arch (type)); | |
3a58abaf AM |
10334 | |
10335 | /* We must add the new type to the hash table immediately, in case | |
10336 | - we encounter this type again during a recursive call below. */ | |
10337 | - stored = obstack_alloc (&objfile->objfile_obstack, sizeof (struct type_pair)); | |
10338 | + we encounter this type again during a recursive call below. Memory could | |
10339 | + be allocated from OBJFILE in the case we will be removing OBJFILE, this | |
10340 | + optimization is missed and xfree is called for it from COPIED_TYPES. */ | |
10341 | + stored = xmalloc (sizeof (*stored)); | |
10342 | stored->old = type; | |
10343 | stored->new = new_type; | |
10344 | *slot = stored; | |
7566401a ER |
10345 | @@ -2873,6 +3048,19 @@ copy_type_recursive (struct objfile *objfile, |
10346 | TYPE_OBJFILE_OWNED (new_type) = 0; | |
10347 | TYPE_OWNER (new_type).gdbarch = get_type_arch (type); | |
3a58abaf | 10348 | |
7566401a ER |
10349 | + /* TYPE_MAIN_TYPE memory copy above rewrote the TYPE_DISCARDABLE flag so we |
10350 | + need to initialize it again. And even if TYPE was already discardable | |
10351 | + NEW_TYPE so far is not registered in TYPE_DISCARDABLE_TABLE. */ | |
10352 | + TYPE_DISCARDABLE (new_type) = 0; | |
10353 | + set_type_as_discardable (new_type); | |
10354 | + | |
3a58abaf AM |
10355 | + /* Pre-clear the fields processed by delete_main_type. If DWARF block |
10356 | + evaluations below call error we would leave an unfreeable TYPE. */ | |
10357 | + TYPE_TARGET_TYPE (new_type) = NULL; | |
10358 | + TYPE_VPTR_BASETYPE (new_type) = NULL; | |
10359 | + TYPE_NFIELDS (new_type) = 0; | |
10360 | + TYPE_FIELDS (new_type) = NULL; | |
10361 | + | |
10362 | if (TYPE_NAME (type)) | |
10363 | TYPE_NAME (new_type) = xstrdup (TYPE_NAME (type)); | |
10364 | if (TYPE_TAG_NAME (type)) | |
7566401a | 10365 | @@ -2881,12 +3069,45 @@ copy_type_recursive (struct objfile *objfile, |
3a58abaf AM |
10366 | TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type); |
10367 | TYPE_LENGTH (new_type) = TYPE_LENGTH (type); | |
10368 | ||
10369 | + if (TYPE_ALLOCATED (new_type)) | |
10370 | + { | |
10371 | + gdb_assert (!TYPE_NOT_ALLOCATED (new_type)); | |
10372 | + | |
10373 | + if (!dwarf_locexpr_baton_eval (TYPE_ALLOCATED (new_type))) | |
10374 | + TYPE_NOT_ALLOCATED (new_type) = 1; | |
10375 | + TYPE_ALLOCATED (new_type) = NULL; | |
10376 | + } | |
10377 | + | |
10378 | + if (TYPE_ASSOCIATED (new_type)) | |
10379 | + { | |
10380 | + gdb_assert (!TYPE_NOT_ASSOCIATED (new_type)); | |
10381 | + | |
10382 | + if (!dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (new_type))) | |
10383 | + TYPE_NOT_ASSOCIATED (new_type) = 1; | |
10384 | + TYPE_ASSOCIATED (new_type) = NULL; | |
10385 | + } | |
10386 | + | |
10387 | + if (!TYPE_DATA_LOCATION_IS_ADDR (new_type) | |
10388 | + && TYPE_DATA_LOCATION_DWARF_BLOCK (new_type)) | |
10389 | + { | |
10390 | + if (TYPE_NOT_ALLOCATED (new_type) | |
10391 | + || TYPE_NOT_ASSOCIATED (new_type)) | |
10392 | + TYPE_DATA_LOCATION_DWARF_BLOCK (new_type) = NULL; | |
10393 | + else | |
10394 | + { | |
10395 | + TYPE_DATA_LOCATION_IS_ADDR (new_type) = 1; | |
10396 | + TYPE_DATA_LOCATION_ADDR (new_type) = dwarf_locexpr_baton_eval | |
10397 | + (TYPE_DATA_LOCATION_DWARF_BLOCK (new_type)); | |
10398 | + } | |
10399 | + } | |
10400 | + | |
10401 | /* Copy the fields. */ | |
10402 | if (TYPE_NFIELDS (type)) | |
10403 | { | |
10404 | int i, nfields; | |
10405 | ||
10406 | nfields = TYPE_NFIELDS (type); | |
10407 | + TYPE_NFIELDS (new_type) = nfields; | |
10408 | TYPE_FIELDS (new_type) = XCALLOC (nfields, struct field); | |
10409 | for (i = 0; i < nfields; i++) | |
10410 | { | |
7566401a | 10411 | @@ -2895,8 +3116,8 @@ copy_type_recursive (struct objfile *objfile, |
3a58abaf AM |
10412 | TYPE_FIELD_BITSIZE (new_type, i) = TYPE_FIELD_BITSIZE (type, i); |
10413 | if (TYPE_FIELD_TYPE (type, i)) | |
10414 | TYPE_FIELD_TYPE (new_type, i) | |
10415 | - = copy_type_recursive (objfile, TYPE_FIELD_TYPE (type, i), | |
10416 | - copied_types); | |
10417 | + = copy_type_recursive_1 (objfile, TYPE_FIELD_TYPE (type, i), | |
7566401a | 10418 | + copied_types); |
3a58abaf AM |
10419 | if (TYPE_FIELD_NAME (type, i)) |
10420 | TYPE_FIELD_NAME (new_type, i) = | |
10421 | xstrdup (TYPE_FIELD_NAME (type, i)); | |
7566401a | 10422 | @@ -2915,6 +3136,16 @@ copy_type_recursive (struct objfile *objfile, |
3a58abaf AM |
10423 | xstrdup (TYPE_FIELD_STATIC_PHYSNAME (type, |
10424 | i))); | |
10425 | break; | |
10426 | + case FIELD_LOC_KIND_DWARF_BLOCK: | |
10427 | + /* `struct dwarf2_locexpr_baton' is too bound to its objfile so | |
10428 | + it is expected to be made constant by CHECK_TYPEDEF. */ | |
10429 | + if (TYPE_NOT_ALLOCATED (new_type) | |
10430 | + || TYPE_NOT_ASSOCIATED (new_type)) | |
10431 | + SET_FIELD_DWARF_BLOCK (TYPE_FIELD (new_type, i), NULL); | |
10432 | + else | |
10433 | + SET_FIELD_BITPOS (TYPE_FIELD (new_type, i), | |
10434 | + dwarf_locexpr_baton_eval (TYPE_FIELD_DWARF_BLOCK (type, i))); | |
10435 | + break; | |
10436 | default: | |
10437 | internal_error (__FILE__, __LINE__, | |
10438 | _("Unexpected type field location kind: %d"), | |
7566401a | 10439 | @@ -2923,17 +3154,30 @@ copy_type_recursive (struct objfile *objfile, |
3a58abaf AM |
10440 | } |
10441 | } | |
10442 | ||
10443 | + /* Convert TYPE_RANGE_HIGH_BOUND_IS_COUNT into a regular bound. */ | |
10444 | + if (TYPE_CODE (type) == TYPE_CODE_RANGE | |
10445 | + && TYPE_RANGE_HIGH_BOUND_IS_COUNT (type)) | |
10446 | + { | |
10447 | + TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type) = 0; | |
10448 | + TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (type) | |
10449 | + + TYPE_HIGH_BOUND (type) - 1; | |
10450 | + } | |
10451 | + | |
10452 | + /* Both FIELD_LOC_KIND_DWARF_BLOCK and TYPE_RANGE_HIGH_BOUND_IS_COUNT were | |
10453 | + possibly converted. */ | |
10454 | + TYPE_DYNAMIC (new_type) = 0; | |
10455 | + | |
10456 | /* Copy pointers to other types. */ | |
10457 | if (TYPE_TARGET_TYPE (type)) | |
10458 | TYPE_TARGET_TYPE (new_type) = | |
10459 | - copy_type_recursive (objfile, | |
10460 | - TYPE_TARGET_TYPE (type), | |
10461 | - copied_types); | |
10462 | + copy_type_recursive_1 (objfile, | |
10463 | + TYPE_TARGET_TYPE (type), | |
7566401a | 10464 | + copied_types); |
3a58abaf AM |
10465 | if (TYPE_VPTR_BASETYPE (type)) |
10466 | TYPE_VPTR_BASETYPE (new_type) = | |
10467 | - copy_type_recursive (objfile, | |
10468 | - TYPE_VPTR_BASETYPE (type), | |
10469 | - copied_types); | |
10470 | + copy_type_recursive_1 (objfile, | |
10471 | + TYPE_VPTR_BASETYPE (type), | |
7566401a | 10472 | + copied_types); |
3a58abaf AM |
10473 | /* Maybe copy the type_specific bits. |
10474 | ||
10475 | NOTE drow/2005-12-09: We do not copy the C++-specific bits like | |
7566401a | 10476 | @@ -2951,6 +3195,17 @@ copy_type_recursive (struct objfile *objfile, |
3a58abaf AM |
10477 | return new_type; |
10478 | } | |
10479 | ||
10480 | +/* Recursively copy (deep copy) TYPE. Return a new type allocated using | |
10481 | + malloc, a saved type if we have already visited TYPE (using COPIED_TYPES), | |
10482 | + or TYPE if it is not associated with OBJFILE. */ | |
10483 | + | |
10484 | +struct type * | |
10485 | +copy_type_recursive (struct type *type, | |
10486 | + htab_t copied_types) | |
10487 | +{ | |
7566401a | 10488 | + return copy_type_recursive_1 (TYPE_OBJFILE (type), type, copied_types); |
3a58abaf AM |
10489 | +} |
10490 | + | |
10491 | /* Make a copy of the given TYPE, except that the pointer & reference | |
10492 | types are not preserved. | |
10493 | ||
7566401a | 10494 | @@ -2973,6 +3228,217 @@ copy_type (const struct type *type) |
3a58abaf AM |
10495 | return new_type; |
10496 | } | |
10497 | ||
7566401a ER |
10498 | +/* Callback type for main_type_crawl. */ |
10499 | +typedef int (*main_type_crawl_iter) (struct type *type, void *data); | |
10500 | + | |
10501 | +/* Iterate all main_type structures reachable through any `struct type *' from | |
10502 | + TYPE. ITER will be called only for one type of each main_type, use | |
10503 | + TYPE_CHAIN traversal to find all the type instances. ITER is being called | |
10504 | + for each main_type found. ITER returns non-zero if main_type_crawl should | |
10505 | + depth-first enter the specific type. ITER must provide some detection for | |
10506 | + reentering the same main_type as this function would otherwise endlessly | |
10507 | + loop. */ | |
10508 | + | |
10509 | +static void | |
10510 | +main_type_crawl (struct type *type, main_type_crawl_iter iter, void *data) | |
10511 | +{ | |
10512 | + struct type *type_iter; | |
10513 | + int i; | |
10514 | + | |
10515 | + if (!type) | |
10516 | + return; | |
10517 | + | |
10518 | + gdb_assert (TYPE_OBJFILE (type) == NULL); | |
10519 | + | |
10520 | + /* `struct cplus_struct_type' handling is unsupported by this function. */ | |
10521 | + gdb_assert ((TYPE_CODE (type) != TYPE_CODE_STRUCT | |
10522 | + && TYPE_CODE (type) != TYPE_CODE_UNION) | |
10523 | + || !HAVE_CPLUS_STRUCT (type) || !TYPE_CPLUS_SPECIFIC (type)); | |
10524 | + | |
10525 | + if (!(*iter) (type, data)) | |
10526 | + return; | |
10527 | + | |
10528 | + /* Iterate all the type instances of this main_type. */ | |
10529 | + type_iter = type; | |
10530 | + do | |
10531 | + { | |
10532 | + gdb_assert (TYPE_MAIN_TYPE (type_iter) == TYPE_MAIN_TYPE (type)); | |
10533 | + | |
10534 | + main_type_crawl (TYPE_POINTER_TYPE (type), iter, data); | |
10535 | + main_type_crawl (TYPE_REFERENCE_TYPE (type), iter, data); | |
10536 | + | |
10537 | + type_iter = TYPE_CHAIN (type_iter); | |
10538 | + } | |
10539 | + while (type_iter != type); | |
10540 | + | |
10541 | + for (i = 0; i < TYPE_NFIELDS (type); i++) | |
10542 | + main_type_crawl (TYPE_FIELD_TYPE (type, i), iter, data); | |
10543 | + | |
10544 | + main_type_crawl (TYPE_TARGET_TYPE (type), iter, data); | |
10545 | + main_type_crawl (TYPE_VPTR_BASETYPE (type), iter, data); | |
10546 | +} | |
3a58abaf AM |
10547 | + |
10548 | +/* A helper for delete_type which deletes a main_type and the things to which | |
10549 | + it refers. TYPE is a type whose main_type we wish to destroy. */ | |
10550 | + | |
10551 | +static void | |
7566401a | 10552 | +delete_main_type (struct type *type) |
3a58abaf AM |
10553 | +{ |
10554 | + int i; | |
3a58abaf | 10555 | + |
7566401a ER |
10556 | + gdb_assert (TYPE_DISCARDABLE (type)); |
10557 | + gdb_assert (TYPE_OBJFILE (type) == NULL); | |
3a58abaf AM |
10558 | + |
10559 | + xfree (TYPE_NAME (type)); | |
10560 | + xfree (TYPE_TAG_NAME (type)); | |
10561 | + | |
10562 | + for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
10563 | + { | |
10564 | + xfree (TYPE_FIELD_NAME (type, i)); | |
10565 | + | |
10566 | + if (TYPE_FIELD_LOC_KIND (type, i) == FIELD_LOC_KIND_PHYSNAME) | |
10567 | + xfree (TYPE_FIELD_STATIC_PHYSNAME (type, i)); | |
10568 | + } | |
10569 | + xfree (TYPE_FIELDS (type)); | |
10570 | + | |
7566401a ER |
10571 | + /* `struct cplus_struct_type' handling is unsupported by this function. */ |
10572 | + gdb_assert ((TYPE_CODE (type) != TYPE_CODE_STRUCT | |
10573 | + && TYPE_CODE (type) != TYPE_CODE_UNION) | |
10574 | + || !HAVE_CPLUS_STRUCT (type) || !TYPE_CPLUS_SPECIFIC (type)); | |
3a58abaf AM |
10575 | + |
10576 | + xfree (TYPE_MAIN_TYPE (type)); | |
10577 | +} | |
10578 | + | |
7566401a ER |
10579 | +/* Delete all the instances on TYPE_CHAIN of TYPE, including their referenced |
10580 | + main_type. TYPE must be a reclaimable type - neither permanent nor objfile | |
10581 | + associated. */ | |
3a58abaf AM |
10582 | + |
10583 | +static void | |
7566401a | 10584 | +delete_type_chain (struct type *type) |
3a58abaf | 10585 | +{ |
7566401a | 10586 | + struct type *type_iter, *type_iter_to_free; |
3a58abaf | 10587 | + |
7566401a ER |
10588 | + gdb_assert (TYPE_DISCARDABLE (type)); |
10589 | + gdb_assert (TYPE_OBJFILE (type) == NULL); | |
3a58abaf | 10590 | + |
7566401a | 10591 | + delete_main_type (type); |
3a58abaf | 10592 | + |
7566401a ER |
10593 | + type_iter = type; |
10594 | + do | |
10595 | + { | |
10596 | + type_iter_to_free = type_iter; | |
10597 | + type_iter = TYPE_CHAIN (type_iter); | |
10598 | + xfree (type_iter_to_free); | |
10599 | + } | |
10600 | + while (type_iter != type); | |
3a58abaf AM |
10601 | +} |
10602 | + | |
7566401a | 10603 | +/* Hash function for type_discardable_table. */ |
3a58abaf | 10604 | + |
7566401a ER |
10605 | +static hashval_t |
10606 | +type_discardable_hash (const void *p) | |
3a58abaf | 10607 | +{ |
7566401a | 10608 | + const struct type *type = p; |
3a58abaf | 10609 | + |
7566401a | 10610 | + return htab_hash_pointer (TYPE_MAIN_TYPE (type)); |
3a58abaf AM |
10611 | +} |
10612 | + | |
7566401a | 10613 | +/* Equality function for type_discardable_table. */ |
3a58abaf | 10614 | + |
7566401a ER |
10615 | +static int |
10616 | +type_discardable_equal (const void *a, const void *b) | |
3a58abaf | 10617 | +{ |
7566401a ER |
10618 | + const struct type *left = a; |
10619 | + const struct type *right = b; | |
3a58abaf | 10620 | + |
7566401a | 10621 | + return TYPE_MAIN_TYPE (left) == TYPE_MAIN_TYPE (right); |
3a58abaf AM |
10622 | +} |
10623 | + | |
7566401a | 10624 | +/* A helper for type_mark_used. */ |
3a58abaf | 10625 | + |
7566401a ER |
10626 | +static int |
10627 | +type_mark_used_crawl (struct type *type, void *unused) | |
3a58abaf | 10628 | +{ |
7566401a ER |
10629 | + if (!TYPE_DISCARDABLE (type)) |
10630 | + return 0; | |
3a58abaf | 10631 | + |
7566401a ER |
10632 | + if (TYPE_DISCARDABLE_AGE (type) == type_discardable_age_current) |
10633 | + return 0; | |
3a58abaf | 10634 | + |
7566401a ER |
10635 | + TYPE_DISCARDABLE_AGE (type) = type_discardable_age_current; |
10636 | + | |
10637 | + /* Continue the traversal. */ | |
10638 | + return 1; | |
3a58abaf AM |
10639 | +} |
10640 | + | |
7566401a | 10641 | +/* Mark TYPE and its connected types as used in this free_all_types pass. */ |
3a58abaf | 10642 | + |
7566401a ER |
10643 | +void |
10644 | +type_mark_used (struct type *type) | |
3a58abaf | 10645 | +{ |
7566401a | 10646 | + if (type == NULL) |
3a58abaf AM |
10647 | + return; |
10648 | + | |
7566401a ER |
10649 | + if (!TYPE_DISCARDABLE (type)) |
10650 | + return; | |
3a58abaf | 10651 | + |
7566401a | 10652 | + main_type_crawl (type, type_mark_used_crawl, NULL); |
3a58abaf AM |
10653 | +} |
10654 | + | |
10655 | +/* Increment the reference count for TYPE. */ | |
10656 | + | |
10657 | +void | |
10658 | +type_incref (struct type *type) | |
10659 | +{ | |
7566401a | 10660 | +} |
3a58abaf | 10661 | + |
7566401a ER |
10662 | +/* Decrement the reference count for TYPE. If TYPE has no more |
10663 | + references, delete it. */ | |
3a58abaf | 10664 | + |
7566401a ER |
10665 | +void |
10666 | +type_decref (struct type *type) | |
10667 | +{ | |
3a58abaf AM |
10668 | +} |
10669 | + | |
7566401a ER |
10670 | +/* A traverse callback for type_discardable_table which removes any |
10671 | + type_discardable whose reference count is now zero (unused link). */ | |
3a58abaf AM |
10672 | + |
10673 | +static int | |
7566401a | 10674 | +type_discardable_remove (void **slot, void *unused) |
3a58abaf | 10675 | +{ |
7566401a ER |
10676 | + struct type *type = *slot; |
10677 | + | |
10678 | + gdb_assert (TYPE_DISCARDABLE (type)); | |
3a58abaf | 10679 | + |
7566401a | 10680 | + if (TYPE_DISCARDABLE_AGE (type) != type_discardable_age_current) |
3a58abaf | 10681 | + { |
7566401a | 10682 | + delete_type_chain (type); |
3a58abaf | 10683 | + |
7566401a | 10684 | + htab_clear_slot (type_discardable_table, slot); |
3a58abaf AM |
10685 | + } |
10686 | + | |
10687 | + return 1; | |
10688 | +} | |
10689 | + | |
7566401a ER |
10690 | +/* Free all the reclaimable types that have been allocated and that have |
10691 | + currently zero reference counter. | |
3a58abaf | 10692 | + |
7566401a ER |
10693 | + This function is called after each command, successful or not. Use this |
10694 | + cleanup only in the GDB idle state as GDB only marks those types used by | |
10695 | + globally tracked objects (with no autovariable references tracking). */ | |
3a58abaf AM |
10696 | + |
10697 | +void | |
10698 | +free_all_types (void) | |
10699 | +{ | |
7566401a ER |
10700 | + /* Mark a new pass. As GDB checks all the entries were visited after each |
10701 | + pass there cannot be any stale entries already containing the changed | |
10702 | + value. */ | |
10703 | + type_discardable_age_current ^= 1; | |
3a58abaf | 10704 | + |
7566401a ER |
10705 | + observer_notify_mark_used (); |
10706 | + | |
10707 | + htab_traverse (type_discardable_table, type_discardable_remove, NULL); | |
10708 | +} | |
10709 | ||
10710 | /* Helper functions to initialize architecture-specific types. */ | |
10711 | ||
10712 | @@ -3463,6 +3929,11 @@ void | |
10713 | _initialize_gdbtypes (void) | |
3a58abaf AM |
10714 | { |
10715 | gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init); | |
7566401a ER |
10716 | + |
10717 | + type_discardable_table = htab_create_alloc (20, type_discardable_hash, | |
10718 | + type_discardable_equal, NULL, | |
10719 | + xcalloc, xfree); | |
10720 | + | |
10721 | objfile_type_data = register_objfile_data (); | |
3a58abaf AM |
10722 | |
10723 | add_setshow_zinteger_cmd ("overload", no_class, &overload_debug, _("\ | |
3a58abaf | 10724 | diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h |
7566401a | 10725 | index be6ed55..6a51a4e 100644 |
3a58abaf AM |
10726 | --- a/gdb/gdbtypes.h |
10727 | +++ b/gdb/gdbtypes.h | |
7566401a | 10728 | @@ -137,6 +137,8 @@ enum type_code |
3a58abaf | 10729 | |
7566401a | 10730 | TYPE_CODE_DECFLOAT, /* Decimal floating point. */ |
3a58abaf | 10731 | |
7566401a | 10732 | + TYPE_CODE_MODULE, /* Fortran module. */ |
3a58abaf | 10733 | + |
7566401a ER |
10734 | /* Internal function type. */ |
10735 | TYPE_CODE_INTERNAL_FUNCTION | |
3a58abaf | 10736 | }; |
7566401a | 10737 | @@ -213,6 +215,11 @@ enum type_instance_flag_value |
3a58abaf AM |
10738 | |
10739 | #define TYPE_TARGET_STUB(t) (TYPE_MAIN_TYPE (t)->flag_target_stub) | |
10740 | ||
10741 | +/* Type needs to be evaluated on each CHECK_TYPEDEF and its results must not be | |
10742 | + sticky. */ | |
10743 | + | |
10744 | +#define TYPE_DYNAMIC(t) (TYPE_MAIN_TYPE (t)->flag_dynamic) | |
10745 | + | |
10746 | /* Static type. If this is set, the corresponding type had | |
10747 | * a static modifier. | |
10748 | * Note: This may be unnecessary, since static data members | |
7566401a ER |
10749 | @@ -278,6 +285,48 @@ enum type_instance_flag_value |
10750 | #define TYPE_OWNER(t) TYPE_MAIN_TYPE(t)->owner | |
10751 | #define TYPE_OBJFILE(t) (TYPE_OBJFILE_OWNED(t)? TYPE_OWNER(t).objfile : NULL) | |
3a58abaf | 10752 | |
7566401a ER |
10753 | +/* Define this type as being reclaimable during free_all_types. Type is |
10754 | + required to be have TYPE_OBJFILE set to NULL. Setting this flag requires | |
10755 | + initializing TYPE_DISCARDABLE_AGE, see alloc_type_discardable. */ | |
10756 | + | |
10757 | +#define TYPE_DISCARDABLE(t) (TYPE_MAIN_TYPE (t)->flag_discardable) | |
10758 | + | |
10759 | +/* Marker this type has been visited by the type_mark_used by this | |
10760 | + mark-and-sweep types garbage collecting pass. Current pass is represented | |
10761 | + by TYPE_DISCARDABLE_AGE_CURRENT. */ | |
10762 | + | |
10763 | +#define TYPE_DISCARDABLE_AGE(t) (TYPE_MAIN_TYPE (t)->flag_discardable_age) | |
10764 | + | |
3a58abaf AM |
10765 | +/* Is HIGH_BOUND a low-bound relative count (1) or the high bound itself (0)? */ |
10766 | + | |
10767 | +#define TYPE_RANGE_HIGH_BOUND_IS_COUNT(range_type) \ | |
10768 | + (TYPE_MAIN_TYPE (range_type)->flag_range_high_bound_is_count) | |
10769 | + | |
10770 | +/* Not allocated. TYPE_ALLOCATED(t) must be NULL in such case. If this flag | |
10771 | + is unset and TYPE_ALLOCATED(t) is NULL then the type is allocated. If this | |
10772 | + flag is unset and TYPE_ALLOCATED(t) is not NULL then its DWARF block | |
10773 | + determines the actual allocation state. */ | |
10774 | + | |
10775 | +#define TYPE_NOT_ALLOCATED(t) (TYPE_MAIN_TYPE (t)->flag_not_allocated) | |
10776 | + | |
10777 | +/* Not associated. TYPE_ASSOCIATED(t) must be NULL in such case. If this flag | |
10778 | + is unset and TYPE_ASSOCIATED(t) is NULL then the type is associated. If | |
10779 | + this flag is unset and TYPE_ASSOCIATED(t) is not NULL then its DWARF block | |
10780 | + determines the actual association state. */ | |
10781 | + | |
10782 | +#define TYPE_NOT_ASSOCIATED(t) (TYPE_MAIN_TYPE (t)->flag_not_associated) | |
10783 | + | |
10784 | +/* Address of the actual data as for DW_AT_data_location. Its dwarf block must | |
10785 | + not be evaluated unless both TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are | |
10786 | + false. If TYPE_DATA_LOCATION_IS_ADDR set then TYPE_DATA_LOCATION_ADDR value | |
10787 | + is the actual data address value. If unset and | |
10788 | + TYPE_DATA_LOCATION_DWARF_BLOCK is NULL then the value is the normal | |
7566401a | 10789 | + value_raw_address. If unset and TYPE_DATA_LOCATION_DWARF_BLOCK is not NULL |
3a58abaf AM |
10790 | + then its DWARF block determines the actual data address. */ |
10791 | + | |
10792 | +#define TYPE_DATA_LOCATION_IS_ADDR(t) \ | |
10793 | + (TYPE_MAIN_TYPE (t)->flag_data_location_is_addr) | |
10794 | + | |
10795 | /* Constant type. If this is set, the corresponding type has a | |
10796 | * const modifier. | |
10797 | */ | |
7566401a | 10798 | @@ -365,6 +414,13 @@ struct main_type |
3a58abaf AM |
10799 | unsigned int flag_nottext : 1; |
10800 | unsigned int flag_fixed_instance : 1; | |
7566401a ER |
10801 | unsigned int flag_objfile_owned : 1; |
10802 | + unsigned int flag_discardable : 1; | |
10803 | + unsigned int flag_discardable_age : 1; | |
3a58abaf AM |
10804 | + unsigned int flag_dynamic : 1; |
10805 | + unsigned int flag_range_high_bound_is_count : 1; | |
10806 | + unsigned int flag_not_allocated : 1; | |
10807 | + unsigned int flag_not_associated : 1; | |
10808 | + unsigned int flag_data_location_is_addr : 1; | |
10809 | ||
10810 | /* Number of fields described for this type. This field appears at | |
10811 | this location because it packs nicely here. */ | |
7566401a | 10812 | @@ -431,6 +487,20 @@ struct main_type |
3a58abaf AM |
10813 | |
10814 | struct type *target_type; | |
10815 | ||
10816 | + /* For DW_AT_data_location. */ | |
10817 | + union | |
10818 | + { | |
10819 | + struct dwarf2_locexpr_baton *dwarf_block; | |
10820 | + CORE_ADDR addr; | |
10821 | + } | |
10822 | + data_location; | |
10823 | + | |
10824 | + /* For DW_AT_allocated. */ | |
10825 | + struct dwarf2_locexpr_baton *allocated; | |
10826 | + | |
10827 | + /* For DW_AT_associated. */ | |
10828 | + struct dwarf2_locexpr_baton *associated; | |
10829 | + | |
10830 | /* For structure and union types, a description of each field. | |
10831 | For set and pascal array types, there is one "field", | |
10832 | whose type is the domain type of the set or array. | |
7566401a ER |
10833 | @@ -538,6 +608,9 @@ struct main_type |
10834 | supporting multiple ABIs. Right now this is only fetched from | |
10835 | the Dwarf-2 DW_AT_calling_convention attribute. */ | |
10836 | unsigned calling_convention; | |
10837 | + | |
10838 | + /* For TYPE_CODE_MODULE, the list of symbols contained in the module. */ | |
10839 | + struct block *module_block; | |
10840 | } type_specific; | |
10841 | }; | |
10842 | ||
10843 | @@ -812,9 +885,9 @@ extern void allocate_cplus_struct_type (struct type *); | |
3a58abaf AM |
10844 | #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type |
10845 | #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type | |
10846 | #define TYPE_CHAIN(thistype) (thistype)->chain | |
10847 | -/* Note that if thistype is a TYPEDEF type, you have to call check_typedef. | |
10848 | - But check_typedef does set the TYPE_LENGTH of the TYPEDEF type, | |
10849 | - so you only have to call check_typedef once. Since allocate_value | |
10850 | +/* Note that if thistype is a TYPEDEF, ARRAY or STRING type, you have to call | |
10851 | + check_typedef. But check_typedef does set the TYPE_LENGTH of the TYPEDEF | |
10852 | + type, so you only have to call check_typedef once. Since allocate_value | |
10853 | calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe. */ | |
10854 | #define TYPE_LENGTH(thistype) (thistype)->length | |
7566401a ER |
10855 | /* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real |
10856 | @@ -823,23 +896,44 @@ extern void allocate_cplus_struct_type (struct type *); | |
3a58abaf AM |
10857 | #define TYPE_NFIELDS(thistype) TYPE_MAIN_TYPE(thistype)->nfields |
10858 | #define TYPE_FIELDS(thistype) TYPE_MAIN_TYPE(thistype)->fields | |
10859 | #define TYPE_TEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->template_args | |
10860 | +#define TYPE_DATA_LOCATION_DWARF_BLOCK(thistype) TYPE_MAIN_TYPE (thistype)->data_location.dwarf_block | |
10861 | +#define TYPE_DATA_LOCATION_ADDR(thistype) TYPE_MAIN_TYPE (thistype)->data_location.addr | |
10862 | +#define TYPE_ALLOCATED(thistype) TYPE_MAIN_TYPE (thistype)->allocated | |
10863 | +#define TYPE_ASSOCIATED(thistype) TYPE_MAIN_TYPE (thistype)->associated | |
10864 | ||
10865 | #define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0) | |
10866 | #define TYPE_LOW_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 0) | |
10867 | #define TYPE_HIGH_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 1) | |
10868 | - | |
10869 | -/* Moto-specific stuff for FORTRAN arrays */ | |
10870 | - | |
10871 | -#define TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED(arraytype) \ | |
10872 | - (TYPE_FIELD_ARTIFICIAL(TYPE_INDEX_TYPE((arraytype)),1)) | |
10873 | +#define TYPE_BYTE_STRIDE(range_type) TYPE_FIELD_BITPOS (range_type, 2) | |
10874 | + | |
10875 | +/* Whether we should use TYPE_FIELD_DWARF_BLOCK (and not TYPE_FIELD_BITPOS). */ | |
10876 | +#define TYPE_RANGE_BOUND_IS_DWARF_BLOCK(range_type, fieldno) \ | |
10877 | + (TYPE_FIELD_LOC_KIND (range_type, fieldno) == FIELD_LOC_KIND_DWARF_BLOCK) | |
10878 | +#define TYPE_RANGE_BOUND_SET_DWARF_BLOCK(range_type, fieldno) \ | |
10879 | + (TYPE_FIELD_LOC_KIND (range_type, fieldno) = FIELD_LOC_KIND_DWARF_BLOCK) | |
10880 | +#define TYPE_ARRAY_BOUND_IS_DWARF_BLOCK(array_type, fieldno) \ | |
10881 | + TYPE_RANGE_BOUND_IS_DWARF_BLOCK (TYPE_INDEX_TYPE (array_type), fieldno) | |
10882 | + | |
10883 | +/* Unbound arrays, such as GCC array[]; at end of struct. */ | |
10884 | +#define TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED(rangetype) \ | |
10885 | + TYPE_FIELD_ARTIFICIAL((rangetype),0) | |
10886 | +#define TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED(rangetype) \ | |
10887 | + TYPE_FIELD_ARTIFICIAL((rangetype),1) | |
10888 | #define TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED(arraytype) \ | |
10889 | - (TYPE_FIELD_ARTIFICIAL(TYPE_INDEX_TYPE((arraytype)),0)) | |
10890 | - | |
10891 | -#define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \ | |
10892 | - (TYPE_HIGH_BOUND(TYPE_INDEX_TYPE((arraytype)))) | |
10893 | + TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED (TYPE_INDEX_TYPE (arraytype)) | |
10894 | +#define TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED(arraytype) \ | |
10895 | + TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (TYPE_INDEX_TYPE (arraytype)) | |
10896 | ||
10897 | #define TYPE_ARRAY_LOWER_BOUND_VALUE(arraytype) \ | |
10898 | - (TYPE_LOW_BOUND(TYPE_INDEX_TYPE((arraytype)))) | |
10899 | + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (arraytype)) | |
10900 | +#define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \ | |
10901 | + TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (arraytype)) | |
10902 | +/* TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)) with a fallback to the | |
10903 | + element size if no specific stride value is known. */ | |
10904 | +#define TYPE_ARRAY_BYTE_STRIDE_VALUE(arraytype) \ | |
10905 | + (TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)) == 0 \ | |
10906 | + ? TYPE_LENGTH (TYPE_TARGET_TYPE (arraytype)) \ | |
10907 | + : TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype))) | |
10908 | ||
10909 | /* C++ */ | |
10910 | ||
7566401a ER |
10911 | @@ -855,6 +949,7 @@ extern void allocate_cplus_struct_type (struct type *); |
10912 | #define TYPE_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff | |
10913 | #define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat | |
10914 | #define TYPE_CALLING_CONVENTION(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.calling_convention | |
10915 | +#define TYPE_MODULE_BLOCK(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.module_block | |
10916 | #define TYPE_BASECLASS(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].type | |
10917 | #define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses | |
10918 | #define TYPE_BASECLASS_NAME(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].name | |
10919 | @@ -1131,7 +1226,7 @@ extern const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN | |
10920 | Use alloc_type_arch to allocate a type owned by an architecture. | |
10921 | Use alloc_type_copy to allocate a type with the same owner as a | |
10922 | pre-existing template type, no matter whether objfile or gdbarch. */ | |
3a58abaf AM |
10923 | -extern struct type *alloc_type (struct objfile *); |
10924 | +extern struct type *alloc_type (struct objfile *, struct type *); | |
7566401a ER |
10925 | extern struct type *alloc_type_arch (struct gdbarch *); |
10926 | extern struct type *alloc_type_copy (const struct type *); | |
3a58abaf | 10927 | |
7566401a | 10928 | @@ -1226,6 +1321,18 @@ extern struct type *create_array_type (struct type *, struct type *, |
3a58abaf | 10929 | struct type *); |
7566401a | 10930 | extern struct type *lookup_array_range_type (struct type *, int, int); |
3a58abaf AM |
10931 | |
10932 | +extern CORE_ADDR type_range_any_field_internal (struct type *range_type, | |
10933 | + int fieldno); | |
10934 | + | |
10935 | +extern int type_range_high_bound_internal (struct type *range_type); | |
10936 | + | |
10937 | +extern int type_range_count_bound_internal (struct type *range_type); | |
10938 | + | |
10939 | +extern CORE_ADDR type_range_byte_stride_internal (struct type *range_type, | |
10940 | + struct type *element_type); | |
10941 | + | |
10942 | +extern void finalize_type (struct type *type); | |
10943 | + | |
7566401a ER |
10944 | extern struct type *create_string_type (struct type *, struct type *, |
10945 | struct type *); | |
10946 | extern struct type *lookup_string_range_type (struct type *, int, int); | |
10947 | @@ -1262,6 +1369,8 @@ extern int get_discrete_bounds (struct type *, LONGEST *, LONGEST *); | |
10948 | ||
10949 | extern int is_ancestor (struct type *, struct type *); | |
10950 | ||
10951 | +extern void type_mark_used (struct type *type); | |
10952 | + | |
10953 | /* Overload resolution */ | |
3a58abaf | 10954 | |
7566401a ER |
10955 | #define LENGTH_MATCH(bv) ((bv)->rank[0]) |
10956 | @@ -1324,10 +1433,15 @@ extern void maintenance_print_type (char *, int); | |
3a58abaf AM |
10957 | |
10958 | extern htab_t create_copied_types_hash (struct objfile *objfile); | |
10959 | ||
10960 | -extern struct type *copy_type_recursive (struct objfile *objfile, | |
10961 | - struct type *type, | |
10962 | +extern struct type *copy_type_recursive (struct type *type, | |
10963 | htab_t copied_types); | |
10964 | ||
10965 | extern struct type *copy_type (const struct type *type); | |
10966 | ||
7566401a ER |
10967 | +extern void free_all_types (void); |
10968 | + | |
3a58abaf AM |
10969 | +extern void type_incref (struct type *type); |
10970 | + | |
10971 | +extern void type_decref (struct type *type); | |
3a58abaf AM |
10972 | + |
10973 | #endif /* GDBTYPES_H */ | |
3a58abaf | 10974 | diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c |
7566401a | 10975 | index 0f9d44e..c910e88 100644 |
3a58abaf AM |
10976 | --- a/gdb/gnu-v3-abi.c |
10977 | +++ b/gdb/gnu-v3-abi.c | |
7566401a ER |
10978 | @@ -26,6 +26,7 @@ |
10979 | #include "demangle.h" | |
10980 | #include "objfiles.h" | |
10981 | #include "valprint.h" | |
10982 | +#include "c-lang.h" | |
10983 | ||
10984 | #include "gdb_assert.h" | |
10985 | #include "gdb_string.h" | |
10986 | @@ -459,10 +460,8 @@ gnuv3_find_method_in (struct type *domain, CORE_ADDR voffset, | |
3a58abaf AM |
10987 | LONGEST adjustment) |
10988 | { | |
10989 | int i; | |
10990 | - const char *physname; | |
10991 | ||
10992 | /* Search this class first. */ | |
10993 | - physname = NULL; | |
10994 | if (adjustment == 0) | |
10995 | { | |
10996 | int len; | |
7566401a | 10997 | @@ -590,15 +589,24 @@ gnuv3_print_method_ptr (const gdb_byte *contents, |
3a58abaf AM |
10998 | { |
10999 | char *demangled_name = cplus_demangle (physname, | |
11000 | DMGL_ANSI | DMGL_PARAMS); | |
11001 | - if (demangled_name != NULL) | |
11002 | + fprintf_filtered (stream, "&virtual "); | |
11003 | + if (demangled_name == NULL) | |
11004 | + fputs_filtered (physname, stream); | |
11005 | + else | |
11006 | { | |
11007 | - fprintf_filtered (stream, "&virtual "); | |
11008 | fputs_filtered (demangled_name, stream); | |
11009 | xfree (demangled_name); | |
11010 | - return; | |
11011 | } | |
11012 | + return; | |
11013 | } | |
11014 | } | |
7566401a ER |
11015 | + else if (ptr_value != 0) |
11016 | + { | |
11017 | + /* Found a non-virtual function: print out the type. */ | |
11018 | + fputs_filtered ("(", stream); | |
11019 | + c_print_type (type, "", stream, -1, 0); | |
11020 | + fputs_filtered (") ", stream); | |
11021 | + } | |
3a58abaf | 11022 | |
7566401a ER |
11023 | /* We didn't find it; print the raw data. */ |
11024 | if (vbit) | |
3a58abaf | 11025 | diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c |
ab050a48 | 11026 | index fe848ff..905dcc3 100644 |
3a58abaf AM |
11027 | --- a/gdb/i386-linux-nat.c |
11028 | +++ b/gdb/i386-linux-nat.c | |
7566401a ER |
11029 | @@ -586,6 +586,8 @@ i386_linux_store_inferior_registers (struct target_ops *ops, |
11030 | ||
11031 | static unsigned long i386_linux_dr[DR_CONTROL + 1]; | |
11032 | ||
11033 | +/* Get debug register REGNUM value from only the one LWP of PTID. */ | |
11034 | + | |
11035 | static unsigned long | |
11036 | i386_linux_dr_get (ptid_t ptid, int regnum) | |
3a58abaf | 11037 | { |
7566401a ER |
11038 | @@ -614,6 +616,8 @@ i386_linux_dr_get (ptid_t ptid, int regnum) |
11039 | return value; | |
11040 | } | |
3a58abaf | 11041 | |
7566401a | 11042 | +/* Set debug register REGNUM to VALUE in only the one LWP of PTID. */ |
3a58abaf | 11043 | + |
7566401a ER |
11044 | static void |
11045 | i386_linux_dr_set (ptid_t ptid, int regnum, unsigned long value) | |
11046 | { | |
11047 | @@ -630,6 +634,8 @@ i386_linux_dr_set (ptid_t ptid, int regnum, unsigned long value) | |
11048 | perror_with_name (_("Couldn't write debug register")); | |
11049 | } | |
3a58abaf | 11050 | |
7566401a ER |
11051 | +/* Set DR_CONTROL to ADDR in all LWPs of LWP_LIST. */ |
11052 | + | |
11053 | static void | |
11054 | i386_linux_dr_set_control (unsigned long control) | |
11055 | { | |
11056 | @@ -641,6 +647,8 @@ i386_linux_dr_set_control (unsigned long control) | |
11057 | i386_linux_dr_set (ptid, DR_CONTROL, control); | |
11058 | } | |
11059 | ||
11060 | +/* Set address REGNUM (zero based) to ADDR in all LWPs of LWP_LIST. */ | |
11061 | + | |
11062 | static void | |
11063 | i386_linux_dr_set_addr (int regnum, CORE_ADDR addr) | |
11064 | { | |
11065 | @@ -654,18 +662,55 @@ i386_linux_dr_set_addr (int regnum, CORE_ADDR addr) | |
11066 | i386_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr); | |
11067 | } | |
11068 | ||
11069 | +/* Set address REGNUM (zero based) to zero in all LWPs of LWP_LIST. */ | |
11070 | + | |
11071 | static void | |
11072 | i386_linux_dr_reset_addr (int regnum) | |
11073 | { | |
11074 | i386_linux_dr_set_addr (regnum, 0); | |
3a58abaf | 11075 | } |
3a58abaf | 11076 | |
7566401a ER |
11077 | +/* Get DR_STATUS from only the one LWP of INFERIOR_PTID. */ |
11078 | + | |
11079 | static unsigned long | |
11080 | i386_linux_dr_get_status (void) | |
11081 | { | |
11082 | return i386_linux_dr_get (inferior_ptid, DR_STATUS); | |
11083 | } | |
11084 | ||
ab050a48 | 11085 | +/* Unset MASK bits in DR_STATUS in all LWPs of LWP_LIST. */ |
7566401a ER |
11086 | + |
11087 | +static void | |
11088 | +i386_linux_dr_unset_status (unsigned long mask) | |
3a58abaf | 11089 | +{ |
7566401a ER |
11090 | + struct lwp_info *lp; |
11091 | + ptid_t ptid; | |
11092 | + | |
11093 | + ALL_LWPS (lp, ptid) | |
11094 | + { | |
11095 | + unsigned long value; | |
11096 | + | |
11097 | + value = i386_linux_dr_get (ptid, DR_STATUS); | |
11098 | + value &= ~mask; | |
11099 | + i386_linux_dr_set (ptid, DR_STATUS, value); | |
11100 | + } | |
11101 | +} | |
3a58abaf | 11102 | + |
7566401a ER |
11103 | +/* See i386_dr_low_type.detach. Do not use wrappers i386_linux_dr_set_control |
11104 | + or i386_linux_dr_reset_addr as they would modify the register cache | |
11105 | + (i386_linux_dr). */ | |
3a58abaf | 11106 | + |
7566401a ER |
11107 | +static void |
11108 | +i386_linux_dr_detach (void) | |
11109 | +{ | |
11110 | + int regnum; | |
3a58abaf | 11111 | + |
7566401a ER |
11112 | + i386_linux_dr_set (inferior_ptid, DR_CONTROL, 0); |
11113 | + i386_linux_dr_unset_status (~0UL); | |
11114 | + for (regnum = DR_FIRSTADDR; regnum <= DR_LASTADDR; regnum++) | |
11115 | + i386_linux_dr_set (inferior_ptid, regnum, 0); | |
3a58abaf AM |
11116 | +} |
11117 | + | |
7566401a ER |
11118 | static void |
11119 | i386_linux_new_thread (ptid_t ptid) | |
3a58abaf | 11120 | { |
7566401a ER |
11121 | @@ -837,6 +882,8 @@ _initialize_i386_linux_nat (void) |
11122 | i386_dr_low.set_addr = i386_linux_dr_set_addr; | |
11123 | i386_dr_low.reset_addr = i386_linux_dr_reset_addr; | |
11124 | i386_dr_low.get_status = i386_linux_dr_get_status; | |
11125 | + i386_dr_low.unset_status = i386_linux_dr_unset_status; | |
11126 | + i386_dr_low.detach = i386_linux_dr_detach; | |
11127 | i386_set_debug_register_length (4); | |
11128 | ||
11129 | /* Override the default ptrace resume method. */ | |
11130 | diff --git a/gdb/i386-nat.c b/gdb/i386-nat.c | |
ab050a48 | 11131 | index 325b4df..631ccd6 100644 |
7566401a ER |
11132 | --- a/gdb/i386-nat.c |
11133 | +++ b/gdb/i386-nat.c | |
11134 | @@ -137,8 +137,11 @@ struct i386_dr_low_type i386_dr_low; | |
11135 | #define I386_DR_GET_RW_LEN(i) \ | |
11136 | ((dr_control_mirror >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (i))) & 0x0f) | |
11137 | ||
11138 | +/* Mask that this I'th watchpoint has triggered. */ | |
11139 | +#define I386_DR_WATCH_MASK(i) (1 << (i)) | |
11140 | + | |
11141 | /* Did the watchpoint whose address is in the I'th register break? */ | |
11142 | -#define I386_DR_WATCH_HIT(i) (dr_status_mirror & (1 << (i))) | |
11143 | +#define I386_DR_WATCH_HIT(i) (dr_status_mirror & I386_DR_WATCH_MASK (i)) | |
11144 | ||
11145 | /* A macro to loop over all debug registers. */ | |
11146 | #define ALL_DEBUG_REGISTERS(i) for (i = 0; i < DR_NADDR; i++) | |
11147 | @@ -358,6 +361,10 @@ i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits) | |
11148 | i386_dr_low.set_addr (i, addr); | |
11149 | i386_dr_low.set_control (dr_control_mirror); | |
11150 | ||
11151 | + /* Only a sanity check for leftover bits (set possibly only by inferior). */ | |
11152 | + if (i386_dr_low.unset_status) | |
11153 | + i386_dr_low.unset_status (I386_DR_WATCH_MASK (i)); | |
3a58abaf | 11154 | + |
7566401a | 11155 | return 0; |
3a58abaf AM |
11156 | } |
11157 | ||
7566401a ER |
11158 | @@ -387,6 +394,11 @@ i386_remove_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits) |
11159 | i386_dr_low.set_control (dr_control_mirror); | |
11160 | if (i386_dr_low.reset_addr) | |
11161 | i386_dr_low.reset_addr (i); | |
11162 | + | |
11163 | + /* Status must be already queried for each LWP. Otherwise it will | |
11164 | + be lost in all-stop mode + breakpoint always-inserted off. */ | |
11165 | + if (i386_dr_low.unset_status) | |
11166 | + i386_dr_low.unset_status (I386_DR_WATCH_MASK (i)); | |
11167 | } | |
11168 | retval = 0; | |
11169 | } | |
11170 | @@ -520,6 +532,17 @@ i386_remove_watchpoint (CORE_ADDR addr, int len, int type) | |
11171 | return retval; | |
3a58abaf AM |
11172 | } |
11173 | ||
7566401a ER |
11174 | +/* See target_detach_watchpoints. */ |
11175 | + | |
11176 | +static int | |
11177 | +i386_detach_watchpoints (void) | |
3a58abaf | 11178 | +{ |
7566401a ER |
11179 | + if (i386_dr_low.detach) |
11180 | + i386_dr_low.detach (); | |
11181 | + | |
3a58abaf AM |
11182 | + return 0; |
11183 | +} | |
11184 | + | |
7566401a ER |
11185 | /* Return non-zero if we can watch a memory region that starts at |
11186 | address ADDR and whose length is LEN bytes. */ | |
11187 | ||
ab050a48 | 11188 | @@ -578,28 +601,7 @@ static int |
7566401a | 11189 | i386_stopped_by_watchpoint (void) |
3a58abaf | 11190 | { |
7566401a ER |
11191 | CORE_ADDR addr = 0; |
11192 | - return i386_stopped_data_address (¤t_target, &addr); | |
11193 | -} | |
11194 | - | |
11195 | -/* Return non-zero if the inferior has some break/watchpoint that | |
11196 | - triggered. */ | |
11197 | - | |
11198 | -static int | |
11199 | -i386_stopped_by_hwbp (void) | |
11200 | -{ | |
11201 | - int i; | |
11202 | - | |
11203 | - dr_status_mirror = i386_dr_low.get_status (); | |
11204 | - if (maint_show_dr) | |
11205 | - i386_show_dr ("stopped_by_hwbp", 0, 0, hw_execute); | |
11206 | - | |
11207 | - ALL_DEBUG_REGISTERS(i) | |
11208 | - { | |
11209 | - if (I386_DR_WATCH_HIT (i)) | |
11210 | - return 1; | |
11211 | - } | |
11212 | - | |
11213 | - return 0; | |
11214 | + return target_stopped_data_address (¤t_target, &addr); | |
11215 | } | |
11216 | ||
11217 | /* Insert a hardware-assisted breakpoint at BP_TGT->placed_address. | |
ab050a48 | 11218 | @@ -693,6 +695,7 @@ i386_use_watchpoints (struct target_ops *t) |
7566401a ER |
11219 | t->to_stopped_data_address = i386_stopped_data_address; |
11220 | t->to_insert_watchpoint = i386_insert_watchpoint; | |
11221 | t->to_remove_watchpoint = i386_remove_watchpoint; | |
11222 | + t->to_detach_watchpoints = i386_detach_watchpoints; | |
11223 | t->to_insert_hw_breakpoint = i386_insert_hw_breakpoint; | |
11224 | t->to_remove_hw_breakpoint = i386_remove_hw_breakpoint; | |
11225 | } | |
11226 | diff --git a/gdb/i386-nat.h b/gdb/i386-nat.h | |
11227 | index f49b9f6..cd31958 100644 | |
11228 | --- a/gdb/i386-nat.h | |
11229 | +++ b/gdb/i386-nat.h | |
11230 | @@ -49,16 +49,23 @@ extern void i386_use_watchpoints (struct target_ops *); | |
11231 | functions are: | |
11232 | ||
11233 | set_control -- set the debug control (DR7) | |
11234 | - register to a given value | |
11235 | + register to a given value for all LWPs | |
11236 | ||
11237 | set_addr -- put an address into one debug | |
11238 | - register | |
11239 | + register for all LWPs | |
11240 | ||
11241 | reset_addr -- reset the address stored in | |
11242 | - one debug register | |
11243 | + one debug register for all LWPs | |
11244 | ||
11245 | get_status -- return the value of the debug | |
11246 | - status (DR6) register. | |
11247 | + status (DR6) register for current LWP | |
11248 | + | |
11249 | + unset_status -- unset the specified bits of the debug | |
11250 | + status (DR6) register for all LWPs | |
11251 | + | |
11252 | + detach -- clear all debug registers of only the | |
11253 | + INFERIOR_PTID task without affecting any | |
11254 | + register caches. | |
11255 | ||
11256 | Additionally, the native file should set the debug_register_length | |
11257 | field to 4 or 8 depending on the number of bytes used for | |
11258 | @@ -70,6 +77,8 @@ struct i386_dr_low_type | |
11259 | void (*set_addr) (int, CORE_ADDR); | |
11260 | void (*reset_addr) (int); | |
11261 | unsigned long (*get_status) (void); | |
11262 | + void (*unset_status) (unsigned long); | |
11263 | + void (*detach) (void); | |
11264 | int debug_register_length; | |
11265 | }; | |
11266 | ||
ab050a48 BZ |
11267 | diff --git a/gdb/infcall.c b/gdb/infcall.c |
11268 | index c9d98cf..277399a 100644 | |
11269 | --- a/gdb/infcall.c | |
11270 | +++ b/gdb/infcall.c | |
11271 | @@ -441,6 +441,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) | |
11272 | struct gdbarch *gdbarch; | |
11273 | struct breakpoint *terminate_bp = NULL; | |
11274 | struct minimal_symbol *tm; | |
11275 | + struct cleanup *terminate_bp_cleanup = NULL; | |
11276 | ptid_t call_thread_ptid; | |
11277 | struct gdb_exception e; | |
11278 | const char *name; | |
11279 | @@ -772,7 +773,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) | |
11280 | ||
11281 | /* Register a clean-up for unwind_on_terminating_exception_breakpoint. */ | |
11282 | if (terminate_bp) | |
11283 | - make_cleanup_delete_breakpoint (terminate_bp); | |
11284 | + terminate_bp_cleanup = make_cleanup_delete_breakpoint (terminate_bp); | |
11285 | ||
11286 | /* - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - | |
11287 | If you're looking to implement asynchronous dummy-frames, then | |
11288 | @@ -987,6 +988,11 @@ When the function is done executing, GDB will silently stop."), | |
11289 | internal_error (__FILE__, __LINE__, _("... should not be here")); | |
11290 | } | |
11291 | ||
11292 | + /* If we get here and the std::terminate() breakpoint has been set, | |
11293 | + it has to be cleaned manually. */ | |
11294 | + if (terminate_bp) | |
11295 | + do_cleanups (terminate_bp_cleanup); | |
11296 | + | |
11297 | /* If we get here the called FUNCTION ran to completion, | |
11298 | and the dummy frame has already been popped. */ | |
11299 | ||
7566401a ER |
11300 | diff --git a/gdb/infcmd.c b/gdb/infcmd.c |
11301 | index 9e98290..fab1892 100644 | |
11302 | --- a/gdb/infcmd.c | |
11303 | +++ b/gdb/infcmd.c | |
11304 | @@ -801,7 +801,7 @@ nexti_command (char *count_string, int from_tty) | |
11305 | step_1 (1, 1, count_string); | |
11306 | } | |
11307 | ||
11308 | -static void | |
11309 | +void | |
11310 | delete_longjmp_breakpoint_cleanup (void *arg) | |
3a58abaf | 11311 | { |
7566401a ER |
11312 | int thread = * (int *) arg; |
11313 | @@ -841,10 +841,13 @@ step_1 (int skip_subroutines, int single_inst, char *count_string) | |
11314 | ||
11315 | if (!single_inst || skip_subroutines) /* leave si command alone */ | |
3a58abaf | 11316 | { |
7566401a ER |
11317 | + struct thread_info *tp = inferior_thread (); |
11318 | + | |
11319 | if (in_thread_list (inferior_ptid)) | |
11320 | thread = pid_to_thread_id (inferior_ptid); | |
11321 | ||
11322 | set_longjmp_breakpoint (thread); | |
11323 | + tp->initiating_frame = get_frame_id (get_current_frame ()); | |
11324 | ||
11325 | make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); | |
11326 | } | |
11327 | @@ -1193,6 +1196,15 @@ signal_command (char *signum_exp, int from_tty) | |
11328 | proceed ((CORE_ADDR) -1, oursig, 0); | |
3a58abaf AM |
11329 | } |
11330 | ||
7566401a | 11331 | +/* A continuation callback for until_next_command. */ |
3a58abaf | 11332 | + |
3a58abaf | 11333 | +static void |
7566401a | 11334 | +until_next_continuation (void *arg) |
3a58abaf | 11335 | +{ |
7566401a ER |
11336 | + struct thread_info *tp = arg; |
11337 | + delete_longjmp_breakpoint (tp->num); | |
3a58abaf | 11338 | +} |
7566401a ER |
11339 | + |
11340 | /* Proceed until we reach a different source line with pc greater than | |
11341 | our current one or exit the function. We skip calls in both cases. | |
3a58abaf | 11342 | |
7566401a ER |
11343 | @@ -1209,6 +1221,8 @@ until_next_command (int from_tty) |
11344 | struct symbol *func; | |
11345 | struct symtab_and_line sal; | |
11346 | struct thread_info *tp = inferior_thread (); | |
11347 | + int thread = tp->num; | |
11348 | + struct cleanup *old_chain; | |
3a58abaf | 11349 | |
7566401a ER |
11350 | clear_proceed_status (); |
11351 | set_step_frame (); | |
11352 | @@ -1244,7 +1258,19 @@ until_next_command (int from_tty) | |
11353 | ||
11354 | tp->step_multi = 0; /* Only one call to proceed */ | |
3a58abaf | 11355 | |
7566401a ER |
11356 | + set_longjmp_breakpoint (thread); |
11357 | + tp->initiating_frame = get_frame_id (frame); | |
11358 | + old_chain = make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); | |
11359 | + | |
11360 | proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1); | |
11361 | + | |
11362 | + if (target_can_async_p () && is_running (inferior_ptid)) | |
3a58abaf | 11363 | + { |
7566401a ER |
11364 | + discard_cleanups (old_chain); |
11365 | + add_continuation (tp, until_next_continuation, tp, NULL); | |
3a58abaf | 11366 | + } |
7566401a ER |
11367 | + else |
11368 | + do_cleanups (old_chain); | |
11369 | } | |
11370 | ||
11371 | static void | |
11372 | @@ -1421,6 +1447,7 @@ finish_command_continuation (void *arg) | |
11373 | if (bs != NULL && tp->proceed_to_finish) | |
11374 | observer_notify_normal_stop (bs, 1 /* print frame */); | |
11375 | delete_breakpoint (a->breakpoint); | |
11376 | + delete_longjmp_breakpoint (inferior_thread ()->num); | |
11377 | } | |
11378 | ||
11379 | static void | |
11380 | @@ -1504,6 +1531,7 @@ finish_forward (struct symbol *function, struct frame_info *frame) | |
11381 | struct breakpoint *breakpoint; | |
11382 | struct cleanup *old_chain; | |
11383 | struct finish_command_continuation_args *cargs; | |
11384 | + int thread = tp->num; | |
11385 | ||
11386 | sal = find_pc_line (get_frame_pc (frame), 0); | |
11387 | sal.pc = get_frame_pc (frame); | |
11388 | @@ -1514,6 +1542,10 @@ finish_forward (struct symbol *function, struct frame_info *frame) | |
11389 | ||
11390 | old_chain = make_cleanup_delete_breakpoint (breakpoint); | |
11391 | ||
11392 | + set_longjmp_breakpoint (thread); | |
11393 | + tp->initiating_frame = get_frame_id (frame); | |
11394 | + make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); | |
3a58abaf | 11395 | + |
7566401a ER |
11396 | tp->proceed_to_finish = 1; /* We want stop_registers, please... */ |
11397 | proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); | |
3a58abaf | 11398 | |
7566401a ER |
11399 | diff --git a/gdb/inferior.h b/gdb/inferior.h |
11400 | index f1b5d17..31add7d 100644 | |
11401 | --- a/gdb/inferior.h | |
11402 | +++ b/gdb/inferior.h | |
11403 | @@ -272,6 +272,8 @@ extern void interrupt_target_command (char *args, int from_tty); | |
11404 | ||
11405 | extern void interrupt_target_1 (int all_threads); | |
11406 | ||
11407 | +extern void delete_longjmp_breakpoint_cleanup (void *arg); | |
3a58abaf | 11408 | + |
7566401a ER |
11409 | extern void detach_command (char *, int); |
11410 | ||
11411 | extern void notice_new_inferior (ptid_t, int, int); | |
3a58abaf | 11412 | diff --git a/gdb/infrun.c b/gdb/infrun.c |
ab050a48 | 11413 | index ff7c6b9..9d29b15 100644 |
3a58abaf AM |
11414 | --- a/gdb/infrun.c |
11415 | +++ b/gdb/infrun.c | |
7566401a ER |
11416 | @@ -45,6 +45,8 @@ |
11417 | #include "language.h" | |
11418 | #include "solib.h" | |
11419 | #include "main.h" | |
11420 | +#include "dictionary.h" | |
11421 | +#include "block.h" | |
11422 | #include "gdb_assert.h" | |
11423 | #include "mi/mi-common.h" | |
11424 | #include "event-top.h" | |
11425 | @@ -1782,6 +1784,8 @@ static void insert_step_resume_breakpoint_at_sal (struct gdbarch *gdbarch, | |
11426 | struct symtab_and_line sr_sal, | |
11427 | struct frame_id sr_id); | |
11428 | static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR); | |
11429 | +static void check_exception_resume (struct execution_control_state *, | |
11430 | + struct frame_info *, struct symbol *); | |
3a58abaf | 11431 | |
7566401a ER |
11432 | static void stop_stepping (struct execution_control_state *ecs); |
11433 | static void prepare_to_wait (struct execution_control_state *ecs); | |
11434 | @@ -2687,6 +2691,10 @@ handle_inferior_event (struct execution_control_state *ecs) | |
3a58abaf | 11435 | |
7566401a ER |
11436 | stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid)); |
11437 | ||
11438 | + /* Clear WATCHPOINT_TRIGGERED values from previous stop which could | |
11439 | + confuse bpstat_stop_status and bpstat_explains_signal. */ | |
11440 | + watchpoints_triggered (&ecs->ws); | |
3a58abaf | 11441 | + |
7566401a | 11442 | ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); |
3a58abaf | 11443 | |
7566401a ER |
11444 | ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat); |
11445 | @@ -2724,6 +2732,10 @@ handle_inferior_event (struct execution_control_state *ecs) | |
3a58abaf | 11446 | |
7566401a | 11447 | stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid)); |
3a58abaf | 11448 | |
7566401a ER |
11449 | + /* Clear WATCHPOINT_TRIGGERED values from previous stop which could |
11450 | + confuse bpstat_stop_status and bpstat_explains_signal. */ | |
11451 | + watchpoints_triggered (&ecs->ws); | |
11452 | + | |
11453 | /* This causes the eventpoints and symbol table to be reset. | |
11454 | Must do this now, before trying to determine whether to | |
11455 | stop. */ | |
ab050a48 BZ |
11456 | @@ -2845,6 +2857,9 @@ targets should add new threads to the thread list themselves in non-stop mode.") |
11457 | { | |
11458 | struct regcache *regcache = get_thread_regcache (ecs->ptid); | |
11459 | struct gdbarch *gdbarch = get_regcache_arch (regcache); | |
11460 | + struct cleanup *old_chain = save_inferior_ptid (); | |
11461 | + | |
11462 | + inferior_ptid = ecs->ptid; | |
11463 | ||
11464 | fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = %s\n", | |
11465 | paddress (gdbarch, stop_pc)); | |
11466 | @@ -2861,6 +2876,8 @@ targets should add new threads to the thread list themselves in non-stop mode.") | |
11467 | fprintf_unfiltered (gdb_stdlog, | |
11468 | "infrun: (no data address available)\n"); | |
11469 | } | |
11470 | + | |
11471 | + do_cleanups (old_chain); | |
11472 | } | |
11473 | ||
11474 | if (stepping_past_singlestep_breakpoint) | |
11475 | @@ -3468,23 +3485,33 @@ process_event_stop_test: | |
7566401a ER |
11476 | |
11477 | ecs->event_thread->stepping_over_breakpoint = 1; | |
11478 | ||
11479 | - if (!gdbarch_get_longjmp_target_p (gdbarch) | |
11480 | - || !gdbarch_get_longjmp_target (gdbarch, frame, &jmp_buf_pc)) | |
11481 | + if (what.is_longjmp) | |
11482 | { | |
11483 | - if (debug_infrun) | |
11484 | - fprintf_unfiltered (gdb_stdlog, "\ | |
11485 | + if (!gdbarch_get_longjmp_target_p (gdbarch) | |
11486 | + || !gdbarch_get_longjmp_target (gdbarch, | |
11487 | + frame, &jmp_buf_pc)) | |
11488 | + { | |
11489 | + if (debug_infrun) | |
11490 | + fprintf_unfiltered (gdb_stdlog, "\ | |
11491 | infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n"); | |
11492 | - keep_going (ecs); | |
11493 | - return; | |
11494 | - } | |
11495 | + keep_going (ecs); | |
11496 | + return; | |
11497 | + } | |
11498 | ||
11499 | - /* We're going to replace the current step-resume breakpoint | |
11500 | - with a longjmp-resume breakpoint. */ | |
11501 | - delete_step_resume_breakpoint (ecs->event_thread); | |
11502 | + /* We're going to replace the current step-resume breakpoint | |
11503 | + with a longjmp-resume breakpoint. */ | |
11504 | + delete_step_resume_breakpoint (ecs->event_thread); | |
11505 | ||
11506 | - /* Insert a breakpoint at resume address. */ | |
11507 | - insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc); | |
11508 | + /* Insert a breakpoint at resume address. */ | |
11509 | + insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc); | |
11510 | + } | |
11511 | + else | |
11512 | + { | |
11513 | + struct symbol *func = get_frame_function (frame); | |
11514 | ||
11515 | + if (func) | |
11516 | + check_exception_resume (ecs, frame, func); | |
11517 | + } | |
11518 | keep_going (ecs); | |
11519 | return; | |
11520 | ||
ab050a48 | 11521 | @@ -3496,6 +3523,53 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n"); |
7566401a ER |
11522 | gdb_assert (ecs->event_thread->step_resume_breakpoint != NULL); |
11523 | delete_step_resume_breakpoint (ecs->event_thread); | |
11524 | ||
11525 | + if (!what.is_longjmp) | |
11526 | + { | |
11527 | + /* There are several cases to consider. | |
11528 | + | |
11529 | + 1. The initiating frame no longer exists. In this case | |
11530 | + we must stop, because the exception has gone too far. | |
11531 | + | |
11532 | + 2. The initiating frame exists, and is the same as the | |
11533 | + current frame. | |
11534 | + | |
11535 | + 2.1. If we are stepping, defer to the stepping logic. | |
11536 | + | |
11537 | + 2.2. Otherwise, we are not stepping, so we are doing a | |
11538 | + "finish" and we have reached the calling frame. So, | |
11539 | + stop. | |
11540 | + | |
11541 | + 3. The initiating frame exists and is different from | |
11542 | + the current frame. This means the exception has been | |
11543 | + caught beneath the initiating frame, so keep going. */ | |
11544 | + struct frame_info *init_frame | |
11545 | + = frame_find_by_id (ecs->event_thread->initiating_frame); | |
11546 | + if (init_frame) | |
11547 | + { | |
11548 | + struct frame_id current_id | |
11549 | + = get_frame_id (get_current_frame ()); | |
11550 | + if (frame_id_eq (current_id, | |
11551 | + ecs->event_thread->initiating_frame)) | |
11552 | + { | |
11553 | + if (ecs->event_thread->step_range_start) | |
11554 | + { | |
11555 | + /* Case 2.1. */ | |
11556 | + break; | |
11557 | + } | |
11558 | + else | |
11559 | + { | |
11560 | + /* Case 2.2: fall through. */ | |
11561 | + } | |
11562 | + } | |
11563 | + else | |
11564 | + { | |
11565 | + /* Case 3. */ | |
11566 | + keep_going (ecs); | |
11567 | + return; | |
11568 | + } | |
11569 | + } | |
11570 | + } | |
11571 | + | |
11572 | ecs->event_thread->stop_step = 1; | |
11573 | print_stop_reason (END_STEPPING_RANGE, 0); | |
11574 | stop_stepping (ecs); | |
ab050a48 | 11575 | @@ -4500,6 +4574,96 @@ insert_longjmp_resume_breakpoint (struct gdbarch *gdbarch, CORE_ADDR pc) |
7566401a | 11576 | set_momentary_breakpoint_at_pc (gdbarch, pc, bp_longjmp_resume); |
3a58abaf AM |
11577 | } |
11578 | ||
7566401a ER |
11579 | +/* Insert an exception resume breakpoint. TP is the thread throwing |
11580 | + the exception. The block B is the block of the unwinder debug hook | |
11581 | + function. FRAME is the frame corresponding to the call to this | |
11582 | + function. SYM is the symbol of the function argument holding the | |
11583 | + target PC of the exception. */ | |
11584 | + | |
11585 | +static void | |
11586 | +insert_exception_resume_breakpoint (struct thread_info *tp, | |
11587 | + struct block *b, | |
11588 | + struct frame_info *frame, | |
11589 | + struct symbol *sym) | |
3a58abaf | 11590 | +{ |
7566401a | 11591 | + struct gdb_exception e; |
3a58abaf | 11592 | + |
7566401a ER |
11593 | + /* We want to ignore errors here. */ |
11594 | + TRY_CATCH (e, RETURN_MASK_ALL) | |
11595 | + { | |
11596 | + struct symbol *vsym; | |
11597 | + struct value *value; | |
11598 | + CORE_ADDR handler; | |
11599 | + struct breakpoint *bp; | |
3a58abaf | 11600 | + |
7566401a ER |
11601 | + vsym = lookup_symbol (SYMBOL_LINKAGE_NAME (sym), b, VAR_DOMAIN, NULL); |
11602 | + value = read_var_value (vsym, frame); | |
11603 | + handler = value_as_address (value); | |
3a58abaf | 11604 | + |
7566401a ER |
11605 | + /* We're going to replace the current step-resume breakpoint |
11606 | + with an exception-resume breakpoint. */ | |
11607 | + delete_step_resume_breakpoint (tp); | |
3a58abaf | 11608 | + |
7566401a ER |
11609 | + if (debug_infrun) |
11610 | + fprintf_unfiltered (gdb_stdlog, | |
11611 | + "infrun: exception resume at %lx\n", | |
11612 | + (unsigned long) handler); | |
3a58abaf | 11613 | + |
7566401a ER |
11614 | + bp = set_momentary_breakpoint_at_pc (get_frame_arch (frame), |
11615 | + handler, bp_exception_resume); | |
11616 | + inferior_thread ()->step_resume_breakpoint = bp; | |
3a58abaf AM |
11617 | + } |
11618 | +} | |
11619 | + | |
7566401a ER |
11620 | +/* This is called when an exception has been intercepted. Check to |
11621 | + see whether the exception's destination is of interest, and if so, | |
11622 | + set an exception resume breakpoint there. */ | |
3a58abaf | 11623 | + |
7566401a ER |
11624 | +static void |
11625 | +check_exception_resume (struct execution_control_state *ecs, | |
11626 | + struct frame_info *frame, struct symbol *func) | |
11627 | +{ | |
11628 | + struct gdb_exception e; | |
3a58abaf | 11629 | + |
7566401a ER |
11630 | + TRY_CATCH (e, RETURN_MASK_ALL) |
11631 | + { | |
11632 | + struct block *b; | |
11633 | + struct dict_iterator iter; | |
11634 | + struct symbol *sym; | |
11635 | + int argno = 0; | |
11636 | + | |
11637 | + /* The exception breakpoint is a thread-specific breakpoint on | |
11638 | + the unwinder's debug hook, declared as: | |
11639 | + | |
11640 | + void _Unwind_DebugHook (void *cfa, void *handler); | |
11641 | + | |
11642 | + The CFA argument indicates the frame to which control is | |
11643 | + about to be transferred. HANDLER is the destination PC. | |
11644 | + | |
11645 | + We ignore the CFA and set a temporary breakpoint at HANDLER. | |
11646 | + This is not extremely efficient but it avoids issues in gdb | |
11647 | + with computing the DWARF CFA, and it also works even in weird | |
11648 | + cases such as throwing an exception from inside a signal | |
11649 | + handler. */ | |
11650 | + | |
11651 | + b = SYMBOL_BLOCK_VALUE (func); | |
11652 | + ALL_BLOCK_SYMBOLS (b, iter, sym) | |
11653 | + { | |
11654 | + if (!SYMBOL_IS_ARGUMENT (sym)) | |
11655 | + continue; | |
3a58abaf | 11656 | + |
7566401a ER |
11657 | + if (argno == 0) |
11658 | + ++argno; | |
11659 | + else | |
11660 | + { | |
11661 | + insert_exception_resume_breakpoint (ecs->event_thread, | |
11662 | + b, frame, sym); | |
11663 | + break; | |
11664 | + } | |
11665 | + } | |
11666 | + } | |
3a58abaf AM |
11667 | +} |
11668 | + | |
7566401a ER |
11669 | static void |
11670 | stop_stepping (struct execution_control_state *ecs) | |
11671 | { | |
ab050a48 | 11672 | @@ -4568,6 +4732,8 @@ keep_going (struct execution_control_state *ecs) |
7566401a ER |
11673 | } |
11674 | if (e.reason < 0) | |
11675 | { | |
11676 | + if (debug_infrun) | |
11677 | + exception_fprintf (gdb_stdlog, e, "infrun: exception while inserting breakpoints: "); | |
11678 | stop_stepping (ecs); | |
11679 | return; | |
11680 | } | |
3a58abaf | 11681 | diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c |
7566401a | 11682 | index 6b68e7d..5095180 100644 |
3a58abaf AM |
11683 | --- a/gdb/jv-lang.c |
11684 | +++ b/gdb/jv-lang.c | |
7566401a | 11685 | @@ -1121,6 +1121,7 @@ const struct exp_descriptor exp_descriptor_java = |
3a58abaf | 11686 | { |
7566401a ER |
11687 | print_subexp_standard, |
11688 | operator_length_standard, | |
11689 | + operator_check_standard, | |
11690 | op_name_standard, | |
11691 | dump_subexp_body_standard, | |
11692 | evaluate_subexp_java | |
11693 | diff --git a/gdb/language.h b/gdb/language.h | |
11694 | index c650e07..660fdf6 100644 | |
11695 | --- a/gdb/language.h | |
11696 | +++ b/gdb/language.h | |
11697 | @@ -237,7 +237,6 @@ struct language_defn | |
11698 | variables. */ | |
3a58abaf | 11699 | |
7566401a ER |
11700 | struct symbol *(*la_lookup_symbol_nonlocal) (const char *, |
11701 | - const char *, | |
11702 | const struct block *, | |
11703 | const domain_enum); | |
3a58abaf AM |
11704 | |
11705 | diff --git a/gdb/linespec.c b/gdb/linespec.c | |
7566401a | 11706 | index 3e943a1..b96d425 100644 |
3a58abaf AM |
11707 | --- a/gdb/linespec.c |
11708 | +++ b/gdb/linespec.c | |
7566401a ER |
11709 | @@ -30,6 +30,7 @@ |
11710 | #include "value.h" | |
11711 | #include "completer.h" | |
11712 | #include "cp-abi.h" | |
11713 | +#include "cp-support.h" | |
11714 | #include "parser-defs.h" | |
11715 | #include "block.h" | |
11716 | #include "objc-lang.h" | |
11717 | @@ -839,13 +840,33 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, | |
3a58abaf AM |
11718 | } |
11719 | else if (paren_pointer != NULL) | |
11720 | { | |
11721 | - p = paren_pointer + 1; | |
11722 | + /* We need to deal with method and function overloads | |
11723 | + with no parameters. Gdb and gcc (and who knows about other | |
11724 | + compilers) are very inconsistent with the keyword "void". | |
11725 | + Canonicalizing C++ types is insufficient in this case, since | |
11726 | + we still need to enforce the presence (or lack thereof) of | |
11727 | + "void". For simplicity, omit the keyword "void" if present. */ | |
11728 | + if (strncmp (paren_pointer - 5, "(void)", 6) == 0) | |
11729 | + { | |
11730 | + char *a, *b; | |
11731 | + a = paren_pointer - 4; | |
11732 | + b = paren_pointer; | |
11733 | + while ((*(a++) = *(b++)) != '\0') ; | |
11734 | + *a = '\0'; | |
11735 | + p = paren_pointer - 3; | |
11736 | + } | |
11737 | + else | |
11738 | + p = paren_pointer + 1; | |
11739 | } | |
11740 | else | |
11741 | { | |
11742 | p = skip_quoted (*argptr); | |
11743 | } | |
11744 | ||
11745 | + /* Make sure we keep important kewords like "const" */ | |
11746 | + if (strncmp (p, " const", 6) == 0) | |
11747 | + p += 6; | |
11748 | + | |
7566401a ER |
11749 | /* Keep any template parameters */ |
11750 | if (*p == '<') | |
11751 | p = find_template_name_end (p); | |
11752 | @@ -1257,6 +1278,9 @@ decode_compound (char **argptr, int funfirstline, char ***canonical, | |
11753 | /* Move pointer ahead to next double-colon. */ | |
11754 | while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')) | |
11755 | { | |
11756 | + if (current_language->la_language == language_cplus) | |
11757 | + p += cp_validate_operator (p); | |
3a58abaf | 11758 | + |
7566401a ER |
11759 | if (p[0] == '<') |
11760 | { | |
11761 | temp_end = find_template_name_end (p); | |
11762 | @@ -1334,6 +1358,15 @@ decode_compound (char **argptr, int funfirstline, char ***canonical, | |
11763 | while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':') | |
11764 | p++; | |
11765 | /* At this point p->"". String ended. */ | |
11766 | + /* Nope, C++ operators could have spaces in them | |
11767 | + ("foo::operator <" or "foo::operator delete []"). | |
11768 | + I apologize, this is a bit hacky... */ | |
11769 | + if (current_language->la_language == language_cplus | |
11770 | + && *p == ' ' && p - 8 - *argptr + 1 > 0) | |
11771 | + { | |
11772 | + /* The above loop has already swallowed "operator". */ | |
11773 | + p += cp_validate_operator (p - 8) - 8; | |
11774 | + } | |
11775 | } | |
3a58abaf | 11776 | |
7566401a ER |
11777 | /* Allocate our own copy of the substring between argptr and |
11778 | @@ -1407,6 +1440,7 @@ lookup_prefix_sym (char **argptr, char *p) | |
11779 | { | |
11780 | char *p1; | |
11781 | char *copy; | |
11782 | + struct symbol *sym; | |
3a58abaf | 11783 | |
7566401a ER |
11784 | /* Extract the class name. */ |
11785 | p1 = p; | |
11786 | @@ -1425,7 +1459,26 @@ lookup_prefix_sym (char **argptr, char *p) | |
11787 | /* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA", | |
11788 | argptr->"inA::fun" */ | |
11789 | ||
11790 | - return lookup_symbol (copy, 0, STRUCT_DOMAIN, 0); | |
11791 | + sym = lookup_symbol (copy, 0, STRUCT_DOMAIN, 0); | |
11792 | + if (sym == NULL) | |
11793 | + { | |
11794 | + /* Typedefs are in VAR_DOMAIN so the above symbol lookup will | |
11795 | + fail when the user attempts to lookup a method of a class | |
11796 | + via a typedef'd name (NOT via the classes name, which is already | |
11797 | + handled in symbol_matches_domain). So try the lookup again | |
11798 | + using VAR_DOMAIN (where typedefs live) and double-check that we | |
11799 | + found a struct/class type. */ | |
11800 | + struct symbol *s = lookup_symbol (copy, 0, VAR_DOMAIN, 0); | |
11801 | + if (s != NULL) | |
11802 | + { | |
11803 | + struct type *t = SYMBOL_TYPE (s); | |
11804 | + CHECK_TYPEDEF (t); | |
11805 | + if (TYPE_CODE (t) == TYPE_CODE_STRUCT) | |
11806 | + return s; | |
11807 | + } | |
11808 | + } | |
3a58abaf | 11809 | + |
7566401a ER |
11810 | + return sym; |
11811 | } | |
3a58abaf | 11812 | |
7566401a ER |
11813 | /* This finds the method COPY in the class whose type is T and whose |
11814 | @@ -1474,26 +1527,16 @@ find_method (int funfirstline, char ***canonical, char *saved_arg, | |
11815 | } | |
11816 | else | |
11817 | { | |
11818 | - char *tmp; | |
11819 | - | |
11820 | - if (is_operator_name (copy)) | |
11821 | - { | |
11822 | - tmp = (char *) alloca (strlen (copy + 3) + 9); | |
11823 | - strcpy (tmp, "operator "); | |
11824 | - strcat (tmp, copy + 3); | |
11825 | - } | |
11826 | - else | |
11827 | - tmp = copy; | |
11828 | if (not_found_ptr) | |
11829 | *not_found_ptr = 1; | |
11830 | - if (tmp[0] == '~') | |
11831 | + if (copy[0] == '~') | |
11832 | cplusplus_error (saved_arg, | |
11833 | "the class `%s' does not have destructor defined\n", | |
11834 | SYMBOL_PRINT_NAME (sym_class)); | |
11835 | else | |
11836 | cplusplus_error (saved_arg, | |
11837 | "the class %s does not have any method named %s\n", | |
11838 | - SYMBOL_PRINT_NAME (sym_class), tmp); | |
11839 | + SYMBOL_PRINT_NAME (sym_class), copy); | |
11840 | } | |
11841 | } | |
3a58abaf | 11842 | |
7566401a ER |
11843 | @@ -1780,7 +1823,7 @@ symbol_found (int funfirstline, char ***canonical, char *copy, |
11844 | { | |
11845 | struct blockvector *bv = BLOCKVECTOR (SYMBOL_SYMTAB (sym)); | |
11846 | struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); | |
11847 | - if (lookup_block_symbol (b, copy, NULL, VAR_DOMAIN) != NULL) | |
11848 | + if (lookup_block_symbol (b, copy, VAR_DOMAIN) != NULL) | |
11849 | build_canonical_line_spec (values.sals, copy, canonical); | |
11850 | } | |
11851 | return values; | |
11852 | diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c | |
11853 | index 98f6347..0907f03 100644 | |
11854 | --- a/gdb/linux-nat.c | |
11855 | +++ b/gdb/linux-nat.c | |
11856 | @@ -1710,6 +1710,7 @@ resume_callback (struct lwp_info *lp, void *data) | |
11857 | lp->stopped = 0; | |
11858 | lp->step = 0; | |
11859 | memset (&lp->siginfo, 0, sizeof (lp->siginfo)); | |
11860 | + lp->watchpoint_hit_set = 0; | |
11861 | } | |
11862 | else if (lp->stopped && debug_linux_nat) | |
11863 | fprintf_unfiltered (gdb_stdlog, "RC: Not resuming sibling %s (has pending)\n", | |
11864 | @@ -1847,6 +1848,7 @@ linux_nat_resume (struct target_ops *ops, | |
3a58abaf | 11865 | |
7566401a ER |
11866 | linux_ops->to_resume (linux_ops, ptid, step, signo); |
11867 | memset (&lp->siginfo, 0, sizeof (lp->siginfo)); | |
11868 | + lp->watchpoint_hit_set = 0; | |
3a58abaf | 11869 | |
7566401a ER |
11870 | if (debug_linux_nat) |
11871 | fprintf_unfiltered (gdb_stdlog, | |
11872 | @@ -2286,6 +2288,78 @@ maybe_clear_ignore_sigint (struct lwp_info *lp) | |
11873 | } | |
3a58abaf AM |
11874 | } |
11875 | ||
7566401a ER |
11876 | +/* Fetch the possible triggered data watchpoint info and store it to LP. |
11877 | + The hardware data watchpoint trigger gets cleared during this fetch. */ | |
3a58abaf AM |
11878 | + |
11879 | +static void | |
7566401a | 11880 | +save_sigtrap (struct lwp_info *lp) |
3a58abaf | 11881 | +{ |
7566401a | 11882 | + struct cleanup *old_chain; |
3a58abaf | 11883 | + |
7566401a ER |
11884 | + /* linux_nat_stopped_data_address is not even installed in this case. */ |
11885 | + if (linux_ops->to_stopped_data_address == NULL) | |
11886 | + return; | |
3a58abaf | 11887 | + |
7566401a ER |
11888 | + old_chain = save_inferior_ptid (); |
11889 | + inferior_ptid = lp->ptid; | |
3a58abaf | 11890 | + |
7566401a ER |
11891 | + lp->watchpoint_hit_set = |
11892 | + linux_ops->to_stopped_data_address (¤t_target, &lp->watchpoint_hit); | |
3a58abaf | 11893 | + |
7566401a | 11894 | + do_cleanups (old_chain); |
3a58abaf AM |
11895 | +} |
11896 | + | |
7566401a ER |
11897 | +/* Wrap target_stopped_data_address where the GNU/Linux native target may be |
11898 | + directed by the watchpoint/debug register number. Base the reported value | |
11899 | + on the triggered data address instead. During inferior stop the assignment | |
11900 | + of watchpoint/debug registers may change making the register number specific | |
11901 | + trigger info stale. */ | |
3a58abaf AM |
11902 | + |
11903 | +static int | |
7566401a | 11904 | +linux_nat_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p) |
3a58abaf | 11905 | +{ |
7566401a ER |
11906 | + struct lwp_info *lp = find_lwp_pid (inferior_ptid); |
11907 | + | |
11908 | + gdb_assert (lp != NULL); | |
11909 | + | |
11910 | + *addr_p = lp->watchpoint_hit; | |
11911 | + | |
11912 | + return lp->watchpoint_hit_set; | |
3a58abaf AM |
11913 | +} |
11914 | + | |
7566401a ER |
11915 | +/* In `set follow-fork-mode child' with multithreaded parent we need to detach |
11916 | + watchpoints from all the LWPs. In such case INFERIOR_PTID will be the | |
11917 | + non-threaded new child while LWP_LIST will still contain all the threads of | |
11918 | + the parent being detached. */ | |
11919 | + | |
11920 | +static int | |
11921 | +linux_nat_detach_watchpoints (void) | |
3a58abaf | 11922 | +{ |
7566401a ER |
11923 | + struct lwp_info *lp; |
11924 | + int found = 0, retval = 0; | |
11925 | + ptid_t filter = pid_to_ptid (ptid_get_pid (inferior_ptid)); | |
11926 | + struct cleanup *old_chain = save_inferior_ptid (); | |
3a58abaf | 11927 | + |
7566401a ER |
11928 | + for (lp = lwp_list; lp; lp = lp->next) |
11929 | + if (ptid_match (lp->ptid, filter)) | |
11930 | + { | |
11931 | + inferior_ptid = lp->ptid; | |
11932 | + retval |= linux_ops->to_detach_watchpoints (); | |
11933 | + found = 1; | |
11934 | + } | |
3a58abaf | 11935 | + |
7566401a | 11936 | + do_cleanups (old_chain); |
3a58abaf | 11937 | + |
7566401a ER |
11938 | + if (!found) |
11939 | + { | |
11940 | + gdb_assert (!is_lwp (inferior_ptid)); | |
3a58abaf | 11941 | + |
7566401a ER |
11942 | + retval |= linux_ops->to_detach_watchpoints (); |
11943 | + } | |
3a58abaf | 11944 | + |
7566401a | 11945 | + return retval; |
3a58abaf AM |
11946 | +} |
11947 | + | |
7566401a | 11948 | /* Wait until LP is stopped. */ |
3a58abaf AM |
11949 | |
11950 | static int | |
7566401a ER |
11951 | @@ -2337,6 +2411,8 @@ stop_wait_callback (struct lwp_info *lp, void *data) |
11952 | /* Save the trap's siginfo in case we need it later. */ | |
11953 | save_siginfo (lp); | |
3a58abaf | 11954 | |
7566401a | 11955 | + save_sigtrap (lp); |
3a58abaf | 11956 | + |
7566401a ER |
11957 | /* Now resume this LWP and get the SIGSTOP event. */ |
11958 | errno = 0; | |
11959 | ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); | |
11960 | @@ -2701,10 +2777,14 @@ linux_nat_filter_event (int lwpid, int status, int options) | |
11961 | add_thread (lp->ptid); | |
3a58abaf AM |
11962 | } |
11963 | ||
7566401a ER |
11964 | - /* Save the trap's siginfo in case we need it later. */ |
11965 | if (WIFSTOPPED (status) | |
11966 | && (WSTOPSIG (status) == SIGTRAP || WSTOPSIG (status) == TRAP_IS_SYSCALL)) | |
11967 | - save_siginfo (lp); | |
3a58abaf | 11968 | + { |
7566401a ER |
11969 | + /* Save the trap's siginfo in case we need it later. */ |
11970 | + save_siginfo (lp); | |
3a58abaf | 11971 | + |
7566401a ER |
11972 | + save_sigtrap (lp); |
11973 | + } | |
3a58abaf | 11974 | |
7566401a ER |
11975 | /* Handle GNU/Linux's extended waitstatus for trace events. |
11976 | It is necessary to check if WSTOPSIG is signaling that | |
11977 | @@ -4999,6 +5079,10 @@ linux_nat_add_target (struct target_ops *t) | |
11978 | t->to_thread_alive = linux_nat_thread_alive; | |
11979 | t->to_pid_to_str = linux_nat_pid_to_str; | |
11980 | t->to_has_thread_control = tc_schedlock; | |
11981 | + if (linux_ops->to_stopped_data_address) | |
11982 | + t->to_stopped_data_address = linux_nat_stopped_data_address; | |
11983 | + if (linux_ops->to_detach_watchpoints) | |
11984 | + t->to_detach_watchpoints = linux_nat_detach_watchpoints; | |
11985 | ||
11986 | t->to_can_async_p = linux_nat_can_async_p; | |
11987 | t->to_is_async_p = linux_nat_is_async_p; | |
3a58abaf | 11988 | diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h |
7566401a | 11989 | index eae74f3..73204fc 100644 |
3a58abaf AM |
11990 | --- a/gdb/linux-nat.h |
11991 | +++ b/gdb/linux-nat.h | |
7566401a ER |
11992 | @@ -62,6 +62,12 @@ struct lwp_info |
11993 | be the address of a hardware watchpoint. */ | |
11994 | struct siginfo siginfo; | |
3a58abaf | 11995 | |
7566401a ER |
11996 | + /* WATCHPOINT_HIT_SET is non-zero if this LWP stopped with a trap and a data |
11997 | + watchpoint has been found as triggered. In such case WATCHPOINT_HIT | |
11998 | + contains data address of the triggered data watchpoint. */ | |
11999 | + unsigned watchpoint_hit_set : 1; | |
12000 | + CORE_ADDR watchpoint_hit; | |
3a58abaf | 12001 | + |
7566401a ER |
12002 | /* Non-zero if we expect a duplicated SIGINT. */ |
12003 | int ignore_sigint; | |
3a58abaf | 12004 | |
3a58abaf | 12005 | diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c |
7566401a | 12006 | index 88c7e5e..2d0b3ca 100644 |
3a58abaf AM |
12007 | --- a/gdb/m2-lang.c |
12008 | +++ b/gdb/m2-lang.c | |
7566401a | 12009 | @@ -356,6 +356,7 @@ const struct exp_descriptor exp_descriptor_modula2 = |
3a58abaf | 12010 | { |
7566401a ER |
12011 | print_subexp_standard, |
12012 | operator_length_standard, | |
12013 | + operator_check_standard, | |
12014 | op_name_standard, | |
12015 | dump_subexp_body_standard, | |
12016 | evaluate_subexp_modula2 | |
12017 | diff --git a/gdb/machoread.c b/gdb/machoread.c | |
12018 | index 5f9a0fe..66fa067 100644 | |
12019 | --- a/gdb/machoread.c | |
12020 | +++ b/gdb/machoread.c | |
12021 | @@ -681,6 +681,7 @@ static struct sym_fns macho_sym_fns = { | |
12022 | macho_new_init, /* sym_new_init: init anything gbl to entire symtab */ | |
12023 | macho_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
12024 | macho_symfile_read, /* sym_read: read a symbol file into symtab */ | |
12025 | + NULL, /* sym_read_psymbols */ | |
12026 | macho_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
12027 | macho_symfile_offsets, /* sym_offsets: xlate external to internal form */ | |
12028 | NULL /* next: pointer to next struct sym_fns */ | |
3a58abaf | 12029 | diff --git a/gdb/main.c b/gdb/main.c |
7566401a | 12030 | index 55411a8..ac9a540 100644 |
3a58abaf AM |
12031 | --- a/gdb/main.c |
12032 | +++ b/gdb/main.c | |
7566401a | 12033 | @@ -40,6 +40,7 @@ |
3a58abaf AM |
12034 | #include "interps.h" |
12035 | #include "main.h" | |
12036 | ||
12037 | +#include "python/python.h" | |
7566401a | 12038 | #include "source.h" |
3a58abaf | 12039 | |
7566401a ER |
12040 | /* If nonzero, display time usage both at startup and for each command. */ |
12041 | @@ -259,6 +260,8 @@ captured_main (void *data) | |
3a58abaf AM |
12042 | char *cdarg = NULL; |
12043 | char *ttyarg = NULL; | |
12044 | ||
12045 | + int python_script = 0; | |
12046 | + | |
12047 | /* These are static so that we can take their address in an initializer. */ | |
12048 | static int print_help; | |
12049 | static int print_version; | |
7566401a | 12050 | @@ -434,10 +437,14 @@ captured_main (void *data) |
3a58abaf AM |
12051 | {"args", no_argument, &set_args, 1}, |
12052 | {"l", required_argument, 0, 'l'}, | |
12053 | {"return-child-result", no_argument, &return_child_result, 1}, | |
12054 | +#if HAVE_PYTHON | |
12055 | + {"python", no_argument, 0, 'P'}, | |
12056 | + {"P", no_argument, 0, 'P'}, | |
12057 | +#endif | |
12058 | {0, no_argument, 0, 0} | |
12059 | }; | |
12060 | ||
12061 | - while (1) | |
12062 | + while (!python_script) | |
12063 | { | |
12064 | int option_index; | |
12065 | ||
7566401a | 12066 | @@ -455,6 +462,9 @@ captured_main (void *data) |
3a58abaf AM |
12067 | case 0: |
12068 | /* Long option that just sets a flag. */ | |
12069 | break; | |
12070 | + case 'P': | |
12071 | + python_script = 1; | |
12072 | + break; | |
12073 | case OPT_SE: | |
12074 | symarg = optarg; | |
12075 | execarg = optarg; | |
7566401a | 12076 | @@ -631,7 +641,31 @@ extern int gdbtk_test (char *); |
3a58abaf AM |
12077 | use_windows = 0; |
12078 | } | |
12079 | ||
12080 | - if (set_args) | |
12081 | + if (python_script) | |
12082 | + { | |
12083 | + /* The first argument is a python script to evaluate, and | |
12084 | + subsequent arguments are passed to the script for | |
12085 | + processing there. */ | |
12086 | + if (optind >= argc) | |
12087 | + { | |
12088 | + fprintf_unfiltered (gdb_stderr, | |
12089 | + _("%s: Python script file name required\n"), | |
12090 | + argv[0]); | |
12091 | + exit (1); | |
12092 | + } | |
12093 | + | |
12094 | + /* FIXME: should handle inferior I/O intelligently here. | |
12095 | + E.g., should be possible to run gdb in pipeline and have | |
12096 | + Python (and gdb) output go to stderr or file; and if a | |
12097 | + prompt is needed, open the tty. */ | |
12098 | + quiet = 1; | |
12099 | + /* FIXME: should read .gdbinit if, and only if, a prompt is | |
12100 | + requested by the script. Though... maybe this is not | |
12101 | + ideal? */ | |
12102 | + /* FIXME: likewise, reading in history. */ | |
12103 | + inhibit_gdbinit = 1; | |
12104 | + } | |
12105 | + else if (set_args) | |
12106 | { | |
12107 | /* The remaining options are the command-line options for the | |
12108 | inferior. The first one is the sym/exec file, and the rest | |
7566401a | 12109 | @@ -864,7 +898,8 @@ Can't attach to process and specify a core file at the same time.")); |
3a58abaf AM |
12110 | xfree (cmdarg); |
12111 | ||
12112 | /* Read in the old history after all the command files have been read. */ | |
12113 | - init_history (); | |
12114 | + if (!python_script) | |
12115 | + init_history (); | |
12116 | ||
12117 | if (batch) | |
12118 | { | |
7566401a | 12119 | @@ -893,13 +928,25 @@ Can't attach to process and specify a core file at the same time.")); |
3a58abaf AM |
12120 | #endif |
12121 | } | |
12122 | ||
12123 | - /* NOTE: cagney/1999-11-07: There is probably no reason for not | |
12124 | - moving this loop and the code found in captured_command_loop() | |
12125 | - into the command_loop() proper. The main thing holding back that | |
12126 | - change - SET_TOP_LEVEL() - has been eliminated. */ | |
12127 | - while (1) | |
12128 | +#if HAVE_PYTHON | |
12129 | + if (python_script) | |
12130 | { | |
12131 | - catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); | |
12132 | + extern int pagination_enabled; | |
12133 | + pagination_enabled = 0; | |
12134 | + run_python_script (argc - optind, &argv[optind]); | |
12135 | + return 1; | |
12136 | + } | |
12137 | + else | |
12138 | +#endif | |
12139 | + { | |
12140 | + /* NOTE: cagney/1999-11-07: There is probably no reason for not | |
12141 | + moving this loop and the code found in captured_command_loop() | |
12142 | + into the command_loop() proper. The main thing holding back that | |
12143 | + change - SET_TOP_LEVEL() - has been eliminated. */ | |
12144 | + while (1) | |
12145 | + { | |
12146 | + catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); | |
12147 | + } | |
12148 | } | |
12149 | /* No exit -- exit is through quit_command. */ | |
12150 | } | |
7566401a | 12151 | @@ -931,7 +978,12 @@ print_gdb_help (struct ui_file *stream) |
3a58abaf AM |
12152 | fputs_unfiltered (_("\ |
12153 | This is the GNU debugger. Usage:\n\n\ | |
12154 | gdb [options] [executable-file [core-file or process-id]]\n\ | |
12155 | - gdb [options] --args executable-file [inferior-arguments ...]\n\n\ | |
12156 | + gdb [options] --args executable-file [inferior-arguments ...]\n"), stream); | |
12157 | +#if HAVE_PYTHON | |
12158 | + fputs_unfiltered (_("\ | |
12159 | + gdb [options] [--python|-P] script-file [script-arguments ...]\n"), stream); | |
12160 | +#endif | |
12161 | + fputs_unfiltered (_("\n\ | |
12162 | Options:\n\n\ | |
12163 | "), stream); | |
12164 | fputs_unfiltered (_("\ | |
7566401a | 12165 | @@ -969,7 +1021,13 @@ Options:\n\n\ |
3a58abaf AM |
12166 | --nw Do not use a window interface.\n\ |
12167 | --nx Do not read "), stream); | |
12168 | fputs_unfiltered (gdbinit, stream); | |
12169 | - fputs_unfiltered (_(" file.\n\ | |
12170 | + fputs_unfiltered (_(" file.\n"), stream); | |
12171 | +#if HAVE_PYTHON | |
12172 | + fputs_unfiltered (_("\ | |
12173 | + --python, -P Following argument is Python script file; remaining\n\ | |
12174 | + arguments are passed to script.\n"), stream); | |
12175 | +#endif | |
12176 | + fputs_unfiltered (_("\ | |
12177 | --quiet Do not print version number on startup.\n\ | |
12178 | --readnow Fully read symbol files on first access.\n\ | |
12179 | "), stream); | |
12180 | diff --git a/gdb/maint.c b/gdb/maint.c | |
7566401a | 12181 | index ecbae12..80fc36e 100644 |
3a58abaf AM |
12182 | --- a/gdb/maint.c |
12183 | +++ b/gdb/maint.c | |
7566401a | 12184 | @@ -914,4 +914,12 @@ When enabled GDB is profiled."), |
3a58abaf AM |
12185 | show_maintenance_profile_p, |
12186 | &maintenance_set_cmdlist, | |
12187 | &maintenance_show_cmdlist); | |
12188 | + add_setshow_filename_cmd ("gdb_datadir", class_maintenance, | |
12189 | + &gdb_datadir, _("Set GDB's datadir path."), | |
12190 | + _("Show GDB's datadir path."), | |
12191 | + _("\ | |
12192 | +When set, GDB uses the specified path to search for data files."), | |
12193 | + NULL, NULL, | |
12194 | + &maintenance_set_cmdlist, | |
12195 | + &maintenance_show_cmdlist); | |
12196 | } | |
12197 | diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c | |
7566401a | 12198 | index aac82e9..626292c 100644 |
3a58abaf AM |
12199 | --- a/gdb/mdebugread.c |
12200 | +++ b/gdb/mdebugread.c | |
7566401a | 12201 | @@ -4802,7 +4802,7 @@ new_type (char *name) |
3a58abaf AM |
12202 | { |
12203 | struct type *t; | |
12204 | ||
12205 | - t = alloc_type (current_objfile); | |
12206 | + t = alloc_type (current_objfile, NULL); | |
12207 | TYPE_NAME (t) = name; | |
12208 | TYPE_CPLUS_SPECIFIC (t) = (struct cplus_struct_type *) &cplus_struct_default; | |
12209 | return t; | |
12210 | diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c | |
7566401a | 12211 | index 0baaa83..94ebfeb 100644 |
3a58abaf AM |
12212 | --- a/gdb/mi/mi-cmd-var.c |
12213 | +++ b/gdb/mi/mi-cmd-var.c | |
7566401a ER |
12214 | @@ -697,7 +697,6 @@ mi_cmd_var_update (char *command, char **argv, int argc) |
12215 | } | |
12216 | else | |
12217 | { | |
12218 | - /* Get varobj handle, if a valid var obj name was specified */ | |
12219 | struct varobj *var = varobj_get_handle (name); | |
3a58abaf | 12220 | |
7566401a ER |
12221 | varobj_update_one (var, print_values, 1 /* explicit */); |
12222 | diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c | |
12223 | index 857a5d5..6181002 100644 | |
12224 | --- a/gdb/mi/mi-main.c | |
12225 | +++ b/gdb/mi/mi-main.c | |
12226 | @@ -1130,7 +1130,7 @@ mi_cmd_list_features (char *command, char **argv, int argc) | |
12227 | ui_out_field_string (uiout, NULL, "frozen-varobjs"); | |
12228 | ui_out_field_string (uiout, NULL, "pending-breakpoints"); | |
12229 | ui_out_field_string (uiout, NULL, "thread-info"); | |
12230 | - | |
3a58abaf | 12231 | + |
7566401a ER |
12232 | #if HAVE_PYTHON |
12233 | ui_out_field_string (uiout, NULL, "python"); | |
12234 | #endif | |
3a58abaf AM |
12235 | diff --git a/gdb/mipsread.c b/gdb/mipsread.c |
12236 | index a84003f..924c1c5 100644 | |
12237 | --- a/gdb/mipsread.c | |
12238 | +++ b/gdb/mipsread.c | |
12239 | @@ -394,6 +394,7 @@ static struct sym_fns ecoff_sym_fns = | |
12240 | mipscoff_new_init, /* sym_new_init: init anything gbl to entire symtab */ | |
12241 | mipscoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
12242 | mipscoff_symfile_read, /* sym_read: read a symbol file into symtab */ | |
12243 | + NULL, /* sym_read_psymbols */ | |
12244 | mipscoff_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
12245 | default_symfile_offsets, /* sym_offsets: dummy FIXME til implem sym reloc */ | |
12246 | default_symfile_segments, /* sym_segments: Get segment information from | |
3a58abaf | 12247 | diff --git a/gdb/objfiles.c b/gdb/objfiles.c |
ab050a48 | 12248 | index 8dcca70..e5442ca 100644 |
3a58abaf AM |
12249 | --- a/gdb/objfiles.c |
12250 | +++ b/gdb/objfiles.c | |
ab050a48 BZ |
12251 | @@ -634,6 +634,11 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) |
12252 | } | |
12253 | } | |
12254 | ||
12255 | + /* Alread QUICK_ADDRMAP tiself assumes all sections have the same offset. */ | |
12256 | + if (objfile->quick_addrmap) | |
12257 | + addrmap_relocate (objfile->quick_addrmap, | |
12258 | + ANOFFSET (delta, SECT_OFF_TEXT (objfile))); | |
12259 | + | |
12260 | { | |
12261 | struct partial_symbol **psym; | |
12262 | ||
12263 | @@ -731,6 +736,20 @@ have_partial_symbols (void) | |
7566401a ER |
12264 | if (objfile_has_partial_symbols (ofp)) |
12265 | return 1; | |
3a58abaf AM |
12266 | } |
12267 | + | |
12268 | + /* Try again, after reading partial symbols. We do this in two | |
12269 | + passes because objfiles are always added to the head of the list, | |
12270 | + and there might be a later objfile for which we've already read | |
12271 | + partial symbols. */ | |
12272 | + ALL_OBJFILES (ofp) | |
12273 | + { | |
12274 | + require_partial_symbols (ofp); | |
12275 | + if (ofp->psymtabs != NULL) | |
12276 | + { | |
12277 | + return 1; | |
12278 | + } | |
12279 | + } | |
12280 | + | |
12281 | return 0; | |
12282 | } | |
12283 | ||
12284 | diff --git a/gdb/objfiles.h b/gdb/objfiles.h | |
7566401a | 12285 | index 62fa498..1fc9c6a 100644 |
3a58abaf AM |
12286 | --- a/gdb/objfiles.h |
12287 | +++ b/gdb/objfiles.h | |
12288 | @@ -212,6 +212,11 @@ struct objfile | |
12289 | ||
12290 | struct partial_symtab *psymtabs; | |
12291 | ||
12292 | + /* An address map that can be used to quickly determine if an | |
12293 | + address comes from this objfile. This can be NULL. */ | |
12294 | + | |
12295 | + struct addrmap *quick_addrmap; | |
12296 | + | |
12297 | /* Map addresses to the entries of PSYMTABS. It would be more efficient to | |
12298 | have a map per the whole process but ADDRMAP cannot selectively remove | |
12299 | its items during FREE_OBJFILE. This mapping is already present even for | |
7566401a | 12300 | @@ -414,6 +419,15 @@ struct objfile |
3a58abaf | 12301 | |
7566401a | 12302 | #define OBJF_USERLOADED (1 << 3) /* User loaded */ |
3a58abaf AM |
12303 | |
12304 | +/* Set if we have tried to read partial symtabs for this objfile. | |
12305 | + This is used to allow lazy reading of partial symtabs. */ | |
12306 | + | |
12307 | +#define OBJF_SYMTABS_READ (1 << 6) | |
12308 | + | |
12309 | +/* This flag is set for the main objfile. */ | |
12310 | + | |
12311 | +#define OBJF_MAIN (1 << 7) | |
12312 | + | |
12313 | /* The object file that the main symbol table was loaded from (e.g. the | |
12314 | argument to the "symbol-file" or "file" command). */ | |
12315 | ||
7566401a | 12316 | @@ -568,6 +582,13 @@ extern void gdb_bfd_unref (struct bfd *abfd); |
3a58abaf AM |
12317 | ALL_OBJFILES (objfile) \ |
12318 | ALL_OBJFILE_PSYMTABS (objfile, p) | |
12319 | ||
12320 | +/* Like ALL_PSYMTABS, but ensure that partial symbols have been read | |
12321 | + before examining the objfile. */ | |
12322 | + | |
12323 | +#define ALL_PSYMTABS_REQUIRED(objfile, p) \ | |
12324 | + ALL_OBJFILES (objfile) \ | |
12325 | + ALL_OBJFILE_PSYMTABS (require_partial_symbols (objfile), p) | |
12326 | + | |
12327 | /* Traverse all minimal symbols in all objfiles. */ | |
12328 | ||
12329 | #define ALL_MSYMBOLS(objfile, m) \ | |
3a58abaf | 12330 | diff --git a/gdb/parse.c b/gdb/parse.c |
7566401a | 12331 | index ef938e3..c243bd8 100644 |
3a58abaf AM |
12332 | --- a/gdb/parse.c |
12333 | +++ b/gdb/parse.c | |
7566401a ER |
12334 | @@ -63,6 +63,7 @@ const struct exp_descriptor exp_descriptor_standard = |
12335 | { | |
12336 | print_subexp_standard, | |
12337 | operator_length_standard, | |
12338 | + operator_check_standard, | |
12339 | op_name_standard, | |
12340 | dump_subexp_body_standard, | |
12341 | evaluate_subexp_standard | |
12342 | @@ -837,6 +838,15 @@ operator_length_standard (struct expression *expr, int endpos, | |
3a58abaf AM |
12343 | args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); |
12344 | break; | |
12345 | ||
12346 | + case TYPE_INSTANCE: | |
12347 | + oplen = 4 + longest_to_int (expr->elts[endpos - 2].longconst); | |
12348 | + args = 1; | |
12349 | + break; | |
12350 | + | |
12351 | + case TYPE_INSTANCE_LOOKUP: | |
12352 | + oplen = 3; | |
12353 | + break; | |
12354 | + | |
12355 | case OP_OBJC_MSGCALL: /* Objective C message (method) call */ | |
12356 | oplen = 4; | |
12357 | args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); | |
7566401a ER |
12358 | @@ -1355,6 +1365,150 @@ parser_fprintf (FILE *x, const char *y, ...) |
12359 | va_end (args); | |
12360 | } | |
3a58abaf | 12361 | |
7566401a | 12362 | +/* Implementation of the exp_descriptor method operator_check. */ |
3a58abaf | 12363 | + |
7566401a ER |
12364 | +int |
12365 | +operator_check_standard (struct expression *exp, int pos, | |
12366 | + int (*type_func) (struct type *type, void *data), | |
12367 | + int (*objfile_func) (struct objfile *objfile, | |
12368 | + void *data), | |
12369 | + void *data) | |
12370 | +{ | |
12371 | + const union exp_element *const elts = exp->elts; | |
12372 | + struct type *type = NULL; | |
12373 | + struct objfile *objfile = NULL; | |
12374 | + | |
12375 | + /* Extended operators should have been already handled by exp_descriptor | |
12376 | + iterate method of its specific language. */ | |
12377 | + gdb_assert (elts[pos].opcode < OP_EXTENDED0); | |
12378 | + | |
12379 | + /* Track the callers of write_exp_elt_type for this table. */ | |
12380 | + | |
12381 | + switch (elts[pos].opcode) | |
12382 | + { | |
12383 | + case BINOP_VAL: | |
12384 | + case OP_COMPLEX: | |
12385 | + case OP_DECFLOAT: | |
12386 | + case OP_DOUBLE: | |
12387 | + case OP_LONG: | |
12388 | + case OP_SCOPE: | |
12389 | + case OP_TYPE: | |
12390 | + case UNOP_CAST: | |
12391 | + case UNOP_MAX: | |
12392 | + case UNOP_MEMVAL: | |
12393 | + case UNOP_MIN: | |
12394 | + type = elts[pos + 1].type; | |
12395 | + break; | |
3a58abaf | 12396 | + |
7566401a ER |
12397 | + case UNOP_MEMVAL_TLS: |
12398 | + objfile = elts[pos + 1].objfile; | |
12399 | + type = elts[pos + 2].type; | |
12400 | + break; | |
3a58abaf | 12401 | + |
7566401a ER |
12402 | + case OP_VAR_VALUE: |
12403 | + { | |
12404 | + const struct block *const block = elts[pos + 1].block; | |
12405 | + const struct symbol *const symbol = elts[pos + 2].symbol; | |
12406 | + const struct obj_section *const section = SYMBOL_OBJ_SECTION (symbol); | |
12407 | + | |
12408 | + /* Check objfile where the variable itself is placed. */ | |
12409 | + if (section && objfile_func && (*objfile_func) (section->objfile, data)) | |
12410 | + return 1; | |
12411 | + | |
12412 | + /* Check objfile where is placed the code touching the variable. */ | |
12413 | + objfile = block_objfile (block); | |
12414 | + | |
12415 | + type = SYMBOL_TYPE (symbol); | |
12416 | + } | |
12417 | + break; | |
12418 | + } | |
12419 | + | |
12420 | + /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL. */ | |
12421 | + | |
12422 | + if (type && type_func && (*type_func) (type, data)) | |
12423 | + return 1; | |
12424 | + if (type && TYPE_OBJFILE (type) && objfile_func | |
12425 | + && (*objfile_func) (TYPE_OBJFILE (type), data)) | |
12426 | + return 1; | |
12427 | + if (objfile && objfile_func && (*objfile_func) (objfile, data)) | |
12428 | + return 1; | |
12429 | + | |
12430 | + return 0; | |
12431 | +} | |
12432 | + | |
12433 | +/* Call TYPE_FUNC and OBJFILE_FUNC for any TYPE and OBJFILE found being | |
12434 | + referenced by EXP. The functions are never called with NULL TYPE or NULL | |
12435 | + OBJFILE. Functions get passed an arbitrary caller supplied DATA pointer. | |
12436 | + If any of the functions returns non-zero value then (any other) non-zero | |
12437 | + value is immediately returned to the caller. Otherwise zero is returned | |
12438 | + after iterating through whole EXP. */ | |
12439 | + | |
12440 | +static int | |
12441 | +exp_iterate (struct expression *exp, | |
12442 | + int (*type_func) (struct type *type, void *data), | |
12443 | + int (*objfile_func) (struct objfile *objfile, void *data), | |
12444 | + void *data) | |
3a58abaf | 12445 | +{ |
7566401a ER |
12446 | + int endpos; |
12447 | + const union exp_element *const elts = exp->elts; | |
12448 | + | |
12449 | + for (endpos = exp->nelts; endpos > 0; ) | |
12450 | + { | |
12451 | + int pos, args, oplen = 0; | |
3a58abaf | 12452 | + |
7566401a ER |
12453 | + exp->language_defn->la_exp_desc->operator_length (exp, endpos, |
12454 | + &oplen, &args); | |
12455 | + gdb_assert (oplen > 0); | |
3a58abaf | 12456 | + |
7566401a ER |
12457 | + pos = endpos - oplen; |
12458 | + if (exp->language_defn->la_exp_desc->operator_check (exp, pos, type_func, | |
12459 | + objfile_func, data)) | |
12460 | + return 1; | |
3a58abaf | 12461 | + |
7566401a ER |
12462 | + endpos = pos; |
12463 | + } | |
3a58abaf | 12464 | + |
7566401a ER |
12465 | + return 0; |
12466 | +} | |
3a58abaf | 12467 | + |
7566401a | 12468 | +/* Helper for exp_uses_objfile. */ |
3a58abaf | 12469 | + |
7566401a ER |
12470 | +static int |
12471 | +exp_uses_objfile_iter (struct objfile *exp_objfile, void *objfile_voidp) | |
12472 | +{ | |
12473 | + struct objfile *objfile = objfile_voidp; | |
12474 | + | |
12475 | + return exp_objfile == objfile; | |
3a58abaf AM |
12476 | +} |
12477 | + | |
7566401a ER |
12478 | +/* Return 1 if EXP uses OBJFILE (and will become dangling when OBJFILE |
12479 | + is unloaded), otherwise return 0. */ | |
3a58abaf | 12480 | + |
7566401a ER |
12481 | +int |
12482 | +exp_uses_objfile (struct expression *exp, struct objfile *objfile) | |
12483 | +{ | |
12484 | + return exp_iterate (exp, NULL, exp_uses_objfile_iter, objfile); | |
12485 | +} | |
3a58abaf | 12486 | + |
7566401a ER |
12487 | +/* Helper for exp_types_mark_used. */ |
12488 | + | |
12489 | +static int | |
12490 | +exp_types_mark_used_iter (struct type *type, void *unused) | |
12491 | +{ | |
12492 | + type_mark_used (type); | |
12493 | + | |
12494 | + /* Continue the traversal. */ | |
12495 | + return 0; | |
12496 | +} | |
12497 | + | |
12498 | +/* Call type_mark_used for any TYPE contained in EXP. */ | |
12499 | + | |
12500 | +void | |
12501 | +exp_types_mark_used (struct expression *exp) | |
12502 | +{ | |
12503 | + exp_iterate (exp, exp_types_mark_used_iter, NULL, NULL); | |
12504 | +} | |
12505 | + | |
12506 | void | |
12507 | _initialize_parse (void) | |
12508 | { | |
12509 | diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h | |
12510 | index cbda9c3..a07e6f2 100644 | |
12511 | --- a/gdb/parser-defs.h | |
12512 | +++ b/gdb/parser-defs.h | |
12513 | @@ -189,6 +189,13 @@ extern void operator_length (struct expression *, int, int *, int *); | |
12514 | ||
12515 | extern void operator_length_standard (struct expression *, int, int *, int *); | |
12516 | ||
12517 | +extern int operator_check_standard (struct expression *exp, int pos, | |
12518 | + int (*type_func) (struct type *type, | |
12519 | + void *data), | |
12520 | + int (*objfile_func) | |
12521 | + (struct objfile *objfile, void *data), | |
12522 | + void *data); | |
12523 | + | |
12524 | extern char *op_name_standard (enum exp_opcode); | |
12525 | ||
12526 | extern struct type *follow_types (struct type *); | |
12527 | @@ -267,6 +274,20 @@ struct exp_descriptor | |
12528 | the number of subexpressions it takes. */ | |
12529 | void (*operator_length) (struct expression*, int, int*, int *); | |
12530 | ||
12531 | + /* Call TYPE_FUNC and OBJFILE_FUNC for any TYPE and OBJFILE found being | |
12532 | + referenced by the single operator of EXP at position POS. Operator | |
12533 | + parameters are located at positive (POS + number) offsets in EXP. | |
12534 | + The functions should never be called with NULL TYPE or NULL OBJFILE. | |
12535 | + Functions should get passed an arbitrary caller supplied DATA pointer. | |
12536 | + If any of the functions returns non-zero value then (any other) non-zero | |
12537 | + value should be immediately returned to the caller. Otherwise zero | |
12538 | + should be returned. */ | |
12539 | + int (*operator_check) (struct expression *exp, int pos, | |
12540 | + int (*type_func) (struct type *type, void *data), | |
12541 | + int (*objfile_func) (struct objfile *objfile, | |
12542 | + void *data), | |
12543 | + void *data); | |
12544 | + | |
12545 | /* Name of this operator for dumping purposes. */ | |
12546 | char *(*op_name) (enum exp_opcode); | |
12547 | ||
12548 | @@ -299,4 +320,8 @@ extern void print_subexp_standard (struct expression *, int *, | |
12549 | ||
12550 | extern void parser_fprintf (FILE *, const char *, ...) ATTR_FORMAT (printf, 2 ,3); | |
12551 | ||
12552 | +extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile); | |
12553 | + | |
12554 | +extern void exp_types_mark_used (struct expression *exp); | |
12555 | + | |
12556 | #endif /* PARSER_DEFS_H */ | |
12557 | diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c | |
12558 | index 47b74ad..22fb2fc 100644 | |
12559 | --- a/gdb/ppc-linux-nat.c | |
12560 | +++ b/gdb/ppc-linux-nat.c | |
12561 | @@ -1391,6 +1391,24 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw) | |
12562 | return 0; | |
12563 | } | |
3a58abaf | 12564 | |
7566401a ER |
12565 | +/* See target_detach_watchpoints. Do not use wrapper |
12566 | + ppc_linux_remove_watchpoint as it would modify the register cache | |
12567 | + (saved_dabr_value). */ | |
12568 | + | |
12569 | +static int | |
12570 | +ppc_linux_detach_watchpoints (void) | |
12571 | +{ | |
12572 | + pid_t tid; | |
12573 | + | |
12574 | + tid = TIDGET (inferior_ptid); | |
12575 | + if (tid == 0) | |
12576 | + tid = PIDGET (inferior_ptid); | |
12577 | + | |
12578 | + if (ptrace (PTRACE_SET_DEBUGREG, tid, NULL, NULL) < 0) | |
12579 | + return -1; | |
12580 | + return 0; | |
12581 | +} | |
12582 | + | |
12583 | static void | |
12584 | ppc_linux_new_thread (ptid_t ptid) | |
12585 | { | |
12586 | @@ -1648,6 +1666,7 @@ _initialize_ppc_linux_nat (void) | |
12587 | t->to_region_ok_for_hw_watchpoint = ppc_linux_region_ok_for_hw_watchpoint; | |
12588 | t->to_insert_watchpoint = ppc_linux_insert_watchpoint; | |
12589 | t->to_remove_watchpoint = ppc_linux_remove_watchpoint; | |
12590 | + t->to_detach_watchpoints = ppc_linux_detach_watchpoints; | |
12591 | t->to_stopped_by_watchpoint = ppc_linux_stopped_by_watchpoint; | |
12592 | t->to_stopped_data_address = ppc_linux_stopped_data_address; | |
12593 | t->to_watchpoint_addr_within_range = ppc_linux_watchpoint_addr_within_range; | |
12594 | diff --git a/gdb/printcmd.c b/gdb/printcmd.c | |
12595 | index 5d8b936..fb0a455 100644 | |
12596 | --- a/gdb/printcmd.c | |
12597 | +++ b/gdb/printcmd.c | |
12598 | @@ -46,7 +46,6 @@ | |
12599 | #include "exceptions.h" | |
12600 | #include "observer.h" | |
12601 | #include "solist.h" | |
12602 | -#include "solib.h" | |
12603 | #include "parser-defs.h" | |
12604 | #include "charset.h" | |
3a58abaf | 12605 | |
7566401a | 12606 | @@ -900,6 +899,11 @@ print_command_1 (char *exp, int inspect, int voidprint) |
3a58abaf AM |
12607 | else |
12608 | val = access_value_history (0); | |
12609 | ||
12610 | + /* Do not try to OBJECT_ADDRESS_SET here anything. We are interested in the | |
12611 | + source variable base addresses as found by READ_VAR_VALUE. The value here | |
12612 | + can be already a calculated expression address inappropriate for | |
12613 | + DW_OP_push_object_address. */ | |
12614 | + | |
12615 | if (voidprint || (val && value_type (val) && | |
12616 | TYPE_CODE (value_type (val)) != TYPE_CODE_VOID)) | |
12617 | { | |
7566401a ER |
12618 | @@ -1396,6 +1400,22 @@ x_command (char *exp, int from_tty) |
12619 | set_internalvar (lookup_internalvar ("__"), last_examine_value); | |
12620 | } | |
12621 | } | |
12622 | + | |
12623 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ | |
12624 | + | |
12625 | +static void | |
12626 | +print_types_mark_used (void) | |
12627 | +{ | |
12628 | + struct display *d; | |
12629 | + | |
12630 | + if (last_examine_value) | |
12631 | + type_mark_used (value_type (last_examine_value)); | |
12632 | + | |
12633 | + for (d = display_chain; d; d = d->next) | |
12634 | + if (d->exp) | |
12635 | + exp_types_mark_used (d->exp); | |
12636 | +} | |
12637 | + | |
12638 | \f | |
3a58abaf | 12639 | |
7566401a ER |
12640 | /* Add an expression to the auto-display chain. |
12641 | @@ -1798,50 +1818,6 @@ disable_display_command (char *args, int from_tty) | |
12642 | } | |
12643 | } | |
3a58abaf | 12644 | |
7566401a ER |
12645 | -/* Return 1 if D uses SOLIB (and will become dangling when SOLIB |
12646 | - is unloaded), otherwise return 0. */ | |
12647 | - | |
12648 | -static int | |
12649 | -display_uses_solib_p (const struct display *d, | |
12650 | - const struct so_list *solib) | |
12651 | -{ | |
12652 | - int endpos; | |
12653 | - struct expression *const exp = d->exp; | |
12654 | - const union exp_element *const elts = exp->elts; | |
12655 | - | |
12656 | - if (d->block != NULL | |
12657 | - && solib_contains_address_p (solib, d->block->startaddr)) | |
12658 | - return 1; | |
12659 | - | |
12660 | - for (endpos = exp->nelts; endpos > 0; ) | |
12661 | - { | |
12662 | - int i, args, oplen = 0; | |
12663 | - | |
12664 | - exp->language_defn->la_exp_desc->operator_length (exp, endpos, | |
12665 | - &oplen, &args); | |
12666 | - gdb_assert (oplen > 0); | |
12667 | - | |
12668 | - i = endpos - oplen; | |
12669 | - if (elts[i].opcode == OP_VAR_VALUE) | |
12670 | - { | |
12671 | - const struct block *const block = elts[i + 1].block; | |
12672 | - const struct symbol *const symbol = elts[i + 2].symbol; | |
12673 | - const struct obj_section *const section = | |
12674 | - SYMBOL_OBJ_SECTION (symbol); | |
12675 | - | |
12676 | - if (block != NULL | |
12677 | - && solib_contains_address_p (solib, block->startaddr)) | |
12678 | - return 1; | |
12679 | - | |
12680 | - if (section && section->objfile == solib->objfile) | |
12681 | - return 1; | |
12682 | - } | |
12683 | - endpos -= oplen; | |
12684 | - } | |
12685 | - | |
12686 | - return 0; | |
12687 | -} | |
12688 | - | |
12689 | /* display_chain items point to blocks and expressions. Some expressions in | |
12690 | turn may point to symbols. | |
12691 | Both symbols and blocks are obstack_alloc'd on objfile_stack, and are | |
12692 | @@ -1853,18 +1829,20 @@ display_uses_solib_p (const struct display *d, | |
12693 | static void | |
12694 | clear_dangling_display_expressions (struct so_list *solib) | |
12695 | { | |
12696 | + struct objfile *objfile = solib->objfile; | |
12697 | struct display *d; | |
12698 | - struct objfile *objfile = NULL; | |
3a58abaf | 12699 | |
7566401a ER |
12700 | - for (d = display_chain; d; d = d->next) |
12701 | - { | |
12702 | - if (d->exp && display_uses_solib_p (d, solib)) | |
12703 | - { | |
12704 | - xfree (d->exp); | |
12705 | - d->exp = NULL; | |
12706 | - d->block = NULL; | |
12707 | - } | |
12708 | - } | |
12709 | + if (objfile == NULL) | |
12710 | + return; | |
3a58abaf | 12711 | + |
7566401a ER |
12712 | + for (d = display_chain; d != NULL; d = d->next) |
12713 | + if (block_objfile (d->block) == objfile | |
12714 | + || (d->exp && exp_uses_objfile (d->exp, objfile))) | |
12715 | + { | |
12716 | + xfree (d->exp); | |
12717 | + d->exp = NULL; | |
12718 | + d->block = NULL; | |
12719 | + } | |
12720 | } | |
12721 | \f | |
12722 | ||
12723 | @@ -2749,4 +2727,6 @@ Show printing of source filename and line number with <symbol>."), NULL, | |
12724 | NULL, | |
12725 | show_print_symbol_filename, | |
12726 | &setprintlist, &showprintlist); | |
3a58abaf | 12727 | + |
7566401a ER |
12728 | + observer_attach_mark_used (print_types_mark_used); |
12729 | } | |
3a58abaf AM |
12730 | diff --git a/gdb/python/lib/gdb/FrameIterator.py b/gdb/python/lib/gdb/FrameIterator.py |
12731 | new file mode 100644 | |
7566401a | 12732 | index 0000000..5654546 |
3a58abaf AM |
12733 | --- /dev/null |
12734 | +++ b/gdb/python/lib/gdb/FrameIterator.py | |
12735 | @@ -0,0 +1,33 @@ | |
12736 | +# Iterator over frames. | |
12737 | + | |
7566401a | 12738 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. |
3a58abaf AM |
12739 | + |
12740 | +# This program is free software; you can redistribute it and/or modify | |
12741 | +# it under the terms of the GNU General Public License as published by | |
12742 | +# the Free Software Foundation; either version 3 of the License, or | |
12743 | +# (at your option) any later version. | |
12744 | +# | |
12745 | +# This program is distributed in the hope that it will be useful, | |
12746 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12747 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12748 | +# GNU General Public License for more details. | |
12749 | +# | |
12750 | +# You should have received a copy of the GNU General Public License | |
12751 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
12752 | + | |
12753 | +class FrameIterator: | |
12754 | + """An iterator that iterates over frames.""" | |
12755 | + | |
12756 | + def __init__ (self, frame): | |
12757 | + "Initialize a FrameIterator. FRAME is the starting frame." | |
12758 | + self.frame = frame | |
12759 | + | |
12760 | + def __iter__ (self): | |
12761 | + return self | |
12762 | + | |
12763 | + def next (self): | |
12764 | + result = self.frame | |
7566401a | 12765 | + if result is None: |
3a58abaf AM |
12766 | + raise StopIteration |
12767 | + self.frame = result.older () | |
12768 | + return result | |
7566401a ER |
12769 | diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py |
12770 | new file mode 100644 | |
12771 | index 0000000..b790a54 | |
12772 | --- /dev/null | |
12773 | +++ b/gdb/python/lib/gdb/FrameWrapper.py | |
12774 | @@ -0,0 +1,112 @@ | |
12775 | +# Wrapper API for frames. | |
12776 | + | |
12777 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
12778 | + | |
12779 | +# This program is free software; you can redistribute it and/or modify | |
12780 | +# it under the terms of the GNU General Public License as published by | |
12781 | +# the Free Software Foundation; either version 3 of the License, or | |
12782 | +# (at your option) any later version. | |
12783 | +# | |
12784 | +# This program is distributed in the hope that it will be useful, | |
12785 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12786 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12787 | +# GNU General Public License for more details. | |
12788 | +# | |
12789 | +# You should have received a copy of the GNU General Public License | |
12790 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
12791 | + | |
12792 | +import gdb | |
12793 | + | |
12794 | +# FIXME: arguably all this should be on Frame somehow. | |
12795 | +class FrameWrapper: | |
12796 | + def __init__ (self, frame): | |
12797 | + self.frame = frame; | |
12798 | + | |
12799 | + def write_symbol (self, stream, sym, block): | |
12800 | + if len (sym.linkage_name): | |
12801 | + nsym, is_field_of_this = gdb.lookup_symbol (sym.linkage_name, block) | |
12802 | + if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER: | |
12803 | + sym = nsym | |
12804 | + | |
12805 | + stream.write (sym.print_name + "=") | |
12806 | + try: | |
12807 | + val = self.read_var (sym) | |
12808 | + if val != None: | |
12809 | + val = str (val) | |
12810 | + # FIXME: would be nice to have a more precise exception here. | |
12811 | + except RuntimeError, text: | |
12812 | + val = text | |
12813 | + if val == None: | |
12814 | + stream.write ("???") | |
12815 | + else: | |
12816 | + stream.write (str (val)) | |
12817 | + | |
12818 | + def print_frame_locals (self, stream, func): | |
12819 | + if not func: | |
12820 | + return | |
12821 | + | |
12822 | + first = True | |
12823 | + block = func.value | |
12824 | + | |
12825 | + for sym in block: | |
12826 | + if sym.is_argument: | |
12827 | + continue; | |
12828 | + | |
12829 | + self.write_symbol (stream, sym, block) | |
12830 | + stream.write ('\n') | |
12831 | + | |
12832 | + def print_frame_args (self, stream, func): | |
12833 | + if not func: | |
12834 | + return | |
12835 | + | |
12836 | + first = True | |
12837 | + block = func.value | |
12838 | + | |
12839 | + for sym in block: | |
12840 | + if not sym.is_argument: | |
12841 | + continue; | |
12842 | + | |
12843 | + if not first: | |
12844 | + stream.write (", ") | |
12845 | + | |
12846 | + self.write_symbol (stream, sym, block) | |
12847 | + first = False | |
12848 | + | |
12849 | + # FIXME: this should probably just be a method on gdb.Frame. | |
12850 | + # But then we need stream wrappers. | |
12851 | + def describe (self, stream, full): | |
12852 | + if self.type () == gdb.DUMMY_FRAME: | |
12853 | + stream.write (" <function called from gdb>\n") | |
12854 | + elif self.type () == gdb.SIGTRAMP_FRAME: | |
12855 | + stream.write (" <signal handler called>\n") | |
12856 | + else: | |
12857 | + sal = self.find_sal () | |
12858 | + pc = self.pc () | |
12859 | + name = self.name () | |
12860 | + if not name: | |
12861 | + name = "??" | |
12862 | + if pc != sal.pc or not sal.symtab: | |
12863 | + stream.write (" 0x%08x in" % pc) | |
12864 | + stream.write (" " + name + " (") | |
12865 | + | |
12866 | + func = self.function () | |
12867 | + self.print_frame_args (stream, func) | |
12868 | + | |
12869 | + stream.write (")") | |
12870 | + | |
12871 | + if sal.symtab and sal.symtab.filename: | |
12872 | + stream.write (" at " + sal.symtab.filename) | |
12873 | + stream.write (":" + str (sal.line)) | |
12874 | + | |
12875 | + if not self.name () or (not sal.symtab or not sal.symtab.filename): | |
12876 | + lib = gdb.solib_address (pc) | |
12877 | + if lib: | |
12878 | + stream.write (" from " + lib) | |
12879 | + | |
12880 | + stream.write ("\n") | |
12881 | + | |
12882 | + if full: | |
12883 | + self.print_frame_locals (stream, func) | |
12884 | + | |
12885 | + def __getattr__ (self, name): | |
12886 | + return getattr (self.frame, name) | |
3a58abaf AM |
12887 | diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py |
12888 | new file mode 100644 | |
12889 | index 0000000..b375c68 | |
12890 | --- /dev/null | |
12891 | +++ b/gdb/python/lib/gdb/__init__.py | |
12892 | @@ -0,0 +1,19 @@ | |
12893 | +# Startup code. | |
12894 | + | |
12895 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
12896 | + | |
12897 | +# This program is free software; you can redistribute it and/or modify | |
12898 | +# it under the terms of the GNU General Public License as published by | |
12899 | +# the Free Software Foundation; either version 3 of the License, or | |
12900 | +# (at your option) any later version. | |
12901 | +# | |
12902 | +# This program is distributed in the hope that it will be useful, | |
12903 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12904 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12905 | +# GNU General Public License for more details. | |
12906 | +# | |
12907 | +# You should have received a copy of the GNU General Public License | |
12908 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
12909 | + | |
12910 | +# Load the require command by default. | |
12911 | +import gdb.command.require | |
12912 | diff --git a/gdb/python/lib/gdb/backtrace.py b/gdb/python/lib/gdb/backtrace.py | |
12913 | new file mode 100644 | |
12914 | index 0000000..2baab5f | |
12915 | --- /dev/null | |
12916 | +++ b/gdb/python/lib/gdb/backtrace.py | |
12917 | @@ -0,0 +1,42 @@ | |
12918 | +# Filtering backtrace. | |
12919 | + | |
12920 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
12921 | + | |
12922 | +# This program is free software; you can redistribute it and/or modify | |
12923 | +# it under the terms of the GNU General Public License as published by | |
12924 | +# the Free Software Foundation; either version 3 of the License, or | |
12925 | +# (at your option) any later version. | |
12926 | +# | |
12927 | +# This program is distributed in the hope that it will be useful, | |
12928 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12929 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12930 | +# GNU General Public License for more details. | |
12931 | +# | |
12932 | +# You should have received a copy of the GNU General Public License | |
12933 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
12934 | + | |
12935 | +import gdb | |
12936 | +import itertools | |
12937 | + | |
12938 | +# Our only exports. | |
12939 | +__all__ = ['push_frame_filter', 'create_frame_filter'] | |
12940 | + | |
12941 | +frame_filter = None | |
12942 | + | |
12943 | +def push_frame_filter (constructor): | |
12944 | + """Register a new backtrace filter class with the 'backtrace' command. | |
12945 | +The filter will be passed an iterator as an argument. The iterator | |
12946 | +will return gdb.Frame-like objects. The filter should in turn act as | |
12947 | +an iterator returning such objects.""" | |
12948 | + global frame_filter | |
12949 | + if frame_filter == None: | |
12950 | + frame_filter = constructor | |
12951 | + else: | |
12952 | + frame_filter = lambda iterator: constructor (frame_filter (iterator)) | |
12953 | + | |
12954 | +def create_frame_filter (iter): | |
12955 | + global frame_filter | |
12956 | + if frame_filter is None: | |
12957 | + return iter | |
12958 | + return frame_filter (iter) | |
12959 | + | |
12960 | diff --git a/gdb/python/lib/gdb/command/__init__.py b/gdb/python/lib/gdb/command/__init__.py | |
12961 | new file mode 100644 | |
12962 | index 0000000..8b13789 | |
12963 | --- /dev/null | |
12964 | +++ b/gdb/python/lib/gdb/command/__init__.py | |
12965 | @@ -0,0 +1 @@ | |
12966 | + | |
12967 | diff --git a/gdb/python/lib/gdb/command/alias.py b/gdb/python/lib/gdb/command/alias.py | |
12968 | new file mode 100644 | |
12969 | index 0000000..96b6618 | |
12970 | --- /dev/null | |
12971 | +++ b/gdb/python/lib/gdb/command/alias.py | |
12972 | @@ -0,0 +1,59 @@ | |
12973 | +# Alias command. | |
12974 | + | |
12975 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
12976 | + | |
12977 | +# This program is free software; you can redistribute it and/or modify | |
12978 | +# it under the terms of the GNU General Public License as published by | |
12979 | +# the Free Software Foundation; either version 3 of the License, or | |
12980 | +# (at your option) any later version. | |
12981 | +# | |
12982 | +# This program is distributed in the hope that it will be useful, | |
12983 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12984 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12985 | +# GNU General Public License for more details. | |
12986 | +# | |
12987 | +# You should have received a copy of the GNU General Public License | |
12988 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
12989 | + | |
12990 | +import gdb | |
12991 | + | |
12992 | +class AliasImplementation (gdb.Command): | |
12993 | + def __init__ (self, name, real, doc): | |
12994 | + # Have to set __doc__ before the super init call. | |
12995 | + # It would be nice if gdb's help looked up __doc__ dynamically. | |
12996 | + self.__doc__ = doc | |
12997 | + # Note: no good way to complete :( | |
12998 | + super (AliasImplementation, self).__init__ (name, gdb.COMMAND_NONE) | |
12999 | + self.real = real | |
13000 | + | |
13001 | + def invoke(self, arg, from_tty): | |
13002 | + gdb.execute (self.real + ' ' + arg, from_tty) | |
13003 | + | |
13004 | +class AliasCommand (gdb.Command): | |
13005 | + """Alias one command to another. | |
13006 | +In the simplest form, the first word is the name of the alias, and | |
13007 | +the remaining words are the the expansion. | |
13008 | +An '=' by itself can be used to define a multi-word alias; words | |
13009 | +before the '=' are the name of the new command.""" | |
13010 | + | |
13011 | + def __init__ (self): | |
13012 | + # Completion is not quite right here. | |
13013 | + super (AliasCommand, self).__init__ ("alias", gdb.COMMAND_NONE, | |
13014 | + gdb.COMPLETE_COMMAND) | |
13015 | + | |
13016 | + def invoke (self, arg, from_tty): | |
13017 | + self.dont_repeat () | |
13018 | + # Without some form of quoting we can't alias a multi-word | |
13019 | + # command to another command. | |
13020 | + args = arg.split() | |
13021 | + try: | |
13022 | + start = args.index ('=') | |
13023 | + end = start + 1 | |
13024 | + except ValueError: | |
13025 | + start = 1 | |
13026 | + end = 1 | |
13027 | + target = " ".join(args[end:]) | |
13028 | + AliasImplementation (" ".join (args[0:start]), target, | |
13029 | + "This command is an alias for '%s'." % target) | |
13030 | + | |
13031 | +AliasCommand() | |
13032 | diff --git a/gdb/python/lib/gdb/command/backtrace.py b/gdb/python/lib/gdb/command/backtrace.py | |
13033 | new file mode 100644 | |
7566401a | 13034 | index 0000000..ec9a527 |
3a58abaf AM |
13035 | --- /dev/null |
13036 | +++ b/gdb/python/lib/gdb/command/backtrace.py | |
7566401a | 13037 | @@ -0,0 +1,106 @@ |
3a58abaf AM |
13038 | +# New backtrace command. |
13039 | + | |
7566401a | 13040 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. |
3a58abaf AM |
13041 | + |
13042 | +# This program is free software; you can redistribute it and/or modify | |
13043 | +# it under the terms of the GNU General Public License as published by | |
13044 | +# the Free Software Foundation; either version 3 of the License, or | |
13045 | +# (at your option) any later version. | |
13046 | +# | |
13047 | +# This program is distributed in the hope that it will be useful, | |
13048 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13049 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13050 | +# GNU General Public License for more details. | |
13051 | +# | |
13052 | +# You should have received a copy of the GNU General Public License | |
13053 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13054 | + | |
13055 | +import gdb | |
13056 | +import gdb.backtrace | |
13057 | +import itertools | |
13058 | +from gdb.FrameIterator import FrameIterator | |
7566401a | 13059 | +from gdb.FrameWrapper import FrameWrapper |
3a58abaf AM |
13060 | +import sys |
13061 | + | |
3a58abaf AM |
13062 | +class ReverseBacktraceParameter (gdb.Parameter): |
13063 | + """The new-backtrace command can show backtraces in 'reverse' order. | |
13064 | +This means that the innermost frame will be printed last. | |
13065 | +Note that reverse backtraces are more expensive to compute.""" | |
13066 | + | |
13067 | + set_doc = "Enable or disable reverse backtraces." | |
13068 | + show_doc = "Show whether backtraces will be printed in reverse order." | |
13069 | + | |
13070 | + def __init__(self): | |
13071 | + gdb.Parameter.__init__ (self, "reverse-backtrace", | |
13072 | + gdb.COMMAND_STACK, gdb.PARAM_BOOLEAN) | |
13073 | + # Default to compatibility with gdb. | |
13074 | + self.value = False | |
13075 | + | |
13076 | +class FilteringBacktrace (gdb.Command): | |
13077 | + """Print backtrace of all stack frames, or innermost COUNT frames. | |
13078 | +With a negative argument, print outermost -COUNT frames. | |
13079 | +Use of the 'full' qualifier also prints the values of the local variables. | |
13080 | +Use of the 'raw' qualifier avoids any filtering by loadable modules. | |
13081 | +""" | |
13082 | + | |
13083 | + def __init__ (self): | |
13084 | + # FIXME: this is not working quite well enough to replace | |
13085 | + # "backtrace" yet. | |
13086 | + gdb.Command.__init__ (self, "new-backtrace", gdb.COMMAND_STACK) | |
13087 | + self.reverse = ReverseBacktraceParameter() | |
13088 | + | |
13089 | + def reverse_iter (self, iter): | |
13090 | + result = [] | |
13091 | + for item in iter: | |
13092 | + result.append (item) | |
13093 | + result.reverse() | |
13094 | + return result | |
13095 | + | |
13096 | + def final_n (self, iter, x): | |
13097 | + result = [] | |
13098 | + for item in iter: | |
13099 | + result.append (item) | |
13100 | + return result[x:] | |
13101 | + | |
13102 | + def invoke (self, arg, from_tty): | |
13103 | + i = 0 | |
13104 | + count = 0 | |
13105 | + filter = True | |
13106 | + full = False | |
13107 | + | |
13108 | + for word in arg.split (" "): | |
13109 | + if word == '': | |
13110 | + continue | |
13111 | + elif word == 'raw': | |
13112 | + filter = False | |
13113 | + elif word == 'full': | |
13114 | + full = True | |
13115 | + else: | |
13116 | + count = int (word) | |
13117 | + | |
13118 | + # FIXME: provide option to start at selected frame | |
13119 | + # However, should still number as if starting from newest | |
7566401a | 13120 | + newest_frame = gdb.selected_thread ().newest_frame () |
3a58abaf | 13121 | + iter = itertools.imap (FrameWrapper, |
7566401a | 13122 | + FrameIterator (newest_frame)) |
3a58abaf AM |
13123 | + if filter: |
13124 | + iter = gdb.backtrace.create_frame_filter (iter) | |
13125 | + | |
13126 | + # Now wrap in an iterator that numbers the frames. | |
13127 | + iter = itertools.izip (itertools.count (0), iter) | |
13128 | + | |
13129 | + # Reverse if the user wanted that. | |
13130 | + if self.reverse.value: | |
13131 | + iter = self.reverse_iter (iter) | |
13132 | + | |
13133 | + # Extract sub-range user wants. | |
13134 | + if count < 0: | |
13135 | + iter = self.final_n (iter, count) | |
13136 | + elif count > 0: | |
13137 | + iter = itertools.islice (iter, 0, count) | |
13138 | + | |
13139 | + for pair in iter: | |
13140 | + sys.stdout.write ("#%-2d" % pair[0]) | |
13141 | + pair[1].describe (sys.stdout, full) | |
13142 | + | |
13143 | +FilteringBacktrace() | |
13144 | diff --git a/gdb/python/lib/gdb/command/ignore_errors.py b/gdb/python/lib/gdb/command/ignore_errors.py | |
13145 | new file mode 100644 | |
13146 | index 0000000..6fa48ff | |
13147 | --- /dev/null | |
13148 | +++ b/gdb/python/lib/gdb/command/ignore_errors.py | |
13149 | @@ -0,0 +1,37 @@ | |
13150 | +# Ignore errors in user commands. | |
13151 | + | |
13152 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
13153 | + | |
13154 | +# This program is free software; you can redistribute it and/or modify | |
13155 | +# it under the terms of the GNU General Public License as published by | |
13156 | +# the Free Software Foundation; either version 3 of the License, or | |
13157 | +# (at your option) any later version. | |
13158 | +# | |
13159 | +# This program is distributed in the hope that it will be useful, | |
13160 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13161 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13162 | +# GNU General Public License for more details. | |
13163 | +# | |
13164 | +# You should have received a copy of the GNU General Public License | |
13165 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13166 | + | |
13167 | +import gdb | |
13168 | + | |
13169 | +class IgnoreErrorsCommand (gdb.Command): | |
13170 | + """Execute a single command, ignoring all errors. | |
13171 | +Only one-line commands are supported. | |
13172 | +This is primarily useful in scripts.""" | |
13173 | + | |
13174 | + def __init__ (self): | |
13175 | + super (IgnoreErrorsCommand, self).__init__ ("ignore-errors", | |
13176 | + gdb.COMMAND_OBSCURE, | |
13177 | + # FIXME... | |
13178 | + gdb.COMPLETE_COMMAND) | |
13179 | + | |
13180 | + def invoke (self, arg, from_tty): | |
13181 | + try: | |
13182 | + gdb.execute (arg, from_tty) | |
13183 | + except: | |
13184 | + pass | |
13185 | + | |
13186 | +IgnoreErrorsCommand () | |
13187 | diff --git a/gdb/python/lib/gdb/command/pahole.py b/gdb/python/lib/gdb/command/pahole.py | |
13188 | new file mode 100644 | |
7566401a | 13189 | index 0000000..21a0bf0 |
3a58abaf AM |
13190 | --- /dev/null |
13191 | +++ b/gdb/python/lib/gdb/command/pahole.py | |
7566401a | 13192 | @@ -0,0 +1,75 @@ |
3a58abaf AM |
13193 | +# pahole command for gdb |
13194 | + | |
7566401a | 13195 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. |
3a58abaf AM |
13196 | + |
13197 | +# This program is free software; you can redistribute it and/or modify | |
13198 | +# it under the terms of the GNU General Public License as published by | |
13199 | +# the Free Software Foundation; either version 3 of the License, or | |
13200 | +# (at your option) any later version. | |
13201 | +# | |
13202 | +# This program is distributed in the hope that it will be useful, | |
13203 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13204 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13205 | +# GNU General Public License for more details. | |
13206 | +# | |
13207 | +# You should have received a copy of the GNU General Public License | |
13208 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13209 | + | |
13210 | +import gdb | |
13211 | + | |
13212 | +class Pahole (gdb.Command): | |
13213 | + """Show the holes in a structure. | |
13214 | +This command takes a single argument, a type name. | |
13215 | +It prints the type and displays comments showing where holes are.""" | |
13216 | + | |
13217 | + def __init__ (self): | |
13218 | + super (Pahole, self).__init__ ("pahole", gdb.COMMAND_NONE, | |
13219 | + gdb.COMPLETE_SYMBOL) | |
13220 | + | |
3a58abaf AM |
13221 | + def pahole (self, type, level, name): |
13222 | + if name is None: | |
13223 | + name = '' | |
7566401a | 13224 | + tag = type.tag |
3a58abaf AM |
13225 | + if tag is None: |
13226 | + tag = '' | |
13227 | + print '%sstruct %s {' % (' ' * (2 * level), tag) | |
13228 | + bitpos = 0 | |
13229 | + for field in type.fields (): | |
13230 | + # Skip static fields. | |
13231 | + if not hasattr (field, ('bitpos')): | |
13232 | + continue | |
13233 | + | |
7566401a | 13234 | + ftype = field.type.strip_typedefs() |
3a58abaf AM |
13235 | + |
13236 | + if bitpos != field.bitpos: | |
13237 | + hole = field.bitpos - bitpos | |
13238 | + print ' /* XXX %d bit hole, try to pack */' % hole | |
13239 | + bitpos = field.bitpos | |
13240 | + if field.bitsize > 0: | |
13241 | + fieldsize = field.bitsize | |
13242 | + else: | |
13243 | + # TARGET_CHAR_BIT here... | |
7566401a | 13244 | + fieldsize = 8 * ftype.sizeof |
3a58abaf AM |
13245 | + |
13246 | + # TARGET_CHAR_BIT | |
13247 | + print ' /* %3d %3d */' % (int (bitpos / 8), int (fieldsize / 8)), | |
13248 | + bitpos = bitpos + fieldsize | |
13249 | + | |
7566401a | 13250 | + if ftype.code == gdb.TYPE_CODE_STRUCT: |
3a58abaf AM |
13251 | + self.pahole (ftype, level + 1, field.name) |
13252 | + else: | |
13253 | + print ' ' * (2 + 2 * level), | |
13254 | + print '%s %s' % (str (ftype), field.name) | |
13255 | + | |
13256 | + print ' ' * (14 + 2 * level), | |
13257 | + print '} %s' % name | |
13258 | + | |
13259 | + def invoke (self, arg, from_tty): | |
7566401a ER |
13260 | + type = gdb.lookup_type (arg) |
13261 | + type = type.strip_typedefs () | |
13262 | + if type.code != gdb.TYPE_CODE_STRUCT: | |
3a58abaf AM |
13263 | + raise TypeError, '%s is not a struct type' % arg |
13264 | + print ' ' * 14, | |
13265 | + self.pahole (type, 0, '') | |
13266 | + | |
13267 | +Pahole() | |
13268 | diff --git a/gdb/python/lib/gdb/command/require.py b/gdb/python/lib/gdb/command/require.py | |
13269 | new file mode 100644 | |
13270 | index 0000000..1fbc1e8 | |
13271 | --- /dev/null | |
13272 | +++ b/gdb/python/lib/gdb/command/require.py | |
13273 | @@ -0,0 +1,57 @@ | |
13274 | +# Demand-loading commands. | |
13275 | + | |
13276 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
13277 | + | |
13278 | +# This program is free software; you can redistribute it and/or modify | |
13279 | +# it under the terms of the GNU General Public License as published by | |
13280 | +# the Free Software Foundation; either version 3 of the License, or | |
13281 | +# (at your option) any later version. | |
13282 | +# | |
13283 | +# This program is distributed in the hope that it will be useful, | |
13284 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13285 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13286 | +# GNU General Public License for more details. | |
13287 | +# | |
13288 | +# You should have received a copy of the GNU General Public License | |
13289 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13290 | + | |
13291 | +import gdb | |
13292 | +import os | |
13293 | + | |
13294 | +class RequireCommand (gdb.Command): | |
13295 | + """Prefix command for requiring features.""" | |
13296 | + | |
13297 | + def __init__ (self): | |
13298 | + super (RequireCommand, self).__init__ ("require", | |
13299 | + gdb.COMMAND_SUPPORT, | |
13300 | + gdb.COMPLETE_NONE, | |
13301 | + True) | |
13302 | + | |
13303 | +class RequireSubcommand (gdb.Command): | |
13304 | + """Demand-load a command by name.""" | |
13305 | + | |
13306 | + def __init__ (self, name): | |
13307 | + self.__doc__ = "Demand-load a %s by name." % name | |
13308 | + super (RequireSubcommand, self).__init__ ("require %s" % name, | |
13309 | + gdb.COMMAND_SUPPORT) | |
13310 | + self.name = name | |
13311 | + | |
13312 | + def invoke (self, arg, from_tty): | |
13313 | + for cmd in arg.split(): | |
13314 | + exec ('import gdb.' + self.name + '.' + cmd, globals ()) | |
13315 | + | |
13316 | + def complete (self, text, word): | |
13317 | + dir = gdb.pythondir + '/gdb/' + self.name | |
13318 | + result = [] | |
13319 | + for file in os.listdir(dir): | |
13320 | + if not file.startswith (word) or not file.endswith ('.py'): | |
13321 | + continue | |
13322 | + feature = file[0:-3] | |
13323 | + if feature == 'require' or feature == '__init__': | |
13324 | + continue | |
13325 | + result.append (feature) | |
13326 | + return result | |
13327 | + | |
13328 | +RequireCommand() | |
13329 | +RequireSubcommand("command") | |
13330 | +RequireSubcommand("function") | |
13331 | diff --git a/gdb/python/lib/gdb/command/save_breakpoints.py b/gdb/python/lib/gdb/command/save_breakpoints.py | |
13332 | new file mode 100644 | |
7566401a | 13333 | index 0000000..6143187 |
3a58abaf AM |
13334 | --- /dev/null |
13335 | +++ b/gdb/python/lib/gdb/command/save_breakpoints.py | |
13336 | @@ -0,0 +1,65 @@ | |
13337 | +# Save breakpoints. | |
13338 | + | |
13339 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
13340 | + | |
13341 | +# This program is free software; you can redistribute it and/or modify | |
13342 | +# it under the terms of the GNU General Public License as published by | |
13343 | +# the Free Software Foundation; either version 3 of the License, or | |
13344 | +# (at your option) any later version. | |
13345 | +# | |
13346 | +# This program is distributed in the hope that it will be useful, | |
13347 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13348 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13349 | +# GNU General Public License for more details. | |
13350 | +# | |
13351 | +# You should have received a copy of the GNU General Public License | |
13352 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13353 | + | |
13354 | +from __future__ import with_statement | |
13355 | +import gdb | |
13356 | + | |
13357 | +class SavePrefixCommand (gdb.Command): | |
13358 | + "Prefix command for saving things." | |
13359 | + | |
13360 | + def __init__ (self): | |
13361 | + super (SavePrefixCommand, self).__init__ ("save", | |
13362 | + gdb.COMMAND_SUPPORT, | |
13363 | + gdb.COMPLETE_NONE, True) | |
13364 | + | |
13365 | +class SaveBreakpointsCommand (gdb.Command): | |
13366 | + """Save the current breakpoints to a file. | |
13367 | +This command takes a single argument, a file name. | |
13368 | +The breakpoints can be restored using the 'source' command.""" | |
13369 | + | |
13370 | + def __init__ (self): | |
13371 | + super (SaveBreakpointsCommand, self).__init__ ("save breakpoints", | |
13372 | + gdb.COMMAND_SUPPORT, | |
13373 | + gdb.COMPLETE_FILENAME) | |
13374 | + | |
13375 | + def invoke (self, arg, from_tty): | |
13376 | + self.dont_repeat () | |
13377 | + bps = gdb.breakpoints () | |
13378 | + if bps is None: | |
13379 | + raise RuntimeError, 'No breakpoints to save' | |
13380 | + with open (arg.strip (), 'w') as f: | |
13381 | + for bp in bps: | |
13382 | + print >> f, "break", bp.location, | |
13383 | + if bp.thread is not None: | |
13384 | + print >> f, " thread", bp.thread, | |
13385 | + if bp.condition is not None: | |
13386 | + print >> f, " if", bp.condition, | |
13387 | + print >> f | |
13388 | + if not bp.enabled: | |
7566401a | 13389 | + print >> f, "disable $bpnum" |
3a58abaf AM |
13390 | + # Note: we don't save the ignore count; there doesn't |
13391 | + # seem to be much point. | |
13392 | + commands = bp.commands | |
13393 | + if commands is not None: | |
13394 | + print >> f, "commands" | |
13395 | + # Note that COMMANDS has a trailing newline. | |
13396 | + print >> f, commands, | |
13397 | + print >> f, "end" | |
13398 | + print >> f | |
13399 | + | |
13400 | +SavePrefixCommand () | |
13401 | +SaveBreakpointsCommand () | |
7566401a ER |
13402 | diff --git a/gdb/python/lib/gdb/command/upto.py b/gdb/python/lib/gdb/command/upto.py |
13403 | new file mode 100644 | |
13404 | index 0000000..faf54ed | |
13405 | --- /dev/null | |
13406 | +++ b/gdb/python/lib/gdb/command/upto.py | |
13407 | @@ -0,0 +1,129 @@ | |
13408 | +# upto command. | |
13409 | + | |
13410 | +# Copyright (C) 2009 Free Software Foundation, Inc. | |
13411 | + | |
13412 | +# This program is free software; you can redistribute it and/or modify | |
13413 | +# it under the terms of the GNU General Public License as published by | |
13414 | +# the Free Software Foundation; either version 3 of the License, or | |
13415 | +# (at your option) any later version. | |
13416 | +# | |
13417 | +# This program is distributed in the hope that it will be useful, | |
13418 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13419 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13420 | +# GNU General Public License for more details. | |
13421 | +# | |
13422 | +# You should have received a copy of the GNU General Public License | |
13423 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13424 | + | |
13425 | +import gdb | |
13426 | +import re | |
13427 | +from gdb.FrameIterator import FrameIterator | |
13428 | +from gdb.FrameWrapper import FrameWrapper | |
13429 | + | |
13430 | +class UptoPrefix (gdb.Command): | |
13431 | + def __init__ (self): | |
13432 | + super (UptoPrefix, self).__init__ ("upto", gdb.COMMAND_STACK, | |
13433 | + prefix = True) | |
13434 | + | |
13435 | +class UptoImplementation (gdb.Command): | |
13436 | + def __init__ (self, subcommand): | |
13437 | + super (UptoImplementation, self).__init__ ("upto " + subcommand, | |
13438 | + gdb.COMMAND_STACK) | |
13439 | + | |
13440 | + def search (self): | |
13441 | + saved = gdb.selected_frame () | |
13442 | + iter = FrameIterator (saved) | |
13443 | + found = False | |
13444 | + try: | |
13445 | + for frame in iter: | |
13446 | + frame.select () | |
13447 | + try: | |
13448 | + if self.filter (frame): | |
13449 | + wrapper = FrameWrapper (frame) | |
13450 | + wrapper.describe (sys.stdout, False) | |
13451 | + return | |
13452 | + except: | |
13453 | + pass | |
13454 | + except: | |
13455 | + pass | |
13456 | + saved.select () | |
13457 | + raise RuntimeError, 'Could not find a matching frame' | |
13458 | + | |
13459 | + def invoke (self, arg, from_tty): | |
13460 | + self.rx = re.compile (arg) | |
13461 | + self.search () | |
13462 | + | |
13463 | +class UptoSymbolCommand (UptoImplementation): | |
13464 | + """Select and print some calling stack frame, based on symbol. | |
13465 | +The argument is a regular expression. This command moves up the | |
13466 | +stack, stopping at the first frame whose symbol matches the regular | |
13467 | +expression.""" | |
13468 | + | |
13469 | + def __init__ (self): | |
13470 | + super (UptoSymbolCommand, self).__init__ ("symbol") | |
13471 | + | |
13472 | + def filter (self, frame): | |
13473 | + name = frame.name () | |
13474 | + if name is not None: | |
13475 | + if self.rx.search (name) is not None: | |
13476 | + return True | |
13477 | + return False | |
13478 | + | |
13479 | +class UptoSourceCommand (UptoImplementation): | |
13480 | + """Select and print some calling stack frame, based on source file. | |
13481 | +The argument is a regular expression. This command moves up the | |
13482 | +stack, stopping at the first frame whose source file name matches the | |
13483 | +regular expression.""" | |
13484 | + | |
13485 | + def __init__ (self): | |
13486 | + super (UptoSourceCommand, self).__init__ ("source") | |
13487 | + | |
13488 | + def filter (self, frame): | |
13489 | + name = frame.find_sal ().symtab.filename | |
13490 | + if name is not None: | |
13491 | + if self.rx.search (name) is not None: | |
13492 | + return True | |
13493 | + return False | |
13494 | + | |
13495 | +class UptoObjectCommand (UptoImplementation): | |
13496 | + """Select and print some calling stack frame, based on object file. | |
13497 | +The argument is a regular expression. This command moves up the | |
13498 | +stack, stopping at the first frame whose object file name matches the | |
13499 | +regular expression.""" | |
13500 | + | |
13501 | + def __init__ (self): | |
13502 | + super (UptoObjectCommand, self).__init__ ("object") | |
13503 | + | |
13504 | + def filter (self, frame): | |
13505 | + name = frame.find_sal ().symtab.objfile.filename | |
13506 | + if name is not None: | |
13507 | + if self.rx.search (name) is not None: | |
13508 | + return True | |
13509 | + return False | |
13510 | + | |
13511 | +class UptoWhereCommand (UptoImplementation): | |
13512 | + """Select and print some calling stack frame, based on expression. | |
13513 | +The argument is an expression. This command moves up the stack, | |
13514 | +parsing and evaluating the expression in each frame. This stops when | |
13515 | +the expression evaluates to a non-zero (true) value.""" | |
13516 | + | |
13517 | + def __init__ (self): | |
13518 | + super (UptoWhereCommand, self).__init__ ("where") | |
13519 | + | |
13520 | + def filter (self, frame): | |
13521 | + try: | |
13522 | + if gdb.parse_and_eval (self.expression): | |
13523 | + return True | |
13524 | + except: | |
13525 | + pass | |
13526 | + return False | |
13527 | + | |
13528 | + def invoke (self, arg, from_tty): | |
13529 | + self.expression = arg | |
13530 | + self.search () | |
13531 | + | |
13532 | +UptoPrefix () | |
13533 | +UptoSymbolCommand () | |
13534 | +UptoSourceCommand () | |
13535 | +UptoObjectCommand () | |
13536 | +UptoWhereCommand () | |
3a58abaf AM |
13537 | diff --git a/gdb/python/lib/gdb/function/__init__.py b/gdb/python/lib/gdb/function/__init__.py |
13538 | new file mode 100644 | |
13539 | index 0000000..8b13789 | |
13540 | --- /dev/null | |
13541 | +++ b/gdb/python/lib/gdb/function/__init__.py | |
13542 | @@ -0,0 +1 @@ | |
13543 | + | |
13544 | diff --git a/gdb/python/lib/gdb/function/caller_is.py b/gdb/python/lib/gdb/function/caller_is.py | |
13545 | new file mode 100644 | |
13546 | index 0000000..2b9c5c7 | |
13547 | --- /dev/null | |
13548 | +++ b/gdb/python/lib/gdb/function/caller_is.py | |
13549 | @@ -0,0 +1,58 @@ | |
13550 | +# Caller-is functions. | |
13551 | + | |
13552 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
13553 | + | |
13554 | +# This program is free software; you can redistribute it and/or modify | |
13555 | +# it under the terms of the GNU General Public License as published by | |
13556 | +# the Free Software Foundation; either version 3 of the License, or | |
13557 | +# (at your option) any later version. | |
13558 | +# | |
13559 | +# This program is distributed in the hope that it will be useful, | |
13560 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13561 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13562 | +# GNU General Public License for more details. | |
13563 | +# | |
13564 | +# You should have received a copy of the GNU General Public License | |
13565 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13566 | + | |
13567 | +import gdb | |
13568 | +import re | |
13569 | + | |
13570 | +class CallerIs (gdb.Function): | |
13571 | + """Return True if the calling function's name is equal to a string. | |
13572 | +This function takes one or two arguments. | |
13573 | +The first argument is the name of a function; if the calling function's | |
13574 | +name is equal to this argument, this function returns True. | |
13575 | +The optional second argument tells this function how many stack frames | |
13576 | +to traverse to find the calling function. The default is 1.""" | |
13577 | + | |
13578 | + def __init__ (self): | |
13579 | + super (CallerIs, self).__init__ ("caller_is") | |
13580 | + | |
13581 | + def invoke (self, name, nframes = 1): | |
13582 | + frame = gdb.selected_frame () | |
13583 | + while nframes > 0: | |
13584 | + frame = frame.older () | |
13585 | + nframes = nframes - 1 | |
13586 | + return frame.name () == name.string () | |
13587 | + | |
13588 | +class CallerMatches (gdb.Function): | |
13589 | + """Return True if the calling function's name matches a string. | |
13590 | +This function takes one or two arguments. | |
13591 | +The first argument is a regular expression; if the calling function's | |
13592 | +name is matched by this argument, this function returns True. | |
13593 | +The optional second argument tells this function how many stack frames | |
13594 | +to traverse to find the calling function. The default is 1.""" | |
13595 | + | |
13596 | + def __init__ (self): | |
13597 | + super (CallerMatches, self).__init__ ("caller_matches") | |
13598 | + | |
13599 | + def invoke (self, name, nframes = 1): | |
13600 | + frame = gdb.selected_frame () | |
13601 | + while nframes > 0: | |
13602 | + frame = frame.older () | |
13603 | + nframes = nframes - 1 | |
13604 | + return re.match (name.string (), frame.name ()) is not None | |
13605 | + | |
13606 | +CallerIs() | |
13607 | +CallerMatches() | |
13608 | diff --git a/gdb/python/lib/gdb/function/in_scope.py b/gdb/python/lib/gdb/function/in_scope.py | |
13609 | new file mode 100644 | |
13610 | index 0000000..debb3bb | |
13611 | --- /dev/null | |
13612 | +++ b/gdb/python/lib/gdb/function/in_scope.py | |
13613 | @@ -0,0 +1,47 @@ | |
13614 | +# In-scope function. | |
13615 | + | |
13616 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
13617 | + | |
13618 | +# This program is free software; you can redistribute it and/or modify | |
13619 | +# it under the terms of the GNU General Public License as published by | |
13620 | +# the Free Software Foundation; either version 3 of the License, or | |
13621 | +# (at your option) any later version. | |
13622 | +# | |
13623 | +# This program is distributed in the hope that it will be useful, | |
13624 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13625 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13626 | +# GNU General Public License for more details. | |
13627 | +# | |
13628 | +# You should have received a copy of the GNU General Public License | |
13629 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
13630 | + | |
13631 | +import gdb | |
13632 | + | |
13633 | +class InScope (gdb.Function): | |
13634 | + """Return True if all the given variables or macros are in scope. | |
13635 | +Takes one argument for each variable name to be checked.""" | |
13636 | + | |
13637 | + def __init__ (self): | |
13638 | + super (InScope, self).__init__ ("in_scope") | |
13639 | + | |
13640 | + def invoke (self, *vars): | |
13641 | + if len (vars) == 0: | |
13642 | + raise TypeError, "in_scope takes at least one argument" | |
13643 | + | |
13644 | + # gdb.Value isn't hashable so it can't be put in a map. | |
13645 | + # Convert to string first. | |
13646 | + wanted = set (map (lambda x: x.string (), vars)) | |
13647 | + found = set () | |
13648 | + block = gdb.selected_frame ().block () | |
13649 | + while block: | |
13650 | + for sym in block: | |
13651 | + if (sym.is_argument or sym.is_constant | |
13652 | + or sym.is_function or sym.is_variable): | |
13653 | + if sym.name in wanted: | |
13654 | + found.add (sym.name) | |
13655 | + | |
13656 | + block = block.superblock | |
13657 | + | |
13658 | + return wanted == found | |
13659 | + | |
13660 | +InScope () | |
7566401a | 13661 | diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c |
3a58abaf AM |
13662 | new file mode 100644 |
13663 | index 0000000..8019e9d | |
13664 | --- /dev/null | |
7566401a | 13665 | +++ b/gdb/python/py-block.c |
3a58abaf AM |
13666 | @@ -0,0 +1,265 @@ |
13667 | +/* Python interface to blocks. | |
13668 | + | |
13669 | + Copyright (C) 2008 Free Software Foundation, Inc. | |
13670 | + | |
13671 | + This file is part of GDB. | |
13672 | + | |
13673 | + This program is free software; you can redistribute it and/or modify | |
13674 | + it under the terms of the GNU General Public License as published by | |
13675 | + the Free Software Foundation; either version 3 of the License, or | |
13676 | + (at your option) any later version. | |
13677 | + | |
13678 | + This program is distributed in the hope that it will be useful, | |
13679 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13680 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13681 | + GNU General Public License for more details. | |
13682 | + | |
13683 | + You should have received a copy of the GNU General Public License | |
13684 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
13685 | + | |
13686 | +#include "defs.h" | |
13687 | +#include "block.h" | |
13688 | +#include "dictionary.h" | |
13689 | +#include "symtab.h" | |
13690 | +#include "python-internal.h" | |
13691 | + | |
13692 | +typedef struct { | |
13693 | + PyObject_HEAD | |
13694 | + struct block *block; | |
13695 | +} block_object; | |
13696 | + | |
13697 | +typedef struct { | |
13698 | + PyObject_HEAD | |
13699 | + struct dictionary *dict; | |
13700 | + struct dict_iterator iter; | |
13701 | + int initialized_p; | |
13702 | +} block_syms_iterator_object; | |
13703 | + | |
13704 | +static PyTypeObject block_syms_iterator_object_type; | |
13705 | + | |
13706 | +static PyObject * | |
13707 | +blpy_iter (PyObject *self) | |
13708 | +{ | |
13709 | + block_syms_iterator_object *block_iter_obj; | |
13710 | + | |
13711 | + block_iter_obj = PyObject_New (block_syms_iterator_object, | |
13712 | + &block_syms_iterator_object_type); | |
13713 | + if (block_iter_obj == NULL) | |
13714 | + { | |
13715 | + PyErr_SetString (PyExc_MemoryError, | |
13716 | + "Could not allocate iterator object."); | |
13717 | + return NULL; | |
13718 | + } | |
13719 | + | |
13720 | + block_iter_obj->dict = BLOCK_DICT (((block_object *) self)->block); | |
13721 | + block_iter_obj->initialized_p = 0; | |
13722 | + | |
13723 | + return (PyObject *) block_iter_obj; | |
13724 | +} | |
13725 | + | |
13726 | +static PyObject * | |
13727 | +blpy_get_start (PyObject *self, void *closure) | |
13728 | +{ | |
13729 | + block_object *self_block = (block_object *) self; | |
13730 | + | |
13731 | + return PyLong_FromUnsignedLongLong (BLOCK_START (self_block->block)); | |
13732 | +} | |
13733 | + | |
13734 | +static PyObject * | |
13735 | +blpy_get_end (PyObject *self, void *closure) | |
13736 | +{ | |
13737 | + block_object *self_block = (block_object *) self; | |
13738 | + | |
13739 | + return PyLong_FromUnsignedLongLong (BLOCK_END (self_block->block)); | |
13740 | +} | |
13741 | + | |
13742 | +static PyObject * | |
13743 | +blpy_get_function (PyObject *self, void *closure) | |
13744 | +{ | |
13745 | + block_object *self_block = (block_object *) self; | |
13746 | + struct symbol *sym; | |
13747 | + | |
13748 | + sym = BLOCK_FUNCTION (self_block->block); | |
13749 | + if (sym) | |
13750 | + return symbol_to_symbol_object (sym); | |
13751 | + | |
13752 | + Py_RETURN_NONE; | |
13753 | +} | |
13754 | + | |
13755 | +static PyObject * | |
13756 | +blpy_get_superblock (PyObject *self, void *closure) | |
13757 | +{ | |
13758 | + block_object *self_block = (block_object *) self; | |
13759 | + struct block *block; | |
13760 | + | |
13761 | + block = BLOCK_SUPERBLOCK (self_block->block); | |
13762 | + if (block) | |
13763 | + return block_to_block_object (block); | |
13764 | + | |
13765 | + Py_RETURN_NONE; | |
13766 | +} | |
13767 | + | |
13768 | +PyObject * | |
13769 | +block_to_block_object (struct block *block) | |
13770 | +{ | |
13771 | + block_object *block_obj; | |
13772 | + | |
13773 | + block_obj = PyObject_New (block_object, &block_object_type); | |
13774 | + if (block_obj == NULL) | |
13775 | + { | |
13776 | + PyErr_SetString (PyExc_MemoryError, "Could not allocate block object."); | |
13777 | + return NULL; | |
13778 | + } | |
13779 | + | |
13780 | + block_obj->block = block; | |
13781 | + | |
13782 | + return (PyObject *) block_obj; | |
13783 | +} | |
13784 | + | |
13785 | +struct block * | |
13786 | +block_object_to_block (PyObject *obj) | |
13787 | +{ | |
13788 | + if (! PyObject_TypeCheck (obj, &block_object_type)) | |
13789 | + return NULL; | |
13790 | + return ((block_object *) obj)->block; | |
13791 | +} | |
13792 | + | |
13793 | +static PyObject * | |
13794 | +blpy_block_syms_iter (PyObject *self) | |
13795 | +{ | |
13796 | + return self; | |
13797 | +} | |
13798 | + | |
13799 | +static PyObject * | |
13800 | +blpy_block_syms_iternext (PyObject *self) | |
13801 | +{ | |
13802 | + block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self; | |
13803 | + struct symbol *sym; | |
13804 | + | |
13805 | + if (!iter_obj->initialized_p) | |
13806 | + { | |
13807 | + sym = dict_iterator_first (iter_obj->dict, &(iter_obj->iter)); | |
13808 | + iter_obj->initialized_p = 1; | |
13809 | + } | |
13810 | + else | |
13811 | + sym = dict_iterator_next (&(iter_obj->iter)); | |
13812 | + | |
13813 | + return (sym == NULL)? NULL : symbol_to_symbol_object (sym); | |
13814 | +} | |
13815 | + | |
13816 | +/* Return the innermost lexical block containing the specified pc value, | |
13817 | + or 0 if there is none. */ | |
13818 | + | |
13819 | +PyObject * | |
13820 | +gdbpy_block_for_pc (PyObject *self, PyObject *args) | |
13821 | +{ | |
13822 | + unsigned PY_LONG_LONG pc; | |
13823 | + struct block *block; | |
13824 | + PyObject *sym_obj; | |
13825 | + | |
13826 | + if (!PyArg_ParseTuple (args, "K", &pc)) | |
13827 | + return NULL; | |
13828 | + | |
13829 | + block = block_for_pc (pc); | |
13830 | + if (block) | |
13831 | + return block_to_block_object (block); | |
13832 | + | |
13833 | + Py_RETURN_NONE; | |
13834 | +} | |
13835 | + | |
13836 | +void | |
13837 | +gdbpy_initialize_blocks (void) | |
13838 | +{ | |
13839 | + block_object_type.tp_new = PyType_GenericNew; | |
13840 | + if (PyType_Ready (&block_object_type) < 0) | |
13841 | + return; | |
13842 | + | |
13843 | + block_syms_iterator_object_type.tp_new = PyType_GenericNew; | |
13844 | + if (PyType_Ready (&block_syms_iterator_object_type) < 0) | |
13845 | + return; | |
13846 | + | |
13847 | + Py_INCREF (&block_object_type); | |
13848 | + PyModule_AddObject (gdb_module, "Block", (PyObject *) &block_object_type); | |
13849 | + | |
13850 | + Py_INCREF (&block_syms_iterator_object_type); | |
13851 | + PyModule_AddObject (gdb_module, "BlockIterator", | |
13852 | + (PyObject *) &block_syms_iterator_object_type); | |
13853 | +} | |
13854 | + | |
13855 | +\f | |
13856 | + | |
13857 | +static PyGetSetDef block_object_getset[] = { | |
13858 | + { "start", blpy_get_start, NULL, "Start address of the block.", NULL }, | |
13859 | + { "end", blpy_get_end, NULL, "End address of the block.", NULL }, | |
13860 | + { "function", blpy_get_function, NULL, | |
13861 | + "Symbol that names the block, or None.", NULL }, | |
13862 | + { "superblock", blpy_get_superblock, NULL, | |
13863 | + "Block containing the block, or None.", NULL }, | |
13864 | + { NULL } /* Sentinel */ | |
13865 | +}; | |
13866 | + | |
13867 | +PyTypeObject block_object_type = { | |
13868 | + PyObject_HEAD_INIT (NULL) | |
13869 | + 0, /*ob_size*/ | |
13870 | + "gdb.Block", /*tp_name*/ | |
13871 | + sizeof (block_object), /*tp_basicsize*/ | |
13872 | + 0, /*tp_itemsize*/ | |
13873 | + 0, /*tp_dealloc*/ | |
13874 | + 0, /*tp_print*/ | |
13875 | + 0, /*tp_getattr*/ | |
13876 | + 0, /*tp_setattr*/ | |
13877 | + 0, /*tp_compare*/ | |
13878 | + 0, /*tp_repr*/ | |
13879 | + 0, /*tp_as_number*/ | |
13880 | + 0, /*tp_as_sequence*/ | |
13881 | + 0, /*tp_as_mapping*/ | |
13882 | + 0, /*tp_hash */ | |
13883 | + 0, /*tp_call*/ | |
13884 | + 0, /*tp_str*/ | |
13885 | + 0, /*tp_getattro*/ | |
13886 | + 0, /*tp_setattro*/ | |
13887 | + 0, /*tp_as_buffer*/ | |
13888 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ | |
13889 | + "GDB block object", /* tp_doc */ | |
13890 | + 0, /* tp_traverse */ | |
13891 | + 0, /* tp_clear */ | |
13892 | + 0, /* tp_richcompare */ | |
13893 | + 0, /* tp_weaklistoffset */ | |
13894 | + blpy_iter, /* tp_iter */ | |
13895 | + 0, /* tp_iternext */ | |
13896 | + 0, /* tp_methods */ | |
13897 | + 0, /* tp_members */ | |
13898 | + block_object_getset /* tp_getset */ | |
13899 | +}; | |
13900 | + | |
13901 | +static PyTypeObject block_syms_iterator_object_type = { | |
13902 | + PyObject_HEAD_INIT (NULL) | |
13903 | + 0, /*ob_size*/ | |
13904 | + "gdb.BlockIterator", /*tp_name*/ | |
13905 | + sizeof (block_syms_iterator_object), /*tp_basicsize*/ | |
13906 | + 0, /*tp_itemsize*/ | |
13907 | + 0, /*tp_dealloc*/ | |
13908 | + 0, /*tp_print*/ | |
13909 | + 0, /*tp_getattr*/ | |
13910 | + 0, /*tp_setattr*/ | |
13911 | + 0, /*tp_compare*/ | |
13912 | + 0, /*tp_repr*/ | |
13913 | + 0, /*tp_as_number*/ | |
13914 | + 0, /*tp_as_sequence*/ | |
13915 | + 0, /*tp_as_mapping*/ | |
13916 | + 0, /*tp_hash */ | |
13917 | + 0, /*tp_call*/ | |
13918 | + 0, /*tp_str*/ | |
13919 | + 0, /*tp_getattro*/ | |
13920 | + 0, /*tp_setattro*/ | |
13921 | + 0, /*tp_as_buffer*/ | |
13922 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ | |
13923 | + "GDB block syms iterator object", /* tp_doc */ | |
13924 | + 0, /* tp_traverse */ | |
13925 | + 0, /* tp_clear */ | |
13926 | + 0, /* tp_richcompare */ | |
13927 | + 0, /* tp_weaklistoffset */ | |
13928 | + blpy_block_syms_iter, /* tp_iter */ | |
13929 | + blpy_block_syms_iternext, /* tp_iternext */ | |
13930 | + 0 /* tp_methods */ | |
13931 | +}; | |
7566401a | 13932 | diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c |
3a58abaf | 13933 | new file mode 100644 |
7566401a | 13934 | index 0000000..afa9526 |
3a58abaf | 13935 | --- /dev/null |
7566401a | 13936 | +++ b/gdb/python/py-breakpoint.c |
3a58abaf AM |
13937 | @@ -0,0 +1,665 @@ |
13938 | +/* Python interface to breakpoints | |
13939 | + | |
13940 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
13941 | + | |
13942 | + This file is part of GDB. | |
13943 | + | |
13944 | + This program is free software; you can redistribute it and/or modify | |
13945 | + it under the terms of the GNU General Public License as published by | |
13946 | + the Free Software Foundation; either version 3 of the License, or | |
13947 | + (at your option) any later version. | |
13948 | + | |
13949 | + This program is distributed in the hope that it will be useful, | |
13950 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13951 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13952 | + GNU General Public License for more details. | |
13953 | + | |
13954 | + You should have received a copy of the GNU General Public License | |
13955 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
13956 | + | |
13957 | +#include "defs.h" | |
13958 | +#include "value.h" | |
13959 | +#include "exceptions.h" | |
13960 | +#include "python-internal.h" | |
13961 | +#include "charset.h" | |
13962 | +#include "breakpoint.h" | |
13963 | +#include "gdbcmd.h" | |
13964 | +#include "gdbthread.h" | |
13965 | +#include "observer.h" | |
13966 | + | |
13967 | + | |
13968 | +/* From breakpoint.c. */ | |
13969 | +extern struct breakpoint *breakpoint_chain; | |
13970 | + | |
13971 | + | |
13972 | +typedef struct breakpoint_object breakpoint_object; | |
13973 | + | |
13974 | +static PyTypeObject breakpoint_object_type; | |
13975 | + | |
13976 | +/* A dynamically allocated vector of breakpoint objects. Each | |
13977 | + breakpoint has a number. A breakpoint is valid if its slot in this | |
13978 | + vector is non-null. When a breakpoint is deleted, we drop our | |
13979 | + reference to it and zero its slot; this is how we let the Python | |
13980 | + object have a lifetime which is independent from that of the gdb | |
13981 | + breakpoint. */ | |
13982 | +static breakpoint_object **bppy_breakpoints; | |
13983 | + | |
13984 | +/* Number of slots in bppy_breakpoints. */ | |
13985 | +static int bppy_slots; | |
13986 | + | |
13987 | +/* Number of live breakpoints. */ | |
13988 | +static int bppy_live; | |
13989 | + | |
13990 | +/* Variables used to pass information between the Breakpoint | |
13991 | + constructor and the breakpoint-created hook function. */ | |
13992 | +static breakpoint_object *bppy_pending_object; | |
13993 | + | |
13994 | +struct breakpoint_object | |
13995 | +{ | |
13996 | + PyObject_HEAD | |
13997 | + | |
13998 | + /* The breakpoint number according to gdb. */ | |
13999 | + int number; | |
14000 | + | |
14001 | + /* The gdb breakpoint object, or NULL if the breakpoint has been | |
14002 | + deleted. */ | |
14003 | + struct breakpoint *bp; | |
14004 | +}; | |
14005 | + | |
14006 | +/* Evaluate to true if the breakpoint NUM is valid, false otherwise. */ | |
14007 | +#define BPPY_VALID_P(Num) \ | |
14008 | + ((Num) >= 0 \ | |
14009 | + && (Num) < bppy_slots \ | |
14010 | + && bppy_breakpoints[Num] != NULL) | |
14011 | + | |
14012 | +/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python | |
14013 | + exception if it is invalid. */ | |
14014 | +#define BPPY_REQUIRE_VALID(Breakpoint) \ | |
14015 | + do { \ | |
14016 | + if (! BPPY_VALID_P ((Breakpoint)->number)) \ | |
14017 | + return PyErr_Format (PyExc_RuntimeError, "breakpoint %d is invalid", \ | |
14018 | + (Breakpoint)->number); \ | |
14019 | + } while (0) | |
14020 | + | |
14021 | +/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python | |
14022 | + exception if it is invalid. This macro is for use in setter functions. */ | |
14023 | +#define BPPY_SET_REQUIRE_VALID(Breakpoint) \ | |
14024 | + do { \ | |
14025 | + if (! BPPY_VALID_P ((Breakpoint)->number)) \ | |
14026 | + { \ | |
14027 | + PyErr_Format (PyExc_RuntimeError, "breakpoint %d is invalid", \ | |
14028 | + (Breakpoint)->number); \ | |
14029 | + return -1; \ | |
14030 | + } \ | |
14031 | + } while (0) | |
14032 | + | |
14033 | +/* Python function which checks the validity of a breakpoint object. */ | |
14034 | +static PyObject * | |
14035 | +bppy_is_valid (PyObject *self, PyObject *args) | |
14036 | +{ | |
14037 | + if (((breakpoint_object *) self)->bp) | |
14038 | + Py_RETURN_TRUE; | |
14039 | + Py_RETURN_FALSE; | |
14040 | +} | |
14041 | + | |
14042 | +/* Python function to test whether or not the breakpoint is enabled. */ | |
14043 | +static PyObject * | |
14044 | +bppy_get_enabled (PyObject *self, void *closure) | |
14045 | +{ | |
14046 | + if (! ((breakpoint_object *) self)->bp) | |
14047 | + Py_RETURN_FALSE; | |
14048 | + /* Not clear what we really want here. */ | |
14049 | + if (((breakpoint_object *) self)->bp->enable_state == bp_enabled) | |
14050 | + Py_RETURN_TRUE; | |
14051 | + Py_RETURN_FALSE; | |
14052 | +} | |
14053 | + | |
14054 | +/* Python function to test whether or not the breakpoint is silent. */ | |
14055 | +static PyObject * | |
14056 | +bppy_get_silent (PyObject *self, void *closure) | |
14057 | +{ | |
14058 | + BPPY_REQUIRE_VALID ((breakpoint_object *) self); | |
14059 | + if (((breakpoint_object *) self)->bp->silent) | |
14060 | + Py_RETURN_TRUE; | |
14061 | + Py_RETURN_FALSE; | |
14062 | +} | |
14063 | + | |
14064 | +/* Python function to set the enabled state of a breakpoint. */ | |
14065 | +static int | |
14066 | +bppy_set_enabled (PyObject *self, PyObject *newvalue, void *closure) | |
14067 | +{ | |
14068 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14069 | + int cmp; | |
14070 | + | |
14071 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
14072 | + | |
14073 | + if (newvalue == NULL) | |
14074 | + { | |
14075 | + PyErr_SetString (PyExc_TypeError, "cannot delete `enabled' attribute"); | |
14076 | + return -1; | |
14077 | + } | |
14078 | + else if (! PyBool_Check (newvalue)) | |
14079 | + { | |
14080 | + PyErr_SetString (PyExc_TypeError, | |
14081 | + "the value of `enabled' must be a boolean"); | |
14082 | + return -1; | |
14083 | + } | |
14084 | + | |
14085 | + cmp = PyObject_IsTrue (newvalue); | |
14086 | + if (cmp < 0) | |
14087 | + return -1; | |
14088 | + else if (cmp == 1) | |
14089 | + enable_breakpoint (self_bp->bp); | |
14090 | + else | |
14091 | + disable_breakpoint (self_bp->bp); | |
14092 | + return 0; | |
14093 | +} | |
14094 | + | |
14095 | +/* Python function to set the 'silent' state of a breakpoint. */ | |
14096 | +static int | |
14097 | +bppy_set_silent (PyObject *self, PyObject *newvalue, void *closure) | |
14098 | +{ | |
14099 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14100 | + int cmp; | |
14101 | + | |
14102 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
14103 | + | |
14104 | + if (newvalue == NULL) | |
14105 | + { | |
14106 | + PyErr_SetString (PyExc_TypeError, "cannot delete `silent' attribute"); | |
14107 | + return -1; | |
14108 | + } | |
14109 | + else if (! PyBool_Check (newvalue)) | |
14110 | + { | |
14111 | + PyErr_SetString (PyExc_TypeError, | |
14112 | + "the value of `silent' must be a boolean"); | |
14113 | + return -1; | |
14114 | + } | |
14115 | + | |
14116 | + cmp = PyObject_IsTrue (newvalue); | |
14117 | + if (cmp < 0) | |
14118 | + return -1; | |
14119 | + else | |
14120 | + self_bp->bp->silent = cmp; | |
14121 | + | |
14122 | + return 0; | |
14123 | +} | |
14124 | + | |
14125 | +/* Python function to set the thread of a breakpoint. */ | |
14126 | +static int | |
14127 | +bppy_set_thread (PyObject *self, PyObject *newvalue, void *closure) | |
14128 | +{ | |
14129 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14130 | + int id; | |
14131 | + | |
14132 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
14133 | + | |
14134 | + if (newvalue == NULL) | |
14135 | + { | |
14136 | + PyErr_SetString (PyExc_TypeError, "cannot delete `thread' attribute"); | |
14137 | + return -1; | |
14138 | + } | |
14139 | + else if (PyInt_Check (newvalue)) | |
14140 | + { | |
14141 | + id = (int) PyInt_AsLong (newvalue); | |
14142 | + if (! valid_thread_id (id)) | |
14143 | + { | |
14144 | + PyErr_SetString (PyExc_RuntimeError, "invalid thread id"); | |
14145 | + return -1; | |
14146 | + } | |
14147 | + } | |
14148 | + else if (newvalue == Py_None) | |
14149 | + id = -1; | |
14150 | + else | |
14151 | + { | |
14152 | + PyErr_SetString (PyExc_TypeError, | |
14153 | + "the value of `thread' must be an integer or None"); | |
14154 | + return -1; | |
14155 | + } | |
14156 | + | |
14157 | + self_bp->bp->thread = id; | |
14158 | + | |
14159 | + return 0; | |
14160 | +} | |
14161 | + | |
14162 | +/* Python function to set the ignore count of a breakpoint. */ | |
14163 | +static int | |
14164 | +bppy_set_ignore_count (PyObject *self, PyObject *newvalue, void *closure) | |
14165 | +{ | |
14166 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14167 | + long value; | |
14168 | + | |
14169 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
14170 | + | |
14171 | + if (newvalue == NULL) | |
14172 | + { | |
14173 | + PyErr_SetString (PyExc_TypeError, | |
14174 | + "cannot delete `ignore_count' attribute"); | |
14175 | + return -1; | |
14176 | + } | |
14177 | + else if (! PyInt_Check (newvalue)) | |
14178 | + { | |
14179 | + PyErr_SetString (PyExc_TypeError, | |
14180 | + "the value of `ignore_count' must be an integer"); | |
14181 | + return -1; | |
14182 | + } | |
14183 | + | |
14184 | + value = PyInt_AsLong (newvalue); | |
14185 | + if (value < 0) | |
14186 | + value = 0; | |
14187 | + set_ignore_count (self_bp->number, (int) value, 0); | |
14188 | + | |
14189 | + return 0; | |
14190 | +} | |
14191 | + | |
14192 | +/* Python function to set the hit count of a breakpoint. */ | |
14193 | +static int | |
14194 | +bppy_set_hit_count (PyObject *self, PyObject *newvalue, void *closure) | |
14195 | +{ | |
14196 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14197 | + | |
14198 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
14199 | + | |
14200 | + if (newvalue == NULL) | |
14201 | + { | |
14202 | + PyErr_SetString (PyExc_TypeError, "cannot delete `hit_count' attribute"); | |
14203 | + return -1; | |
14204 | + } | |
14205 | + else if (! PyInt_Check (newvalue) || PyInt_AsLong (newvalue) != 0) | |
14206 | + { | |
14207 | + PyErr_SetString (PyExc_AttributeError, | |
14208 | + "the value of `hit_count' must be zero"); | |
14209 | + return -1; | |
14210 | + } | |
14211 | + | |
14212 | + self_bp->bp->hit_count = 0; | |
14213 | + | |
14214 | + return 0; | |
14215 | +} | |
14216 | + | |
14217 | +/* Python function to get the location of a breakpoint. */ | |
14218 | +static PyObject * | |
14219 | +bppy_get_location (PyObject *self, void *closure) | |
14220 | +{ | |
14221 | + char *str; | |
14222 | + | |
14223 | + BPPY_REQUIRE_VALID ((breakpoint_object *) self); | |
14224 | + str = ((breakpoint_object *) self)->bp->addr_string; | |
14225 | + /* FIXME: watchpoints? tracepoints? */ | |
14226 | + if (! str) | |
14227 | + str = ""; | |
14228 | + return PyString_Decode (str, strlen (str), host_charset (), NULL); | |
14229 | +} | |
14230 | + | |
14231 | +/* Python function to get the condition expression of a breakpoint. */ | |
14232 | +static PyObject * | |
14233 | +bppy_get_condition (PyObject *self, void *closure) | |
14234 | +{ | |
14235 | + char *str; | |
14236 | + BPPY_REQUIRE_VALID ((breakpoint_object *) self); | |
14237 | + | |
14238 | + str = ((breakpoint_object *) self)->bp->cond_string; | |
14239 | + if (! str) | |
14240 | + Py_RETURN_NONE; | |
14241 | + return PyString_Decode (str, strlen (str), host_charset (), NULL); | |
14242 | +} | |
14243 | + | |
14244 | +static int | |
14245 | +bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure) | |
14246 | +{ | |
14247 | + char *exp; | |
14248 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14249 | + volatile struct gdb_exception except; | |
14250 | + | |
14251 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
14252 | + | |
14253 | + if (newvalue == NULL) | |
14254 | + { | |
14255 | + PyErr_SetString (PyExc_TypeError, "cannot delete `condition' attribute"); | |
14256 | + return -1; | |
14257 | + } | |
14258 | + else if (newvalue == Py_None) | |
14259 | + exp = ""; | |
14260 | + else | |
14261 | + { | |
14262 | + exp = python_string_to_host_string (newvalue); | |
14263 | + if (exp == NULL) | |
14264 | + return -1; | |
14265 | + } | |
14266 | + | |
14267 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
14268 | + { | |
14269 | + set_breakpoint_condition (self_bp->bp, exp, 0); | |
14270 | + } | |
14271 | + GDB_PY_SET_HANDLE_EXCEPTION (except); | |
14272 | + | |
14273 | + return 0; | |
14274 | +} | |
14275 | + | |
14276 | +/* Python function to get the commands attached to a breakpoint. */ | |
14277 | +static PyObject * | |
14278 | +bppy_get_commands (PyObject *self, void *closure) | |
14279 | +{ | |
14280 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14281 | + long length; | |
14282 | + volatile struct gdb_exception except; | |
14283 | + struct ui_file *string_file; | |
14284 | + struct cleanup *chain; | |
14285 | + PyObject *result; | |
14286 | + char *cmdstr; | |
14287 | + | |
14288 | + BPPY_REQUIRE_VALID (self_bp); | |
14289 | + | |
14290 | + if (! self_bp->bp->commands) | |
14291 | + Py_RETURN_NONE; | |
14292 | + | |
14293 | + string_file = mem_fileopen (); | |
14294 | + chain = make_cleanup_ui_file_delete (string_file); | |
14295 | + | |
14296 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
14297 | + { | |
14298 | + /* FIXME: this can fail. Maybe we need to be making a new | |
14299 | + ui_out object here? */ | |
14300 | + ui_out_redirect (uiout, string_file); | |
14301 | + print_command_lines (uiout, self_bp->bp->commands, 0); | |
14302 | + ui_out_redirect (uiout, NULL); | |
14303 | + } | |
14304 | + cmdstr = ui_file_xstrdup (string_file, &length); | |
14305 | + GDB_PY_HANDLE_EXCEPTION (except); | |
14306 | + | |
14307 | + result = PyString_Decode (cmdstr, strlen (cmdstr), host_charset (), NULL); | |
14308 | + do_cleanups (chain); | |
14309 | + xfree (cmdstr); | |
14310 | + return result; | |
14311 | +} | |
14312 | + | |
14313 | +/* Python function to get the breakpoint's number. */ | |
14314 | +static PyObject * | |
14315 | +bppy_get_number (PyObject *self, void *closure) | |
14316 | +{ | |
14317 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14318 | + | |
14319 | + BPPY_REQUIRE_VALID (self_bp); | |
14320 | + | |
14321 | + return PyInt_FromLong (self_bp->number); | |
14322 | +} | |
14323 | + | |
14324 | +/* Python function to get the breakpoint's thread ID. */ | |
14325 | +static PyObject * | |
14326 | +bppy_get_thread (PyObject *self, void *closure) | |
14327 | +{ | |
14328 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14329 | + | |
14330 | + BPPY_REQUIRE_VALID (self_bp); | |
14331 | + | |
14332 | + if (self_bp->bp->thread == -1) | |
14333 | + Py_RETURN_NONE; | |
14334 | + | |
14335 | + return PyInt_FromLong (self_bp->bp->thread); | |
14336 | +} | |
14337 | + | |
14338 | +/* Python function to get the breakpoint's hit count. */ | |
14339 | +static PyObject * | |
14340 | +bppy_get_hit_count (PyObject *self, void *closure) | |
14341 | +{ | |
14342 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14343 | + | |
14344 | + BPPY_REQUIRE_VALID (self_bp); | |
14345 | + | |
14346 | + return PyInt_FromLong (self_bp->bp->hit_count); | |
14347 | +} | |
14348 | + | |
14349 | +/* Python function to get the breakpoint's ignore count. */ | |
14350 | +static PyObject * | |
14351 | +bppy_get_ignore_count (PyObject *self, void *closure) | |
14352 | +{ | |
14353 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
14354 | + | |
14355 | + BPPY_REQUIRE_VALID (self_bp); | |
14356 | + | |
14357 | + return PyInt_FromLong (self_bp->bp->ignore_count); | |
14358 | +} | |
14359 | + | |
14360 | +/* Python function to create a new breakpoint. */ | |
14361 | +static PyObject * | |
14362 | +bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs) | |
14363 | +{ | |
14364 | + PyObject *result; | |
14365 | + char *spec; | |
14366 | + volatile struct gdb_exception except; | |
14367 | + | |
14368 | + /* FIXME: allow condition, thread, temporary, ... ? */ | |
14369 | + if (! PyArg_ParseTuple (args, "s", &spec)) | |
14370 | + return NULL; | |
14371 | + result = subtype->tp_alloc (subtype, 0); | |
14372 | + if (! result) | |
14373 | + return NULL; | |
14374 | + bppy_pending_object = (breakpoint_object *) result; | |
14375 | + bppy_pending_object->number = -1; | |
14376 | + bppy_pending_object->bp = NULL; | |
14377 | + | |
14378 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
14379 | + { | |
7566401a ER |
14380 | + set_breakpoint (python_gdbarch, spec, NULL, 0, 0, -1, 0, |
14381 | + AUTO_BOOLEAN_TRUE, 1); | |
3a58abaf AM |
14382 | + } |
14383 | + if (except.reason < 0) | |
14384 | + { | |
14385 | + subtype->tp_free (result); | |
14386 | + return PyErr_Format (except.reason == RETURN_QUIT | |
14387 | + ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, | |
14388 | + "%s", except.message); | |
14389 | + } | |
14390 | + | |
14391 | + BPPY_REQUIRE_VALID ((breakpoint_object *) result); | |
14392 | + return result; | |
14393 | +} | |
14394 | + | |
14395 | +\f | |
14396 | + | |
14397 | +/* Static function to return a tuple holding all breakpoints. */ | |
14398 | + | |
14399 | +PyObject * | |
14400 | +gdbpy_breakpoints (PyObject *self, PyObject *args) | |
14401 | +{ | |
14402 | + PyObject *result; | |
14403 | + | |
14404 | + if (bppy_live == 0) | |
14405 | + Py_RETURN_NONE; | |
14406 | + | |
14407 | + result = PyTuple_New (bppy_live); | |
14408 | + if (result) | |
14409 | + { | |
14410 | + int i, out = 0; | |
14411 | + for (i = 0; out < bppy_live; ++i) | |
14412 | + { | |
14413 | + if (! bppy_breakpoints[i]) | |
14414 | + continue; | |
14415 | + Py_INCREF (bppy_breakpoints[i]); | |
14416 | + PyTuple_SetItem (result, out, (PyObject *) bppy_breakpoints[i]); | |
14417 | + ++out; | |
14418 | + } | |
14419 | + } | |
14420 | + return result; | |
14421 | +} | |
14422 | + | |
14423 | +\f | |
14424 | + | |
14425 | +/* Event callback functions. */ | |
14426 | + | |
14427 | +/* Callback that is used when a breakpoint is created. This function | |
14428 | + will create a new Python breakpoint object. */ | |
14429 | +static void | |
14430 | +gdbpy_breakpoint_created (int num) | |
14431 | +{ | |
14432 | + breakpoint_object *newbp; | |
14433 | + struct breakpoint *bp; | |
14434 | + PyGILState_STATE state; | |
14435 | + | |
14436 | + if (num < 0) | |
14437 | + return; | |
14438 | + | |
14439 | + for (bp = breakpoint_chain; bp; bp = bp->next) | |
14440 | + if (bp->number == num) | |
14441 | + break; | |
14442 | + if (! bp) | |
14443 | + return; | |
14444 | + | |
14445 | + if (num >= bppy_slots) | |
14446 | + { | |
14447 | + int old = bppy_slots; | |
14448 | + bppy_slots = bppy_slots * 2 + 10; | |
14449 | + bppy_breakpoints | |
14450 | + = (breakpoint_object **) xrealloc (bppy_breakpoints, | |
14451 | + (bppy_slots | |
14452 | + * sizeof (breakpoint_object *))); | |
14453 | + memset (&bppy_breakpoints[old], 0, | |
14454 | + (bppy_slots - old) * sizeof (PyObject *)); | |
14455 | + } | |
14456 | + | |
14457 | + ++bppy_live; | |
14458 | + | |
14459 | + state = PyGILState_Ensure (); | |
14460 | + | |
14461 | + if (bppy_pending_object) | |
14462 | + { | |
14463 | + newbp = bppy_pending_object; | |
14464 | + bppy_pending_object = NULL; | |
14465 | + } | |
14466 | + else | |
14467 | + newbp = PyObject_New (breakpoint_object, &breakpoint_object_type); | |
14468 | + if (newbp) | |
14469 | + { | |
14470 | + PyObject *hookfn; | |
14471 | + | |
14472 | + newbp->number = num; | |
14473 | + newbp->bp = bp; | |
14474 | + bppy_breakpoints[num] = newbp; | |
14475 | + | |
14476 | + hookfn = gdbpy_get_hook_function ("new_breakpoint"); | |
14477 | + if (hookfn) | |
14478 | + { | |
14479 | + PyObject *result; | |
14480 | + result = PyObject_CallFunctionObjArgs (hookfn, newbp, NULL); | |
14481 | + if (result) | |
14482 | + { | |
14483 | + Py_DECREF (result); | |
14484 | + } | |
14485 | + Py_DECREF (hookfn); | |
14486 | + } | |
14487 | + } | |
14488 | + | |
14489 | + /* Just ignore errors here. */ | |
14490 | + PyErr_Clear (); | |
14491 | + | |
14492 | + PyGILState_Release (state); | |
14493 | +} | |
14494 | + | |
14495 | +/* Callback that is used when a breakpoint is deleted. This will | |
14496 | + invalidate the corresponding Python object. */ | |
14497 | +static void | |
14498 | +gdbpy_breakpoint_deleted (int num) | |
14499 | +{ | |
14500 | + PyGILState_STATE state; | |
14501 | + | |
14502 | + state = PyGILState_Ensure (); | |
14503 | + if (BPPY_VALID_P (num)) | |
14504 | + { | |
14505 | + bppy_breakpoints[num]->bp = NULL; | |
14506 | + Py_DECREF (bppy_breakpoints[num]); | |
14507 | + bppy_breakpoints[num] = NULL; | |
14508 | + --bppy_live; | |
14509 | + } | |
14510 | + PyGILState_Release (state); | |
14511 | +} | |
14512 | + | |
14513 | +\f | |
14514 | + | |
14515 | +/* Initialize the Python breakpoint code. */ | |
14516 | +void | |
14517 | +gdbpy_initialize_breakpoints (void) | |
14518 | +{ | |
14519 | + breakpoint_object_type.tp_new = bppy_new; | |
14520 | + if (PyType_Ready (&breakpoint_object_type) < 0) | |
14521 | + return; | |
14522 | + | |
14523 | + Py_INCREF (&breakpoint_object_type); | |
14524 | + PyModule_AddObject (gdb_module, "Breakpoint", | |
14525 | + (PyObject *) &breakpoint_object_type); | |
14526 | + | |
14527 | + observer_attach_breakpoint_created (gdbpy_breakpoint_created); | |
14528 | + observer_attach_breakpoint_deleted (gdbpy_breakpoint_deleted); | |
14529 | +} | |
14530 | + | |
14531 | +\f | |
14532 | + | |
14533 | +static PyGetSetDef breakpoint_object_getset[] = { | |
14534 | + { "enabled", bppy_get_enabled, bppy_set_enabled, | |
14535 | + "Boolean telling whether the breakpoint is enabled.", NULL }, | |
14536 | + { "silent", bppy_get_silent, bppy_set_silent, | |
14537 | + "Boolean telling whether the breakpoint is silent.", NULL }, | |
14538 | + { "thread", bppy_get_thread, bppy_set_thread, | |
14539 | + "Thread ID for the breakpoint.\n\ | |
14540 | +If the value is a thread ID (integer), then this is a thread-specific breakpoint.\n\ | |
14541 | +If the value is None, then this breakpoint not thread-specific.\n\ | |
14542 | +No other type of value can be used.", NULL }, | |
14543 | + { "ignore_count", bppy_get_ignore_count, bppy_set_ignore_count, | |
14544 | + "Number of times this breakpoint should be automatically continued.", | |
14545 | + NULL }, | |
14546 | + { "number", bppy_get_number, NULL, | |
14547 | + "Breakpoint's number assigned by GDB.", NULL }, | |
14548 | + { "hit_count", bppy_get_hit_count, bppy_set_hit_count, | |
14549 | + "Number of times the breakpoint has been hit.\n\ | |
14550 | +Can be set to zero to clear the count. No other value is valid\n\ | |
14551 | +when setting this property.", NULL }, | |
14552 | + { "location", bppy_get_location, NULL, | |
14553 | + "Location of the breakpoint, as specified by the user.", NULL}, | |
14554 | + { "condition", bppy_get_condition, bppy_set_condition, | |
14555 | + "Condition of the breakpoint, as specified by the user,\ | |
14556 | +or None if no condition set."}, | |
14557 | + { "commands", bppy_get_commands, NULL, | |
14558 | + "Commands of the breakpoint, as specified by the user."}, | |
14559 | + { NULL } /* Sentinel. */ | |
14560 | +}; | |
14561 | + | |
14562 | +static PyMethodDef breakpoint_object_methods[] = | |
14563 | +{ | |
14564 | + { "is_valid", bppy_is_valid, METH_NOARGS, | |
14565 | + "Return true if this breakpoint is valid, false if not." }, | |
14566 | + { NULL } /* Sentinel. */ | |
14567 | +}; | |
14568 | + | |
14569 | +static PyTypeObject breakpoint_object_type = | |
14570 | +{ | |
14571 | + PyObject_HEAD_INIT (NULL) | |
14572 | + 0, /*ob_size*/ | |
14573 | + "gdb.Breakpoint", /*tp_name*/ | |
14574 | + sizeof (breakpoint_object), /*tp_basicsize*/ | |
14575 | + 0, /*tp_itemsize*/ | |
14576 | + 0, /*tp_dealloc*/ | |
14577 | + 0, /*tp_print*/ | |
14578 | + 0, /*tp_getattr*/ | |
14579 | + 0, /*tp_setattr*/ | |
14580 | + 0, /*tp_compare*/ | |
14581 | + 0, /*tp_repr*/ | |
14582 | + 0, /*tp_as_number*/ | |
14583 | + 0, /*tp_as_sequence*/ | |
14584 | + 0, /*tp_as_mapping*/ | |
14585 | + 0, /*tp_hash */ | |
14586 | + 0, /*tp_call*/ | |
14587 | + 0, /*tp_str*/ | |
14588 | + 0, /*tp_getattro*/ | |
14589 | + 0, /*tp_setattro*/ | |
14590 | + 0, /*tp_as_buffer*/ | |
14591 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
14592 | + "GDB breakpoint object", /* tp_doc */ | |
14593 | + 0, /* tp_traverse */ | |
14594 | + 0, /* tp_clear */ | |
14595 | + 0, /* tp_richcompare */ | |
14596 | + 0, /* tp_weaklistoffset */ | |
14597 | + 0, /* tp_iter */ | |
14598 | + 0, /* tp_iternext */ | |
14599 | + breakpoint_object_methods, /* tp_methods */ | |
14600 | + 0, /* tp_members */ | |
14601 | + breakpoint_object_getset /* tp_getset */ | |
14602 | +}; | |
7566401a ER |
14603 | diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c |
14604 | index 528aca6..04b3fd1 100644 | |
14605 | --- a/gdb/python/py-cmd.c | |
14606 | +++ b/gdb/python/py-cmd.c | |
14607 | @@ -49,8 +49,7 @@ static struct cmdpy_completer completers[] = | |
3a58abaf AM |
14608 | |
14609 | #define N_COMPLETERS (sizeof (completers) / sizeof (completers[0])) | |
14610 | ||
14611 | -/* A gdb command. For the time being only ordinary commands (not | |
14612 | - set/show commands) are allowed. */ | |
14613 | +/* A gdb command. */ | |
14614 | struct cmdpy_object | |
14615 | { | |
14616 | PyObject_HEAD | |
7566401a | 14617 | @@ -70,7 +69,6 @@ typedef struct cmdpy_object cmdpy_object; |
3a58abaf AM |
14618 | |
14619 | static PyTypeObject cmdpy_object_type; | |
14620 | ||
14621 | - | |
14622 | /* Constants used by this module. */ | |
14623 | static PyObject *invoke_cst; | |
14624 | static PyObject *complete_cst; | |
7566401a | 14625 | @@ -263,10 +261,13 @@ cmdpy_completer (struct cmd_list_element *command, char *text, char *word) |
3a58abaf AM |
14626 | *BASE_LIST is set to the final prefix command's list of |
14627 | *sub-commands. | |
14628 | ||
14629 | + START_LIST is the list in which the search starts. | |
14630 | + | |
14631 | This function returns the xmalloc()d name of the new command. On | |
14632 | error sets the Python error and returns NULL. */ | |
14633 | -static char * | |
14634 | -parse_command_name (char *text, struct cmd_list_element ***base_list) | |
14635 | +char * | |
14636 | +gdbpy_parse_command_name (char *text, struct cmd_list_element ***base_list, | |
14637 | + struct cmd_list_element **start_list) | |
14638 | { | |
14639 | struct cmd_list_element *elt; | |
14640 | int len = strlen (text); | |
7566401a | 14641 | @@ -299,7 +300,7 @@ parse_command_name (char *text, struct cmd_list_element ***base_list) |
3a58abaf AM |
14642 | ; |
14643 | if (i < 0) | |
14644 | { | |
14645 | - *base_list = &cmdlist; | |
14646 | + *base_list = start_list; | |
14647 | return result; | |
14648 | } | |
14649 | ||
7566401a | 14650 | @@ -308,7 +309,7 @@ parse_command_name (char *text, struct cmd_list_element ***base_list) |
3a58abaf AM |
14651 | prefix_text[i + 1] = '\0'; |
14652 | ||
14653 | text = prefix_text; | |
14654 | - elt = lookup_cmd_1 (&text, cmdlist, NULL, 1); | |
14655 | + elt = lookup_cmd_1 (&text, *start_list, NULL, 1); | |
14656 | if (!elt || elt == (struct cmd_list_element *) -1) | |
14657 | { | |
14658 | PyErr_Format (PyExc_RuntimeError, _("could not find command prefix %s"), | |
7566401a ER |
14659 | @@ -399,7 +400,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw) |
14660 | return -1; | |
14661 | } | |
3a58abaf | 14662 | |
7566401a ER |
14663 | - cmd_name = parse_command_name (name, &cmd_list); |
14664 | + cmd_name = gdbpy_parse_command_name (name, &cmd_list, &cmdlist); | |
14665 | if (! cmd_name) | |
14666 | return -1; | |
3a58abaf | 14667 | |
7566401a ER |
14668 | diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c |
14669 | index 279415c..5d8ce0a 100644 | |
14670 | --- a/gdb/python/py-frame.c | |
14671 | +++ b/gdb/python/py-frame.c | |
14672 | @@ -202,10 +202,59 @@ frapy_pc (PyObject *self, PyObject *args) | |
14673 | return PyLong_FromUnsignedLongLong (pc); | |
14674 | } | |
3a58abaf | 14675 | |
7566401a ER |
14676 | +/* Implementation of gdb.Frame.block (self) -> gdb.Block. |
14677 | + Returns the frame's code block. */ | |
3a58abaf AM |
14678 | + |
14679 | +static PyObject * | |
7566401a | 14680 | +frapy_block (PyObject *self, PyObject *args) |
3a58abaf AM |
14681 | +{ |
14682 | + struct frame_info *frame; | |
7566401a | 14683 | + struct block *block = NULL; |
3a58abaf AM |
14684 | + volatile struct gdb_exception except; |
14685 | + | |
14686 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
14687 | + { | |
14688 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
14689 | + | |
7566401a | 14690 | + block = block_for_pc (get_frame_address_in_block (frame)); |
3a58abaf AM |
14691 | + } |
14692 | + GDB_PY_HANDLE_EXCEPTION (except); | |
14693 | + | |
7566401a ER |
14694 | + if (block) |
14695 | + return block_to_block_object (block); | |
3a58abaf | 14696 | + |
7566401a | 14697 | + Py_RETURN_NONE; |
3a58abaf AM |
14698 | +} |
14699 | + | |
7566401a ER |
14700 | + |
14701 | +/* Implementation of gdb.Frame.function (self) -> gdb.Symbol. | |
14702 | + Returns the symbol for the function corresponding to this frame. */ | |
3a58abaf AM |
14703 | + |
14704 | +static PyObject * | |
7566401a | 14705 | +frapy_function (PyObject *self, PyObject *args) |
3a58abaf | 14706 | +{ |
7566401a | 14707 | + struct symbol *sym = NULL; |
3a58abaf | 14708 | + struct frame_info *frame; |
3a58abaf AM |
14709 | + volatile struct gdb_exception except; |
14710 | + | |
14711 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
14712 | + { | |
14713 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
14714 | + | |
7566401a | 14715 | + sym = find_pc_function (get_frame_address_in_block (frame)); |
3a58abaf AM |
14716 | + } |
14717 | + GDB_PY_HANDLE_EXCEPTION (except); | |
14718 | + | |
7566401a ER |
14719 | + if (sym) |
14720 | + return symbol_to_symbol_object (sym); | |
3a58abaf | 14721 | + |
7566401a | 14722 | + Py_RETURN_NONE; |
3a58abaf AM |
14723 | +} |
14724 | + | |
7566401a ER |
14725 | /* Convert a frame_info struct to a Python Frame object. |
14726 | Sets a Python exception and returns NULL on error. */ | |
14727 | ||
14728 | -static frame_object * | |
14729 | +PyObject * | |
14730 | frame_info_to_frame_object (struct frame_info *frame) | |
14731 | { | |
14732 | frame_object *frame_obj; | |
14733 | @@ -235,7 +284,7 @@ frame_info_to_frame_object (struct frame_info *frame) | |
14734 | ||
14735 | frame_obj->gdbarch = get_frame_arch (frame); | |
14736 | ||
14737 | - return frame_obj; | |
14738 | + return (PyObject *) frame_obj; | |
14739 | } | |
14740 | ||
14741 | /* Implementation of gdb.Frame.older (self) -> gdb.Frame. | |
14742 | @@ -296,7 +345,30 @@ frapy_newer (PyObject *self, PyObject *args) | |
14743 | return next_obj; | |
14744 | } | |
14745 | ||
14746 | -/* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value. | |
14747 | +/* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line. | |
14748 | + Returns the frame's symtab and line. */ | |
3a58abaf AM |
14749 | + |
14750 | +static PyObject * | |
7566401a | 14751 | +frapy_find_sal (PyObject *self, PyObject *args) |
3a58abaf | 14752 | +{ |
3a58abaf | 14753 | + struct frame_info *frame; |
7566401a | 14754 | + struct symtab_and_line sal; |
3a58abaf | 14755 | + volatile struct gdb_exception except; |
7566401a | 14756 | + PyObject *sal_obj = NULL; /* Initialize to appease gcc warning. */ |
3a58abaf AM |
14757 | + |
14758 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
14759 | + { | |
14760 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
14761 | + | |
7566401a ER |
14762 | + find_frame_sal (frame, &sal); |
14763 | + sal_obj = symtab_and_line_to_sal_object (sal); | |
3a58abaf AM |
14764 | + } |
14765 | + GDB_PY_HANDLE_EXCEPTION (except); | |
14766 | + | |
7566401a | 14767 | + return sal_obj; |
3a58abaf AM |
14768 | +} |
14769 | + | |
7566401a ER |
14770 | +/* Implementation of gdb.Frame.read_var (self, variable) -> gdb.Value. |
14771 | Returns the value of the given variable in this frame. The argument must be | |
14772 | a string. Returns None if GDB can't find the specified variable. */ | |
14773 | ||
14774 | @@ -312,7 +384,9 @@ frapy_read_var (PyObject *self, PyObject *args) | |
14775 | if (!PyArg_ParseTuple (args, "O", &sym_obj)) | |
14776 | return NULL; | |
14777 | ||
14778 | - if (gdbpy_is_string (sym_obj)) | |
14779 | + if (PyObject_TypeCheck (sym_obj, &symbol_object_type)) | |
14780 | + var = symbol_object_to_symbol (sym_obj); | |
14781 | + else if (gdbpy_is_string (sym_obj)) | |
14782 | { | |
14783 | char *var_name; | |
14784 | struct block *block = NULL; | |
14785 | @@ -365,6 +439,25 @@ frapy_read_var (PyObject *self, PyObject *args) | |
14786 | Py_RETURN_NONE; | |
14787 | } | |
14788 | ||
14789 | +/* Select this frame. */ | |
3a58abaf AM |
14790 | + |
14791 | +static PyObject * | |
7566401a | 14792 | +frapy_select (PyObject *self, PyObject *args) |
3a58abaf | 14793 | +{ |
7566401a ER |
14794 | + struct frame_info *fi; |
14795 | + frame_object *frame = (frame_object *) self; | |
3a58abaf AM |
14796 | + volatile struct gdb_exception except; |
14797 | + | |
14798 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
14799 | + { | |
7566401a ER |
14800 | + FRAPY_REQUIRE_VALID (frame, fi); |
14801 | + select_frame (fi); | |
3a58abaf AM |
14802 | + } |
14803 | + GDB_PY_HANDLE_EXCEPTION (except); | |
14804 | + | |
3a58abaf AM |
14805 | + Py_RETURN_NONE; |
14806 | +} | |
14807 | + | |
7566401a ER |
14808 | /* Implementation of gdb.selected_frame () -> gdb.Frame. |
14809 | Returns the selected frame object. */ | |
14810 | ||
14811 | @@ -372,7 +465,7 @@ PyObject * | |
14812 | gdbpy_selected_frame (PyObject *self, PyObject *args) | |
14813 | { | |
14814 | struct frame_info *frame; | |
14815 | - frame_object *frame_obj = NULL; /* Initialize to appease gcc warning. */ | |
14816 | + PyObject *frame_obj = NULL; /* Initialize to appease gcc warning. */ | |
14817 | volatile struct gdb_exception except; | |
14818 | ||
14819 | TRY_CATCH (except, RETURN_MASK_ALL) | |
14820 | @@ -382,7 +475,7 @@ gdbpy_selected_frame (PyObject *self, PyObject *args) | |
14821 | } | |
14822 | GDB_PY_HANDLE_EXCEPTION (except); | |
14823 | ||
14824 | - return (PyObject *) frame_obj; | |
14825 | + return frame_obj; | |
14826 | } | |
14827 | ||
14828 | /* Implementation of gdb.stop_reason_string (Integer) -> String. | |
14829 | @@ -484,15 +577,26 @@ Return the reason why it's not possible to find frames older than this." }, | |
14830 | { "pc", frapy_pc, METH_NOARGS, | |
14831 | "pc () -> Long.\n\ | |
14832 | Return the frame's resume address." }, | |
14833 | + { "block", frapy_block, METH_NOARGS, | |
14834 | + "block () -> gdb.Block.\n\ | |
14835 | +Return the frame's code block." }, | |
14836 | + { "function", frapy_function, METH_NOARGS, | |
14837 | + "function () -> gdb.Symbol.\n\ | |
14838 | +Returns the symbol for the function corresponding to this frame." }, | |
14839 | { "older", frapy_older, METH_NOARGS, | |
14840 | "older () -> gdb.Frame.\n\ | |
14841 | Return the frame that called this frame." }, | |
14842 | { "newer", frapy_newer, METH_NOARGS, | |
14843 | "newer () -> gdb.Frame.\n\ | |
14844 | Return the frame called by this frame." }, | |
14845 | + { "find_sal", frapy_find_sal, METH_NOARGS, | |
14846 | + "find_sal () -> gdb.Symtab_and_line.\n\ | |
14847 | +Return the frame's symtab and line." }, | |
14848 | { "read_var", frapy_read_var, METH_VARARGS, | |
14849 | "read_var (variable) -> gdb.Value.\n\ | |
14850 | Return the value of the variable in this frame." }, | |
14851 | + { "select", frapy_select, METH_NOARGS, | |
14852 | + "Select this frame as the user's current frame." }, | |
14853 | {NULL} /* Sentinel */ | |
14854 | }; | |
14855 | ||
14856 | diff --git a/gdb/python/py-hooks.c b/gdb/python/py-hooks.c | |
14857 | new file mode 100644 | |
14858 | index 0000000..a3140bc | |
14859 | --- /dev/null | |
14860 | +++ b/gdb/python/py-hooks.c | |
14861 | @@ -0,0 +1,50 @@ | |
14862 | +/* Notifications from gdb to Python | |
3a58abaf | 14863 | + |
7566401a | 14864 | + Copyright (C) 2008 Free Software Foundation, Inc. |
3a58abaf | 14865 | + |
7566401a | 14866 | + This file is part of GDB. |
3a58abaf | 14867 | + |
7566401a ER |
14868 | + This program is free software; you can redistribute it and/or modify |
14869 | + it under the terms of the GNU General Public License as published by | |
14870 | + the Free Software Foundation; either version 3 of the License, or | |
14871 | + (at your option) any later version. | |
3a58abaf | 14872 | + |
7566401a ER |
14873 | + This program is distributed in the hope that it will be useful, |
14874 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14875 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14876 | + GNU General Public License for more details. | |
3a58abaf | 14877 | + |
7566401a ER |
14878 | + You should have received a copy of the GNU General Public License |
14879 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
3a58abaf | 14880 | + |
7566401a ER |
14881 | +#include "defs.h" |
14882 | +#include "cli/cli-decode.h" | |
14883 | +#include "charset.h" | |
14884 | +#include "python.h" | |
14885 | +#include "python-internal.h" | |
14886 | +#include "observer.h" | |
3a58abaf | 14887 | + |
7566401a ER |
14888 | +PyObject * |
14889 | +gdbpy_get_hook_function (const char *name) | |
3a58abaf | 14890 | +{ |
7566401a ER |
14891 | + PyObject *hooks; |
14892 | + PyObject *result; | |
3a58abaf | 14893 | + |
7566401a ER |
14894 | + if (! PyObject_HasAttrString (gdb_module, "hooks")) |
14895 | + return NULL; | |
14896 | + hooks = PyObject_GetAttrString (gdb_module, "hooks"); | |
14897 | + if (! hooks) | |
14898 | + return NULL; | |
14899 | + /* The cast is because the Python function doesn't declare const argument. | |
14900 | + This is a problem in Python version 2.4, but not in 2.5. */ | |
14901 | + if (! PyObject_HasAttrString (hooks, (char *) name)) | |
3a58abaf | 14902 | + { |
7566401a | 14903 | + Py_DECREF (hooks); |
3a58abaf AM |
14904 | + return NULL; |
14905 | + } | |
7566401a ER |
14906 | + /* The cast is because the Python function doesn't declare const argument. |
14907 | + This is a problem in Python version 2.4, but not in 2.5. */ | |
14908 | + result = PyObject_GetAttrString (hooks, (char *) name); | |
14909 | + Py_DECREF (hooks); | |
14910 | + return result; | |
14911 | +} | |
14912 | diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c | |
14913 | new file mode 100644 | |
14914 | index 0000000..5e90cc2 | |
14915 | --- /dev/null | |
14916 | +++ b/gdb/python/py-inferior.c | |
14917 | @@ -0,0 +1,926 @@ | |
14918 | +/* Python interface to inferiors. | |
3a58abaf | 14919 | + |
7566401a | 14920 | + Copyright (C) 2009 Free Software Foundation, Inc. |
3a58abaf | 14921 | + |
7566401a | 14922 | + This file is part of GDB. |
3a58abaf | 14923 | + |
7566401a ER |
14924 | + This program is free software; you can redistribute it and/or modify |
14925 | + it under the terms of the GNU General Public License as published by | |
14926 | + the Free Software Foundation; either version 3 of the License, or | |
14927 | + (at your option) any later version. | |
14928 | + | |
14929 | + This program is distributed in the hope that it will be useful, | |
14930 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14931 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14932 | + GNU General Public License for more details. | |
3a58abaf | 14933 | + |
7566401a ER |
14934 | + You should have received a copy of the GNU General Public License |
14935 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
3a58abaf | 14936 | + |
7566401a ER |
14937 | +#include "defs.h" |
14938 | +#include "exceptions.h" | |
14939 | +#include "gdbcore.h" | |
14940 | +#include "gdbthread.h" | |
14941 | +#include "inferior.h" | |
14942 | +#include "observer.h" | |
14943 | +#include "python-internal.h" | |
14944 | +#include "arch-utils.h" | |
14945 | +#include "language.h" | |
14946 | + | |
14947 | +struct threadlist_entry { | |
14948 | + thread_object *thread_obj; | |
14949 | + struct threadlist_entry *next; | |
14950 | +}; | |
14951 | + | |
14952 | +typedef struct | |
3a58abaf | 14953 | +{ |
7566401a | 14954 | + PyObject_HEAD |
3a58abaf | 14955 | + |
7566401a ER |
14956 | + /* The inferior we represent. */ |
14957 | + struct inferior *inferior; | |
3a58abaf | 14958 | + |
7566401a ER |
14959 | + /* thread_object instances under this inferior. This list owns a reference |
14960 | + to each object it contains. */ | |
14961 | + struct threadlist_entry *threads; | |
3a58abaf | 14962 | + |
7566401a ER |
14963 | + /* Number of threads in the list. */ |
14964 | + int nthreads; | |
14965 | +} inferior_object; | |
3a58abaf | 14966 | + |
7566401a | 14967 | +static PyTypeObject inferior_object_type; |
3a58abaf | 14968 | + |
7566401a ER |
14969 | +typedef struct { |
14970 | + PyObject_HEAD | |
14971 | + void *buffer; | |
3a58abaf | 14972 | + |
7566401a ER |
14973 | + /* These are kept just for mbpy_str. */ |
14974 | + CORE_ADDR addr; | |
14975 | + CORE_ADDR length; | |
14976 | +} membuf_object; | |
3a58abaf | 14977 | + |
7566401a | 14978 | +static PyTypeObject membuf_object_type; |
3a58abaf | 14979 | + |
7566401a ER |
14980 | +/* Require that INFERIOR be a valid inferior ID. */ |
14981 | +#define INFPY_REQUIRE_VALID(Inferior) \ | |
14982 | + do { \ | |
14983 | + if (!Inferior->inferior) \ | |
14984 | + { \ | |
14985 | + PyErr_SetString (PyExc_RuntimeError, \ | |
14986 | + "inferior no longer exists"); \ | |
14987 | + return NULL; \ | |
14988 | + } \ | |
14989 | + } while (0) | |
3a58abaf | 14990 | + |
7566401a ER |
14991 | +struct inflist_entry { |
14992 | + inferior_object *inf_obj; | |
14993 | + struct inflist_entry *next; | |
14994 | +}; | |
3a58abaf | 14995 | + |
7566401a ER |
14996 | +\f |
14997 | + | |
14998 | +/* Inferior objects list. */ | |
14999 | + | |
15000 | +/* List containing inferior_objects. This list owns a reference to each | |
15001 | + object it contains. */ | |
15002 | +static struct inflist_entry *inferior_list; | |
15003 | + | |
15004 | +static int ninferiors; | |
15005 | + | |
15006 | + | |
15007 | +/* An observer callback function that is called when an inferior has | |
15008 | + been created. Creates a corresponding Python object for the inferior | |
15009 | + and adds it to the list. */ | |
15010 | +static void | |
15011 | +add_inferior_object (int pid) | |
3a58abaf | 15012 | +{ |
7566401a ER |
15013 | + struct inferior *inf = find_inferior_pid (pid); |
15014 | + inferior_object *inf_obj; | |
15015 | + struct inflist_entry *entry; | |
15016 | + struct cleanup *cleanup; | |
3a58abaf | 15017 | + |
7566401a | 15018 | + if (!inf) |
3a58abaf | 15019 | + { |
7566401a ER |
15020 | + warning (_("Can't create Python Inferior object.")); |
15021 | + return; | |
15022 | + } | |
3a58abaf | 15023 | + |
7566401a ER |
15024 | + cleanup = ensure_python_env (get_current_arch (), current_language); |
15025 | + | |
15026 | + inf_obj = PyObject_New (inferior_object, &inferior_object_type); | |
15027 | + if (!inf_obj) | |
15028 | + { | |
15029 | + warning (_("Can't create Python Inferior object.")); | |
15030 | + gdbpy_print_stack (); | |
15031 | + do_cleanups (cleanup); | |
15032 | + return; | |
3a58abaf | 15033 | + } |
3a58abaf | 15034 | + |
7566401a ER |
15035 | + inf_obj->inferior = inf; |
15036 | + inf_obj->threads = NULL; | |
15037 | + inf_obj->nthreads = 0; | |
3a58abaf | 15038 | + |
7566401a ER |
15039 | + entry = xmalloc (sizeof (struct inflist_entry)); |
15040 | + entry->inf_obj = inf_obj; | |
15041 | + entry->next = inferior_list; | |
3a58abaf | 15042 | + |
7566401a | 15043 | + inferior_list = entry; |
3a58abaf | 15044 | + |
7566401a | 15045 | + ninferiors++; |
3a58abaf | 15046 | + |
7566401a ER |
15047 | + do_cleanups (cleanup); |
15048 | +} | |
3a58abaf | 15049 | + |
7566401a ER |
15050 | +/* An observer callback function that is called when an inferior has |
15051 | + been deleted. Removes the corresponding Python object from the | |
15052 | + inferior list, and removes the list's reference to the object. */ | |
15053 | +static void | |
15054 | +delete_inferior_object (int pid) | |
15055 | +{ | |
15056 | + PyGILState_STATE state; | |
15057 | + struct inflist_entry **inf_entry, *inf_tmp; | |
15058 | + struct threadlist_entry *th_entry, *th_tmp; | |
3a58abaf | 15059 | + |
7566401a ER |
15060 | + /* Find inferior_object for the given PID. */ |
15061 | + for (inf_entry = &inferior_list; *inf_entry != NULL; | |
15062 | + inf_entry = &(*inf_entry)->next) | |
15063 | + if ((*inf_entry)->inf_obj->inferior->pid == pid) | |
15064 | + break; | |
3a58abaf | 15065 | + |
7566401a ER |
15066 | + if (!*inf_entry) |
15067 | + return; | |
3a58abaf | 15068 | + |
7566401a | 15069 | + state = PyGILState_Ensure (); |
3a58abaf | 15070 | + |
7566401a ER |
15071 | + inf_tmp = *inf_entry; |
15072 | + inf_tmp->inf_obj->inferior = NULL; | |
3a58abaf | 15073 | + |
7566401a ER |
15074 | + /* Deallocate threads list. */ |
15075 | + for (th_entry = inf_tmp->inf_obj->threads; th_entry != NULL;) | |
3a58abaf | 15076 | + { |
7566401a ER |
15077 | + Py_DECREF (th_entry->thread_obj); |
15078 | + | |
15079 | + th_tmp = th_entry; | |
15080 | + th_entry = th_entry->next; | |
15081 | + xfree (th_tmp); | |
3a58abaf AM |
15082 | + } |
15083 | + | |
7566401a | 15084 | + inf_tmp->inf_obj->nthreads = 0; |
3a58abaf | 15085 | + |
7566401a ER |
15086 | + *inf_entry = (*inf_entry)->next; |
15087 | + Py_DECREF (inf_tmp->inf_obj); | |
15088 | + xfree (inf_tmp); | |
3a58abaf | 15089 | + |
7566401a | 15090 | + ninferiors--; |
3a58abaf | 15091 | + |
7566401a | 15092 | + PyGILState_Release (state); |
3a58abaf AM |
15093 | +} |
15094 | + | |
7566401a ER |
15095 | +/* Finds the Python Inferior object for the given pid. Returns a borrowed |
15096 | + reference. */ | |
3a58abaf | 15097 | +PyObject * |
7566401a | 15098 | +find_inferior_object (int pid) |
3a58abaf | 15099 | +{ |
7566401a | 15100 | + struct inflist_entry *p; |
3a58abaf | 15101 | + |
7566401a ER |
15102 | + for (p = inferior_list; p != NULL; p = p->next) |
15103 | + if (p->inf_obj->inferior->pid == pid) | |
15104 | + return (PyObject *) p->inf_obj; | |
3a58abaf | 15105 | + |
7566401a ER |
15106 | + return NULL; |
15107 | +} | |
3a58abaf | 15108 | + |
7566401a ER |
15109 | +/* Finds the Python InferiorThread object for the given ptid. Returns a |
15110 | + borrowed reference. */ | |
15111 | +thread_object * | |
15112 | +find_thread_object (ptid_t ptid) | |
15113 | +{ | |
15114 | + int pid; | |
15115 | + struct inflist_entry *p; | |
15116 | + struct threadlist_entry *q; | |
3a58abaf | 15117 | + |
7566401a ER |
15118 | + pid = PIDGET (ptid); |
15119 | + for (p = inferior_list; p != NULL; p = p->next) | |
15120 | + if (p->inf_obj->inferior->pid == pid) | |
15121 | + for (q = p->inf_obj->threads; q != NULL; q = q->next) | |
15122 | + if (ptid_equal (q->thread_obj->thread->ptid, ptid)) | |
15123 | + return q->thread_obj; | |
3a58abaf | 15124 | + |
7566401a | 15125 | + return NULL; |
3a58abaf AM |
15126 | +} |
15127 | + | |
7566401a | 15128 | +\f |
3a58abaf | 15129 | + |
7566401a ER |
15130 | +/* Inferior object. */ |
15131 | + | |
15132 | +static void | |
15133 | +add_thread_object (struct thread_info *tp) | |
3a58abaf | 15134 | +{ |
7566401a ER |
15135 | + PyGILState_STATE state; |
15136 | + thread_object *thread_obj; | |
15137 | + inferior_object *inf_obj; | |
15138 | + struct threadlist_entry *entry; | |
3a58abaf | 15139 | + |
7566401a ER |
15140 | + state = PyGILState_Ensure (); |
15141 | + | |
15142 | + thread_obj = create_thread_object (tp); | |
15143 | + if (!thread_obj) | |
3a58abaf | 15144 | + { |
7566401a ER |
15145 | + warning (_("Can't create Python InferiorThread object.")); |
15146 | + gdbpy_print_stack (); | |
15147 | + PyGILState_Release (state); | |
15148 | + return; | |
3a58abaf | 15149 | + } |
3a58abaf | 15150 | + |
7566401a | 15151 | + inf_obj = (inferior_object *) thread_obj->inf_obj; |
3a58abaf | 15152 | + |
7566401a ER |
15153 | + entry = xmalloc (sizeof (struct threadlist_entry)); |
15154 | + entry->thread_obj = thread_obj; | |
15155 | + entry->next = inf_obj->threads; | |
3a58abaf | 15156 | + |
7566401a ER |
15157 | + inf_obj->threads = entry; |
15158 | + inf_obj->nthreads++; | |
15159 | + | |
15160 | + PyGILState_Release (state); | |
15161 | +} | |
15162 | + | |
15163 | +static void | |
15164 | +delete_thread_object (struct thread_info *tp, int ignore) | |
3a58abaf | 15165 | +{ |
7566401a ER |
15166 | + PyGILState_STATE state; |
15167 | + inferior_object *inf_obj; | |
15168 | + thread_object *thread_obj; | |
15169 | + struct threadlist_entry **entry, *tmp; | |
3a58abaf | 15170 | + |
7566401a ER |
15171 | + inf_obj = (inferior_object *) find_inferior_object (PIDGET(tp->ptid)); |
15172 | + if (!inf_obj) | |
15173 | + return; | |
3a58abaf | 15174 | + |
7566401a ER |
15175 | + /* Find thread entry in its inferior's thread_list. */ |
15176 | + for (entry = &inf_obj->threads; *entry != NULL; entry = &(*entry)->next) | |
15177 | + if ((*entry)->thread_obj->thread == tp) | |
15178 | + break; | |
15179 | + | |
15180 | + if (!*entry) | |
15181 | + return; | |
15182 | + | |
15183 | + state = PyGILState_Ensure (); | |
3a58abaf | 15184 | + |
7566401a ER |
15185 | + tmp = *entry; |
15186 | + tmp->thread_obj->thread = NULL; | |
3a58abaf | 15187 | + |
7566401a ER |
15188 | + *entry = (*entry)->next; |
15189 | + inf_obj->nthreads--; | |
15190 | + | |
15191 | + Py_DECREF (tmp->thread_obj); | |
15192 | + xfree (tmp); | |
15193 | + | |
15194 | + | |
15195 | + PyGILState_Release (state); | |
15196 | +} | |
15197 | + | |
15198 | +static PyObject * | |
15199 | +infpy_threads (PyObject *self, PyObject *args) | |
3a58abaf | 15200 | +{ |
7566401a ER |
15201 | + int i; |
15202 | + struct threadlist_entry *entry; | |
15203 | + inferior_object *inf_obj = (inferior_object *) self; | |
15204 | + PyObject *tuple; | |
15205 | + | |
15206 | + INFPY_REQUIRE_VALID (inf_obj); | |
3a58abaf | 15207 | + |
7566401a ER |
15208 | + |
15209 | + tuple = PyTuple_New (inf_obj->nthreads); | |
15210 | + if (!tuple) | |
3a58abaf AM |
15211 | + return NULL; |
15212 | + | |
7566401a ER |
15213 | + /* The list is in reverse order of thread age (i.e., newest comes first), |
15214 | + is this a problem? */ | |
15215 | + for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads; | |
15216 | + i++, entry = entry->next) | |
3a58abaf | 15217 | + { |
7566401a ER |
15218 | + Py_INCREF (entry->thread_obj); |
15219 | + PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->thread_obj); | |
3a58abaf AM |
15220 | + } |
15221 | + | |
7566401a | 15222 | + return tuple; |
3a58abaf AM |
15223 | +} |
15224 | + | |
7566401a ER |
15225 | +static PyObject * |
15226 | +infpy_get_num (PyObject *self, void *closure) | |
15227 | +{ | |
15228 | + inferior_object *inf = (inferior_object *) self; | |
3a58abaf | 15229 | + |
7566401a ER |
15230 | + INFPY_REQUIRE_VALID (inf); |
15231 | + | |
15232 | + return PyLong_FromLong (inf->inferior->num); | |
15233 | +} | |
15234 | + | |
15235 | +static PyObject * | |
15236 | +infpy_get_pid (PyObject *self, void *closure) | |
3a58abaf | 15237 | +{ |
7566401a | 15238 | + inferior_object *inf = (inferior_object *) self; |
3a58abaf | 15239 | + |
7566401a ER |
15240 | + INFPY_REQUIRE_VALID (inf); |
15241 | + | |
15242 | + return PyLong_FromLong (inf->inferior->pid); | |
15243 | +} | |
15244 | + | |
15245 | +static PyObject * | |
15246 | +infpy_get_was_attached (PyObject *self, void *closure) | |
15247 | +{ | |
15248 | + inferior_object *inf = (inferior_object *) self; | |
15249 | + INFPY_REQUIRE_VALID (inf); | |
15250 | + if (inf->inferior->attach_flag) | |
15251 | + Py_RETURN_TRUE; | |
15252 | + Py_RETURN_FALSE; | |
3a58abaf AM |
15253 | +} |
15254 | + | |
15255 | +\f | |
15256 | + | |
7566401a ER |
15257 | +/* Implementation of gdb.inferiors () -> (gdb.Inferior, ...). |
15258 | + Returns a list of all inferiors. */ | |
3a58abaf | 15259 | + |
7566401a ER |
15260 | +PyObject * |
15261 | +gdbpy_inferiors (PyObject *unused, PyObject *unused2) | |
15262 | +{ | |
15263 | + int i; | |
15264 | + struct inflist_entry *entry; | |
15265 | + PyObject *tuple; | |
3a58abaf | 15266 | + |
7566401a ER |
15267 | + tuple = PyTuple_New (ninferiors); |
15268 | + if (!tuple) | |
15269 | + return NULL; | |
3a58abaf | 15270 | + |
7566401a ER |
15271 | + /* The list is in reverse order of inferior age (i.e., newest comes first), |
15272 | + is this a problem? */ | |
15273 | + for (i = 0, entry = inferior_list; i < ninferiors; i++, entry = entry->next) | |
15274 | + { | |
15275 | + Py_INCREF (entry->inf_obj); | |
15276 | + PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->inf_obj); | |
15277 | + } | |
3a58abaf | 15278 | + |
7566401a ER |
15279 | + return tuple; |
15280 | +} | |
3a58abaf | 15281 | + |
7566401a | 15282 | +\f |
3a58abaf | 15283 | + |
7566401a | 15284 | +/* Membuf and memory manipulation. */ |
3a58abaf | 15285 | + |
7566401a ER |
15286 | +/* Implementation of gdb.read_memory (address, length). |
15287 | + Returns a Python buffer object with LENGTH bytes of the inferior's memory | |
15288 | + at ADDRESS. Both arguments are integers. */ | |
3a58abaf | 15289 | + |
7566401a ER |
15290 | +static PyObject * |
15291 | +infpy_read_memory (PyObject *self, PyObject *args) | |
15292 | +{ | |
15293 | + int error = 0; | |
15294 | + CORE_ADDR addr, length; | |
15295 | + void *buffer = NULL; | |
15296 | + membuf_object *membuf_obj; | |
15297 | + PyObject *addr_obj, *length_obj; | |
15298 | + struct cleanup *cleanups; | |
15299 | + volatile struct gdb_exception except; | |
3a58abaf | 15300 | + |
7566401a ER |
15301 | + if (! PyArg_ParseTuple (args, "OO", &addr_obj, &length_obj)) |
15302 | + return NULL; | |
3a58abaf | 15303 | + |
7566401a | 15304 | + cleanups = make_cleanup (null_cleanup, NULL); |
3a58abaf | 15305 | + |
7566401a | 15306 | + TRY_CATCH (except, RETURN_MASK_ALL) |
3a58abaf | 15307 | + { |
7566401a ER |
15308 | + if (!get_addr_from_python (addr_obj, &addr) |
15309 | + || !get_addr_from_python (length_obj, &length)) | |
3a58abaf | 15310 | + { |
7566401a ER |
15311 | + error = 1; |
15312 | + break; | |
3a58abaf | 15313 | + } |
3a58abaf | 15314 | + |
7566401a ER |
15315 | + buffer = xmalloc (length); |
15316 | + make_cleanup (xfree, buffer); | |
3a58abaf | 15317 | + |
7566401a | 15318 | + read_memory (addr, buffer, length); |
3a58abaf | 15319 | + } |
7566401a | 15320 | + GDB_PY_HANDLE_EXCEPTION (except); |
3a58abaf | 15321 | + |
7566401a | 15322 | + if (error) |
3a58abaf | 15323 | + { |
7566401a ER |
15324 | + do_cleanups (cleanups); |
15325 | + return NULL; | |
3a58abaf AM |
15326 | + } |
15327 | + | |
7566401a ER |
15328 | + membuf_obj = PyObject_New (membuf_object, &membuf_object_type); |
15329 | + if (membuf_obj == NULL) | |
3a58abaf | 15330 | + { |
7566401a ER |
15331 | + PyErr_SetString (PyExc_MemoryError, |
15332 | + "Could not allocate memory buffer object."); | |
15333 | + do_cleanups (cleanups); | |
15334 | + return NULL; | |
3a58abaf AM |
15335 | + } |
15336 | + | |
7566401a ER |
15337 | + discard_cleanups (cleanups); |
15338 | + | |
15339 | + membuf_obj->buffer = buffer; | |
15340 | + membuf_obj->addr = addr; | |
15341 | + membuf_obj->length = length; | |
3a58abaf | 15342 | + |
7566401a ER |
15343 | + return PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0, |
15344 | + Py_END_OF_BUFFER); | |
3a58abaf AM |
15345 | +} |
15346 | + | |
7566401a ER |
15347 | +/* Implementation of gdb.write_memory (address, buffer [, length]). |
15348 | + Writes the contents of BUFFER (a Python object supporting the read buffer | |
15349 | + protocol) at ADDRESS in the inferior's memory. Write LENGTH bytes from | |
15350 | + BUFFER, or its entire contents if the argument is not provided. The | |
15351 | + function returns nothing. */ | |
3a58abaf | 15352 | + |
7566401a ER |
15353 | +static PyObject * |
15354 | +infpy_write_memory (PyObject *self, PyObject *args) | |
3a58abaf | 15355 | +{ |
7566401a ER |
15356 | + int buf_len, error = 0; |
15357 | + const char *buffer; | |
15358 | + CORE_ADDR addr, length; | |
15359 | + PyObject *addr_obj, *length_obj = NULL; | |
15360 | + volatile struct gdb_exception except; | |
3a58abaf | 15361 | + |
7566401a ER |
15362 | + if (! PyArg_ParseTuple (args, "Os#|O", &addr_obj, &buffer, &buf_len, |
15363 | + &length_obj)) | |
15364 | + return NULL; | |
15365 | + | |
15366 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
3a58abaf | 15367 | + { |
7566401a ER |
15368 | + if (!get_addr_from_python (addr_obj, &addr)) |
15369 | + { | |
15370 | + error = 1; | |
15371 | + break; | |
15372 | + } | |
15373 | + | |
15374 | + if (!length_obj) | |
15375 | + length = buf_len; | |
15376 | + else if (!get_addr_from_python (length_obj, &length)) | |
15377 | + { | |
15378 | + error = 1; | |
15379 | + break; | |
15380 | + } | |
15381 | + | |
15382 | + write_memory (addr, buffer, length); | |
3a58abaf | 15383 | + } |
7566401a | 15384 | + GDB_PY_HANDLE_EXCEPTION (except); |
3a58abaf | 15385 | + |
7566401a ER |
15386 | + if (error) |
15387 | + return NULL; | |
15388 | + | |
15389 | + Py_RETURN_NONE; | |
3a58abaf AM |
15390 | +} |
15391 | + | |
7566401a | 15392 | +/* Destructor of Membuf objects. */ |
3a58abaf | 15393 | + |
7566401a ER |
15394 | +static void |
15395 | +mbpy_dealloc (PyObject *self) | |
3a58abaf | 15396 | +{ |
7566401a ER |
15397 | + xfree (((membuf_object *) self)->buffer); |
15398 | + self->ob_type->tp_free (self); | |
3a58abaf AM |
15399 | +} |
15400 | + | |
7566401a | 15401 | +/* Return a description of the Membuf object. */ |
3a58abaf | 15402 | + |
7566401a ER |
15403 | +static PyObject * |
15404 | +mbpy_str (PyObject *self) | |
3a58abaf | 15405 | +{ |
7566401a | 15406 | + membuf_object *membuf_obj = (membuf_object *) self; |
3a58abaf | 15407 | + |
7566401a ER |
15408 | + return PyString_FromFormat ("memory buffer for address %s, %s bytes long", |
15409 | + paddress (python_gdbarch, membuf_obj->addr), | |
15410 | + pulongest (membuf_obj->length)); | |
15411 | +} | |
3a58abaf | 15412 | + |
7566401a ER |
15413 | +static Py_ssize_t |
15414 | +get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr) | |
15415 | +{ | |
15416 | + membuf_object *membuf_obj = (membuf_object *) self; | |
3a58abaf | 15417 | + |
7566401a ER |
15418 | + if (segment) |
15419 | + { | |
15420 | + PyErr_SetString (PyExc_SystemError, | |
15421 | + "The memory buffer supports only one segment."); | |
15422 | + return -1; | |
15423 | + } | |
3a58abaf | 15424 | + |
7566401a | 15425 | + *ptrptr = membuf_obj->buffer; |
3a58abaf | 15426 | + |
7566401a ER |
15427 | + return membuf_obj->length; |
15428 | +} | |
3a58abaf | 15429 | + |
7566401a ER |
15430 | +static Py_ssize_t |
15431 | +get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr) | |
15432 | +{ | |
15433 | + return get_read_buffer (self, segment, ptrptr); | |
15434 | +} | |
3a58abaf | 15435 | + |
7566401a ER |
15436 | +static Py_ssize_t |
15437 | +get_seg_count (PyObject *self, Py_ssize_t *lenp) | |
3a58abaf | 15438 | +{ |
7566401a ER |
15439 | + if (lenp) |
15440 | + *lenp = ((membuf_object *) self)->length; | |
3a58abaf | 15441 | + |
7566401a | 15442 | + return 1; |
3a58abaf | 15443 | +} |
3a58abaf | 15444 | + |
7566401a ER |
15445 | +static Py_ssize_t |
15446 | +get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr) | |
15447 | +{ | |
15448 | + void *ptr = NULL; | |
15449 | + Py_ssize_t ret; | |
3a58abaf | 15450 | + |
7566401a ER |
15451 | + ret = get_read_buffer (self, segment, &ptr); |
15452 | + *ptrptr = (char *) ptr; | |
3a58abaf | 15453 | + |
7566401a ER |
15454 | + return ret; |
15455 | +} | |
3a58abaf | 15456 | + |
7566401a ER |
15457 | +/* Adds GDB value V to the pattern buffer in *PATTERN_BUF. If SIZE is not zero, |
15458 | + it specifies the number of bytes from V to copy to *PATTERN_BUF. The | |
15459 | + function increases the size of *PATTERN_BUF as necessary, adjusting | |
15460 | + *PATTERN_BUF_END and *PATTERN_BUF_SIZE in the process. */ | |
3a58abaf | 15461 | + |
7566401a ER |
15462 | +static void |
15463 | +add_value_pattern (struct value *v, int size, char **pattern_buf, | |
15464 | + char **pattern_buf_end, ULONGEST *pattern_buf_size) | |
15465 | +{ | |
15466 | + int val_bytes; | |
3a58abaf | 15467 | + |
7566401a ER |
15468 | + if (size) |
15469 | + { | |
15470 | + LONGEST x = value_as_long (v); | |
3a58abaf | 15471 | + |
7566401a ER |
15472 | + if (size == 1) |
15473 | + *(*pattern_buf_end)++ = x; | |
15474 | + else | |
15475 | + { | |
15476 | + put_bits (x, *pattern_buf_end, size * 8, | |
15477 | + gdbarch_byte_order (python_gdbarch) == BFD_ENDIAN_BIG); | |
15478 | + *pattern_buf_end += size; | |
15479 | + } | |
15480 | + } | |
15481 | + else | |
15482 | + { | |
15483 | + val_bytes = TYPE_LENGTH (value_type (v)); | |
3a58abaf | 15484 | + |
7566401a ER |
15485 | + increase_pattern_buffer (pattern_buf, pattern_buf_end, |
15486 | + pattern_buf_size, val_bytes); | |
3a58abaf | 15487 | + |
7566401a ER |
15488 | + memcpy (*pattern_buf_end, value_contents_raw (v), val_bytes); |
15489 | + *pattern_buf_end += val_bytes; | |
15490 | + } | |
15491 | +} | |
3a58abaf | 15492 | + |
7566401a ER |
15493 | +/* This function does the actual work of constructing the pattern buffer from |
15494 | + OBJ. If OBJ is an object which implements the read buffer protocol (such | |
15495 | + as a string, a byte array or gdb.Membuf), then its contents are directly | |
15496 | + copied to *PATTERN_BUF. If it is a list, then this function is recursively | |
15497 | + called for each of its elements. If OBJ is an object which can be converted | |
15498 | + to a GDB value, then the contents of the value are copied to PATTERN_BUF. | |
15499 | + If SIZE is different than zero, then it limits the number of bytes which | |
15500 | + are copied to the buffer in case OBJ is converted to a GDB value. That | |
15501 | + means that SIZE influences only Python scalars and gdb.Value objects. | |
15502 | + The function increases the size of *PATTERN_BUF as necessary, adjusting | |
15503 | + *PATTERN_BUF_END and *PATTERN_BUF_SIZE in the process. | |
3a58abaf | 15504 | + |
7566401a ER |
15505 | + Returns 1 on success or 0 on failure, with a Python exception set. This |
15506 | + function can also throw GDB exceptions. */ | |
3a58abaf | 15507 | + |
7566401a ER |
15508 | +static int |
15509 | +add_pattern_element (PyObject *obj, int size, char **pattern_buf, | |
15510 | + char **pattern_buf_end, ULONGEST *pattern_buf_size) | |
15511 | +{ | |
15512 | + if (PyObject_CheckReadBuffer (obj)) | |
15513 | + { | |
15514 | + /* Handle string, Unicode string, byte array, gdb.Membuf and any other | |
15515 | + object implementing the buffer protocol. The SIZE parameter is | |
15516 | + ignored in this case. */ | |
3a58abaf | 15517 | + |
7566401a ER |
15518 | + Py_ssize_t val_bytes; |
15519 | + const void *buffer; | |
3a58abaf | 15520 | + |
7566401a ER |
15521 | + if (PyObject_AsReadBuffer (obj, &buffer, &val_bytes) == -1) |
15522 | + return 0; | |
3a58abaf | 15523 | + |
7566401a ER |
15524 | + increase_pattern_buffer (pattern_buf, pattern_buf_end, |
15525 | + pattern_buf_size, val_bytes); | |
3a58abaf | 15526 | + |
7566401a ER |
15527 | + memcpy (*pattern_buf_end, buffer, val_bytes); |
15528 | + *pattern_buf_end += val_bytes; | |
15529 | + } | |
15530 | + else if (gdbpy_is_value_object (obj)) | |
15531 | + add_value_pattern (value_object_to_value (obj), size, pattern_buf, | |
15532 | + pattern_buf_end, pattern_buf_size); | |
15533 | + else if (PySequence_Check (obj)) | |
15534 | + { | |
15535 | + /* Handle lists and tuples. */ | |
3a58abaf | 15536 | + |
7566401a | 15537 | + Py_ssize_t i, num_objs; |
3a58abaf | 15538 | + |
7566401a ER |
15539 | + num_objs = PySequence_Size (obj); |
15540 | + for (i = 0; i < num_objs; i++) | |
15541 | + if (!add_pattern_element (PySequence_GetItem (obj, i), size, | |
15542 | + pattern_buf, pattern_buf_end, | |
15543 | + pattern_buf_size)) | |
15544 | + return 0; | |
15545 | + } | |
15546 | + else | |
15547 | + { | |
15548 | + /* See if we can convert from a Python object to a GDB value. */ | |
3a58abaf | 15549 | + |
7566401a | 15550 | + struct value *v = convert_value_from_python (obj); |
3a58abaf | 15551 | + |
7566401a ER |
15552 | + if (v) |
15553 | + add_value_pattern (v, size, pattern_buf, pattern_buf_end, | |
15554 | + pattern_buf_size); | |
15555 | + else | |
15556 | + return 0; | |
15557 | + } | |
3a58abaf | 15558 | + |
7566401a ER |
15559 | + return 1; |
15560 | +} | |
3a58abaf | 15561 | + |
7566401a ER |
15562 | +/* Constructs the search pattern from OBJ, putting it in *PATTERN_BUFP, and its |
15563 | + size in *PATTERN_LENP. See the function add_pattern_element to learn how | |
15564 | + the search pattern is obtained from OBJ. | |
3a58abaf | 15565 | + |
7566401a ER |
15566 | + Returns 1 on success or 0 on failure, with a Python exception set. This |
15567 | + function can also throw GDB exceptions. */ | |
3a58abaf | 15568 | + |
7566401a ER |
15569 | +static int |
15570 | +get_search_pattern (PyObject *obj, int size, char **pattern_bufp, | |
15571 | + ULONGEST *pattern_lenp) | |
15572 | +{ | |
15573 | + /* Buffer to hold the search pattern. */ | |
15574 | + char *pattern_buf; | |
15575 | + /* Current size of search pattern buffer. | |
15576 | + We realloc space as needed. */ | |
15577 | + ULONGEST pattern_buf_size; | |
15578 | + /* Pointer to one past the last in-use part of pattern_buf. */ | |
15579 | + char *pattern_buf_end; | |
15580 | + struct cleanup *old_cleanups; | |
3a58abaf | 15581 | + |
7566401a ER |
15582 | + allocate_pattern_buffer (&pattern_buf, &pattern_buf_end, &pattern_buf_size); |
15583 | + old_cleanups = make_cleanup (free_current_contents, &pattern_buf); | |
3a58abaf | 15584 | + |
7566401a ER |
15585 | + if (!add_pattern_element (obj, size, &pattern_buf, &pattern_buf_end, |
15586 | + &pattern_buf_size)) | |
3a58abaf | 15587 | + { |
7566401a ER |
15588 | + do_cleanups (old_cleanups); |
15589 | + | |
15590 | + return 0; | |
3a58abaf AM |
15591 | + } |
15592 | + | |
7566401a ER |
15593 | + *pattern_bufp = pattern_buf; |
15594 | + *pattern_lenp = pattern_buf_end - pattern_buf; | |
3a58abaf | 15595 | + |
7566401a | 15596 | + discard_cleanups (old_cleanups); |
3a58abaf | 15597 | + |
7566401a | 15598 | + return 1; |
3a58abaf AM |
15599 | +} |
15600 | + | |
7566401a ER |
15601 | +/* Implementation of |
15602 | + gdb.search_memory (address, length, pattern [, size] [, max_count]). | |
15603 | + The third argument may be either a pattern, or a list or tupple of patterns | |
15604 | + to be searched. Size is the size in bytes of each search query value, either | |
15605 | + 1, 2, 4 or 8. Returns a list of the addresses where matches were found. */ | |
3a58abaf | 15606 | + |
7566401a ER |
15607 | +static PyObject * |
15608 | +infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw) | |
3a58abaf | 15609 | +{ |
7566401a ER |
15610 | + int size = 0; |
15611 | + unsigned int found_count = 0; | |
15612 | + long max_count = 0; | |
15613 | + CORE_ADDR start_addr, length; | |
15614 | + char *pattern_buf; | |
15615 | + static char *keywords[] = { "address", "length", "pattern", "size", | |
15616 | + "max_count", NULL }; | |
15617 | + ULONGEST pattern_len, search_space_len; | |
15618 | + PyObject *pattern, *list = NULL, *start_addr_obj, *length_obj; | |
3a58abaf AM |
15619 | + volatile struct gdb_exception except; |
15620 | + | |
7566401a ER |
15621 | + if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO|il", keywords, |
15622 | + &start_addr_obj, &length_obj, &pattern, | |
15623 | + &size, &max_count)) | |
3a58abaf AM |
15624 | + return NULL; |
15625 | + | |
7566401a ER |
15626 | + if (!max_count) |
15627 | + max_count = LONG_MAX; | |
3a58abaf | 15628 | + |
7566401a | 15629 | + if (size != 0 && size != 1 && size != 2 && size != 4 && size != 8) |
3a58abaf | 15630 | + { |
7566401a ER |
15631 | + PyErr_SetString (PyExc_ValueError, "invalid pattern size"); |
15632 | + return NULL; | |
3a58abaf | 15633 | + } |
3a58abaf | 15634 | + |
7566401a ER |
15635 | + TRY_CATCH (except, RETURN_MASK_ALL) |
15636 | + { | |
15637 | + if (get_addr_from_python (start_addr_obj, &start_addr) | |
15638 | + && get_addr_from_python (length_obj, &length)) | |
15639 | + { | |
15640 | + if (!length) | |
15641 | + { | |
15642 | + PyErr_SetString (PyExc_ValueError, "empty search range"); | |
15643 | + break; | |
15644 | + } | |
15645 | + /* Watch for overflows. */ | |
15646 | + else if (length > CORE_ADDR_MAX | |
15647 | + || (start_addr + length - 1) < start_addr) | |
15648 | + { | |
15649 | + PyErr_SetString (PyExc_ValueError, "search range too large"); | |
15650 | + break; | |
15651 | + } | |
3a58abaf | 15652 | + |
7566401a | 15653 | + search_space_len = length; |
3a58abaf | 15654 | + |
7566401a ER |
15655 | + if (get_search_pattern (pattern, size, &pattern_buf, &pattern_len)) |
15656 | + { | |
15657 | + /* Any cleanups get automatically executed on an exception. */ | |
15658 | + struct cleanup *cleanups = make_cleanup (xfree, pattern_buf); | |
3a58abaf | 15659 | + |
7566401a | 15660 | + list = PyList_New (0); |
3a58abaf | 15661 | + |
7566401a ER |
15662 | + while (search_space_len >= pattern_len && found_count < max_count) |
15663 | + { | |
15664 | + CORE_ADDR found_addr; | |
15665 | + int found; | |
3a58abaf | 15666 | + |
7566401a ER |
15667 | + found = search_memory (&start_addr, &search_space_len, |
15668 | + pattern_buf, pattern_len, &found_addr); | |
15669 | + if (found <= 0) | |
15670 | + break; | |
3a58abaf | 15671 | + |
7566401a ER |
15672 | + PyList_Append (list, PyLong_FromUnsignedLong (found_addr)); |
15673 | + ++found_count; | |
15674 | + } | |
3a58abaf | 15675 | + |
7566401a ER |
15676 | + do_cleanups (cleanups); |
15677 | + } | |
15678 | + } | |
3a58abaf | 15679 | + } |
7566401a | 15680 | + GDB_PY_HANDLE_EXCEPTION (except); |
3a58abaf | 15681 | + |
7566401a | 15682 | + return list; |
3a58abaf AM |
15683 | +} |
15684 | + | |
7566401a ER |
15685 | +\f |
15686 | + | |
15687 | +void | |
15688 | +gdbpy_initialize_inferior (void) | |
3a58abaf | 15689 | +{ |
7566401a ER |
15690 | + if (PyType_Ready (&inferior_object_type) < 0) |
15691 | + return; | |
15692 | + | |
15693 | + Py_INCREF (&inferior_object_type); | |
15694 | + PyModule_AddObject (gdb_module, "Inferior", | |
15695 | + (PyObject *) &inferior_object_type); | |
15696 | + | |
15697 | + inferior_list = NULL; | |
15698 | + ninferiors = 0; | |
15699 | + | |
15700 | + observer_attach_new_inferior (add_inferior_object); | |
15701 | + observer_attach_inferior_exit (delete_inferior_object); | |
15702 | + observer_attach_new_thread (add_thread_object); | |
15703 | + observer_attach_thread_exit (delete_thread_object); | |
15704 | + | |
15705 | + if (PyType_Ready (&membuf_object_type) < 0) | |
15706 | + return; | |
15707 | + | |
15708 | + Py_INCREF (&membuf_object_type); | |
15709 | + PyModule_AddObject (gdb_module, "Membuf", (PyObject *) &membuf_object_type); | |
3a58abaf AM |
15710 | +} |
15711 | + | |
7566401a ER |
15712 | +\f |
15713 | + | |
15714 | +static PyGetSetDef inferior_object_getset[] = | |
3a58abaf | 15715 | +{ |
7566401a ER |
15716 | + { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL }, |
15717 | + { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.", | |
15718 | + NULL }, | |
15719 | + { "was_attached", infpy_get_was_attached, NULL, | |
15720 | + "True if the inferior was created using 'attach'.", NULL }, | |
3a58abaf | 15721 | + |
7566401a ER |
15722 | + { NULL } |
15723 | +}; | |
3a58abaf | 15724 | + |
7566401a | 15725 | +static PyMethodDef inferior_object_methods[] = |
3a58abaf | 15726 | +{ |
7566401a ER |
15727 | + { "threads", infpy_threads, METH_NOARGS, |
15728 | + "Return all the threads of this inferior." }, | |
3a58abaf | 15729 | + |
7566401a ER |
15730 | + { "read_memory", infpy_read_memory, METH_VARARGS, |
15731 | + "read_memory (address, length) -> buffer\n\ | |
15732 | +Return a buffer object for reading from the inferior's memory." }, | |
15733 | + { "write_memory", infpy_write_memory, METH_VARARGS, | |
15734 | + "write_memory (address, buffer [, length])\n\ | |
15735 | +Write the given buffer object to the inferior's memory." }, | |
15736 | + { "search_memory", (PyCFunction) infpy_search_memory, METH_VARARGS | METH_KEYWORDS, | |
15737 | + "search_memory (address, length, pattern [, size] [, max_count]) -> list\n\ | |
15738 | +Return a list with the addresses where matches were found." }, | |
3a58abaf | 15739 | + |
7566401a ER |
15740 | + { NULL } |
15741 | +}; | |
15742 | + | |
15743 | +static PyTypeObject inferior_object_type = | |
15744 | +{ | |
15745 | + PyObject_HEAD_INIT (NULL) | |
15746 | + 0, /* ob_size */ | |
15747 | + "gdb.Inferior", /* tp_name */ | |
15748 | + sizeof (inferior_object), /* tp_basicsize */ | |
15749 | + 0, /* tp_itemsize */ | |
15750 | + 0, /* tp_dealloc */ | |
15751 | + 0, /* tp_print */ | |
15752 | + 0, /* tp_getattr */ | |
15753 | + 0, /* tp_setattr */ | |
15754 | + 0, /* tp_compare */ | |
15755 | + 0, /* tp_repr */ | |
15756 | + 0, /* tp_as_number */ | |
15757 | + 0, /* tp_as_sequence */ | |
15758 | + 0, /* tp_as_mapping */ | |
15759 | + 0, /* tp_hash */ | |
15760 | + 0, /* tp_call */ | |
15761 | + 0, /* tp_str */ | |
15762 | + 0, /* tp_getattro */ | |
15763 | + 0, /* tp_setattro */ | |
15764 | + 0, /* tp_as_buffer */ | |
15765 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */ | |
15766 | + "GDB inferior object", /* tp_doc */ | |
15767 | + 0, /* tp_traverse */ | |
15768 | + 0, /* tp_clear */ | |
15769 | + 0, /* tp_richcompare */ | |
15770 | + 0, /* tp_weaklistoffset */ | |
15771 | + 0, /* tp_iter */ | |
15772 | + 0, /* tp_iternext */ | |
15773 | + inferior_object_methods, /* tp_methods */ | |
15774 | + 0, /* tp_members */ | |
15775 | + inferior_object_getset, /* tp_getset */ | |
15776 | + 0, /* tp_base */ | |
15777 | + 0, /* tp_dict */ | |
15778 | + 0, /* tp_descr_get */ | |
15779 | + 0, /* tp_descr_set */ | |
15780 | + 0, /* tp_dictoffset */ | |
15781 | + 0, /* tp_init */ | |
15782 | + 0 /* tp_alloc */ | |
15783 | +}; | |
15784 | + | |
15785 | +\f | |
3a58abaf AM |
15786 | + |
15787 | +/* Python doesn't provide a decent way to get compatibility here. */ | |
15788 | +#if HAVE_LIBPYTHON2_4 | |
15789 | +#define CHARBUFFERPROC_NAME getcharbufferproc | |
15790 | +#else | |
15791 | +#define CHARBUFFERPROC_NAME charbufferproc | |
15792 | +#endif | |
15793 | + | |
15794 | +static PyBufferProcs buffer_procs = { | |
15795 | + get_read_buffer, | |
15796 | + get_write_buffer, | |
15797 | + get_seg_count, | |
15798 | + /* The cast here works around a difference between Python 2.4 and | |
15799 | + Python 2.5. */ | |
15800 | + (CHARBUFFERPROC_NAME) get_char_buffer | |
15801 | +}; | |
15802 | + | |
15803 | +static PyTypeObject membuf_object_type = { | |
15804 | + PyObject_HEAD_INIT (NULL) | |
15805 | + 0, /*ob_size*/ | |
15806 | + "gdb.Membuf", /*tp_name*/ | |
15807 | + sizeof (membuf_object), /*tp_basicsize*/ | |
15808 | + 0, /*tp_itemsize*/ | |
15809 | + mbpy_dealloc, /*tp_dealloc*/ | |
15810 | + 0, /*tp_print*/ | |
15811 | + 0, /*tp_getattr*/ | |
15812 | + 0, /*tp_setattr*/ | |
15813 | + 0, /*tp_compare*/ | |
15814 | + 0, /*tp_repr*/ | |
15815 | + 0, /*tp_as_number*/ | |
15816 | + 0, /*tp_as_sequence*/ | |
15817 | + 0, /*tp_as_mapping*/ | |
15818 | + 0, /*tp_hash */ | |
15819 | + 0, /*tp_call*/ | |
15820 | + mbpy_str, /*tp_str*/ | |
15821 | + 0, /*tp_getattro*/ | |
15822 | + 0, /*tp_setattro*/ | |
15823 | + &buffer_procs, /*tp_as_buffer*/ | |
15824 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
15825 | + "GDB memory buffer object", /*tp_doc*/ | |
15826 | + 0, /* tp_traverse */ | |
15827 | + 0, /* tp_clear */ | |
15828 | + 0, /* tp_richcompare */ | |
15829 | + 0, /* tp_weaklistoffset */ | |
15830 | + 0, /* tp_iter */ | |
15831 | + 0, /* tp_iternext */ | |
15832 | + 0, /* tp_methods */ | |
15833 | + 0, /* tp_members */ | |
15834 | + 0, /* tp_getset */ | |
15835 | + 0, /* tp_base */ | |
15836 | + 0, /* tp_dict */ | |
15837 | + 0, /* tp_descr_get */ | |
15838 | + 0, /* tp_descr_set */ | |
15839 | + 0, /* tp_dictoffset */ | |
15840 | + 0, /* tp_init */ | |
15841 | + 0, /* tp_alloc */ | |
15842 | + PyType_GenericNew /* tp_new */ | |
15843 | +}; | |
7566401a | 15844 | diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c |
3a58abaf | 15845 | new file mode 100644 |
7566401a | 15846 | index 0000000..21e4eab |
3a58abaf | 15847 | --- /dev/null |
7566401a ER |
15848 | +++ b/gdb/python/py-infthread.c |
15849 | @@ -0,0 +1,285 @@ | |
15850 | +/* Python interface to inferior threads. | |
3a58abaf | 15851 | + |
7566401a | 15852 | + Copyright (C) 2009 Free Software Foundation, Inc. |
3a58abaf AM |
15853 | + |
15854 | + This file is part of GDB. | |
15855 | + | |
15856 | + This program is free software; you can redistribute it and/or modify | |
15857 | + it under the terms of the GNU General Public License as published by | |
15858 | + the Free Software Foundation; either version 3 of the License, or | |
15859 | + (at your option) any later version. | |
15860 | + | |
15861 | + This program is distributed in the hope that it will be useful, | |
15862 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15863 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15864 | + GNU General Public License for more details. | |
15865 | + | |
15866 | + You should have received a copy of the GNU General Public License | |
15867 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
15868 | + | |
15869 | +#include "defs.h" | |
7566401a ER |
15870 | +#include "exceptions.h" |
15871 | +#include "gdbthread.h" | |
15872 | +#include "inferior.h" | |
3a58abaf | 15873 | +#include "python-internal.h" |
3a58abaf | 15874 | + |
7566401a ER |
15875 | +static PyTypeObject thread_object_type; |
15876 | + | |
15877 | +/* Require that INFERIOR be a valid inferior ID. */ | |
15878 | +#define THPY_REQUIRE_VALID(Thread) \ | |
15879 | + do { \ | |
15880 | + if (!Thread->thread) \ | |
15881 | + { \ | |
15882 | + PyErr_SetString (PyExc_RuntimeError, \ | |
15883 | + "thread no longer exists"); \ | |
15884 | + return NULL; \ | |
15885 | + } \ | |
15886 | + } while (0) | |
3a58abaf | 15887 | + |
7566401a | 15888 | +\f |
3a58abaf | 15889 | + |
7566401a ER |
15890 | +thread_object * |
15891 | +create_thread_object (struct thread_info *tp) | |
15892 | +{ | |
15893 | + thread_object *thread_obj; | |
15894 | + | |
15895 | + thread_obj = PyObject_New (thread_object, &thread_object_type); | |
15896 | + if (!thread_obj) | |
15897 | + return NULL; | |
3a58abaf | 15898 | + |
7566401a ER |
15899 | + thread_obj->thread = tp; |
15900 | + thread_obj->inf_obj = find_inferior_object (PIDGET (tp->ptid)); | |
15901 | + Py_INCREF (thread_obj->inf_obj); | |
3a58abaf | 15902 | + |
7566401a ER |
15903 | + return thread_obj; |
15904 | +} | |
3a58abaf AM |
15905 | + |
15906 | +\f | |
15907 | + | |
3a58abaf | 15908 | +static void |
7566401a | 15909 | +thpy_dealloc (PyObject *self) |
3a58abaf | 15910 | +{ |
7566401a ER |
15911 | + Py_DECREF (((thread_object *) self)->inf_obj); |
15912 | + self->ob_type->tp_free (self); | |
3a58abaf AM |
15913 | +} |
15914 | + | |
15915 | +static PyObject * | |
7566401a | 15916 | +thpy_get_num (PyObject *self, void *closure) |
3a58abaf | 15917 | +{ |
7566401a | 15918 | + thread_object *thread_obj = (thread_object *) self; |
3a58abaf | 15919 | + |
7566401a ER |
15920 | + THPY_REQUIRE_VALID (thread_obj); |
15921 | + | |
15922 | + return PyLong_FromLong (thread_obj->thread->num); | |
3a58abaf AM |
15923 | +} |
15924 | + | |
7566401a ER |
15925 | +\f |
15926 | + | |
15927 | +/* Implementation of Inferior.frames () -> (gdb.Frame, ...). | |
15928 | + Returns a tuple of all frame objects. */ | |
3a58abaf | 15929 | +PyObject * |
7566401a | 15930 | +thpy_frames (PyObject *self, PyObject *args) |
3a58abaf | 15931 | +{ |
7566401a ER |
15932 | + int result = 0; |
15933 | + struct frame_info *frame; | |
15934 | + PyObject *frame_obj; | |
15935 | + PyObject *list, *tuple; | |
15936 | + thread_object *thread_obj = (thread_object *) self; | |
15937 | + struct cleanup *cleanup; | |
15938 | + volatile struct gdb_exception except; | |
3a58abaf | 15939 | + |
7566401a | 15940 | + THPY_REQUIRE_VALID (thread_obj); |
3a58abaf | 15941 | + |
7566401a ER |
15942 | + list = PyList_New (0); |
15943 | + if (list == NULL) | |
3a58abaf | 15944 | + { |
7566401a ER |
15945 | + PyErr_SetString (PyExc_MemoryError, "Could not allocate frames list."); |
15946 | + return NULL; | |
3a58abaf AM |
15947 | + } |
15948 | + | |
7566401a | 15949 | + cleanup = make_cleanup_restore_current_thread (); |
3a58abaf | 15950 | + |
7566401a | 15951 | + TRY_CATCH (except, RETURN_MASK_ALL) |
3a58abaf | 15952 | + { |
7566401a | 15953 | + switch_to_thread (thread_obj->thread->ptid); |
3a58abaf | 15954 | + |
7566401a ER |
15955 | + for (frame = get_current_frame (); frame; frame = get_prev_frame (frame)) |
15956 | + { | |
15957 | + frame_obj = frame_info_to_frame_object (frame); | |
15958 | + if (frame_obj == NULL) | |
3a58abaf | 15959 | + { |
7566401a ER |
15960 | + Py_DECREF (list); |
15961 | + list = NULL; | |
15962 | + break; | |
3a58abaf AM |
15963 | + } |
15964 | + | |
7566401a | 15965 | + PyList_Append (list, frame_obj); |
3a58abaf AM |
15966 | + } |
15967 | + } | |
7566401a ER |
15968 | + if (except.reason < 0) |
15969 | + { | |
15970 | + Py_DECREF (list); | |
15971 | + return PyErr_Format (except.reason == RETURN_QUIT | |
15972 | + ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, | |
15973 | + "%s", except.message); | |
15974 | + } | |
3a58abaf | 15975 | + |
7566401a | 15976 | + do_cleanups (cleanup); |
3a58abaf | 15977 | + |
7566401a ER |
15978 | + if (list) |
15979 | + { | |
15980 | + tuple = PyList_AsTuple (list); | |
15981 | + Py_DECREF (list); | |
15982 | + } | |
15983 | + else | |
15984 | + tuple = NULL; | |
15985 | + | |
15986 | + return tuple; | |
15987 | +} | |
15988 | + | |
15989 | +/* Implementation of InferiorThread.newest_frame () -> gdb.Frame. | |
15990 | + Returns the newest frame object. */ | |
15991 | +PyObject * | |
15992 | +thpy_newest_frame (PyObject *self, PyObject *args) | |
15993 | +{ | |
15994 | + struct frame_info *frame; | |
15995 | + PyObject *frame_obj = NULL; /* Initialize to appease gcc warning. */ | |
15996 | + thread_object *thread_obj = (thread_object *) self; | |
15997 | + struct cleanup *cleanup; | |
15998 | + volatile struct gdb_exception except; | |
15999 | + | |
16000 | + THPY_REQUIRE_VALID (thread_obj); | |
16001 | + | |
16002 | + cleanup = make_cleanup_restore_current_thread (); | |
16003 | + | |
16004 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
16005 | + { | |
16006 | + switch_to_thread (thread_obj->thread->ptid); | |
16007 | + | |
16008 | + frame = get_current_frame (); | |
16009 | + frame_obj = frame_info_to_frame_object (frame); | |
16010 | + } | |
16011 | + GDB_PY_HANDLE_EXCEPTION (except); | |
16012 | + | |
16013 | + do_cleanups (cleanup); | |
16014 | + | |
16015 | + return frame_obj; | |
16016 | +} | |
16017 | + | |
16018 | +/* Implementation of InferiorThread.switch (). | |
16019 | + Makes this the GDB selected thread. */ | |
16020 | +static PyObject * | |
16021 | +thpy_switch (PyObject *self, PyObject *args) | |
16022 | +{ | |
16023 | + thread_object *thread_obj = (thread_object *) self; | |
16024 | + struct cleanup *cleanup; | |
16025 | + volatile struct gdb_exception except; | |
16026 | + | |
16027 | + THPY_REQUIRE_VALID (thread_obj); | |
16028 | + | |
16029 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
16030 | + { | |
16031 | + switch_to_thread (thread_obj->thread->ptid); | |
16032 | + } | |
16033 | + GDB_PY_HANDLE_EXCEPTION (except); | |
16034 | + | |
16035 | + Py_RETURN_NONE; | |
16036 | +} | |
16037 | + | |
16038 | +\f | |
16039 | + | |
16040 | +/* Implementation of gdb.selected_thread () -> gdb.InferiorThread. | |
16041 | + Returns the selected thread object. */ | |
16042 | +PyObject * | |
16043 | +gdbpy_selected_thread (PyObject *self, PyObject *args) | |
3a58abaf | 16044 | +{ |
7566401a ER |
16045 | + PyObject *thread_obj; |
16046 | + | |
16047 | + thread_obj = (PyObject *) find_thread_object (inferior_ptid); | |
16048 | + if (thread_obj) | |
16049 | + { | |
16050 | + Py_INCREF (thread_obj); | |
16051 | + return thread_obj; | |
16052 | + } | |
16053 | + | |
16054 | + Py_RETURN_NONE; | |
16055 | +} | |
16056 | + | |
16057 | +\f | |
3a58abaf | 16058 | + |
7566401a ER |
16059 | +void |
16060 | +gdbpy_initialize_thread (void) | |
16061 | +{ | |
16062 | + if (PyType_Ready (&thread_object_type) < 0) | |
3a58abaf AM |
16063 | + return; |
16064 | + | |
7566401a ER |
16065 | + Py_INCREF (&thread_object_type); |
16066 | + PyModule_AddObject (gdb_module, "InferiorThread", | |
16067 | + (PyObject *) &thread_object_type); | |
3a58abaf AM |
16068 | +} |
16069 | + | |
16070 | +\f | |
16071 | + | |
7566401a ER |
16072 | +static PyGetSetDef thread_object_getset[] = |
16073 | +{ | |
16074 | + { "num", thpy_get_num, NULL, "ID of the thread, as assigned by GDB.", NULL }, | |
16075 | + | |
16076 | + { NULL } | |
16077 | +}; | |
16078 | + | |
16079 | +static PyMethodDef thread_object_methods[] = | |
3a58abaf | 16080 | +{ |
7566401a ER |
16081 | + { "frames", thpy_frames, METH_NOARGS, |
16082 | + "frames () -> (gdb.Frame, ...)\n\ | |
16083 | +Return a tuple containing all frames in the thread." }, | |
16084 | + { "newest_frame", thpy_newest_frame, METH_NOARGS, | |
16085 | + "newest_frame () -> gdb.Frame\n\ | |
16086 | +Return the newest frame in the thread." }, | |
16087 | + { "switch", thpy_switch, METH_NOARGS, | |
16088 | + "switch ()\n\ | |
16089 | +Makes this the GDB selected thread." }, | |
16090 | + | |
3a58abaf AM |
16091 | + { NULL } |
16092 | +}; | |
16093 | + | |
7566401a | 16094 | +static PyTypeObject thread_object_type = |
3a58abaf AM |
16095 | +{ |
16096 | + PyObject_HEAD_INIT (NULL) | |
16097 | + 0, /*ob_size*/ | |
7566401a ER |
16098 | + "gdb.InferiorThread", /*tp_name*/ |
16099 | + sizeof (thread_object), /*tp_basicsize*/ | |
3a58abaf | 16100 | + 0, /*tp_itemsize*/ |
7566401a | 16101 | + thpy_dealloc, /*tp_dealloc*/ |
3a58abaf AM |
16102 | + 0, /*tp_print*/ |
16103 | + 0, /*tp_getattr*/ | |
16104 | + 0, /*tp_setattr*/ | |
16105 | + 0, /*tp_compare*/ | |
16106 | + 0, /*tp_repr*/ | |
16107 | + 0, /*tp_as_number*/ | |
16108 | + 0, /*tp_as_sequence*/ | |
16109 | + 0, /*tp_as_mapping*/ | |
16110 | + 0, /*tp_hash */ | |
16111 | + 0, /*tp_call*/ | |
16112 | + 0, /*tp_str*/ | |
16113 | + 0, /*tp_getattro*/ | |
16114 | + 0, /*tp_setattro*/ | |
16115 | + 0, /*tp_as_buffer*/ | |
7566401a ER |
16116 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ |
16117 | + "GDB thread object", /* tp_doc */ | |
3a58abaf AM |
16118 | + 0, /* tp_traverse */ |
16119 | + 0, /* tp_clear */ | |
16120 | + 0, /* tp_richcompare */ | |
16121 | + 0, /* tp_weaklistoffset */ | |
16122 | + 0, /* tp_iter */ | |
16123 | + 0, /* tp_iternext */ | |
7566401a | 16124 | + thread_object_methods, /* tp_methods */ |
3a58abaf | 16125 | + 0, /* tp_members */ |
7566401a | 16126 | + thread_object_getset, /* tp_getset */ |
3a58abaf AM |
16127 | + 0, /* tp_base */ |
16128 | + 0, /* tp_dict */ | |
16129 | + 0, /* tp_descr_get */ | |
16130 | + 0, /* tp_descr_set */ | |
16131 | + 0, /* tp_dictoffset */ | |
16132 | + 0, /* tp_init */ | |
7566401a | 16133 | + 0 /* tp_alloc */ |
3a58abaf | 16134 | +}; |
7566401a | 16135 | diff --git a/gdb/python/py-membuf.c b/gdb/python/py-membuf.c |
3a58abaf | 16136 | new file mode 100644 |
7566401a | 16137 | index 0000000..7bc294c |
3a58abaf | 16138 | --- /dev/null |
7566401a ER |
16139 | +++ b/gdb/python/py-membuf.c |
16140 | @@ -0,0 +1,268 @@ | |
16141 | +/* Python interface to the inferior memory. | |
3a58abaf AM |
16142 | + |
16143 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
16144 | + | |
16145 | + This file is part of GDB. | |
16146 | + | |
16147 | + This program is free software; you can redistribute it and/or modify | |
16148 | + it under the terms of the GNU General Public License as published by | |
16149 | + the Free Software Foundation; either version 3 of the License, or | |
16150 | + (at your option) any later version. | |
16151 | + | |
16152 | + This program is distributed in the hope that it will be useful, | |
16153 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16154 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16155 | + GNU General Public License for more details. | |
16156 | + | |
16157 | + You should have received a copy of the GNU General Public License | |
16158 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
16159 | + | |
3a58abaf | 16160 | +#include "defs.h" |
3a58abaf | 16161 | +#include "exceptions.h" |
7566401a | 16162 | +#include "gdbcore.h" |
3a58abaf | 16163 | +#include "python-internal.h" |
3a58abaf | 16164 | + |
7566401a ER |
16165 | +typedef struct { |
16166 | + PyObject_HEAD | |
16167 | + void *buffer; | |
3a58abaf | 16168 | + |
7566401a ER |
16169 | + /* These are kept just for mbpy_str. */ |
16170 | + CORE_ADDR addr; | |
16171 | + CORE_ADDR length; | |
16172 | +} membuf_object; | |
3a58abaf | 16173 | + |
7566401a | 16174 | +static PyTypeObject membuf_object_type; |
3a58abaf | 16175 | + |
7566401a ER |
16176 | +/* Implementation of gdb.read_memory (address, length). |
16177 | + Returns a Python buffer object with LENGTH bytes of the inferior's memory | |
16178 | + at ADDRESS. Both arguments are integers. */ | |
3a58abaf | 16179 | + |
7566401a ER |
16180 | +PyObject * |
16181 | +gdbpy_read_memory (PyObject *self, PyObject *args) | |
3a58abaf | 16182 | +{ |
7566401a ER |
16183 | + int error = 0; |
16184 | + CORE_ADDR addr, length; | |
16185 | + void *buffer = NULL; | |
16186 | + membuf_object *membuf_obj; | |
16187 | + PyObject *addr_obj, *length_obj; | |
16188 | + struct cleanup *cleanups = NULL; | |
16189 | + volatile struct gdb_exception except; | |
3a58abaf | 16190 | + |
7566401a ER |
16191 | + if (! PyArg_ParseTuple (args, "OO", &addr_obj, &length_obj)) |
16192 | + return NULL; | |
3a58abaf | 16193 | + |
7566401a ER |
16194 | + TRY_CATCH (except, RETURN_MASK_ALL) |
16195 | + { | |
16196 | + if (!get_addr_from_python (addr_obj, &addr) | |
16197 | + || !get_addr_from_python (length_obj, &length)) | |
16198 | + { | |
16199 | + error = 1; | |
16200 | + break; | |
16201 | + } | |
3a58abaf | 16202 | + |
7566401a ER |
16203 | + buffer = xmalloc (length); |
16204 | + cleanups = make_cleanup (xfree, buffer); | |
3a58abaf | 16205 | + |
7566401a ER |
16206 | + read_memory (addr, buffer, length); |
16207 | + } | |
16208 | + GDB_PY_HANDLE_EXCEPTION (except); | |
3a58abaf | 16209 | + |
7566401a ER |
16210 | + if (error) |
16211 | + return NULL; | |
3a58abaf | 16212 | + |
7566401a | 16213 | + discard_cleanups (cleanups); |
3a58abaf | 16214 | + |
7566401a ER |
16215 | + membuf_obj = PyObject_New (membuf_object, &membuf_object_type); |
16216 | + if (membuf_obj == NULL) | |
3a58abaf | 16217 | + { |
7566401a ER |
16218 | + xfree (buffer); |
16219 | + PyErr_SetString (PyExc_MemoryError, | |
16220 | + "Could not allocate memory buffer object."); | |
16221 | + return NULL; | |
3a58abaf AM |
16222 | + } |
16223 | + | |
7566401a ER |
16224 | + membuf_obj->buffer = buffer; |
16225 | + membuf_obj->addr = addr; | |
16226 | + membuf_obj->length = length; | |
16227 | + | |
16228 | + return PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0, | |
16229 | + Py_END_OF_BUFFER); | |
3a58abaf AM |
16230 | +} |
16231 | + | |
7566401a ER |
16232 | +/* Implementation of gdb.write_memory (address, buffer [, length]). |
16233 | + Writes the contents of BUFFER (a Python object supporting the read buffer | |
16234 | + protocol) at ADDRESS in the inferior's memory. Write LENGTH bytes from | |
16235 | + BUFFER, or its entire contents if the argument is not provided. The | |
16236 | + function returns nothing. */ | |
16237 | + | |
16238 | +PyObject * | |
16239 | +gdbpy_write_memory (PyObject *self, PyObject *args) | |
3a58abaf | 16240 | +{ |
7566401a ER |
16241 | + int buf_len, error = 0; |
16242 | + const char *buffer; | |
16243 | + CORE_ADDR addr, length; | |
16244 | + PyObject *addr_obj, *length_obj = NULL; | |
16245 | + volatile struct gdb_exception except; | |
3a58abaf | 16246 | + |
7566401a ER |
16247 | + if (! PyArg_ParseTuple (args, "Os#|O", &addr_obj, &buffer, &buf_len, |
16248 | + &length_obj)) | |
16249 | + return NULL; | |
16250 | + | |
16251 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
3a58abaf | 16252 | + { |
7566401a | 16253 | + if (!get_addr_from_python (addr_obj, &addr)) |
3a58abaf | 16254 | + { |
7566401a ER |
16255 | + error = 1; |
16256 | + break; | |
3a58abaf | 16257 | + } |
7566401a ER |
16258 | + |
16259 | + if (!length_obj) | |
16260 | + length = buf_len; | |
16261 | + else if (!get_addr_from_python (length_obj, &length)) | |
3a58abaf | 16262 | + { |
7566401a ER |
16263 | + error = 1; |
16264 | + break; | |
3a58abaf | 16265 | + } |
3a58abaf | 16266 | + |
7566401a ER |
16267 | + write_memory (addr, buffer, length); |
16268 | + } | |
16269 | + GDB_PY_HANDLE_EXCEPTION (except); | |
3a58abaf | 16270 | + |
7566401a ER |
16271 | + if (error) |
16272 | + return NULL; | |
3a58abaf | 16273 | + |
7566401a ER |
16274 | + Py_RETURN_NONE; |
16275 | +} | |
3a58abaf | 16276 | + |
7566401a | 16277 | +/* Destructor of Membuf objects. */ |
3a58abaf | 16278 | + |
7566401a ER |
16279 | +static void |
16280 | +mbpy_dealloc (PyObject *self) | |
16281 | +{ | |
16282 | + xfree (((membuf_object *) self)->buffer); | |
16283 | + self->ob_type->tp_free (self); | |
16284 | +} | |
3a58abaf | 16285 | + |
7566401a | 16286 | +/* Return a description of the Membuf object. */ |
3a58abaf | 16287 | + |
7566401a ER |
16288 | +static PyObject * |
16289 | +mbpy_str (PyObject *self) | |
16290 | +{ | |
16291 | + membuf_object *membuf_obj = (membuf_object *) self; | |
3a58abaf | 16292 | + |
7566401a ER |
16293 | + return PyString_FromFormat ("memory buffer for address %s, %s bytes long", |
16294 | + paddress (membuf_obj->addr), | |
16295 | + pulongest (membuf_obj->length)); | |
16296 | +} | |
3a58abaf | 16297 | + |
7566401a ER |
16298 | +static Py_ssize_t |
16299 | +get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr) | |
16300 | +{ | |
16301 | + membuf_object *membuf_obj = (membuf_object *) self; | |
3a58abaf | 16302 | + |
7566401a ER |
16303 | + if (segment) |
16304 | + { | |
16305 | + PyErr_SetString (PyExc_SystemError, | |
16306 | + "The memory buffer supports only one segment."); | |
3a58abaf AM |
16307 | + return -1; |
16308 | + } | |
16309 | + | |
7566401a ER |
16310 | + *ptrptr = membuf_obj->buffer; |
16311 | + | |
16312 | + return membuf_obj->length; | |
3a58abaf AM |
16313 | +} |
16314 | + | |
7566401a ER |
16315 | +static Py_ssize_t |
16316 | +get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr) | |
3a58abaf | 16317 | +{ |
7566401a | 16318 | + return get_read_buffer (self, segment, ptrptr); |
3a58abaf AM |
16319 | +} |
16320 | + | |
7566401a ER |
16321 | +static Py_ssize_t |
16322 | +get_seg_count (PyObject *self, Py_ssize_t *lenp) | |
3a58abaf | 16323 | +{ |
7566401a ER |
16324 | + if (lenp) |
16325 | + *lenp = ((membuf_object *) self)->length; | |
3a58abaf | 16326 | + |
7566401a | 16327 | + return 1; |
3a58abaf AM |
16328 | +} |
16329 | + | |
7566401a ER |
16330 | +static Py_ssize_t |
16331 | +get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr) | |
3a58abaf | 16332 | +{ |
7566401a ER |
16333 | + void *ptr = NULL; |
16334 | + Py_ssize_t ret; | |
3a58abaf | 16335 | + |
7566401a ER |
16336 | + ret = get_read_buffer (self, segment, &ptr); |
16337 | + *ptrptr = (char *) ptr; | |
3a58abaf | 16338 | + |
7566401a ER |
16339 | + return ret; |
16340 | +} | |
3a58abaf | 16341 | + |
7566401a ER |
16342 | +/* Python doesn't provide a decent way to get compatibility here. */ |
16343 | +#if HAVE_LIBPYTHON2_4 | |
16344 | +#define CHARBUFFERPROC_NAME getcharbufferproc | |
16345 | +#else | |
16346 | +#define CHARBUFFERPROC_NAME charbufferproc | |
16347 | +#endif | |
3a58abaf | 16348 | + |
7566401a ER |
16349 | +static PyBufferProcs buffer_procs = { |
16350 | + get_read_buffer, | |
16351 | + get_write_buffer, | |
16352 | + get_seg_count, | |
16353 | + /* The cast here works around a difference between Python 2.4 and | |
16354 | + Python 2.5. */ | |
16355 | + (CHARBUFFERPROC_NAME) get_char_buffer | |
16356 | +}; | |
3a58abaf | 16357 | + |
7566401a | 16358 | +static PyTypeObject membuf_object_type = { |
3a58abaf AM |
16359 | + PyObject_HEAD_INIT (NULL) |
16360 | + 0, /*ob_size*/ | |
7566401a ER |
16361 | + "gdb.Membuf", /*tp_name*/ |
16362 | + sizeof (membuf_object), /*tp_basicsize*/ | |
3a58abaf | 16363 | + 0, /*tp_itemsize*/ |
7566401a | 16364 | + mbpy_dealloc, /*tp_dealloc*/ |
3a58abaf AM |
16365 | + 0, /*tp_print*/ |
16366 | + 0, /*tp_getattr*/ | |
16367 | + 0, /*tp_setattr*/ | |
16368 | + 0, /*tp_compare*/ | |
16369 | + 0, /*tp_repr*/ | |
16370 | + 0, /*tp_as_number*/ | |
16371 | + 0, /*tp_as_sequence*/ | |
16372 | + 0, /*tp_as_mapping*/ | |
16373 | + 0, /*tp_hash */ | |
16374 | + 0, /*tp_call*/ | |
7566401a ER |
16375 | + mbpy_str, /*tp_str*/ |
16376 | + 0, /*tp_getattro*/ | |
16377 | + 0, /*tp_setattro*/ | |
16378 | + &buffer_procs, /*tp_as_buffer*/ | |
16379 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
16380 | + "GDB memory buffer object", /*tp_doc*/ | |
3a58abaf AM |
16381 | + 0, /* tp_traverse */ |
16382 | + 0, /* tp_clear */ | |
16383 | + 0, /* tp_richcompare */ | |
16384 | + 0, /* tp_weaklistoffset */ | |
16385 | + 0, /* tp_iter */ | |
16386 | + 0, /* tp_iternext */ | |
16387 | + 0, /* tp_methods */ | |
16388 | + 0, /* tp_members */ | |
16389 | + 0, /* tp_getset */ | |
16390 | + 0, /* tp_base */ | |
16391 | + 0, /* tp_dict */ | |
16392 | + 0, /* tp_descr_get */ | |
16393 | + 0, /* tp_descr_set */ | |
16394 | + 0, /* tp_dictoffset */ | |
7566401a | 16395 | + 0, /* tp_init */ |
3a58abaf AM |
16396 | + 0, /* tp_alloc */ |
16397 | + PyType_GenericNew /* tp_new */ | |
16398 | +}; | |
7566401a ER |
16399 | + |
16400 | +void | |
16401 | +gdbpy_initialize_membuf (void) | |
16402 | +{ | |
16403 | + if (PyType_Ready (&membuf_object_type) < 0) | |
16404 | + return; | |
16405 | + | |
16406 | + Py_INCREF (&membuf_object_type); | |
16407 | + PyModule_AddObject (gdb_module, "Membuf", (PyObject *) &membuf_object_type); | |
16408 | +} | |
16409 | diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c | |
3a58abaf | 16410 | new file mode 100644 |
7566401a | 16411 | index 0000000..1f591a8 |
3a58abaf | 16412 | --- /dev/null |
7566401a ER |
16413 | +++ b/gdb/python/py-param.c |
16414 | @@ -0,0 +1,606 @@ | |
16415 | +/* gdb parameters implemented in Python | |
3a58abaf | 16416 | + |
7566401a | 16417 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. |
3a58abaf AM |
16418 | + |
16419 | + This file is part of GDB. | |
16420 | + | |
16421 | + This program is free software; you can redistribute it and/or modify | |
16422 | + it under the terms of the GNU General Public License as published by | |
16423 | + the Free Software Foundation; either version 3 of the License, or | |
16424 | + (at your option) any later version. | |
16425 | + | |
16426 | + This program is distributed in the hope that it will be useful, | |
16427 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16428 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16429 | + GNU General Public License for more details. | |
16430 | + | |
16431 | + You should have received a copy of the GNU General Public License | |
16432 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
16433 | + | |
7566401a | 16434 | + |
3a58abaf | 16435 | +#include "defs.h" |
7566401a | 16436 | +#include "value.h" |
3a58abaf | 16437 | +#include "exceptions.h" |
3a58abaf | 16438 | +#include "python-internal.h" |
7566401a ER |
16439 | +#include "charset.h" |
16440 | +#include "gdbcmd.h" | |
16441 | +#include "cli/cli-decode.h" | |
16442 | +#include "completer.h" | |
3a58abaf | 16443 | + |
7566401a ER |
16444 | +/* Parameter constants and their values. */ |
16445 | +struct parm_constant | |
16446 | +{ | |
16447 | + char *name; | |
16448 | + int value; | |
16449 | +}; | |
3a58abaf | 16450 | + |
7566401a | 16451 | +struct parm_constant parm_constants[] = |
3a58abaf | 16452 | +{ |
7566401a ER |
16453 | + { "PARAM_BOOLEAN", var_boolean }, |
16454 | + { "PARAM_AUTO_BOOLEAN", var_auto_boolean }, | |
16455 | + { "PARAM_UINTEGER", var_uinteger }, | |
16456 | + { "PARAM_INTEGER", var_integer }, | |
16457 | + { "PARAM_STRING", var_string }, | |
16458 | + { "PARAM_STRING_NOESCAPE", var_string_noescape }, | |
16459 | + { "PARAM_OPTIONAL_FILENAME", var_optional_filename }, | |
16460 | + { "PARAM_FILENAME", var_filename }, | |
16461 | + { "PARAM_ZINTEGER", var_zinteger }, | |
16462 | + { "PARAM_ENUM", var_enum }, | |
16463 | + { NULL, 0 } | |
16464 | +}; | |
3a58abaf | 16465 | + |
7566401a ER |
16466 | +/* A union that can hold anything described by enum var_types. */ |
16467 | +union parmpy_variable | |
16468 | +{ | |
16469 | + /* Hold an integer value, for boolean and integer types. */ | |
16470 | + int intval; | |
3a58abaf | 16471 | + |
7566401a ER |
16472 | + /* Hold an auto_boolean. */ |
16473 | + enum auto_boolean autoboolval; | |
3a58abaf | 16474 | + |
7566401a ER |
16475 | + /* Hold an unsigned integer value, for uinteger. */ |
16476 | + unsigned int uintval; | |
3a58abaf | 16477 | + |
7566401a ER |
16478 | + /* Hold a string, for the various string types. */ |
16479 | + char *stringval; | |
16480 | + | |
16481 | + /* Hold a string, for enums. */ | |
16482 | + const char *cstringval; | |
16483 | +}; | |
16484 | + | |
16485 | +/* A gdb parameter. */ | |
16486 | +struct parmpy_object | |
3a58abaf | 16487 | +{ |
7566401a | 16488 | + PyObject_HEAD |
3a58abaf | 16489 | + |
7566401a ER |
16490 | + /* The type of the parameter. */ |
16491 | + enum var_types type; | |
3a58abaf | 16492 | + |
7566401a ER |
16493 | + /* The value of the parameter. */ |
16494 | + union parmpy_variable value; | |
3a58abaf | 16495 | + |
7566401a ER |
16496 | + /* For an enum command, the possible values. The vector is |
16497 | + allocated with xmalloc, as is each element. It is | |
16498 | + NULL-terminated. */ | |
16499 | + const char **enumeration; | |
16500 | +}; | |
3a58abaf | 16501 | + |
7566401a | 16502 | +typedef struct parmpy_object parmpy_object; |
3a58abaf | 16503 | + |
7566401a | 16504 | +static PyTypeObject parmpy_object_type; |
3a58abaf | 16505 | + |
7566401a ER |
16506 | +/* Some handy string constants. */ |
16507 | +static PyObject *set_doc_cst; | |
16508 | +static PyObject *show_doc_cst; | |
3a58abaf | 16509 | + |
7566401a ER |
16510 | +\f |
16511 | + | |
16512 | +/* Get an attribute. */ | |
3a58abaf | 16513 | +static PyObject * |
7566401a | 16514 | +get_attr (PyObject *obj, PyObject *attr_name) |
3a58abaf | 16515 | +{ |
7566401a ER |
16516 | + if (PyString_Check (attr_name) |
16517 | + && ! strcmp (PyString_AsString (attr_name), "value")) | |
16518 | + { | |
16519 | + parmpy_object *self = (parmpy_object *) obj; | |
16520 | + return gdbpy_parameter_value (self->type, &self->value); | |
16521 | + } | |
3a58abaf | 16522 | + |
7566401a | 16523 | + return PyObject_GenericGetAttr (obj, attr_name); |
3a58abaf AM |
16524 | +} |
16525 | + | |
7566401a ER |
16526 | +/* Set a parameter value from a Python value. Return 0 on success, -1 |
16527 | + on failure. */ | |
16528 | +static int | |
16529 | +set_parameter_value (parmpy_object *self, PyObject *value) | |
3a58abaf | 16530 | +{ |
7566401a | 16531 | + int cmp; |
3a58abaf | 16532 | + |
7566401a ER |
16533 | + switch (self->type) |
16534 | + { | |
16535 | + case var_string: | |
16536 | + case var_string_noescape: | |
16537 | + case var_optional_filename: | |
16538 | + case var_filename: | |
16539 | + if (! gdbpy_is_string (value) | |
16540 | + && (self->type == var_filename | |
16541 | + || value != Py_None)) | |
16542 | + { | |
16543 | + PyErr_SetString (PyExc_RuntimeError, "string required"); | |
16544 | + return -1; | |
16545 | + } | |
16546 | + if (self->value.stringval) | |
16547 | + xfree (self->value.stringval); | |
16548 | + if (value == Py_None) | |
16549 | + { | |
16550 | + if (self->type == var_optional_filename) | |
16551 | + self->value.stringval = xstrdup (""); | |
16552 | + else | |
16553 | + self->value.stringval = NULL; | |
16554 | + } | |
16555 | + else | |
16556 | + self->value.stringval = python_string_to_host_string (value); | |
16557 | + break; | |
3a58abaf | 16558 | + |
7566401a ER |
16559 | + case var_enum: |
16560 | + { | |
16561 | + int i; | |
16562 | + char *str; | |
3a58abaf | 16563 | + |
7566401a ER |
16564 | + if (! gdbpy_is_string (value)) |
16565 | + { | |
16566 | + PyErr_SetString (PyExc_RuntimeError, "string required"); | |
16567 | + return -1; | |
16568 | + } | |
3a58abaf | 16569 | + |
7566401a ER |
16570 | + str = python_string_to_host_string (value); |
16571 | + for (i = 0; self->enumeration[i]; ++i) | |
16572 | + if (! strcmp (self->enumeration[i], str)) | |
16573 | + break; | |
16574 | + xfree (str); | |
16575 | + if (! self->enumeration[i]) | |
16576 | + { | |
16577 | + PyErr_SetString (PyExc_RuntimeError, | |
16578 | + "value must be member of enumeration"); | |
16579 | + return -1; | |
16580 | + } | |
16581 | + self->value.cstringval = self->enumeration[i]; | |
16582 | + break; | |
16583 | + } | |
3a58abaf | 16584 | + |
7566401a ER |
16585 | + case var_boolean: |
16586 | + if (! PyBool_Check (value)) | |
16587 | + { | |
16588 | + PyErr_SetString (PyExc_RuntimeError, "boolean required"); | |
16589 | + return -1; | |
16590 | + } | |
16591 | + cmp = PyObject_IsTrue (value); | |
16592 | + if (cmp < 0) | |
16593 | + return -1; | |
16594 | + self->value.intval = cmp; | |
16595 | + break; | |
3a58abaf | 16596 | + |
7566401a ER |
16597 | + case var_auto_boolean: |
16598 | + if (! PyBool_Check (value) && value != Py_None) | |
16599 | + { | |
16600 | + PyErr_SetString (PyExc_RuntimeError, | |
16601 | + "boolean or None required"); | |
16602 | + return -1; | |
16603 | + } | |
3a58abaf | 16604 | + |
7566401a ER |
16605 | + if (value == Py_None) |
16606 | + self->value.autoboolval = AUTO_BOOLEAN_AUTO; | |
16607 | + else | |
16608 | + { | |
16609 | + cmp = PyObject_IsTrue (value); | |
16610 | + if (cmp < 0 ) | |
16611 | + return -1; | |
16612 | + if (cmp == 1) | |
16613 | + self->value.autoboolval = AUTO_BOOLEAN_TRUE; | |
16614 | + else | |
16615 | + self->value.autoboolval = AUTO_BOOLEAN_FALSE; | |
3a58abaf | 16616 | + |
7566401a ER |
16617 | + break; |
16618 | + } | |
3a58abaf | 16619 | + |
7566401a ER |
16620 | + case var_integer: |
16621 | + case var_zinteger: | |
16622 | + case var_uinteger: | |
16623 | + { | |
16624 | + long l; | |
16625 | + int ok; | |
3a58abaf | 16626 | + |
7566401a ER |
16627 | + if (! PyInt_Check (value)) |
16628 | + { | |
16629 | + PyErr_SetString (PyExc_RuntimeError, "value must be integer"); | |
16630 | + return -1; | |
16631 | + } | |
3a58abaf | 16632 | + |
7566401a ER |
16633 | + l = PyInt_AsLong (value); |
16634 | + if (self->type == var_uinteger) | |
16635 | + { | |
16636 | + ok = (l >= 0 && l <= UINT_MAX); | |
16637 | + if (l == 0) | |
16638 | + l = UINT_MAX; | |
16639 | + } | |
16640 | + else if (self->type == var_integer) | |
16641 | + { | |
16642 | + ok = (l >= INT_MIN && l <= INT_MAX); | |
16643 | + if (l == 0) | |
16644 | + l = INT_MAX; | |
16645 | + } | |
16646 | + else | |
16647 | + ok = (l >= INT_MIN && l <= INT_MAX); | |
3a58abaf | 16648 | + |
7566401a ER |
16649 | + if (! ok) |
16650 | + { | |
16651 | + PyErr_SetString (PyExc_RuntimeError, "range exceeded"); | |
16652 | + return -1; | |
16653 | + } | |
3a58abaf | 16654 | + |
7566401a ER |
16655 | + self->value.intval = (int) l; |
16656 | + break; | |
16657 | + } | |
3a58abaf | 16658 | + |
7566401a ER |
16659 | + default: |
16660 | + PyErr_SetString (PyExc_RuntimeError, "programmer error: unhandled type"); | |
16661 | + return -1; | |
16662 | + } | |
3a58abaf | 16663 | + |
7566401a | 16664 | + return 0; |
3a58abaf AM |
16665 | +} |
16666 | + | |
7566401a ER |
16667 | +/* Set an attribute. */ |
16668 | +static int | |
16669 | +set_attr (PyObject *obj, PyObject *attr_name, PyObject *val) | |
3a58abaf | 16670 | +{ |
7566401a ER |
16671 | + if (PyString_Check (attr_name) |
16672 | + && ! strcmp (PyString_AsString (attr_name), "value")) | |
16673 | + { | |
16674 | + if (!val) | |
16675 | + { | |
16676 | + PyErr_SetString (PyExc_RuntimeError, | |
16677 | + "cannot delete a parameter's value"); | |
16678 | + return -1; | |
16679 | + } | |
16680 | + return set_parameter_value ((parmpy_object *) obj, val); | |
16681 | + } | |
3a58abaf | 16682 | + |
7566401a ER |
16683 | + return PyObject_GenericSetAttr (obj, attr_name, val); |
16684 | +} | |
3a58abaf | 16685 | + |
7566401a | 16686 | +\f |
3a58abaf | 16687 | + |
7566401a ER |
16688 | +/* A helper function that dispatches to the appropriate add_setshow |
16689 | + function. */ | |
16690 | +static void | |
16691 | +add_setshow_generic (int parmclass, enum command_class cmdclass, | |
16692 | + char *cmd_name, parmpy_object *self, | |
16693 | + char *set_doc, char *show_doc, char *help_doc, | |
16694 | + struct cmd_list_element **set_list, | |
16695 | + struct cmd_list_element **show_list) | |
16696 | +{ | |
16697 | + switch (parmclass) | |
3a58abaf | 16698 | + { |
7566401a ER |
16699 | + case var_boolean: |
16700 | + add_setshow_boolean_cmd (cmd_name, cmdclass, &self->value.intval, | |
16701 | + set_doc, show_doc, help_doc, | |
16702 | + NULL, NULL, set_list, show_list); | |
16703 | + break; | |
3a58abaf | 16704 | + |
7566401a ER |
16705 | + case var_auto_boolean: |
16706 | + add_setshow_auto_boolean_cmd (cmd_name, cmdclass, | |
16707 | + &self->value.autoboolval, | |
16708 | + set_doc, show_doc, help_doc, | |
16709 | + NULL, NULL, set_list, show_list); | |
16710 | + break; | |
16711 | + | |
16712 | + case var_uinteger: | |
16713 | + add_setshow_uinteger_cmd (cmd_name, cmdclass, &self->value.uintval, | |
16714 | + set_doc, show_doc, help_doc, | |
16715 | + NULL, NULL, set_list, show_list); | |
16716 | + break; | |
16717 | + | |
16718 | + case var_integer: | |
16719 | + add_setshow_integer_cmd (cmd_name, cmdclass, &self->value.intval, | |
16720 | + set_doc, show_doc, help_doc, | |
16721 | + NULL, NULL, set_list, show_list); | |
16722 | + break; | |
16723 | + | |
16724 | + case var_string: | |
16725 | + add_setshow_string_cmd (cmd_name, cmdclass, &self->value.stringval, | |
16726 | + set_doc, show_doc, help_doc, | |
16727 | + NULL, NULL, set_list, show_list); | |
16728 | + break; | |
16729 | + | |
16730 | + case var_string_noescape: | |
16731 | + add_setshow_string_noescape_cmd (cmd_name, cmdclass, | |
16732 | + &self->value.stringval, | |
16733 | + set_doc, show_doc, help_doc, | |
16734 | + NULL, NULL, set_list, show_list); | |
16735 | + break; | |
16736 | + | |
16737 | + case var_optional_filename: | |
16738 | + add_setshow_optional_filename_cmd (cmd_name, cmdclass, | |
16739 | + &self->value.stringval, | |
16740 | + set_doc, show_doc, help_doc, | |
16741 | + NULL, NULL, set_list, show_list); | |
16742 | + break; | |
16743 | + | |
16744 | + case var_filename: | |
16745 | + add_setshow_filename_cmd (cmd_name, cmdclass, &self->value.stringval, | |
16746 | + set_doc, show_doc, help_doc, | |
16747 | + NULL, NULL, set_list, show_list); | |
16748 | + break; | |
16749 | + | |
16750 | + case var_zinteger: | |
16751 | + add_setshow_zinteger_cmd (cmd_name, cmdclass, &self->value.intval, | |
16752 | + set_doc, show_doc, help_doc, | |
16753 | + NULL, NULL, set_list, show_list); | |
16754 | + break; | |
16755 | + | |
16756 | + case var_enum: | |
16757 | + add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration, | |
16758 | + &self->value.cstringval, | |
16759 | + set_doc, show_doc, help_doc, | |
16760 | + NULL, NULL, set_list, show_list); | |
16761 | + /* Initialize the value, just in case. */ | |
16762 | + self->value.cstringval = self->enumeration[0]; | |
16763 | + break; | |
3a58abaf | 16764 | + } |
7566401a | 16765 | +} |
3a58abaf | 16766 | + |
7566401a ER |
16767 | +/* A helper which computes enum values. Returns 1 on success, 0 on |
16768 | + error. */ | |
16769 | +static int | |
16770 | +compute_enum_values (parmpy_object *self, PyObject *enum_values) | |
16771 | +{ | |
16772 | + Py_ssize_t size, i; | |
3a58abaf | 16773 | + |
7566401a | 16774 | + if (! enum_values) |
3a58abaf | 16775 | + { |
7566401a ER |
16776 | + PyErr_SetString (PyExc_RuntimeError, |
16777 | + "enumeration required for PARAM_ENUM"); | |
16778 | + return 0; | |
3a58abaf AM |
16779 | + } |
16780 | + | |
7566401a | 16781 | + if (! PySequence_Check (enum_values)) |
3a58abaf | 16782 | + { |
7566401a ER |
16783 | + PyErr_SetString (PyExc_RuntimeError, "enumeration is not a sequence"); |
16784 | + return 0; | |
3a58abaf | 16785 | + } |
7566401a ER |
16786 | + |
16787 | + size = PySequence_Size (enum_values); | |
16788 | + if (size < 0) | |
16789 | + return 0; | |
16790 | + if (size == 0) | |
3a58abaf | 16791 | + { |
7566401a ER |
16792 | + PyErr_SetString (PyExc_RuntimeError, "empty enumeration"); |
16793 | + return 0; | |
3a58abaf | 16794 | + } |
3a58abaf | 16795 | + |
7566401a ER |
16796 | + self->enumeration = xmalloc ((size + 1) * sizeof (char *)); |
16797 | + memset (self->enumeration, 0, (size + 1) * sizeof (char *)); | |
3a58abaf | 16798 | + |
7566401a ER |
16799 | + for (i = 0; i < size; ++i) |
16800 | + { | |
16801 | + PyObject *item = PySequence_GetItem (enum_values, i); | |
16802 | + if (! item) | |
16803 | + return 0; | |
16804 | + if (! gdbpy_is_string (item)) | |
16805 | + { | |
16806 | + PyErr_SetString (PyExc_RuntimeError, "enumeration item not a string"); | |
16807 | + return 0; | |
16808 | + } | |
16809 | + self->enumeration[i] = python_string_to_host_string (item); | |
16810 | + } | |
16811 | + | |
16812 | + return 1; | |
3a58abaf AM |
16813 | +} |
16814 | + | |
7566401a ER |
16815 | +/* A helper function which returns a documentation string for an |
16816 | + object. */ | |
16817 | +static char * | |
16818 | +get_doc_string (PyObject *object, PyObject *attr) | |
3a58abaf | 16819 | +{ |
7566401a ER |
16820 | + char *result = NULL; |
16821 | + if (PyObject_HasAttr (object, attr)) | |
16822 | + { | |
16823 | + PyObject *ds_obj = PyObject_GetAttr (object, attr); | |
16824 | + if (ds_obj && gdbpy_is_string (ds_obj)) | |
16825 | + result = python_string_to_host_string (ds_obj); | |
16826 | + } | |
16827 | + if (! result) | |
16828 | + result = xstrdup ("This command is not documented."); | |
16829 | + return result; | |
16830 | +} | |
3a58abaf | 16831 | + |
7566401a | 16832 | +/* Object initializer; sets up gdb-side structures for command. |
3a58abaf | 16833 | + |
7566401a | 16834 | + Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM]) |
3a58abaf | 16835 | + |
7566401a ER |
16836 | + NAME is the name of the parameter. It may consist of multiple |
16837 | + words, in which case the final word is the name of the new command, | |
16838 | + and earlier words must be prefix commands. | |
3a58abaf | 16839 | + |
7566401a ER |
16840 | + CMDCLASS is the kind of command. It should be one of the COMMAND_* |
16841 | + constants defined in the gdb module. | |
3a58abaf | 16842 | + |
7566401a ER |
16843 | + PARMCLASS is the type of the parameter. It should be one of the |
16844 | + PARAM_* constants defined in the gdb module. | |
16845 | + | |
16846 | + If PARMCLASS is PARAM_ENUM, then the final argument should be a | |
16847 | + collection of strings. These strings are the valid values for this | |
16848 | + parameter. | |
16849 | + | |
16850 | + The documentation for the parameter is taken from the doc string | |
16851 | + for the python class. | |
16852 | + | |
16853 | +*/ | |
16854 | +static int | |
16855 | +parmpy_init (PyObject *self, PyObject *args, PyObject *kwds) | |
16856 | +{ | |
16857 | + parmpy_object *obj = (parmpy_object *) self; | |
16858 | + char *name; | |
16859 | + char *set_doc, *show_doc, *doc; | |
16860 | + char *cmd_name; | |
16861 | + int parmclass, cmdtype; | |
16862 | + PyObject *enum_values = NULL; | |
16863 | + struct cmd_list_element *cmd_list; | |
16864 | + struct cmd_list_element **set_list, **show_list; | |
16865 | + volatile struct gdb_exception except; | |
16866 | + | |
16867 | + if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass, | |
16868 | + &enum_values)) | |
16869 | + return -1; | |
16870 | + | |
16871 | + if (cmdtype != no_class && cmdtype != class_run | |
16872 | + && cmdtype != class_vars && cmdtype != class_stack | |
16873 | + && cmdtype != class_files && cmdtype != class_support | |
16874 | + && cmdtype != class_info && cmdtype != class_breakpoint | |
16875 | + && cmdtype != class_trace && cmdtype != class_obscure | |
16876 | + && cmdtype != class_maintenance) | |
16877 | + { | |
16878 | + PyErr_Format (PyExc_RuntimeError, "invalid command class argument"); | |
16879 | + return -1; | |
16880 | + } | |
16881 | + | |
16882 | + if (parmclass != var_boolean && parmclass != var_auto_boolean | |
16883 | + && parmclass != var_uinteger && parmclass != var_integer | |
16884 | + && parmclass != var_string && parmclass != var_string_noescape | |
16885 | + && parmclass != var_optional_filename && parmclass != var_filename | |
16886 | + && parmclass != var_zinteger && parmclass != var_enum) | |
16887 | + { | |
16888 | + PyErr_SetString (PyExc_RuntimeError, "invalid parameter class argument"); | |
16889 | + return -1; | |
16890 | + } | |
16891 | + | |
16892 | + if (enum_values && parmclass != var_enum) | |
16893 | + { | |
16894 | + PyErr_SetString (PyExc_RuntimeError, | |
16895 | + "only PARAM_ENUM accepts a fourth argument"); | |
16896 | + return -1; | |
16897 | + } | |
16898 | + if (parmclass == var_enum) | |
16899 | + { | |
16900 | + if (! compute_enum_values (obj, enum_values)) | |
16901 | + return -1; | |
16902 | + } | |
16903 | + | |
16904 | + obj->type = (enum var_types) parmclass; | |
16905 | + memset (&obj->value, 0, sizeof (obj->value)); | |
16906 | + obj->enumeration = NULL; | |
16907 | + | |
16908 | + cmd_name = gdbpy_parse_command_name (name, &set_list, &setlist); | |
16909 | + if (! cmd_name) | |
16910 | + return -1; | |
16911 | + xfree (cmd_name); | |
16912 | + cmd_name = gdbpy_parse_command_name (name, &show_list, &showlist); | |
16913 | + if (! cmd_name) | |
16914 | + return -1; | |
16915 | + | |
16916 | + /* FIXME: there is no way to register a destructor function for | |
16917 | + set/show commands. So, these are leaked. */ | |
16918 | + set_doc = get_doc_string (self, set_doc_cst); | |
16919 | + show_doc = get_doc_string (self, show_doc_cst); | |
16920 | + doc = get_doc_string (self, gdbpy_doc_cst); | |
16921 | + | |
16922 | + Py_INCREF (self); | |
16923 | + | |
16924 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
16925 | + { | |
16926 | + add_setshow_generic (parmclass, (enum command_class) cmdtype, | |
16927 | + cmd_name, obj, | |
16928 | + set_doc, show_doc, | |
16929 | + doc, set_list, show_list); | |
16930 | + } | |
16931 | + if (except.reason < 0) | |
16932 | + { | |
16933 | + xfree (cmd_name); | |
16934 | + xfree (set_doc); | |
16935 | + xfree (show_doc); | |
16936 | + xfree (doc); | |
16937 | + Py_DECREF (self); | |
16938 | + PyErr_Format (except.reason == RETURN_QUIT | |
16939 | + ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, | |
16940 | + "%s", except.message); | |
16941 | + return -1; | |
16942 | + } | |
16943 | + return 0; | |
16944 | +} | |
16945 | + | |
16946 | +\f | |
16947 | + | |
16948 | +/* Initialize the 'parameters' module. */ | |
16949 | +void | |
16950 | +gdbpy_initialize_parameters (void) | |
16951 | +{ | |
16952 | + int i; | |
16953 | + | |
16954 | + if (PyType_Ready (&parmpy_object_type) < 0) | |
16955 | + return; | |
16956 | + | |
16957 | + set_doc_cst = PyString_FromString ("set_doc"); | |
16958 | + if (! set_doc_cst) | |
16959 | + return; | |
16960 | + show_doc_cst = PyString_FromString ("show_doc"); | |
16961 | + if (! show_doc_cst) | |
16962 | + return; | |
16963 | + | |
16964 | + for (i = 0; parm_constants[i].name; ++i) | |
16965 | + { | |
16966 | + if (PyModule_AddIntConstant (gdb_module, | |
16967 | + parm_constants[i].name, | |
16968 | + parm_constants[i].value) < 0) | |
16969 | + return; | |
16970 | + } | |
16971 | + | |
16972 | + Py_INCREF (&parmpy_object_type); | |
16973 | + PyModule_AddObject (gdb_module, "Parameter", | |
16974 | + (PyObject *) &parmpy_object_type); | |
16975 | +} | |
16976 | + | |
16977 | +\f | |
16978 | + | |
16979 | +static PyTypeObject parmpy_object_type = | |
16980 | +{ | |
3a58abaf AM |
16981 | + PyObject_HEAD_INIT (NULL) |
16982 | + 0, /*ob_size*/ | |
7566401a ER |
16983 | + "gdb.Parameter", /*tp_name*/ |
16984 | + sizeof (parmpy_object), /*tp_basicsize*/ | |
3a58abaf AM |
16985 | + 0, /*tp_itemsize*/ |
16986 | + 0, /*tp_dealloc*/ | |
16987 | + 0, /*tp_print*/ | |
16988 | + 0, /*tp_getattr*/ | |
16989 | + 0, /*tp_setattr*/ | |
16990 | + 0, /*tp_compare*/ | |
16991 | + 0, /*tp_repr*/ | |
16992 | + 0, /*tp_as_number*/ | |
16993 | + 0, /*tp_as_sequence*/ | |
16994 | + 0, /*tp_as_mapping*/ | |
16995 | + 0, /*tp_hash */ | |
16996 | + 0, /*tp_call*/ | |
7566401a ER |
16997 | + 0, /*tp_str*/ |
16998 | + get_attr, /*tp_getattro*/ | |
16999 | + set_attr, /*tp_setattro*/ | |
3a58abaf | 17000 | + 0, /*tp_as_buffer*/ |
7566401a ER |
17001 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ |
17002 | + "GDB parameter object", /* tp_doc */ | |
3a58abaf AM |
17003 | + 0, /* tp_traverse */ |
17004 | + 0, /* tp_clear */ | |
17005 | + 0, /* tp_richcompare */ | |
17006 | + 0, /* tp_weaklistoffset */ | |
17007 | + 0, /* tp_iter */ | |
17008 | + 0, /* tp_iternext */ | |
17009 | + 0, /* tp_methods */ | |
17010 | + 0, /* tp_members */ | |
7566401a ER |
17011 | + 0, /* tp_getset */ |
17012 | + 0, /* tp_base */ | |
17013 | + 0, /* tp_dict */ | |
17014 | + 0, /* tp_descr_get */ | |
17015 | + 0, /* tp_descr_set */ | |
17016 | + 0, /* tp_dictoffset */ | |
17017 | + parmpy_init, /* tp_init */ | |
17018 | + 0, /* tp_alloc */ | |
17019 | + PyType_GenericNew /* tp_new */ | |
3a58abaf | 17020 | +}; |
7566401a ER |
17021 | diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c |
17022 | index 5d696c8..a6348ba 100644 | |
17023 | --- a/gdb/python/py-prettyprint.c | |
17024 | +++ b/gdb/python/py-prettyprint.c | |
17025 | @@ -121,6 +121,7 @@ find_pretty_printer (PyObject *value) | |
17026 | ||
17027 | return function; | |
17028 | } | |
17029 | + | |
17030 | /* Pretty-print a single value, via the printer object PRINTER. | |
17031 | If the function returns a string, a PyObject containing the string | |
17032 | is returned. Otherwise, if the function returns a value, | |
17033 | @@ -141,10 +142,15 @@ pretty_print_one_value (PyObject *printer, struct value **out_value) | |
17034 | if (! gdbpy_is_string (result)) | |
17035 | { | |
17036 | *out_value = convert_value_from_python (result); | |
17037 | - if (PyErr_Occurred ()) | |
17038 | - *out_value = NULL; | |
17039 | - Py_DECREF (result); | |
17040 | - result = NULL; | |
17041 | + if (PyErr_Occurred ()) | |
17042 | + *out_value = NULL; | |
17043 | + else | |
17044 | + /* We must increment the value's refcount, because we | |
17045 | + are about to decref RESULT, and this may result in | |
17046 | + the value being destroyed. */ | |
17047 | + value_incref (*out_value); | |
17048 | + Py_DECREF (result); | |
17049 | + result = NULL; | |
17050 | } | |
17051 | } | |
17052 | } | |
17053 | @@ -556,14 +562,7 @@ gdbpy_get_varobj_pretty_printer (struct value *value) | |
17054 | { | |
17055 | PyObject *val_obj; | |
17056 | PyObject *pretty_printer = NULL; | |
17057 | - volatile struct gdb_exception except; | |
17058 | ||
17059 | - TRY_CATCH (except, RETURN_MASK_ALL) | |
17060 | - { | |
17061 | - value = value_copy (value); | |
17062 | - } | |
17063 | - GDB_PY_HANDLE_EXCEPTION (except); | |
17064 | - | |
17065 | val_obj = value_to_value_object (value); | |
17066 | if (! val_obj) | |
17067 | return NULL; | |
17068 | diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c | |
3a58abaf | 17069 | new file mode 100644 |
7566401a | 17070 | index 0000000..03d43c1 |
3a58abaf | 17071 | --- /dev/null |
7566401a ER |
17072 | +++ b/gdb/python/py-symbol.c |
17073 | @@ -0,0 +1,336 @@ | |
17074 | +/* Python interface to symbols. | |
3a58abaf | 17075 | + |
7566401a | 17076 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. |
3a58abaf AM |
17077 | + |
17078 | + This file is part of GDB. | |
17079 | + | |
17080 | + This program is free software; you can redistribute it and/or modify | |
17081 | + it under the terms of the GNU General Public License as published by | |
17082 | + the Free Software Foundation; either version 3 of the License, or | |
17083 | + (at your option) any later version. | |
17084 | + | |
17085 | + This program is distributed in the hope that it will be useful, | |
17086 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17087 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17088 | + GNU General Public License for more details. | |
17089 | + | |
17090 | + You should have received a copy of the GNU General Public License | |
17091 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
17092 | + | |
17093 | +#include "defs.h" | |
7566401a ER |
17094 | +#include "block.h" |
17095 | +#include "exceptions.h" | |
17096 | +#include "frame.h" | |
3a58abaf | 17097 | +#include "symtab.h" |
3a58abaf AM |
17098 | +#include "python-internal.h" |
17099 | + | |
17100 | +typedef struct { | |
17101 | + PyObject_HEAD | |
7566401a ER |
17102 | + struct symbol *symbol; |
17103 | +} symbol_object; | |
3a58abaf AM |
17104 | + |
17105 | + | |
17106 | +static PyObject * | |
7566401a | 17107 | +sympy_str (PyObject *self) |
3a58abaf AM |
17108 | +{ |
17109 | + int ret; | |
17110 | + char *s; | |
17111 | + PyObject *result; | |
17112 | + | |
7566401a ER |
17113 | + ret = asprintf (&s, "symbol for %s", |
17114 | + SYMBOL_PRINT_NAME (((symbol_object *) self)->symbol)); | |
3a58abaf AM |
17115 | + if (ret < 0) |
17116 | + Py_RETURN_NONE; | |
17117 | + | |
17118 | + result = PyString_FromString (s); | |
17119 | + xfree (s); | |
17120 | + | |
17121 | + return result; | |
17122 | +} | |
17123 | + | |
17124 | +static PyObject * | |
7566401a | 17125 | +sympy_get_value (PyObject *self, void *closure) |
3a58abaf | 17126 | +{ |
7566401a | 17127 | + symbol_object *self_sym = (symbol_object *) self; |
3a58abaf | 17128 | + |
7566401a | 17129 | + switch (SYMBOL_CLASS (self_sym->symbol)) |
3a58abaf | 17130 | + { |
7566401a ER |
17131 | + case LOC_BLOCK: |
17132 | + return block_to_block_object (SYMBOL_BLOCK_VALUE (self_sym->symbol)); | |
3a58abaf AM |
17133 | + } |
17134 | + | |
7566401a ER |
17135 | + PyErr_SetString (PyExc_NotImplementedError, |
17136 | + "Symbol type not yet supported in Python scripts."); | |
17137 | + return NULL; | |
3a58abaf AM |
17138 | +} |
17139 | + | |
17140 | +static PyObject * | |
7566401a | 17141 | +sympy_get_symtab (PyObject *self, void *closure) |
3a58abaf | 17142 | +{ |
7566401a | 17143 | + symbol_object *self_sym = (symbol_object *) self; |
3a58abaf | 17144 | + |
7566401a | 17145 | + return symtab_to_symtab_object (SYMBOL_SYMTAB (self_sym->symbol)); |
3a58abaf AM |
17146 | +} |
17147 | + | |
17148 | +static PyObject * | |
7566401a | 17149 | +sympy_get_name (PyObject *self, void *closure) |
3a58abaf | 17150 | +{ |
7566401a | 17151 | + symbol_object *self_sym = (symbol_object *) self; |
3a58abaf | 17152 | + |
7566401a | 17153 | + return PyString_FromString (SYMBOL_NATURAL_NAME (self_sym->symbol)); |
3a58abaf AM |
17154 | +} |
17155 | + | |
17156 | +static PyObject * | |
7566401a | 17157 | +sympy_get_linkage_name (PyObject *self, void *closure) |
3a58abaf | 17158 | +{ |
7566401a ER |
17159 | + symbol_object *self_sym = (symbol_object *) self; |
17160 | + | |
17161 | + return PyString_FromString (SYMBOL_LINKAGE_NAME (self_sym->symbol)); | |
3a58abaf AM |
17162 | +} |
17163 | + | |
17164 | +static PyObject * | |
7566401a | 17165 | +sympy_get_print_name (PyObject *self, void *closure) |
3a58abaf | 17166 | +{ |
7566401a ER |
17167 | + symbol_object *self_sym = (symbol_object *) self; |
17168 | + | |
17169 | + return PyString_FromString (SYMBOL_PRINT_NAME (self_sym->symbol)); | |
3a58abaf AM |
17170 | +} |
17171 | + | |
17172 | +static PyObject * | |
7566401a | 17173 | +sympy_get_addr_class (PyObject *self, void *closure) |
3a58abaf | 17174 | +{ |
7566401a | 17175 | + symbol_object *self_sym = (symbol_object *) self; |
3a58abaf | 17176 | + |
7566401a ER |
17177 | + return PyInt_FromLong (SYMBOL_CLASS (self_sym->symbol)); |
17178 | +} | |
3a58abaf | 17179 | + |
7566401a ER |
17180 | +static PyObject * |
17181 | +sympy_is_argument (PyObject *self, void *closure) | |
17182 | +{ | |
17183 | + symbol_object *self_sym = (symbol_object *) self; | |
17184 | + | |
17185 | + return PyBool_FromLong (SYMBOL_IS_ARGUMENT (self_sym->symbol)); | |
3a58abaf AM |
17186 | +} |
17187 | + | |
7566401a ER |
17188 | +static PyObject * |
17189 | +sympy_is_constant (PyObject *self, void *closure) | |
3a58abaf | 17190 | +{ |
7566401a ER |
17191 | + symbol_object *self_sym = (symbol_object *) self; |
17192 | + enum address_class class = SYMBOL_CLASS (self_sym->symbol); | |
3a58abaf | 17193 | + |
7566401a ER |
17194 | + return PyBool_FromLong (class == LOC_CONST || class == LOC_CONST_BYTES); |
17195 | +} | |
17196 | + | |
17197 | +static PyObject * | |
17198 | +sympy_is_function (PyObject *self, void *closure) | |
17199 | +{ | |
17200 | + symbol_object *self_sym = (symbol_object *) self; | |
17201 | + enum address_class class = SYMBOL_CLASS (self_sym->symbol); | |
17202 | + | |
17203 | + return PyBool_FromLong (class == LOC_BLOCK); | |
17204 | +} | |
17205 | + | |
17206 | +static PyObject * | |
17207 | +sympy_is_variable (PyObject *self, void *closure) | |
17208 | +{ | |
17209 | + symbol_object *self_sym = (symbol_object *) self; | |
17210 | + enum address_class class = SYMBOL_CLASS (self_sym->symbol); | |
17211 | + | |
17212 | + return PyBool_FromLong (!SYMBOL_IS_ARGUMENT (self_sym->symbol) | |
17213 | + && (class == LOC_LOCAL || class == LOC_REGISTER || class == LOC_STATIC | |
17214 | + || class == LOC_COMPUTED || class == LOC_OPTIMIZED_OUT)); | |
3a58abaf AM |
17215 | +} |
17216 | + | |
17217 | +PyObject * | |
7566401a | 17218 | +symbol_to_symbol_object (struct symbol *sym) |
3a58abaf | 17219 | +{ |
7566401a | 17220 | + symbol_object *sym_obj; |
3a58abaf | 17221 | + |
7566401a ER |
17222 | + sym_obj = PyObject_New (symbol_object, &symbol_object_type); |
17223 | + if (sym_obj == NULL) | |
3a58abaf | 17224 | + { |
7566401a | 17225 | + PyErr_SetString (PyExc_MemoryError, "Could not allocate symbol object."); |
3a58abaf AM |
17226 | + return NULL; |
17227 | + } | |
17228 | + | |
7566401a | 17229 | + sym_obj->symbol = sym; |
3a58abaf | 17230 | + |
7566401a ER |
17231 | + return (PyObject *) sym_obj; |
17232 | +} | |
3a58abaf | 17233 | + |
7566401a ER |
17234 | +struct symbol * |
17235 | +symbol_object_to_symbol (PyObject *obj) | |
17236 | +{ | |
17237 | + if (! PyObject_TypeCheck (obj, &symbol_object_type)) | |
17238 | + return NULL; | |
17239 | + return ((symbol_object *) obj)->symbol; | |
3a58abaf AM |
17240 | +} |
17241 | + | |
7566401a ER |
17242 | +/* Implementation of |
17243 | + gdb.lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this) | |
17244 | + A tuple with 2 elements is always returned. The first is the symbol | |
17245 | + object or None, the second is a boolean with the value of | |
17246 | + is_a_field_of_this (see comment in lookup_symbol_in_language). */ | |
17247 | + | |
17248 | +PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw) | |
3a58abaf | 17249 | +{ |
7566401a ER |
17250 | + int domain = VAR_DOMAIN, is_a_field_of_this = 0; |
17251 | + const char *name; | |
17252 | + static char *keywords[] = { "name", "block", "domain", NULL }; | |
17253 | + struct symbol *symbol; | |
17254 | + PyObject *block_obj = NULL, *ret_tuple, *sym_obj, *bool_obj; | |
17255 | + struct block *block = NULL; | |
17256 | + | |
17257 | + if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!i", keywords, &name, | |
17258 | + &block_object_type, &block_obj, &domain)) | |
17259 | + return NULL; | |
17260 | + | |
17261 | + if (block_obj) | |
17262 | + block = block_object_to_block (block_obj); | |
17263 | + else | |
3a58abaf | 17264 | + { |
7566401a ER |
17265 | + struct frame_info *selected_frame; |
17266 | + volatile struct gdb_exception except; | |
17267 | + | |
17268 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
17269 | + { | |
17270 | + selected_frame = get_selected_frame (_("No frame selected.")); | |
17271 | + block = block_for_pc (get_frame_address_in_block (selected_frame)); | |
17272 | + } | |
17273 | + GDB_PY_HANDLE_EXCEPTION (except); | |
17274 | + } | |
17275 | + | |
17276 | + symbol = lookup_symbol (name, block, domain, &is_a_field_of_this); | |
3a58abaf | 17277 | + |
7566401a ER |
17278 | + ret_tuple = PyTuple_New (2); |
17279 | + if (!ret_tuple) | |
17280 | + { | |
17281 | + PyErr_SetString (PyExc_MemoryError, "Could not allocate tuple object."); | |
3a58abaf AM |
17282 | + return NULL; |
17283 | + } | |
17284 | + | |
7566401a ER |
17285 | + if (symbol) |
17286 | + { | |
17287 | + sym_obj = symbol_to_symbol_object (symbol); | |
17288 | + if (!sym_obj) | |
17289 | + { | |
17290 | + Py_DECREF (ret_tuple); | |
17291 | + return NULL; | |
17292 | + } | |
17293 | + } | |
17294 | + else | |
17295 | + { | |
17296 | + sym_obj = Py_None; | |
17297 | + Py_INCREF (Py_None); | |
17298 | + } | |
17299 | + PyTuple_SET_ITEM (ret_tuple, 0, sym_obj); | |
3a58abaf | 17300 | + |
7566401a ER |
17301 | + bool_obj = is_a_field_of_this? Py_True : Py_False; |
17302 | + Py_INCREF (bool_obj); | |
17303 | + PyTuple_SET_ITEM (ret_tuple, 1, bool_obj); | |
17304 | + | |
17305 | + return ret_tuple; | |
3a58abaf AM |
17306 | +} |
17307 | + | |
17308 | +void | |
7566401a | 17309 | +gdbpy_initialize_symbols (void) |
3a58abaf | 17310 | +{ |
7566401a | 17311 | + if (PyType_Ready (&symbol_object_type) < 0) |
3a58abaf AM |
17312 | + return; |
17313 | + | |
7566401a ER |
17314 | + /* FIXME: These would probably be best exposed as class attributes of Symbol, |
17315 | + but I don't know how to do it except by messing with the type's dictionary. | |
17316 | + That seems too messy. */ | |
17317 | + /* FIXME 2: Some of these were removed from GDB since I first wrote this code, | |
17318 | + so it's probably a good idea not to expose them to Python. */ | |
17319 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_UNDEF", LOC_UNDEF); | |
17320 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_CONST", LOC_CONST); | |
17321 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_STATIC", LOC_STATIC); | |
17322 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGISTER", LOC_REGISTER); | |
17323 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_ARG", LOC_ARG); | |
17324 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REF_ARG", LOC_REF_ARG); | |
17325 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_LOCAL", LOC_LOCAL); | |
17326 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_TYPEDEF", LOC_TYPEDEF); | |
17327 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_LABEL", LOC_LABEL); | |
17328 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_BLOCK", LOC_BLOCK); | |
17329 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_CONST_BYTES", | |
17330 | + LOC_CONST_BYTES); | |
17331 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_UNRESOLVED", LOC_UNRESOLVED); | |
17332 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_OPTIMIZED_OUT", | |
17333 | + LOC_OPTIMIZED_OUT); | |
17334 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_COMPUTED", LOC_COMPUTED); | |
17335 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGPARM_ADDR", | |
17336 | + LOC_REGPARM_ADDR); | |
17337 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_UNDEF_DOMAIN", UNDEF_DOMAIN); | |
17338 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_VAR_DOMAIN", VAR_DOMAIN); | |
17339 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_STRUCT_DOMAIN", STRUCT_DOMAIN); | |
17340 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LABEL_DOMAIN", LABEL_DOMAIN); | |
17341 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_VARIABLES_DOMAIN", | |
17342 | + VARIABLES_DOMAIN); | |
17343 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_FUNCTIONS_DOMAIN", | |
17344 | + FUNCTIONS_DOMAIN); | |
17345 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_TYPES_DOMAIN", TYPES_DOMAIN); | |
3a58abaf | 17346 | + |
7566401a ER |
17347 | + Py_INCREF (&symbol_object_type); |
17348 | + PyModule_AddObject (gdb_module, "Symbol", (PyObject *) &symbol_object_type); | |
3a58abaf AM |
17349 | +} |
17350 | + | |
17351 | +\f | |
17352 | + | |
7566401a ER |
17353 | +static PyGetSetDef symbol_object_getset[] = { |
17354 | + { "value", sympy_get_value, NULL, "Value of the symbol.", NULL }, | |
17355 | + { "symtab", sympy_get_symtab, NULL, | |
17356 | + "Symbol table in which the symbol appears.", NULL }, | |
17357 | + { "name", sympy_get_name, NULL, | |
17358 | + "Name of the symbol, as it appears in the source code.", NULL }, | |
17359 | + { "linkage_name", sympy_get_linkage_name, NULL, | |
17360 | + "Name of the symbol, as used by the linker (i.e., may be mangled).", NULL }, | |
17361 | + { "print_name", sympy_get_print_name, NULL, | |
17362 | + "Name of the symbol in a form suitable for output.\n\ | |
17363 | +This is either name or linkage_name, depending on whether the user asked GDB\n\ | |
17364 | +to display demangled or mangled names.", NULL }, | |
17365 | + { "addr_class", sympy_get_addr_class, NULL, "Address class of the symbol." }, | |
17366 | + { "is_argument", sympy_is_argument, NULL, | |
17367 | + "True if the symbol is an argument of a function." }, | |
17368 | + { "is_constant", sympy_is_constant, NULL, | |
17369 | + "True if the symbol is a constant." }, | |
17370 | + { "is_function", sympy_is_function, NULL, | |
17371 | + "True if the symbol is a function or method." }, | |
17372 | + { "is_variable", sympy_is_variable, NULL, | |
17373 | + "True if the symbol is a variable." }, | |
17374 | + { NULL } /* Sentinel */ | |
3a58abaf AM |
17375 | +}; |
17376 | + | |
7566401a | 17377 | +PyTypeObject symbol_object_type = { |
3a58abaf AM |
17378 | + PyObject_HEAD_INIT (NULL) |
17379 | + 0, /*ob_size*/ | |
7566401a ER |
17380 | + "gdb.Symbol", /*tp_name*/ |
17381 | + sizeof (symbol_object), /*tp_basicsize*/ | |
3a58abaf AM |
17382 | + 0, /*tp_itemsize*/ |
17383 | + 0, /*tp_dealloc*/ | |
17384 | + 0, /*tp_print*/ | |
17385 | + 0, /*tp_getattr*/ | |
17386 | + 0, /*tp_setattr*/ | |
17387 | + 0, /*tp_compare*/ | |
17388 | + 0, /*tp_repr*/ | |
17389 | + 0, /*tp_as_number*/ | |
17390 | + 0, /*tp_as_sequence*/ | |
17391 | + 0, /*tp_as_mapping*/ | |
17392 | + 0, /*tp_hash */ | |
17393 | + 0, /*tp_call*/ | |
7566401a | 17394 | + sympy_str, /*tp_str*/ |
3a58abaf AM |
17395 | + 0, /*tp_getattro*/ |
17396 | + 0, /*tp_setattro*/ | |
17397 | + 0, /*tp_as_buffer*/ | |
17398 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
7566401a | 17399 | + "GDB symbol object", /* tp_doc */ |
3a58abaf AM |
17400 | + 0, /* tp_traverse */ |
17401 | + 0, /* tp_clear */ | |
17402 | + 0, /* tp_richcompare */ | |
17403 | + 0, /* tp_weaklistoffset */ | |
17404 | + 0, /* tp_iter */ | |
17405 | + 0, /* tp_iternext */ | |
17406 | + 0, /* tp_methods */ | |
17407 | + 0, /* tp_members */ | |
7566401a | 17408 | + symbol_object_getset /* tp_getset */ |
3a58abaf | 17409 | +}; |
7566401a | 17410 | diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c |
3a58abaf | 17411 | new file mode 100644 |
7566401a | 17412 | index 0000000..830e586 |
3a58abaf | 17413 | --- /dev/null |
7566401a ER |
17414 | +++ b/gdb/python/py-symtab.c |
17415 | @@ -0,0 +1,322 @@ | |
17416 | +/* Python interface to symbol tables. | |
3a58abaf AM |
17417 | + |
17418 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
17419 | + | |
17420 | + This file is part of GDB. | |
17421 | + | |
17422 | + This program is free software; you can redistribute it and/or modify | |
17423 | + it under the terms of the GNU General Public License as published by | |
17424 | + the Free Software Foundation; either version 3 of the License, or | |
17425 | + (at your option) any later version. | |
17426 | + | |
17427 | + This program is distributed in the hope that it will be useful, | |
17428 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17429 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17430 | + GNU General Public License for more details. | |
17431 | + | |
17432 | + You should have received a copy of the GNU General Public License | |
17433 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
17434 | + | |
17435 | +#include "defs.h" | |
3a58abaf | 17436 | +#include "charset.h" |
7566401a ER |
17437 | +#include "symtab.h" |
17438 | +#include "source.h" | |
17439 | +#include "python-internal.h" | |
3a58abaf | 17440 | + |
7566401a | 17441 | +typedef struct { |
3a58abaf | 17442 | + PyObject_HEAD |
7566401a ER |
17443 | + struct symtab *symtab; |
17444 | +} symtab_object; | |
3a58abaf | 17445 | + |
7566401a | 17446 | +static PyTypeObject symtab_object_type; |
3a58abaf | 17447 | + |
7566401a | 17448 | +typedef struct { |
3a58abaf | 17449 | + PyObject_HEAD |
7566401a ER |
17450 | + symtab_object *symtab; |
17451 | + struct symtab_and_line *sal; | |
17452 | +} sal_object; | |
3a58abaf | 17453 | + |
7566401a | 17454 | +static PyTypeObject sal_object_type; |
3a58abaf | 17455 | + |
3a58abaf | 17456 | + |
7566401a ER |
17457 | +static PyObject * |
17458 | +stpy_str (PyObject *self) | |
3a58abaf | 17459 | +{ |
7566401a ER |
17460 | + int ret; |
17461 | + char *s; | |
17462 | + PyObject *result; | |
3a58abaf | 17463 | + |
7566401a ER |
17464 | + ret = asprintf (&s, "symbol table for %s", |
17465 | + ((symtab_object *) self)->symtab->filename); | |
17466 | + if (ret < 0) | |
17467 | + Py_RETURN_NONE; | |
3a58abaf | 17468 | + |
7566401a ER |
17469 | + result = PyString_FromString (s); |
17470 | + xfree (s); | |
3a58abaf | 17471 | + |
7566401a | 17472 | + return result; |
3a58abaf AM |
17473 | +} |
17474 | + | |
17475 | +static PyObject * | |
7566401a | 17476 | +stpy_get_filename (PyObject *self, void *closure) |
3a58abaf | 17477 | +{ |
7566401a ER |
17478 | + symtab_object *self_symtab = (symtab_object *) self; |
17479 | + PyObject *str_obj; | |
17480 | + | |
17481 | + /* FIXME: Can symtab->filename really be NULL? */ | |
17482 | + if (self_symtab->symtab->filename) | |
17483 | + str_obj = PyString_Decode (self_symtab->symtab->filename, | |
17484 | + strlen (self_symtab->symtab->filename), | |
17485 | + host_charset (), NULL); | |
17486 | + else | |
3a58abaf | 17487 | + { |
7566401a ER |
17488 | + str_obj = Py_None; |
17489 | + Py_INCREF (Py_None); | |
3a58abaf | 17490 | + } |
3a58abaf | 17491 | + |
7566401a ER |
17492 | + return str_obj; |
17493 | +} | |
3a58abaf | 17494 | + |
3a58abaf | 17495 | +static PyObject * |
7566401a | 17496 | +stpy_get_objfile (PyObject *self, void *closure) |
3a58abaf | 17497 | +{ |
7566401a ER |
17498 | + symtab_object *self_symtab = (symtab_object *) self; |
17499 | + PyObject *result = objfile_to_objfile_object (self_symtab->symtab->objfile); | |
17500 | + Py_INCREF (result); | |
17501 | + return result; | |
3a58abaf AM |
17502 | +} |
17503 | + | |
3a58abaf | 17504 | +static PyObject * |
7566401a | 17505 | +stpy_fullname (PyObject *self, PyObject *args) |
3a58abaf | 17506 | +{ |
7566401a | 17507 | + char *fullname; |
3a58abaf | 17508 | + |
7566401a ER |
17509 | + fullname = symtab_to_fullname (((symtab_object *) self)->symtab); |
17510 | + if (fullname) | |
17511 | + return PyString_Decode (fullname, strlen (fullname), host_charset (), NULL); | |
3a58abaf | 17512 | + |
7566401a | 17513 | + Py_RETURN_NONE; |
3a58abaf AM |
17514 | +} |
17515 | + | |
3a58abaf | 17516 | +static PyObject * |
7566401a | 17517 | +salpy_str (PyObject *self) |
3a58abaf | 17518 | +{ |
7566401a ER |
17519 | + int ret; |
17520 | + char *s, *filename; | |
17521 | + sal_object *sal_obj; | |
3a58abaf | 17522 | + PyObject *result; |
3a58abaf | 17523 | + |
7566401a ER |
17524 | + sal_obj = (sal_object *) self; |
17525 | + filename = (sal_obj->symtab == (symtab_object *) Py_None)? "<unknown>" : | |
17526 | + sal_obj->symtab->symtab->filename; | |
17527 | + ret = asprintf (&s, "symbol and line for %s, line %d", filename, | |
17528 | + sal_obj->sal->line); | |
17529 | + if (ret < 0) | |
17530 | + Py_RETURN_NONE; | |
3a58abaf | 17531 | + |
7566401a ER |
17532 | + result = PyString_FromString (s); |
17533 | + xfree (s); | |
3a58abaf AM |
17534 | + |
17535 | + return result; | |
17536 | +} | |
17537 | + | |
3a58abaf | 17538 | +static PyObject * |
7566401a | 17539 | +salpy_get_pc (PyObject *self, void *closure) |
3a58abaf | 17540 | +{ |
7566401a | 17541 | + return PyLong_FromUnsignedLongLong (((sal_object *) self)->sal->pc); |
3a58abaf AM |
17542 | +} |
17543 | + | |
3a58abaf | 17544 | +static PyObject * |
7566401a | 17545 | +salpy_get_line (PyObject *self, void *closure) |
3a58abaf | 17546 | +{ |
7566401a | 17547 | + return PyLong_FromUnsignedLongLong (((sal_object *) self)->sal->line); |
3a58abaf AM |
17548 | +} |
17549 | + | |
3a58abaf | 17550 | +static PyObject * |
7566401a | 17551 | +salpy_get_symtab (PyObject *self, void *closure) |
3a58abaf | 17552 | +{ |
7566401a | 17553 | + sal_object *self_sal = (sal_object *) self; |
3a58abaf | 17554 | + |
7566401a | 17555 | + Py_INCREF (self_sal->symtab); |
3a58abaf | 17556 | + |
7566401a | 17557 | + return (PyObject *) self_sal->symtab; |
3a58abaf AM |
17558 | +} |
17559 | + | |
7566401a ER |
17560 | +static void |
17561 | +salpy_dealloc (PyObject *self) | |
3a58abaf | 17562 | +{ |
7566401a | 17563 | + sal_object *self_sal = (sal_object *) self; |
3a58abaf | 17564 | + |
7566401a ER |
17565 | + Py_DECREF (self_sal->symtab); |
17566 | + xfree (self_sal->sal); | |
17567 | + self_sal->ob_type->tp_free (self); | |
3a58abaf AM |
17568 | +} |
17569 | + | |
7566401a ER |
17570 | +PyObject * |
17571 | +symtab_and_line_to_sal_object (struct symtab_and_line sal) | |
3a58abaf | 17572 | +{ |
7566401a ER |
17573 | + sal_object *sal_obj; |
17574 | + symtab_object *symtab_obj; | |
3a58abaf | 17575 | + |
7566401a ER |
17576 | + sal_obj = PyObject_New (sal_object, &sal_object_type); |
17577 | + if (sal_obj == NULL) | |
3a58abaf | 17578 | + { |
7566401a ER |
17579 | + PyErr_SetString (PyExc_MemoryError, |
17580 | + "Could not allocate Symtab_and_line object."); | |
3a58abaf AM |
17581 | + return NULL; |
17582 | + } | |
17583 | + | |
7566401a ER |
17584 | + if (sal.symtab) |
17585 | + { | |
17586 | + symtab_obj = (symtab_object *) symtab_to_symtab_object (sal.symtab); | |
17587 | + if (symtab_obj == NULL) | |
17588 | + { | |
17589 | + Py_DECREF (sal_obj); | |
17590 | + return NULL; | |
17591 | + } | |
3a58abaf | 17592 | + |
7566401a ER |
17593 | + symtab_obj->symtab = sal.symtab; |
17594 | + } | |
17595 | + else | |
3a58abaf | 17596 | + { |
7566401a ER |
17597 | + symtab_obj = (symtab_object *) Py_None; |
17598 | + Py_INCREF (Py_None); | |
3a58abaf | 17599 | + } |
3a58abaf | 17600 | + |
7566401a ER |
17601 | + sal_obj->sal = (struct symtab_and_line *) |
17602 | + xmalloc (sizeof (struct symtab_and_line)); | |
17603 | + *(sal_obj->sal) = sal; | |
17604 | + sal_obj->symtab = symtab_obj; | |
17605 | + | |
17606 | + return (PyObject *) sal_obj; | |
3a58abaf AM |
17607 | +} |
17608 | + | |
7566401a ER |
17609 | +PyObject * |
17610 | +symtab_to_symtab_object (struct symtab *symtab) | |
3a58abaf | 17611 | +{ |
7566401a ER |
17612 | + symtab_object *symtab_obj; |
17613 | + | |
17614 | + symtab_obj = PyObject_New (symtab_object, &symtab_object_type); | |
17615 | + if (symtab_obj == NULL) | |
3a58abaf | 17616 | + { |
7566401a ER |
17617 | + PyErr_SetString (PyExc_MemoryError, |
17618 | + "Could not allocate Symtab object."); | |
17619 | + | |
17620 | + return NULL; | |
3a58abaf | 17621 | + } |
3a58abaf | 17622 | + |
7566401a ER |
17623 | + symtab_obj->symtab = symtab; |
17624 | + | |
17625 | + return (PyObject *) symtab_obj; | |
3a58abaf AM |
17626 | +} |
17627 | + | |
7566401a ER |
17628 | +void |
17629 | +gdbpy_initialize_symtabs (void) | |
3a58abaf | 17630 | +{ |
7566401a ER |
17631 | + symtab_object_type.tp_new = PyType_GenericNew; |
17632 | + if (PyType_Ready (&symtab_object_type) < 0) | |
17633 | + return; | |
3a58abaf | 17634 | + |
7566401a ER |
17635 | + sal_object_type.tp_new = PyType_GenericNew; |
17636 | + if (PyType_Ready (&sal_object_type) < 0) | |
17637 | + return; | |
17638 | + | |
17639 | + Py_INCREF (&symtab_object_type); | |
17640 | + PyModule_AddObject (gdb_module, "Symtab", (PyObject *) &symtab_object_type); | |
3a58abaf | 17641 | + |
7566401a ER |
17642 | + Py_INCREF (&sal_object_type); |
17643 | + PyModule_AddObject (gdb_module, "Symtab_and_line", | |
17644 | + (PyObject *) &sal_object_type); | |
3a58abaf AM |
17645 | +} |
17646 | + | |
7566401a | 17647 | +\f |
3a58abaf | 17648 | + |
7566401a ER |
17649 | +static PyGetSetDef symtab_object_getset[] = { |
17650 | + { "filename", stpy_get_filename, NULL, | |
17651 | + "The symbol table's source filename.", NULL }, | |
17652 | + { "objfile", stpy_get_objfile, NULL, "The symtab's objfile.", | |
17653 | + NULL }, | |
17654 | + {NULL} /* Sentinel */ | |
17655 | +}; | |
3a58abaf | 17656 | + |
7566401a ER |
17657 | +static PyMethodDef symtab_object_methods[] = { |
17658 | + { "fullname", stpy_fullname, METH_NOARGS, | |
17659 | + "Return the symtab's full source filename." }, | |
17660 | + {NULL} /* Sentinel */ | |
17661 | +}; | |
3a58abaf | 17662 | + |
7566401a ER |
17663 | +static PyTypeObject symtab_object_type = { |
17664 | + PyObject_HEAD_INIT (NULL) | |
17665 | + 0, /*ob_size*/ | |
17666 | + "gdb.Symtab", /*tp_name*/ | |
17667 | + sizeof (symtab_object), /*tp_basicsize*/ | |
17668 | + 0, /*tp_itemsize*/ | |
17669 | + 0, /*tp_dealloc*/ | |
17670 | + 0, /*tp_print*/ | |
17671 | + 0, /*tp_getattr*/ | |
17672 | + 0, /*tp_setattr*/ | |
17673 | + 0, /*tp_compare*/ | |
17674 | + 0, /*tp_repr*/ | |
17675 | + 0, /*tp_as_number*/ | |
17676 | + 0, /*tp_as_sequence*/ | |
17677 | + 0, /*tp_as_mapping*/ | |
17678 | + 0, /*tp_hash */ | |
17679 | + 0, /*tp_call*/ | |
17680 | + stpy_str, /*tp_str*/ | |
17681 | + 0, /*tp_getattro*/ | |
17682 | + 0, /*tp_setattro*/ | |
17683 | + 0, /*tp_as_buffer*/ | |
17684 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
17685 | + "GDB symtab object", /* tp_doc */ | |
17686 | + 0, /* tp_traverse */ | |
17687 | + 0, /* tp_clear */ | |
17688 | + 0, /* tp_richcompare */ | |
17689 | + 0, /* tp_weaklistoffset */ | |
17690 | + 0, /* tp_iter */ | |
17691 | + 0, /* tp_iternext */ | |
17692 | + symtab_object_methods, /* tp_methods */ | |
17693 | + 0, /* tp_members */ | |
17694 | + symtab_object_getset /* tp_getset */ | |
17695 | +}; | |
3a58abaf | 17696 | + |
7566401a ER |
17697 | +static PyGetSetDef sal_object_getset[] = { |
17698 | + { "symtab", salpy_get_symtab, NULL, "Symtab object.", NULL }, | |
17699 | + { "pc", salpy_get_pc, NULL, "Return the symtab_and_line's pc.", NULL }, | |
17700 | + { "line", salpy_get_line, NULL, | |
17701 | + "Return the symtab_and_line's line.", NULL }, | |
17702 | + {NULL} /* Sentinel */ | |
17703 | +}; | |
3a58abaf | 17704 | + |
7566401a ER |
17705 | +static PyTypeObject sal_object_type = { |
17706 | + PyObject_HEAD_INIT (NULL) | |
17707 | + 0, /*ob_size*/ | |
17708 | + "gdb.Symtab_and_line", /*tp_name*/ | |
17709 | + sizeof (sal_object), /*tp_basicsize*/ | |
17710 | + 0, /*tp_itemsize*/ | |
17711 | + salpy_dealloc, /*tp_dealloc*/ | |
17712 | + 0, /*tp_print*/ | |
17713 | + 0, /*tp_getattr*/ | |
17714 | + 0, /*tp_setattr*/ | |
17715 | + 0, /*tp_compare*/ | |
17716 | + 0, /*tp_repr*/ | |
17717 | + 0, /*tp_as_number*/ | |
17718 | + 0, /*tp_as_sequence*/ | |
17719 | + 0, /*tp_as_mapping*/ | |
17720 | + 0, /*tp_hash */ | |
17721 | + 0, /*tp_call*/ | |
17722 | + salpy_str, /*tp_str*/ | |
17723 | + 0, /*tp_getattro*/ | |
17724 | + 0, /*tp_setattro*/ | |
17725 | + 0, /*tp_as_buffer*/ | |
17726 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
17727 | + "GDB symtab_and_line object", /* tp_doc */ | |
17728 | + 0, /* tp_traverse */ | |
17729 | + 0, /* tp_clear */ | |
17730 | + 0, /* tp_richcompare */ | |
17731 | + 0, /* tp_weaklistoffset */ | |
17732 | + 0, /* tp_iter */ | |
17733 | + 0, /* tp_iternext */ | |
17734 | + 0, /* tp_methods */ | |
17735 | + 0, /* tp_members */ | |
17736 | + sal_object_getset /* tp_getset */ | |
17737 | +}; | |
17738 | diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c | |
17739 | index 590d90a..f512248 100644 | |
17740 | --- a/gdb/python/py-type.c | |
17741 | +++ b/gdb/python/py-type.c | |
17742 | @@ -27,6 +27,8 @@ | |
17743 | #include "demangle.h" | |
17744 | #include "objfiles.h" | |
17745 | #include "language.h" | |
17746 | +#include "observer.h" | |
17747 | +#include "gdb_assert.h" | |
17748 | ||
17749 | typedef struct pyty_type_object | |
17750 | { | |
17751 | @@ -35,11 +37,17 @@ typedef struct pyty_type_object | |
17752 | ||
17753 | /* If a Type object is associated with an objfile, it is kept on a | |
17754 | doubly-linked list, rooted in the objfile. This lets us copy the | |
17755 | - underlying struct type when the objfile is deleted. */ | |
17756 | + underlying struct type when the objfile is deleted. | |
3a58abaf | 17757 | + |
7566401a ER |
17758 | + With NULL objfile Type still can be doubly-linked in the list |
17759 | + PYTY_OBJECTS_DISCARDABLE. */ | |
17760 | struct pyty_type_object *prev; | |
17761 | struct pyty_type_object *next; | |
17762 | } type_object; | |
17763 | ||
17764 | +/* First element of a doubly-linked list of TYPE_DISCARDABLE Types. */ | |
17765 | +static type_object *pyty_objects_discardable; | |
3a58abaf | 17766 | + |
7566401a ER |
17767 | static PyTypeObject type_object_type; |
17768 | ||
17769 | /* A Field object. */ | |
17770 | @@ -169,6 +177,11 @@ convert_field (struct type *type, int field) | |
17771 | if (PyObject_SetAttrString (result, "artificial", arg) < 0) | |
17772 | goto failarg; | |
17773 | ||
17774 | + arg = field < TYPE_N_BASECLASSES (type) ? Py_True : Py_False; | |
17775 | + Py_INCREF (arg); | |
17776 | + if (PyObject_SetAttrString (result, "is_base_class", arg) < 0) | |
17777 | + goto failarg; | |
3a58abaf | 17778 | + |
7566401a ER |
17779 | arg = PyLong_FromLong (TYPE_FIELD_BITSIZE (type, field)); |
17780 | if (!arg) | |
17781 | goto fail; | |
17782 | @@ -361,7 +374,7 @@ typy_get_sizeof (PyObject *self, void *closure) | |
17783 | } | |
17784 | ||
17785 | static struct type * | |
17786 | -typy_lookup_typename (char *type_name) | |
17787 | +typy_lookup_typename (char *type_name, struct block *block) | |
17788 | { | |
17789 | struct type *type = NULL; | |
17790 | volatile struct gdb_exception except; | |
17791 | @@ -375,7 +388,7 @@ typy_lookup_typename (char *type_name) | |
17792 | type = lookup_enum (type_name + 5, NULL); | |
17793 | else | |
17794 | type = lookup_typename (python_language, python_gdbarch, | |
17795 | - type_name, NULL, 0); | |
17796 | + type_name, block, 0); | |
17797 | } | |
17798 | if (except.reason < 0) | |
17799 | { | |
17800 | @@ -389,7 +402,8 @@ typy_lookup_typename (char *type_name) | |
17801 | } | |
17802 | ||
17803 | static struct type * | |
17804 | -typy_lookup_type (struct demangle_component *demangled) | |
17805 | +typy_lookup_type (struct demangle_component *demangled, | |
17806 | + struct block *block) | |
17807 | { | |
17808 | struct type *type; | |
17809 | char *type_name; | |
17810 | @@ -404,7 +418,7 @@ typy_lookup_type (struct demangle_component *demangled) | |
17811 | || demangled_type == DEMANGLE_COMPONENT_CONST | |
17812 | || demangled_type == DEMANGLE_COMPONENT_VOLATILE) | |
17813 | { | |
17814 | - type = typy_lookup_type (demangled->u.s_binary.left); | |
17815 | + type = typy_lookup_type (demangled->u.s_binary.left, block); | |
17816 | if (! type) | |
17817 | return NULL; | |
17818 | ||
17819 | @@ -422,7 +436,7 @@ typy_lookup_type (struct demangle_component *demangled) | |
17820 | } | |
17821 | ||
17822 | type_name = cp_comp_to_string (demangled, 10); | |
17823 | - type = typy_lookup_typename (type_name); | |
3a58abaf | 17824 | + type = typy_lookup_typename (type_name, block); |
7566401a ER |
17825 | xfree (type_name); |
17826 | ||
17827 | return type; | |
17828 | @@ -436,10 +450,23 @@ typy_template_argument (PyObject *self, PyObject *args) | |
17829 | struct demangle_component *demangled; | |
17830 | const char *err; | |
17831 | struct type *argtype; | |
3a58abaf AM |
17832 | + struct block *block = NULL; |
17833 | + PyObject *block_obj = NULL; | |
7566401a ER |
17834 | |
17835 | - if (! PyArg_ParseTuple (args, "i", &argno)) | |
3a58abaf | 17836 | + if (! PyArg_ParseTuple (args, "i|O", &argno, &block_obj)) |
7566401a ER |
17837 | return NULL; |
17838 | ||
3a58abaf AM |
17839 | + if (block_obj) |
17840 | + { | |
17841 | + block = block_object_to_block (block_obj); | |
17842 | + if (! block) | |
17843 | + { | |
17844 | + PyErr_SetString (PyExc_RuntimeError, | |
17845 | + "second argument must be block"); | |
17846 | + return NULL; | |
17847 | + } | |
17848 | + } | |
17849 | + | |
7566401a ER |
17850 | type = check_typedef (type); |
17851 | if (TYPE_CODE (type) == TYPE_CODE_REF) | |
17852 | type = check_typedef (TYPE_TARGET_TYPE (type)); | |
17853 | @@ -482,7 +509,7 @@ typy_template_argument (PyObject *self, PyObject *args) | |
17854 | return NULL; | |
17855 | } | |
17856 | ||
17857 | - argtype = typy_lookup_type (demangled->u.s_binary.left); | |
3a58abaf | 17858 | + argtype = typy_lookup_type (demangled->u.s_binary.left, block); |
7566401a ER |
17859 | if (! argtype) |
17860 | return NULL; | |
17861 | ||
17862 | @@ -524,8 +551,59 @@ typy_str (PyObject *self) | |
17863 | ||
17864 | \f | |
17865 | ||
17866 | +/* Key associated with each objfile pointing to the first element of | |
17867 | + a doubly-linked list of Types associated with this objfile. */ | |
17868 | static const struct objfile_data *typy_objfile_data_key; | |
17869 | ||
17870 | +/* Link TYPE_OBJ to its appropriate list. Either to its objfile associated one | |
17871 | + or at least to the global list for TYPE_DISCARDABLE Types. Permanent types | |
17872 | + do not get linked anywhere. */ | |
17873 | +static void | |
17874 | +typy_link (type_object *type_obj) | |
3a58abaf | 17875 | +{ |
7566401a | 17876 | + type_obj->prev = NULL; |
3a58abaf | 17877 | + |
7566401a | 17878 | + if (type_obj->type && TYPE_OBJFILE (type_obj->type)) |
3a58abaf | 17879 | + { |
7566401a | 17880 | + struct objfile *objfile = TYPE_OBJFILE (type_obj->type); |
3a58abaf | 17881 | + |
7566401a ER |
17882 | + type_obj->next = objfile_data (objfile, typy_objfile_data_key); |
17883 | + if (type_obj->next) | |
17884 | + type_obj->next->prev = type_obj; | |
17885 | + set_objfile_data (objfile, typy_objfile_data_key, type_obj); | |
3a58abaf | 17886 | + } |
7566401a | 17887 | + else if (type_obj->type && TYPE_DISCARDABLE (type_obj->type)) |
3a58abaf | 17888 | + { |
7566401a ER |
17889 | + type_obj->next = pyty_objects_discardable; |
17890 | + if (type_obj->next) | |
17891 | + type_obj->next->prev = type_obj; | |
17892 | + pyty_objects_discardable = type_obj; | |
3a58abaf | 17893 | + } |
7566401a ER |
17894 | + else |
17895 | + type_obj->next = NULL; | |
3a58abaf AM |
17896 | +} |
17897 | + | |
7566401a ER |
17898 | +/* Unlink TYPE_OBJ from its current list. Permanent types are not linked |
17899 | + anywhere and this function has no effect on them. */ | |
3a58abaf | 17900 | +static void |
7566401a | 17901 | +typy_unlink (type_object *type_obj) |
3a58abaf | 17902 | +{ |
7566401a ER |
17903 | + if (type_obj->prev) |
17904 | + type_obj->prev->next = type_obj->next; | |
17905 | + else if (type_obj->type && TYPE_OBJFILE (type_obj->type)) | |
3a58abaf | 17906 | + { |
7566401a ER |
17907 | + /* Must reset head of list. */ |
17908 | + struct objfile *objfile = TYPE_OBJFILE (type_obj->type); | |
3a58abaf | 17909 | + |
7566401a | 17910 | + set_objfile_data (objfile, typy_objfile_data_key, type_obj->next); |
3a58abaf | 17911 | + } |
7566401a ER |
17912 | + else if (pyty_objects_discardable == type_obj) |
17913 | + pyty_objects_discardable = type_obj->next; | |
3a58abaf | 17914 | + |
7566401a ER |
17915 | + if (type_obj->next) |
17916 | + type_obj->next->prev = type_obj->prev; | |
3a58abaf AM |
17917 | +} |
17918 | + | |
7566401a ER |
17919 | static void |
17920 | save_objfile_types (struct objfile *objfile, void *datum) | |
17921 | { | |
17922 | @@ -543,12 +621,13 @@ save_objfile_types (struct objfile *objfile, void *datum) | |
17923 | { | |
17924 | type_object *next = obj->next; | |
17925 | ||
17926 | - htab_empty (copied_types); | |
17927 | + gdb_assert (TYPE_OBJFILE (obj->type) == objfile); | |
17928 | + typy_unlink (obj); | |
17929 | ||
17930 | - obj->type = copy_type_recursive (objfile, obj->type, copied_types); | |
17931 | + obj->type = copy_type_recursive (obj->type, copied_types); | |
17932 | ||
17933 | - obj->next = NULL; | |
17934 | - obj->prev = NULL; | |
17935 | + gdb_assert (TYPE_OBJFILE (obj->type) == NULL); | |
17936 | + typy_link (obj); | |
17937 | ||
17938 | obj = next; | |
17939 | } | |
17940 | @@ -559,41 +638,25 @@ save_objfile_types (struct objfile *objfile, void *datum) | |
17941 | } | |
17942 | ||
17943 | static void | |
17944 | -set_type (type_object *obj, struct type *type) | |
3a58abaf | 17945 | +typy_dealloc (PyObject *obj) |
7566401a ER |
17946 | { |
17947 | - obj->type = type; | |
17948 | - obj->prev = NULL; | |
17949 | - if (type && TYPE_OBJFILE (type)) | |
17950 | - { | |
17951 | - struct objfile *objfile = TYPE_OBJFILE (type); | |
17952 | + type_object *type_obj = (type_object *) obj; | |
17953 | ||
17954 | - obj->next = objfile_data (objfile, typy_objfile_data_key); | |
17955 | - if (obj->next) | |
17956 | - obj->next->prev = obj; | |
17957 | - set_objfile_data (objfile, typy_objfile_data_key, obj); | |
17958 | - } | |
17959 | - else | |
17960 | - obj->next = NULL; | |
17961 | + typy_unlink (type_obj); | |
3a58abaf | 17962 | + |
7566401a ER |
17963 | + type_obj->ob_type->tp_free (obj); |
17964 | } | |
17965 | ||
17966 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ | |
17967 | static void | |
17968 | -typy_dealloc (PyObject *obj) | |
17969 | +typy_types_mark_used (void) | |
17970 | { | |
17971 | - type_object *type = (type_object *) obj; | |
17972 | - | |
17973 | - if (type->prev) | |
17974 | - type->prev->next = type->next; | |
17975 | - else if (type->type && TYPE_OBJFILE (type->type)) | |
17976 | - { | |
17977 | - /* Must reset head of list. */ | |
17978 | - struct objfile *objfile = TYPE_OBJFILE (type->type); | |
17979 | - if (objfile) | |
17980 | - set_objfile_data (objfile, typy_objfile_data_key, type->next); | |
17981 | - } | |
17982 | - if (type->next) | |
17983 | - type->next->prev = type->prev; | |
17984 | + type_object *type_obj; | |
17985 | ||
17986 | - type->ob_type->tp_free (type); | |
17987 | + for (type_obj = pyty_objects_discardable; | |
17988 | + type_obj != NULL; | |
17989 | + type_obj = type_obj->next) | |
17990 | + type_mark_used (type_obj->type); | |
17991 | } | |
17992 | ||
17993 | /* Create a new Type referring to TYPE. */ | |
17994 | @@ -604,7 +667,10 @@ type_to_type_object (struct type *type) | |
17995 | ||
17996 | type_obj = PyObject_New (type_object, &type_object_type); | |
17997 | if (type_obj) | |
17998 | - set_type (type_obj, type); | |
3a58abaf | 17999 | + { |
7566401a ER |
18000 | + type_obj->type = type; |
18001 | + typy_link (type_obj); | |
3a58abaf | 18002 | + } |
7566401a ER |
18003 | |
18004 | return (PyObject *) type_obj; | |
18005 | } | |
18006 | @@ -623,14 +689,28 @@ type_object_to_type (PyObject *obj) | |
18007 | PyObject * | |
18008 | gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw) | |
18009 | { | |
18010 | - static char *keywords[] = { "name", NULL }; | |
18011 | + static char *keywords[] = { "name", "block", NULL }; | |
18012 | char *type_name = NULL; | |
18013 | struct type *type = NULL; | |
18014 | + PyObject *block_obj = NULL; | |
18015 | + struct block *block = NULL; | |
18016 | ||
18017 | - if (! PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &type_name)) | |
18018 | + if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O", keywords, | |
18019 | + &type_name, &block_obj)) | |
18020 | return NULL; | |
18021 | ||
18022 | - type = typy_lookup_typename (type_name); | |
18023 | + if (block_obj) | |
3a58abaf | 18024 | + { |
7566401a ER |
18025 | + block = block_object_to_block (block_obj); |
18026 | + if (! block) | |
18027 | + { | |
18028 | + PyErr_SetString (PyExc_RuntimeError, | |
18029 | + "'block' argument must be a Block"); | |
18030 | + return NULL; | |
18031 | + } | |
3a58abaf AM |
18032 | + } |
18033 | + | |
7566401a ER |
18034 | + type = typy_lookup_typename (type_name, block); |
18035 | if (! type) | |
18036 | return NULL; | |
18037 | ||
18038 | @@ -664,6 +744,8 @@ gdbpy_initialize_types (void) | |
18039 | ||
18040 | Py_INCREF (&field_object_type); | |
18041 | PyModule_AddObject (gdb_module, "Field", (PyObject *) &field_object_type); | |
3a58abaf | 18042 | + |
7566401a ER |
18043 | + observer_attach_mark_used (typy_types_mark_used); |
18044 | } | |
18045 | ||
18046 | \f | |
18047 | diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c | |
18048 | index 49c0437..84a476e 100644 | |
18049 | --- a/gdb/python/py-utils.c | |
18050 | +++ b/gdb/python/py-utils.c | |
3a58abaf AM |
18051 | @@ -19,6 +19,7 @@ |
18052 | ||
18053 | #include "defs.h" | |
18054 | #include "charset.h" | |
18055 | +#include "value.h" | |
18056 | #include "python-internal.h" | |
18057 | ||
18058 | ||
7566401a | 18059 | @@ -219,3 +220,48 @@ gdbpy_is_string (PyObject *obj) |
3a58abaf AM |
18060 | { |
18061 | return PyString_Check (obj) || PyUnicode_Check (obj); | |
18062 | } | |
18063 | + | |
18064 | +/* Converts OBJ to a CORE_ADDR value. | |
18065 | + | |
18066 | + Returns 1 on success or 0 on failure, with a Python exception set. This | |
18067 | + function can also throw GDB exceptions. */ | |
18068 | + | |
18069 | +int | |
18070 | +get_addr_from_python (PyObject *obj, CORE_ADDR *addr) | |
18071 | +{ | |
18072 | + if (gdbpy_is_value_object (obj)) | |
18073 | + *addr = value_as_address (value_object_to_value (obj)); | |
18074 | + else if (PyLong_Check (obj)) | |
18075 | + { | |
18076 | + /* Assume CORE_ADDR corresponds to unsigned long. */ | |
18077 | + *addr = PyLong_AsUnsignedLong (obj); | |
18078 | + if (PyErr_Occurred () != NULL) | |
18079 | + return 0; | |
18080 | + } | |
18081 | + else if (PyInt_Check (obj)) | |
18082 | + { | |
18083 | + long val; | |
18084 | + | |
18085 | + /* Assume CORE_ADDR corresponds to unsigned long. */ | |
18086 | + val = PyInt_AsLong (obj); | |
18087 | + | |
18088 | + if (val >= 0) | |
18089 | + *addr = val; | |
18090 | + else | |
18091 | + { | |
18092 | + /* If no error ocurred, VAL is indeed negative. */ | |
18093 | + if (PyErr_Occurred () != NULL) | |
18094 | + return 0; | |
18095 | + | |
18096 | + PyErr_SetString (PyExc_ValueError, "negative address"); | |
18097 | + return 0; | |
18098 | + } | |
18099 | + } | |
18100 | + else | |
18101 | + { | |
18102 | + PyErr_SetString (PyExc_TypeError, "invalid type for address"); | |
18103 | + return 0; | |
18104 | + } | |
18105 | + | |
18106 | + return 1; | |
18107 | +} | |
7566401a | 18108 | diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c |
ab050a48 | 18109 | index 0146593..b82fcb6 100644 |
7566401a ER |
18110 | --- a/gdb/python/py-value.c |
18111 | +++ b/gdb/python/py-value.c | |
18112 | @@ -25,6 +25,7 @@ | |
18113 | #include "language.h" | |
18114 | #include "dfp.h" | |
18115 | #include "valprint.h" | |
18116 | +#include "observer.h" | |
18117 | ||
18118 | #ifdef HAVE_PYTHON | |
18119 | ||
18120 | @@ -43,6 +44,10 @@ | |
3a58abaf | 18121 | /* Python's long type corresponds to C's long long type. */ |
7566401a | 18122 | #define builtin_type_pylong builtin_type (python_gdbarch)->builtin_long_long |
3a58abaf AM |
18123 | |
18124 | +/* Python's long type corresponds to C's long long type. Unsigned version. */ | |
18125 | +#define builtin_type_upylong builtin_type \ | |
7566401a | 18126 | + (python_gdbarch)->builtin_unsigned_long_long |
3a58abaf AM |
18127 | + |
18128 | #define builtin_type_pybool \ | |
7566401a | 18129 | language_bool_type (python_language, python_gdbarch) |
3a58abaf | 18130 | |
7566401a | 18131 | @@ -913,7 +918,34 @@ convert_value_from_python (PyObject *obj) |
3a58abaf AM |
18132 | { |
18133 | LONGEST l = PyLong_AsLongLong (obj); | |
18134 | ||
18135 | - if (! PyErr_Occurred ()) | |
18136 | + if (PyErr_Occurred ()) | |
18137 | + { | |
18138 | + /* If the error was an overflow, we can try converting to | |
18139 | + ULONGEST instead. */ | |
18140 | + if (PyErr_ExceptionMatches (PyExc_OverflowError)) | |
18141 | + { | |
18142 | + PyObject *etype, *evalue, *etraceback, *zero; | |
18143 | + | |
18144 | + PyErr_Fetch (&etype, &evalue, &etraceback); | |
18145 | + zero = PyInt_FromLong (0); | |
18146 | + | |
18147 | + /* Check whether obj is positive. */ | |
18148 | + if (PyObject_RichCompareBool (obj, zero, Py_GT) > 0) | |
18149 | + { | |
18150 | + ULONGEST ul; | |
18151 | + | |
18152 | + ul = PyLong_AsUnsignedLongLong (obj); | |
18153 | + if (! PyErr_Occurred ()) | |
18154 | + value = value_from_ulongest (builtin_type_upylong, ul); | |
18155 | + } | |
18156 | + else | |
18157 | + /* There's nothing we can do. */ | |
18158 | + PyErr_Restore (etype, evalue, etraceback); | |
18159 | + | |
18160 | + Py_DECREF (zero); | |
18161 | + } | |
18162 | + } | |
18163 | + else | |
18164 | value = value_from_longest (builtin_type_pylong, l); | |
18165 | } | |
18166 | else if (PyFloat_Check (obj)) | |
7566401a | 18167 | @@ -972,6 +1004,25 @@ gdbpy_history (PyObject *self, PyObject *args) |
3a58abaf AM |
18168 | return value_to_value_object (res_val); |
18169 | } | |
18170 | ||
7566401a ER |
18171 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ |
18172 | + | |
18173 | +static void | |
18174 | +python_types_mark_used (void) | |
18175 | +{ | |
18176 | + value_object *iter; | |
18177 | + | |
18178 | + for (iter = values_in_python; iter; iter = iter->next) | |
18179 | + type_mark_used (value_type (iter->value)); | |
18180 | +} | |
18181 | + | |
3a58abaf AM |
18182 | +/* Returns 1 in OBJ is a gdb.Value object, 0 otherwise. */ |
18183 | + | |
18184 | +int | |
18185 | +gdbpy_is_value_object (PyObject *obj) | |
18186 | +{ | |
18187 | + return PyObject_TypeCheck (obj, &value_object_type); | |
18188 | +} | |
18189 | + | |
18190 | void | |
18191 | gdbpy_initialize_values (void) | |
18192 | { | |
7566401a ER |
18193 | @@ -982,6 +1033,8 @@ gdbpy_initialize_values (void) |
18194 | PyModule_AddObject (gdb_module, "Value", (PyObject *) &value_object_type); | |
3a58abaf | 18195 | |
7566401a | 18196 | values_in_python = NULL; |
3a58abaf | 18197 | + |
7566401a ER |
18198 | + observer_attach_mark_used (python_types_mark_used); |
18199 | } | |
3a58abaf | 18200 | |
7566401a ER |
18201 | \f |
18202 | diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h | |
18203 | index 67a78af..47662d9 100644 | |
18204 | --- a/gdb/python/python-internal.h | |
18205 | +++ b/gdb/python/python-internal.h | |
18206 | @@ -61,33 +61,76 @@ typedef int Py_ssize_t; | |
18207 | #define PyEval_ReleaseLock() 0 | |
18208 | #endif | |
3a58abaf | 18209 | |
7566401a ER |
18210 | +#include "command.h" |
18211 | + | |
18212 | +struct block; | |
18213 | +struct symbol; | |
18214 | +struct symtab_and_line; | |
18215 | struct value; | |
18216 | struct language_defn; | |
18217 | ||
18218 | extern PyObject *gdb_module; | |
18219 | +extern PyTypeObject block_object_type; | |
18220 | extern PyTypeObject value_object_type; | |
18221 | +extern PyTypeObject symbol_object_type; | |
18222 | + | |
18223 | +/* Used in python-inferior.c. */ | |
18224 | +typedef struct | |
18225 | +{ | |
18226 | + PyObject_HEAD | |
18227 | + | |
18228 | + /* The thread we represent. */ | |
18229 | + struct thread_info *thread; | |
18230 | + | |
18231 | + /* The Inferior object to which this thread belongs. */ | |
18232 | + PyObject *inf_obj; | |
18233 | +} thread_object; | |
18234 | ||
18235 | PyObject *gdbpy_history (PyObject *self, PyObject *args); | |
18236 | +PyObject *gdbpy_breakpoints (PyObject *, PyObject *); | |
18237 | PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *); | |
18238 | +PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw); | |
18239 | PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args); | |
18240 | +PyObject *gdbpy_block_for_pc (PyObject *self, PyObject *args); | |
18241 | PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw); | |
18242 | +PyObject *gdbpy_inferiors (PyObject *unused, PyObject *unused2); | |
18243 | +PyObject *gdbpy_selected_thread (PyObject *self, PyObject *args); | |
18244 | ||
18245 | +PyObject *symtab_and_line_to_sal_object (struct symtab_and_line sal); | |
18246 | +PyObject *symtab_to_symtab_object (struct symtab *symtab); | |
18247 | +PyObject *symbol_to_symbol_object (struct symbol *sym); | |
18248 | +PyObject *block_to_block_object (struct block *block); | |
18249 | PyObject *value_to_value_object (struct value *v); | |
18250 | PyObject *type_to_type_object (struct type *); | |
18251 | PyObject *objfile_to_objfile_object (struct objfile *); | |
18252 | +PyObject *frame_info_to_frame_object (struct frame_info *frame); | |
18253 | +thread_object *create_thread_object (struct thread_info *tp); | |
18254 | +thread_object *find_thread_object (ptid_t ptid); | |
18255 | +PyObject *find_inferior_object (int pid); | |
18256 | ||
18257 | PyObject *objfpy_get_printers (PyObject *, void *); | |
3a58abaf | 18258 | |
7566401a ER |
18259 | +struct block *block_object_to_block (PyObject *obj); |
18260 | +struct symbol *symbol_object_to_symbol (PyObject *obj); | |
18261 | struct value *value_object_to_value (PyObject *self); | |
18262 | struct value *convert_value_from_python (PyObject *obj); | |
18263 | struct type *type_object_to_type (PyObject *obj); | |
3a58abaf | 18264 | |
7566401a | 18265 | +PyObject *gdbpy_get_hook_function (const char *); |
3a58abaf | 18266 | + |
7566401a ER |
18267 | void gdbpy_initialize_values (void); |
18268 | +void gdbpy_initialize_breakpoints (void); | |
18269 | void gdbpy_initialize_frames (void); | |
18270 | +void gdbpy_initialize_symtabs (void); | |
18271 | void gdbpy_initialize_commands (void); | |
18272 | +void gdbpy_initialize_symbols (void); | |
18273 | void gdbpy_initialize_types (void); | |
18274 | +void gdbpy_initialize_blocks (void); | |
18275 | void gdbpy_initialize_functions (void); | |
18276 | void gdbpy_initialize_objfile (void); | |
18277 | +void gdbpy_initialize_parameters (void); | |
18278 | +void gdbpy_initialize_thread (void); | |
18279 | +void gdbpy_initialize_inferior (void); | |
18280 | ||
18281 | struct cleanup *make_cleanup_py_decref (PyObject *py); | |
18282 | ||
18283 | @@ -97,6 +140,12 @@ struct cleanup *ensure_python_env (struct gdbarch *gdbarch, | |
18284 | extern struct gdbarch *python_gdbarch; | |
18285 | extern const struct language_defn *python_language; | |
18286 | ||
18287 | +char *gdbpy_parse_command_name (char *text, | |
18288 | + struct cmd_list_element ***base_list, | |
18289 | + struct cmd_list_element **start_list); | |
18290 | + | |
18291 | +PyObject *gdbpy_parameter_value (enum var_types, void *); | |
18292 | + | |
18293 | /* Use this after a TRY_EXCEPT to throw the appropriate Python | |
18294 | exception. */ | |
18295 | #define GDB_PY_HANDLE_EXCEPTION(Exception) \ | |
18296 | @@ -107,6 +156,19 @@ extern const struct language_defn *python_language; | |
18297 | "%s", Exception.message); \ | |
18298 | } while (0) | |
18299 | ||
18300 | +/* Use this after a TRY_EXCEPT to throw the appropriate Python | |
18301 | + exception. This macro is for use inside setter functions. */ | |
18302 | +#define GDB_PY_SET_HANDLE_EXCEPTION(Exception) \ | |
18303 | + do { \ | |
18304 | + if (Exception.reason < 0) \ | |
18305 | + { \ | |
18306 | + PyErr_Format (Exception.reason == RETURN_QUIT \ | |
18307 | + ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \ | |
18308 | + "%s", Exception.message); \ | |
18309 | + return -1; \ | |
18310 | + } \ | |
18311 | + } while (0) | |
18312 | + | |
18313 | ||
18314 | void gdbpy_print_stack (void); | |
18315 | ||
18316 | @@ -118,17 +180,22 @@ char *python_string_to_host_string (PyObject *obj); | |
18317 | PyObject *target_string_to_unicode (const gdb_byte *str, int length); | |
18318 | int gdbpy_is_string (PyObject *obj); | |
18319 | ||
18320 | +int gdbpy_is_value_object (PyObject *obj); | |
18321 | + | |
18322 | /* Note that these are declared here, and not in python.h with the | |
18323 | other pretty-printer functions, because they refer to PyObject. */ | |
18324 | PyObject *apply_varobj_pretty_printer (PyObject *print_obj, | |
18325 | struct value **replacement); | |
18326 | PyObject *gdbpy_get_varobj_pretty_printer (struct value *value); | |
18327 | +PyObject *gdbpy_instantiate_printer (PyObject *cons, PyObject *value); | |
18328 | char *gdbpy_get_display_hint (PyObject *printer); | |
18329 | PyObject *gdbpy_default_visualizer (PyObject *self, PyObject *args); | |
18330 | ||
18331 | -extern PyObject *gdbpy_doc_cst; | |
18332 | extern PyObject *gdbpy_children_cst; | |
18333 | extern PyObject *gdbpy_to_string_cst; | |
18334 | extern PyObject *gdbpy_display_hint_cst; | |
18335 | +extern PyObject *gdbpy_doc_cst; | |
18336 | + | |
18337 | +int get_addr_from_python (PyObject *obj, CORE_ADDR *addr); | |
18338 | ||
18339 | #endif /* GDB_PYTHON_INTERNAL_H */ | |
18340 | diff --git a/gdb/python/python.c b/gdb/python/python.c | |
18341 | index 254bd28..5a2a9ae 100644 | |
18342 | --- a/gdb/python/python.c | |
18343 | +++ b/gdb/python/python.c | |
18344 | @@ -27,6 +27,7 @@ | |
18345 | #include "observer.h" | |
18346 | #include "value.h" | |
18347 | #include "language.h" | |
18348 | +#include "event-loop.h" | |
18349 | ||
18350 | #include <ctype.h> | |
3a58abaf | 18351 | |
7566401a | 18352 | @@ -45,11 +46,18 @@ static int gdbpy_auto_load = 1; |
3a58abaf AM |
18353 | #include "cli/cli-decode.h" |
18354 | #include "charset.h" | |
18355 | #include "top.h" | |
18356 | +#include "solib.h" | |
18357 | #include "exceptions.h" | |
18358 | #include "python-internal.h" | |
18359 | +#include "linespec.h" | |
18360 | +#include "symtab.h" | |
18361 | +#include "source.h" | |
18362 | #include "version.h" | |
18363 | +#include "inferior.h" | |
18364 | +#include "gdbthread.h" | |
18365 | #include "target.h" | |
18366 | #include "gdbthread.h" | |
18367 | +#include "event-top.h" | |
3a58abaf AM |
18368 | |
18369 | static PyMethodDef GdbMethods[]; | |
18370 | ||
7566401a | 18371 | @@ -197,10 +205,10 @@ python_command (char *arg, int from_tty) |
3a58abaf AM |
18372 | NULL (and set a Python exception) on error. Helper function for |
18373 | get_parameter. */ | |
18374 | ||
18375 | -static PyObject * | |
18376 | -parameter_to_python (struct cmd_list_element *cmd) | |
18377 | +PyObject * | |
18378 | +gdbpy_parameter_value (enum var_types type, void *var) | |
18379 | { | |
18380 | - switch (cmd->var_type) | |
18381 | + switch (type) | |
18382 | { | |
18383 | case var_string: | |
18384 | case var_string_noescape: | |
7566401a | 18385 | @@ -208,7 +216,7 @@ parameter_to_python (struct cmd_list_element *cmd) |
3a58abaf AM |
18386 | case var_filename: |
18387 | case var_enum: | |
18388 | { | |
18389 | - char *str = * (char **) cmd->var; | |
18390 | + char *str = * (char **) var; | |
18391 | if (! str) | |
18392 | str = ""; | |
18393 | return PyString_Decode (str, strlen (str), host_charset (), NULL); | |
7566401a | 18394 | @@ -216,7 +224,7 @@ parameter_to_python (struct cmd_list_element *cmd) |
3a58abaf AM |
18395 | |
18396 | case var_boolean: | |
18397 | { | |
18398 | - if (* (int *) cmd->var) | |
18399 | + if (* (int *) var) | |
18400 | Py_RETURN_TRUE; | |
18401 | else | |
18402 | Py_RETURN_FALSE; | |
7566401a | 18403 | @@ -224,7 +232,7 @@ parameter_to_python (struct cmd_list_element *cmd) |
3a58abaf AM |
18404 | |
18405 | case var_auto_boolean: | |
18406 | { | |
18407 | - enum auto_boolean ab = * (enum auto_boolean *) cmd->var; | |
18408 | + enum auto_boolean ab = * (enum auto_boolean *) var; | |
18409 | if (ab == AUTO_BOOLEAN_TRUE) | |
18410 | Py_RETURN_TRUE; | |
18411 | else if (ab == AUTO_BOOLEAN_FALSE) | |
7566401a | 18412 | @@ -234,15 +242,15 @@ parameter_to_python (struct cmd_list_element *cmd) |
3a58abaf AM |
18413 | } |
18414 | ||
18415 | case var_integer: | |
18416 | - if ((* (int *) cmd->var) == INT_MAX) | |
18417 | + if ((* (int *) var) == INT_MAX) | |
18418 | Py_RETURN_NONE; | |
18419 | /* Fall through. */ | |
18420 | case var_zinteger: | |
18421 | - return PyLong_FromLong (* (int *) cmd->var); | |
18422 | + return PyLong_FromLong (* (int *) var); | |
18423 | ||
18424 | case var_uinteger: | |
18425 | { | |
18426 | - unsigned int val = * (unsigned int *) cmd->var; | |
18427 | + unsigned int val = * (unsigned int *) var; | |
18428 | if (val == UINT_MAX) | |
18429 | Py_RETURN_NONE; | |
18430 | return PyLong_FromUnsignedLong (val); | |
7566401a | 18431 | @@ -280,7 +288,7 @@ gdbpy_parameter (PyObject *self, PyObject *args) |
3a58abaf AM |
18432 | |
18433 | if (! cmd->var) | |
7566401a | 18434 | return PyErr_Format (PyExc_RuntimeError, "`%s' is not a parameter", arg); |
3a58abaf | 18435 | - return parameter_to_python (cmd); |
3a58abaf AM |
18436 | + return gdbpy_parameter_value (cmd->var_type, cmd->var); |
18437 | } | |
18438 | ||
18439 | /* A Python function which evaluates a string using the gdb CLI. */ | |
7566401a | 18440 | @@ -319,6 +327,233 @@ execute_gdb_command (PyObject *self, PyObject *args) |
3a58abaf AM |
18441 | Py_RETURN_NONE; |
18442 | } | |
18443 | ||
18444 | +/* Implementation of gdb.solib_address (Long) -> String. | |
18445 | + Returns the name of the shared library holding a given address, or None. */ | |
18446 | + | |
18447 | +static PyObject * | |
18448 | +gdbpy_solib_address (PyObject *self, PyObject *args) | |
18449 | +{ | |
18450 | + unsigned long long pc; | |
18451 | + char *soname; | |
18452 | + PyObject *str_obj; | |
18453 | + | |
18454 | + if (!PyArg_ParseTuple (args, "K", &pc)) | |
18455 | + return NULL; | |
18456 | + | |
7566401a | 18457 | + soname = solib_name_from_address (pc); |
3a58abaf AM |
18458 | + if (soname) |
18459 | + str_obj = PyString_Decode (soname, strlen (soname), host_charset (), NULL); | |
18460 | + else | |
18461 | + { | |
18462 | + str_obj = Py_None; | |
18463 | + Py_INCREF (Py_None); | |
18464 | + } | |
18465 | + | |
18466 | + return str_obj; | |
18467 | +} | |
18468 | + | |
7566401a ER |
18469 | +/* A Python function which is a wrapper for decode_line_1. */ |
18470 | + | |
3a58abaf | 18471 | +static PyObject * |
7566401a | 18472 | +gdbpy_decode_line (PyObject *self, PyObject *args) |
3a58abaf | 18473 | +{ |
7566401a ER |
18474 | + struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to appease gcc. */ |
18475 | + struct symtab_and_line sal; | |
18476 | + char *arg = NULL; | |
18477 | + int free_sals = 0, i; | |
18478 | + PyObject *result = NULL; | |
18479 | + volatile struct gdb_exception except; | |
3a58abaf | 18480 | + |
7566401a | 18481 | + if (! PyArg_ParseTuple (args, "|s", &arg)) |
3a58abaf AM |
18482 | + return NULL; |
18483 | + | |
7566401a ER |
18484 | + TRY_CATCH (except, RETURN_MASK_ALL) |
18485 | + { | |
18486 | + if (arg) | |
18487 | + { | |
18488 | + char *copy; | |
3a58abaf | 18489 | + |
7566401a ER |
18490 | + arg = strdup (arg); |
18491 | + copy = arg; | |
3a58abaf | 18492 | + |
7566401a ER |
18493 | + sals = decode_line_1 (©, 0, 0, 0, 0, 0); |
18494 | + free_sals = 1; | |
18495 | + } | |
18496 | + else | |
18497 | + { | |
18498 | + set_default_source_symtab_and_line (); | |
18499 | + sal = get_current_source_symtab_and_line (); | |
18500 | + sals.sals = &sal; | |
18501 | + sals.nelts = 1; | |
18502 | + } | |
18503 | + } | |
18504 | + if (arg) | |
18505 | + xfree (arg); | |
3a58abaf | 18506 | + |
7566401a | 18507 | + if (except.reason < 0) |
3a58abaf | 18508 | + { |
7566401a ER |
18509 | + if (free_sals) |
18510 | + xfree (sals.sals); | |
18511 | + /* We know this will always throw. */ | |
18512 | + GDB_PY_HANDLE_EXCEPTION (except); | |
18513 | + } | |
3a58abaf | 18514 | + |
7566401a ER |
18515 | + if (sals.nelts) |
18516 | + { | |
18517 | + result = PyTuple_New (sals.nelts); | |
18518 | + for (i = 0; i < sals.nelts; ++i) | |
3a58abaf | 18519 | + { |
7566401a ER |
18520 | + PyObject *obj; |
18521 | + char *str; | |
18522 | + | |
18523 | + obj = symtab_and_line_to_sal_object (sals.sals[i]); | |
18524 | + if (! obj) | |
18525 | + { | |
18526 | + Py_DECREF (result); | |
18527 | + result = NULL; | |
18528 | + break; | |
18529 | + } | |
18530 | + | |
18531 | + PyTuple_SetItem (result, i, obj); | |
3a58abaf AM |
18532 | + } |
18533 | + } | |
3a58abaf | 18534 | + |
7566401a ER |
18535 | + if (free_sals) |
18536 | + xfree (sals.sals); | |
3a58abaf | 18537 | + |
7566401a ER |
18538 | + if (result) |
18539 | + return result; | |
18540 | + Py_RETURN_NONE; | |
3a58abaf AM |
18541 | +} |
18542 | + | |
7566401a ER |
18543 | +/* Parse a string and evaluate it as an expression. */ |
18544 | +static PyObject * | |
18545 | +gdbpy_parse_and_eval (PyObject *self, PyObject *args) | |
18546 | +{ | |
18547 | + char *expr_str; | |
18548 | + struct value *result = NULL; | |
18549 | + volatile struct gdb_exception except; | |
3a58abaf | 18550 | + |
7566401a ER |
18551 | + if (!PyArg_ParseTuple (args, "s", &expr_str)) |
18552 | + return NULL; | |
3a58abaf | 18553 | + |
7566401a | 18554 | + TRY_CATCH (except, RETURN_MASK_ALL) |
3a58abaf | 18555 | + { |
7566401a ER |
18556 | + result = parse_and_eval (expr_str); |
18557 | + } | |
18558 | + GDB_PY_HANDLE_EXCEPTION (except); | |
3a58abaf | 18559 | + |
7566401a ER |
18560 | + return value_to_value_object (result); |
18561 | +} | |
3a58abaf | 18562 | + |
7566401a | 18563 | +\f |
3a58abaf | 18564 | + |
7566401a | 18565 | +/* Posting and handling events. */ |
3a58abaf AM |
18566 | + |
18567 | +/* A single event. */ | |
18568 | +struct gdbpy_event | |
18569 | +{ | |
18570 | + /* The Python event. This is just a callable object. */ | |
18571 | + PyObject *event; | |
18572 | + /* The next event. */ | |
18573 | + struct gdbpy_event *next; | |
18574 | +}; | |
18575 | + | |
18576 | +/* All pending events. */ | |
18577 | +static struct gdbpy_event *gdbpy_event_list; | |
18578 | +/* The final link of the event list. */ | |
18579 | +static struct gdbpy_event **gdbpy_event_list_end; | |
18580 | + | |
18581 | +/* We use a file handler, and not an async handler, so that we can | |
18582 | + wake up the main thread even when it is blocked in poll(). */ | |
18583 | +static int gdbpy_event_fds[2]; | |
18584 | + | |
18585 | +/* The file handler callback. This reads from the internal pipe, and | |
18586 | + then processes the Python event queue. This will always be run in | |
18587 | + the main gdb thread. */ | |
18588 | +static void | |
18589 | +gdbpy_run_events (int err, gdb_client_data ignore) | |
18590 | +{ | |
18591 | + PyGILState_STATE state; | |
18592 | + char buffer[100]; | |
18593 | + int r; | |
18594 | + | |
18595 | + state = PyGILState_Ensure (); | |
18596 | + | |
18597 | + /* Just read whatever is available on the fd. It is relatively | |
18598 | + harmless if there are any bytes left over. */ | |
18599 | + r = read (gdbpy_event_fds[0], buffer, sizeof (buffer)); | |
18600 | + | |
18601 | + while (gdbpy_event_list) | |
18602 | + { | |
18603 | + /* Dispatching the event might push a new element onto the event | |
18604 | + loop, so we update here "atomically enough". */ | |
18605 | + struct gdbpy_event *item = gdbpy_event_list; | |
18606 | + gdbpy_event_list = gdbpy_event_list->next; | |
18607 | + if (gdbpy_event_list == NULL) | |
18608 | + gdbpy_event_list_end = &gdbpy_event_list; | |
18609 | + | |
18610 | + /* Ignore errors. */ | |
18611 | + PyObject_CallObject (item->event, NULL); | |
18612 | + | |
18613 | + Py_DECREF (item->event); | |
18614 | + xfree (item); | |
18615 | + } | |
18616 | + | |
18617 | + PyGILState_Release (state); | |
18618 | +} | |
18619 | + | |
18620 | +/* Submit an event to the gdb thread. */ | |
18621 | +static PyObject * | |
18622 | +gdbpy_post_event (PyObject *self, PyObject *args) | |
18623 | +{ | |
18624 | + struct gdbpy_event *event; | |
18625 | + PyObject *func; | |
18626 | + int wakeup; | |
18627 | + | |
18628 | + if (!PyArg_ParseTuple (args, "O", &func)) | |
18629 | + return NULL; | |
18630 | + | |
18631 | + if (!PyCallable_Check (func)) | |
18632 | + { | |
18633 | + PyErr_SetString (PyExc_RuntimeError, "Posted event is not callable"); | |
18634 | + return NULL; | |
18635 | + } | |
18636 | + | |
18637 | + Py_INCREF (func); | |
18638 | + | |
18639 | + /* From here until the end of the function, we have the GIL, so we | |
18640 | + can operate on our global data structures without worrying. */ | |
18641 | + wakeup = gdbpy_event_list == NULL; | |
18642 | + | |
18643 | + event = XNEW (struct gdbpy_event); | |
18644 | + event->event = func; | |
18645 | + event->next = NULL; | |
18646 | + *gdbpy_event_list_end = event; | |
18647 | + gdbpy_event_list_end = &event->next; | |
18648 | + | |
18649 | + /* Wake up gdb when needed. */ | |
18650 | + if (wakeup) | |
18651 | + { | |
18652 | + char c = 'q'; /* Anything. */ | |
18653 | + if (write (gdbpy_event_fds[1], &c, 1) != 1) | |
18654 | + return PyErr_SetFromErrno (PyExc_IOError); | |
18655 | + } | |
18656 | + | |
18657 | + Py_RETURN_NONE; | |
18658 | +} | |
18659 | + | |
18660 | +/* Initialize the Python event handler. */ | |
18661 | +static void | |
18662 | +gdbpy_initialize_events (void) | |
18663 | +{ | |
18664 | + if (!pipe (gdbpy_event_fds)) | |
18665 | + { | |
18666 | + gdbpy_event_list_end = &gdbpy_event_list; | |
18667 | + add_file_handler (gdbpy_event_fds[0], gdbpy_run_events, NULL); | |
18668 | + } | |
18669 | +} | |
18670 | + | |
7566401a ER |
18671 | \f |
18672 | ||
18673 | /* Printing. */ | |
18674 | @@ -357,6 +592,69 @@ gdbpy_print_stack (void) | |
18675 | ||
18676 | \f | |
18677 | ||
18678 | +/* Script interface. */ | |
3a58abaf AM |
18679 | + |
18680 | +/* True if 'gdb -P' was used, false otherwise. */ | |
18681 | +static int running_python_script; | |
18682 | + | |
18683 | +/* True if we are currently in a call to 'gdb.cli', false otherwise. */ | |
18684 | +static int in_cli; | |
18685 | + | |
18686 | +/* Enter the command loop. */ | |
18687 | + | |
18688 | +static PyObject * | |
18689 | +gdbpy_cli (PyObject *unused1, PyObject *unused2) | |
18690 | +{ | |
18691 | + if (! running_python_script || in_cli) | |
18692 | + return PyErr_Format (PyExc_RuntimeError, "cannot invoke CLI recursively"); | |
18693 | + | |
18694 | + in_cli = 1; | |
18695 | + cli_command_loop (); | |
18696 | + in_cli = 0; | |
18697 | + | |
18698 | + Py_RETURN_NONE; | |
18699 | +} | |
18700 | + | |
18701 | +/* Set up the Python argument vector and evaluate a script. This is | |
18702 | + used to implement 'gdb -P'. */ | |
18703 | + | |
18704 | +void | |
18705 | +run_python_script (int argc, char **argv) | |
18706 | +{ | |
18707 | + FILE *input; | |
18708 | + PyGILState_STATE state; | |
18709 | + | |
18710 | + /* We never free this, since we plan to exit at the end. */ | |
18711 | + state = PyGILState_Ensure (); | |
18712 | + | |
18713 | + running_python_script = 1; | |
18714 | + PySys_SetArgv (argc - 1, argv + 1); | |
18715 | + input = fopen (argv[0], "r"); | |
18716 | + if (! input) | |
18717 | + { | |
18718 | + fprintf (stderr, "could not open %s: %s\n", argv[0], strerror (errno)); | |
18719 | + exit (1); | |
18720 | + } | |
18721 | + PyRun_SimpleFile (input, argv[0]); | |
18722 | + fclose (input); | |
18723 | + exit (0); | |
18724 | +} | |
18725 | + | |
18726 | +void | |
18727 | +source_python_script (FILE *stream, char *file) | |
18728 | +{ | |
18729 | + PyGILState_STATE state; | |
18730 | + | |
18731 | + state = PyGILState_Ensure (); | |
18732 | + | |
18733 | + PyRun_SimpleFile (stream, file); | |
18734 | + | |
18735 | + fclose (stream); | |
18736 | + PyGILState_Release (state); | |
18737 | +} | |
18738 | + | |
18739 | +\f | |
18740 | + | |
7566401a ER |
18741 | /* The "current" objfile. This is set when gdb detects that a new |
18742 | objfile has been loaded. It is only set for the duration of a call | |
18743 | to gdbpy_new_objfile; it is NULL at other times. */ | |
18744 | @@ -501,6 +799,13 @@ eval_python_from_control_command (struct command_line *cmd) | |
18745 | error (_("Python scripting is not supported in this copy of GDB.")); | |
18746 | } | |
18747 | ||
18748 | +void | |
18749 | +source_python_script (FILE *stream) | |
3a58abaf | 18750 | +{ |
7566401a ER |
18751 | + fclose (stream); |
18752 | + error (_("Python scripting is not supported in this copy of GDB.")); | |
18753 | +} | |
3a58abaf | 18754 | + |
7566401a ER |
18755 | #endif /* HAVE_PYTHON */ |
18756 | ||
18757 | \f | |
18758 | @@ -592,13 +897,27 @@ Enables or disables auto-loading of Python code when an object is opened."), | |
18759 | PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version); | |
18760 | PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", (char*) host_name); | |
18761 | PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name); | |
18762 | +#ifdef PYTHONDIR | |
18763 | + PyModule_AddStringConstant (gdb_module, "pythondir", PYTHONDIR); | |
18764 | +#else | |
18765 | + if (gdb_datadir) | |
18766 | + PyModule_AddStringConstant (gdb_module, "datadir", gdb_datadir); | |
18767 | +#endif | |
18768 | ||
18769 | gdbpy_initialize_values (); | |
18770 | + gdbpy_initialize_breakpoints (); | |
18771 | gdbpy_initialize_frames (); | |
18772 | + gdbpy_initialize_symtabs (); | |
18773 | gdbpy_initialize_commands (); | |
18774 | + gdbpy_initialize_symbols (); | |
18775 | + gdbpy_initialize_blocks (); | |
18776 | gdbpy_initialize_functions (); | |
18777 | gdbpy_initialize_types (); | |
18778 | + gdbpy_initialize_parameters (); | |
18779 | gdbpy_initialize_objfile (); | |
18780 | + gdbpy_initialize_thread (); | |
18781 | + gdbpy_initialize_inferior (); | |
18782 | + gdbpy_initialize_events (); | |
18783 | ||
18784 | PyRun_SimpleString ("import gdb"); | |
18785 | PyRun_SimpleString ("gdb.pretty_printers = []"); | |
18786 | @@ -634,6 +953,15 @@ class GdbOutputFile:\n\ | |
18787 | \n\ | |
18788 | sys.stderr = GdbOutputFile()\n\ | |
18789 | sys.stdout = GdbOutputFile()\n\ | |
18790 | +if hasattr (gdb, 'datadir'):\n\ | |
18791 | + gdb.pythondir = gdb.datadir + '/python'\n\ | |
18792 | +if hasattr (gdb, 'pythondir'):\n\ | |
18793 | + sys.path.insert(0, gdb.pythondir)\n\ | |
18794 | + gdb.__path__ = [gdb.pythondir + '/gdb']\n\ | |
18795 | + from os.path import exists\n\ | |
18796 | + ipy = gdb.pythondir + '/gdb/__init__.py'\n\ | |
18797 | + if exists (ipy):\n\ | |
18798 | + execfile (ipy)\n\ | |
18799 | "); | |
18800 | ||
18801 | /* Release the GIL while gdb runs. */ | |
18802 | @@ -653,9 +981,14 @@ static PyMethodDef GdbMethods[] = | |
18803 | "Get a value from history" }, | |
18804 | { "execute", execute_gdb_command, METH_VARARGS, | |
18805 | "Execute a gdb command" }, | |
18806 | + { "cli", gdbpy_cli, METH_NOARGS, | |
18807 | + "Enter the gdb CLI" }, | |
18808 | { "parameter", gdbpy_parameter, METH_VARARGS, | |
18809 | "Return a gdb parameter's value" }, | |
18810 | ||
18811 | + { "breakpoints", gdbpy_breakpoints, METH_NOARGS, | |
18812 | + "Return a tuple of all breakpoint objects" }, | |
3a58abaf | 18813 | + |
7566401a ER |
18814 | { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS, |
18815 | "Find the default visualizer for a Value." }, | |
18816 | ||
18817 | @@ -676,6 +1009,37 @@ Return a string explaining unwind stop reason." }, | |
18818 | "lookup_type (name [, block]) -> type\n\ | |
18819 | Return a Type corresponding to the given name." }, | |
18820 | ||
18821 | + { "lookup_symbol", (PyCFunction) gdbpy_lookup_symbol, | |
18822 | + METH_VARARGS | METH_KEYWORDS, | |
18823 | + "lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)\n\ | |
18824 | +Return a tuple with the symbol corresponding to the given name (or None) and\n\ | |
18825 | +a boolean indicating if name is a field of the current implied argument\n\ | |
18826 | +`this' (when the current language is object-oriented)." }, | |
18827 | + { "solib_address", gdbpy_solib_address, METH_VARARGS, | |
18828 | + "solib_address (Long) -> String.\n\ | |
18829 | +Return the name of the shared library holding a given address, or None." }, | |
3a58abaf | 18830 | + |
7566401a ER |
18831 | + { "block_for_pc", gdbpy_block_for_pc, METH_VARARGS, |
18832 | + "Return the block containing the given pc value, or None." }, | |
3a58abaf | 18833 | + |
7566401a ER |
18834 | + { "decode_line", gdbpy_decode_line, METH_VARARGS, |
18835 | + "Decode a string argument the way that 'break' or 'edit' does.\n\ | |
18836 | +Return a tuple holding the file name (or None) and line number (or None).\n\ | |
18837 | +Note: may later change to return an object." }, | |
3a58abaf | 18838 | + |
7566401a ER |
18839 | + { "selected_thread", gdbpy_selected_thread, METH_NOARGS, |
18840 | + "selected_thread () -> gdb.InferiorThread.\n\ | |
18841 | +Return the selected thread object." }, | |
18842 | + { "inferiors", gdbpy_inferiors, METH_NOARGS, | |
18843 | + "inferiors () -> (gdb.Inferior, ...).\n\ | |
18844 | +Return a tuple containing all inferiors." }, | |
3a58abaf | 18845 | + |
7566401a ER |
18846 | + { "parse_and_eval", gdbpy_parse_and_eval, METH_VARARGS, |
18847 | + "Parse a string as an expression, evaluate it, and return the result." }, | |
3a58abaf | 18848 | + |
7566401a ER |
18849 | + { "post_event", gdbpy_post_event, METH_VARARGS, |
18850 | + "Post an event into gdb's event loop." }, | |
3a58abaf | 18851 | + |
7566401a ER |
18852 | { "write", gdbpy_write, METH_VARARGS, |
18853 | "Write a string using gdb's filtered stream." }, | |
18854 | { "flush", gdbpy_flush, METH_NOARGS, | |
18855 | diff --git a/gdb/python/python.h b/gdb/python/python.h | |
18856 | index e970180..bbb6184 100644 | |
18857 | --- a/gdb/python/python.h | |
18858 | +++ b/gdb/python/python.h | |
18859 | @@ -24,6 +24,10 @@ | |
18860 | ||
18861 | void eval_python_from_control_command (struct command_line *); | |
18862 | ||
18863 | +void source_python_script (FILE *stream, char *file); | |
3a58abaf | 18864 | + |
7566401a | 18865 | +void run_python_script (int argc, char **argv); |
3a58abaf | 18866 | + |
7566401a ER |
18867 | int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, |
18868 | int embedded_offset, CORE_ADDR address, | |
18869 | struct ui_file *stream, int recurse, | |
18870 | diff --git a/gdb/scm-lang.c b/gdb/scm-lang.c | |
18871 | index de34894..07518b0 100644 | |
18872 | --- a/gdb/scm-lang.c | |
18873 | +++ b/gdb/scm-lang.c | |
18874 | @@ -233,6 +233,7 @@ const struct exp_descriptor exp_descriptor_scm = | |
18875 | { | |
18876 | print_subexp_standard, | |
18877 | operator_length_standard, | |
18878 | + operator_check_standard, | |
18879 | op_name_standard, | |
18880 | dump_subexp_body_standard, | |
18881 | evaluate_exp | |
18882 | diff --git a/gdb/scm-valprint.c b/gdb/scm-valprint.c | |
18883 | index cc3319a..d0d4702 100644 | |
18884 | --- a/gdb/scm-valprint.c | |
18885 | +++ b/gdb/scm-valprint.c | |
18886 | @@ -62,9 +62,9 @@ scm_inferior_print (struct type *type, LONGEST value, struct ui_file *stream, | |
18887 | { | |
18888 | /* XXX: Should we cache these symbols? */ | |
18889 | gdb_output_sym = | |
18890 | - lookup_symbol_global ("gdb_output", NULL, NULL, VAR_DOMAIN); | |
18891 | + lookup_symbol_global ("gdb_output", NULL, VAR_DOMAIN); | |
18892 | gdb_output_len_sym = | |
18893 | - lookup_symbol_global ("gdb_output_length", NULL, NULL, VAR_DOMAIN); | |
18894 | + lookup_symbol_global ("gdb_output_length", NULL, VAR_DOMAIN); | |
18895 | ||
18896 | if ((gdb_output_sym == NULL) || (gdb_output_len_sym == NULL)) | |
18897 | ret = -1; | |
18898 | diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c | |
18899 | index 8b96a6f..9428d92 100644 | |
18900 | --- a/gdb/solib-darwin.c | |
18901 | +++ b/gdb/solib-darwin.c | |
18902 | @@ -389,7 +389,6 @@ darwin_relocate_section_addresses (struct so_list *so, | |
18903 | static struct symbol * | |
18904 | darwin_lookup_lib_symbol (const struct objfile *objfile, | |
18905 | const char *name, | |
18906 | - const char *linkage_name, | |
18907 | const domain_enum domain) | |
18908 | { | |
18909 | return NULL; | |
18910 | diff --git a/gdb/solib-spu.c b/gdb/solib-spu.c | |
18911 | index 19e3212..9f06fa9 100644 | |
18912 | --- a/gdb/solib-spu.c | |
18913 | +++ b/gdb/solib-spu.c | |
18914 | @@ -334,16 +334,13 @@ spu_bfd_open (char *pathname) | |
18915 | static struct symbol * | |
18916 | spu_lookup_lib_symbol (const struct objfile *objfile, | |
18917 | const char *name, | |
18918 | - const char *linkage_name, | |
18919 | const domain_enum domain) | |
18920 | { | |
18921 | if (bfd_get_arch (objfile->obfd) == bfd_arch_spu) | |
18922 | - return lookup_global_symbol_from_objfile (objfile, name, linkage_name, | |
18923 | - domain); | |
18924 | + return lookup_global_symbol_from_objfile (objfile, name, domain); | |
18925 | ||
18926 | if (svr4_so_ops.lookup_lib_global_symbol != NULL) | |
18927 | - return svr4_so_ops.lookup_lib_global_symbol (objfile, name, linkage_name, | |
18928 | - domain); | |
18929 | + return svr4_so_ops.lookup_lib_global_symbol (objfile, name, domain); | |
18930 | return NULL; | |
18931 | } | |
18932 | ||
18933 | diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c | |
18934 | index 6cfaa85..68aadc0 100644 | |
18935 | --- a/gdb/solib-svr4.c | |
18936 | +++ b/gdb/solib-svr4.c | |
18937 | @@ -1908,15 +1908,13 @@ struct target_so_ops svr4_so_ops; | |
18938 | static struct symbol * | |
18939 | elf_lookup_lib_symbol (const struct objfile *objfile, | |
18940 | const char *name, | |
18941 | - const char *linkage_name, | |
18942 | const domain_enum domain) | |
18943 | { | |
18944 | if (objfile->obfd == NULL | |
18945 | || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1) | |
18946 | return NULL; | |
18947 | ||
18948 | - return lookup_global_symbol_from_objfile | |
18949 | - (objfile, name, linkage_name, domain); | |
18950 | + return lookup_global_symbol_from_objfile (objfile, name, domain); | |
18951 | } | |
18952 | ||
18953 | extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */ | |
18954 | diff --git a/gdb/solib.c b/gdb/solib.c | |
18955 | index a2ad0c4..3574e62 100644 | |
18956 | --- a/gdb/solib.c | |
18957 | +++ b/gdb/solib.c | |
18958 | @@ -1127,13 +1127,12 @@ show_auto_solib_add (struct ui_file *file, int from_tty, | |
18959 | struct symbol * | |
18960 | solib_global_lookup (const struct objfile *objfile, | |
18961 | const char *name, | |
18962 | - const char *linkage_name, | |
18963 | const domain_enum domain) | |
18964 | { | |
18965 | struct target_so_ops *ops = solib_ops (target_gdbarch); | |
18966 | ||
18967 | if (ops->lookup_lib_global_symbol != NULL) | |
18968 | - return ops->lookup_lib_global_symbol (objfile, name, linkage_name, domain); | |
18969 | + return ops->lookup_lib_global_symbol (objfile, name, domain); | |
18970 | return NULL; | |
18971 | } | |
18972 | ||
18973 | diff --git a/gdb/solist.h b/gdb/solist.h | |
18974 | index 63a6ba0..005e8f7 100644 | |
18975 | --- a/gdb/solist.h | |
18976 | +++ b/gdb/solist.h | |
18977 | @@ -114,7 +114,6 @@ struct target_so_ops | |
18978 | /* Hook for looking up global symbols in a library-specific way. */ | |
18979 | struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile, | |
18980 | const char *name, | |
18981 | - const char *linkage_name, | |
18982 | const domain_enum domain); | |
18983 | ||
18984 | /* Given two so_list objects, one from the GDB thread list | |
18985 | @@ -146,7 +145,6 @@ extern struct target_so_ops *current_target_so_ops; | |
18986 | /* Handler for library-specific global symbol lookup in solib.c. */ | |
18987 | struct symbol *solib_global_lookup (const struct objfile *objfile, | |
18988 | const char *name, | |
18989 | - const char *linkage_name, | |
18990 | const domain_enum domain); | |
18991 | ||
18992 | #endif | |
18993 | diff --git a/gdb/somread.c b/gdb/somread.c | |
18994 | index 36a2b28..4d5bda9 100644 | |
18995 | --- a/gdb/somread.c | |
18996 | +++ b/gdb/somread.c | |
18997 | @@ -435,6 +435,7 @@ static struct sym_fns som_sym_fns = | |
18998 | som_new_init, /* sym_new_init: init anything gbl to entire symtab */ | |
18999 | som_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
19000 | som_symfile_read, /* sym_read: read a symbol file into symtab */ | |
19001 | + NULL, /* sym_read_psymbols */ | |
19002 | som_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
19003 | som_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */ | |
19004 | default_symfile_segments, /* sym_segments: Get segment information from | |
19005 | diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c | |
19006 | index 7e7ab9c..a014b7a 100644 | |
19007 | --- a/gdb/spu-tdep.c | |
19008 | +++ b/gdb/spu-tdep.c | |
19009 | @@ -1839,7 +1839,7 @@ spu_catch_start (struct objfile *objfile) | |
19010 | struct symbol *sym; | |
19011 | struct symtab_and_line sal; | |
19012 | ||
19013 | - sym = lookup_block_symbol (block, "main", NULL, VAR_DOMAIN); | |
19014 | + sym = lookup_block_symbol (block, "main", VAR_DOMAIN); | |
19015 | if (sym) | |
19016 | { | |
19017 | fixup_symbol_section (sym, objfile); | |
19018 | diff --git a/gdb/stabsread.c b/gdb/stabsread.c | |
19019 | index e62bb15..ad6568e 100644 | |
19020 | --- a/gdb/stabsread.c | |
19021 | +++ b/gdb/stabsread.c | |
19022 | @@ -322,7 +322,7 @@ dbx_alloc_type (int typenums[2], struct objfile *objfile) | |
19023 | ||
19024 | if (typenums[0] == -1) | |
19025 | { | |
19026 | - return (alloc_type (objfile)); | |
19027 | + return (alloc_type (objfile, NULL)); | |
19028 | } | |
19029 | ||
19030 | type_addr = dbx_lookup_type (typenums, objfile); | |
19031 | @@ -332,7 +332,7 @@ dbx_alloc_type (int typenums[2], struct objfile *objfile) | |
19032 | We will fill it in later if we find out how. */ | |
19033 | if (*type_addr == 0) | |
19034 | { | |
19035 | - *type_addr = alloc_type (objfile); | |
19036 | + *type_addr = alloc_type (objfile, NULL); | |
19037 | } | |
19038 | ||
19039 | return (*type_addr); | |
19040 | diff --git a/gdb/stack.c b/gdb/stack.c | |
19041 | index 1c37801..594eb16 100644 | |
19042 | --- a/gdb/stack.c | |
19043 | +++ b/gdb/stack.c | |
19044 | @@ -1308,24 +1308,24 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty) | |
19045 | else | |
19046 | count = -1; | |
19047 | ||
19048 | - if (info_verbose) | |
19049 | - { | |
19050 | - struct partial_symtab *ps; | |
19051 | - | |
19052 | - /* Read in symbols for all of the frames. Need to do this in a | |
19053 | - separate pass so that "Reading in symbols for xxx" messages | |
19054 | - don't screw up the appearance of the backtrace. Also if | |
19055 | - people have strong opinions against reading symbols for | |
19056 | - backtrace this may have to be an option. */ | |
19057 | - i = count; | |
19058 | - for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi)) | |
19059 | - { | |
19060 | - QUIT; | |
19061 | - ps = find_pc_psymtab (get_frame_address_in_block (fi)); | |
19062 | - if (ps) | |
19063 | - PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in. */ | |
19064 | - } | |
19065 | - } | |
3a58abaf | 19066 | + { |
7566401a | 19067 | + struct partial_symtab *ps; |
3a58abaf | 19068 | + |
7566401a ER |
19069 | + /* Read in symbols for all of the frames. Need to do this |
19070 | + unconditionally to ensure that psymbols are read. Also need to | |
19071 | + do this in a separate pass so that "Reading in symbols for xxx" | |
19072 | + messages don't screw up the appearance of the backtrace. Also | |
19073 | + if people have strong opinions against reading symbols for | |
19074 | + backtrace this may have to be an option. */ | |
19075 | + i = count; | |
19076 | + for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi)) | |
19077 | + { | |
19078 | + QUIT; | |
19079 | + ps = find_pc_psymtab (get_frame_address_in_block (fi)); | |
19080 | + if (info_verbose && ps) | |
19081 | + PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in. */ | |
19082 | + } | |
19083 | + } | |
19084 | ||
19085 | for (i = 0, fi = trailing; fi && count--; i++, fi = get_prev_frame (fi)) | |
19086 | { | |
19087 | @@ -1473,6 +1473,8 @@ print_block_frame_locals (struct block *b, struct frame_info *frame, | |
19088 | case LOC_COMPUTED: | |
19089 | if (SYMBOL_IS_ARGUMENT (sym)) | |
19090 | break; | |
19091 | + if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN) | |
19092 | + break; | |
19093 | values_printed = 1; | |
19094 | print_variable_and_value (NULL, sym, frame, stream, 4 * num_tabs); | |
19095 | break; | |
19096 | diff --git a/gdb/symfile.c b/gdb/symfile.c | |
19097 | index 2458201..c31b72a 100644 | |
19098 | --- a/gdb/symfile.c | |
19099 | +++ b/gdb/symfile.c | |
19100 | @@ -921,6 +921,17 @@ new_symfile_objfile (struct objfile *objfile, int add_flags) | |
19101 | clear_complaints (&symfile_complaints, 0, add_flags & SYMFILE_VERBOSE); | |
19102 | } | |
19103 | ||
19104 | +/* A helper function which returns true if OBJFILE has any debug | |
19105 | + symbols, and false otherwise. */ | |
19106 | +static int | |
19107 | +has_any_debug_symbols (struct objfile *objfile) | |
3a58abaf | 19108 | +{ |
7566401a ER |
19109 | + return (objfile->psymtabs || objfile->quick_addrmap |
19110 | + || (objfile->separate_debug_objfile | |
19111 | + && (objfile->separate_debug_objfile->psymtabs | |
19112 | + || objfile->separate_debug_objfile->quick_addrmap))); | |
19113 | +} | |
3a58abaf | 19114 | + |
7566401a ER |
19115 | /* Process a symbol file, as either the main file or as a dynamically |
19116 | loaded file. | |
19117 | ||
19118 | @@ -958,13 +969,16 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, | |
19119 | /* Give user a chance to burp if we'd be | |
19120 | interactively wiping out any existing symbols. */ | |
19121 | ||
19122 | - if ((have_full_symbols () || have_partial_symbols ()) | |
19123 | - && (add_flags & SYMFILE_MAINLINE) | |
19124 | + if ((add_flags & SYMFILE_MAINLINE) | |
19125 | + && (have_full_symbols () || have_partial_symbols ()) | |
19126 | && from_tty | |
19127 | + && (have_full_symbols () || have_partial_symbols ()) | |
19128 | && !query (_("Load new symbol table from \"%s\"? "), name)) | |
19129 | error (_("Not confirmed.")); | |
19130 | ||
19131 | objfile = allocate_objfile (abfd, flags); | |
19132 | + if (add_flags & SYMFILE_MAINLINE) | |
19133 | + objfile->flags |= OBJF_MAIN; | |
19134 | discard_cleanups (my_cleanups); | |
19135 | ||
19136 | if (addrs) | |
19137 | @@ -997,6 +1011,8 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, | |
19138 | ||
19139 | if ((flags & OBJF_READNOW) || readnow_symbol_files) | |
19140 | { | |
19141 | + require_partial_symbols (objfile); | |
3a58abaf | 19142 | + |
7566401a ER |
19143 | if (from_tty || info_verbose) |
19144 | { | |
19145 | printf_unfiltered (_("expanding to full symbols...")); | |
19146 | @@ -1015,7 +1031,7 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, | |
19147 | /* If the file has its own symbol tables it has no separate debug info. | |
19148 | `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to SYMTABS/PSYMTABS. | |
19149 | `.gnu_debuglink' may no longer be present with `.note.gnu.build-id'. */ | |
19150 | - if (objfile->psymtabs == NULL) | |
19151 | + if (!has_any_debug_symbols (objfile)) | |
19152 | debugfile = find_separate_debug_file (objfile); | |
19153 | if (debugfile) | |
19154 | { | |
19155 | @@ -1039,9 +1055,10 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, | |
19156 | xfree (debugfile); | |
19157 | } | |
19158 | ||
19159 | + /* has_any_debug_symbols is not fully compatible with the former calls which | |
19160 | + would just be needlessly expensive here. */ | |
19161 | if ((from_tty || info_verbose) | |
19162 | - && !objfile_has_partial_symbols (objfile) | |
19163 | - && !objfile_has_full_symbols (objfile)) | |
19164 | + && !has_any_debug_symbols (objfile)) | |
19165 | { | |
19166 | wrap_here (""); | |
19167 | printf_unfiltered (_("(no debugging symbols found)...")); | |
19168 | @@ -2422,14 +2439,15 @@ reread_symbols (void) | |
19169 | zero is OK since dbxread.c also does what it needs to do if | |
19170 | objfile->global_psymbols.size is 0. */ | |
19171 | (*objfile->sf->sym_read) (objfile, 0); | |
19172 | - if (!objfile_has_partial_symbols (objfile) | |
19173 | - && !objfile_has_full_symbols (objfile)) | |
19174 | + if (!has_any_debug_symbols (objfile)) | |
19175 | { | |
19176 | wrap_here (""); | |
19177 | printf_unfiltered (_("(no debugging symbols found)\n")); | |
19178 | wrap_here (""); | |
19179 | } | |
19180 | ||
19181 | + objfile->flags &= ~OBJF_SYMTABS_READ; | |
3a58abaf | 19182 | + |
7566401a ER |
19183 | /* We're done reading the symbol file; finish off complaints. */ |
19184 | clear_complaints (&symfile_complaints, 0, 1); | |
19185 | ||
19186 | @@ -2727,7 +2745,7 @@ allocate_symtab (char *filename, struct objfile *objfile) | |
19187 | } | |
19188 | ||
19189 | struct partial_symtab * | |
19190 | -allocate_psymtab (char *filename, struct objfile *objfile) | |
19191 | +allocate_psymtab (const char *filename, struct objfile *objfile) | |
19192 | { | |
19193 | struct partial_symtab *psymtab; | |
19194 | ||
19195 | @@ -3041,7 +3059,8 @@ again2: | |
19196 | ||
19197 | struct partial_symtab * | |
19198 | start_psymtab_common (struct objfile *objfile, | |
19199 | - struct section_offsets *section_offsets, char *filename, | |
19200 | + struct section_offsets *section_offsets, | |
19201 | + const char *filename, | |
19202 | CORE_ADDR textlow, struct partial_symbol **global_syms, | |
19203 | struct partial_symbol **static_syms) | |
19204 | { | |
19205 | diff --git a/gdb/symfile.h b/gdb/symfile.h | |
19206 | index 8c9249c..bf9d9e7 100644 | |
19207 | --- a/gdb/symfile.h | |
19208 | +++ b/gdb/symfile.h | |
19209 | @@ -140,6 +140,12 @@ struct sym_fns | |
19210 | ||
19211 | void (*sym_read) (struct objfile *, int); | |
19212 | ||
19213 | + /* Read the partial symbols for an objfile. This may be NULL, in | |
19214 | + which case gdb assumes that sym_read already read the partial | |
19215 | + symbols. */ | |
3a58abaf | 19216 | + |
7566401a | 19217 | + void (*sym_read_psymbols) (struct objfile *); |
3a58abaf | 19218 | + |
7566401a ER |
19219 | /* Called when we are finished with an objfile. Should do all |
19220 | cleanup that is specific to the object file format for the | |
19221 | particular objfile. */ | |
19222 | @@ -266,7 +272,7 @@ extern void free_section_addr_info (struct section_addr_info *); | |
19223 | ||
19224 | extern struct partial_symtab *start_psymtab_common (struct objfile *, | |
19225 | struct section_offsets *, | |
19226 | - char *, CORE_ADDR, | |
19227 | + const char *, CORE_ADDR, | |
19228 | struct partial_symbol **, | |
19229 | struct partial_symbol **); | |
19230 | ||
19231 | @@ -309,7 +315,7 @@ extern int auto_solib_limit; | |
19232 | ||
19233 | extern void set_initial_language (void); | |
19234 | ||
19235 | -extern struct partial_symtab *allocate_psymtab (char *, struct objfile *); | |
19236 | +extern struct partial_symtab *allocate_psymtab (const char *, struct objfile *); | |
19237 | ||
19238 | extern void discard_psymtab (struct partial_symtab *); | |
19239 | ||
19240 | @@ -378,7 +384,7 @@ void free_symfile_segment_data (struct symfile_segment_data *data); | |
19241 | /* From dwarf2read.c */ | |
19242 | ||
19243 | extern int dwarf2_has_info (struct objfile *); | |
19244 | - | |
19245 | +extern void dwarf2_create_quick_addrmap (struct objfile *); | |
19246 | extern void dwarf2_build_psymtabs (struct objfile *, int); | |
19247 | extern void dwarf2_build_frame_info (struct objfile *); | |
19248 | ||
19249 | diff --git a/gdb/symmisc.c b/gdb/symmisc.c | |
19250 | index eb35369..dfd8c8c 100644 | |
19251 | --- a/gdb/symmisc.c | |
19252 | +++ b/gdb/symmisc.c | |
19253 | @@ -1128,7 +1128,7 @@ maintenance_check_symtabs (char *ignore, int from_tty) | |
19254 | while (length--) | |
19255 | { | |
19256 | sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym), | |
19257 | - NULL, SYMBOL_DOMAIN (*psym)); | |
19258 | + SYMBOL_DOMAIN (*psym)); | |
19259 | if (!sym) | |
19260 | { | |
19261 | printf_filtered ("Static symbol `"); | |
19262 | @@ -1145,7 +1145,7 @@ maintenance_check_symtabs (char *ignore, int from_tty) | |
19263 | while (length--) | |
19264 | { | |
19265 | sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym), | |
19266 | - NULL, SYMBOL_DOMAIN (*psym)); | |
19267 | + SYMBOL_DOMAIN (*psym)); | |
19268 | if (!sym) | |
19269 | { | |
19270 | printf_filtered ("Global symbol `"); | |
19271 | diff --git a/gdb/symtab.c b/gdb/symtab.c | |
19272 | index 8d9d72c..82e0163 100644 | |
19273 | --- a/gdb/symtab.c | |
19274 | +++ b/gdb/symtab.c | |
19275 | @@ -42,6 +42,7 @@ | |
19276 | #include "ada-lang.h" | |
19277 | #include "p-lang.h" | |
19278 | #include "addrmap.h" | |
19279 | +#include "cp-support.h" | |
19280 | ||
19281 | #include "hashtab.h" | |
19282 | ||
19283 | @@ -85,7 +86,6 @@ static int find_line_common (struct linetable *, int, int *); | |
19284 | char *operator_chars (char *p, char **end); | |
19285 | ||
19286 | static struct symbol *lookup_symbol_aux (const char *name, | |
19287 | - const char *linkage_name, | |
19288 | const struct block *block, | |
19289 | const domain_enum domain, | |
19290 | enum language language, | |
19291 | @@ -93,20 +93,19 @@ static struct symbol *lookup_symbol_aux (const char *name, | |
19292 | ||
19293 | static | |
19294 | struct symbol *lookup_symbol_aux_local (const char *name, | |
19295 | - const char *linkage_name, | |
19296 | const struct block *block, | |
19297 | - const domain_enum domain); | |
19298 | + const domain_enum domain, | |
19299 | + enum language language, | |
19300 | + int *is_a_field_of_this); | |
19301 | ||
19302 | static | |
19303 | struct symbol *lookup_symbol_aux_symtabs (int block_index, | |
19304 | const char *name, | |
19305 | - const char *linkage_name, | |
19306 | const domain_enum domain); | |
19307 | ||
19308 | static | |
19309 | struct symbol *lookup_symbol_aux_psymtabs (int block_index, | |
19310 | const char *name, | |
19311 | - const char *linkage_name, | |
19312 | const domain_enum domain); | |
19313 | ||
19314 | static int file_matches (char *, char **, int); | |
19315 | @@ -271,7 +270,7 @@ lookup_partial_symtab (const char *name) | |
19316 | make_cleanup (xfree, real_path); | |
19317 | } | |
19318 | ||
19319 | - ALL_PSYMTABS (objfile, pst) | |
19320 | + ALL_PSYMTABS_REQUIRED (objfile, pst) | |
19321 | { | |
19322 | if (FILENAME_CMP (name, pst->filename) == 0) | |
19323 | { | |
19324 | @@ -414,7 +413,8 @@ symbol_init_language_specific (struct general_symbol_info *gsymbol, | |
19325 | gsymbol->language = language; | |
19326 | if (gsymbol->language == language_cplus | |
19327 | || gsymbol->language == language_java | |
19328 | - || gsymbol->language == language_objc) | |
19329 | + || gsymbol->language == language_objc | |
19330 | + || gsymbol->language == language_fortran) | |
19331 | { | |
19332 | gsymbol->language_specific.cplus_specific.demangled_name = NULL; | |
19333 | } | |
19334 | @@ -474,7 +474,7 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, | |
19335 | || gsymbol->language == language_auto) | |
19336 | { | |
19337 | demangled = | |
19338 | - cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); | |
19339 | + cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE); | |
19340 | if (demangled != NULL) | |
19341 | { | |
19342 | gsymbol->language = language_cplus; | |
19343 | @@ -633,6 +633,7 @@ symbol_natural_name (const struct general_symbol_info *gsymbol) | |
19344 | case language_cplus: | |
19345 | case language_java: | |
19346 | case language_objc: | |
19347 | + case language_fortran: | |
19348 | if (gsymbol->language_specific.cplus_specific.demangled_name != NULL) | |
19349 | return gsymbol->language_specific.cplus_specific.demangled_name; | |
19350 | break; | |
19351 | @@ -658,6 +659,7 @@ symbol_demangled_name (const struct general_symbol_info *gsymbol) | |
19352 | case language_cplus: | |
19353 | case language_java: | |
19354 | case language_objc: | |
19355 | + case language_fortran: | |
19356 | if (gsymbol->language_specific.cplus_specific.demangled_name != NULL) | |
19357 | return gsymbol->language_specific.cplus_specific.demangled_name; | |
19358 | break; | |
19359 | @@ -868,7 +870,13 @@ find_pc_sect_psymtab (CORE_ADDR pc, struct obj_section *section) | |
19360 | than the later used TEXTLOW/TEXTHIGH one. */ | |
19361 | ||
19362 | ALL_OBJFILES (objfile) | |
19363 | - if (objfile->psymtabs_addrmap != NULL) | |
3a58abaf | 19364 | + { |
7566401a | 19365 | + if (objfile->quick_addrmap) |
3a58abaf | 19366 | + { |
7566401a ER |
19367 | + if (!addrmap_find (objfile->quick_addrmap, pc)) |
19368 | + continue; | |
3a58abaf | 19369 | + } |
7566401a ER |
19370 | + if (require_partial_symbols (objfile)->psymtabs_addrmap != NULL) |
19371 | { | |
19372 | struct partial_symtab *pst; | |
19373 | ||
19374 | @@ -901,6 +909,7 @@ find_pc_sect_psymtab (CORE_ADDR pc, struct obj_section *section) | |
19375 | return pst; | |
19376 | } | |
19377 | } | |
3a58abaf | 19378 | + } |
7566401a ER |
19379 | |
19380 | /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs | |
19381 | which still have no corresponding full SYMTABs read. But it is not | |
19382 | @@ -1168,6 +1177,22 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile) | |
19383 | return psym; | |
19384 | } | |
19385 | ||
19386 | +/* Ensure that the partial symbols for OBJFILE have been loaded. This | |
19387 | + function always returns its argument, as a convenience. */ | |
3a58abaf | 19388 | + |
7566401a ER |
19389 | +struct objfile * |
19390 | +require_partial_symbols (struct objfile *objfile) | |
3a58abaf | 19391 | +{ |
7566401a | 19392 | + if ((objfile->flags & OBJF_SYMTABS_READ) == 0) |
3a58abaf | 19393 | + { |
7566401a | 19394 | + objfile->flags |= OBJF_SYMTABS_READ; |
3a58abaf | 19395 | + |
7566401a ER |
19396 | + if (objfile->sf->sym_read_psymbols) |
19397 | + (*objfile->sf->sym_read_psymbols) (objfile); | |
3a58abaf | 19398 | + } |
7566401a | 19399 | + return objfile; |
3a58abaf AM |
19400 | +} |
19401 | + | |
7566401a ER |
19402 | /* Find the definition for a specified symbol name NAME |
19403 | in domain DOMAIN, visible from lexical block BLOCK. | |
19404 | Returns the struct symbol pointer, or zero if no symbol is found. | |
19405 | @@ -1194,10 +1219,14 @@ lookup_symbol_in_language (const char *name, const struct block *block, | |
19406 | { | |
19407 | char *demangled_name = NULL; | |
19408 | const char *modified_name = NULL; | |
19409 | - const char *mangled_name = NULL; | |
19410 | struct symbol *returnval; | |
19411 | struct cleanup *cleanup = make_cleanup (null_cleanup, 0); | |
19412 | ||
19413 | + if(strncmp(name, "::", 2) == 0){/* this must be a global name */ | |
19414 | + name = name+2; | |
19415 | + block = NULL; | |
19416 | + } | |
3a58abaf | 19417 | + |
7566401a ER |
19418 | modified_name = name; |
19419 | ||
19420 | /* If we are using C++ or Java, demangle the name before doing a lookup, so | |
19421 | @@ -1207,7 +1236,6 @@ lookup_symbol_in_language (const char *name, const struct block *block, | |
19422 | demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS); | |
19423 | if (demangled_name) | |
19424 | { | |
19425 | - mangled_name = name; | |
19426 | modified_name = demangled_name; | |
19427 | make_cleanup (xfree, demangled_name); | |
19428 | } | |
19429 | @@ -1229,7 +1257,6 @@ lookup_symbol_in_language (const char *name, const struct block *block, | |
19430 | DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA); | |
19431 | if (demangled_name) | |
19432 | { | |
19433 | - mangled_name = name; | |
19434 | modified_name = demangled_name; | |
19435 | make_cleanup (xfree, demangled_name); | |
19436 | } | |
19437 | @@ -1248,8 +1275,8 @@ lookup_symbol_in_language (const char *name, const struct block *block, | |
19438 | modified_name = copy; | |
19439 | } | |
19440 | ||
19441 | - returnval = lookup_symbol_aux (modified_name, mangled_name, block, | |
19442 | - domain, lang, is_a_field_of_this); | |
19443 | + returnval = lookup_symbol_aux (modified_name, block, domain, lang, | |
19444 | + is_a_field_of_this); | |
19445 | do_cleanups (cleanup); | |
19446 | ||
19447 | return returnval; | |
19448 | @@ -1273,9 +1300,9 @@ lookup_symbol (const char *name, const struct block *block, | |
19449 | well. */ | |
19450 | ||
19451 | static struct symbol * | |
19452 | -lookup_symbol_aux (const char *name, const char *linkage_name, | |
19453 | - const struct block *block, const domain_enum domain, | |
19454 | - enum language language, int *is_a_field_of_this) | |
19455 | +lookup_symbol_aux (const char *name, const struct block *block, | |
19456 | + const domain_enum domain, enum language language, | |
19457 | + int *is_a_field_of_this) | |
19458 | { | |
19459 | struct symbol *sym; | |
19460 | const struct language_defn *langdef; | |
19461 | @@ -1291,55 +1318,19 @@ lookup_symbol_aux (const char *name, const char *linkage_name, | |
19462 | /* Search specified block and its superiors. Don't search | |
19463 | STATIC_BLOCK or GLOBAL_BLOCK. */ | |
19464 | ||
19465 | - sym = lookup_symbol_aux_local (name, linkage_name, block, domain); | |
19466 | + sym = lookup_symbol_aux_local (name, block, domain, language, is_a_field_of_this); | |
19467 | if (sym != NULL) | |
19468 | return sym; | |
19469 | ||
19470 | - /* If requested to do so by the caller and if appropriate for LANGUAGE, | |
19471 | - check to see if NAME is a field of `this'. */ | |
19472 | - | |
19473 | - langdef = language_def (language); | |
19474 | - | |
19475 | - if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL | |
19476 | - && block != NULL) | |
19477 | - { | |
19478 | - struct symbol *sym = NULL; | |
19479 | - /* 'this' is only defined in the function's block, so find the | |
19480 | - enclosing function block. */ | |
19481 | - for (; block && !BLOCK_FUNCTION (block); | |
19482 | - block = BLOCK_SUPERBLOCK (block)); | |
19483 | - | |
19484 | - if (block && !dict_empty (BLOCK_DICT (block))) | |
19485 | - sym = lookup_block_symbol (block, langdef->la_name_of_this, | |
19486 | - NULL, VAR_DOMAIN); | |
19487 | - if (sym) | |
19488 | - { | |
19489 | - struct type *t = sym->type; | |
19490 | - | |
19491 | - /* I'm not really sure that type of this can ever | |
19492 | - be typedefed; just be safe. */ | |
19493 | - CHECK_TYPEDEF (t); | |
19494 | - if (TYPE_CODE (t) == TYPE_CODE_PTR | |
19495 | - || TYPE_CODE (t) == TYPE_CODE_REF) | |
19496 | - t = TYPE_TARGET_TYPE (t); | |
19497 | - | |
19498 | - if (TYPE_CODE (t) != TYPE_CODE_STRUCT | |
19499 | - && TYPE_CODE (t) != TYPE_CODE_UNION) | |
19500 | - error (_("Internal error: `%s' is not an aggregate"), | |
19501 | - langdef->la_name_of_this); | |
19502 | - | |
19503 | - if (check_field (t, name)) | |
19504 | - { | |
19505 | - *is_a_field_of_this = 1; | |
19506 | - return NULL; | |
19507 | - } | |
19508 | - } | |
19509 | - } | |
19510 | + /* this symbol was found to be a member variable | |
19511 | + do not perform the global search. */ | |
19512 | + if (is_a_field_of_this && *is_a_field_of_this) | |
3a58abaf | 19513 | + return NULL; |
7566401a ER |
19514 | |
19515 | /* Now do whatever is appropriate for LANGUAGE to look | |
19516 | up static and global variables. */ | |
19517 | - | |
19518 | - sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name, block, domain); | |
19519 | + langdef = language_def (language); | |
19520 | + sym = langdef->la_lookup_symbol_nonlocal (name, block, domain); | |
19521 | if (sym != NULL) | |
19522 | return sym; | |
19523 | ||
19524 | @@ -1349,11 +1340,11 @@ lookup_symbol_aux (const char *name, const char *linkage_name, | |
19525 | desired name as a file-level static, then do psymtab-to-symtab | |
19526 | conversion on the fly and return the found symbol. */ | |
19527 | ||
19528 | - sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name, domain); | |
19529 | + sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, domain); | |
19530 | if (sym != NULL) | |
19531 | return sym; | |
19532 | ||
19533 | - sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name, domain); | |
19534 | + sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, domain); | |
19535 | if (sym != NULL) | |
19536 | return sym; | |
19537 | ||
19538 | @@ -1364,30 +1355,81 @@ lookup_symbol_aux (const char *name, const char *linkage_name, | |
19539 | Don't search STATIC_BLOCK or GLOBAL_BLOCK. */ | |
19540 | ||
19541 | static struct symbol * | |
19542 | -lookup_symbol_aux_local (const char *name, const char *linkage_name, | |
19543 | - const struct block *block, | |
19544 | - const domain_enum domain) | |
19545 | +lookup_symbol_aux_local (const char *name, const struct block *block, | |
19546 | + const domain_enum domain, enum language language, | |
19547 | + int *is_a_field_of_this) | |
19548 | { | |
19549 | struct symbol *sym; | |
19550 | - const struct block *static_block = block_static_block (block); | |
19551 | + const struct block *global_block = block_global_block (block); | |
19552 | + const struct block *block_iterator = block; | |
19553 | + const struct language_defn *langdef; | |
3a58abaf | 19554 | + |
7566401a ER |
19555 | + langdef = language_def (language); |
19556 | ||
19557 | /* Check if either no block is specified or it's a global block. */ | |
19558 | ||
19559 | - if (static_block == NULL) | |
19560 | + if (global_block == NULL) | |
19561 | return NULL; | |
19562 | ||
19563 | - while (block != static_block) | |
19564 | + while (block_iterator != global_block) | |
19565 | { | |
19566 | - sym = lookup_symbol_aux_block (name, linkage_name, block, domain); | |
3a58abaf | 19567 | + |
7566401a | 19568 | + sym = lookup_symbol_aux_block (name, block_iterator, domain); |
3a58abaf | 19569 | + |
7566401a ER |
19570 | if (sym != NULL) |
19571 | return sym; | |
19572 | - | |
19573 | - if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block)) | |
19574 | - break; | |
19575 | - block = BLOCK_SUPERBLOCK (block); | |
19576 | + | |
19577 | + if (language == language_cplus ) | |
19578 | + { | |
19579 | + sym = cp_lookup_symbol_imports (block_scope (block_iterator), name, | |
19580 | + block_iterator, domain, 1, 1); | |
3a58abaf | 19581 | + |
7566401a ER |
19582 | + if (sym != NULL) |
19583 | + return sym; | |
19584 | + } | |
3a58abaf | 19585 | + |
7566401a ER |
19586 | + if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL |
19587 | + && BLOCK_FUNCTION (block_iterator)) | |
19588 | + { | |
19589 | + if (!dict_empty (BLOCK_DICT (block_iterator))) | |
19590 | + { | |
19591 | + sym = lookup_block_symbol (block_iterator, | |
19592 | + langdef->la_name_of_this, | |
19593 | + VAR_DOMAIN); | |
19594 | + | |
19595 | + | |
19596 | + if (sym) | |
19597 | + { | |
19598 | + struct type *t = sym->type; | |
19599 | + | |
19600 | + /* I'm not really sure that type of this can ever | |
19601 | + be typedefed; just be safe. */ | |
19602 | + CHECK_TYPEDEF (t); | |
19603 | + if (TYPE_CODE (t) == TYPE_CODE_PTR | |
19604 | + || TYPE_CODE (t) == TYPE_CODE_REF) | |
19605 | + t = TYPE_TARGET_TYPE (t); | |
19606 | + | |
19607 | + if (TYPE_CODE (t) != TYPE_CODE_STRUCT | |
19608 | + && TYPE_CODE (t) != TYPE_CODE_UNION) | |
19609 | + error (_("Internal error: `%s' is not an aggregate"), | |
19610 | + langdef->la_name_of_this); | |
19611 | + | |
19612 | + if (check_field (t, name)) | |
19613 | + { | |
19614 | + *is_a_field_of_this = 1; | |
19615 | + return NULL; | |
19616 | + } | |
19617 | + } | |
19618 | + } | |
19619 | + } | |
3a58abaf | 19620 | + |
7566401a ER |
19621 | + if (BLOCK_FUNCTION (block_iterator) != NULL && block_inlined_p (block_iterator)) |
19622 | + break; | |
3a58abaf | 19623 | + |
7566401a ER |
19624 | + block_iterator = BLOCK_SUPERBLOCK (block_iterator); |
19625 | } | |
3a58abaf | 19626 | |
7566401a ER |
19627 | - /* We've reached the edge of the function without finding a result. */ |
19628 | + /* We've reached the global block without finding a result. */ | |
3a58abaf | 19629 | |
7566401a ER |
19630 | return NULL; |
19631 | } | |
19632 | @@ -1416,13 +1458,12 @@ lookup_objfile_from_block (const struct block *block) | |
19633 | block_found appropriately. */ | |
3a58abaf | 19634 | |
7566401a ER |
19635 | struct symbol * |
19636 | -lookup_symbol_aux_block (const char *name, const char *linkage_name, | |
19637 | - const struct block *block, | |
19638 | +lookup_symbol_aux_block (const char *name, const struct block *block, | |
19639 | const domain_enum domain) | |
3a58abaf | 19640 | { |
7566401a | 19641 | struct symbol *sym; |
3a58abaf | 19642 | |
7566401a ER |
19643 | - sym = lookup_block_symbol (block, name, linkage_name, domain); |
19644 | + sym = lookup_block_symbol (block, name, domain); | |
19645 | if (sym) | |
19646 | { | |
19647 | block_found = block; | |
19648 | @@ -1438,7 +1479,6 @@ lookup_symbol_aux_block (const char *name, const char *linkage_name, | |
19649 | struct symbol * | |
19650 | lookup_global_symbol_from_objfile (const struct objfile *objfile, | |
19651 | const char *name, | |
19652 | - const char *linkage_name, | |
19653 | const domain_enum domain) | |
19654 | { | |
19655 | struct symbol *sym; | |
19656 | @@ -1452,7 +1492,7 @@ lookup_global_symbol_from_objfile (const struct objfile *objfile, | |
19657 | { | |
19658 | bv = BLOCKVECTOR (s); | |
19659 | block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); | |
19660 | - sym = lookup_block_symbol (block, name, linkage_name, domain); | |
19661 | + sym = lookup_block_symbol (block, name, domain); | |
19662 | if (sym) | |
19663 | { | |
19664 | block_found = block; | |
19665 | @@ -1461,23 +1501,23 @@ lookup_global_symbol_from_objfile (const struct objfile *objfile, | |
19666 | } | |
3a58abaf | 19667 | |
7566401a ER |
19668 | /* Now go through psymtabs. */ |
19669 | + require_partial_symbols ((struct objfile *) objfile); | |
19670 | ALL_OBJFILE_PSYMTABS (objfile, ps) | |
19671 | { | |
19672 | if (!ps->readin | |
19673 | - && lookup_partial_symbol (ps, name, linkage_name, | |
19674 | - 1, domain)) | |
19675 | + && lookup_partial_symbol (ps, name, 1, domain)) | |
19676 | { | |
19677 | s = PSYMTAB_TO_SYMTAB (ps); | |
19678 | bv = BLOCKVECTOR (s); | |
19679 | block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); | |
19680 | - sym = lookup_block_symbol (block, name, linkage_name, domain); | |
19681 | + sym = lookup_block_symbol (block, name, domain); | |
19682 | return fixup_symbol_section (sym, (struct objfile *)objfile); | |
19683 | } | |
19684 | } | |
3a58abaf | 19685 | |
7566401a ER |
19686 | if (objfile->separate_debug_objfile) |
19687 | return lookup_global_symbol_from_objfile (objfile->separate_debug_objfile, | |
19688 | - name, linkage_name, domain); | |
19689 | + name, domain); | |
3a58abaf | 19690 | |
7566401a ER |
19691 | return NULL; |
19692 | } | |
19693 | @@ -1488,8 +1528,7 @@ lookup_global_symbol_from_objfile (const struct objfile *objfile, | |
19694 | static symbols. */ | |
3a58abaf | 19695 | |
7566401a ER |
19696 | static struct symbol * |
19697 | -lookup_symbol_aux_symtabs (int block_index, | |
19698 | - const char *name, const char *linkage_name, | |
19699 | +lookup_symbol_aux_symtabs (int block_index, const char *name, | |
19700 | const domain_enum domain) | |
19701 | { | |
19702 | struct symbol *sym; | |
19703 | @@ -1502,7 +1541,7 @@ lookup_symbol_aux_symtabs (int block_index, | |
19704 | { | |
19705 | bv = BLOCKVECTOR (s); | |
19706 | block = BLOCKVECTOR_BLOCK (bv, block_index); | |
19707 | - sym = lookup_block_symbol (block, name, linkage_name, domain); | |
19708 | + sym = lookup_block_symbol (block, name, domain); | |
19709 | if (sym) | |
19710 | { | |
19711 | block_found = block; | |
19712 | @@ -1520,7 +1559,6 @@ lookup_symbol_aux_symtabs (int block_index, | |
3a58abaf | 19713 | |
7566401a ER |
19714 | static struct symbol * |
19715 | lookup_symbol_aux_psymtabs (int block_index, const char *name, | |
19716 | - const char *linkage_name, | |
19717 | const domain_enum domain) | |
19718 | { | |
19719 | struct symbol *sym; | |
19720 | @@ -1531,16 +1569,15 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name, | |
19721 | struct symtab *s; | |
19722 | const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0); | |
3a58abaf | 19723 | |
7566401a ER |
19724 | - ALL_PSYMTABS (objfile, ps) |
19725 | + ALL_PSYMTABS_REQUIRED (objfile, ps) | |
19726 | { | |
19727 | if (!ps->readin | |
19728 | - && lookup_partial_symbol (ps, name, linkage_name, | |
19729 | - psymtab_index, domain)) | |
19730 | + && lookup_partial_symbol (ps, name, psymtab_index, domain)) | |
19731 | { | |
19732 | s = PSYMTAB_TO_SYMTAB (ps); | |
19733 | bv = BLOCKVECTOR (s); | |
19734 | block = BLOCKVECTOR_BLOCK (bv, block_index); | |
19735 | - sym = lookup_block_symbol (block, name, linkage_name, domain); | |
19736 | + sym = lookup_block_symbol (block, name, domain); | |
19737 | if (!sym) | |
19738 | { | |
19739 | /* This shouldn't be necessary, but as a last resort try | |
19740 | @@ -1557,7 +1594,7 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name, | |
19741 | block = BLOCKVECTOR_BLOCK (bv, | |
19742 | block_index == GLOBAL_BLOCK ? | |
19743 | STATIC_BLOCK : GLOBAL_BLOCK); | |
19744 | - sym = lookup_block_symbol (block, name, linkage_name, domain); | |
19745 | + sym = lookup_block_symbol (block, name, domain); | |
19746 | if (!sym) | |
19747 | error (_("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>)."), | |
19748 | block_index == GLOBAL_BLOCK ? "global" : "static", | |
19749 | @@ -1576,7 +1613,6 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name, | |
19750 | ||
19751 | struct symbol * | |
19752 | basic_lookup_symbol_nonlocal (const char *name, | |
19753 | - const char *linkage_name, | |
19754 | const struct block *block, | |
19755 | const domain_enum domain) | |
19756 | { | |
19757 | @@ -1610,11 +1646,11 @@ basic_lookup_symbol_nonlocal (const char *name, | |
19758 | than that one, so I don't think we should worry about that for | |
19759 | now. */ | |
3a58abaf | 19760 | |
7566401a ER |
19761 | - sym = lookup_symbol_static (name, linkage_name, block, domain); |
19762 | + sym = lookup_symbol_static (name, block, domain); | |
19763 | if (sym != NULL) | |
19764 | return sym; | |
3a58abaf | 19765 | |
7566401a ER |
19766 | - return lookup_symbol_global (name, linkage_name, block, domain); |
19767 | + return lookup_symbol_global (name, block, domain); | |
3a58abaf AM |
19768 | } |
19769 | ||
7566401a ER |
19770 | /* Lookup a symbol in the static block associated to BLOCK, if there |
19771 | @@ -1622,14 +1658,13 @@ basic_lookup_symbol_nonlocal (const char *name, | |
19772 | ||
19773 | struct symbol * | |
19774 | lookup_symbol_static (const char *name, | |
19775 | - const char *linkage_name, | |
19776 | const struct block *block, | |
19777 | const domain_enum domain) | |
3a58abaf | 19778 | { |
7566401a | 19779 | const struct block *static_block = block_static_block (block); |
3a58abaf | 19780 | |
7566401a ER |
19781 | if (static_block != NULL) |
19782 | - return lookup_symbol_aux_block (name, linkage_name, static_block, domain); | |
19783 | + return lookup_symbol_aux_block (name, static_block, domain); | |
19784 | else | |
19785 | return NULL; | |
19786 | } | |
19787 | @@ -1639,7 +1674,6 @@ lookup_symbol_static (const char *name, | |
3a58abaf | 19788 | |
7566401a ER |
19789 | struct symbol * |
19790 | lookup_symbol_global (const char *name, | |
19791 | - const char *linkage_name, | |
19792 | const struct block *block, | |
19793 | const domain_enum domain) | |
19794 | { | |
19795 | @@ -1649,15 +1683,15 @@ lookup_symbol_global (const char *name, | |
19796 | /* Call library-specific lookup procedure. */ | |
19797 | objfile = lookup_objfile_from_block (block); | |
19798 | if (objfile != NULL) | |
19799 | - sym = solib_global_lookup (objfile, name, linkage_name, domain); | |
19800 | + sym = solib_global_lookup (objfile, name, domain); | |
19801 | if (sym != NULL) | |
19802 | return sym; | |
19803 | ||
19804 | - sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name, domain); | |
19805 | + sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, domain); | |
19806 | if (sym != NULL) | |
19807 | return sym; | |
19808 | ||
19809 | - return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name, domain); | |
19810 | + return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, domain); | |
19811 | } | |
3a58abaf | 19812 | |
7566401a ER |
19813 | int |
19814 | @@ -1681,14 +1715,11 @@ symbol_matches_domain (enum language symbol_language, | |
19815 | } | |
3a58abaf | 19816 | |
7566401a ER |
19817 | /* Look, in partial_symtab PST, for symbol whose natural name is NAME. |
19818 | - If LINKAGE_NAME is non-NULL, check in addition that the symbol's | |
19819 | - linkage name matches it. Check the global symbols if GLOBAL, the | |
19820 | - static symbols if not */ | |
19821 | + Check the global symbols if GLOBAL, the static symbols if not. */ | |
19822 | ||
19823 | struct partial_symbol * | |
19824 | lookup_partial_symbol (struct partial_symtab *pst, const char *name, | |
19825 | - const char *linkage_name, int global, | |
19826 | - domain_enum domain) | |
19827 | + int global, domain_enum domain) | |
19828 | { | |
19829 | struct partial_symbol *temp; | |
19830 | struct partial_symbol **start, **psym; | |
19831 | @@ -1740,9 +1771,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, | |
19832 | internal_error (__FILE__, __LINE__, _("failed internal consistency check")); | |
19833 | ||
19834 | while (top <= real_top | |
19835 | - && (linkage_name != NULL | |
19836 | - ? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0 | |
19837 | - : SYMBOL_MATCHES_SEARCH_NAME (*top,name))) | |
19838 | + && SYMBOL_MATCHES_SEARCH_NAME (*top, name)) | |
3a58abaf | 19839 | { |
7566401a ER |
19840 | if (symbol_matches_domain (SYMBOL_LANGUAGE (*top), |
19841 | SYMBOL_DOMAIN (*top), domain)) | |
19842 | @@ -1759,15 +1788,9 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, | |
19843 | for (psym = start; psym < start + length; psym++) | |
19844 | { | |
19845 | if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym), | |
19846 | - SYMBOL_DOMAIN (*psym), domain)) | |
19847 | - { | |
19848 | - if (linkage_name != NULL | |
19849 | - ? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0 | |
19850 | - : SYMBOL_MATCHES_SEARCH_NAME (*psym, name)) | |
19851 | - { | |
19852 | - return (*psym); | |
19853 | - } | |
19854 | - } | |
19855 | + SYMBOL_DOMAIN (*psym), domain) | |
19856 | + && SYMBOL_MATCHES_SEARCH_NAME (*psym, name)) | |
19857 | + return (*psym); | |
3a58abaf | 19858 | } |
3a58abaf AM |
19859 | } |
19860 | ||
7566401a ER |
19861 | @@ -1809,22 +1832,25 @@ basic_lookup_transparent_type (const char *name) |
19862 | { | |
19863 | bv = BLOCKVECTOR (s); | |
19864 | block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); | |
19865 | - sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); | |
19866 | + sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); | |
19867 | if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) | |
19868 | { | |
19869 | return SYMBOL_TYPE (sym); | |
19870 | } | |
19871 | } | |
3a58abaf | 19872 | |
7566401a ER |
19873 | - ALL_PSYMTABS (objfile, ps) |
19874 | + /* FIXME: .debug_pubnames should be read in. | |
19875 | + | |
19876 | + One may also try to the first pass without the require_partial_symbols | |
19877 | + call but that would behave nondeterministically. */ | |
19878 | + ALL_PSYMTABS_REQUIRED (objfile, ps) | |
19879 | { | |
19880 | - if (!ps->readin && lookup_partial_symbol (ps, name, NULL, | |
19881 | - 1, STRUCT_DOMAIN)) | |
19882 | + if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_DOMAIN)) | |
19883 | { | |
19884 | s = PSYMTAB_TO_SYMTAB (ps); | |
19885 | bv = BLOCKVECTOR (s); | |
19886 | block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); | |
19887 | - sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); | |
19888 | + sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); | |
19889 | if (!sym) | |
19890 | { | |
19891 | /* This shouldn't be necessary, but as a last resort | |
19892 | @@ -1833,7 +1859,7 @@ basic_lookup_transparent_type (const char *name) | |
19893 | * the psymtab gets it wrong in some cases. | |
19894 | */ | |
19895 | block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); | |
19896 | - sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); | |
19897 | + sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); | |
19898 | if (!sym) | |
19899 | error (_("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\ | |
19900 | %s may be an inlined function, or may be a template function\n\ | |
19901 | @@ -1857,21 +1883,26 @@ basic_lookup_transparent_type (const char *name) | |
19902 | { | |
19903 | bv = BLOCKVECTOR (s); | |
19904 | block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); | |
19905 | - sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); | |
19906 | + sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); | |
19907 | if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) | |
19908 | { | |
19909 | return SYMBOL_TYPE (sym); | |
19910 | } | |
19911 | } | |
3a58abaf | 19912 | |
7566401a ER |
19913 | - ALL_PSYMTABS (objfile, ps) |
19914 | + /* FIXME: Something like .debug_pubnames containing also static symbols | |
19915 | + should be read in. Compiler needs to be taught to generate it first. | |
19916 | + | |
19917 | + One may also try to the first pass without the require_partial_symbols | |
19918 | + call but that would behave nondeterministically. */ | |
19919 | + ALL_PSYMTABS_REQUIRED (objfile, ps) | |
19920 | { | |
19921 | - if (!ps->readin && lookup_partial_symbol (ps, name, NULL, 0, STRUCT_DOMAIN)) | |
19922 | + if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_DOMAIN)) | |
19923 | { | |
19924 | s = PSYMTAB_TO_SYMTAB (ps); | |
19925 | bv = BLOCKVECTOR (s); | |
19926 | block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); | |
19927 | - sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); | |
19928 | + sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); | |
19929 | if (!sym) | |
19930 | { | |
19931 | /* This shouldn't be necessary, but as a last resort | |
19932 | @@ -1880,7 +1911,7 @@ basic_lookup_transparent_type (const char *name) | |
19933 | * the psymtab gets it wrong in some cases. | |
19934 | */ | |
19935 | block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); | |
19936 | - sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN); | |
19937 | + sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); | |
19938 | if (!sym) | |
19939 | error (_("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\ | |
19940 | %s may be an inlined function, or may be a template function\n\ | |
19941 | @@ -1905,9 +1936,23 @@ find_main_psymtab (void) | |
19942 | struct partial_symtab *pst; | |
19943 | struct objfile *objfile; | |
19944 | ||
19945 | - ALL_PSYMTABS (objfile, pst) | |
19946 | + ALL_OBJFILES (objfile) | |
19947 | + { | |
19948 | + if ((objfile->flags & OBJF_MAIN) == 0) | |
19949 | + continue; | |
19950 | + require_partial_symbols (objfile); | |
19951 | + ALL_OBJFILE_PSYMTABS (objfile, pst) | |
19952 | + { | |
19953 | + if (lookup_partial_symbol (pst, main_name (), 1, VAR_DOMAIN)) | |
3a58abaf | 19954 | + { |
7566401a | 19955 | + return pst; |
3a58abaf | 19956 | + } |
7566401a ER |
19957 | + } |
19958 | + } | |
3a58abaf | 19959 | + |
7566401a ER |
19960 | + ALL_PSYMTABS_REQUIRED (objfile, pst) |
19961 | { | |
19962 | - if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN)) | |
19963 | + if (lookup_partial_symbol (pst, main_name (), 1, VAR_DOMAIN)) | |
19964 | { | |
19965 | return (pst); | |
19966 | } | |
19967 | @@ -1925,14 +1970,10 @@ find_main_psymtab (void) | |
19968 | search on the symbols. Each symbol which is marked as being a ObjC/C++ | |
19969 | symbol (language_cplus or language_objc set) has both the encoded and | |
19970 | non-encoded names tested for a match. | |
3a58abaf | 19971 | - |
7566401a ER |
19972 | - If LINKAGE_NAME is non-NULL, verify that any symbol we find has this |
19973 | - particular mangled name. | |
19974 | */ | |
3a58abaf | 19975 | |
7566401a ER |
19976 | struct symbol * |
19977 | lookup_block_symbol (const struct block *block, const char *name, | |
19978 | - const char *linkage_name, | |
19979 | const domain_enum domain) | |
3a58abaf | 19980 | { |
7566401a ER |
19981 | struct dict_iterator iter; |
19982 | @@ -1945,9 +1986,7 @@ lookup_block_symbol (const struct block *block, const char *name, | |
19983 | sym = dict_iter_name_next (name, &iter)) | |
19984 | { | |
19985 | if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), | |
19986 | - SYMBOL_DOMAIN (sym), domain) | |
19987 | - && (linkage_name != NULL | |
19988 | - ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1)) | |
19989 | + SYMBOL_DOMAIN (sym), domain)) | |
19990 | return sym; | |
3a58abaf | 19991 | } |
7566401a ER |
19992 | return NULL; |
19993 | @@ -1967,9 +2006,7 @@ lookup_block_symbol (const struct block *block, const char *name, | |
19994 | sym = dict_iter_name_next (name, &iter)) | |
3a58abaf | 19995 | { |
7566401a ER |
19996 | if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), |
19997 | - SYMBOL_DOMAIN (sym), domain) | |
19998 | - && (linkage_name != NULL | |
19999 | - ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1)) | |
20000 | + SYMBOL_DOMAIN (sym), domain)) | |
3a58abaf | 20001 | { |
7566401a ER |
20002 | sym_found = sym; |
20003 | if (!SYMBOL_IS_ARGUMENT (sym)) | |
20004 | @@ -3172,7 +3209,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[], | |
20005 | matching the regexp. That way we don't have to reproduce all of | |
20006 | the machinery below. */ | |
3a58abaf | 20007 | |
7566401a ER |
20008 | - ALL_PSYMTABS (objfile, ps) |
20009 | + ALL_PSYMTABS_REQUIRED (objfile, ps) | |
20010 | { | |
20011 | struct partial_symbol **bound, **gbound, **sbound; | |
20012 | int keep_going = 1; | |
20013 | diff --git a/gdb/symtab.h b/gdb/symtab.h | |
20014 | index 740d4e0..461ff95 100644 | |
20015 | --- a/gdb/symtab.h | |
20016 | +++ b/gdb/symtab.h | |
20017 | @@ -171,9 +171,6 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *); | |
20018 | #define SYMBOL_SECTION(symbol) (symbol)->ginfo.section | |
20019 | #define SYMBOL_OBJ_SECTION(symbol) (symbol)->ginfo.obj_section | |
3a58abaf | 20020 | |
7566401a ER |
20021 | -#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol) \ |
20022 | - (symbol)->ginfo.language_specific.cplus_specific.demangled_name | |
3a58abaf | 20023 | - |
7566401a ER |
20024 | /* Initializes the language dependent portion of a symbol |
20025 | depending upon the language for the symbol. */ | |
20026 | #define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \ | |
20027 | @@ -394,7 +391,13 @@ typedef enum domain_enum_tag | |
20028 | FUNCTIONS_DOMAIN, | |
3a58abaf | 20029 | |
7566401a ER |
20030 | /* All defined types */ |
20031 | - TYPES_DOMAIN | |
20032 | + TYPES_DOMAIN, | |
3a58abaf | 20033 | + |
7566401a ER |
20034 | + /* Fortran common blocks. Their naming must be separate from VAR_DOMAIN. */ |
20035 | + COMMON_BLOCK_DOMAIN, | |
3a58abaf | 20036 | + |
7566401a ER |
20037 | + /* Fortran module. Their naming must be separate. */ |
20038 | + MODULE_DOMAIN | |
3a58abaf | 20039 | } |
7566401a | 20040 | domain_enum; |
3a58abaf | 20041 | |
7566401a ER |
20042 | @@ -990,7 +993,6 @@ extern struct symbol *lookup_symbol (const char *, const struct block *, |
20043 | that can't think of anything better to do. */ | |
3a58abaf | 20044 | |
7566401a ER |
20045 | extern struct symbol *basic_lookup_symbol_nonlocal (const char *, |
20046 | - const char *, | |
20047 | const struct block *, | |
20048 | const domain_enum); | |
3a58abaf | 20049 | |
7566401a ER |
20050 | @@ -1001,7 +1003,6 @@ extern struct symbol *basic_lookup_symbol_nonlocal (const char *, |
20051 | is one; do nothing if BLOCK is NULL or a global block. */ | |
3a58abaf | 20052 | |
7566401a ER |
20053 | extern struct symbol *lookup_symbol_static (const char *name, |
20054 | - const char *linkage_name, | |
20055 | const struct block *block, | |
20056 | const domain_enum domain); | |
3a58abaf | 20057 | |
7566401a ER |
20058 | @@ -1009,7 +1010,6 @@ extern struct symbol *lookup_symbol_static (const char *name, |
20059 | necessary). */ | |
3a58abaf | 20060 | |
7566401a ER |
20061 | extern struct symbol *lookup_symbol_global (const char *name, |
20062 | - const char *linkage_name, | |
20063 | const struct block *block, | |
20064 | const domain_enum domain); | |
3a58abaf | 20065 | |
7566401a ER |
20066 | @@ -1018,21 +1018,18 @@ extern struct symbol *lookup_symbol_global (const char *name, |
20067 | will fix up the symbol if necessary. */ | |
3a58abaf | 20068 | |
7566401a ER |
20069 | extern struct symbol *lookup_symbol_aux_block (const char *name, |
20070 | - const char *linkage_name, | |
20071 | const struct block *block, | |
20072 | const domain_enum domain); | |
3a58abaf | 20073 | |
7566401a | 20074 | /* Lookup a partial symbol. */ |
3a58abaf | 20075 | |
7566401a ER |
20076 | extern struct partial_symbol *lookup_partial_symbol (struct partial_symtab *, |
20077 | - const char *, | |
20078 | const char *, int, | |
20079 | domain_enum); | |
3a58abaf | 20080 | |
7566401a | 20081 | /* lookup a symbol by name, within a specified block */ |
3a58abaf | 20082 | |
7566401a ER |
20083 | extern struct symbol *lookup_block_symbol (const struct block *, const char *, |
20084 | - const char *, | |
20085 | const domain_enum); | |
3a58abaf | 20086 | |
7566401a ER |
20087 | /* lookup a [struct, union, enum] by name, within a specified block */ |
20088 | @@ -1062,6 +1059,8 @@ extern void clear_pc_function_cache (void); | |
3a58abaf | 20089 | |
7566401a | 20090 | /* from symtab.c: */ |
3a58abaf | 20091 | |
7566401a ER |
20092 | +struct objfile *require_partial_symbols (struct objfile *); |
20093 | + | |
20094 | /* lookup partial symbol table by filename */ | |
3a58abaf | 20095 | |
7566401a ER |
20096 | extern struct partial_symtab *lookup_partial_symtab (const char *); |
20097 | @@ -1356,7 +1355,6 @@ extern /*const */ char *main_name (void); | |
20098 | /* Check global symbols in objfile. */ | |
20099 | struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile, | |
20100 | const char *name, | |
20101 | - const char *linkage_name, | |
20102 | const domain_enum domain); | |
3a58abaf | 20103 | |
7566401a ER |
20104 | extern struct symtabs_and_lines |
20105 | diff --git a/gdb/target.c b/gdb/target.c | |
20106 | index e5d14fd..37fab72 100644 | |
20107 | --- a/gdb/target.c | |
20108 | +++ b/gdb/target.c | |
20109 | @@ -124,6 +124,8 @@ static int debug_to_insert_watchpoint (CORE_ADDR, int, int); | |
20110 | ||
20111 | static int debug_to_remove_watchpoint (CORE_ADDR, int, int); | |
20112 | ||
20113 | +static int debug_to_detach_watchpoints (void); | |
20114 | + | |
20115 | static int debug_to_stopped_by_watchpoint (void); | |
20116 | ||
20117 | static int debug_to_stopped_data_address (struct target_ops *, CORE_ADDR *); | |
20118 | @@ -622,6 +624,7 @@ update_current_target (void) | |
20119 | INHERIT (to_remove_hw_breakpoint, t); | |
20120 | INHERIT (to_insert_watchpoint, t); | |
20121 | INHERIT (to_remove_watchpoint, t); | |
20122 | + INHERIT (to_detach_watchpoints, t); | |
20123 | INHERIT (to_stopped_data_address, t); | |
20124 | INHERIT (to_have_steppable_watchpoint, t); | |
20125 | INHERIT (to_have_continuable_watchpoint, t); | |
20126 | @@ -733,6 +736,9 @@ update_current_target (void) | |
20127 | de_fault (to_remove_watchpoint, | |
20128 | (int (*) (CORE_ADDR, int, int)) | |
20129 | return_minus_one); | |
20130 | + de_fault (to_detach_watchpoints, | |
20131 | + (int (*) (void)) | |
20132 | + return_zero); | |
20133 | de_fault (to_stopped_by_watchpoint, | |
20134 | (int (*) (void)) | |
20135 | return_zero); | |
20136 | @@ -3173,6 +3179,19 @@ debug_to_remove_watchpoint (CORE_ADDR addr, int len, int type) | |
20137 | return retval; | |
3a58abaf AM |
20138 | } |
20139 | ||
7566401a ER |
20140 | +static int |
20141 | +debug_to_detach_watchpoints (void) | |
3a58abaf | 20142 | +{ |
7566401a | 20143 | + int retval; |
3a58abaf | 20144 | + |
7566401a ER |
20145 | + retval = debug_target.to_detach_watchpoints (); |
20146 | + | |
20147 | + fprintf_unfiltered (gdb_stdlog, | |
20148 | + "target_detach_watchpoints () = %ld\n", | |
20149 | + (unsigned long) retval); | |
20150 | + return retval; | |
3a58abaf AM |
20151 | +} |
20152 | + | |
7566401a ER |
20153 | static void |
20154 | debug_to_terminal_init (void) | |
3a58abaf | 20155 | { |
7566401a ER |
20156 | @@ -3420,6 +3439,7 @@ setup_target_debug (void) |
20157 | current_target.to_remove_hw_breakpoint = debug_to_remove_hw_breakpoint; | |
20158 | current_target.to_insert_watchpoint = debug_to_insert_watchpoint; | |
20159 | current_target.to_remove_watchpoint = debug_to_remove_watchpoint; | |
20160 | + current_target.to_detach_watchpoints = debug_to_detach_watchpoints; | |
20161 | current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint; | |
20162 | current_target.to_stopped_data_address = debug_to_stopped_data_address; | |
20163 | current_target.to_watchpoint_addr_within_range = debug_to_watchpoint_addr_within_range; | |
3a58abaf | 20164 | diff --git a/gdb/target.h b/gdb/target.h |
ab050a48 | 20165 | index b1cb852..3c06eba 100644 |
3a58abaf AM |
20166 | --- a/gdb/target.h |
20167 | +++ b/gdb/target.h | |
7566401a ER |
20168 | @@ -395,6 +395,7 @@ struct target_ops |
20169 | int (*to_remove_hw_breakpoint) (struct gdbarch *, struct bp_target_info *); | |
20170 | int (*to_remove_watchpoint) (CORE_ADDR, int, int); | |
20171 | int (*to_insert_watchpoint) (CORE_ADDR, int, int); | |
20172 | + int (*to_detach_watchpoints) (void); | |
20173 | int (*to_stopped_by_watchpoint) (void); | |
20174 | int to_have_steppable_watchpoint; | |
20175 | int to_have_continuable_watchpoint; | |
ab050a48 BZ |
20176 | @@ -1124,7 +1125,7 @@ extern char *normal_pid_to_str (ptid_t ptid); |
20177 | /* Hardware watchpoint interfaces. */ | |
20178 | ||
20179 | /* Returns non-zero if we were stopped by a hardware watchpoint (memory read or | |
20180 | - write). */ | |
20181 | + write). Only the INFERIOR_PTID task is being queried. */ | |
20182 | ||
20183 | #define target_stopped_by_watchpoint \ | |
20184 | (*current_target.to_stopped_by_watchpoint) | |
20185 | @@ -1166,14 +1167,26 @@ extern char *normal_pid_to_str (ptid_t ptid); | |
7566401a ER |
20186 | #define target_remove_watchpoint(addr, len, type) \ |
20187 | (*current_target.to_remove_watchpoint) (addr, len, type) | |
20188 | ||
20189 | +/* Clear all debug registers without affecting any register caches. Function | |
20190 | + acts on INFERIOR_PTID which should be the forked-off process, either the | |
20191 | + non-threaded child one or the threaded parent one, depending on `set | |
20192 | + follow-fork-mode'. Both watchpoints and hardware breakpoints get removed. | |
20193 | + Return 0 on success, -1 on failure. */ | |
20194 | + | |
20195 | +#define target_detach_watchpoints() \ | |
20196 | + (*current_target.to_detach_watchpoints) () | |
20197 | + | |
20198 | #define target_insert_hw_breakpoint(gdbarch, bp_tgt) \ | |
20199 | (*current_target.to_insert_hw_breakpoint) (gdbarch, bp_tgt) | |
20200 | ||
ab050a48 BZ |
20201 | #define target_remove_hw_breakpoint(gdbarch, bp_tgt) \ |
20202 | (*current_target.to_remove_hw_breakpoint) (gdbarch, bp_tgt) | |
20203 | ||
20204 | -#define target_stopped_data_address(target, x) \ | |
20205 | - (*target.to_stopped_data_address) (target, x) | |
20206 | +/* Return non-zero if target knows the data address which triggered this | |
20207 | + target_stopped_by_watchpoint, in such case place it to *ADDR_P. Only the | |
20208 | + INFERIOR_PTID task is being queried. */ | |
20209 | +#define target_stopped_data_address(target, addr_p) \ | |
20210 | + (*target.to_stopped_data_address) (target, addr_p) | |
20211 | ||
20212 | #define target_watchpoint_addr_within_range(target, addr, start, length) \ | |
20213 | (*target.to_watchpoint_addr_within_range) (target, addr, start, length) | |
20214 | @@ -1203,6 +1216,20 @@ extern int target_search_memory (CORE_ADDR start_addr, | |
3a58abaf AM |
20215 | ULONGEST pattern_len, |
20216 | CORE_ADDR *found_addrp); | |
20217 | ||
20218 | +/* Utility functions which can be used by search_memory implementations. */ | |
20219 | + | |
20220 | +void allocate_pattern_buffer (char **pattern_bufp, char **pattern_buf_end, | |
20221 | + ULONGEST *pattern_buf_size); | |
20222 | + | |
20223 | +void increase_pattern_buffer (char **pattern_bufp, char **pattern_buf_end, | |
20224 | + ULONGEST *pattern_buf_size, int val_bytes); | |
20225 | + | |
20226 | +int search_memory (CORE_ADDR *start_addr, ULONGEST *search_space_len, | |
20227 | + const char *pattern_buf, ULONGEST pattern_len, | |
20228 | + CORE_ADDR *found_addr); | |
20229 | + | |
20230 | +void put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p); | |
20231 | + | |
20232 | /* Command logging facility. */ | |
20233 | ||
20234 | #define target_log_command(p) \ | |
ab050a48 | 20235 | @@ -1322,6 +1349,14 @@ extern struct target_ops *find_target_beneath (struct target_ops *); |
7566401a ER |
20236 | |
20237 | extern char *target_get_osdata (const char *type); | |
20238 | ||
20239 | +/* Read OS data object of type TYPE from the target, and return it in | |
20240 | + XML format. The result is NUL-terminated and returned as a string, | |
20241 | + allocated using xmalloc. If an error occurs or the transfer is | |
20242 | + unsupported, NULL is returned. Empty objects are returned as | |
20243 | + allocated but empty strings. */ | |
3a58abaf | 20244 | + |
7566401a | 20245 | +extern char *target_get_osdata (const char *type); |
3a58abaf | 20246 | + |
7566401a ER |
20247 | \f |
20248 | /* Stuff that should be shared among the various remote targets. */ | |
20249 | ||
3a58abaf AM |
20250 | diff --git a/gdb/testsuite/gdb.arch/powerpc-power7.exp b/gdb/testsuite/gdb.arch/powerpc-power7.exp |
20251 | new file mode 100644 | |
7566401a | 20252 | index 0000000..ae301db |
3a58abaf AM |
20253 | --- /dev/null |
20254 | +++ b/gdb/testsuite/gdb.arch/powerpc-power7.exp | |
7566401a | 20255 | @@ -0,0 +1,175 @@ |
3a58abaf AM |
20256 | +# Copyright 2009 Free Software Foundation, Inc. |
20257 | + | |
20258 | +# This program is free software; you can redistribute it and/or modify | |
20259 | +# it under the terms of the GNU General Public License as published by | |
20260 | +# the Free Software Foundation; either version 2 of the License, or | |
20261 | +# (at your option) any later version. | |
20262 | +# | |
20263 | +# This program is distributed in the hope that it will be useful, | |
20264 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20265 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20266 | +# GNU General Public License for more details. | |
20267 | +# | |
20268 | +# You should have received a copy of the GNU General Public License | |
20269 | +# along with this program; if not, write to the Free Software | |
20270 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
20271 | + | |
20272 | +# Test PowerPC Power7 instructions disassembly. | |
20273 | + | |
20274 | +if {![istarget "powerpc*-*-*"]} then { | |
20275 | + verbose "Skipping PowerPC Power7 instructions disassembly." | |
20276 | + return | |
20277 | +} | |
20278 | + | |
20279 | +set testfile "powerpc-power7" | |
20280 | +set srcfile ${testfile}.s | |
20281 | +set objfile ${objdir}/${subdir}/${testfile}.o | |
20282 | + | |
20283 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] != "" } { | |
20284 | + untested "PowerPC Power7 instructions disassembly" | |
20285 | + return -1 | |
20286 | +} | |
20287 | + | |
20288 | + | |
20289 | +gdb_exit | |
20290 | +gdb_start | |
20291 | +gdb_reinitialize_dir $srcdir/$subdir | |
20292 | +gdb_load ${objfile} | |
20293 | + | |
20294 | + | |
20295 | +# Disassemble the function. | |
20296 | + | |
20297 | +set test "disass func" | |
20298 | +gdb_test_multiple $test $test { | |
20299 | + -re "\r\nDump of assembler code for function func:(\r\n.*\r\n)End of assembler dump.\r\n$gdb_prompt $" { | |
20300 | + set func $expect_out(1,string) | |
20301 | + pass $test | |
20302 | + } | |
20303 | +} | |
20304 | + | |
7566401a ER |
20305 | +proc instr_to_patt {offset instr} { |
20306 | + # 0x0000000000000018 <func+24>: stxvd2x vs43,r4,r5 | |
20307 | + return ".*\r\n[string map {0x 0x0*} $offset] <func\\+?\[0-9\]*>:\[ \t\]*[string map [list { } "\[ \t\]+" . {\.}] $instr]\[ \t\]*\r\n.*" | |
20308 | +} | |
20309 | + | |
20310 | +# KFAIL strings would not exist if -Many would print the same as -Mpower7. | |
20311 | +# That means the power7 form should be the preferred one. | |
20312 | +# http://sourceware.org/ml/gdb-patches/2009-03/threads.html#00020 | |
20313 | + | |
20314 | +proc func_check {offset instr {kfail ""}} { | |
3a58abaf AM |
20315 | + global func |
20316 | + | |
3a58abaf | 20317 | + set test "Found $offset: $instr" |
7566401a | 20318 | + if [regexp -nocase -line [instr_to_patt $offset $instr] $func] { |
3a58abaf | 20319 | + pass $test |
7566401a ER |
20320 | + } elseif {$kfail != "" && [regexp -nocase -line [instr_to_patt $offset $kfail] $func]} { |
20321 | + kfail gdb/NNNN $test | |
3a58abaf AM |
20322 | + } else { |
20323 | + fail $test | |
20324 | + } | |
20325 | +} | |
20326 | + | |
20327 | +func_check 0x0 "lxvd2x vs3,r4,r5" | |
20328 | +func_check 0x4 "lxvd2ux vs3,r4,r5" | |
20329 | +func_check 0x8 "lxvd2x vs43,r4,r5" | |
20330 | +func_check 0xc "lxvd2ux vs43,r4,r5" | |
20331 | +func_check 0x10 "stxvd2x vs3,r4,r5" | |
20332 | +func_check 0x14 "stxvd2ux vs3,r4,r5" | |
20333 | +func_check 0x18 "stxvd2x vs43,r4,r5" | |
20334 | +func_check 0x1c "stxvd2ux vs43,r4,r5" | |
20335 | +func_check 0x20 "xxmrghd vs3,vs4,vs5" | |
20336 | +func_check 0x24 "xxmrghd vs43,vs44,vs45" | |
20337 | +func_check 0x28 "xxmrgld vs3,vs4,vs5" | |
20338 | +func_check 0x2c "xxmrgld vs43,vs44,vs45" | |
20339 | +func_check 0x30 "xxmrghd vs3,vs4,vs5" | |
20340 | +func_check 0x34 "xxmrghd vs43,vs44,vs45" | |
20341 | +func_check 0x38 "xxmrgld vs3,vs4,vs5" | |
20342 | +func_check 0x3c "xxmrgld vs43,vs44,vs45" | |
20343 | +func_check 0x40 "xxpermdi vs3,vs4,vs5,1" | |
20344 | +func_check 0x44 "xxpermdi vs43,vs44,vs45,1" | |
20345 | +func_check 0x48 "xxpermdi vs3,vs4,vs5,2" | |
20346 | +func_check 0x4c "xxpermdi vs43,vs44,vs45,2" | |
20347 | +func_check 0x50 "xvmovdp vs3,vs4" | |
20348 | +func_check 0x54 "xvmovdp vs43,vs44" | |
20349 | +func_check 0x58 "xvmovdp vs3,vs4" | |
20350 | +func_check 0x5c "xvmovdp vs43,vs44" | |
20351 | +func_check 0x60 "xvcpsgndp vs3,vs4,vs5" | |
20352 | +func_check 0x64 "xvcpsgndp vs43,vs44,vs45" | |
20353 | +func_check 0x68 "wait" | |
20354 | +func_check 0x6c "wait" | |
20355 | +func_check 0x70 "waitrsv" | |
20356 | +func_check 0x74 "waitrsv" | |
20357 | +func_check 0x78 "waitimpl" | |
20358 | +func_check 0x7c "waitimpl" | |
20359 | +func_check 0x80 "doze" | |
20360 | +func_check 0x84 "nap" | |
20361 | +func_check 0x88 "sleep" | |
20362 | +func_check 0x8c "rvwinkle" | |
20363 | +func_check 0x90 "prtyw r3,r4" | |
20364 | +func_check 0x94 "prtyd r13,r14" | |
7566401a ER |
20365 | +func_check 0x98 "mfcfar r10" "mfspr r10,28" |
20366 | +func_check 0x9c "mtcfar r11" "mtspr 28,r11" | |
3a58abaf AM |
20367 | +func_check 0xa0 "cmpb r3,r4,r5" |
20368 | +func_check 0xa4 "lwzcix r10,r11,r12" | |
20369 | +func_check 0xa8 "dadd f16,f17,f18" | |
20370 | +func_check 0xac "daddq f20,f22,f24" | |
20371 | +func_check 0xb0 "dss 3" | |
20372 | +func_check 0xb4 "dssall" | |
20373 | +func_check 0xb8 "dst r5,r4,1" | |
20374 | +func_check 0xbc "dstt r8,r7,0" | |
20375 | +func_check 0xc0 "dstst r5,r6,3" | |
20376 | +func_check 0xc4 "dststt r4,r5,2" | |
20377 | +func_check 0xc8 "divwe r10,r11,r12" | |
20378 | +func_check 0xcc "divwe. r11,r12,r13" | |
20379 | +func_check 0xd0 "divweo r12,r13,r14" | |
20380 | +func_check 0xd4 "divweo. r13,r14,r15" | |
20381 | +func_check 0xd8 "divweu r10,r11,r12" | |
20382 | +func_check 0xdc "divweu. r11,r12,r13" | |
20383 | +func_check 0xe0 "divweuo r12,r13,r14" | |
20384 | +func_check 0xe4 "divweuo. r13,r14,r15" | |
20385 | +func_check 0xe8 "bpermd r7,r17,r27" | |
20386 | +func_check 0xec "popcntw r10,r20" | |
20387 | +func_check 0xf0 "popcntd r10,r20" | |
20388 | +func_check 0xf4 "ldbrx r20,r21,r22" | |
20389 | +func_check 0xf8 "stdbrx r20,r21,r22" | |
20390 | +func_check 0xfc "lfiwzx f10,0,r10" | |
20391 | +func_check 0x100 "lfiwzx f10,r9,r10" | |
20392 | +func_check 0x104 "fcfids f4,f5" | |
20393 | +func_check 0x108 "fcfids. f4,f5" | |
20394 | +func_check 0x10c "fcfidus f4,f5" | |
20395 | +func_check 0x110 "fcfidus. f4,f5" | |
20396 | +func_check 0x114 "fctiwu f4,f5" | |
20397 | +func_check 0x118 "fctiwu. f4,f5" | |
20398 | +func_check 0x11c "fctiwuz f4,f5" | |
20399 | +func_check 0x120 "fctiwuz. f4,f5" | |
20400 | +func_check 0x124 "fctidu f4,f5" | |
20401 | +func_check 0x128 "fctidu. f4,f5" | |
20402 | +func_check 0x12c "fctiduz f4,f5" | |
20403 | +func_check 0x130 "fctiduz. f4,f5" | |
20404 | +func_check 0x134 "fcfidu f4,f5" | |
20405 | +func_check 0x138 "fcfidu. f4,f5" | |
20406 | +func_check 0x13c "ftdiv cr0,f10,f11" | |
20407 | +func_check 0x140 "ftdiv cr7,f10,f11" | |
20408 | +func_check 0x144 "ftsqrt cr0,f10" | |
20409 | +func_check 0x148 "ftsqrt cr7,f10" | |
7566401a ER |
20410 | +func_check 0x14c "dcbtt r8,r9" "dcbt 16,r8,r9" |
20411 | +func_check 0x150 "dcbtstt r8,r9" "dcbtst 16,r8,r9" | |
3a58abaf AM |
20412 | +func_check 0x154 "dcffix f10,f12" |
20413 | +func_check 0x158 "dcffix. f20,f22" | |
20414 | +func_check 0x15c "lbarx r10,r11,r12" | |
20415 | +func_check 0x160 "lbarx r10,r11,r12" | |
20416 | +func_check 0x164 "lbarx r10,r11,r12,1" | |
20417 | +func_check 0x168 "lharx r20,r21,r22" | |
20418 | +func_check 0x16c "lharx r20,r21,r22" | |
20419 | +func_check 0x170 "lharx r20,r21,r22,1" | |
20420 | +func_check 0x174 "stbcx. r10,r11,r12" | |
20421 | +func_check 0x178 "sthcx. r10,r11,r12" | |
20422 | +func_check 0x17c "fre f14,f15" | |
20423 | +func_check 0x180 "fre. f14,f15" | |
20424 | +func_check 0x184 "fres f14,f15" | |
20425 | +func_check 0x188 "fres. f14,f15" | |
20426 | +func_check 0x18c "frsqrte f14,f15" | |
20427 | +func_check 0x190 "frsqrte. f14,f15" | |
20428 | +func_check 0x194 "frsqrtes f14,f15" | |
20429 | +func_check 0x198 "frsqrtes. f14,f15" | |
20430 | +func_check 0x19c "isel r2,r3,r4,28" | |
20431 | diff --git a/gdb/testsuite/gdb.arch/powerpc-power7.s b/gdb/testsuite/gdb.arch/powerpc-power7.s | |
20432 | new file mode 100644 | |
20433 | index 0000000..98b2e79 | |
20434 | --- /dev/null | |
20435 | +++ b/gdb/testsuite/gdb.arch/powerpc-power7.s | |
20436 | @@ -0,0 +1,107 @@ | |
20437 | + .text | |
20438 | + .globl func | |
20439 | +func: | |
20440 | + .long 0x7c642e98 /* 0: lxvd2x vs3,r4,r5 */ | |
20441 | + .long 0x7c642ed8 /* 4: lxvd2ux vs3,r4,r5 */ | |
20442 | + .long 0x7d642e99 /* 8: lxvd2x vs43,r4,r5 */ | |
20443 | + .long 0x7d642ed9 /* c: lxvd2ux vs43,r4,r5 */ | |
20444 | + .long 0x7c642f98 /* 10: stxvd2x vs3,r4,r5 */ | |
20445 | + .long 0x7c642fd8 /* 14: stxvd2ux vs3,r4,r5 */ | |
20446 | + .long 0x7d642f99 /* 18: stxvd2x vs43,r4,r5 */ | |
20447 | + .long 0x7d642fd9 /* 1c: stxvd2ux vs43,r4,r5 */ | |
20448 | + .long 0xf0642850 /* 20: xxmrghd vs3,vs4,vs5 */ | |
20449 | + .long 0xf16c6857 /* 24: xxmrghd vs43,vs44,vs45 */ | |
20450 | + .long 0xf0642b50 /* 28: xxmrgld vs3,vs4,vs5 */ | |
20451 | + .long 0xf16c6b57 /* 2c: xxmrgld vs43,vs44,vs45 */ | |
20452 | + .long 0xf0642850 /* 30: xxmrghd vs3,vs4,vs5 */ | |
20453 | + .long 0xf16c6857 /* 34: xxmrghd vs43,vs44,vs45 */ | |
20454 | + .long 0xf0642b50 /* 38: xxmrgld vs3,vs4,vs5 */ | |
20455 | + .long 0xf16c6b57 /* 3c: xxmrgld vs43,vs44,vs45 */ | |
20456 | + .long 0xf0642950 /* 40: xxpermdi vs3,vs4,vs5,1 */ | |
20457 | + .long 0xf16c6957 /* 44: xxpermdi vs43,vs44,vs45,1 */ | |
20458 | + .long 0xf0642a50 /* 48: xxpermdi vs3,vs4,vs5,2 */ | |
20459 | + .long 0xf16c6a57 /* 4c: xxpermdi vs43,vs44,vs45,2 */ | |
20460 | + .long 0xf0642780 /* 50: xvmovdp vs3,vs4 */ | |
20461 | + .long 0xf16c6787 /* 54: xvmovdp vs43,vs44 */ | |
20462 | + .long 0xf0642780 /* 58: xvmovdp vs3,vs4 */ | |
20463 | + .long 0xf16c6787 /* 5c: xvmovdp vs43,vs44 */ | |
20464 | + .long 0xf0642f80 /* 60: xvcpsgndp vs3,vs4,vs5 */ | |
20465 | + .long 0xf16c6f87 /* 64: xvcpsgndp vs43,vs44,vs45 */ | |
20466 | + .long 0x7c00007c /* 68: wait */ | |
20467 | + .long 0x7c00007c /* 6c: wait */ | |
20468 | + .long 0x7c20007c /* 70: waitrsv */ | |
20469 | + .long 0x7c20007c /* 74: waitrsv */ | |
20470 | + .long 0x7c40007c /* 78: waitimpl */ | |
20471 | + .long 0x7c40007c /* 7c: waitimpl */ | |
20472 | + .long 0x4c000324 /* 80: doze */ | |
20473 | + .long 0x4c000364 /* 84: nap */ | |
20474 | + .long 0x4c0003a4 /* 88: sleep */ | |
20475 | + .long 0x4c0003e4 /* 8c: rvwinkle */ | |
20476 | + .long 0x7c830134 /* 90: prtyw r3,r4 */ | |
20477 | + .long 0x7dcd0174 /* 94: prtyd r13,r14 */ | |
20478 | + .long 0x7d5c02a6 /* 98: mfcfar r10 */ | |
20479 | + .long 0x7d7c03a6 /* 9c: mtcfar r11 */ | |
20480 | + .long 0x7c832bf8 /* a0: cmpb r3,r4,r5 */ | |
20481 | + .long 0x7d4b662a /* a4: lwzcix r10,r11,r12 */ | |
20482 | + .long 0xee119004 /* a8: dadd f16,f17,f18 */ | |
20483 | + .long 0xfe96c004 /* ac: daddq f20,f22,f24 */ | |
20484 | + .long 0x7c60066c /* b0: dss 3 */ | |
20485 | + .long 0x7e00066c /* b4: dssall */ | |
20486 | + .long 0x7c2522ac /* b8: dst r5,r4,1 */ | |
20487 | + .long 0x7e083aac /* bc: dstt r8,r7,0 */ | |
20488 | + .long 0x7c6532ec /* c0: dstst r5,r6,3 */ | |
20489 | + .long 0x7e442aec /* c4: dststt r4,r5,2 */ | |
20490 | + .long 0x7d4b6356 /* c8: divwe r10,r11,r12 */ | |
20491 | + .long 0x7d6c6b57 /* cc: divwe. r11,r12,r13 */ | |
20492 | + .long 0x7d8d7756 /* d0: divweo r12,r13,r14 */ | |
20493 | + .long 0x7dae7f57 /* d4: divweo. r13,r14,r15 */ | |
20494 | + .long 0x7d4b6316 /* d8: divweu r10,r11,r12 */ | |
20495 | + .long 0x7d6c6b17 /* dc: divweu. r11,r12,r13 */ | |
20496 | + .long 0x7d8d7716 /* e0: divweuo r12,r13,r14 */ | |
20497 | + .long 0x7dae7f17 /* e4: divweuo. r13,r14,r15 */ | |
20498 | + .long 0x7e27d9f8 /* e8: bpermd r7,r17,r27 */ | |
20499 | + .long 0x7e8a02f4 /* ec: popcntw r10,r20 */ | |
20500 | + .long 0x7e8a03f4 /* f0: popcntd r10,r20 */ | |
20501 | + .long 0x7e95b428 /* f4: ldbrx r20,r21,r22 */ | |
20502 | + .long 0x7e95b528 /* f8: stdbrx r20,r21,r22 */ | |
20503 | + .long 0x7d4056ee /* fc: lfiwzx f10,0,r10 */ | |
20504 | + .long 0x7d4956ee /* 100: lfiwzx f10,r9,r10 */ | |
20505 | + .long 0xec802e9c /* 104: fcfids f4,f5 */ | |
20506 | + .long 0xec802e9d /* 108: fcfids. f4,f5 */ | |
20507 | + .long 0xec802f9c /* 10c: fcfidus f4,f5 */ | |
20508 | + .long 0xec802f9d /* 110: fcfidus. f4,f5 */ | |
20509 | + .long 0xfc80291c /* 114: fctiwu f4,f5 */ | |
20510 | + .long 0xfc80291d /* 118: fctiwu. f4,f5 */ | |
20511 | + .long 0xfc80291e /* 11c: fctiwuz f4,f5 */ | |
20512 | + .long 0xfc80291f /* 120: fctiwuz. f4,f5 */ | |
20513 | + .long 0xfc802f5c /* 124: fctidu f4,f5 */ | |
20514 | + .long 0xfc802f5d /* 128: fctidu. f4,f5 */ | |
20515 | + .long 0xfc802f5e /* 12c: fctiduz f4,f5 */ | |
20516 | + .long 0xfc802f5f /* 130: fctiduz. f4,f5 */ | |
20517 | + .long 0xfc802f9c /* 134: fcfidu f4,f5 */ | |
20518 | + .long 0xfc802f9d /* 138: fcfidu. f4,f5 */ | |
20519 | + .long 0xfc0a5900 /* 13c: ftdiv cr0,f10,f11 */ | |
20520 | + .long 0xff8a5900 /* 140: ftdiv cr7,f10,f11 */ | |
20521 | + .long 0xfc005140 /* 144: ftsqrt cr0,f10 */ | |
20522 | + .long 0xff805140 /* 148: ftsqrt cr7,f10 */ | |
20523 | + .long 0x7e084a2c /* 14c: dcbtt r8,r9 */ | |
20524 | + .long 0x7e0849ec /* 150: dcbtstt r8,r9 */ | |
20525 | + .long 0xed406644 /* 154: dcffix f10,f12 */ | |
20526 | + .long 0xee80b645 /* 158: dcffix. f20,f22 */ | |
20527 | + .long 0x7d4b6068 /* 15c: lbarx r10,r11,r12 */ | |
20528 | + .long 0x7d4b6068 /* 160: lbarx r10,r11,r12 */ | |
20529 | + .long 0x7d4b6069 /* 164: lbarx r10,r11,r12,1 */ | |
20530 | + .long 0x7e95b0e8 /* 168: lharx r20,r21,r22 */ | |
20531 | + .long 0x7e95b0e8 /* 16c: lharx r20,r21,r22 */ | |
20532 | + .long 0x7e95b0e9 /* 170: lharx r20,r21,r22,1 */ | |
20533 | + .long 0x7d4b656d /* 174: stbcx. r10,r11,r12 */ | |
20534 | + .long 0x7d4b65ad /* 178: sthcx. r10,r11,r12 */ | |
20535 | + .long 0xfdc07830 /* 17c: fre f14,f15 */ | |
20536 | + .long 0xfdc07831 /* 180: fre. f14,f15 */ | |
20537 | + .long 0xedc07830 /* 184: fres f14,f15 */ | |
20538 | + .long 0xedc07831 /* 188: fres. f14,f15 */ | |
20539 | + .long 0xfdc07834 /* 18c: frsqrte f14,f15 */ | |
20540 | + .long 0xfdc07835 /* 190: frsqrte. f14,f15 */ | |
20541 | + .long 0xedc07834 /* 194: frsqrtes f14,f15 */ | |
20542 | + .long 0xedc07835 /* 198: frsqrtes. f14,f15 */ | |
20543 | + .long 0x7c43271e /* 19c: isel r2,r3,r4,28 */ | |
20544 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S | |
20545 | new file mode 100644 | |
20546 | index 0000000..66f7a39 | |
20547 | --- /dev/null | |
20548 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S | |
20549 | @@ -0,0 +1,455 @@ | |
20550 | + .file "x86_64-vla-typedef.c" | |
20551 | + .section .debug_abbrev,"",@progbits | |
20552 | +.Ldebug_abbrev0: | |
20553 | + .section .debug_info,"",@progbits | |
20554 | +.Ldebug_info0: | |
20555 | + .section .debug_line,"",@progbits | |
20556 | +.Ldebug_line0: | |
20557 | + .text | |
20558 | +.Ltext0: | |
20559 | +.globl foo | |
20560 | + .type foo, @function | |
20561 | +foo: | |
20562 | +.LFB2: | |
20563 | + .file 1 "x86_64-vla-typedef.c" | |
20564 | + .loc 1 22 0 | |
20565 | + pushq %rbp | |
20566 | +.LCFI0: | |
20567 | + movq %rsp, %rbp | |
20568 | +.LCFI1: | |
20569 | + subq $64, %rsp | |
20570 | +.LCFI2: | |
20571 | + movl %edi, -36(%rbp) | |
20572 | + .loc 1 22 0 | |
20573 | + movq %rsp, %rax | |
20574 | + movq %rax, -48(%rbp) | |
20575 | + .loc 1 23 0 | |
20576 | + movl -36(%rbp), %edx | |
20577 | + movslq %edx,%rax | |
20578 | + subq $1, %rax | |
20579 | + movq %rax, -24(%rbp) | |
20580 | + .loc 1 24 0 | |
20581 | + movslq %edx,%rax | |
20582 | + addq $15, %rax | |
20583 | + addq $15, %rax | |
20584 | + shrq $4, %rax | |
20585 | + salq $4, %rax | |
20586 | + subq %rax, %rsp | |
20587 | + movq %rsp, -56(%rbp) | |
20588 | + movq -56(%rbp), %rax | |
20589 | + addq $15, %rax | |
20590 | + shrq $4, %rax | |
20591 | + salq $4, %rax | |
20592 | + movq %rax, -56(%rbp) | |
20593 | + movq -56(%rbp), %rax | |
20594 | + movq %rax, -16(%rbp) | |
20595 | + .loc 1 27 0 | |
20596 | + movl $0, -4(%rbp) | |
20597 | + jmp .L2 | |
20598 | +.L3: | |
20599 | + .loc 1 28 0 | |
20600 | + movl -4(%rbp), %esi | |
20601 | + movl -4(%rbp), %eax | |
20602 | + movl %eax, %ecx | |
20603 | + movq -16(%rbp), %rdx | |
20604 | + movslq %esi,%rax | |
20605 | + movb %cl, (%rdx,%rax) | |
20606 | + .loc 1 27 0 | |
20607 | + addl $1, -4(%rbp) | |
20608 | +.L2: | |
20609 | + movl -4(%rbp), %eax | |
20610 | + cmpl -36(%rbp), %eax | |
20611 | + jl .L3 | |
20612 | + .loc 1 30 0 | |
20613 | + .globl break_here | |
20614 | +break_here: | |
20615 | + movq -16(%rbp), %rax | |
20616 | + movb $0, (%rax) | |
20617 | + movq -48(%rbp), %rsp | |
20618 | + .loc 1 31 0 | |
20619 | + leave | |
20620 | + ret | |
20621 | +.LFE2: | |
20622 | + .size foo, .-foo | |
20623 | + .section .debug_frame,"",@progbits | |
20624 | +.Lframe0: | |
20625 | + .long .LECIE0-.LSCIE0 | |
20626 | +.LSCIE0: | |
20627 | + .long 0xffffffff | |
20628 | + .byte 0x1 | |
20629 | + .string "" | |
20630 | + .uleb128 0x1 | |
20631 | + .sleb128 -8 | |
20632 | + .byte 0x10 | |
20633 | + .byte 0xc | |
20634 | + .uleb128 0x7 | |
20635 | + .uleb128 0x8 | |
20636 | + .byte 0x90 | |
20637 | + .uleb128 0x1 | |
20638 | + .align 8 | |
20639 | +.LECIE0: | |
20640 | +.LSFDE0: | |
20641 | + .long .LEFDE0-.LASFDE0 | |
20642 | +.LASFDE0: | |
20643 | + .long .Lframe0 | |
20644 | + .quad .LFB2 | |
20645 | + .quad .LFE2-.LFB2 | |
20646 | + .byte 0x4 | |
20647 | + .long .LCFI0-.LFB2 | |
20648 | + .byte 0xe | |
20649 | + .uleb128 0x10 | |
20650 | + .byte 0x86 | |
20651 | + .uleb128 0x2 | |
20652 | + .byte 0x4 | |
20653 | + .long .LCFI1-.LCFI0 | |
20654 | + .byte 0xd | |
20655 | + .uleb128 0x6 | |
20656 | + .align 8 | |
20657 | +.LEFDE0: | |
20658 | + .section .eh_frame,"a",@progbits | |
20659 | +.Lframe1: | |
20660 | + .long .LECIE1-.LSCIE1 | |
20661 | +.LSCIE1: | |
20662 | + .long 0x0 | |
20663 | + .byte 0x1 | |
20664 | + .string "zR" | |
20665 | + .uleb128 0x1 | |
20666 | + .sleb128 -8 | |
20667 | + .byte 0x10 | |
20668 | + .uleb128 0x1 | |
20669 | + .byte 0x3 | |
20670 | + .byte 0xc | |
20671 | + .uleb128 0x7 | |
20672 | + .uleb128 0x8 | |
20673 | + .byte 0x90 | |
20674 | + .uleb128 0x1 | |
20675 | + .align 8 | |
20676 | +.LECIE1: | |
20677 | +.LSFDE1: | |
20678 | + .long .LEFDE1-.LASFDE1 | |
20679 | +.LASFDE1: | |
20680 | + .long .LASFDE1-.Lframe1 | |
20681 | + .long .LFB2 | |
20682 | + .long .LFE2-.LFB2 | |
20683 | + .uleb128 0x0 | |
20684 | + .byte 0x4 | |
20685 | + .long .LCFI0-.LFB2 | |
20686 | + .byte 0xe | |
20687 | + .uleb128 0x10 | |
20688 | + .byte 0x86 | |
20689 | + .uleb128 0x2 | |
20690 | + .byte 0x4 | |
20691 | + .long .LCFI1-.LCFI0 | |
20692 | + .byte 0xd | |
20693 | + .uleb128 0x6 | |
20694 | + .align 8 | |
20695 | +.LEFDE1: | |
20696 | + .text | |
20697 | +.Letext0: | |
20698 | + .section .debug_loc,"",@progbits | |
20699 | +.Ldebug_loc0: | |
20700 | +.LLST0: | |
20701 | + .quad .LFB2-.Ltext0 | |
20702 | + .quad .LCFI0-.Ltext0 | |
20703 | + .value 0x2 | |
20704 | + .byte 0x77 | |
20705 | + .sleb128 8 | |
20706 | + .quad .LCFI0-.Ltext0 | |
20707 | + .quad .LCFI1-.Ltext0 | |
20708 | + .value 0x2 | |
20709 | + .byte 0x77 | |
20710 | + .sleb128 16 | |
20711 | + .quad .LCFI1-.Ltext0 | |
20712 | + .quad .LFE2-.Ltext0 | |
20713 | + .value 0x2 | |
20714 | + .byte 0x76 | |
20715 | + .sleb128 16 | |
20716 | + .quad 0x0 | |
20717 | + .quad 0x0 | |
20718 | + .section .debug_info | |
20719 | + .long .Ldebug_end - .Ldebug_start | |
20720 | +.Ldebug_start: | |
20721 | + .value 0x2 | |
20722 | + .long .Ldebug_abbrev0 | |
20723 | + .byte 0x8 | |
20724 | + .uleb128 0x1 | |
20725 | + .long .LASF2 | |
20726 | + .byte 0x1 | |
20727 | + .long .LASF3 | |
20728 | + .long .LASF4 | |
20729 | + .quad .Ltext0 | |
20730 | + .quad .Letext0 | |
20731 | + .long .Ldebug_line0 | |
20732 | + .uleb128 0x2 | |
20733 | + .byte 0x1 | |
20734 | + .string "foo" | |
20735 | + .byte 0x1 | |
20736 | + .byte 0x16 | |
20737 | + .byte 0x1 | |
20738 | + .quad .LFB2 | |
20739 | + .quad .LFE2 | |
20740 | + .long .LLST0 | |
20741 | + .long 0x83 | |
20742 | + .uleb128 0x3 | |
20743 | + .long .LASF5 | |
20744 | + .byte 0x1 | |
20745 | + .byte 0x15 | |
20746 | + .long 0x83 | |
20747 | + .byte 0x2 | |
20748 | + .byte 0x91 | |
20749 | + .sleb128 -52 | |
20750 | +.Ltag_typedef: | |
20751 | + .uleb128 0x4 | |
20752 | + .long .LASF6 | |
20753 | + .byte 0x1 | |
20754 | + .byte 0x17 | |
20755 | + .long .Ltag_array_type - .debug_info | |
20756 | + .uleb128 0x5 /* Abbrev Number: 5 (DW_TAG_variable) */ | |
20757 | + .long .LASF0 | |
20758 | + .byte 0x1 | |
20759 | + .byte 0x18 | |
20760 | +#if 1 | |
20761 | + .long .Ltag_typedef - .debug_info | |
20762 | +#else | |
20763 | + /* Debugging only: Skip the typedef indirection. */ | |
20764 | + .long .Ltag_array_type - .debug_info | |
20765 | +#endif | |
20766 | + /* DW_AT_location: DW_FORM_block1: start */ | |
20767 | + .byte 0x3 | |
20768 | + .byte 0x91 | |
20769 | + .sleb128 -32 | |
20770 | +#if 0 | |
20771 | + .byte 0x6 /* DW_OP_deref */ | |
20772 | +#else | |
20773 | + .byte 0x96 /* DW_OP_nop */ | |
20774 | +#endif | |
20775 | + /* DW_AT_location: DW_FORM_block1: end */ | |
20776 | + .uleb128 0x6 | |
20777 | + .string "i" | |
20778 | + .byte 0x1 | |
20779 | + .byte 0x19 | |
20780 | + .long 0x83 | |
20781 | + .byte 0x2 | |
20782 | + .byte 0x91 | |
20783 | + .sleb128 -20 | |
20784 | + .byte 0x0 | |
20785 | + .uleb128 0x7 | |
20786 | + .byte 0x4 | |
20787 | + .byte 0x5 | |
20788 | + .string "int" | |
20789 | +.Ltag_array_type: | |
20790 | + .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */ | |
20791 | + .long 0xa0 + (2f - 1f) /* DW_AT_type: DW_FORM_ref4 */ | |
20792 | + .long 0x9d + (2f - 1f) /* DW_AT_sibling: DW_FORM_ref4 */ | |
20793 | +1: /* DW_AT_data_location: DW_FORM_block1: start */ | |
20794 | + .byte 2f - 3f /* length */ | |
20795 | +3: | |
20796 | + .byte 0x97 /* DW_OP_push_object_address */ | |
20797 | + .byte 0x6 /* DW_OP_deref */ | |
20798 | +2: /* DW_AT_data_location: DW_FORM_block1: end */ | |
20799 | + .uleb128 0x9 | |
20800 | + .long 0x9d + (2b - 1b) /* DW_AT_type: DW_FORM_ref4 */ | |
20801 | + .byte 0x3 | |
20802 | + .byte 0x91 | |
20803 | + .sleb128 -40 | |
20804 | + .byte 0x6 | |
20805 | + .byte 0x0 | |
20806 | + .uleb128 0xa | |
20807 | + .byte 0x8 | |
20808 | + .byte 0x7 | |
20809 | + .uleb128 0xb | |
20810 | + .byte 0x1 | |
20811 | + .byte 0x6 | |
20812 | + .long .LASF1 | |
20813 | + .byte 0x0 | |
20814 | +.Ldebug_end: | |
20815 | + .section .debug_abbrev | |
20816 | + .uleb128 0x1 | |
20817 | + .uleb128 0x11 | |
20818 | + .byte 0x1 | |
20819 | + .uleb128 0x25 | |
20820 | + .uleb128 0xe | |
20821 | + .uleb128 0x13 | |
20822 | + .uleb128 0xb | |
20823 | + .uleb128 0x3 | |
20824 | + .uleb128 0xe | |
20825 | + .uleb128 0x1b | |
20826 | + .uleb128 0xe | |
20827 | + .uleb128 0x11 | |
20828 | + .uleb128 0x1 | |
20829 | + .uleb128 0x12 | |
20830 | + .uleb128 0x1 | |
20831 | + .uleb128 0x10 | |
20832 | + .uleb128 0x6 | |
20833 | + .byte 0x0 | |
20834 | + .byte 0x0 | |
20835 | + .uleb128 0x2 | |
20836 | + .uleb128 0x2e | |
20837 | + .byte 0x1 | |
20838 | + .uleb128 0x3f | |
20839 | + .uleb128 0xc | |
20840 | + .uleb128 0x3 | |
20841 | + .uleb128 0x8 | |
20842 | + .uleb128 0x3a | |
20843 | + .uleb128 0xb | |
20844 | + .uleb128 0x3b | |
20845 | + .uleb128 0xb | |
20846 | + .uleb128 0x27 | |
20847 | + .uleb128 0xc | |
20848 | + .uleb128 0x11 | |
20849 | + .uleb128 0x1 | |
20850 | + .uleb128 0x12 | |
20851 | + .uleb128 0x1 | |
20852 | + .uleb128 0x40 | |
20853 | + .uleb128 0x6 | |
20854 | + .uleb128 0x1 | |
20855 | + .uleb128 0x13 | |
20856 | + .byte 0x0 | |
20857 | + .byte 0x0 | |
20858 | + .uleb128 0x3 | |
20859 | + .uleb128 0x5 | |
20860 | + .byte 0x0 | |
20861 | + .uleb128 0x3 | |
20862 | + .uleb128 0xe | |
20863 | + .uleb128 0x3a | |
20864 | + .uleb128 0xb | |
20865 | + .uleb128 0x3b | |
20866 | + .uleb128 0xb | |
20867 | + .uleb128 0x49 | |
20868 | + .uleb128 0x13 | |
20869 | + .uleb128 0x2 | |
20870 | + .uleb128 0xa | |
20871 | + .byte 0x0 | |
20872 | + .byte 0x0 | |
20873 | + .uleb128 0x4 | |
20874 | + .uleb128 0x16 | |
20875 | + .byte 0x0 | |
20876 | + .uleb128 0x3 | |
20877 | + .uleb128 0xe | |
20878 | + .uleb128 0x3a | |
20879 | + .uleb128 0xb | |
20880 | + .uleb128 0x3b | |
20881 | + .uleb128 0xb | |
20882 | + .uleb128 0x49 | |
20883 | + .uleb128 0x13 | |
20884 | + .byte 0x0 | |
20885 | + .byte 0x0 | |
20886 | + .uleb128 0x5 | |
20887 | + .uleb128 0x34 | |
20888 | + .byte 0x0 | |
20889 | + .uleb128 0x3 | |
20890 | + .uleb128 0xe | |
20891 | + .uleb128 0x3a | |
20892 | + .uleb128 0xb | |
20893 | + .uleb128 0x3b | |
20894 | + .uleb128 0xb | |
20895 | + .uleb128 0x49 | |
20896 | + .uleb128 0x13 | |
20897 | + .uleb128 0x2 | |
20898 | + .uleb128 0xa | |
20899 | + .byte 0x0 | |
20900 | + .byte 0x0 | |
20901 | + .uleb128 0x6 | |
20902 | + .uleb128 0x34 | |
20903 | + .byte 0x0 | |
20904 | + .uleb128 0x3 | |
20905 | + .uleb128 0x8 | |
20906 | + .uleb128 0x3a | |
20907 | + .uleb128 0xb | |
20908 | + .uleb128 0x3b | |
20909 | + .uleb128 0xb | |
20910 | + .uleb128 0x49 | |
20911 | + .uleb128 0x13 | |
20912 | + .uleb128 0x2 | |
20913 | + .uleb128 0xa | |
20914 | + .byte 0x0 | |
20915 | + .byte 0x0 | |
20916 | + .uleb128 0x7 | |
20917 | + .uleb128 0x24 | |
20918 | + .byte 0x0 | |
20919 | + .uleb128 0xb | |
20920 | + .uleb128 0xb | |
20921 | + .uleb128 0x3e | |
20922 | + .uleb128 0xb | |
20923 | + .uleb128 0x3 | |
20924 | + .uleb128 0x8 | |
20925 | + .byte 0x0 | |
20926 | + .byte 0x0 | |
20927 | + .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */ | |
20928 | + .uleb128 0x1 | |
20929 | + .byte 0x1 | |
20930 | + .uleb128 0x49 /* DW_AT_type */ | |
20931 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
20932 | + .uleb128 0x1 /* DW_AT_sibling */ | |
20933 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
20934 | + .uleb128 0x50 /* DW_AT_data_location */ | |
20935 | + .uleb128 0xa /* DW_FORM_block1 */ | |
20936 | + .byte 0x0 | |
20937 | + .byte 0x0 | |
20938 | + .uleb128 0x9 | |
20939 | + .uleb128 0x21 | |
20940 | + .byte 0x0 | |
20941 | + .uleb128 0x49 /* DW_AT_type */ | |
20942 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
20943 | + .uleb128 0x2f | |
20944 | + .uleb128 0xa | |
20945 | + .byte 0x0 | |
20946 | + .byte 0x0 | |
20947 | + .uleb128 0xa | |
20948 | + .uleb128 0x24 | |
20949 | + .byte 0x0 | |
20950 | + .uleb128 0xb | |
20951 | + .uleb128 0xb | |
20952 | + .uleb128 0x3e | |
20953 | + .uleb128 0xb | |
20954 | + .byte 0x0 | |
20955 | + .byte 0x0 | |
20956 | + .uleb128 0xb | |
20957 | + .uleb128 0x24 | |
20958 | + .byte 0x0 | |
20959 | + .uleb128 0xb | |
20960 | + .uleb128 0xb | |
20961 | + .uleb128 0x3e | |
20962 | + .uleb128 0xb | |
20963 | + .uleb128 0x3 | |
20964 | + .uleb128 0xe | |
20965 | + .byte 0x0 | |
20966 | + .byte 0x0 | |
20967 | + .byte 0x0 | |
20968 | + .section .debug_pubnames,"",@progbits | |
20969 | + .long 0x16 | |
20970 | + .value 0x2 | |
20971 | + .long .Ldebug_info0 | |
20972 | + .long 0xa8 | |
20973 | + .long 0x2d | |
20974 | + .string "foo" | |
20975 | + .long 0x0 | |
20976 | + .section .debug_aranges,"",@progbits | |
20977 | + .long 0x2c | |
20978 | + .value 0x2 | |
20979 | + .long .Ldebug_info0 | |
20980 | + .byte 0x8 | |
20981 | + .byte 0x0 | |
20982 | + .value 0x0 | |
20983 | + .value 0x0 | |
20984 | + .quad .Ltext0 | |
20985 | + .quad .Letext0-.Ltext0 | |
20986 | + .quad 0x0 | |
20987 | + .quad 0x0 | |
20988 | + .section .debug_str,"MS",@progbits,1 | |
20989 | +.LASF0: | |
20990 | + .string "array" | |
20991 | +.LASF5: | |
20992 | + .string "size" | |
20993 | +.LASF3: | |
20994 | + .string "x86_64-vla-typedef.c" | |
20995 | +.LASF6: | |
20996 | + .string "array_t" | |
20997 | +.LASF1: | |
20998 | + .string "char" | |
20999 | +.LASF4: | |
21000 | + .string "gdb.arch" | |
21001 | +.LASF2: | |
21002 | + .string "GNU C 4.3.2 20081105 (Red Hat 4.3.2-7)" | |
21003 | + .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)" | |
21004 | + .section .note.GNU-stack,"",@progbits | |
21005 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c | |
21006 | new file mode 100644 | |
21007 | index 0000000..b809c4e | |
21008 | --- /dev/null | |
21009 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c | |
21010 | @@ -0,0 +1,43 @@ | |
21011 | +/* This testcase is part of GDB, the GNU debugger. | |
21012 | + | |
21013 | + Copyright 2008 Free Software Foundation, Inc. | |
21014 | + | |
21015 | + This program is free software; you can redistribute it and/or modify | |
21016 | + it under the terms of the GNU General Public License as published by | |
21017 | + the Free Software Foundation; either version 3 of the License, or | |
21018 | + (at your option) any later version. | |
21019 | + | |
21020 | + This program is distributed in the hope that it will be useful, | |
21021 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21022 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21023 | + GNU General Public License for more details. | |
21024 | + | |
21025 | + You should have received a copy of the GNU General Public License | |
21026 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
21027 | + | |
21028 | +#if 0 | |
21029 | + | |
21030 | +void | |
21031 | +foo (int size) | |
21032 | +{ | |
21033 | + typedef char array_t[size]; | |
21034 | + array_t array; | |
21035 | + int i; | |
21036 | + | |
21037 | + for (i = 0; i < size; i++) | |
21038 | + array[i] = i; | |
21039 | + | |
21040 | + array[0] = 0; /* break-here */ | |
21041 | +} | |
21042 | + | |
21043 | +#else | |
21044 | + | |
21045 | +int | |
21046 | +main (void) | |
21047 | +{ | |
21048 | + foo (26); | |
21049 | + foo (78); | |
21050 | + return 0; | |
21051 | +} | |
21052 | + | |
21053 | +#endif | |
21054 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp | |
21055 | new file mode 100644 | |
7566401a | 21056 | index 0000000..b05411e |
3a58abaf AM |
21057 | --- /dev/null |
21058 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp | |
21059 | @@ -0,0 +1,64 @@ | |
21060 | +# Copyright 2009 Free Software Foundation, Inc. | |
21061 | + | |
21062 | +# This program is free software; you can redistribute it and/or modify | |
21063 | +# it under the terms of the GNU General Public License as published by | |
21064 | +# the Free Software Foundation; either version 3 of the License, or | |
21065 | +# (at your option) any later version. | |
21066 | +# | |
21067 | +# This program is distributed in the hope that it will be useful, | |
21068 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21069 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21070 | +# GNU General Public License for more details. | |
21071 | +# | |
21072 | +# You should have received a copy of the GNU General Public License | |
21073 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21074 | + | |
21075 | +# Test DW_AT_data_location accessed through DW_TAG_typedef intermediate. | |
21076 | + | |
21077 | +if ![istarget "x86_64-*-*"] then { | |
21078 | + verbose "Skipping over gdb.arch/x86_64-vla-typedef.exp test made only for x86_64." | |
21079 | + return | |
21080 | +} | |
21081 | + | |
21082 | +set testfile x86_64-vla-typedef | |
21083 | +set srcasmfile ${testfile}-foo.S | |
21084 | +set srcfile ${testfile}.c | |
21085 | +set binfile ${objdir}/${subdir}/${testfile} | |
21086 | +set binobjfile ${objdir}/${subdir}/${testfile}-foo.o | |
21087 | +if { [gdb_compile "${srcdir}/${subdir}/${srcasmfile}" "${binobjfile}" object {}] != "" } { | |
21088 | + untested "Couldn't compile test program" | |
21089 | + return -1 | |
21090 | +} | |
21091 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${binobjfile}" "${binfile}" executable {debug}] != "" } { | |
21092 | + untested "Couldn't compile test program" | |
21093 | + return -1 | |
21094 | +} | |
21095 | + | |
21096 | +gdb_exit | |
21097 | +gdb_start | |
21098 | +gdb_reinitialize_dir $srcdir/$subdir | |
21099 | +gdb_load ${binfile} | |
21100 | + | |
21101 | +if ![runto_main] { | |
21102 | + untested x86_64-vla-typedef | |
21103 | + return -1 | |
21104 | +} | |
21105 | + | |
21106 | +gdb_breakpoint "break_here" | |
21107 | + | |
21108 | +gdb_continue_to_breakpoint "break_here" | |
21109 | + | |
21110 | +gdb_test "whatis array" "type = array_t" "first: whatis array" | |
21111 | + | |
21112 | +gdb_test "ptype array" "type = char \\\[26\\\]" "first: ptype array" | |
21113 | + | |
7566401a ER |
21114 | +gdb_test "p array\[1\]" "\\$\[0-9\] = 1 '\\\\001'" |
21115 | +gdb_test "p array\[2\]" "\\$\[0-9\] = 2 '\\\\002'" | |
21116 | +gdb_test "p array\[3\]" "\\$\[0-9\] = 3 '\\\\003'" | |
21117 | +gdb_test "p array\[4\]" "\\$\[0-9\] = 4 '\\\\004'" | |
3a58abaf AM |
21118 | + |
21119 | +gdb_continue_to_breakpoint "break_here" | |
21120 | + | |
21121 | +gdb_test "whatis array" "type = array_t" "second: whatis array" | |
21122 | + | |
21123 | +gdb_test "ptype array" "type = char \\\[78\\\]" "second: ptype array" | |
7566401a ER |
21124 | diff --git a/gdb/testsuite/gdb.base/arrayidx.c b/gdb/testsuite/gdb.base/arrayidx.c |
21125 | index 98d4d35..f98a656 100644 | |
21126 | --- a/gdb/testsuite/gdb.base/arrayidx.c | |
21127 | +++ b/gdb/testsuite/gdb.base/arrayidx.c | |
21128 | @@ -17,6 +17,13 @@ | |
3a58abaf | 21129 | |
7566401a | 21130 | int array[] = {1, 2, 3, 4}; |
3a58abaf | 21131 | |
7566401a ER |
21132 | +#ifdef __GNUC__ |
21133 | +struct | |
21134 | + { | |
21135 | + int a[0]; | |
21136 | + } unbound; | |
21137 | +#endif | |
3a58abaf | 21138 | + |
7566401a ER |
21139 | int |
21140 | main (void) | |
3a58abaf | 21141 | { |
7566401a ER |
21142 | diff --git a/gdb/testsuite/gdb.base/arrayidx.exp b/gdb/testsuite/gdb.base/arrayidx.exp |
21143 | index 71ce4aa..af0e5f8 100644 | |
21144 | --- a/gdb/testsuite/gdb.base/arrayidx.exp | |
21145 | +++ b/gdb/testsuite/gdb.base/arrayidx.exp | |
21146 | @@ -59,4 +59,12 @@ gdb_test "print array" \ | |
21147 | "\\{\\\[0\\\] = 1, \\\[1\\\] = 2, \\\[2\\\] = 3, \\\[3\\\] = 4\\}" \ | |
21148 | "Print array with array-indexes on" | |
3a58abaf | 21149 | |
3a58abaf | 21150 | - |
7566401a ER |
21151 | +set test "p unbound.a == &unbound.a\[0\]" |
21152 | +gdb_test_multiple $test $test { | |
21153 | + -re " = 1\r\n$gdb_prompt $" { | |
21154 | + pass $test | |
3a58abaf | 21155 | + } |
7566401a ER |
21156 | + -re "No symbol \"unbound\" in current context.\r\n$gdb_prompt $" { |
21157 | + unsupported "$test (no GCC)" | |
21158 | + } | |
21159 | +} | |
3a58abaf | 21160 | diff --git a/gdb/testsuite/gdb.base/help.exp b/gdb/testsuite/gdb.base/help.exp |
7566401a | 21161 | index d76cc36..496ff18 100644 |
3a58abaf AM |
21162 | --- a/gdb/testsuite/gdb.base/help.exp |
21163 | +++ b/gdb/testsuite/gdb.base/help.exp | |
7566401a | 21164 | @@ -606,7 +606,7 @@ gdb_test "help stepi" "Step one instruction exactly\.\[\r\n\]+Argument N means d |
3a58abaf AM |
21165 | gdb_test "help signal" "Continue program giving it signal.*" "help signal" |
21166 | # test help source | |
21167 | # vxgdb reads .vxgdbinit | |
21168 | -gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Optional -v switch \\(before the filename\\) causes each command in\[\r\n\]+FILE to be echoed as it is executed\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when GDB is started\." "help source" | |
21169 | +gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Optional -v switch \\(before the filename\\) causes each command in\[\r\n\]+FILE to be echoed as it is executed\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when GDB is started\.\[\r\n\]+Optional -p switch \\(before the filename\\) causes FILE to be evaluated\[\r\n\]+as Python code\." "help source" | |
21170 | # test help stack | |
21171 | test_class_help "stack" { | |
21172 | "Examining the stack\..*\[\r\n\]+" | |
21173 | diff --git a/gdb/testsuite/gdb.base/lineno-makeup-func.c b/gdb/testsuite/gdb.base/lineno-makeup-func.c | |
21174 | new file mode 100644 | |
21175 | index 0000000..1a0220e | |
21176 | --- /dev/null | |
21177 | +++ b/gdb/testsuite/gdb.base/lineno-makeup-func.c | |
21178 | @@ -0,0 +1,21 @@ | |
21179 | +/* This testcase is part of GDB, the GNU debugger. | |
21180 | + | |
21181 | + Copyright 2009 Free Software Foundation, Inc. | |
21182 | + | |
21183 | + This program is free software; you can redistribute it and/or modify | |
21184 | + it under the terms of the GNU General Public License as published by | |
21185 | + the Free Software Foundation; either version 3 of the License, or | |
21186 | + (at your option) any later version. | |
21187 | + | |
21188 | + This program is distributed in the hope that it will be useful, | |
21189 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21190 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21191 | + GNU General Public License for more details. | |
21192 | + | |
21193 | + You should have received a copy of the GNU General Public License | |
21194 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
21195 | + | |
21196 | +void | |
21197 | +func (void) | |
21198 | +{ | |
21199 | +} | |
21200 | diff --git a/gdb/testsuite/gdb.base/lineno-makeup.c b/gdb/testsuite/gdb.base/lineno-makeup.c | |
21201 | new file mode 100644 | |
21202 | index 0000000..bb20e98 | |
21203 | --- /dev/null | |
21204 | +++ b/gdb/testsuite/gdb.base/lineno-makeup.c | |
21205 | @@ -0,0 +1,35 @@ | |
21206 | +/* This testcase is part of GDB, the GNU debugger. | |
21207 | + | |
21208 | + Copyright 2009 Free Software Foundation, Inc. | |
21209 | + | |
21210 | + This program is free software; you can redistribute it and/or modify | |
21211 | + it under the terms of the GNU General Public License as published by | |
21212 | + the Free Software Foundation; either version 3 of the License, or | |
21213 | + (at your option) any later version. | |
21214 | + | |
21215 | + This program is distributed in the hope that it will be useful, | |
21216 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21217 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21218 | + GNU General Public License for more details. | |
21219 | + | |
21220 | + You should have received a copy of the GNU General Public License | |
21221 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
21222 | + | |
21223 | +/* DW_AT_low_pc-DW_AT_high_pc should cover the function without line number | |
21224 | + information (.debug_line) so we cannot use an external object file. | |
21225 | + | |
21226 | + It must not be just a label as it would alias on the next function even for | |
21227 | + correct GDB. Therefore some stub data must be placed there. | |
21228 | + | |
21229 | + We need to provide a real stub function body as at least s390 | |
21230 | + (s390_analyze_prologue) would skip the whole body till reaching `main'. */ | |
21231 | + | |
21232 | +extern void func (void); | |
21233 | +asm ("func: .incbin \"gdb.base/lineno-makeup-func.bin\""); | |
21234 | + | |
21235 | +int | |
21236 | +main (void) | |
21237 | +{ | |
21238 | + func (); | |
21239 | + return 0; | |
21240 | +} | |
21241 | diff --git a/gdb/testsuite/gdb.base/lineno-makeup.exp b/gdb/testsuite/gdb.base/lineno-makeup.exp | |
21242 | new file mode 100644 | |
21243 | index 0000000..0c75b84 | |
21244 | --- /dev/null | |
21245 | +++ b/gdb/testsuite/gdb.base/lineno-makeup.exp | |
21246 | @@ -0,0 +1,78 @@ | |
21247 | +# Copyright 2009 Free Software Foundation, Inc. | |
21248 | + | |
21249 | +# This program is free software; you can redistribute it and/or modify | |
21250 | +# it under the terms of the GNU General Public License as published by | |
21251 | +# the Free Software Foundation; either version 3 of the License, or | |
21252 | +# (at your option) any later version. | |
21253 | +# | |
21254 | +# This program is distributed in the hope that it will be useful, | |
21255 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21256 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21257 | +# GNU General Public License for more details. | |
21258 | +# | |
21259 | +# You should have received a copy of the GNU General Public License | |
21260 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21261 | + | |
21262 | +set testfile "lineno-makeup" | |
21263 | +set srcfuncfile ${testfile}-func.c | |
21264 | +set srcfile ${testfile}.c | |
21265 | +set objfuncfile ${objdir}/${subdir}/${testfile}-func.o | |
21266 | +set binfuncfile ${objdir}/${subdir}/${testfile}-func.bin | |
21267 | +set binfile ${objdir}/${subdir}/${testfile} | |
21268 | + | |
21269 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfuncfile}" "${objfuncfile}" object {}] != "" } { | |
21270 | + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." | |
21271 | +} | |
21272 | + | |
21273 | +set objcopy [catch "exec objcopy -O binary --only-section .text ${objfuncfile} ${binfuncfile}" output] | |
21274 | +verbose -log "objcopy=$objcopy: $output" | |
21275 | +if { $objcopy != 0 } { | |
21276 | + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." | |
21277 | +} | |
21278 | +set binfuncfilesize [file size $binfuncfile] | |
21279 | +verbose -log "file size $binfuncfile = $binfuncfilesize" | |
21280 | + | |
21281 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
21282 | + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." | |
21283 | +} | |
21284 | + | |
21285 | +gdb_exit | |
21286 | +gdb_start | |
21287 | +gdb_reinitialize_dir $srcdir/$subdir | |
21288 | +gdb_load ${binfile} | |
21289 | + | |
21290 | +set b_addr "" | |
21291 | +set test "break func" | |
21292 | +gdb_test_multiple $test $test { | |
21293 | + -re "Breakpoint \[0-9\]+ at (0x\[0-9a-f\]+)\r\n$gdb_prompt $" { | |
21294 | + set b_addr $expect_out(1,string) | |
21295 | + pass $test | |
21296 | + } | |
21297 | + -re "Breakpoint \[0-9\]+ at (0x\[0-9a-f\]+): .*\r\n$gdb_prompt $" { | |
21298 | + set b_addr $expect_out(1,string) | |
21299 | + fail $test | |
21300 | + } | |
21301 | +} | |
21302 | +verbose -log "b_addr=<$b_addr>" | |
21303 | + | |
21304 | +set p_addr "" | |
21305 | +set test "print func" | |
21306 | +gdb_test_multiple $test $test { | |
21307 | + -re "\\$\[0-9\]+ = {<text variable, no debug info>} (0x\[0-9a-f\]+) <func>\r\n$gdb_prompt $" { | |
21308 | + set p_addr $expect_out(1,string) | |
21309 | + pass $test | |
21310 | + } | |
21311 | +} | |
21312 | +verbose -log "p_addr=<$p_addr>" | |
21313 | + | |
21314 | +set test "break address belongs to func" | |
21315 | +if {$b_addr == $p_addr} { | |
21316 | + pass "$test (exact match)" | |
21317 | +} else { | |
21318 | + set skip [expr $b_addr - $p_addr] | |
21319 | + if {$skip > 0 && $skip < $binfuncfilesize} { | |
21320 | + pass "$test (prologue skip by $skip bytes)" | |
21321 | + } else { | |
21322 | + fail $test | |
21323 | + } | |
21324 | +} | |
3a58abaf | 21325 | diff --git a/gdb/testsuite/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp |
7566401a | 21326 | index 55c4d31..df25d3c 100644 |
3a58abaf AM |
21327 | --- a/gdb/testsuite/gdb.base/macscp.exp |
21328 | +++ b/gdb/testsuite/gdb.base/macscp.exp | |
7566401a | 21329 | @@ -33,6 +33,14 @@ if [test_compiler_info gcc*] { |
3a58abaf AM |
21330 | lappend options additional_flags=-g3 |
21331 | } | |
21332 | ||
21333 | +# Workaround ccache making lineno non-zero for command-line definitions. | |
21334 | +if {[find_gcc] == "gcc" && [file executable "/usr/bin/gcc"]} { | |
21335 | + set result [catch "exec which gcc" output] | |
21336 | + if {$result == 0 && [string first "/ccache/" $output] >= -1} { | |
7566401a | 21337 | + lappend options "compiler=/usr/bin/gcc" |
3a58abaf AM |
21338 | + } |
21339 | +} | |
21340 | + | |
21341 | # Generate the intermediate object file. This is required by Darwin to | |
21342 | # have access to the .debug_macinfo section. | |
21343 | if {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${objfile}" \ | |
7566401a ER |
21344 | diff --git a/gdb/testsuite/gdb.base/radix.exp b/gdb/testsuite/gdb.base/radix.exp |
21345 | index 750fd23..dfdb929 100644 | |
21346 | --- a/gdb/testsuite/gdb.base/radix.exp | |
21347 | +++ b/gdb/testsuite/gdb.base/radix.exp | |
21348 | @@ -162,13 +162,6 @@ gdb_test "set radix" \ | |
21349 | "Input and output radices now set to decimal 10, hex a, octal 12\." \ | |
21350 | "Reset radices" | |
21351 | ||
21352 | -gdb_test "set input-radix 0" \ | |
21353 | - "Nonsense input radix ``decimal 0''; input radix unchanged\\." \ | |
21354 | - "Reject input-radix 0" | |
21355 | -gdb_test "show input-radix" \ | |
21356 | - "Default input radix for entering numbers is 10\\." \ | |
21357 | - "Input radix unchanged after rejecting 0" | |
21358 | - | |
21359 | gdb_test "set input-radix 1" \ | |
21360 | "Nonsense input radix ``decimal 1''; input radix unchanged\\." \ | |
21361 | "Reject input-radix 1" | |
3a58abaf AM |
21362 | diff --git a/gdb/testsuite/gdb.base/valgrind-attach.c b/gdb/testsuite/gdb.base/valgrind-attach.c |
21363 | new file mode 100644 | |
21364 | index 0000000..84b57db | |
21365 | --- /dev/null | |
21366 | +++ b/gdb/testsuite/gdb.base/valgrind-attach.c | |
21367 | @@ -0,0 +1,28 @@ | |
21368 | +/* This testcase is part of GDB, the GNU debugger. | |
21369 | + | |
21370 | + Copyright 2009 Free Software Foundation, Inc. | |
21371 | + | |
21372 | + This program is free software; you can redistribute it and/or modify | |
21373 | + it under the terms of the GNU General Public License as published by | |
21374 | + the Free Software Foundation; either version 3 of the License, or | |
21375 | + (at your option) any later version. | |
21376 | + | |
21377 | + This program is distributed in the hope that it will be useful, | |
21378 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21379 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21380 | + GNU General Public License for more details. | |
21381 | + | |
21382 | + You should have received a copy of the GNU General Public License | |
21383 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
21384 | + | |
21385 | +#include <stdlib.h> | |
21386 | + | |
21387 | +int | |
21388 | +main (void) | |
21389 | +{ | |
21390 | + int *a = malloc (1); | |
21391 | + | |
21392 | + a[10] = 0; /* crash-here */ | |
21393 | + | |
21394 | + return 0; | |
21395 | +} | |
21396 | diff --git a/gdb/testsuite/gdb.base/valgrind-attach.exp b/gdb/testsuite/gdb.base/valgrind-attach.exp | |
21397 | new file mode 100644 | |
21398 | index 0000000..1f9b26e | |
21399 | --- /dev/null | |
21400 | +++ b/gdb/testsuite/gdb.base/valgrind-attach.exp | |
21401 | @@ -0,0 +1,94 @@ | |
21402 | +# Copyright 2009 Free Software Foundation, Inc. | |
21403 | + | |
21404 | +# This program is free software; you can redistribute it and/or modify | |
21405 | +# it under the terms of the GNU General Public License as published by | |
21406 | +# the Free Software Foundation; either version 3 of the License, or | |
21407 | +# (at your option) any later version. | |
21408 | +# | |
21409 | +# This program is distributed in the hope that it will be useful, | |
21410 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21411 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21412 | +# GNU General Public License for more details. | |
21413 | +# | |
21414 | +# You should have received a copy of the GNU General Public License | |
21415 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21416 | + | |
21417 | +set testfile valgrind-attach | |
21418 | +set shfile ${testfile}.sh | |
21419 | +set srcfile ${testfile}.c | |
21420 | +set binfile ${objdir}/${subdir}/${testfile} | |
21421 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
21422 | + untested "Couldn't compile test program" | |
21423 | + return -1 | |
21424 | +} | |
21425 | + | |
21426 | +gdb_exit | |
21427 | +gdb_stop_suppressing_tests; | |
21428 | + | |
21429 | +set VALGRIND "valgrind" | |
21430 | + | |
21431 | +# Syntax for ${shfile} is: <binfile> <valgrind> <db-command-arguments> | |
21432 | +set VALGRIND_SPAWN "sh ${srcdir}/${subdir}/${shfile} $binfile $VALGRIND $GDB $INTERNAL_GDBFLAGS $GDBFLAGS [host_info gdb_opts]" | |
21433 | + | |
21434 | +set test "spawn valgrind" | |
21435 | +verbose "Spawning $VALGRIND_SPAWN" | |
21436 | + | |
21437 | +if [info exists gdb_spawn_id] { | |
21438 | + fail $test | |
21439 | + return -1 | |
21440 | +} | |
21441 | + | |
21442 | +if ![is_remote host] { | |
21443 | + if { [which $VALGRIND] == 0 } then { | |
21444 | + untested "Couldn't find $VALGRIND" | |
21445 | + return -1 | |
21446 | + } | |
21447 | +} | |
21448 | +set res [remote_spawn host "$VALGRIND_SPAWN"] | |
21449 | +if { $res < 0 || $res == "" } { | |
21450 | + perror "Spawning $VALGRIND_SPAWN failed." | |
21451 | + return -1 | |
21452 | +} | |
21453 | +set gdb_spawn_id -1; | |
21454 | + | |
21455 | +gdb_expect { | |
21456 | + -re "---- Attach to debugger \\? --- \\\[Return/N/n/Y/y/C/c\\\] ---- $" { | |
21457 | + pass $test | |
21458 | + } | |
21459 | + eof { | |
21460 | + perror "(eof) $VALGRIND never initialized" | |
21461 | + remote_close host | |
21462 | + return -1 | |
21463 | + } | |
21464 | + timeout { | |
21465 | + perror "(timeout) $VALGRIND never initialized" | |
21466 | + remote_close host | |
21467 | + return -1 | |
21468 | + } | |
21469 | +} | |
21470 | +send_gdb "y\n" | |
21471 | + | |
21472 | +set test "spawn gdb" | |
21473 | +set test2 "crash line caught" | |
21474 | +gdb_expect { | |
21475 | + -re "starting debugger with cmd:.* in main .* crash-here .*\[\r\n\]$gdb_prompt $" { | |
21476 | + pass $test | |
21477 | + pass $test2 | |
21478 | + } | |
21479 | + -re "starting debugger with cmd:.*\[\r\n\]$gdb_prompt $" { | |
21480 | + pass $test | |
21481 | + fail $test2 | |
21482 | + } | |
21483 | + eof { | |
21484 | + perror "(eof) $GDB never initialized" | |
21485 | + remote_close host | |
21486 | + return -1 | |
21487 | + } | |
21488 | + timeout { | |
21489 | + perror "(timeout) $GDB never initialized" | |
21490 | + remote_close host | |
21491 | + return -1 | |
21492 | + } | |
21493 | +} | |
21494 | + | |
21495 | +remote_close host | |
21496 | diff --git a/gdb/testsuite/gdb.base/valgrind-attach.sh b/gdb/testsuite/gdb.base/valgrind-attach.sh | |
21497 | new file mode 100755 | |
21498 | index 0000000..f02c6f7 | |
21499 | --- /dev/null | |
21500 | +++ b/gdb/testsuite/gdb.base/valgrind-attach.sh | |
21501 | @@ -0,0 +1,20 @@ | |
21502 | +#! /bin/sh | |
21503 | + | |
21504 | +# Copyright 2009 Free Software Foundation, Inc. | |
21505 | + | |
21506 | +# This program is free software; you can redistribute it and/or modify | |
21507 | +# it under the terms of the GNU General Public License as published by | |
21508 | +# the Free Software Foundation; either version 3 of the License, or | |
21509 | +# (at your option) any later version. | |
21510 | +# | |
21511 | +# This program is distributed in the hope that it will be useful, | |
21512 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21513 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21514 | +# GNU General Public License for more details. | |
21515 | +# | |
21516 | +# You should have received a copy of the GNU General Public License | |
21517 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21518 | + | |
21519 | +BINFILE="$1"; shift | |
21520 | +VALGRIND="$1"; shift | |
21521 | +"$VALGRIND" --db-attach=yes --db-command="$* %f %p" "$BINFILE" | |
21522 | diff --git a/gdb/testsuite/gdb.base/vla-overflow.c b/gdb/testsuite/gdb.base/vla-overflow.c | |
21523 | new file mode 100644 | |
21524 | index 0000000..c5d5ee0 | |
21525 | --- /dev/null | |
21526 | +++ b/gdb/testsuite/gdb.base/vla-overflow.c | |
21527 | @@ -0,0 +1,30 @@ | |
21528 | +/* This testcase is part of GDB, the GNU debugger. | |
21529 | + | |
21530 | + Copyright 2008 Free Software Foundation, Inc. | |
21531 | + | |
21532 | + This program is free software; you can redistribute it and/or modify | |
21533 | + it under the terms of the GNU General Public License as published by | |
21534 | + the Free Software Foundation; either version 3 of the License, or | |
21535 | + (at your option) any later version. | |
21536 | + | |
21537 | + This program is distributed in the hope that it will be useful, | |
21538 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21539 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21540 | + GNU General Public License for more details. | |
21541 | + | |
21542 | + You should have received a copy of the GNU General Public License | |
21543 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
21544 | + | |
21545 | +#include <stdlib.h> | |
21546 | + | |
21547 | +int | |
21548 | +main (int argc, char **argv) | |
21549 | +{ | |
21550 | + int array[argc]; | |
21551 | + | |
21552 | + array[0] = array[0]; | |
21553 | + | |
21554 | + abort (); | |
21555 | + | |
21556 | + return 0; | |
21557 | +} | |
21558 | diff --git a/gdb/testsuite/gdb.base/vla-overflow.exp b/gdb/testsuite/gdb.base/vla-overflow.exp | |
21559 | new file mode 100644 | |
21560 | index 0000000..7203a48 | |
21561 | --- /dev/null | |
21562 | +++ b/gdb/testsuite/gdb.base/vla-overflow.exp | |
21563 | @@ -0,0 +1,108 @@ | |
21564 | +# Copyright 2008 Free Software Foundation, Inc. | |
21565 | + | |
21566 | +# This program is free software; you can redistribute it and/or modify | |
21567 | +# it under the terms of the GNU General Public License as published by | |
21568 | +# the Free Software Foundation; either version 3 of the License, or | |
21569 | +# (at your option) any later version. | |
21570 | +# | |
21571 | +# This program is distributed in the hope that it will be useful, | |
21572 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21573 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21574 | +# GNU General Public License for more details. | |
21575 | +# | |
21576 | +# You should have received a copy of the GNU General Public License | |
21577 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21578 | + | |
21579 | +# We could crash in: | |
21580 | +# #0 block_linkage_function (bl=0x0) at ../../gdb/block.c:69 | |
21581 | +# #1 in dwarf_block_get_frame_base (...) at ../../gdb/dwarf2block.c:97 | |
21582 | +# 97 framefunc = block_linkage_function (get_frame_block (frame, NULL)); | |
21583 | +# #2 in execute_stack_op (...) at ../../gdb/dwarf2expr.c:496 | |
21584 | +# #3 in dwarf_block_exec_core () at ../../gdb/dwarf2block.c:156 | |
21585 | +# #4 dwarf_block_exec (...) at ../../gdb/dwarf2block.c:206 | |
21586 | +# #5 in range_type_count_bound_internal (...) at ../../gdb/gdbtypes.c:1430 | |
21587 | +# #6 in create_array_type (...) at ../../gdb/gdbtypes.c:840 | |
21588 | +# ... | |
21589 | +# #21 in psymtab_to_symtab (...) at ../../gdb/symfile.c:292 | |
21590 | +# ... | |
21591 | +# #29 in backtrace_command_1 () at ../../gdb/stack.c:1273 | |
21592 | + | |
21593 | +set testfile vla-overflow | |
21594 | +set shfile ${objdir}/${subdir}/${testfile}-gdb.sh | |
21595 | +set srcfile ${testfile}.c | |
21596 | +set binfile ${objdir}/${subdir}/${testfile} | |
21597 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
21598 | + untested "Couldn't compile test program" | |
21599 | + return -1 | |
21600 | +} | |
21601 | + | |
21602 | +set f [open "|getconf PAGESIZE" "r"] | |
21603 | +gets $f pagesize | |
21604 | +close $f | |
21605 | + | |
21606 | +gdb_exit | |
21607 | +gdb_start | |
21608 | +gdb_reinitialize_dir $srcdir/$subdir | |
21609 | +gdb_load ${binfile} | |
21610 | + | |
21611 | +set pid_of_gdb [exp_pid -i [board_info host fileid]] | |
21612 | + | |
21613 | +if { [runto_main] < 0 } { | |
21614 | + untested vla-overflow | |
21615 | + return -1 | |
21616 | +} | |
21617 | + | |
21618 | +# Get the GDB memory size when we stay at main. | |
21619 | + | |
21620 | +proc memory_v_pages_get {} { | |
21621 | + global pid_of_gdb pagesize | |
21622 | + set fd [open "/proc/$pid_of_gdb/statm"] | |
21623 | + gets $fd line | |
21624 | + close $fd | |
21625 | + # number of pages of virtual memory | |
21626 | + scan $line "%d" drs | |
21627 | + return $drs | |
21628 | +} | |
21629 | + | |
21630 | +set pages_found [memory_v_pages_get] | |
21631 | + | |
21632 | +set mb_reserve 10 | |
21633 | +verbose -log "pages_found = $pages_found, mb_reserve = $mb_reserve" | |
21634 | +set kb_found [expr $pages_found * $pagesize / 1024] | |
21635 | +set kb_permit [expr $kb_found + 1 * 1024 + $mb_reserve * 1024] | |
21636 | +verbose -log "kb_found = $kb_found, kb_permit = $kb_permit" | |
21637 | + | |
21638 | +# Create the ulimit wrapper. | |
21639 | +set f [open $shfile "w"] | |
21640 | +puts $f "#! /bin/sh" | |
21641 | +puts $f "ulimit -v $kb_permit" | |
21642 | +puts $f "exec $GDB \"\$@\"" | |
21643 | +close $f | |
21644 | +remote_exec host "chmod +x $shfile" | |
21645 | + | |
21646 | +gdb_exit | |
21647 | +set GDBold $GDB | |
21648 | +set GDB "$shfile" | |
21649 | +gdb_start | |
21650 | +set GDB $GDBold | |
21651 | + | |
21652 | +gdb_reinitialize_dir $srcdir/$subdir | |
21653 | +gdb_load ${binfile} | |
21654 | + | |
21655 | +set pid_of_gdb [exp_pid -i [board_info host fileid]] | |
21656 | + | |
21657 | +# Check the size again after the second run. | |
21658 | +# We must not stop in main as it would cache `array' and never crash later. | |
21659 | + | |
21660 | +gdb_run_cmd | |
21661 | + | |
21662 | +verbose -log "kb_found before abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" | |
21663 | + | |
21664 | +gdb_test "" "Program received signal SIGABRT, Aborted..*" "Enter abort()" | |
21665 | + | |
21666 | +verbose -log "kb_found in abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" | |
21667 | + | |
21668 | +# `abort' can get expressed as `*__GI_abort'. | |
21669 | +gdb_test "bt" "in \[^ \]*abort \\(.* in main \\(.*" "Backtrace after abort()" | |
21670 | + | |
21671 | +verbose -log "kb_found in bt after abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" | |
21672 | diff --git a/gdb/testsuite/gdb.base/vla.c b/gdb/testsuite/gdb.base/vla.c | |
21673 | new file mode 100644 | |
21674 | index 0000000..e1f3ed1 | |
21675 | --- /dev/null | |
21676 | +++ b/gdb/testsuite/gdb.base/vla.c | |
21677 | @@ -0,0 +1,55 @@ | |
21678 | +/* This testcase is part of GDB, the GNU debugger. | |
21679 | + | |
21680 | + Copyright 2008 Free Software Foundation, Inc. | |
21681 | + | |
21682 | + This program is free software; you can redistribute it and/or modify | |
21683 | + it under the terms of the GNU General Public License as published by | |
21684 | + the Free Software Foundation; either version 3 of the License, or | |
21685 | + (at your option) any later version. | |
21686 | + | |
21687 | + This program is distributed in the hope that it will be useful, | |
21688 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21689 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21690 | + GNU General Public License for more details. | |
21691 | + | |
21692 | + You should have received a copy of the GNU General Public License | |
21693 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
21694 | + | |
21695 | +#include <string.h> | |
21696 | + | |
21697 | +void | |
21698 | +marker (void) | |
21699 | +{ | |
21700 | +} | |
21701 | + | |
21702 | +void | |
21703 | +bar (char *a, char *b, char *c, int size) | |
21704 | +{ | |
21705 | + memset (a, '1', size); | |
21706 | + memset (b, '2', size); | |
21707 | + memset (c, '3', 48); | |
21708 | +} | |
21709 | + | |
21710 | +void | |
21711 | +foo (int size) | |
21712 | +{ | |
21713 | + char temp1[size]; | |
21714 | + char temp3[48]; | |
21715 | + | |
21716 | + temp1[size - 1] = '\0'; | |
21717 | + { | |
21718 | + char temp2[size]; | |
21719 | + | |
21720 | + bar (temp1, temp2, temp3, size); | |
21721 | + | |
21722 | + marker (); /* break-here */ | |
21723 | + } | |
21724 | +} | |
21725 | + | |
21726 | +int | |
21727 | +main (void) | |
21728 | +{ | |
21729 | + foo (26); | |
21730 | + foo (78); | |
21731 | + return 0; | |
21732 | +} | |
21733 | diff --git a/gdb/testsuite/gdb.base/vla.exp b/gdb/testsuite/gdb.base/vla.exp | |
21734 | new file mode 100644 | |
21735 | index 0000000..5da7378 | |
21736 | --- /dev/null | |
21737 | +++ b/gdb/testsuite/gdb.base/vla.exp | |
21738 | @@ -0,0 +1,62 @@ | |
21739 | +# Copyright 2008 Free Software Foundation, Inc. | |
21740 | + | |
21741 | +# This program is free software; you can redistribute it and/or modify | |
21742 | +# it under the terms of the GNU General Public License as published by | |
21743 | +# the Free Software Foundation; either version 3 of the License, or | |
21744 | +# (at your option) any later version. | |
21745 | +# | |
21746 | +# This program is distributed in the hope that it will be useful, | |
21747 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21748 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21749 | +# GNU General Public License for more details. | |
21750 | +# | |
21751 | +# You should have received a copy of the GNU General Public License | |
21752 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21753 | + | |
21754 | +set testfile vla | |
21755 | +set srcfile ${testfile}.c | |
21756 | +set binfile ${objdir}/${subdir}/${testfile} | |
21757 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
21758 | + untested "Couldn't compile test program" | |
21759 | + return -1 | |
21760 | +} | |
21761 | + | |
21762 | +gdb_exit | |
21763 | +gdb_start | |
21764 | +gdb_reinitialize_dir $srcdir/$subdir | |
21765 | +gdb_load ${binfile} | |
21766 | + | |
21767 | +if ![runto_main] { | |
21768 | + untested vla | |
21769 | + return -1 | |
21770 | +} | |
21771 | + | |
21772 | +gdb_breakpoint [gdb_get_line_number "break-here"] | |
21773 | + | |
21774 | +gdb_continue_to_breakpoint "break-here" | |
21775 | + | |
21776 | +gdb_test "whatis temp1" "type = char \\\[variable\\\]" "first: whatis temp1" | |
21777 | +gdb_test "whatis temp2" "type = char \\\[variable\\\]" "first: whatis temp2" | |
21778 | +gdb_test "whatis temp3" "type = char \\\[48\\\]" "first: whatis temp3" | |
21779 | + | |
21780 | +gdb_test "ptype temp1" "type = char \\\[26\\\]" "first: ptype temp1" | |
21781 | +gdb_test "ptype temp2" "type = char \\\[26\\\]" "first: ptype temp2" | |
21782 | +gdb_test "ptype temp3" "type = char \\\[48\\\]" "first: ptype temp3" | |
21783 | + | |
21784 | +gdb_test "p temp1" " = '1' <repeats 26 times>" "first: print temp1" | |
21785 | +gdb_test "p temp2" " = '2' <repeats 26 times>" "first: print temp2" | |
21786 | +gdb_test "p temp3" " = '3' <repeats 48 times>" "first: print temp3" | |
21787 | + | |
21788 | +gdb_continue_to_breakpoint "break-here" | |
21789 | + | |
21790 | +gdb_test "whatis temp1" "type = char \\\[variable\\\]" "second: whatis temp1" | |
21791 | +gdb_test "whatis temp2" "type = char \\\[variable\\\]" "second: whatis temp2" | |
21792 | +gdb_test "whatis temp3" "type = char \\\[48\\\]" "second: whatis temp3" | |
21793 | + | |
21794 | +gdb_test "ptype temp1" "type = char \\\[78\\\]" "second: ptype temp1" | |
21795 | +gdb_test "ptype temp2" "type = char \\\[78\\\]" "second: ptype temp2" | |
21796 | +gdb_test "ptype temp3" "type = char \\\[48\\\]" "second: ptype temp3" | |
21797 | + | |
21798 | +gdb_test "p temp1" " = '1' <repeats 78 times>" "second: print temp1" | |
21799 | +gdb_test "p temp2" " = '2' <repeats 78 times>" "second: print temp2" | |
21800 | +gdb_test "p temp3" " = '3' <repeats 48 times>" "second: print temp3" | |
7566401a ER |
21801 | diff --git a/gdb/testsuite/gdb.base/watchpoint-hw.c b/gdb/testsuite/gdb.base/watchpoint-hw.c |
21802 | index 8da9af5..e2de53a 100644 | |
21803 | --- a/gdb/testsuite/gdb.base/watchpoint-hw.c | |
21804 | +++ b/gdb/testsuite/gdb.base/watchpoint-hw.c | |
21805 | @@ -20,5 +20,11 @@ int watchee; | |
21806 | int | |
21807 | main (void) | |
21808 | { | |
21809 | + volatile int dummy; | |
3a58abaf | 21810 | + |
7566401a ER |
21811 | + dummy = watchee; |
21812 | + dummy = 1; | |
21813 | + dummy = 2; /* break-at-exit */ | |
3a58abaf | 21814 | + |
7566401a ER |
21815 | return 0; |
21816 | } | |
21817 | diff --git a/gdb/testsuite/gdb.base/watchpoint-hw.exp b/gdb/testsuite/gdb.base/watchpoint-hw.exp | |
21818 | index a2bb731..d74d6c7 100644 | |
21819 | --- a/gdb/testsuite/gdb.base/watchpoint-hw.exp | |
21820 | +++ b/gdb/testsuite/gdb.base/watchpoint-hw.exp | |
21821 | @@ -21,19 +21,12 @@ if {(![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] | |
21822 | return | |
21823 | } | |
21824 | ||
21825 | -set testfile watchpoint-hw | |
21826 | -set srcfile ${testfile}.c | |
21827 | -set binfile ${objdir}/${subdir}/${testfile} | |
21828 | -if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
21829 | - untested "Couldn't compile test program" | |
21830 | +set test watchpoint-hw | |
21831 | +set srcfile ${test}.c | |
21832 | +if { [prepare_for_testing ${test}.exp ${test} ${srcfile}] } { | |
21833 | return -1 | |
21834 | } | |
21835 | ||
21836 | -gdb_exit | |
21837 | -gdb_start | |
21838 | -gdb_reinitialize_dir $srcdir/$subdir | |
21839 | -gdb_load ${binfile} | |
21840 | - | |
21841 | # Create the watchpoint before the inferior gets started. Now the native CPU | |
21842 | # target is still not active and its `to_can_use_hw_breakpoint' is not | |
21843 | # installed, therefore only a software watchpoint gets created. | |
21844 | @@ -43,10 +36,40 @@ gdb_test "watch watchee" "atchpoint 1: watchee" | |
21845 | # `runto_main' or `runto main' would delete the watchpoint created above. | |
21846 | ||
21847 | if { [gdb_start_cmd] < 0 } { | |
21848 | - untested start | |
21849 | + untested ${test}.exp | |
21850 | return -1 | |
21851 | } | |
21852 | gdb_test "" "main .* at .*" "start" | |
21853 | ||
21854 | # Check it is really a `hw'-watchpoint. | |
21855 | gdb_test "info watchpoints" "1 *hw watchpoint .* watchee" | |
3a58abaf | 21856 | + |
7566401a ER |
21857 | +# Before the inferior gets started we would get: |
21858 | +# Target does not support this type of hardware watchpoint. | |
21859 | +gdb_test "delete 1" | |
21860 | +gdb_test "rwatch watchee" | |
3a58abaf | 21861 | + |
7566401a ER |
21862 | +set breakline [gdb_get_line_number "break-at-exit"] |
21863 | +gdb_breakpoint $breakline | |
3a58abaf | 21864 | + |
7566401a | 21865 | +gdb_test "continue" "Continuing.\r\nHardware read watchpoint 3: watchee\r\n\r\nValue = 0\r\n.*" |
3a58abaf | 21866 | + |
7566401a ER |
21867 | +# Here should be no repeated notification of the read watchpoint. |
21868 | +gdb_test "continue" \ | |
21869 | + "Continuing\\.\[ \r\n\]+Breakpoint \[0-9\]+, .*break-at-exit.*" \ | |
21870 | + "continue to break-at-exit after rwatch" | |
3a58abaf | 21871 | + |
7566401a | 21872 | +clean_restart ${test} |
3a58abaf AM |
21873 | + |
21874 | +if ![runto_main] { | |
7566401a | 21875 | + untested ${test}.exp |
3a58abaf AM |
21876 | + return -1 |
21877 | +} | |
21878 | + | |
7566401a ER |
21879 | +gdb_test "hbreak ${srcfile}:${breakline}" \ |
21880 | + "Hardware assisted breakpoint 2 at 0x\[0-9a-f\]+: file .*${srcfile}, line ${breakline}\\." \ | |
21881 | + "hbreak" | |
3a58abaf | 21882 | + |
7566401a ER |
21883 | +gdb_test "continue" \ |
21884 | + "Continuing\\.\[ \r\n\]+Breakpoint \[0-9\]+, .*break-at-exit.*" \ | |
21885 | + "continue to break-at-exit after hbreak" | |
21886 | diff --git a/gdb/testsuite/gdb.cp/Makefile.in b/gdb/testsuite/gdb.cp/Makefile.in | |
21887 | index 0a087c7..b4880f2 100644 | |
21888 | --- a/gdb/testsuite/gdb.cp/Makefile.in | |
21889 | +++ b/gdb/testsuite/gdb.cp/Makefile.in | |
21890 | @@ -4,7 +4,7 @@ srcdir = @srcdir@ | |
21891 | EXECUTABLES = ambiguous annota2 anon-union cplusfuncs cttiadd \ | |
21892 | derivation inherit local member-ptr method misc \ | |
21893 | overload ovldbreak ref-typ ref-typ2 templates userdef virtfunc namespace \ | |
21894 | - ref-types ref-params method2 pr9594 gdb2495 | |
21895 | + ref-types ref-params method2 pr9594 gdb2495 gdb9593 | |
21896 | ||
21897 | all info install-info dvi install uninstall installcheck check: | |
21898 | @echo "Nothing to be done for $@..." | |
21899 | diff --git a/gdb/testsuite/gdb.cp/cp-relocate.exp b/gdb/testsuite/gdb.cp/cp-relocate.exp | |
21900 | index 4095ccf..03c07d5 100644 | |
21901 | --- a/gdb/testsuite/gdb.cp/cp-relocate.exp | |
21902 | +++ b/gdb/testsuite/gdb.cp/cp-relocate.exp | |
21903 | @@ -30,7 +30,7 @@ proc get_func_address { func } { | |
21904 | global gdb_prompt hex | |
21905 | ||
21906 | set rfunc [string_to_regexp $func] | |
21907 | - gdb_test_multiple "print '${func}'" "get address of ${func}" { | |
21908 | + gdb_test_multiple "print ${func}" "get address of ${func}" { | |
21909 | -re "\\\$\[0-9\]+ = \\{.*\\} (0|($hex) <${rfunc}>)\[\r\n\]+${gdb_prompt} $" { | |
21910 | # $1 = {int ()} 0x24 <function_bar> | |
21911 | # But if the function is at zero, the name may be omitted. | |
21912 | @@ -130,7 +130,7 @@ gdb_test "add-symbol-file ${binfile} 0 -s ${func1_sec} 0x10000 -s ${func2_sec} 0 | |
21913 | "y" | |
21914 | ||
21915 | # Make sure the function addresses were updated. | |
21916 | -gdb_test "break *'$func1_name'" \ | |
21917 | +gdb_test "break *$func1_name" \ | |
21918 | "Breakpoint $decimal at 0x1....: file .*" | |
21919 | -gdb_test "break *'$func2_name'" \ | |
21920 | +gdb_test "break *$func2_name" \ | |
21921 | "Breakpoint $decimal at 0x2....: file .*" | |
3a58abaf | 21922 | diff --git a/gdb/testsuite/gdb.cp/cplusfuncs.cc b/gdb/testsuite/gdb.cp/cplusfuncs.cc |
7566401a | 21923 | index 7f033d6..11dba06 100644 |
3a58abaf AM |
21924 | --- a/gdb/testsuite/gdb.cp/cplusfuncs.cc |
21925 | +++ b/gdb/testsuite/gdb.cp/cplusfuncs.cc | |
7566401a ER |
21926 | @@ -46,7 +46,9 @@ public: |
21927 | void operator [] (foo&); | |
21928 | void operator () (foo&); | |
21929 | void* operator new (size_t) throw (); | |
21930 | + void* operator new[] (size_t) throw (); | |
21931 | void operator delete (void *); | |
21932 | + void operator delete[] (void *); | |
21933 | /**/ operator int (); | |
21934 | /**/ operator char* (); | |
21935 | ||
21936 | @@ -115,7 +117,9 @@ void foo::operator ->* (foo& afoo) { afoo.ifoo = 0; } | |
21937 | void foo::operator [] (foo& afoo) { afoo.ifoo = 0; } | |
21938 | void foo::operator () (foo& afoo) { afoo.ifoo = 0; } | |
21939 | void* foo::operator new (size_t ival) throw () { ival = 0; return 0; } | |
21940 | +void* foo::operator new[] (size_t ival) throw () { ival = 0; return 0; } | |
21941 | void foo::operator delete (void *ptr) { ptr = 0; } | |
21942 | +void foo::operator delete[] (void *ptr) { ptr = 0; } | |
21943 | /**/ foo::operator int () { return 0; } | |
21944 | /**/ foo::operator char* () { return 0; } | |
21945 | ||
21946 | @@ -191,6 +195,12 @@ char * dm_type_char_star (char * p) { return p; } | |
3a58abaf AM |
21947 | int dm_type_foo_ref (foo & foo) { return foo.ifoo; } |
21948 | int * dm_type_int_star (int * p) { return p; } | |
21949 | long * dm_type_long_star (long * p) { return p; } | |
21950 | +int dm_type_short (short i) { return i; } | |
21951 | +int dm_type_long (long i) { return i; } | |
21952 | int dm_type_unsigned_int (unsigned int i) { return i; } | |
21953 | +int dm_type_unsigned_short (unsigned short i) { return i; } | |
21954 | +int dm_type_unsigned_long (unsigned long i) { return i; } | |
21955 | int dm_type_void (void) { return 0; } | |
21956 | void * dm_type_void_star (void * p) { return p; } | |
21957 | +typedef int myint; | |
21958 | +int dm_type_typedef (myint i) { return i; } | |
21959 | diff --git a/gdb/testsuite/gdb.cp/cplusfuncs.exp b/gdb/testsuite/gdb.cp/cplusfuncs.exp | |
7566401a | 21960 | index 5e08768..2ec50ca 100644 |
3a58abaf AM |
21961 | --- a/gdb/testsuite/gdb.cp/cplusfuncs.exp |
21962 | +++ b/gdb/testsuite/gdb.cp/cplusfuncs.exp | |
7566401a ER |
21963 | @@ -63,12 +63,28 @@ set dm_type_foo_ref "foo&" |
21964 | set dm_type_int_star "int*" | |
21965 | set dm_type_long_star "long*" | |
21966 | set dm_type_unsigned_int "unsigned" | |
21967 | -set dm_type_void "" | |
21968 | +set dm_type_void "void" | |
3a58abaf AM |
21969 | set dm_type_void_star "void*" |
21970 | ||
21971 | +# Some other vagaries of GDB's type printing machinery. The integer types | |
21972 | +# may have unsigned before or after their length, and may have "int" | |
21973 | +# appended. The char* conversion operator may have name "char*" even if | |
21974 | +# the type is "char *", because the name comes from the debug information | |
21975 | +# and the type from GDB. Function types may not see through typedefs. | |
21976 | + | |
21977 | +set dm_type_short "short" | |
21978 | +set dm_type_long "long" | |
21979 | +set dm_type_unsigned_short "unsigned short" | |
21980 | +set dm_type_unsigned_long "unsigned long" | |
21981 | +set dm_operator_char_star "char*" | |
21982 | +set dm_operator_char_star_quoted "char\\*" | |
21983 | +set dm_type_typedef 0 | |
21984 | + | |
21985 | proc probe_demangler { } { | |
21986 | global gdb_prompt | |
21987 | global dm_operator_comma | |
21988 | + global dm_operator_char_star | |
21989 | + global dm_operator_char_star_quoted | |
21990 | global dm_type_char_star | |
21991 | global dm_type_char_star_quoted | |
21992 | global dm_type_foo_ref | |
7566401a | 21993 | @@ -77,8 +93,13 @@ proc probe_demangler { } { |
3a58abaf AM |
21994 | global dm_type_unsigned_int |
21995 | global dm_type_void | |
21996 | global dm_type_void_star | |
21997 | + global dm_type_short | |
21998 | + global dm_type_unsigned_short | |
21999 | + global dm_type_long | |
22000 | + global dm_type_unsigned_long | |
22001 | + global dm_type_typedef | |
22002 | ||
7566401a ER |
22003 | - send_gdb "print &'foo::operator,(foo&)'\n" |
22004 | + send_gdb "print &foo::operator,(foo&)\n" | |
3a58abaf | 22005 | gdb_expect { |
7566401a ER |
22006 | -re ".*foo::operator, \\(.*foo.*&.*\\).*\r\n$gdb_prompt $" { |
22007 | # v2 demangler | |
3a58abaf AM |
22008 | @@ -97,6 +118,26 @@ proc probe_demangler { } { |
22009 | } | |
22010 | } | |
22011 | ||
7566401a | 22012 | + send_gdb "print &foo::operator char*($dm_type_void)\n" |
3a58abaf AM |
22013 | + gdb_expect { |
22014 | + -re ".*foo::operator char \\*\\(void\\).*\r\n$gdb_prompt $" { | |
22015 | + # v2 demangler or GDB type printer | |
22016 | + set dm_operator_char_star "char *" | |
22017 | + set dm_operator_char_star_quoted "char \\*" | |
22018 | + pass "detect dm_operator_char_star" | |
22019 | + } | |
22020 | + -re ".*foo::operator char\\*\\(\\).*\r\n$gdb_prompt $" { | |
22021 | + # v3 demangler | |
22022 | + pass "detect dm_operator_char_star" | |
22023 | + } | |
22024 | + -re ".*$gdb_prompt $" { | |
22025 | + fail "detect dm_operator_char_star" | |
22026 | + } | |
22027 | + timeout { | |
22028 | + fail "detect dm_operator_char_star" | |
22029 | + } | |
22030 | + } | |
22031 | + | |
22032 | send_gdb "print &'dm_type_char_star'\n" | |
22033 | gdb_expect { | |
22034 | -re ".*dm_type_char_star\\(char \\*\\).*\r\n$gdb_prompt $" { | |
22035 | @@ -166,6 +207,11 @@ proc probe_demangler { } { | |
22036 | # v3 demangler | |
22037 | pass "detect dm_type_long_star" | |
22038 | } | |
22039 | + -re ".*dm_type_long_star\\(long int \\*\\).*\r\n$gdb_prompt $" { | |
22040 | + # GCC v3 and GDB's type printer | |
22041 | + set dm_type_long_star "long int *" | |
22042 | + pass "detect dm_type_long_star" | |
22043 | + } | |
22044 | -re ".*$gdb_prompt $" { | |
22045 | fail "detect dm_type_long_star" | |
22046 | } | |
22047 | @@ -230,6 +276,101 @@ proc probe_demangler { } { | |
22048 | fail "detect dm_type_void_star (timeout)" | |
22049 | } | |
22050 | } | |
22051 | + | |
22052 | + send_gdb "print &'dm_type_short'\n" | |
22053 | + gdb_expect { | |
22054 | + -re ".*dm_type_short\\(short\\).*\r\n$gdb_prompt $" { | |
22055 | + # v2 and v3 demanglers | |
22056 | + pass "detect dm_type_short" | |
22057 | + } | |
22058 | + -re ".*dm_type_short\\(short int\\).*\r\n$gdb_prompt $" { | |
22059 | + # GDB type printer | |
22060 | + set dm_type_short "short int" | |
22061 | + pass "detect dm_type_short" | |
22062 | + } | |
22063 | + -re ".*$gdb_prompt $" { | |
22064 | + fail "detect dm_type_short" | |
22065 | + } | |
22066 | + timeout { | |
22067 | + fail "detect dm_type_short (timeout)" | |
22068 | + } | |
22069 | + } | |
22070 | + | |
22071 | + send_gdb "print &'dm_type_unsigned_short'\n" | |
22072 | + gdb_expect { | |
22073 | + -re ".*dm_type_unsigned_short\\(unsigned short\\).*\r\n$gdb_prompt $" { | |
22074 | + # v2 and v3 demanglers | |
22075 | + pass "detect dm_type_unsigned_short" | |
22076 | + } | |
22077 | + -re ".*dm_type_unsigned_short\\(short unsigned int\\).*\r\n$gdb_prompt $" { | |
22078 | + # GDB type printer | |
22079 | + set dm_type_unsigned_short "short unsigned int" | |
22080 | + pass "detect dm_type_unsigned_short" | |
22081 | + } | |
22082 | + -re ".*$gdb_prompt $" { | |
22083 | + fail "detect dm_type_unsigned_short" | |
22084 | + } | |
22085 | + timeout { | |
22086 | + fail "detect dm_type_unsigned_short (timeout)" | |
22087 | + } | |
22088 | + } | |
22089 | + | |
22090 | + send_gdb "print &'dm_type_long'\n" | |
22091 | + gdb_expect { | |
22092 | + -re ".*dm_type_long\\(long\\).*\r\n$gdb_prompt $" { | |
22093 | + # v2 and v3 demanglers | |
22094 | + pass "detect dm_type_long" | |
22095 | + } | |
22096 | + -re ".*dm_type_long\\(long int\\).*\r\n$gdb_prompt $" { | |
22097 | + # GDB type printer | |
22098 | + set dm_type_long "long int" | |
22099 | + pass "detect dm_type_long" | |
22100 | + } | |
22101 | + -re ".*$gdb_prompt $" { | |
22102 | + fail "detect dm_type_long" | |
22103 | + } | |
22104 | + timeout { | |
22105 | + fail "detect dm_type_long (timeout)" | |
22106 | + } | |
22107 | + } | |
22108 | + | |
22109 | + send_gdb "print &'dm_type_unsigned_long'\n" | |
22110 | + gdb_expect { | |
22111 | + -re ".*dm_type_unsigned_long\\(unsigned long\\).*\r\n$gdb_prompt $" { | |
22112 | + # v2 and v3 demanglers | |
22113 | + pass "detect dm_type_unsigned_long" | |
22114 | + } | |
22115 | + -re ".*dm_type_unsigned_long\\(long unsigned int\\).*\r\n$gdb_prompt $" { | |
22116 | + # GDB type printer | |
22117 | + set dm_type_unsigned_long "long unsigned int" | |
22118 | + pass "detect dm_type_unsigned_long" | |
22119 | + } | |
22120 | + -re ".*$gdb_prompt $" { | |
22121 | + fail "detect dm_type_unsigned_long" | |
22122 | + } | |
22123 | + timeout { | |
22124 | + fail "detect dm_type_unsigned_long (timeout)" | |
22125 | + } | |
22126 | + } | |
22127 | + | |
22128 | + send_gdb "print &'dm_type_typedef'\n" | |
22129 | + gdb_expect { | |
22130 | + -re ".*dm_type_typedef\\(int\\).*\r\n$gdb_prompt $" { | |
22131 | + # v2 and v3 demanglers | |
22132 | + pass "detect dm_type_typedef" | |
22133 | + } | |
22134 | + -re ".*dm_type_typedef\\(myint\\).*\r\n$gdb_prompt $" { | |
22135 | + # GDB type printer | |
22136 | + set dm_type_typedef 1 | |
22137 | + pass "detect dm_type_typedef" | |
22138 | + } | |
22139 | + -re ".*$gdb_prompt $" { | |
22140 | + fail "detect dm_type_typedef" | |
22141 | + } | |
22142 | + timeout { | |
22143 | + fail "detect dm_type_typedef (timeout)" | |
22144 | + } | |
22145 | + } | |
22146 | } | |
22147 | ||
22148 | # | |
7566401a ER |
22149 | @@ -241,6 +382,7 @@ proc info_func_regexp { name demangled } { |
22150 | global gdb_prompt | |
22151 | ||
22152 | send_gdb "info function $name\n" | |
22153 | + set demangled [regsub {\\\(void\\\)} $demangled {\(\)}] | |
22154 | gdb_expect { | |
22155 | -re ".*File .*:\r\n(class |)$demangled\r\n.*$gdb_prompt $" { | |
22156 | pass "info function for \"$name\"" | |
22157 | @@ -277,16 +419,16 @@ proc print_addr_2 { name good } { | |
22158 | ||
22159 | set good_pattern [string_to_regexp $good] | |
22160 | ||
22161 | - send_gdb "print &'$name'\n" | |
22162 | + send_gdb "print &$name\n" | |
22163 | gdb_expect { | |
22164 | -re ".* = .* $hex <$good_pattern>\r\n$gdb_prompt $" { | |
22165 | - pass "print &'$name'" | |
22166 | + pass "print &$name" | |
22167 | } | |
22168 | -re ".*$gdb_prompt $" { | |
22169 | - fail "print &'$name'" | |
22170 | + fail "print &$name" | |
22171 | } | |
22172 | timeout { | |
22173 | - fail "print &'$name' (timeout)" | |
22174 | + fail "print &$name (timeout)" | |
22175 | } | |
22176 | } | |
22177 | } | |
22178 | @@ -327,7 +469,12 @@ proc print_addr_2_kfail { name good bad bugid } { | |
22179 | # | |
22180 | ||
22181 | proc print_addr { name } { | |
22182 | - print_addr_2 "$name" "$name" | |
22183 | + set expected [regsub {\(void\)} $name {()}] | |
22184 | + if {[string first "::" $name] == -1} { | |
22185 | + # C function -- must be qutoed | |
22186 | + set name "'$name'" | |
22187 | + } | |
22188 | + print_addr_2 "$name" $expected | |
22189 | } | |
22190 | ||
22191 | # | |
22192 | @@ -345,8 +492,9 @@ proc print_addr { name } { | |
3a58abaf AM |
22193 | |
22194 | proc test_lookup_operator_functions {} { | |
22195 | global dm_operator_comma | |
22196 | + global dm_operator_char_star | |
22197 | global dm_type_char_star | |
22198 | - global dm_type_char_star_quoted | |
22199 | + global dm_operator_char_star_quoted | |
22200 | global dm_type_foo_ref | |
22201 | global dm_type_void | |
22202 | global dm_type_void_star | |
7566401a | 22203 | @@ -404,8 +552,8 @@ proc test_lookup_operator_functions {} { |
3a58abaf AM |
22204 | |
22205 | info_func "operator int(" "int foo::operator int($dm_type_void);" | |
22206 | info_func "operator()(" "void foo::operator()($dm_type_foo_ref);" | |
22207 | - info_func "operator $dm_type_char_star_quoted\(" \ | |
22208 | - "char *foo::operator $dm_type_char_star\($dm_type_void);" | |
22209 | + info_func "operator $dm_operator_char_star_quoted\(" \ | |
22210 | + "char *foo::operator $dm_operator_char_star\($dm_type_void);" | |
22211 | ||
22212 | } | |
22213 | ||
7566401a | 22214 | @@ -420,6 +568,7 @@ proc test_paddr_operator_functions {} { |
3a58abaf AM |
22215 | global dm_type_unsigned_int |
22216 | global dm_type_void | |
22217 | global dm_type_void_star | |
22218 | + global dm_operator_char_star | |
22219 | ||
22220 | print_addr "foo::operator*($dm_type_foo_ref)" | |
22221 | print_addr "foo::operator%($dm_type_foo_ref)" | |
7566401a ER |
22222 | @@ -460,17 +609,20 @@ proc test_paddr_operator_functions {} { |
22223 | print_addr "foo::operator\[\]($dm_type_foo_ref)" | |
22224 | print_addr "foo::operator()($dm_type_foo_ref)" | |
22225 | ||
22226 | - gdb_test "print &'foo::operator new'" \ | |
22227 | + gdb_test "print &foo::operator new" \ | |
22228 | " = .* $hex <foo::operator new\\(.*\\)(| static)>" | |
22229 | + gdb_test "print &foo::operator new\[\]" \ | |
22230 | + " = .* $hex <foo::operator new\\\[\\\]\\(.*\\)(| static)>" | |
22231 | if { !$hp_aCC_compiler } { | |
22232 | print_addr "foo::operator delete($dm_type_void_star)" | |
22233 | + print_addr "foo::operator delete[]($dm_type_void_star)" | |
22234 | } else { | |
22235 | gdb_test "print &'foo::operator delete($dm_type_void_star) static'" \ | |
22236 | " = .*(0x\[0-9a-f\]+|) <foo::operator delete.*>" | |
3a58abaf AM |
22237 | } |
22238 | ||
22239 | print_addr "foo::operator int($dm_type_void)" | |
22240 | - print_addr "foo::operator $dm_type_char_star\($dm_type_void)" | |
22241 | + print_addr "foo::operator $dm_operator_char_star\($dm_type_void)" | |
22242 | } | |
22243 | ||
22244 | # | |
7566401a | 22245 | @@ -480,17 +632,21 @@ proc test_paddr_operator_functions {} { |
3a58abaf AM |
22246 | proc test_paddr_overloaded_functions {} { |
22247 | global dm_type_unsigned_int | |
22248 | global dm_type_void | |
22249 | + global dm_type_short | |
22250 | + global dm_type_unsigned_short | |
22251 | + global dm_type_long | |
22252 | + global dm_type_unsigned_long | |
22253 | ||
22254 | print_addr "overload1arg($dm_type_void)" | |
22255 | print_addr "overload1arg(char)" | |
22256 | print_addr "overload1arg(signed char)" | |
22257 | print_addr "overload1arg(unsigned char)" | |
22258 | - print_addr "overload1arg(short)" | |
22259 | - print_addr "overload1arg(unsigned short)" | |
22260 | + print_addr "overload1arg($dm_type_short)" | |
22261 | + print_addr "overload1arg($dm_type_unsigned_short)" | |
22262 | print_addr "overload1arg(int)" | |
22263 | print_addr "overload1arg($dm_type_unsigned_int)" | |
22264 | - print_addr "overload1arg(long)" | |
22265 | - print_addr "overload1arg(unsigned long)" | |
22266 | + print_addr "overload1arg($dm_type_long)" | |
22267 | + print_addr "overload1arg($dm_type_unsigned_long)" | |
22268 | print_addr "overload1arg(float)" | |
22269 | print_addr "overload1arg(double)" | |
22270 | ||
7566401a | 22271 | @@ -513,17 +669,31 @@ proc test_paddr_hairy_functions {} { |
3a58abaf AM |
22272 | global dm_type_char_star |
22273 | global dm_type_int_star | |
22274 | global dm_type_long_star | |
22275 | + global dm_type_typedef | |
22276 | ||
22277 | print_addr_2 "hairyfunc1" "hairyfunc1(int)" | |
22278 | - print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))" | |
22279 | - print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))" | |
22280 | - print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))" | |
22281 | - | |
22282 | - # gdb-gnats bug gdb/19: | |
22283 | - # "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7" | |
22284 | - print_addr_2_kfail "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))" "hairyfunc5(int (*)(long) (*)(char*))" "gdb/19" | |
22285 | - print_addr_2_kfail "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))" "hairyfunc6(int (*)(long) (*)(int*))" "gdb/19" | |
22286 | - print_addr_2_kfail "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))" "hairyfunc7(int (*)(long) (*)(int (*)(char*)))" "gdb/19" | |
22287 | + | |
22288 | + if {$dm_type_typedef == 0} { | |
22289 | + print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))" | |
22290 | + print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))" | |
22291 | + print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))" | |
22292 | + | |
22293 | + # gdb-gnats bug gdb/19: | |
22294 | + # "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7" | |
22295 | + print_addr_2_kfail "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))" "hairyfunc5(int (*)(long) (*)(char*))" "gdb/19" | |
22296 | + print_addr_2_kfail "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))" "hairyfunc6(int (*)(long) (*)(int*))" "gdb/19" | |
22297 | + print_addr_2_kfail "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))" "hairyfunc7(int (*)(long) (*)(int (*)(char*)))" "gdb/19" | |
22298 | + } else { | |
22299 | + print_addr_2 "hairyfunc2" "hairyfunc2(PFPc_i)" | |
22300 | + print_addr_2 "hairyfunc3" "hairyfunc3(PFPFPl_s_i)" | |
22301 | + print_addr_2 "hairyfunc4" "hairyfunc4(PFPFPc_s_i)" | |
22302 | + | |
22303 | + # gdb-gnats bug gdb/19: | |
22304 | + # "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7" | |
22305 | + print_addr_2 "hairyfunc5" "hairyfunc5(PFPc_PFl_i)" | |
22306 | + print_addr_2 "hairyfunc6" "hairyfunc6(PFPi_PFl_i)" | |
22307 | + print_addr_2 "hairyfunc7" "hairyfunc7(PFPFPc_i_PFl_i)" | |
22308 | + } | |
22309 | } | |
22310 | ||
22311 | proc do_tests {} { | |
7566401a ER |
22312 | @@ -534,6 +704,7 @@ proc do_tests {} { |
22313 | global srcdir | |
22314 | global binfile | |
22315 | global gdb_prompt | |
22316 | + global dm_type_int_star | |
22317 | ||
22318 | set prms_id 0 | |
22319 | set bug_id 0 | |
22320 | @@ -557,6 +728,10 @@ proc do_tests {} { | |
22321 | test_paddr_operator_functions | |
22322 | test_paddr_hairy_functions | |
22323 | test_lookup_operator_functions | |
22324 | + | |
22325 | + # A regression test on errors involving operators | |
22326 | + gdb_test "list foo::operator $dm_type_int_star" \ | |
22327 | + ".*the class foo does not have any method named operator $dm_type_int_star.*" | |
22328 | } | |
22329 | ||
22330 | do_tests | |
22331 | diff --git a/gdb/testsuite/gdb.cp/expand-sals.exp b/gdb/testsuite/gdb.cp/expand-sals.exp | |
22332 | index 3c302c3..cd0496d 100644 | |
22333 | --- a/gdb/testsuite/gdb.cp/expand-sals.exp | |
22334 | +++ b/gdb/testsuite/gdb.cp/expand-sals.exp | |
22335 | @@ -48,7 +48,7 @@ gdb_continue_to_breakpoint "caller" ".*caller-line.*" | |
22336 | ||
22337 | # Test GDB caught this return call and not the next one through B::B() | |
22338 | gdb_test "bt" \ | |
22339 | - "#0 \[^\r\n\]* A \[^\r\n\]*\r\n#1 \[^\r\n\]* main \[^\r\n\]*" \ | |
22340 | + "#0 \[^\r\n\]* (A::)?A \[^\r\n\]*\r\n#1 \[^\r\n\]* main \[^\r\n\]*" \ | |
22341 | "bt from A" | |
22342 | ||
22343 | gdb_continue_to_breakpoint "next caller func" ".*func-line.*" | |
22344 | diff --git a/gdb/testsuite/gdb.cp/gdb9593.cc b/gdb/testsuite/gdb.cp/gdb9593.cc | |
3a58abaf | 22345 | new file mode 100644 |
7566401a | 22346 | index 0000000..783c962 |
3a58abaf | 22347 | --- /dev/null |
7566401a ER |
22348 | +++ b/gdb/testsuite/gdb.cp/gdb9593.cc |
22349 | @@ -0,0 +1,180 @@ | |
3a58abaf AM |
22350 | +/* This testcase is part of GDB, the GNU debugger. |
22351 | + | |
7566401a | 22352 | + Copyright 2008, 2009 Free Software Foundation, Inc. |
3a58abaf AM |
22353 | + |
22354 | + This program is free software; you can redistribute it and/or modify | |
22355 | + it under the terms of the GNU General Public License as published by | |
22356 | + the Free Software Foundation; either version 3 of the License, or | |
22357 | + (at your option) any later version. | |
22358 | + | |
22359 | + This program is distributed in the hope that it will be useful, | |
22360 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22361 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22362 | + GNU General Public License for more details. | |
22363 | + | |
22364 | + You should have received a copy of the GNU General Public License | |
7566401a ER |
22365 | + along with this program. If not, see <http://www.gnu.org/licenses/>. |
22366 | + */ | |
22367 | +#include <iostream> | |
3a58abaf | 22368 | + |
7566401a | 22369 | +using namespace std; |
3a58abaf | 22370 | + |
7566401a | 22371 | +class NextOverThrowDerivates |
3a58abaf | 22372 | +{ |
7566401a | 22373 | + |
3a58abaf | 22374 | +public: |
3a58abaf | 22375 | + |
3a58abaf | 22376 | + |
7566401a ER |
22377 | + // Single throw an exception in this function. |
22378 | + void function1() | |
22379 | + { | |
22380 | + throw 20; | |
22381 | + } | |
3a58abaf | 22382 | + |
7566401a ER |
22383 | + // Throw an exception in another function. |
22384 | + void function2() | |
22385 | + { | |
22386 | + function1(); | |
22387 | + } | |
3a58abaf | 22388 | + |
7566401a ER |
22389 | + // Throw an exception in another function, but handle it |
22390 | + // locally. | |
22391 | + void function3 () | |
22392 | + { | |
22393 | + { | |
22394 | + try | |
22395 | + { | |
22396 | + function1 (); | |
22397 | + } | |
22398 | + catch (...) | |
22399 | + { | |
22400 | + cout << "Caught and handled function1 exception" << endl; | |
22401 | + } | |
22402 | + } | |
22403 | + } | |
3a58abaf | 22404 | + |
7566401a ER |
22405 | + void rethrow () |
22406 | + { | |
22407 | + try | |
22408 | + { | |
22409 | + function1 (); | |
22410 | + } | |
22411 | + catch (...) | |
22412 | + { | |
22413 | + throw; | |
22414 | + } | |
22415 | + } | |
3a58abaf | 22416 | + |
7566401a ER |
22417 | + void finish () |
22418 | + { | |
22419 | + // We use this to test that a "finish" here does not end up in | |
22420 | + // this frame, but in the one above. | |
22421 | + try | |
22422 | + { | |
22423 | + function1 (); | |
22424 | + } | |
22425 | + catch (int x) | |
22426 | + { | |
22427 | + } | |
22428 | + function1 (); // marker for until | |
22429 | + } | |
3a58abaf | 22430 | + |
7566401a ER |
22431 | + void until () |
22432 | + { | |
22433 | + function1 (); | |
22434 | + function1 (); // until here | |
22435 | + } | |
3a58abaf | 22436 | + |
7566401a ER |
22437 | +}; |
22438 | +NextOverThrowDerivates next_cases; | |
3a58abaf | 22439 | + |
3a58abaf | 22440 | + |
7566401a ER |
22441 | +int main () |
22442 | +{ | |
22443 | + try | |
22444 | + { | |
22445 | + next_cases.function1 (); | |
3a58abaf | 22446 | + } |
7566401a ER |
22447 | + catch (...) |
22448 | + { | |
22449 | + // Discard | |
3a58abaf | 22450 | + } |
3a58abaf | 22451 | + |
7566401a ER |
22452 | + try |
22453 | + { | |
22454 | + next_cases.function2 (); | |
3a58abaf | 22455 | + } |
7566401a ER |
22456 | + catch (...) |
22457 | + { | |
22458 | + // Discard | |
3a58abaf | 22459 | + } |
3a58abaf | 22460 | + |
7566401a ER |
22461 | + try |
22462 | + { | |
22463 | + // This is duplicated so we can next over one but step into | |
22464 | + // another. | |
22465 | + next_cases.function2 (); | |
22466 | + } | |
22467 | + catch (...) | |
22468 | + { | |
22469 | + // Discard | |
22470 | + } | |
3a58abaf | 22471 | + |
7566401a | 22472 | + next_cases.function3 (); |
3a58abaf | 22473 | + |
7566401a ER |
22474 | + try |
22475 | + { | |
22476 | + next_cases.rethrow (); | |
22477 | + } | |
22478 | + catch (...) | |
22479 | + { | |
22480 | + // Discard | |
22481 | + } | |
3a58abaf | 22482 | + |
7566401a ER |
22483 | + try |
22484 | + { | |
22485 | + // Another duplicate so we can test "finish". | |
22486 | + next_cases.function2 (); | |
22487 | + } | |
22488 | + catch (...) | |
22489 | + { | |
22490 | + // Discard | |
22491 | + } | |
3a58abaf | 22492 | + |
7566401a ER |
22493 | + // Another test for "finish". |
22494 | + try | |
22495 | + { | |
22496 | + next_cases.finish (); | |
22497 | + } | |
22498 | + catch (...) | |
22499 | + { | |
22500 | + } | |
3a58abaf | 22501 | + |
7566401a ER |
22502 | + // Test of "until". |
22503 | + try | |
22504 | + { | |
22505 | + next_cases.finish (); | |
22506 | + } | |
22507 | + catch (...) | |
22508 | + { | |
22509 | + } | |
3a58abaf | 22510 | + |
7566401a ER |
22511 | + // Test of "until" with an argument. |
22512 | + try | |
22513 | + { | |
22514 | + next_cases.until (); | |
22515 | + } | |
22516 | + catch (...) | |
22517 | + { | |
22518 | + } | |
3a58abaf | 22519 | + |
7566401a ER |
22520 | + // Test of "advance". |
22521 | + try | |
3a58abaf | 22522 | + { |
7566401a | 22523 | + next_cases.until (); |
3a58abaf AM |
22524 | + } |
22525 | + catch (...) | |
22526 | + { | |
22527 | + } | |
3a58abaf AM |
22528 | +} |
22529 | + | |
7566401a | 22530 | diff --git a/gdb/testsuite/gdb.cp/gdb9593.exp b/gdb/testsuite/gdb.cp/gdb9593.exp |
3a58abaf | 22531 | new file mode 100644 |
7566401a | 22532 | index 0000000..ee9aeff |
3a58abaf | 22533 | --- /dev/null |
7566401a ER |
22534 | +++ b/gdb/testsuite/gdb.cp/gdb9593.exp |
22535 | @@ -0,0 +1,185 @@ | |
22536 | +# Copyright 2008, 2009 Free Software Foundation, Inc. | |
3a58abaf AM |
22537 | + |
22538 | +# This program is free software; you can redistribute it and/or modify | |
22539 | +# it under the terms of the GNU General Public License as published by | |
22540 | +# the Free Software Foundation; either version 3 of the License, or | |
22541 | +# (at your option) any later version. | |
22542 | +# | |
22543 | +# This program is distributed in the hope that it will be useful, | |
22544 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22545 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22546 | +# GNU General Public License for more details. | |
22547 | +# | |
22548 | +# You should have received a copy of the GNU General Public License | |
22549 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
22550 | + | |
22551 | + | |
3a58abaf AM |
22552 | +if $tracelevel then { |
22553 | + strace $tracelevel | |
22554 | +} | |
22555 | + | |
22556 | +if { [skip_cplus_tests] } { continue } | |
22557 | + | |
7566401a | 22558 | +set prms_id 9593 |
3a58abaf AM |
22559 | +set bug_id 0 |
22560 | + | |
7566401a | 22561 | +set testfile "gdb9593" |
3a58abaf AM |
22562 | +set srcfile ${testfile}.cc |
22563 | +set binfile $objdir/$subdir/$testfile | |
22564 | + | |
22565 | +# Create and source the file that provides information about the compiler | |
22566 | +# used to compile the test case. | |
22567 | +if [get_compiler_info ${binfile} "c++"] { | |
7566401a | 22568 | + untested gdb9593.exp |
3a58abaf AM |
22569 | + return -1 |
22570 | +} | |
22571 | + | |
22572 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
7566401a ER |
22573 | + untested gdb9593.exp |
22574 | + return -1 | |
3a58abaf AM |
22575 | +} |
22576 | + | |
22577 | +# Some targets can't do function calls, so don't even bother with this | |
22578 | +# test. | |
22579 | +if [target_info exists gdb,cannot_call_functions] { | |
7566401a | 22580 | + setup_xfail "*-*-*" 9593 |
3a58abaf AM |
22581 | + fail "This target can not call functions" |
22582 | + continue | |
22583 | +} | |
22584 | + | |
22585 | +gdb_exit | |
22586 | +gdb_start | |
22587 | +gdb_reinitialize_dir $srcdir/$subdir | |
22588 | +gdb_load ${binfile} | |
22589 | + | |
22590 | +if ![runto_main] then { | |
22591 | + perror "couldn't run to main" | |
22592 | + continue | |
22593 | +} | |
22594 | + | |
7566401a ER |
22595 | +# See whether we have the needed unwinder hooks. |
22596 | +set ok 1 | |
22597 | +gdb_test_multiple "print _Unwind_DebugHook" "check for unwinder hook" { | |
22598 | + -re "= .*_Unwind_DebugHook.*\r\n$gdb_prompt $" { | |
22599 | + pass "check for unwinder hook" | |
22600 | + } | |
22601 | + -re "No symbol .* in current context.\r\n$gdb_prompt $" { | |
22602 | + # Pass the test so we don't get bogus fails in the results. | |
22603 | + pass "check for unwinder hook" | |
22604 | + set ok 0 | |
22605 | + } | |
22606 | +} | |
22607 | +if {!$ok} { | |
22608 | + untested gdb9593.exp | |
22609 | + return -1 | |
3a58abaf AM |
22610 | +} |
22611 | + | |
7566401a | 22612 | +# See http://sourceware.org/bugzilla/show_bug.cgi?id=9593 |
3a58abaf | 22613 | + |
7566401a ER |
22614 | +gdb_test "next" \ |
22615 | + ".*catch (...).*" \ | |
22616 | + "next over a throw 1" | |
3a58abaf | 22617 | + |
7566401a ER |
22618 | +gdb_test "next" \ |
22619 | + ".*next_cases.function2.*" \ | |
22620 | + "next past catch 1" | |
3a58abaf | 22621 | + |
7566401a ER |
22622 | +gdb_test "next" \ |
22623 | + ".*catch (...).*" \ | |
22624 | + "next over a throw 2" | |
3a58abaf | 22625 | + |
7566401a ER |
22626 | +gdb_test "next" \ |
22627 | + ".*next_cases.function2.*" \ | |
22628 | + "next past catch 2" | |
3a58abaf | 22629 | + |
7566401a ER |
22630 | +gdb_test "step" \ |
22631 | + ".*function1().*" \ | |
22632 | + "step into function2 1" | |
3a58abaf | 22633 | + |
7566401a ER |
22634 | +gdb_test "next" \ |
22635 | + ".*catch (...).*" \ | |
22636 | + "next over a throw 3" | |
3a58abaf | 22637 | + |
7566401a ER |
22638 | +gdb_test "next" \ |
22639 | + ".*next_cases.function3.*" \ | |
22640 | + "next past catch 3" | |
3a58abaf | 22641 | + |
7566401a ER |
22642 | +gdb_test "next" \ |
22643 | + ".*next_cases.rethrow.*" \ | |
22644 | + "next over a throw 4" | |
3a58abaf | 22645 | + |
7566401a ER |
22646 | +gdb_test "next" \ |
22647 | + ".*catch (...).*" \ | |
22648 | + "next over a rethrow" | |
22649 | + | |
22650 | +gdb_test "next" \ | |
22651 | + ".*next_cases.function2.*" \ | |
22652 | + "next after a rethrow" | |
22653 | + | |
22654 | +gdb_test "step" \ | |
22655 | + ".*function1().*" \ | |
22656 | + "step into function2 2" | |
22657 | + | |
22658 | +gdb_test "finish" \ | |
22659 | + ".*catch (...).*" \ | |
22660 | + "finish 1" | |
22661 | + | |
22662 | +gdb_test "next" \ | |
22663 | + ".*next_cases.finish ().*" \ | |
22664 | + "next past catch 4" | |
22665 | + | |
22666 | +gdb_test "step" \ | |
22667 | + ".*function1 ().*" \ | |
22668 | + "step into finish method" | |
22669 | + | |
22670 | +gdb_test "finish" \ | |
22671 | + ".*catch (...).*" \ | |
22672 | + "finish 2" | |
22673 | + | |
22674 | +gdb_test "next" \ | |
22675 | + ".*next_cases.finish ().*" \ | |
22676 | + "next past catch 5" | |
22677 | + | |
22678 | +gdb_test "step" \ | |
22679 | + ".*function1 ().*" \ | |
22680 | + "step into finish, for until" | |
22681 | + | |
22682 | +gdb_test "until" \ | |
22683 | + ".*catch .int x.*" \ | |
22684 | + "until with no argument 1" | |
22685 | + | |
22686 | +set line [gdb_get_line_number "marker for until" $testfile.cc] | |
22687 | + | |
22688 | +gdb_test "until $line" \ | |
22689 | + ".*function1 ().*" \ | |
22690 | + "next past catch 6" | |
22691 | + | |
22692 | +gdb_test "until" \ | |
22693 | + ".*catch (...).*" \ | |
22694 | + "until with no argument 2" | |
3a58abaf | 22695 | + |
7566401a | 22696 | +set line [gdb_get_line_number "until here" $testfile.cc] |
3a58abaf | 22697 | + |
7566401a ER |
22698 | +gdb_test "next" \ |
22699 | + ".*next_cases.until ().*" \ | |
22700 | + "next past catch 6" | |
22701 | + | |
22702 | +gdb_test "step" \ | |
22703 | + ".*function1 ().*" \ | |
22704 | + "step into until" | |
22705 | + | |
22706 | +gdb_test "until $line" \ | |
22707 | + ".*catch (...).*" \ | |
22708 | + "until-over-throw" | |
22709 | + | |
22710 | +gdb_test "next" \ | |
22711 | + ".*next_cases.until ().*" \ | |
22712 | + "next past catch 7" | |
22713 | + | |
22714 | +gdb_test "step" \ | |
22715 | + ".*function1 ().*" \ | |
22716 | + "step into until, for advance" | |
22717 | + | |
22718 | +gdb_test "advance $line" \ | |
22719 | + ".*catch (...).*" \ | |
22720 | + "advance-over-throw" | |
3a58abaf AM |
22721 | diff --git a/gdb/testsuite/gdb.cp/member-ptr.cc b/gdb/testsuite/gdb.cp/member-ptr.cc |
22722 | index 1dff70a..648b2af 100644 | |
22723 | --- a/gdb/testsuite/gdb.cp/member-ptr.cc | |
22724 | +++ b/gdb/testsuite/gdb.cp/member-ptr.cc | |
22725 | @@ -138,6 +138,7 @@ class Diamond : public Padding, public Left, public Right | |
22726 | { | |
22727 | public: | |
22728 | virtual int vget_base (); | |
22729 | + int (*func_ptr) (int); | |
22730 | }; | |
22731 | ||
22732 | int Diamond::vget_base () | |
22733 | @@ -145,6 +146,12 @@ int Diamond::vget_base () | |
22734 | return this->Left::x + 2000; | |
22735 | } | |
22736 | ||
22737 | +int | |
22738 | +func (int x) | |
22739 | +{ | |
22740 | + return 19 + x; | |
22741 | +} | |
22742 | + | |
22743 | int main () | |
22744 | { | |
22745 | A a; | |
22746 | @@ -162,6 +169,7 @@ int main () | |
22747 | int (Diamond::*right_vpmf) (); | |
22748 | int (Base::*base_vpmf) (); | |
22749 | int Diamond::*diamond_pmi; | |
22750 | + int (* Diamond::*diamond_pfunc_ptr) (int); | |
22751 | ||
22752 | PMI null_pmi; | |
22753 | PMF null_pmf; | |
22754 | @@ -179,6 +187,7 @@ int main () | |
22755 | ||
22756 | diamond.Left::x = 77; | |
22757 | diamond.Right::x = 88; | |
22758 | + diamond.func_ptr = func; | |
22759 | ||
22760 | /* Some valid pointer to members from a base class. */ | |
22761 | left_pmf = (int (Diamond::*) ()) (int (Left::*) ()) (&Base::get_x); | |
22762 | @@ -193,11 +202,19 @@ int main () | |
22763 | /* A pointer to data member from a base class. */ | |
22764 | diamond_pmi = (int Diamond::*) (int Left::*) &Base::x; | |
22765 | ||
22766 | + /* A pointer to data member, where the member is itself a pointer to | |
22767 | + a function. */ | |
22768 | + diamond_pfunc_ptr = (int (* Diamond::*) (int)) &Diamond::func_ptr; | |
22769 | + | |
22770 | null_pmi = NULL; | |
22771 | null_pmf = NULL; | |
22772 | ||
22773 | pmi = NULL; /* Breakpoint 1 here. */ | |
22774 | ||
22775 | + // Invalid (uses diamond_pfunc_ptr as a function): | |
22776 | + // diamond.*diamond_pfunc_ptr (20); | |
22777 | + (diamond.*diamond_pfunc_ptr) (20); | |
22778 | + | |
22779 | k = (a.*pmf)(3); | |
22780 | ||
22781 | pmi = &A::jj; | |
22782 | diff --git a/gdb/testsuite/gdb.cp/member-ptr.exp b/gdb/testsuite/gdb.cp/member-ptr.exp | |
7566401a | 22783 | index b69d4ad..83dd0d5 100644 |
3a58abaf AM |
22784 | --- a/gdb/testsuite/gdb.cp/member-ptr.exp |
22785 | +++ b/gdb/testsuite/gdb.cp/member-ptr.exp | |
22786 | @@ -390,6 +390,33 @@ gdb_test_multiple "print ((int) pmi) == ((char *) &a.j - (char *) & a)" $name { | |
22787 | } | |
22788 | } | |
22789 | ||
22790 | +# Check pointers to data members, which are themselves pointers to | |
22791 | +# functions. These behave like data members, not like pointers to | |
22792 | +# member functions. | |
22793 | + | |
22794 | +gdb_test "ptype diamond_pfunc_ptr" \ | |
22795 | + "type = int \\(\\*Diamond::\\*\\)\\(int\\)" | |
22796 | + | |
22797 | +gdb_test "ptype diamond.*diamond_pfunc_ptr" \ | |
22798 | + "type = int \\(\\*\\)\\(int\\)" | |
22799 | + | |
22800 | +# This one is invalid; () binds more tightly than .*, so it tries to | |
22801 | +# call the member pointer as a normal pointer-to-function. | |
22802 | + | |
22803 | +gdb_test "print diamond.*diamond_pfunc_ptr (20)" \ | |
22804 | + "Invalid data type for function to be called." | |
22805 | + | |
22806 | +# With parentheses, it is valid. | |
22807 | + | |
22808 | +gdb_test "print (diamond.*diamond_pfunc_ptr) (20)" \ | |
22809 | + "$vhn = 39" | |
22810 | + | |
22811 | +# Make sure that we do not interpret this as either a member pointer | |
22812 | +# call or a member function call. | |
22813 | + | |
22814 | +gdb_test "print diamond.func_ptr (20)" \ | |
22815 | + "$vhn = 39" | |
22816 | + | |
22817 | # ========================== | |
22818 | # pointer to member function | |
22819 | # ========================== | |
7566401a ER |
22820 | @@ -420,7 +447,7 @@ gdb_test_multiple "ptype pmf" $name { |
22821 | ||
22822 | set name "print pmf" | |
22823 | gdb_test_multiple "print pmf" $name { | |
22824 | - -re "$vhn = $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" { | |
22825 | + -re "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" { | |
22826 | pass $name | |
22827 | } | |
22828 | -re "$vhn = .*not supported with HP aCC.*\r\n$gdb_prompt $" { | |
3a58abaf AM |
22829 | @@ -608,6 +635,9 @@ gdb_test_multiple "print (a.*pmf)(3)" $name { |
22830 | } | |
22831 | } | |
22832 | ||
22833 | +gdb_test "ptype a.*pmf" "type = int \\(A \\*, int\\)" | |
22834 | +gdb_test "ptype (a.*pmf)(3)" "type = int" | |
22835 | + | |
22836 | # Print out a pointer to data member which requires looking into | |
22837 | # a base class. | |
22838 | gdb_test "print diamond_pmi" "$vhn = &Base::x" | |
7566401a ER |
22839 | @@ -658,5 +688,5 @@ gdb_test "print null_pmi = &A::j" "$vhn = &A::j" |
22840 | gdb_test "print null_pmi = 0" "$vhn = NULL" | |
22841 | ||
22842 | gdb_test "print null_pmf" "$vhn = NULL" | |
22843 | -gdb_test "print null_pmf = &A::foo" "$vhn = $hex <A::foo ?\\(int\\)>" | |
22844 | +gdb_test "print null_pmf = &A::foo" "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::foo ?\\(int\\)>" | |
22845 | gdb_test "print null_pmf = 0" "$vhn = NULL" | |
3a58abaf AM |
22846 | diff --git a/gdb/testsuite/gdb.cp/namespace-multiple-imports.cc b/gdb/testsuite/gdb.cp/namespace-multiple-imports.cc |
22847 | new file mode 100644 | |
22848 | index 0000000..6b180d6 | |
22849 | --- /dev/null | |
22850 | +++ b/gdb/testsuite/gdb.cp/namespace-multiple-imports.cc | |
22851 | @@ -0,0 +1,20 @@ | |
22852 | +namespace A { | |
22853 | + int x = 11; | |
22854 | + namespace{ | |
22855 | + int xx = 22; | |
22856 | + } | |
22857 | +} | |
22858 | + | |
22859 | +using namespace A; | |
22860 | + | |
22861 | +namespace{ | |
22862 | + int xxx = 33; | |
22863 | +}; | |
22864 | + | |
22865 | +int main() | |
22866 | +{ | |
22867 | + x; | |
22868 | + xx; | |
22869 | + xxx; | |
22870 | + return 0; | |
22871 | +} | |
22872 | diff --git a/gdb/testsuite/gdb.cp/namespace-multiple-imports.exp b/gdb/testsuite/gdb.cp/namespace-multiple-imports.exp | |
22873 | new file mode 100644 | |
22874 | index 0000000..e4bb9f8 | |
22875 | --- /dev/null | |
22876 | +++ b/gdb/testsuite/gdb.cp/namespace-multiple-imports.exp | |
22877 | @@ -0,0 +1,49 @@ | |
22878 | +# Copyright 2008 Free Software Foundation, Inc. | |
22879 | + | |
22880 | +# This program is free software; you can redistribute it and/or modify | |
22881 | +# it under the terms of the GNU General Public License as published by | |
22882 | +# the Free Software Foundation; either version 3 of the License, or | |
22883 | +# (at your option) any later version. | |
22884 | +# | |
22885 | +# This program is distributed in the hope that it will be useful, | |
22886 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22887 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22888 | +# GNU General Public License for more details. | |
22889 | +# | |
22890 | +# You should have received a copy of the GNU General Public License | |
22891 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
22892 | + | |
22893 | +if $tracelevel then { | |
22894 | + strace $tracelevel | |
22895 | +} | |
22896 | + | |
22897 | +set prms_id 0 | |
22898 | +set bug_id 0 | |
22899 | + | |
22900 | +set testfile namespace-multiple-imports | |
22901 | +set srcfile ${testfile}.cc | |
22902 | +set binfile ${objdir}/${subdir}/${testfile} | |
22903 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
22904 | + untested "Couldn't compile test program" | |
22905 | + return -1 | |
22906 | +} | |
22907 | + | |
22908 | +# Get things started. | |
22909 | + | |
22910 | +gdb_exit | |
22911 | +gdb_start | |
22912 | +gdb_reinitialize_dir $srcdir/$subdir | |
22913 | +gdb_load ${binfile} | |
22914 | + | |
22915 | +############################################ | |
22916 | +# test printing of namespace imported within | |
22917 | +# the function. | |
22918 | + | |
22919 | +if ![runto_main] then { | |
22920 | + perror "couldn't run to breakpoint main" | |
22921 | + continue | |
22922 | +} | |
22923 | + | |
22924 | +gdb_test "print x" "\\$\[0-9\].* = 11" | |
22925 | +gdb_test "print xx" "\\$\[0-9\].* = 22" | |
22926 | +gdb_test "print xxx" "\\$\[0-9\].* = 33" | |
7566401a | 22927 | diff --git a/gdb/testsuite/gdb.cp/namespace-nested-imports.cc b/gdb/testsuite/gdb.cp/namespace-nested-imports.cc |
3a58abaf | 22928 | new file mode 100644 |
7566401a | 22929 | index 0000000..9723f87 |
3a58abaf | 22930 | --- /dev/null |
7566401a ER |
22931 | +++ b/gdb/testsuite/gdb.cp/namespace-nested-imports.cc |
22932 | @@ -0,0 +1,36 @@ | |
22933 | +namespace A | |
22934 | +{ | |
22935 | + namespace B | |
22936 | + { | |
22937 | + int ab = 11; | |
3a58abaf AM |
22938 | + } |
22939 | +} | |
3a58abaf | 22940 | + |
7566401a ER |
22941 | +namespace C |
22942 | +{ | |
22943 | + namespace D | |
22944 | + { | |
22945 | + using namespace A::B; | |
3a58abaf | 22946 | + |
7566401a ER |
22947 | + int |
22948 | + second() | |
22949 | + { | |
22950 | + ab; | |
22951 | + return 0; | |
22952 | + } | |
3a58abaf | 22953 | + } |
3a58abaf | 22954 | + |
7566401a ER |
22955 | + int |
22956 | + first() | |
22957 | + { | |
22958 | + //ab; | |
22959 | + return D::second(); | |
3a58abaf AM |
22960 | + } |
22961 | +} | |
3a58abaf | 22962 | + |
7566401a ER |
22963 | +int |
22964 | +main() | |
3a58abaf | 22965 | +{ |
7566401a ER |
22966 | + //ab; |
22967 | + return C::first(); | |
3a58abaf | 22968 | +} |
7566401a ER |
22969 | diff --git a/gdb/testsuite/gdb.cp/namespace-nested-imports.exp b/gdb/testsuite/gdb.cp/namespace-nested-imports.exp |
22970 | new file mode 100644 | |
22971 | index 0000000..d279fb5 | |
22972 | --- /dev/null | |
22973 | +++ b/gdb/testsuite/gdb.cp/namespace-nested-imports.exp | |
22974 | @@ -0,0 +1,57 @@ | |
22975 | +# Copyright 2008 Free Software Foundation, Inc. | |
3a58abaf | 22976 | + |
7566401a ER |
22977 | +# This program is free software; you can redistribute it and/or modify |
22978 | +# it under the terms of the GNU General Public License as published by | |
22979 | +# the Free Software Foundation; either version 3 of the License, or | |
22980 | +# (at your option) any later version. | |
22981 | +# | |
22982 | +# This program is distributed in the hope that it will be useful, | |
22983 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22984 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22985 | +# GNU General Public License for more details. | |
22986 | +# | |
22987 | +# You should have received a copy of the GNU General Public License | |
22988 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
22989 | + | |
22990 | +if $tracelevel then { | |
22991 | + strace $tracelevel | |
3a58abaf AM |
22992 | +} |
22993 | + | |
7566401a ER |
22994 | +set prms_id 0 |
22995 | +set bug_id 0 | |
3a58abaf | 22996 | + |
7566401a ER |
22997 | +set testfile namespace-nested-imports |
22998 | +set srcfile ${testfile}.cc | |
22999 | +set binfile ${objdir}/${subdir}/${testfile} | |
23000 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
23001 | + untested "Couldn't compile test program" | |
23002 | + return -1 | |
3a58abaf AM |
23003 | +} |
23004 | + | |
7566401a | 23005 | +# Get things started. |
3a58abaf | 23006 | + |
7566401a ER |
23007 | +gdb_exit |
23008 | +gdb_start | |
23009 | +gdb_reinitialize_dir $srcdir/$subdir | |
23010 | +gdb_load ${binfile} | |
3a58abaf | 23011 | + |
7566401a ER |
23012 | +############################################ |
23013 | +if ![runto_main] then { | |
23014 | + perror "couldn't run to breakpoint main" | |
23015 | + continue | |
3a58abaf AM |
23016 | +} |
23017 | + | |
7566401a ER |
23018 | +gdb_test "print ab" "No symbol .* in current context." |
23019 | + | |
23020 | +############################################ | |
23021 | +gdb_breakpoint C::first | |
23022 | +gdb_continue_to_breakpoint "C::first" | |
23023 | + | |
23024 | +gdb_test "print ab" "No symbol .* in current context." | |
23025 | +gdb_test "print C::D::ab" "= 11" | |
23026 | + | |
23027 | +############################################ | |
23028 | +gdb_breakpoint C::D::second | |
23029 | +gdb_continue_to_breakpoint "C::D::second" | |
23030 | + | |
23031 | +gdb_test "print ab" "= 11" | |
23032 | diff --git a/gdb/testsuite/gdb.cp/namespace-no-imports.cc b/gdb/testsuite/gdb.cp/namespace-no-imports.cc | |
23033 | new file mode 100644 | |
23034 | index 0000000..d1c68ab | |
23035 | --- /dev/null | |
23036 | +++ b/gdb/testsuite/gdb.cp/namespace-no-imports.cc | |
23037 | @@ -0,0 +1,37 @@ | |
23038 | + | |
23039 | +namespace A | |
3a58abaf | 23040 | +{ |
7566401a ER |
23041 | + int _a = 11; |
23042 | + | |
23043 | + namespace B{ | |
23044 | + | |
23045 | + int ab = 22; | |
23046 | + | |
23047 | + namespace C{ | |
23048 | + | |
23049 | + int abc = 33; | |
23050 | + | |
23051 | + int second(){ | |
23052 | + return 0; | |
23053 | + } | |
23054 | + | |
23055 | + } | |
23056 | + | |
23057 | + int first(){ | |
23058 | + _a; | |
23059 | + ab; | |
23060 | + C::abc; | |
23061 | + return C::second(); | |
3a58abaf | 23062 | + } |
7566401a | 23063 | + } |
3a58abaf AM |
23064 | +} |
23065 | + | |
7566401a ER |
23066 | + |
23067 | +int | |
23068 | +main() | |
3a58abaf | 23069 | +{ |
7566401a ER |
23070 | + A::_a; |
23071 | + A::B::ab; | |
23072 | + A::B::C::abc; | |
23073 | + return A::B::first(); | |
3a58abaf | 23074 | +} |
7566401a | 23075 | diff --git a/gdb/testsuite/gdb.cp/namespace-no-imports.exp b/gdb/testsuite/gdb.cp/namespace-no-imports.exp |
3a58abaf | 23076 | new file mode 100644 |
7566401a | 23077 | index 0000000..e508103 |
3a58abaf | 23078 | --- /dev/null |
7566401a ER |
23079 | +++ b/gdb/testsuite/gdb.cp/namespace-no-imports.exp |
23080 | @@ -0,0 +1,76 @@ | |
3a58abaf AM |
23081 | +# Copyright 2008 Free Software Foundation, Inc. |
23082 | + | |
23083 | +# This program is free software; you can redistribute it and/or modify | |
23084 | +# it under the terms of the GNU General Public License as published by | |
23085 | +# the Free Software Foundation; either version 3 of the License, or | |
23086 | +# (at your option) any later version. | |
23087 | +# | |
23088 | +# This program is distributed in the hope that it will be useful, | |
23089 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23090 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23091 | +# GNU General Public License for more details. | |
23092 | +# | |
23093 | +# You should have received a copy of the GNU General Public License | |
23094 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
23095 | + | |
23096 | +if $tracelevel then { | |
23097 | + strace $tracelevel | |
23098 | +} | |
23099 | + | |
23100 | +set prms_id 0 | |
23101 | +set bug_id 0 | |
23102 | + | |
7566401a | 23103 | +set testfile namespace-no-imports |
3a58abaf AM |
23104 | +set srcfile ${testfile}.cc |
23105 | +set binfile ${objdir}/${subdir}/${testfile} | |
23106 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
23107 | + untested "Couldn't compile test program" | |
23108 | + return -1 | |
23109 | +} | |
23110 | + | |
23111 | +# Get things started. | |
23112 | + | |
23113 | +gdb_exit | |
23114 | +gdb_start | |
23115 | +gdb_reinitialize_dir $srcdir/$subdir | |
23116 | +gdb_load ${binfile} | |
23117 | + | |
23118 | +############################################ | |
3a58abaf AM |
23119 | +if ![runto_main] then { |
23120 | + perror "couldn't run to breakpoint main" | |
23121 | + continue | |
23122 | +} | |
23123 | + | |
7566401a ER |
23124 | +gdb_test "print A::_a" "= 11" |
23125 | +gdb_test "print A::B::ab" "= 22" | |
23126 | +gdb_test "print A::B::C::abc" "= 33" | |
3a58abaf | 23127 | + |
7566401a ER |
23128 | +gdb_test "print _a" "No symbol .* in current context." |
23129 | +gdb_test "print ab" "No symbol .* in current context." | |
23130 | +gdb_test "print abc" "No symbol .* in current context." | |
3a58abaf | 23131 | + |
7566401a ER |
23132 | +############################################ |
23133 | +gdb_breakpoint A::B::first | |
23134 | +gdb_continue_to_breakpoint "A::B::first" | |
3a58abaf | 23135 | + |
7566401a ER |
23136 | +gdb_test "print A::_a" "= 11" |
23137 | +gdb_test "print A::B::ab" "= 22" | |
23138 | +gdb_test "print A::B::C::abc" "= 33" | |
3a58abaf | 23139 | + |
7566401a ER |
23140 | +gdb_test "print _a" "= 11" |
23141 | +gdb_test "print ab" "= 22" | |
23142 | +gdb_test "print C::abc" "= 33" | |
3a58abaf | 23143 | + |
7566401a | 23144 | +gdb_test "print abc" "No symbol .* in current context." |
3a58abaf AM |
23145 | + |
23146 | +############################################ | |
7566401a ER |
23147 | +gdb_breakpoint A::B::C::second |
23148 | +gdb_continue_to_breakpoint "A::B::C::second" | |
3a58abaf | 23149 | + |
7566401a ER |
23150 | +gdb_test "print A::_a" "= 11" |
23151 | +gdb_test "print A::B::ab" "= 22" | |
23152 | +gdb_test "print A::B::C::abc" "= 33" | |
23153 | + | |
23154 | +gdb_test "print _a" "= 11" | |
23155 | +gdb_test "print ab" "= 22" | |
23156 | +gdb_test "print abc" "= 33" | |
23157 | diff --git a/gdb/testsuite/gdb.cp/namespace-recursive.cc b/gdb/testsuite/gdb.cp/namespace-recursive.cc | |
23158 | new file mode 100644 | |
23159 | index 0000000..46d4c18 | |
23160 | --- /dev/null | |
23161 | +++ b/gdb/testsuite/gdb.cp/namespace-recursive.cc | |
23162 | @@ -0,0 +1,47 @@ | |
23163 | +namespace A{ | |
23164 | + int ax = 9; | |
3a58abaf AM |
23165 | +} |
23166 | + | |
7566401a ER |
23167 | +namespace B{ |
23168 | + using namespace A; | |
23169 | +} | |
3a58abaf | 23170 | + |
7566401a ER |
23171 | +namespace C{ |
23172 | + using namespace B; | |
23173 | +} | |
3a58abaf | 23174 | + |
7566401a | 23175 | +using namespace C; |
3a58abaf | 23176 | + |
7566401a ER |
23177 | +//--------------- |
23178 | +namespace D{ | |
23179 | + using namespace D; | |
23180 | + int dx = 99; | |
23181 | +} | |
23182 | +using namespace D; | |
3a58abaf | 23183 | + |
7566401a ER |
23184 | +//--------------- |
23185 | +namespace{ | |
23186 | + namespace{ | |
23187 | + int xx = 999; | |
23188 | + } | |
23189 | +} | |
3a58abaf | 23190 | + |
7566401a ER |
23191 | +//--------------- |
23192 | +namespace E{ | |
23193 | + int ex = 9999; | |
23194 | +} | |
3a58abaf | 23195 | + |
7566401a ER |
23196 | +namespace F{ |
23197 | + namespace FE = E; | |
3a58abaf AM |
23198 | +} |
23199 | + | |
7566401a ER |
23200 | +namespace G{ |
23201 | + namespace GF = F; | |
23202 | +} | |
3a58abaf | 23203 | + |
7566401a ER |
23204 | +//---------------- |
23205 | +int main(){ | |
23206 | + using namespace D; | |
23207 | + namespace GX = G; | |
23208 | + return ax + dx + xx + G::GF::FE::ex; | |
23209 | +} | |
23210 | diff --git a/gdb/testsuite/gdb.cp/namespace-recursive.exp b/gdb/testsuite/gdb.cp/namespace-recursive.exp | |
23211 | new file mode 100644 | |
23212 | index 0000000..5543757 | |
23213 | --- /dev/null | |
23214 | +++ b/gdb/testsuite/gdb.cp/namespace-recursive.exp | |
23215 | @@ -0,0 +1,75 @@ | |
23216 | +# Copyright 2008 Free Software Foundation, Inc. | |
23217 | + | |
23218 | +# This program is free software; you can redistribute it and/or modify | |
23219 | +# it under the terms of the GNU General Public License as published by | |
23220 | +# the Free Software Foundation; either version 3 of the License, or | |
23221 | +# (at your option) any later version. | |
23222 | +# | |
23223 | +# This program is distributed in the hope that it will be useful, | |
23224 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23225 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23226 | +# GNU General Public License for more details. | |
23227 | +# | |
23228 | +# You should have received a copy of the GNU General Public License | |
23229 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 23230 | + |
7566401a ER |
23231 | +if $tracelevel then { |
23232 | + strace $tracelevel | |
23233 | +} | |
3a58abaf | 23234 | + |
7566401a ER |
23235 | +set prms_id 0 |
23236 | +set bug_id 0 | |
3a58abaf | 23237 | + |
7566401a ER |
23238 | +set testfile namespace-recursive |
23239 | +set srcfile ${testfile}.cc | |
23240 | +set binfile ${objdir}/${subdir}/${testfile} | |
23241 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
23242 | + untested "Couldn't compile test program" | |
23243 | + return -1 | |
3a58abaf AM |
23244 | +} |
23245 | + | |
7566401a ER |
23246 | +if [get_compiler_info ${binfile}] { |
23247 | + return -1; | |
23248 | +} | |
3a58abaf | 23249 | + |
7566401a ER |
23250 | + |
23251 | +# Get things started. | |
3a58abaf AM |
23252 | + |
23253 | +gdb_exit | |
23254 | +gdb_start | |
23255 | +gdb_reinitialize_dir $srcdir/$subdir | |
23256 | +gdb_load ${binfile} | |
23257 | + | |
7566401a ER |
23258 | +if ![runto_main] then { |
23259 | + perror "couldn't run to breakpoint main" | |
3a58abaf AM |
23260 | + continue |
23261 | +} | |
23262 | + | |
7566401a ER |
23263 | +############################################ |
23264 | +# test printing from namespace imported into | |
23265 | +# imported namespace | |
23266 | + | |
23267 | +gdb_test "print ax" "= 9" | |
3a58abaf AM |
23268 | + |
23269 | +############################################ | |
7566401a ER |
23270 | +# test that gdb can print without falling |
23271 | +# into search loop | |
3a58abaf | 23272 | + |
7566401a | 23273 | +gdb_test "print dx" "= 99" |
3a58abaf | 23274 | + |
7566401a ER |
23275 | +############################################ |
23276 | +# test printing from namespace imported into | |
23277 | +# imported namespace where imports are implicit | |
23278 | +# anonymous namespace imports. | |
23279 | + | |
23280 | +gdb_test "print xx" "= 999" | |
3a58abaf AM |
23281 | + |
23282 | +############################################ | |
7566401a ER |
23283 | +# Test printing using recursive namespace |
23284 | +# aliases. | |
3a58abaf | 23285 | + |
7566401a ER |
23286 | +setup_kfail "gdb/10541" "*-*-*" |
23287 | +gdb_test "ptype G::GF" "= namespace F" | |
3a58abaf | 23288 | + |
7566401a ER |
23289 | +setup_kfail "gdb/10541" "*-*-*" |
23290 | +gdb_test "print G::GF::FE::ex" "= 9999" | |
ab050a48 BZ |
23291 | diff --git a/gdb/testsuite/gdb.cp/namespace-stress-declarations.cc b/gdb/testsuite/gdb.cp/namespace-stress-declarations.cc |
23292 | new file mode 100644 | |
23293 | index 0000000..173e49b | |
23294 | --- /dev/null | |
23295 | +++ b/gdb/testsuite/gdb.cp/namespace-stress-declarations.cc | |
23296 | @@ -0,0 +1,93 @@ | |
23297 | +int a; | |
23298 | +int b; | |
23299 | +int c; | |
23300 | +int d; | |
23301 | +int e; | |
23302 | +int f; | |
23303 | +int g; | |
23304 | +int h; | |
23305 | +int i; | |
23306 | +int j; | |
23307 | +int k; | |
23308 | +int l; | |
23309 | +int m; | |
23310 | +int n; | |
23311 | +int o; | |
23312 | +int p; | |
23313 | +int q; | |
23314 | +int r; | |
23315 | +int s; | |
23316 | +int t; | |
23317 | +int u; | |
23318 | +int v; | |
23319 | +int w; | |
23320 | +int x; | |
23321 | +int y; | |
23322 | +int z; | |
23323 | + | |
23324 | +namespace A | |
23325 | +{ | |
23326 | + int xyz; | |
23327 | + | |
23328 | + using ::a; | |
23329 | + using ::b; | |
23330 | + using ::c; | |
23331 | + using ::d; | |
23332 | + using ::e; | |
23333 | + using ::f; | |
23334 | + using ::g; | |
23335 | + using ::h; | |
23336 | + using ::i; | |
23337 | + using ::j; | |
23338 | + using ::k; | |
23339 | + using ::l; | |
23340 | + using ::m; | |
23341 | + using ::n; | |
23342 | + using ::o; | |
23343 | + using ::p; | |
23344 | + using ::q; | |
23345 | + using ::r; | |
23346 | + using ::s; | |
23347 | + using ::t; | |
23348 | + using ::u; | |
23349 | + using ::v; | |
23350 | + using ::w; | |
23351 | + using ::x; | |
23352 | + using ::y; | |
23353 | + using ::z; | |
23354 | + | |
23355 | +} | |
23356 | + | |
23357 | +using A::a; | |
23358 | +using A::b; | |
23359 | +using A::c; | |
23360 | +using A::d; | |
23361 | +using A::e; | |
23362 | +using A::f; | |
23363 | +using A::g; | |
23364 | +using A::h; | |
23365 | +using A::i; | |
23366 | +using A::j; | |
23367 | +using A::k; | |
23368 | +using A::l; | |
23369 | +using A::m; | |
23370 | +using A::n; | |
23371 | +using A::o; | |
23372 | +using A::p; | |
23373 | +using A::q; | |
23374 | +using A::r; | |
23375 | +using A::s; | |
23376 | +using A::t; | |
23377 | +using A::u; | |
23378 | +using A::v; | |
23379 | +using A::w; | |
23380 | +using A::x; | |
23381 | +using A::y; | |
23382 | +using A::z; | |
23383 | + | |
23384 | +using namespace A; | |
23385 | + | |
23386 | +int main () | |
23387 | +{ | |
23388 | + return 0; | |
23389 | +} | |
23390 | \ No newline at end of file | |
23391 | diff --git a/gdb/testsuite/gdb.cp/namespace-stress-declarations.exp b/gdb/testsuite/gdb.cp/namespace-stress-declarations.exp | |
23392 | new file mode 100644 | |
23393 | index 0000000..f22a14e | |
23394 | --- /dev/null | |
23395 | +++ b/gdb/testsuite/gdb.cp/namespace-stress-declarations.exp | |
23396 | @@ -0,0 +1,50 @@ | |
23397 | +# Copyright 2008 Free Software Foundation, Inc. | |
23398 | + | |
23399 | +# This program is free software; you can redistribute it and/or modify | |
23400 | +# it under the terms of the GNU General Public License as published by | |
23401 | +# the Free Software Foundation; either version 3 of the License, or | |
23402 | +# (at your option) any later version. | |
23403 | +# | |
23404 | +# This program is distributed in the hope that it will be useful, | |
23405 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23406 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23407 | +# GNU General Public License for more details. | |
23408 | +# | |
23409 | +# You should have received a copy of the GNU General Public License | |
23410 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
23411 | + | |
23412 | +if $tracelevel then { | |
23413 | + strace $tracelevel | |
23414 | +} | |
23415 | + | |
23416 | +set prms_id 0 | |
23417 | +set bug_id 0 | |
23418 | + | |
23419 | +set testfile namespace-stress-declarations | |
23420 | +set srcfile ${testfile}.cc | |
23421 | +set binfile ${objdir}/${subdir}/${testfile} | |
23422 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
23423 | + untested "Couldn't compile test program" | |
23424 | + return -1 | |
23425 | +} | |
23426 | + | |
23427 | +if [get_compiler_info ${binfile}] { | |
23428 | + return -1; | |
23429 | +} | |
23430 | + | |
23431 | +# Get things started. | |
23432 | + | |
23433 | +gdb_exit | |
23434 | +gdb_start | |
23435 | +gdb_reinitialize_dir $srcdir/$subdir | |
23436 | +gdb_load ${binfile} | |
23437 | + | |
23438 | +if ![runto_main] then { | |
23439 | + perror "couldn't run to breakpoint main" | |
23440 | + continue | |
23441 | +} | |
23442 | + | |
23443 | +############################################ | |
23444 | +# Test that the search can fail efficiently | |
23445 | + | |
23446 | +gdb_test "print fakex" "No symbol \"fakex\" in current context." | |
7566401a ER |
23447 | diff --git a/gdb/testsuite/gdb.cp/namespace-stress.cc b/gdb/testsuite/gdb.cp/namespace-stress.cc |
23448 | new file mode 100644 | |
23449 | index 0000000..f34083e | |
23450 | --- /dev/null | |
23451 | +++ b/gdb/testsuite/gdb.cp/namespace-stress.cc | |
23452 | @@ -0,0 +1,60 @@ | |
23453 | + | |
23454 | +namespace A{ int x; } | |
23455 | +namespace B{ int x; } | |
23456 | +namespace C{ int x; } | |
23457 | +namespace D{ int x; } | |
23458 | +namespace E{ int x; } | |
23459 | +namespace F{ int x; } | |
23460 | +namespace G{ int x; } | |
23461 | +namespace H{ int x; } | |
23462 | +namespace I{ int x; } | |
23463 | +namespace J{ int x; } | |
23464 | +namespace K{ int x; } | |
23465 | +namespace L{ int x; } | |
23466 | +namespace M{ int x; } | |
23467 | +namespace N{ int x; } | |
23468 | +namespace O{ int x; } | |
23469 | +namespace P{ int x; } | |
23470 | +namespace Q{ int x; } | |
23471 | +namespace R{ int x; } | |
23472 | +namespace S{ int x; } | |
23473 | +namespace T{ int x; } | |
23474 | +namespace U{ int x; } | |
23475 | +namespace V{ int x; } | |
23476 | +namespace W{ int x; } | |
23477 | +namespace X{ int x; } | |
23478 | +namespace Y{ int x; } | |
23479 | +namespace Z{ int x; } | |
23480 | + | |
23481 | + | |
23482 | +int main(){ | |
3a58abaf | 23483 | + |
7566401a ER |
23484 | + using namespace A; |
23485 | + using namespace B; | |
23486 | + using namespace C; | |
23487 | + using namespace D; | |
23488 | + using namespace E; | |
23489 | + using namespace F; | |
23490 | + using namespace G; | |
23491 | + using namespace H; | |
23492 | + using namespace I; | |
23493 | + using namespace J; | |
23494 | + using namespace K; | |
23495 | + using namespace L; | |
23496 | + using namespace M; | |
23497 | + using namespace N; | |
23498 | + using namespace O; | |
23499 | + using namespace P; | |
23500 | + using namespace Q; | |
23501 | + using namespace R; | |
23502 | + using namespace S; | |
23503 | + using namespace T; | |
23504 | + using namespace U; | |
23505 | + using namespace V; | |
23506 | + using namespace W; | |
23507 | + using namespace X; | |
23508 | + using namespace Y; | |
23509 | + using namespace Z; | |
3a58abaf | 23510 | + |
7566401a | 23511 | + return 0; |
3a58abaf | 23512 | +} |
7566401a ER |
23513 | \ No newline at end of file |
23514 | diff --git a/gdb/testsuite/gdb.cp/namespace-stress.exp b/gdb/testsuite/gdb.cp/namespace-stress.exp | |
23515 | new file mode 100644 | |
23516 | index 0000000..1806523 | |
23517 | --- /dev/null | |
23518 | +++ b/gdb/testsuite/gdb.cp/namespace-stress.exp | |
23519 | @@ -0,0 +1,50 @@ | |
23520 | +# Copyright 2008 Free Software Foundation, Inc. | |
3a58abaf | 23521 | + |
7566401a ER |
23522 | +# This program is free software; you can redistribute it and/or modify |
23523 | +# it under the terms of the GNU General Public License as published by | |
23524 | +# the Free Software Foundation; either version 3 of the License, or | |
23525 | +# (at your option) any later version. | |
23526 | +# | |
23527 | +# This program is distributed in the hope that it will be useful, | |
23528 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23529 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23530 | +# GNU General Public License for more details. | |
23531 | +# | |
23532 | +# You should have received a copy of the GNU General Public License | |
23533 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 23534 | + |
7566401a ER |
23535 | +if $tracelevel then { |
23536 | + strace $tracelevel | |
23537 | +} | |
3a58abaf | 23538 | + |
7566401a ER |
23539 | +set prms_id 0 |
23540 | +set bug_id 0 | |
3a58abaf | 23541 | + |
7566401a ER |
23542 | +set testfile namespace-stress |
23543 | +set srcfile ${testfile}.cc | |
23544 | +set binfile ${objdir}/${subdir}/${testfile} | |
23545 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
23546 | + untested "Couldn't compile test program" | |
23547 | + return -1 | |
23548 | +} | |
23549 | + | |
23550 | +if [get_compiler_info ${binfile}] { | |
23551 | + return -1; | |
23552 | +} | |
23553 | + | |
23554 | +# Get things started. | |
23555 | + | |
23556 | +gdb_exit | |
23557 | +gdb_start | |
23558 | +gdb_reinitialize_dir $srcdir/$subdir | |
23559 | +gdb_load ${binfile} | |
3a58abaf AM |
23560 | + |
23561 | +if ![runto_main] then { | |
23562 | + perror "couldn't run to breakpoint main" | |
23563 | + continue | |
23564 | +} | |
23565 | + | |
7566401a ER |
23566 | +############################################ |
23567 | +# Test that the search can fail efficiently | |
3a58abaf | 23568 | + |
7566401a ER |
23569 | +gdb_test "print y" "No symbol \"y\" in current context." |
23570 | diff --git a/gdb/testsuite/gdb.cp/namespace-using.cc b/gdb/testsuite/gdb.cp/namespace-using.cc | |
23571 | index 4786fd5..8ff5622 100644 | |
23572 | --- a/gdb/testsuite/gdb.cp/namespace-using.cc | |
23573 | +++ b/gdb/testsuite/gdb.cp/namespace-using.cc | |
23574 | @@ -1,26 +1,129 @@ | |
23575 | +namespace M | |
23576 | +{ | |
23577 | + int x = 911; | |
23578 | +} | |
3a58abaf | 23579 | + |
7566401a ER |
23580 | +namespace N |
23581 | +{ | |
23582 | + int x = 912; | |
23583 | +} | |
3a58abaf | 23584 | + |
7566401a ER |
23585 | +int marker10 () |
23586 | +{ | |
23587 | + using namespace M; | |
23588 | + int y = x + 1; // marker10 stop | |
23589 | + using namespace N; | |
23590 | + return y; | |
23591 | +} | |
3a58abaf | 23592 | + |
7566401a ER |
23593 | +namespace J |
23594 | +{ | |
23595 | + int jx = 44; | |
23596 | +} | |
3a58abaf | 23597 | + |
7566401a ER |
23598 | +namespace K |
23599 | +{ | |
23600 | + int | |
23601 | + marker9 () | |
23602 | + { | |
23603 | + //x; | |
23604 | + return marker10 (); | |
23605 | + } | |
23606 | +} | |
3a58abaf | 23607 | + |
7566401a ER |
23608 | +namespace L |
23609 | +{ | |
23610 | + using namespace J; | |
23611 | + int | |
23612 | + marker8 () | |
23613 | + { | |
23614 | + jx; | |
23615 | + return K::marker9 (); | |
23616 | + } | |
23617 | +} | |
3a58abaf | 23618 | + |
7566401a | 23619 | +namespace G |
3a58abaf | 23620 | +{ |
7566401a ER |
23621 | + namespace H |
23622 | + { | |
23623 | + int ghx = 6; | |
23624 | + } | |
3a58abaf AM |
23625 | +} |
23626 | + | |
7566401a ER |
23627 | +namespace I |
23628 | +{ | |
23629 | + int | |
23630 | + marker7 () | |
23631 | + { | |
23632 | + using namespace G::H; | |
23633 | + ghx; | |
23634 | + return L::marker8 (); | |
23635 | + } | |
23636 | +} | |
3a58abaf | 23637 | + |
7566401a | 23638 | +namespace E |
3a58abaf | 23639 | +{ |
7566401a ER |
23640 | + namespace F |
23641 | + { | |
23642 | + int efx = 5; | |
23643 | + } | |
3a58abaf AM |
23644 | +} |
23645 | + | |
7566401a | 23646 | +using namespace E::F; |
3a58abaf | 23647 | +int |
7566401a | 23648 | +marker6 () |
3a58abaf | 23649 | +{ |
7566401a ER |
23650 | + efx; |
23651 | + return I::marker7 (); | |
3a58abaf | 23652 | +} |
3a58abaf | 23653 | + |
7566401a ER |
23654 | namespace A |
23655 | { | |
23656 | int _a = 1; | |
23657 | int x = 2; | |
23658 | } | |
23659 | ||
23660 | -int marker4(){ | |
23661 | - using A::x; | |
23662 | - return 0; | |
23663 | +namespace C | |
23664 | +{ | |
23665 | + int cc = 3; | |
23666 | +} | |
3a58abaf | 23667 | + |
7566401a ER |
23668 | +namespace D |
23669 | +{ | |
23670 | + int dx = 4; | |
23671 | +} | |
3a58abaf | 23672 | + |
7566401a ER |
23673 | +using namespace C; |
23674 | +int | |
23675 | +marker5 () | |
23676 | +{ | |
23677 | + cc; | |
23678 | + return marker6 (); | |
3a58abaf AM |
23679 | +} |
23680 | + | |
7566401a ER |
23681 | +int |
23682 | +marker4 () | |
23683 | +{ | |
23684 | + using D::dx; | |
23685 | + return marker5 (); | |
23686 | } | |
23687 | ||
23688 | -int marker3(){ | |
23689 | - return marker4(); | |
23690 | +int | |
23691 | +marker3 () | |
23692 | +{ | |
23693 | + return marker4 (); | |
23694 | } | |
23695 | ||
23696 | -int marker2() | |
23697 | +int | |
23698 | +marker2 () | |
23699 | { | |
23700 | namespace B = A; | |
23701 | B::_a; | |
23702 | - return marker3(); | |
23703 | + return marker3 (); | |
23704 | } | |
23705 | ||
23706 | -int marker1() | |
23707 | +int | |
23708 | +marker1 () | |
23709 | { | |
23710 | int total = 0; | |
23711 | { | |
23712 | @@ -29,17 +132,18 @@ int marker1() | |
23713 | using namespace A; | |
23714 | int c = 2; | |
23715 | { | |
23716 | - int d = 3; | |
23717 | - total = _a + b + c + d + marker2(); // marker1 stop | |
23718 | + int d = 3; | |
23719 | + total = _a + b + c + d + marker2 (); // marker1 stop | |
23720 | } | |
23721 | } | |
23722 | } | |
23723 | return total; | |
23724 | } | |
23725 | ||
23726 | -int main() | |
23727 | +int | |
23728 | +main () | |
23729 | { | |
23730 | using namespace A; | |
23731 | _a; | |
23732 | - return marker1(); | |
23733 | + return marker1 (); | |
23734 | } | |
23735 | diff --git a/gdb/testsuite/gdb.cp/namespace-using.exp b/gdb/testsuite/gdb.cp/namespace-using.exp | |
23736 | index f24973f..fc23115 100644 | |
23737 | --- a/gdb/testsuite/gdb.cp/namespace-using.exp | |
23738 | +++ b/gdb/testsuite/gdb.cp/namespace-using.exp | |
23739 | @@ -28,6 +28,11 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb | |
23740 | return -1 | |
23741 | } | |
23742 | ||
3a58abaf | 23743 | +if [get_compiler_info ${binfile}] { |
7566401a | 23744 | + return -1; |
3a58abaf AM |
23745 | +} |
23746 | + | |
3a58abaf | 23747 | + |
7566401a ER |
23748 | # Get things started. |
23749 | ||
23750 | gdb_exit | |
23751 | @@ -46,42 +51,155 @@ if ![runto_main] then { | |
23752 | ||
23753 | gdb_test "print _a" "= 1" | |
23754 | ||
23755 | +# Test that names are not printed when they | |
23756 | +# are not imported | |
3a58abaf | 23757 | + |
7566401a ER |
23758 | +gdb_breakpoint marker3 |
23759 | +gdb_continue_to_breakpoint "marker3" | |
3a58abaf | 23760 | + |
7566401a ER |
23761 | +#send_gdb "break marker3\n" |
23762 | +#send_gdb "continue\n" | |
3a58abaf | 23763 | + |
7566401a | 23764 | +gdb_test "print _a" "No symbol \"_a\" in current context." "Print _a without import" |
3a58abaf AM |
23765 | + |
23766 | +gdb_exit | |
23767 | +gdb_start | |
23768 | +gdb_reinitialize_dir $srcdir/$subdir | |
23769 | +gdb_load ${binfile} | |
23770 | + | |
3a58abaf | 23771 | + |
7566401a ER |
23772 | ############################################ |
23773 | # test printing of namespace imported into | |
23774 | # a scope containing the pc. | |
23775 | ||
23776 | +if ![runto_main] then { | |
23777 | + perror "couldn't run to breakpoint main" | |
23778 | + continue | |
23779 | +} | |
d566d21e | 23780 | + |
7566401a ER |
23781 | gdb_breakpoint [gdb_get_line_number "marker1 stop"] |
23782 | gdb_continue_to_breakpoint "marker1 stop" | |
23783 | ||
23784 | gdb_test "print _a" "= 1" "print _a in a nested scope" | |
d566d21e | 23785 | |
3a58abaf | 23786 | + |
7566401a ER |
23787 | +gdb_exit |
23788 | +gdb_start | |
23789 | +gdb_reinitialize_dir $srcdir/$subdir | |
23790 | +gdb_load ${binfile} | |
3a58abaf | 23791 | + |
7566401a ER |
23792 | +############################################ |
23793 | +# test printing of namespace imported into | |
23794 | +# file scope. | |
3a58abaf | 23795 | + |
3a58abaf | 23796 | + |
7566401a ER |
23797 | +if ![runto marker5] then { |
23798 | + perror "couldn't run to breakpoint marker5" | |
23799 | + continue | |
3a58abaf AM |
23800 | +} |
23801 | + | |
7566401a ER |
23802 | +gdb_test "print cc" "= 3" |
23803 | + | |
3a58abaf AM |
23804 | +gdb_exit |
23805 | +gdb_start | |
23806 | +gdb_reinitialize_dir $srcdir/$subdir | |
23807 | +gdb_load ${binfile} | |
23808 | + | |
7566401a ER |
23809 | + |
23810 | ############################################ | |
23811 | # Test printing of namespace aliases | |
23812 | ||
23813 | -setup_kfail "gdb/7935" "*-*-*" | |
23814 | if ![runto marker2] then { | |
23815 | perror "couldn't run to breakpoint marker2" | |
23816 | continue | |
23817 | } | |
23818 | ||
23819 | -gdb_test "print B::a" "= 1" | |
23820 | +gdb_test "print B::_a" "= 1" | |
23821 | + | |
23822 | +gdb_test "print _a" "No symbol \"_a\" in current context." "print _a in namespace alias scope" | |
23823 | +gdb_test "print x" "No symbol \"x\" in current context." "print x in namespace alias scope" | |
23824 | + | |
23825 | +gdb_exit | |
23826 | +gdb_start | |
23827 | +gdb_reinitialize_dir $srcdir/$subdir | |
23828 | +gdb_load ${binfile} | |
23829 | + | |
23830 | ||
23831 | ############################################ | |
23832 | # Test that names are not printed when they | |
23833 | # are not imported | |
23834 | ||
23835 | -gdb_breakpoint "marker3" | |
23836 | -gdb_continue_to_breakpoint "marker3" | |
23837 | +if {![runto marker3]} { | |
23838 | + perror "couldn't run to breakpoint marker3" | |
23839 | +} | |
23840 | ||
23841 | -gdb_test "print _a" "No symbol \"_a\" in current context." "Print a without import" | |
23842 | +# gcc-4-3 puts import statements for aliases in | |
23843 | +# the global scope instead of the corresponding | |
23844 | +# function scope. These wrong import statements throw | |
23845 | +# this test off. This is fixed in gcc-4-4. | |
23846 | +if [test_compiler_info gcc-4-3-*] then { setup_xfail *-*-* } | |
23847 | + | |
23848 | +gdb_test "print _a" "No symbol \"_a\" in current context." "Print _a without import" | |
23849 | ||
23850 | ############################################ | |
23851 | # Test printing of individually imported elements | |
23852 | ||
23853 | -setup_kfail "gdb/7936" "*-*-*" | |
23854 | if ![runto marker4] then { | |
23855 | perror "couldn't run to breakpoint marker4" | |
23856 | continue | |
23857 | } | |
23858 | ||
23859 | -gdb_test "print x" "= 2" | |
23860 | +gdb_test "print dx" "= 4" | |
23861 | + | |
23862 | +############################################ | |
23863 | +# Test printing of namespace aliases | |
23864 | + | |
23865 | +if ![runto marker5] then { | |
23866 | + perror "couldn't run to marker5" | |
3a58abaf AM |
23867 | + continue |
23868 | +} | |
23869 | + | |
7566401a | 23870 | +gdb_test "print efx" "= 5" |
3a58abaf | 23871 | + |
7566401a ER |
23872 | +############################################ |
23873 | +# Test printing of variables imported from | |
23874 | +# nested namespaces | |
3a58abaf | 23875 | + |
7566401a ER |
23876 | +if ![runto I::marker7] then { |
23877 | + perror "couldn't run to breakpoint I::marker7" | |
23878 | + continue | |
23879 | +} | |
3a58abaf | 23880 | + |
7566401a | 23881 | +gdb_test "print ghx" "= 6" |
3a58abaf | 23882 | + |
7566401a ER |
23883 | +############################################ |
23884 | +# Test that variables are not printed in a namespace | |
23885 | +# that is sibling to the namespace containing an import | |
3a58abaf | 23886 | + |
7566401a ER |
23887 | +if ![runto L::marker8] then { |
23888 | + perror "couldn't run to breakpoint L::marker8" | |
23889 | + continue | |
23890 | +} | |
3a58abaf | 23891 | + |
7566401a | 23892 | +gdb_test "print jx" "= 44" |
3a58abaf | 23893 | + |
7566401a ER |
23894 | +gdb_breakpoint "K::marker9" |
23895 | +gdb_continue_to_breakpoint "K::marker9" | |
3a58abaf | 23896 | + |
7566401a | 23897 | +gdb_test "print jx" "No symbol \"jx\" in current context." |
3a58abaf | 23898 | + |
7566401a ER |
23899 | +############################################ |
23900 | +# Test that variables are only printed after the line | |
23901 | +# containing the import | |
3a58abaf | 23902 | + |
7566401a ER |
23903 | +if ![runto_main] then { |
23904 | + perror "couldn't run to breakpoint main" | |
23905 | + continue | |
23906 | +} | |
3a58abaf | 23907 | + |
7566401a ER |
23908 | +gdb_breakpoint [gdb_get_line_number "marker10 stop"] |
23909 | +gdb_continue_to_breakpoint "marker10 stop" | |
3a58abaf | 23910 | + |
7566401a ER |
23911 | +# Assert that M::x is printed and not N::x |
23912 | +gdb_test "print x" "= 911" "print x (from M::x)" | |
3a58abaf | 23913 | + |
7566401a ER |
23914 | diff --git a/gdb/testsuite/gdb.cp/namespace.exp b/gdb/testsuite/gdb.cp/namespace.exp |
23915 | index 76b1b82..2042db2 100644 | |
23916 | --- a/gdb/testsuite/gdb.cp/namespace.exp | |
23917 | +++ b/gdb/testsuite/gdb.cp/namespace.exp | |
23918 | @@ -24,6 +24,7 @@ | |
23919 | # for namespaces. | |
23920 | # Note: As of 2000-06-03, they passed under g++ - djb | |
23921 | ||
23922 | +load_lib "cp-support.exp" | |
23923 | ||
23924 | if $tracelevel then { | |
23925 | strace $tracelevel | |
23926 | @@ -259,11 +260,16 @@ gdb_test "ptype E" "type = namespace C::D::E" | |
23927 | gdb_test "ptype CClass" "type = (class C::CClass \{\r\n public:|struct C::CClass \{)\r\n int x;\r\n\}" | |
23928 | gdb_test "ptype CClass::NestedClass" "type = (class C::CClass::NestedClass \{\r\n public:|struct C::CClass::NestedClass \{)\r\n int y;\r\n\}" | |
23929 | gdb_test "ptype NestedClass" "No symbol \"NestedClass\" in current context." | |
23930 | -setup_kfail "gdb/1448" "*-*-*" | |
23931 | -gdb_test "ptype ::C::CClass" "type = class C::CClass \{\r\n public:\r\n int x;\r\n\}" | |
23932 | -setup_kfail "gdb/1448" "*-*-*" | |
23933 | -gdb_test "ptype ::C::CClass::NestedClass" "type = class C::CClass::NestedClass \{\r\n public:\r\n int y;\r\n\}" | |
23934 | -setup_kfail "gdb/1448" "*-*-*" | |
23935 | +cp_test_ptype_class \ | |
23936 | + "ptype ::C::CClass" "" "class" "C::CClass" \ | |
23937 | + { | |
23938 | + { field public "int x;" } | |
23939 | + } | |
23940 | +cp_test_ptype_class \ | |
23941 | + "ptype ::C::CClass::NestedClass" "" "class" "C::CClass::NestedClass" \ | |
23942 | + { | |
23943 | + { field public "int y;" } | |
23944 | + } | |
23945 | gdb_test "ptype ::C::NestedClass" "No symbol \"NestedClass\" in namespace \"C\"." | |
23946 | gdb_test "ptype C::CClass" "No symbol \"CClass\" in namespace \"C::C\"." | |
23947 | gdb_test "ptype C::CClass::NestedClass" "No type \"CClass\" within class or namespace \"C::C\"." | |
23948 | @@ -273,8 +279,11 @@ gdb_test "ptype C::NestedClass" "No symbol \"NestedClass\" in namespace \"C::C\" | |
23949 | ||
23950 | gdb_test "print cOtherFile" "\\$\[0-9\].* = 316" | |
23951 | gdb_test "ptype OtherFileClass" "type = (class C::OtherFileClass \{\r\n public:|struct C::OtherFileClass \{)\r\n int z;\r\n\}" | |
23952 | -setup_kfail "gdb/1448" "*-*-*" | |
23953 | -gdb_test "ptype ::C::OtherFileClass" "type = class C::OtherFileClass \{\r\n public:\r\n int z;\r\n\}" | |
23954 | +cp_test_ptype_class \ | |
23955 | + "ptype ::C::OtherFileClass" "" "class" "C::OtherFileClass" \ | |
23956 | + { | |
23957 | + { field public "int z;" } | |
23958 | + } | |
23959 | gdb_test "ptype C::OtherFileClass" "No symbol \"OtherFileClass\" in namespace \"C::C\"." | |
23960 | ||
23961 | # Some anonymous namespace tests. | |
23962 | diff --git a/gdb/testsuite/gdb.cp/overload.exp b/gdb/testsuite/gdb.cp/overload.exp | |
23963 | index 24025a2..a72932e 100644 | |
23964 | --- a/gdb/testsuite/gdb.cp/overload.exp | |
23965 | +++ b/gdb/testsuite/gdb.cp/overload.exp | |
23966 | @@ -74,12 +74,12 @@ set re_methods "${re_methods}${ws}int overload1arg\\((void|)\\);" | |
23967 | set re_methods "${re_methods}${ws}int overload1arg\\(char\\);" | |
23968 | set re_methods "${re_methods}${ws}int overload1arg\\(signed char\\);" | |
23969 | set re_methods "${re_methods}${ws}int overload1arg\\(unsigned char\\);" | |
23970 | -set re_methods "${re_methods}${ws}int overload1arg\\(short\\);" | |
23971 | -set re_methods "${re_methods}${ws}int overload1arg\\(unsigned short\\);" | |
23972 | +set re_methods "${re_methods}${ws}int overload1arg\\(short( int)?\\);" | |
23973 | +set re_methods "${re_methods}${ws}int overload1arg\\((unsigned short|short unsigned)( int)?\\);" | |
23974 | set re_methods "${re_methods}${ws}int overload1arg\\(int\\);" | |
23975 | set re_methods "${re_methods}${ws}int overload1arg\\(unsigned int\\);" | |
23976 | -set re_methods "${re_methods}${ws}int overload1arg\\(long\\);" | |
23977 | -set re_methods "${re_methods}${ws}int overload1arg\\(unsigned long\\);" | |
23978 | +set re_methods "${re_methods}${ws}int overload1arg\\(long( int)?\\);" | |
23979 | +set re_methods "${re_methods}${ws}int overload1arg\\((unsigned long|long unsigned)( int)?\\);" | |
23980 | set re_methods "${re_methods}${ws}int overload1arg\\(float\\);" | |
23981 | set re_methods "${re_methods}${ws}int overload1arg\\(double\\);" | |
23982 | set re_methods "${re_methods}${ws}int overloadfnarg\\((void|)\\);" | |
23983 | diff --git a/gdb/testsuite/gdb.cp/ovldbreak.exp b/gdb/testsuite/gdb.cp/ovldbreak.exp | |
23984 | index 8a6b795..9997a45 100644 | |
23985 | --- a/gdb/testsuite/gdb.cp/ovldbreak.exp | |
23986 | +++ b/gdb/testsuite/gdb.cp/ovldbreak.exp | |
23987 | @@ -127,10 +127,24 @@ proc set_bp_overloaded {name expectedmenu mychoice bpnumber linenumber} { | |
23988 | } | |
23989 | ||
23990 | # This is the expected menu for overload1arg. | |
23991 | -# Note the arg type variations on lines 6 and 13. | |
23992 | +# Note the arg type variations for void and integer types. | |
23993 | # This accommodates different versions of g++. | |
23994 | ||
23995 | -set menu_overload1arg "\\\[0\\\] cancel\r\n\\\[1\\\] all\r\n\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n\\\[4\\\] foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r\n\\\[5\\\] foo::overload1arg\\(long\\) at.*$srcfile:118\r\n\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n\\\[8\\\] foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r\n\\\[9\\\] foo::overload1arg\\(short\\) at.*$srcfile:114\r\n\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n> $" | |
23996 | +set menu_overload1arg "\\\[0\\\] cancel\r\n" | |
23997 | +append menu_overload1arg "\\\[1\\\] all\r\n" | |
23998 | +append menu_overload1arg "\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n" | |
23999 | +append menu_overload1arg "\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n" | |
24000 | +append menu_overload1arg "\\\[4\\\] foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r\n" | |
24001 | +append menu_overload1arg "\\\[5\\\] foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r\n" | |
24002 | +append menu_overload1arg "\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n" | |
24003 | +append menu_overload1arg "\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n" | |
24004 | +append menu_overload1arg "\\\[8\\\] foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r\n" | |
24005 | +append menu_overload1arg "\\\[9\\\] foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r\n" | |
24006 | +append menu_overload1arg "\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n" | |
24007 | +append menu_overload1arg "\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n" | |
24008 | +append menu_overload1arg "\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n" | |
24009 | +append menu_overload1arg "\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n" | |
24010 | +append menu_overload1arg "> $" | |
24011 | ||
24012 | # Set multiple-symbols to "ask", to allow us to test the use | |
24013 | # of the multiple-choice menu when breaking on an overloaded method. | |
24014 | @@ -157,17 +171,17 @@ set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 13 13 110 | |
24015 | ||
24016 | gdb_test "info break" \ | |
24017 | "Num Type\[\t \]+Disp Enb Address\[\t \]+What.* | |
24018 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r | |
24019 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in main(\\((|void)\\))? at.*$srcfile:49\r | |
24020 | \[\t \]+breakpoint already hit 1 time\r | |
24021 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r | |
24022 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r | |
24023 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r | |
24024 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r | |
24025 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r | |
24026 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r | |
24027 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r | |
24028 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r | |
24029 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r | |
24030 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r | |
24031 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r | |
24032 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r | |
24033 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r | |
24034 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r | |
24035 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r | |
24036 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \ | |
24037 | @@ -215,17 +229,17 @@ gdb_expect { | |
24038 | ||
24039 | gdb_test "info break" \ | |
24040 | "Num Type\[\t \]+Disp Enb Address\[\t \]+What.* | |
24041 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r | |
24042 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in main(\\((|void)\\))? at.*$srcfile:49\r | |
24043 | \[\t \]+breakpoint already hit 1 time\r | |
24044 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r | |
24045 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r | |
24046 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r | |
24047 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r | |
24048 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r | |
24049 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r | |
24050 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r | |
24051 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r | |
24052 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r | |
24053 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r | |
24054 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r | |
24055 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r | |
24056 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r | |
24057 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r | |
24058 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r | |
24059 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \ | |
24060 | @@ -296,12 +310,12 @@ gdb_test "info break" \ | |
24061 | "Num Type\[\t \]+Disp Enb Address\[\t \]+What.* | |
24062 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r | |
24063 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r | |
24064 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r | |
24065 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r | |
24066 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r | |
24067 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r | |
24068 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r | |
24069 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r | |
24070 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r | |
24071 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r | |
24072 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r | |
24073 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r | |
24074 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r | |
24075 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r | |
24076 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r | |
24077 | diff --git a/gdb/testsuite/gdb.cp/shadowing.cc b/gdb/testsuite/gdb.cp/shadowing.cc | |
3a58abaf | 24078 | new file mode 100644 |
7566401a | 24079 | index 0000000..6d9c2f1 |
3a58abaf | 24080 | --- /dev/null |
7566401a ER |
24081 | +++ b/gdb/testsuite/gdb.cp/shadowing.cc |
24082 | @@ -0,0 +1,48 @@ | |
24083 | +namespace A | |
24084 | +{ | |
24085 | + int x = 11; | |
24086 | +} | |
3a58abaf | 24087 | + |
7566401a ER |
24088 | +int x = 22; |
24089 | +int y = 0; | |
3a58abaf | 24090 | + |
7566401a ER |
24091 | +class B |
24092 | +{ | |
24093 | +public: | |
24094 | + int x; | |
24095 | + | |
24096 | + int | |
24097 | + func() | |
24098 | + { | |
24099 | + x = 33; | |
24100 | + y+=x; // marker1 | |
24101 | + | |
24102 | + { | |
24103 | + int x = 44; | |
24104 | + y+=x; // marker2 | |
24105 | + | |
24106 | + { | |
24107 | + int x = 55; | |
24108 | + y+=x; // marker3 | |
24109 | + | |
24110 | + { | |
24111 | + int z = x; //prevent gcc from optimizing away this scope | |
24112 | + using namespace A; | |
24113 | + y+=x; // marker4 | |
24114 | + | |
24115 | + using A::x; | |
24116 | + y+=x; // marker5 | |
24117 | + | |
24118 | + return this->x; | |
24119 | + } | |
24120 | + } | |
24121 | + } | |
24122 | + } | |
24123 | +}; | |
24124 | + | |
24125 | +int | |
24126 | +main() | |
24127 | +{ | |
24128 | + B theB; | |
24129 | + return theB.func(); | |
24130 | +} | |
24131 | diff --git a/gdb/testsuite/gdb.cp/shadowing.exp b/gdb/testsuite/gdb.cp/shadowing.exp | |
3a58abaf | 24132 | new file mode 100644 |
7566401a | 24133 | index 0000000..6922eed |
3a58abaf | 24134 | --- /dev/null |
7566401a ER |
24135 | +++ b/gdb/testsuite/gdb.cp/shadowing.exp |
24136 | @@ -0,0 +1,91 @@ | |
3a58abaf AM |
24137 | +# Copyright 2008 Free Software Foundation, Inc. |
24138 | + | |
24139 | +# This program is free software; you can redistribute it and/or modify | |
24140 | +# it under the terms of the GNU General Public License as published by | |
7566401a | 24141 | +# the Free Software Foundation; either version 3 of the License, or |
3a58abaf | 24142 | +# (at your option) any later version. |
7566401a | 24143 | +# |
3a58abaf AM |
24144 | +# This program is distributed in the hope that it will be useful, |
24145 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24146 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24147 | +# GNU General Public License for more details. | |
7566401a | 24148 | +# |
3a58abaf | 24149 | +# You should have received a copy of the GNU General Public License |
7566401a | 24150 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
3a58abaf | 24151 | + |
7566401a ER |
24152 | +if $tracelevel then { |
24153 | + strace $tracelevel | |
24154 | +} | |
3a58abaf | 24155 | + |
7566401a ER |
24156 | +set prms_id 0 |
24157 | +set bug_id 0 | |
3a58abaf | 24158 | + |
7566401a ER |
24159 | +set testfile shadowing |
24160 | +set srcfile ${testfile}.cc | |
3a58abaf | 24161 | +set binfile ${objdir}/${subdir}/${testfile} |
7566401a ER |
24162 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { |
24163 | + untested "Couldn't compile test program" | |
3a58abaf AM |
24164 | + return -1 |
24165 | +} | |
24166 | + | |
7566401a ER |
24167 | +if [get_compiler_info ${binfile}] { |
24168 | + return -1; | |
24169 | +} | |
24170 | + | |
24171 | +# Get things started. | |
24172 | + | |
3a58abaf AM |
24173 | +gdb_exit |
24174 | +gdb_start | |
24175 | +gdb_reinitialize_dir $srcdir/$subdir | |
24176 | +gdb_load ${binfile} | |
24177 | + | |
7566401a ER |
24178 | +if ![runto_main] then { |
24179 | + perror "couldn't run to breakpoint main" | |
3a58abaf AM |
24180 | + continue |
24181 | +} | |
24182 | + | |
7566401a ER |
24183 | +############################################ |
24184 | +# Test printing of class variable is not shadowed | |
24185 | +# by global variable | |
3a58abaf | 24186 | + |
7566401a ER |
24187 | +gdb_breakpoint [gdb_get_line_number "marker1"] |
24188 | +gdb_continue_to_breakpoint "marker1" | |
3a58abaf | 24189 | + |
7566401a | 24190 | +gdb_test "print x" "= 33" "Print class x shadowing global x" |
3a58abaf | 24191 | + |
7566401a ER |
24192 | + |
24193 | +############################################ | |
24194 | +# Test printing local variable is not shadowed | |
24195 | +# by class variable | |
24196 | + | |
24197 | +gdb_breakpoint [gdb_get_line_number "marker2"] | |
24198 | +gdb_continue_to_breakpoint "marker2" | |
24199 | + | |
24200 | +gdb_test "print x" "= 44" "Print local x shadowing class x" | |
24201 | + | |
24202 | +############################################ | |
24203 | +# Test inner scope x is printed not outer scope | |
24204 | + | |
24205 | +gdb_breakpoint [gdb_get_line_number "marker3"] | |
24206 | +gdb_continue_to_breakpoint "marker3" | |
24207 | + | |
24208 | +gdb_test "print x" "= 55" "Print inner scope x" | |
24209 | + | |
24210 | +############################################ | |
24211 | +# Test printing local variable is not shadowed | |
24212 | +# by namespace variable | |
24213 | + | |
24214 | +gdb_breakpoint [gdb_get_line_number "marker4"] | |
24215 | +gdb_continue_to_breakpoint "marker4" | |
24216 | + | |
24217 | +gdb_test "print x" "= 55" "Print local x not namespace x" | |
24218 | + | |
24219 | +############################################ | |
24220 | +# Test imported namespace element is printed | |
24221 | + | |
24222 | +gdb_breakpoint [gdb_get_line_number "marker5"] | |
24223 | +gdb_continue_to_breakpoint "marker5" | |
24224 | + | |
24225 | +if [test_compiler_info gcc-4-3-*] then { setup_xfail *-*-* } | |
24226 | + | |
24227 | +gdb_test "print x" "= 11" "Print imported namespace x" | |
24228 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.S b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S | |
3a58abaf | 24229 | new file mode 100644 |
7566401a | 24230 | index 0000000..d5b9ca5 |
3a58abaf | 24231 | --- /dev/null |
7566401a ER |
24232 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S |
24233 | @@ -0,0 +1,140 @@ | |
24234 | +/* This testcase is part of GDB, the GNU debugger. | |
3a58abaf | 24235 | + |
7566401a | 24236 | + Copyright 2004, 2007, 2008, 2009 Free Software Foundation, Inc. |
3a58abaf AM |
24237 | + |
24238 | + This program is free software; you can redistribute it and/or modify | |
24239 | + it under the terms of the GNU General Public License as published by | |
24240 | + the Free Software Foundation; either version 3 of the License, or | |
24241 | + (at your option) any later version. | |
24242 | + | |
24243 | + This program is distributed in the hope that it will be useful, | |
24244 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24245 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24246 | + GNU General Public License for more details. | |
24247 | + | |
24248 | + You should have received a copy of the GNU General Public License | |
24249 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
24250 | + | |
7566401a ER |
24251 | +/* Test .debug_aranges containing zero address_size. */ |
24252 | + | |
24253 | +/* Dummy function to provide debug information for. */ | |
24254 | + | |
24255 | + .text | |
24256 | +.Lbegin_text1: | |
24257 | + .globl main | |
24258 | + .type main, %function | |
24259 | +main: | |
24260 | +.Lbegin_main: | |
24261 | + .int 0 | |
24262 | +.Lend_main: | |
24263 | + .size main, .-main | |
24264 | +.Lend_text1: | |
24265 | + | |
24266 | +/* Debug information */ | |
24267 | + | |
24268 | + .section .debug_info | |
24269 | +.Lcu1_begin: | |
24270 | + /* CU header */ | |
24271 | + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ | |
24272 | +.Lcu1_start: | |
24273 | + .2byte 2 /* DWARF Version */ | |
24274 | + .4byte .Labbrev1_begin /* Offset into abbrev section */ | |
24275 | + .byte 4 /* Pointer size */ | |
24276 | + | |
24277 | + /* CU die */ | |
24278 | + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ | |
24279 | + .4byte .Lend_text1 /* DW_AT_high_pc */ | |
24280 | + .4byte .Lbegin_text1 /* DW_AT_low_pc */ | |
24281 | + .ascii "file1.txt\0" /* DW_AT_name */ | |
24282 | + .ascii "GNU C 3.3.3\0" /* DW_AT_producer */ | |
24283 | + .byte 1 /* DW_AT_language (C) */ | |
24284 | + | |
24285 | + /* main */ | |
24286 | + .uleb128 2 /* Abbrev: DW_TAG_subprogram */ | |
24287 | + .byte 1 /* DW_AT_external */ | |
24288 | + .byte 1 /* DW_AT_decl_file */ | |
24289 | + .byte 2 /* DW_AT_decl_line */ | |
24290 | + .ascii "main\0" /* DW_AT_name */ | |
24291 | + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ | |
24292 | + .4byte .Lbegin_main /* DW_AT_low_pc */ | |
24293 | + .4byte .Lend_main /* DW_AT_high_pc */ | |
24294 | + .byte 1 /* DW_AT_frame_base: length */ | |
24295 | + .byte 0x55 /* DW_AT_frame_base: DW_OP_reg5 */ | |
24296 | + | |
24297 | +.Ltype_int: | |
24298 | + .uleb128 3 /* Abbrev: DW_TAG_base_type */ | |
24299 | + .ascii "int\0" /* DW_AT_name */ | |
24300 | + .byte 4 /* DW_AT_byte_size */ | |
24301 | + .byte 5 /* DW_AT_encoding */ | |
24302 | + | |
24303 | + .byte 0 /* End of children of CU */ | |
24304 | + | |
24305 | +.Lcu1_end: | |
24306 | + | |
24307 | +/* Abbrev table */ | |
24308 | + .section .debug_abbrev | |
24309 | +.Labbrev1_begin: | |
24310 | + .uleb128 1 /* Abbrev code */ | |
24311 | + .uleb128 0x11 /* DW_TAG_compile_unit */ | |
24312 | + .byte 1 /* has_children */ | |
24313 | + .uleb128 0x12 /* DW_AT_high_pc */ | |
24314 | + .uleb128 0x1 /* DW_FORM_addr */ | |
24315 | + .uleb128 0x11 /* DW_AT_low_pc */ | |
24316 | + .uleb128 0x1 /* DW_FORM_addr */ | |
24317 | + .uleb128 0x3 /* DW_AT_name */ | |
24318 | + .uleb128 0x8 /* DW_FORM_string */ | |
24319 | + .uleb128 0x25 /* DW_AT_producer */ | |
24320 | + .uleb128 0x8 /* DW_FORM_string */ | |
24321 | + .uleb128 0x13 /* DW_AT_language */ | |
24322 | + .uleb128 0xb /* DW_FORM_data1 */ | |
24323 | + .byte 0x0 /* Terminator */ | |
24324 | + .byte 0x0 /* Terminator */ | |
24325 | + | |
24326 | + .uleb128 2 /* Abbrev code */ | |
24327 | + .uleb128 0x2e /* DW_TAG_subprogram */ | |
24328 | + .byte 0 /* has_children */ | |
24329 | + .uleb128 0x3f /* DW_AT_external */ | |
24330 | + .uleb128 0xc /* DW_FORM_flag */ | |
24331 | + .uleb128 0x3a /* DW_AT_decl_file */ | |
24332 | + .uleb128 0xb /* DW_FORM_data1 */ | |
24333 | + .uleb128 0x3b /* DW_AT_decl_line */ | |
24334 | + .uleb128 0xb /* DW_FORM_data1 */ | |
24335 | + .uleb128 0x3 /* DW_AT_name */ | |
24336 | + .uleb128 0x8 /* DW_FORM_string */ | |
24337 | + .uleb128 0x49 /* DW_AT_type */ | |
24338 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
24339 | + .uleb128 0x11 /* DW_AT_low_pc */ | |
24340 | + .uleb128 0x1 /* DW_FORM_addr */ | |
24341 | + .uleb128 0x12 /* DW_AT_high_pc */ | |
24342 | + .uleb128 0x1 /* DW_FORM_addr */ | |
24343 | + .uleb128 0x40 /* DW_AT_frame_base */ | |
24344 | + .uleb128 0xa /* DW_FORM_block1 */ | |
24345 | + .byte 0x0 /* Terminator */ | |
24346 | + .byte 0x0 /* Terminator */ | |
24347 | + | |
24348 | + .uleb128 3 /* Abbrev code */ | |
24349 | + .uleb128 0x24 /* DW_TAG_base_type */ | |
24350 | + .byte 0 /* has_children */ | |
24351 | + .uleb128 0x3 /* DW_AT_name */ | |
24352 | + .uleb128 0x8 /* DW_FORM_string */ | |
24353 | + .uleb128 0xb /* DW_AT_byte_size */ | |
24354 | + .uleb128 0xb /* DW_FORM_data1 */ | |
24355 | + .uleb128 0x3e /* DW_AT_encoding */ | |
24356 | + .uleb128 0xb /* DW_FORM_data1 */ | |
24357 | + .byte 0x0 /* Terminator */ | |
24358 | + .byte 0x0 /* Terminator */ | |
24359 | + | |
24360 | + .byte 0x0 /* Terminator */ | |
24361 | + .byte 0x0 /* Terminator */ | |
24362 | + | |
24363 | +/* aranges table */ | |
24364 | + .section .debug_aranges | |
24365 | + .long .Laranges_end - 1f | |
24366 | +1: | |
24367 | + .2byte 2 /* aranges Version */ | |
24368 | + .4byte .Lcu1_begin - .debug_info /* Offset into .debug_info section */ | |
24369 | + /* The GDB crasher is this zero value. */ | |
24370 | + .byte 0 /* aranges address_size */ | |
24371 | + .byte 0 /* aranges segment_size */ | |
24372 | + | |
24373 | +.Laranges_end: | |
24374 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp | |
24375 | new file mode 100644 | |
24376 | index 0000000..39632d5 | |
24377 | --- /dev/null | |
24378 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp | |
24379 | @@ -0,0 +1,40 @@ | |
24380 | +# Copyright 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. | |
24381 | + | |
24382 | +# This program is free software; you can redistribute it and/or modify | |
24383 | +# it under the terms of the GNU General Public License as published by | |
24384 | +# the Free Software Foundation; either version 3 of the License, or | |
24385 | +# (at your option) any later version. | |
24386 | +# | |
24387 | +# This program is distributed in the hope that it will be useful, | |
24388 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24389 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24390 | +# GNU General Public License for more details. | |
24391 | +# | |
24392 | +# You should have received a copy of the GNU General Public License | |
24393 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
24394 | + | |
24395 | +# Test .debug_aranges containing zero address_size. | |
24396 | + | |
24397 | +# This test can only be run on targets which support DWARF-2 and use gas. | |
24398 | +# For now pick a sampling of likely targets. | |
24399 | +if {![istarget *-*-linux*] | |
24400 | + && ![istarget *-*-gnu*] | |
24401 | + && ![istarget *-*-elf*] | |
24402 | + && ![istarget *-*-openbsd*] | |
24403 | + && ![istarget arm-*-eabi*] | |
24404 | + && ![istarget powerpc-*-eabi*]} { | |
24405 | + return 0 | |
3a58abaf | 24406 | +} |
7566401a ER |
24407 | + |
24408 | +set testfile "dw2-aranges" | |
24409 | +set srcfile ${testfile}.S | |
24410 | +set binfile ${objdir}/${subdir}/${testfile} | |
24411 | + | |
24412 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {nodebug}] != "" } { | |
24413 | + return -1 | |
24414 | +} | |
24415 | + | |
24416 | +clean_restart $testfile | |
24417 | + | |
24418 | +# Failed gdb_load would abort the testcase execution earlier. | |
24419 | +pass "file loaded" | |
24420 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.c b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c | |
3a58abaf | 24421 | new file mode 100644 |
7566401a | 24422 | index 0000000..1f02d90 |
3a58abaf | 24423 | --- /dev/null |
7566401a ER |
24424 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c |
24425 | @@ -0,0 +1,42 @@ | |
24426 | +/* This testcase is part of GDB, the GNU debugger. | |
3a58abaf | 24427 | + |
7566401a | 24428 | + Copyright 2004 Free Software Foundation, Inc. |
3a58abaf AM |
24429 | + |
24430 | + This program is free software; you can redistribute it and/or modify | |
24431 | + it under the terms of the GNU General Public License as published by | |
7566401a | 24432 | + the Free Software Foundation; either version 2 of the License, or |
3a58abaf AM |
24433 | + (at your option) any later version. |
24434 | + | |
24435 | + This program is distributed in the hope that it will be useful, | |
24436 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24437 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24438 | + GNU General Public License for more details. | |
7566401a | 24439 | + |
3a58abaf | 24440 | + You should have received a copy of the GNU General Public License |
7566401a ER |
24441 | + along with this program; if not, write to the Free Software |
24442 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
24443 | + USA. */ | |
3a58abaf | 24444 | + |
3a58abaf | 24445 | + |
7566401a ER |
24446 | +/* The function `func1' traced into must have debug info on offset > 0; |
24447 | + (DW_UNSND (attr)). This is the reason of `func0' existence. */ | |
24448 | + | |
24449 | +void | |
24450 | +func0(int a, int b) | |
3a58abaf | 24451 | +{ |
7566401a | 24452 | +} |
3a58abaf | 24453 | + |
7566401a | 24454 | +/* `func1' being traced into must have some arguments to dump. */ |
3a58abaf | 24455 | + |
7566401a ER |
24456 | +void |
24457 | +func1(int a, int b) | |
24458 | +{ | |
24459 | + func0 (a,b); | |
24460 | +} | |
24461 | + | |
24462 | +int | |
24463 | +main(void) | |
24464 | +{ | |
24465 | + func1 (1, 2); | |
3a58abaf AM |
24466 | + return 0; |
24467 | +} | |
7566401a | 24468 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp |
3a58abaf | 24469 | new file mode 100644 |
7566401a | 24470 | index 0000000..1c6e84a |
3a58abaf | 24471 | --- /dev/null |
7566401a ER |
24472 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp |
24473 | @@ -0,0 +1,79 @@ | |
24474 | +# Copyright 2006 Free Software Foundation, Inc. | |
24475 | + | |
3a58abaf AM |
24476 | +# This program is free software; you can redistribute it and/or modify |
24477 | +# it under the terms of the GNU General Public License as published by | |
24478 | +# the Free Software Foundation; either version 2 of the License, or | |
24479 | +# (at your option) any later version. | |
7566401a | 24480 | +# |
3a58abaf AM |
24481 | +# This program is distributed in the hope that it will be useful, |
24482 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24483 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24484 | +# GNU General Public License for more details. | |
7566401a | 24485 | +# |
3a58abaf AM |
24486 | +# You should have received a copy of the GNU General Public License |
24487 | +# along with this program; if not, write to the Free Software | |
24488 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
3a58abaf | 24489 | + |
7566401a ER |
24490 | +# Minimal DWARF-2 unit test |
24491 | + | |
24492 | +# This test can only be run on targets which support DWARF-2. | |
24493 | +# For now pick a sampling of likely targets. | |
24494 | +if {![istarget *-*-linux*] | |
24495 | + && ![istarget *-*-gnu*] | |
24496 | + && ![istarget *-*-elf*] | |
24497 | + && ![istarget *-*-openbsd*] | |
24498 | + && ![istarget arm-*-eabi*] | |
24499 | + && ![istarget powerpc-*-eabi*]} { | |
24500 | + return 0 | |
24501 | +} | |
24502 | + | |
24503 | +set testfile "dw2-stripped" | |
24504 | +set srcfile ${testfile}.c | |
24505 | +set binfile ${objdir}/${subdir}/${testfile}.x | |
24506 | + | |
24507 | +remote_exec build "rm -f ${binfile}" | |
24508 | + | |
24509 | +# get the value of gcc_compiled | |
24510 | +if [get_compiler_info ${binfile}] { | |
3a58abaf AM |
24511 | + return -1 |
24512 | +} | |
24513 | + | |
7566401a ER |
24514 | +# This test can only be run on gcc as we use additional_flags=FIXME |
24515 | +if {$gcc_compiled == 0} { | |
24516 | + return 0 | |
24517 | +} | |
24518 | + | |
24519 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-ggdb3}] != "" } { | |
3a58abaf AM |
24520 | + return -1 |
24521 | +} | |
24522 | + | |
7566401a ER |
24523 | +remote_exec build "objcopy -R .debug_loc ${binfile}" |
24524 | +set strip_output [remote_exec build "objdump -h ${binfile}"] | |
3a58abaf | 24525 | + |
7566401a ER |
24526 | +set test "stripping test file preservation" |
24527 | +if [ regexp ".debug_info " $strip_output] { | |
24528 | + pass "$test (.debug_info preserved)" | |
24529 | +} else { | |
24530 | + fail "$test (.debug_info got also stripped)" | |
24531 | +} | |
24532 | + | |
24533 | +set test "stripping test file functionality" | |
24534 | +if [ regexp ".debug_loc " $strip_output] { | |
24535 | + fail "$test (.debug_loc still present)" | |
24536 | +} else { | |
24537 | + pass "$test (.debug_loc stripped)" | |
24538 | +} | |
24539 | + | |
24540 | +gdb_exit | |
24541 | +gdb_start | |
24542 | +gdb_reinitialize_dir $srcdir/$subdir | |
24543 | +gdb_load ${binfile} | |
24544 | + | |
24545 | +# For C programs, "start" should stop in main(). | |
24546 | + | |
24547 | +gdb_test "start" \ | |
24548 | + ".*main \\(\\) at .*" \ | |
24549 | + "start" | |
24550 | +gdb_test "step" \ | |
24551 | + "func.* \\(.*\\) at .*" \ | |
24552 | + "step" | |
24553 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S | |
3a58abaf | 24554 | new file mode 100644 |
7566401a | 24555 | index 0000000..5fcdd84 |
3a58abaf | 24556 | --- /dev/null |
7566401a ER |
24557 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S |
24558 | @@ -0,0 +1,83 @@ | |
24559 | +/* This testcase is part of GDB, the GNU debugger. | |
3a58abaf AM |
24560 | + |
24561 | + Copyright 2009 Free Software Foundation, Inc. | |
24562 | + | |
24563 | + This program is free software; you can redistribute it and/or modify | |
24564 | + it under the terms of the GNU General Public License as published by | |
24565 | + the Free Software Foundation; either version 3 of the License, or | |
24566 | + (at your option) any later version. | |
24567 | + | |
24568 | + This program is distributed in the hope that it will be useful, | |
24569 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24570 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24571 | + GNU General Public License for more details. | |
24572 | + | |
24573 | + You should have received a copy of the GNU General Public License | |
7566401a | 24574 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
3a58abaf | 24575 | + |
7566401a | 24576 | +/* Debug information */ |
3a58abaf | 24577 | + |
7566401a ER |
24578 | + .section .debug_info |
24579 | +.Lcu1_begin: | |
24580 | + /* CU header */ | |
24581 | + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ | |
24582 | +.Lcu1_start: | |
24583 | + .2byte 2 /* DWARF Version */ | |
24584 | + .4byte .Labbrev1_begin /* Offset into abbrev section */ | |
24585 | + .byte 4 /* Pointer size */ | |
3a58abaf | 24586 | + |
7566401a ER |
24587 | + /* CU die */ |
24588 | + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ | |
24589 | + .ascii "dw2-struct-member-data-location.c\0" /* DW_AT_name */ | |
24590 | + .ascii "GNU C 4.3.2\0" /* DW_AT_producer */ | |
24591 | + .byte 1 /* DW_AT_language (C) */ | |
3a58abaf | 24592 | + |
7566401a ER |
24593 | +.Ltype_uchar: |
24594 | + .uleb128 2 /* Abbrev: DW_TAG_structure_type */ | |
24595 | + .ascii "some_struct\0" /* DW_AT_name */ | |
3a58abaf | 24596 | + |
7566401a ER |
24597 | + .uleb128 3 /* Abbrev: DW_TAG_member */ |
24598 | + .ascii "field\0" /* DW_AT_name */ | |
24599 | + .byte 0 /* DW_AT_data_member_location */ | |
3a58abaf | 24600 | + |
7566401a | 24601 | + .byte 0 /* End of children of some_struct */ |
3a58abaf | 24602 | + |
7566401a | 24603 | + .byte 0 /* End of children of CU */ |
3a58abaf | 24604 | + |
7566401a | 24605 | +.Lcu1_end: |
3a58abaf | 24606 | + |
7566401a ER |
24607 | +/* Abbrev table */ |
24608 | + .section .debug_abbrev | |
24609 | +.Labbrev1_begin: | |
24610 | + .uleb128 1 /* Abbrev code */ | |
24611 | + .uleb128 0x11 /* DW_TAG_compile_unit */ | |
24612 | + .byte 1 /* has_children */ | |
24613 | + .uleb128 0x3 /* DW_AT_name */ | |
24614 | + .uleb128 0x8 /* DW_FORM_string */ | |
24615 | + .uleb128 0x25 /* DW_AT_producer */ | |
24616 | + .uleb128 0x8 /* DW_FORM_string */ | |
24617 | + .uleb128 0x13 /* DW_AT_language */ | |
24618 | + .uleb128 0xb /* DW_FORM_data1 */ | |
24619 | + .byte 0x0 /* Terminator */ | |
24620 | + .byte 0x0 /* Terminator */ | |
3a58abaf | 24621 | + |
7566401a ER |
24622 | + .uleb128 2 /* Abbrev code */ |
24623 | + .uleb128 0x13 /* DW_TAG_structure_type */ | |
24624 | + .byte 1 /* has_children */ | |
24625 | + .uleb128 0x3 /* DW_AT_name */ | |
24626 | + .uleb128 0x8 /* DW_FORM_string */ | |
24627 | + .byte 0x0 /* Terminator */ | |
24628 | + .byte 0x0 /* Terminator */ | |
3a58abaf | 24629 | + |
7566401a ER |
24630 | + .uleb128 3 /* Abbrev code */ |
24631 | + .uleb128 0x0d /* DW_TAG_member */ | |
24632 | + .byte 0 /* has_children */ | |
24633 | + .uleb128 0x3 /* DW_AT_name */ | |
24634 | + .uleb128 0x8 /* DW_FORM_string */ | |
24635 | + .uleb128 0x38 /* DW_AT_data_member_location */ | |
24636 | + .uleb128 0x0b /* DW_FORM_data1 */ | |
24637 | + .byte 0x0 /* Terminator */ | |
24638 | + .byte 0x0 /* Terminator */ | |
3a58abaf | 24639 | + |
7566401a ER |
24640 | + .byte 0x0 /* Terminator */ |
24641 | + .byte 0x0 /* Terminator */ | |
24642 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp | |
3a58abaf | 24643 | new file mode 100644 |
7566401a | 24644 | index 0000000..c41151c |
3a58abaf | 24645 | --- /dev/null |
7566401a ER |
24646 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp |
24647 | @@ -0,0 +1,37 @@ | |
24648 | +# Copyright 2009 Free Software Foundation, Inc. | |
3a58abaf AM |
24649 | + |
24650 | +# This program is free software; you can redistribute it and/or modify | |
24651 | +# it under the terms of the GNU General Public License as published by | |
24652 | +# the Free Software Foundation; either version 3 of the License, or | |
24653 | +# (at your option) any later version. | |
24654 | +# | |
24655 | +# This program is distributed in the hope that it will be useful, | |
24656 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24657 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24658 | +# GNU General Public License for more details. | |
24659 | +# | |
24660 | +# You should have received a copy of the GNU General Public License | |
24661 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
24662 | + | |
7566401a ER |
24663 | +# This test can only be run on targets which support DWARF-2 and use gas. |
24664 | +# For now pick a sampling of likely targets. | |
24665 | +if {![istarget *-*-linux*] | |
24666 | + && ![istarget *-*-gnu*] | |
24667 | + && ![istarget *-*-elf*] | |
24668 | + && ![istarget *-*-openbsd*] | |
24669 | + && ![istarget arm-*-eabi*] | |
24670 | + && ![istarget powerpc-*-eabi*]} { | |
24671 | + return 0 | |
3a58abaf AM |
24672 | +} |
24673 | + | |
7566401a ER |
24674 | +set testfile "dw2-struct-member-data-location" |
24675 | +set srcfile ${testfile}.S | |
24676 | +set binfile ${testfile}.x | |
24677 | + | |
24678 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${binfile}" object {nodebug}] != "" } { | |
24679 | + return -1 | |
3a58abaf AM |
24680 | +} |
24681 | + | |
7566401a ER |
24682 | +clean_restart $binfile |
24683 | + | |
24684 | +gdb_test "ptype struct some_struct" "type = struct some_struct {\[\r\n \t\]*void field;\[\r\n \t\]*}" | |
24685 | diff --git a/gdb/testsuite/gdb.fortran/common-block.exp b/gdb/testsuite/gdb.fortran/common-block.exp | |
24686 | new file mode 100644 | |
24687 | index 0000000..888f6c3 | |
24688 | --- /dev/null | |
24689 | +++ b/gdb/testsuite/gdb.fortran/common-block.exp | |
24690 | @@ -0,0 +1,101 @@ | |
24691 | +# Copyright 2008 Free Software Foundation, Inc. | |
24692 | + | |
24693 | +# This program is free software; you can redistribute it and/or modify | |
24694 | +# it under the terms of the GNU General Public License as published by | |
24695 | +# the Free Software Foundation; either version 2 of the License, or | |
24696 | +# (at your option) any later version. | |
24697 | +# | |
24698 | +# This program is distributed in the hope that it will be useful, | |
24699 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24700 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24701 | +# GNU General Public License for more details. | |
24702 | +# | |
24703 | +# You should have received a copy of the GNU General Public License | |
24704 | +# along with this program; if not, write to the Free Software | |
24705 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
24706 | + | |
24707 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
24708 | + | |
24709 | +set testfile "common-block" | |
24710 | +set srcfile ${testfile}.f90 | |
3a58abaf AM |
24711 | +set binfile ${objdir}/${subdir}/${testfile} |
24712 | + | |
7566401a ER |
24713 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } { |
24714 | + untested "Couldn't compile ${srcfile}" | |
3a58abaf AM |
24715 | + return -1 |
24716 | +} | |
24717 | + | |
24718 | +gdb_exit | |
24719 | +gdb_start | |
24720 | +gdb_reinitialize_dir $srcdir/$subdir | |
24721 | +gdb_load ${binfile} | |
24722 | + | |
7566401a ER |
24723 | +if ![runto MAIN__] then { |
24724 | + perror "couldn't run to breakpoint MAIN__" | |
24725 | + continue | |
3a58abaf AM |
24726 | +} |
24727 | + | |
7566401a ER |
24728 | +gdb_breakpoint [gdb_get_line_number "stop-here-out"] |
24729 | +gdb_continue_to_breakpoint "stop-here-out" | |
3a58abaf | 24730 | + |
7566401a ER |
24731 | +# Common block naming with source name /foo/: |
24732 | +# .symtab DW_TAG_common_block's DW_AT_name | |
24733 | +# Intel Fortran foo_ foo_ | |
24734 | +# GNU Fortran foo_ foo | |
24735 | +#set suffix "_" | |
24736 | +set suffix "" | |
3a58abaf | 24737 | + |
7566401a ER |
24738 | +set int4 {(integer\(kind=4\)|INTEGER\(4\))} |
24739 | +set real4 {(real\(kind=4\)|REAL\(4\))} | |
24740 | +set real8 {(real\(kind=8\)|REAL\(8\))} | |
3a58abaf | 24741 | + |
7566401a ER |
24742 | +gdb_test "whatis foo$suffix" "No symbol \"foo$suffix\" in current context." |
24743 | +gdb_test "ptype foo$suffix" "No symbol \"foo$suffix\" in current context." | |
24744 | +gdb_test "p foo$suffix" "No symbol \"foo$suffix\" in current context." | |
24745 | +gdb_test "whatis fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." | |
24746 | +gdb_test "ptype fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." | |
24747 | +gdb_test "p fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." | |
3a58abaf | 24748 | + |
7566401a ER |
24749 | +gdb_test "info locals" "ix_x = 11\r\niy_y = 22\r\niz_z = 33\r\nix = 1\r\niy = 2\r\niz = 3" "info locals out" |
24750 | +gdb_test "info common" "Contents of F77 COMMON block 'fo_o':\r\nix_x = 11\r\niy_y = 22\r\niz_z = 33\r\n\r\nContents of F77 COMMON block 'foo':\r\nix = 1\r\niy = 2\r\niz = 3" "info common out" | |
3a58abaf | 24751 | + |
7566401a ER |
24752 | +gdb_test "ptype ix" "type = $int4" "ptype ix out" |
24753 | +gdb_test "ptype iy" "type = $real4" "ptype iy out" | |
24754 | +gdb_test "ptype iz" "type = $real8" "ptype iz out" | |
24755 | +gdb_test "ptype ix_x" "type = $int4" "ptype ix_x out" | |
24756 | +gdb_test "ptype iy_y" "type = $real4" "ptype iy_y out" | |
24757 | +gdb_test "ptype iz_z" "type = $real8" "ptype iz_z out" | |
3a58abaf | 24758 | + |
7566401a ER |
24759 | +gdb_test "p ix" " = 1 *" "p ix out" |
24760 | +gdb_test "p iy" " = 2 *" "p iy out" | |
24761 | +gdb_test "p iz" " = 3 *" "p iz out" | |
24762 | +gdb_test "p ix_x" " = 11 *" "p ix_x out" | |
24763 | +gdb_test "p iy_y" " = 22 *" "p iy_y out" | |
24764 | +gdb_test "p iz_z" " = 33 *" "p iz_z out" | |
3a58abaf | 24765 | + |
7566401a ER |
24766 | +gdb_breakpoint [gdb_get_line_number "stop-here-in"] |
24767 | +gdb_continue_to_breakpoint "stop-here-in" | |
3a58abaf | 24768 | + |
7566401a ER |
24769 | +gdb_test "whatis foo$suffix" "No symbol \"foo$suffix\" in current context." "whatis foo$suffix in" |
24770 | +gdb_test "ptype foo$suffix" "No symbol \"foo$suffix\" in current context." "ptype foo$suffix in" | |
24771 | +gdb_test "p foo$suffix" "No symbol \"foo$suffix\" in current context." "p foo$suffix in" | |
24772 | +gdb_test "whatis fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." "whatis fo_o$suffix in" | |
24773 | +gdb_test "ptype fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." "ptype fo_o$suffix in" | |
24774 | +gdb_test "p fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." "p fo_o$suffix in" | |
3a58abaf | 24775 | + |
7566401a ER |
24776 | +gdb_test "info locals" "ix = 11\r\niy2 = 22\r\niz = 33\r\nix_x = 1\r\niy_y = 2\r\niz_z2 = 3\r\niy = 5\r\niz_z = 55" "info locals in" |
24777 | +gdb_test "info common" "Contents of F77 COMMON block 'fo_o':\r\nix = 11\r\niy2 = 22\r\niz = 33\r\n\r\nContents of F77 COMMON block 'foo':\r\nix_x = 1\r\niy_y = 2\r\niz_z2 = 3" "info common in" | |
3a58abaf | 24778 | + |
7566401a ER |
24779 | +gdb_test "ptype ix" "type = $int4" "ptype ix in" |
24780 | +gdb_test "ptype iy2" "type = $real4" "ptype iy2 in" | |
24781 | +gdb_test "ptype iz" "type = $real8" "ptype iz in" | |
24782 | +gdb_test "ptype ix_x" "type = $int4" "ptype ix_x in" | |
24783 | +gdb_test "ptype iy_y" "type = $real4" "ptype iy_y in" | |
24784 | +gdb_test "ptype iz_z2" "type = $real8" "ptype iz_z2 in" | |
3a58abaf | 24785 | + |
7566401a ER |
24786 | +gdb_test "p ix" " = 11 *" "p ix in" |
24787 | +gdb_test "p iy2" " = 22 *" "p iy2 in" | |
24788 | +gdb_test "p iz" " = 33 *" "p iz in" | |
24789 | +gdb_test "p ix_x" " = 1 *" "p ix_x in" | |
24790 | +gdb_test "p iy_y" " = 2 *" "p iy_y in" | |
24791 | +gdb_test "p iz_z2" " = 3 *" "p iz_z2 in" | |
24792 | diff --git a/gdb/testsuite/gdb.fortran/common-block.f90 b/gdb/testsuite/gdb.fortran/common-block.f90 | |
24793 | new file mode 100644 | |
24794 | index 0000000..b614e8a | |
24795 | --- /dev/null | |
24796 | +++ b/gdb/testsuite/gdb.fortran/common-block.f90 | |
24797 | @@ -0,0 +1,67 @@ | |
24798 | +! Copyright 2008 Free Software Foundation, Inc. | |
24799 | +! | |
24800 | +! This program is free software; you can redistribute it and/or modify | |
24801 | +! it under the terms of the GNU General Public License as published by | |
24802 | +! the Free Software Foundation; either version 2 of the License, or | |
24803 | +! (at your option) any later version. | |
24804 | +! | |
24805 | +! This program is distributed in the hope that it will be useful, | |
24806 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24807 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24808 | +! GNU General Public License for more details. | |
24809 | +! | |
24810 | +! You should have received a copy of the GNU General Public License | |
24811 | +! along with this program; if not, write to the Free Software | |
24812 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
24813 | +! | |
24814 | +! Ihis file is the Fortran source file for dynamic.exp. | |
24815 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
24816 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
3a58abaf | 24817 | + |
7566401a | 24818 | +subroutine in |
3a58abaf | 24819 | + |
7566401a ER |
24820 | + INTEGER*4 ix |
24821 | + REAL*4 iy2 | |
24822 | + REAL*8 iz | |
3a58abaf | 24823 | + |
7566401a ER |
24824 | + INTEGER*4 ix_x |
24825 | + REAL*4 iy_y | |
24826 | + REAL*8 iz_z2 | |
3a58abaf | 24827 | + |
7566401a ER |
24828 | + common /fo_o/ix,iy2,iz |
24829 | + common /foo/ix_x,iy_y,iz_z2 | |
3a58abaf | 24830 | + |
7566401a ER |
24831 | + iy = 5 |
24832 | + iz_z = 55 | |
3a58abaf | 24833 | + |
7566401a ER |
24834 | + if (ix .ne. 11 .or. iy2 .ne. 22.0 .or. iz .ne. 33.0) call abort |
24835 | + if (ix_x .ne. 1 .or. iy_y .ne. 2.0 .or. iz_z2 .ne. 3.0) call abort | |
3a58abaf | 24836 | + |
7566401a | 24837 | + ix = 0 ! stop-here-in |
3a58abaf | 24838 | + |
7566401a | 24839 | +end subroutine in |
3a58abaf | 24840 | + |
7566401a | 24841 | +program common_test |
3a58abaf | 24842 | + |
7566401a ER |
24843 | + INTEGER*4 ix |
24844 | + REAL*4 iy | |
24845 | + REAL*8 iz | |
3a58abaf | 24846 | + |
7566401a ER |
24847 | + INTEGER*4 ix_x |
24848 | + REAL*4 iy_y | |
24849 | + REAL*8 iz_z | |
3a58abaf | 24850 | + |
7566401a ER |
24851 | + common /foo/ix,iy,iz |
24852 | + common /fo_o/ix_x,iy_y,iz_z | |
3a58abaf | 24853 | + |
7566401a ER |
24854 | + ix = 1 |
24855 | + iy = 2.0 | |
24856 | + iz = 3.0 | |
3a58abaf | 24857 | + |
7566401a ER |
24858 | + ix_x = 11 |
24859 | + iy_y = 22.0 | |
24860 | + iz_z = 33.0 | |
3a58abaf | 24861 | + |
7566401a | 24862 | + call in ! stop-here-out |
3a58abaf | 24863 | + |
7566401a ER |
24864 | +end program common_test |
24865 | diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.exp b/gdb/testsuite/gdb.fortran/dwarf-stride.exp | |
24866 | new file mode 100644 | |
24867 | index 0000000..cd3486b | |
24868 | --- /dev/null | |
24869 | +++ b/gdb/testsuite/gdb.fortran/dwarf-stride.exp | |
24870 | @@ -0,0 +1,42 @@ | |
24871 | +# Copyright 2009 Free Software Foundation, Inc. | |
3a58abaf | 24872 | + |
7566401a ER |
24873 | +# This program is free software; you can redistribute it and/or modify |
24874 | +# it under the terms of the GNU General Public License as published by | |
24875 | +# the Free Software Foundation; either version 2 of the License, or | |
24876 | +# (at your option) any later version. | |
24877 | +# | |
24878 | +# This program is distributed in the hope that it will be useful, | |
24879 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24880 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24881 | +# GNU General Public License for more details. | |
24882 | +# | |
24883 | +# You should have received a copy of the GNU General Public License | |
24884 | +# along with this program; if not, write to the Free Software | |
24885 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
3a58abaf | 24886 | + |
7566401a | 24887 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. |
3a58abaf | 24888 | + |
7566401a ER |
24889 | +# This file is part of the gdb testsuite. Array element stride must not be |
24890 | +# specified in the number of elements but in a number of bytes instead. | |
24891 | +# Original problem: | |
24892 | +# (gdb) p c40pt(1) | |
24893 | +# $1 = '0-hello', ' ' <repeats 33 times> | |
24894 | +# (gdb) p c40pt(2) | |
24895 | +# warning: Fortran array stride not divisible by the element size | |
3a58abaf | 24896 | + |
7566401a ER |
24897 | +set testfile dwarf-stride |
24898 | +set srcfile ${testfile}.f90 | |
3a58abaf | 24899 | + |
7566401a ER |
24900 | +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f77}] } { |
24901 | + return -1 | |
24902 | +} | |
3a58abaf | 24903 | + |
7566401a ER |
24904 | +if ![runto MAIN__] then { |
24905 | + perror "couldn't run to breakpoint MAIN__" | |
24906 | + continue | |
3a58abaf | 24907 | +} |
3a58abaf | 24908 | + |
7566401a ER |
24909 | +gdb_breakpoint [gdb_get_line_number "break-here"] |
24910 | +gdb_continue_to_breakpoint "break-here" ".*break-here.*" | |
24911 | +gdb_test "p c40pt(1)" " = '0-hello.*" | |
24912 | +gdb_test "p c40pt(2)" " = '1-hello.*" | |
24913 | diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.f90 b/gdb/testsuite/gdb.fortran/dwarf-stride.f90 | |
24914 | new file mode 100644 | |
24915 | index 0000000..e492b3a | |
24916 | --- /dev/null | |
24917 | +++ b/gdb/testsuite/gdb.fortran/dwarf-stride.f90 | |
24918 | @@ -0,0 +1,40 @@ | |
24919 | +! Copyright 2009 Free Software Foundation, Inc. | |
24920 | +! | |
24921 | +! This program is free software; you can redistribute it and/or modify | |
24922 | +! it under the terms of the GNU General Public License as published by | |
24923 | +! the Free Software Foundation; either version 2 of the License, or | |
24924 | +! (at your option) any later version. | |
24925 | +! | |
24926 | +! This program is distributed in the hope that it will be useful, | |
24927 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24928 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24929 | +! GNU General Public License for more details. | |
24930 | +! | |
24931 | +! You should have received a copy of the GNU General Public License | |
24932 | +! along with this program; if not, write to the Free Software | |
24933 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
24934 | +! | |
24935 | +! File written by Alan Matsuoka. | |
24936 | + | |
24937 | +program repro | |
3a58abaf | 24938 | + |
7566401a ER |
24939 | + type small_stride |
24940 | + character*40 long_string | |
24941 | + integer small_pad | |
24942 | + end type small_stride | |
3a58abaf | 24943 | + |
7566401a ER |
24944 | + type(small_stride), dimension (20), target :: unpleasant |
24945 | + character*40, pointer, dimension(:):: c40pt | |
3a58abaf | 24946 | + |
7566401a | 24947 | + integer i |
3a58abaf | 24948 | + |
7566401a ER |
24949 | + do i = 0,19 |
24950 | + unpleasant(i+1)%small_pad = i+1 | |
24951 | + unpleasant(i+1)%long_string = char (ichar('0') + i) // '-hello' | |
24952 | + end do | |
3a58abaf | 24953 | + |
7566401a | 24954 | + c40pt => unpleasant%long_string |
3a58abaf | 24955 | + |
7566401a ER |
24956 | + print *, c40pt ! break-here |
24957 | + | |
24958 | +end program repro | |
24959 | diff --git a/gdb/testsuite/gdb.fortran/dynamic.exp b/gdb/testsuite/gdb.fortran/dynamic.exp | |
3a58abaf | 24960 | new file mode 100644 |
7566401a | 24961 | index 0000000..0ccebe0 |
3a58abaf | 24962 | --- /dev/null |
7566401a ER |
24963 | +++ b/gdb/testsuite/gdb.fortran/dynamic.exp |
24964 | @@ -0,0 +1,145 @@ | |
24965 | +# Copyright 2007 Free Software Foundation, Inc. | |
3a58abaf AM |
24966 | + |
24967 | +# This program is free software; you can redistribute it and/or modify | |
24968 | +# it under the terms of the GNU General Public License as published by | |
7566401a | 24969 | +# the Free Software Foundation; either version 2 of the License, or |
3a58abaf | 24970 | +# (at your option) any later version. |
7566401a | 24971 | +# |
3a58abaf AM |
24972 | +# This program is distributed in the hope that it will be useful, |
24973 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24974 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24975 | +# GNU General Public License for more details. | |
7566401a | 24976 | +# |
3a58abaf | 24977 | +# You should have received a copy of the GNU General Public License |
7566401a ER |
24978 | +# along with this program; if not, write to the Free Software |
24979 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
3a58abaf | 24980 | + |
7566401a | 24981 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. |
3a58abaf | 24982 | + |
7566401a ER |
24983 | +# This file is part of the gdb testsuite. It contains tests for dynamically |
24984 | +# allocated Fortran arrays. | |
24985 | +# It depends on the GCC dynamic Fortran arrays DWARF support: | |
24986 | +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22244 | |
3a58abaf | 24987 | + |
7566401a ER |
24988 | +set testfile "dynamic" |
24989 | +set srcfile ${testfile}.f90 | |
3a58abaf | 24990 | +set binfile ${objdir}/${subdir}/${testfile} |
7566401a ER |
24991 | + |
24992 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } { | |
3a58abaf AM |
24993 | + untested "Couldn't compile ${srcfile}" |
24994 | + return -1 | |
24995 | +} | |
24996 | + | |
7566401a ER |
24997 | +gdb_exit |
24998 | +gdb_start | |
24999 | +gdb_reinitialize_dir $srcdir/$subdir | |
25000 | +gdb_load ${binfile} | |
3a58abaf | 25001 | + |
7566401a ER |
25002 | +if ![runto MAIN__] then { |
25003 | + perror "couldn't run to breakpoint MAIN__" | |
25004 | + continue | |
3a58abaf AM |
25005 | +} |
25006 | + | |
7566401a ER |
25007 | +gdb_breakpoint [gdb_get_line_number "varx-init"] |
25008 | +gdb_continue_to_breakpoint "varx-init" | |
25009 | +gdb_test "p varx" "\\$\[0-9\]* = <(object|the array) is not allocated>" "p varx unallocated" | |
25010 | +gdb_test "ptype varx" "type = <(object|the array) is not allocated>" "ptype varx unallocated" | |
25011 | +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" | |
25012 | +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" | |
25013 | +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" | |
25014 | + | |
25015 | +gdb_breakpoint [gdb_get_line_number "varx-allocated"] | |
25016 | +gdb_continue_to_breakpoint "varx-allocated" | |
25017 | +# $1 = (( ( 0, 0, 0, 0, 0, 0) ( 0, 0, 0, 0, 0, 0) --- , 0) ) ( ( 0, 0, ...) ...) ...) | |
25018 | +gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)" "ptype varx allocated" | |
25019 | +# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1. | |
25020 | +gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varx allocated" | |
25021 | + | |
25022 | +gdb_breakpoint [gdb_get_line_number "varx-filled"] | |
25023 | +gdb_continue_to_breakpoint "varx-filled" | |
25024 | +gdb_test "p varx(2, 5, 17)" "\\$\[0-9\]* = 6" | |
25025 | +gdb_test "p varx(1, 5, 17)" "\\$\[0-9\]* = 7" | |
25026 | +gdb_test "p varx(2, 6, 18)" "\\$\[0-9\]* = 8" | |
25027 | +gdb_test "p varx(6, 15, 28)" "\\$\[0-9\]* = 9" | |
25028 | +# The latter one is for the Intel Fortran Compiler 10.1.008 pointer type. | |
25029 | +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" | |
25030 | +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" | |
25031 | + | |
25032 | +gdb_breakpoint [gdb_get_line_number "varv-associated"] | |
25033 | +gdb_continue_to_breakpoint "varv-associated" | |
25034 | +gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 6" "p varx(3, 7, 19) with varv associated" | |
25035 | +gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 6" "p varv(3, 7, 19) associated" | |
25036 | +# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1. | |
25037 | +gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varv associated" | |
25038 | +gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)" "ptype varx with varv associated" | |
25039 | +# Intel Fortran Compiler 10.1.008 uses the pointer type. | |
25040 | +gdb_test "ptype varv" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)\\)?" "ptype varv associated" | |
3a58abaf | 25041 | + |
7566401a ER |
25042 | +gdb_breakpoint [gdb_get_line_number "varv-filled"] |
25043 | +gdb_continue_to_breakpoint "varv-filled" | |
25044 | +gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 10" "p varx(3, 7, 19) with varv filled" | |
25045 | +gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 10" "p varv(3, 7, 19) filled" | |
3a58abaf | 25046 | + |
7566401a ER |
25047 | +gdb_breakpoint [gdb_get_line_number "varv-deassociated"] |
25048 | +gdb_continue_to_breakpoint "varv-deassociated" | |
25049 | +# The latter one is for the Intel Fortran Compiler 10.1.008 pointer type. | |
25050 | +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" | |
25051 | +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" | |
25052 | +gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varv deassociated" | |
25053 | +gdb_test "p varv(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not associated\\." | |
25054 | +gdb_test "ptype varv(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not associated\\." | |
3a58abaf | 25055 | + |
7566401a ER |
25056 | +gdb_breakpoint [gdb_get_line_number "varx-deallocated"] |
25057 | +gdb_continue_to_breakpoint "varx-deallocated" | |
25058 | +gdb_test "p varx" "\\$\[0-9\]* = <(object|the array) is not allocated>" "p varx deallocated" | |
25059 | +gdb_test "ptype varx" "type = <(object|the array) is not allocated>" "ptype varx deallocated" | |
25060 | +gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varx deallocated" | |
25061 | +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" | |
25062 | +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" | |
3a58abaf | 25063 | + |
7566401a ER |
25064 | +gdb_breakpoint [gdb_get_line_number "vary-passed"] |
25065 | +gdb_continue_to_breakpoint "vary-passed" | |
25066 | +# $1 = (( ( 1, 1, 1, 1, 1, 1) ( 1, 1, 1, 1, 1, 1) --- , 1) ) ( ( 1, 1, ...) ...) ...) | |
25067 | +gdb_test "p vary" "\\$\[0-9\]* = \\(\[()1, .\]*\\)" | |
3a58abaf | 25068 | + |
7566401a ER |
25069 | +gdb_breakpoint [gdb_get_line_number "vary-filled"] |
25070 | +gdb_continue_to_breakpoint "vary-filled" | |
25071 | +gdb_test "ptype vary" "type = real(\\(kind=4\\)|\\*4) \\(10,10\\)" | |
25072 | +gdb_test "p vary(1, 1)" "\\$\[0-9\]* = 8" | |
25073 | +gdb_test "p vary(2, 2)" "\\$\[0-9\]* = 9" | |
25074 | +gdb_test "p vary(1, 3)" "\\$\[0-9\]* = 10" | |
25075 | +# $1 = (( ( 3, 3, 3, 3, 3, 3) ( 3, 3, 3, 3, 3, 3) --- , 3) ) ( ( 3, 3, ...) ...) ...) | |
25076 | +gdb_test "p varw" "\\$\[0-9\]* = \\(\[()3, .\]*\\)" | |
3a58abaf | 25077 | + |
7566401a ER |
25078 | +gdb_breakpoint [gdb_get_line_number "varw-almostfilled"] |
25079 | +gdb_continue_to_breakpoint "varw-almostfilled" | |
25080 | +gdb_test "ptype varw" "type = real(\\(kind=4\\)|\\*4) \\(5,4,3\\)" | |
25081 | +gdb_test "p varw(3,1,1)=1" "\\$\[0-9\]* = 1" | |
25082 | +# $1 = (( ( 6, 5, 1, 5, 5, 5) ( 5, 5, 5, 5, 5, 5) --- , 5) ) ( ( 5, 5, ...) ...) ...) | |
25083 | +gdb_test "p varw" "\\$\[0-9\]* = \\( *\\( *\\( *6, *5, *1,\[()5, .\]*\\)" "p varw filled" | |
25084 | +# "up" works with GCC but other Fortran compilers may copy the values into the | |
25085 | +# outer function only on the exit of the inner function. | |
25086 | +# We need both variants as depending on the arch we optionally may still be | |
25087 | +# executing the caller line or not after `finish'. | |
25088 | +gdb_test "finish" ".*(call bar \\(y, x\\)|call foo \\(x, z\\(2:6, 4:7, 6:8\\)\\))" | |
25089 | +gdb_test "p z(2,4,5)" "\\$\[0-9\]* = 3" | |
25090 | +gdb_test "p z(2,4,6)" "\\$\[0-9\]* = 6" | |
25091 | +gdb_test "p z(2,4,7)" "\\$\[0-9\]* = 5" | |
25092 | +gdb_test "p z(4,4,6)" "\\$\[0-9\]* = 1" | |
3a58abaf | 25093 | + |
7566401a ER |
25094 | +gdb_breakpoint [gdb_get_line_number "varz-almostfilled"] |
25095 | +gdb_continue_to_breakpoint "varz-almostfilled" | |
25096 | +# GCC uses the pointer type here, Intel Fortran Compiler 10.1.008 does not. | |
25097 | +gdb_test "ptype varz" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(\\*\\)\\)?" | |
25098 | +# Intel Fortran Compiler 10.1.008 has a bug here - (2:11,7:7) | |
25099 | +# as it produces DW_AT_lower_bound == DW_AT_upper_bound == 7. | |
25100 | +gdb_test "ptype vart" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(2:11,7:\\*\\)\\)?" | |
25101 | +gdb_test "p varz" "\\$\[0-9\]* = \\(\\)" | |
25102 | +gdb_test "p vart" "\\$\[0-9\]* = \\(\\)" | |
25103 | +gdb_test "p varz(3)" "\\$\[0-9\]* = 4" | |
25104 | +# maps to foo::vary(1,1) | |
25105 | +gdb_test "p vart(2,7)" "\\$\[0-9\]* = 8" | |
25106 | +# maps to foo::vary(2,2) | |
25107 | +gdb_test "p vart(3,8)" "\\$\[0-9\]* = 9" | |
25108 | +# maps to foo::vary(1,3) | |
25109 | +gdb_test "p vart(2,9)" "\\$\[0-9\]* = 10" | |
25110 | diff --git a/gdb/testsuite/gdb.fortran/dynamic.f90 b/gdb/testsuite/gdb.fortran/dynamic.f90 | |
25111 | new file mode 100644 | |
25112 | index 0000000..0f43564 | |
25113 | --- /dev/null | |
25114 | +++ b/gdb/testsuite/gdb.fortran/dynamic.f90 | |
25115 | @@ -0,0 +1,98 @@ | |
25116 | +! Copyright 2007 Free Software Foundation, Inc. | |
25117 | +! | |
25118 | +! This program is free software; you can redistribute it and/or modify | |
25119 | +! it under the terms of the GNU General Public License as published by | |
25120 | +! the Free Software Foundation; either version 2 of the License, or | |
25121 | +! (at your option) any later version. | |
25122 | +! | |
25123 | +! This program is distributed in the hope that it will be useful, | |
25124 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25125 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25126 | +! GNU General Public License for more details. | |
25127 | +! | |
25128 | +! You should have received a copy of the GNU General Public License | |
25129 | +! along with this program; if not, write to the Free Software | |
25130 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25131 | +! | |
25132 | +! Ihis file is the Fortran source file for dynamic.exp. | |
25133 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
25134 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
3a58abaf | 25135 | + |
7566401a ER |
25136 | +subroutine baz |
25137 | + real, target, allocatable :: varx (:, :, :) | |
25138 | + real, pointer :: varv (:, :, :) | |
25139 | + real, target :: varu (1, 2, 3) | |
25140 | + logical :: l | |
25141 | + allocate (varx (1:6, 5:15, 17:28)) ! varx-init | |
25142 | + l = allocated (varx) | |
25143 | + varx(:, :, :) = 6 ! varx-allocated | |
25144 | + varx(1, 5, 17) = 7 | |
25145 | + varx(2, 6, 18) = 8 | |
25146 | + varx(6, 15, 28) = 9 | |
25147 | + varv => varx ! varx-filled | |
25148 | + l = associated (varv) | |
25149 | + varv(3, 7, 19) = 10 ! varv-associated | |
25150 | + varv => null () ! varv-filled | |
25151 | + l = associated (varv) | |
25152 | + deallocate (varx) ! varv-deassociated | |
25153 | + l = allocated (varx) | |
25154 | + varu(:, :, :) = 10 ! varx-deallocated | |
25155 | + allocate (varv (1:6, 5:15, 17:28)) | |
25156 | + l = associated (varv) | |
25157 | + varv(:, :, :) = 6 | |
25158 | + varv(1, 5, 17) = 7 | |
25159 | + varv(2, 6, 18) = 8 | |
25160 | + varv(6, 15, 28) = 9 | |
25161 | + deallocate (varv) | |
25162 | + l = associated (varv) | |
25163 | + varv => varu | |
25164 | + varv(1, 1, 1) = 6 | |
25165 | + varv(1, 2, 3) = 7 | |
25166 | + l = associated (varv) | |
25167 | +end subroutine baz | |
25168 | +subroutine foo (vary, varw) | |
25169 | + real :: vary (:, :) | |
25170 | + real :: varw (:, :, :) | |
25171 | + vary(:, :) = 4 ! vary-passed | |
25172 | + vary(1, 1) = 8 | |
25173 | + vary(2, 2) = 9 | |
25174 | + vary(1, 3) = 10 | |
25175 | + varw(:, :, :) = 5 ! vary-filled | |
25176 | + varw(1, 1, 1) = 6 | |
25177 | + varw(2, 2, 2) = 7 ! varw-almostfilled | |
25178 | +end subroutine foo | |
25179 | +subroutine bar (varz, vart) | |
25180 | + real :: varz (*) | |
25181 | + real :: vart (2:11, 7:*) | |
25182 | + varz(1:3) = 4 | |
25183 | + varz(2) = 5 ! varz-almostfilled | |
25184 | + vart(2,7) = vart(2,7) | |
25185 | +end subroutine bar | |
25186 | +program test | |
25187 | + interface | |
25188 | + subroutine foo (vary, varw) | |
25189 | + real :: vary (:, :) | |
25190 | + real :: varw (:, :, :) | |
25191 | + end subroutine | |
25192 | + end interface | |
25193 | + interface | |
25194 | + subroutine bar (varz, vart) | |
25195 | + real :: varz (*) | |
25196 | + real :: vart (2:11, 7:*) | |
25197 | + end subroutine | |
25198 | + end interface | |
25199 | + real :: x (10, 10), y (5), z(8, 8, 8) | |
25200 | + x(:,:) = 1 | |
25201 | + y(:) = 2 | |
25202 | + z(:,:,:) = 3 | |
25203 | + call baz | |
25204 | + call foo (x, z(2:6, 4:7, 6:8)) | |
25205 | + call bar (y, x) | |
25206 | + if (x (1, 1) .ne. 8 .or. x (2, 2) .ne. 9 .or. x (1, 2) .ne. 4) call abort | |
25207 | + if (x (1, 3) .ne. 10) call abort | |
25208 | + if (z (2, 4, 6) .ne. 6 .or. z (3, 5, 7) .ne. 7 .or. z (2, 4, 7) .ne. 5) call abort | |
25209 | + if (any (y .ne. (/4, 5, 4, 2, 2/))) call abort | |
25210 | + call foo (transpose (x), z) | |
25211 | + if (x (1, 1) .ne. 8 .or. x (2, 2) .ne. 9 .or. x (1, 2) .ne. 4) call abort | |
25212 | + if (x (3, 1) .ne. 10) call abort | |
25213 | +end | |
25214 | diff --git a/gdb/testsuite/gdb.fortran/library-module-lib.f90 b/gdb/testsuite/gdb.fortran/library-module-lib.f90 | |
3a58abaf | 25215 | new file mode 100644 |
7566401a | 25216 | index 0000000..6369d34 |
3a58abaf | 25217 | --- /dev/null |
7566401a ER |
25218 | +++ b/gdb/testsuite/gdb.fortran/library-module-lib.f90 |
25219 | @@ -0,0 +1,28 @@ | |
25220 | +! Copyright 2009 Free Software Foundation, Inc. | |
25221 | +! | |
25222 | +! This program is free software; you can redistribute it and/or modify | |
25223 | +! it under the terms of the GNU General Public License as published by | |
25224 | +! the Free Software Foundation; either version 3 of the License, or | |
25225 | +! (at your option) any later version. | |
25226 | +! | |
25227 | +! This program is distributed in the hope that it will be useful, | |
25228 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25229 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25230 | +! GNU General Public License for more details. | |
25231 | +! | |
25232 | +! You should have received a copy of the GNU General Public License | |
25233 | +! along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25234 | + | |
25235 | +module lib | |
25236 | + integer :: var_i = 1 | |
25237 | +contains | |
25238 | + subroutine lib_func | |
25239 | + if (var_i .ne. 1) call abort | |
25240 | + var_i = 2 | |
25241 | + end subroutine lib_func | |
25242 | +end module lib | |
25243 | + | |
25244 | +module libmany | |
25245 | + integer :: var_j = 3 | |
25246 | + integer :: var_k = 4 | |
25247 | +end module libmany | |
25248 | diff --git a/gdb/testsuite/gdb.fortran/library-module-main.f90 b/gdb/testsuite/gdb.fortran/library-module-main.f90 | |
25249 | new file mode 100644 | |
25250 | index 0000000..de63a65 | |
25251 | --- /dev/null | |
25252 | +++ b/gdb/testsuite/gdb.fortran/library-module-main.f90 | |
25253 | @@ -0,0 +1,23 @@ | |
25254 | +! Copyright 2009 Free Software Foundation, Inc. | |
25255 | +! | |
25256 | +! This program is free software; you can redistribute it and/or modify | |
25257 | +! it under the terms of the GNU General Public License as published by | |
25258 | +! the Free Software Foundation; either version 3 of the License, or | |
25259 | +! (at your option) any later version. | |
25260 | +! | |
25261 | +! This program is distributed in the hope that it will be useful, | |
25262 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25263 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25264 | +! GNU General Public License for more details. | |
25265 | +! | |
25266 | +! You should have received a copy of the GNU General Public License | |
25267 | +! along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25268 | + | |
25269 | + use lib | |
25270 | + use libmany, only: var_j | |
25271 | + if (var_i .ne. 1) call abort | |
25272 | + call lib_func | |
25273 | + if (var_i .ne. 2) call abort | |
25274 | + if (var_j .ne. 3) call abort | |
25275 | + var_i = var_i ! i-is-2 | |
25276 | +end | |
25277 | diff --git a/gdb/testsuite/gdb.fortran/library-module.exp b/gdb/testsuite/gdb.fortran/library-module.exp | |
25278 | new file mode 100644 | |
25279 | index 0000000..4b4ea4c | |
25280 | --- /dev/null | |
25281 | +++ b/gdb/testsuite/gdb.fortran/library-module.exp | |
25282 | @@ -0,0 +1,53 @@ | |
25283 | +# Copyright 2009 Free Software Foundation, Inc. | |
3a58abaf AM |
25284 | + |
25285 | +# This program is free software; you can redistribute it and/or modify | |
25286 | +# it under the terms of the GNU General Public License as published by | |
25287 | +# the Free Software Foundation; either version 3 of the License, or | |
25288 | +# (at your option) any later version. | |
25289 | +# | |
25290 | +# This program is distributed in the hope that it will be useful, | |
25291 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25292 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25293 | +# GNU General Public License for more details. | |
25294 | +# | |
25295 | +# You should have received a copy of the GNU General Public License | |
25296 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25297 | + | |
7566401a ER |
25298 | +set testfile "library-module" |
25299 | +set srcfile ${testfile}-main.f90 | |
25300 | +set srclibfile ${testfile}-lib.f90 | |
25301 | +set libfile ${testfile}-lib.so | |
25302 | +set binfile ${testfile} | |
3a58abaf | 25303 | + |
7566401a ER |
25304 | +# Required for -fPIC by gdb_compile_shlib. |
25305 | +if [get_compiler_info not-used] { | |
25306 | + warning "Could not get compiler info" | |
25307 | + return -1 | |
3a58abaf AM |
25308 | +} |
25309 | + | |
7566401a ER |
25310 | +if { [gdb_compile_shlib "${srcdir}/${subdir}/${srclibfile}" $objdir/$subdir/$libfile {debug f77}] != "" } { |
25311 | + untested "Couldn't compile ${srclibfile}" | |
25312 | + return -1 | |
3a58abaf AM |
25313 | +} |
25314 | + | |
7566401a ER |
25315 | +# prepare_for_testing cannot be used as linking with $libfile cannot be passed |
25316 | +# just for the linking phase (and not the source compilation phase). And any | |
25317 | +# warnings on ignored $libfile abort the process. | |
3a58abaf | 25318 | + |
7566401a ER |
25319 | +if { [gdb_compile [list $srcdir/$subdir/$srcfile $objdir/$subdir/$libfile] $objdir/$subdir/$binfile executable {debug f77}] != "" } { |
25320 | + untested "Couldn't compile ${srcfile}" | |
25321 | + return -1 | |
25322 | +} | |
3a58abaf | 25323 | + |
7566401a ER |
25324 | +clean_restart $binfile |
25325 | + | |
25326 | +if ![runto MAIN__] then { | |
25327 | + perror "couldn't run to breakpoint MAIN__" | |
25328 | + continue | |
25329 | +} | |
25330 | + | |
25331 | +gdb_breakpoint [gdb_get_line_number "i-is-2"] | |
25332 | +gdb_continue_to_breakpoint "i-is-2" ".*i-is-2.*" | |
25333 | +gdb_test "print var_i" " = 2" | |
25334 | +gdb_test "print var_j" " = 3" | |
25335 | +gdb_test "print var_k" "No symbol \"var_k\" in current context\\." | |
25336 | diff --git a/gdb/testsuite/gdb.fortran/logical.exp b/gdb/testsuite/gdb.fortran/logical.exp | |
3a58abaf | 25337 | new file mode 100644 |
7566401a | 25338 | index 0000000..ef76f43 |
3a58abaf | 25339 | --- /dev/null |
7566401a ER |
25340 | +++ b/gdb/testsuite/gdb.fortran/logical.exp |
25341 | @@ -0,0 +1,44 @@ | |
25342 | +# Copyright 2007 Free Software Foundation, Inc. | |
3a58abaf AM |
25343 | + |
25344 | +# This program is free software; you can redistribute it and/or modify | |
25345 | +# it under the terms of the GNU General Public License as published by | |
7566401a | 25346 | +# the Free Software Foundation; either version 2 of the License, or |
3a58abaf | 25347 | +# (at your option) any later version. |
7566401a | 25348 | +# |
3a58abaf AM |
25349 | +# This program is distributed in the hope that it will be useful, |
25350 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25351 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25352 | +# GNU General Public License for more details. | |
7566401a | 25353 | +# |
3a58abaf | 25354 | +# You should have received a copy of the GNU General Public License |
7566401a ER |
25355 | +# along with this program; if not, write to the Free Software |
25356 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
3a58abaf | 25357 | + |
7566401a | 25358 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. |
3a58abaf | 25359 | + |
7566401a ER |
25360 | +set testfile "logical" |
25361 | +set srcfile ${testfile}.f90 | |
3a58abaf | 25362 | +set binfile ${objdir}/${subdir}/${testfile} |
3a58abaf | 25363 | + |
7566401a ER |
25364 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } { |
25365 | + untested "Couldn't compile ${srcfile}" | |
3a58abaf AM |
25366 | + return -1 |
25367 | +} | |
25368 | + | |
7566401a ER |
25369 | +gdb_exit |
25370 | +gdb_start | |
25371 | +gdb_reinitialize_dir $srcdir/$subdir | |
25372 | +gdb_load ${binfile} | |
3a58abaf | 25373 | + |
7566401a ER |
25374 | +if ![runto MAIN__] then { |
25375 | + perror "couldn't run to breakpoint MAIN__" | |
25376 | + continue | |
25377 | +} | |
3a58abaf | 25378 | + |
7566401a ER |
25379 | +gdb_breakpoint [gdb_get_line_number "stop-here"] |
25380 | +gdb_continue_to_breakpoint "stop-here" | |
25381 | +gdb_test "p l" " = \\.TRUE\\." | |
25382 | +gdb_test "p l1" " = \\.TRUE\\." | |
25383 | +gdb_test "p l2" " = \\.TRUE\\." | |
25384 | +gdb_test "p l4" " = \\.TRUE\\." | |
25385 | +gdb_test "p l8" " = \\.TRUE\\." | |
25386 | diff --git a/gdb/testsuite/gdb.fortran/logical.f90 b/gdb/testsuite/gdb.fortran/logical.f90 | |
3a58abaf | 25387 | new file mode 100644 |
7566401a | 25388 | index 0000000..4229304 |
3a58abaf | 25389 | --- /dev/null |
7566401a ER |
25390 | +++ b/gdb/testsuite/gdb.fortran/logical.f90 |
25391 | @@ -0,0 +1,33 @@ | |
25392 | +! Copyright 2008 Free Software Foundation, Inc. | |
25393 | +! | |
25394 | +! This program is free software; you can redistribute it and/or modify | |
25395 | +! it under the terms of the GNU General Public License as published by | |
25396 | +! the Free Software Foundation; either version 2 of the License, or | |
25397 | +! (at your option) any later version. | |
25398 | +! | |
25399 | +! This program is distributed in the hope that it will be useful, | |
25400 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25401 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25402 | +! GNU General Public License for more details. | |
25403 | +! | |
25404 | +! You should have received a copy of the GNU General Public License | |
25405 | +! along with this program; if not, write to the Free Software | |
25406 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25407 | +! | |
25408 | +! Ihis file is the Fortran source file for dynamic.exp. | |
25409 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
25410 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
3a58abaf | 25411 | + |
7566401a ER |
25412 | +program test |
25413 | + logical :: l | |
25414 | + logical (kind=1) :: l1 | |
25415 | + logical (kind=2) :: l2 | |
25416 | + logical (kind=4) :: l4 | |
25417 | + logical (kind=8) :: l8 | |
25418 | + l = .TRUE. | |
25419 | + l1 = .TRUE. | |
25420 | + l2 = .TRUE. | |
25421 | + l4 = .TRUE. | |
25422 | + l8 = .TRUE. | |
25423 | + l = .FALSE. ! stop-here | |
25424 | +end | |
25425 | diff --git a/gdb/testsuite/gdb.fortran/module.exp b/gdb/testsuite/gdb.fortran/module.exp | |
25426 | index 342ccee..c836c3c 100644 | |
25427 | --- a/gdb/testsuite/gdb.fortran/module.exp | |
25428 | +++ b/gdb/testsuite/gdb.fortran/module.exp | |
25429 | @@ -15,21 +15,31 @@ | |
25430 | ||
25431 | set testfile "module" | |
25432 | set srcfile ${testfile}.f90 | |
25433 | -set binfile ${objdir}/${subdir}/${testfile} | |
25434 | ||
25435 | -if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } { | |
25436 | - untested "Couldn't compile ${srcfile}" | |
25437 | +if { [prepare_for_testing $testfile.exp $testfile $srcfile {debug f77}] } { | |
25438 | return -1 | |
25439 | } | |
25440 | ||
25441 | -gdb_exit | |
25442 | -gdb_start | |
25443 | -gdb_reinitialize_dir $srcdir/$subdir | |
25444 | -gdb_load ${binfile} | |
25445 | - | |
25446 | if ![runto MAIN__] then { | |
25447 | perror "couldn't run to breakpoint MAIN__" | |
25448 | continue | |
25449 | } | |
25450 | ||
25451 | -gdb_test "print i" " = 42" | |
25452 | +# Do not use simple single-letter names as GDB would pick up for expectedly | |
25453 | +# nonexisting symbols some static variables from system libraries debuginfos. | |
25454 | + | |
25455 | +gdb_breakpoint [gdb_get_line_number "i-is-1"] | |
25456 | +gdb_continue_to_breakpoint "i-is-1" ".*i-is-1.*" | |
25457 | +gdb_test "print var_i" " = 1" "print var_i value 1" | |
25458 | + | |
25459 | +gdb_breakpoint [gdb_get_line_number "i-is-2"] | |
25460 | +gdb_continue_to_breakpoint "i-is-2" ".*i-is-2.*" | |
25461 | +gdb_test "print var_i" " = 2" "print var_i value 2" | |
25462 | + | |
25463 | +gdb_breakpoint [gdb_get_line_number "a-b-c-d"] | |
25464 | +gdb_continue_to_breakpoint "a-b-c-d" ".*a-b-c-d.*" | |
25465 | +gdb_test "print var_a" "No symbol \"var_a\" in current context\\." | |
25466 | +gdb_test "print var_b" " = 11" | |
25467 | +gdb_test "print var_c" "No symbol \"var_c\" in current context\\." | |
25468 | +gdb_test "print var_d" " = 12" | |
25469 | +gdb_test "print var_i" " = 14" "print var_i value 14" | |
25470 | diff --git a/gdb/testsuite/gdb.fortran/module.f90 b/gdb/testsuite/gdb.fortran/module.f90 | |
25471 | index 501ccc8..118931d 100644 | |
25472 | --- a/gdb/testsuite/gdb.fortran/module.f90 | |
25473 | +++ b/gdb/testsuite/gdb.fortran/module.f90 | |
25474 | @@ -13,10 +13,37 @@ | |
25475 | ! You should have received a copy of the GNU General Public License | |
25476 | ! along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25477 | ||
25478 | -module mod | |
25479 | - integer :: i = 42 | |
25480 | -end module mod | |
25481 | +module mod1 | |
25482 | + integer :: var_i = 1 | |
25483 | +end module mod1 | |
25484 | ||
25485 | - use mod | |
25486 | - print *, i | |
25487 | +module mod2 | |
25488 | + integer :: var_i = 2 | |
25489 | +end module mod2 | |
25490 | + | |
25491 | +module modmany | |
25492 | + integer :: var_a = 10, var_b = 11, var_c = 12, var_i = 14 | |
25493 | +end module modmany | |
25494 | + | |
25495 | + subroutine sub1 | |
25496 | + use mod1 | |
25497 | + if (var_i .ne. 1) call abort | |
25498 | + var_i = var_i ! i-is-1 | |
25499 | + end | |
25500 | + | |
25501 | + subroutine sub2 | |
25502 | + use mod2 | |
25503 | + if (var_i .ne. 2) call abort | |
25504 | + var_i = var_i ! i-is-2 | |
25505 | + end | |
25506 | + | |
25507 | + use modmany, only: var_b, var_d => var_c, var_i | |
25508 | + | |
25509 | + call sub1 | |
25510 | + call sub2 | |
25511 | + | |
25512 | + if (var_b .ne. 11) call abort | |
25513 | + if (var_d .ne. 12) call abort | |
25514 | + if (var_i .ne. 14) call abort | |
25515 | + var_b = var_b ! a-b-c-d | |
25516 | end | |
25517 | diff --git a/gdb/testsuite/gdb.fortran/string.exp b/gdb/testsuite/gdb.fortran/string.exp | |
25518 | new file mode 100644 | |
25519 | index 0000000..b1120c3 | |
25520 | --- /dev/null | |
25521 | +++ b/gdb/testsuite/gdb.fortran/string.exp | |
25522 | @@ -0,0 +1,59 @@ | |
25523 | +# Copyright 2008 Free Software Foundation, Inc. | |
3a58abaf | 25524 | + |
7566401a ER |
25525 | +# This program is free software; you can redistribute it and/or modify |
25526 | +# it under the terms of the GNU General Public License as published by | |
25527 | +# the Free Software Foundation; either version 2 of the License, or | |
25528 | +# (at your option) any later version. | |
25529 | +# | |
25530 | +# This program is distributed in the hope that it will be useful, | |
25531 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25532 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25533 | +# GNU General Public License for more details. | |
25534 | +# | |
25535 | +# You should have received a copy of the GNU General Public License | |
25536 | +# along with this program; if not, write to the Free Software | |
25537 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
3a58abaf | 25538 | + |
7566401a | 25539 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. |
3a58abaf | 25540 | + |
7566401a ER |
25541 | +# This file is part of the gdb testsuite. It contains tests for Fortran |
25542 | +# strings with dynamic length. | |
3a58abaf | 25543 | + |
7566401a ER |
25544 | +set testfile "string" |
25545 | +set srcfile ${testfile}.f90 | |
25546 | +set binfile ${objdir}/${subdir}/${testfile} | |
3a58abaf | 25547 | + |
7566401a ER |
25548 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } { |
25549 | + untested "Couldn't compile ${srcfile}" | |
25550 | + return -1 | |
3a58abaf AM |
25551 | +} |
25552 | + | |
7566401a ER |
25553 | +gdb_exit |
25554 | +gdb_start | |
25555 | +gdb_reinitialize_dir $srcdir/$subdir | |
25556 | +gdb_load ${binfile} | |
3a58abaf | 25557 | + |
7566401a ER |
25558 | +if ![runto MAIN__] then { |
25559 | + perror "couldn't run to breakpoint MAIN__" | |
25560 | + continue | |
3a58abaf AM |
25561 | +} |
25562 | + | |
7566401a ER |
25563 | +gdb_breakpoint [gdb_get_line_number "var-init"] |
25564 | +gdb_continue_to_breakpoint "var-init" | |
25565 | +gdb_test "ptype c" "type = character(\\(kind=1\\)|\\*1)" | |
25566 | +gdb_test "ptype d" "type = character(\\(kind=8\\)|\\*8)" | |
25567 | +gdb_test "ptype e" "type = character(\\(kind=4\\)|\\*4)" | |
25568 | +gdb_test "ptype f" "type = character(\\(kind=4\\)|\\*4) \\(7,8:10\\)" | |
25569 | +gdb_test "ptype *e" "Attempt to take contents of a non-pointer value." | |
25570 | +gdb_test "ptype *f" "type = character(\\(kind=4\\)|\\*4) \\(7\\)" | |
25571 | +gdb_test "p c" "\\$\[0-9\]* = 'c'" | |
25572 | +gdb_test "p d" "\\$\[0-9\]* = 'd '" | |
25573 | +gdb_test "p e" "\\$\[0-9\]* = 'g '" | |
25574 | +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 '\\) \\)" | |
25575 | +gdb_test "p *e" "Attempt to take contents of a non-pointer value." | |
25576 | +gdb_test "p *f" "Attempt to take contents of a non-pointer value." | |
3a58abaf | 25577 | + |
7566401a ER |
25578 | +gdb_breakpoint [gdb_get_line_number "var-finish"] |
25579 | +gdb_continue_to_breakpoint "var-finish" | |
25580 | +gdb_test "p e" "\\$\[0-9\]* = 'e '" "p e re-set" | |
25581 | +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" | |
25582 | diff --git a/gdb/testsuite/gdb.fortran/string.f90 b/gdb/testsuite/gdb.fortran/string.f90 | |
25583 | new file mode 100644 | |
25584 | index 0000000..226dc5d | |
25585 | --- /dev/null | |
25586 | +++ b/gdb/testsuite/gdb.fortran/string.f90 | |
25587 | @@ -0,0 +1,37 @@ | |
25588 | +! Copyright 2008 Free Software Foundation, Inc. | |
25589 | +! | |
25590 | +! This program is free software; you can redistribute it and/or modify | |
25591 | +! it under the terms of the GNU General Public License as published by | |
25592 | +! the Free Software Foundation; either version 2 of the License, or | |
25593 | +! (at your option) any later version. | |
25594 | +! | |
25595 | +! This program is distributed in the hope that it will be useful, | |
25596 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25597 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25598 | +! GNU General Public License for more details. | |
25599 | +! | |
25600 | +! You should have received a copy of the GNU General Public License | |
25601 | +! along with this program; if not, write to the Free Software | |
25602 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25603 | +! | |
25604 | +! Ihis file is the Fortran source file for dynamic.exp. | |
25605 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
25606 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
3a58abaf | 25607 | + |
7566401a ER |
25608 | +subroutine foo (e, f) |
25609 | + character (len=1) :: c | |
25610 | + character (len=8) :: d | |
25611 | + character (len=*) :: e | |
25612 | + character (len=*) :: f (1:7, 8:10) | |
25613 | + c = 'c' | |
25614 | + d = 'd' | |
25615 | + e = 'e' ! var-init | |
25616 | + f = 'f' | |
25617 | + f(1,9) = 'f2' | |
25618 | + c = 'c' ! var-finish | |
25619 | +end subroutine foo | |
25620 | + character (len=4) :: g, h (1:7, 8:10) | |
25621 | + g = 'g' | |
25622 | + h = 'h' | |
25623 | + call foo (g, h) | |
25624 | +end | |
25625 | diff --git a/gdb/testsuite/gdb.gdb/selftest.exp b/gdb/testsuite/gdb.gdb/selftest.exp | |
25626 | index 495ae45..d08d7a4 100644 | |
25627 | --- a/gdb/testsuite/gdb.gdb/selftest.exp | |
25628 | +++ b/gdb/testsuite/gdb.gdb/selftest.exp | |
25629 | @@ -95,6 +95,10 @@ proc do_steps_and_nexts {} { | |
25630 | set description "step over ttyarg initialization" | |
25631 | set command "step" | |
25632 | } | |
25633 | + -re ".*python_script = 0.*$gdb_prompt $" { | |
25634 | + set description "step over python_script initialization" | |
25635 | + set command "step" | |
25636 | + } | |
25637 | -re ".*time_at_startup = get_run_time.*$gdb_prompt $" { | |
25638 | set description "next over get_run_time and everything it calls" | |
25639 | set command "next" | |
25640 | diff --git a/gdb/testsuite/gdb.java/jnpe.exp b/gdb/testsuite/gdb.java/jnpe.exp | |
3a58abaf | 25641 | new file mode 100644 |
ab050a48 | 25642 | index 0000000..e71391e |
3a58abaf | 25643 | --- /dev/null |
7566401a | 25644 | +++ b/gdb/testsuite/gdb.java/jnpe.exp |
ab050a48 | 25645 | @@ -0,0 +1,77 @@ |
7566401a | 25646 | +# Copyright 2009 Free Software Foundation, Inc. |
3a58abaf AM |
25647 | + |
25648 | +# This program is free software; you can redistribute it and/or modify | |
25649 | +# it under the terms of the GNU General Public License as published by | |
25650 | +# the Free Software Foundation; either version 3 of the License, or | |
25651 | +# (at your option) any later version. | |
25652 | +# | |
25653 | +# This program is distributed in the hope that it will be useful, | |
25654 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25655 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25656 | +# GNU General Public License for more details. | |
25657 | +# | |
25658 | +# You should have received a copy of the GNU General Public License | |
25659 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25660 | + | |
3a58abaf | 25661 | +if $tracelevel then { |
7566401a | 25662 | + strace $tracelevel |
3a58abaf AM |
25663 | +} |
25664 | + | |
7566401a ER |
25665 | +load_lib "java.exp" |
25666 | + | |
25667 | +set testfile "jnpe" | |
ab050a48 | 25668 | +set srcfile ${testfile}.java |
3a58abaf | 25669 | +set binfile ${objdir}/${subdir}/${testfile} |
ab050a48 BZ |
25670 | +if { [compile_java_from_source ${srcdir}/$subdir/${srcfile} ${binfile} "-g"] != "" } { |
25671 | + untested "Couldn't compile ${srcdir}/$subdir/${srcfile}" | |
7566401a ER |
25672 | + return -1 |
25673 | +} | |
25674 | + | |
25675 | +set prms_id 0 | |
25676 | +set bug_id 0 | |
3a58abaf AM |
25677 | + |
25678 | +# Start with a fresh gdb. | |
7566401a | 25679 | + |
3a58abaf AM |
25680 | +gdb_exit |
25681 | +gdb_start | |
7566401a ER |
25682 | +gdb_reinitialize_dir $srcdir/$subdir |
25683 | +gdb_load ${binfile} | |
3a58abaf | 25684 | + |
7566401a ER |
25685 | +set line [gdb_get_line_number "break here" $testfile.java] |
25686 | +gdb_test "break $testfile.java:$line" "" | |
3a58abaf | 25687 | + |
7566401a | 25688 | +gdb_test "run" \ |
ab050a48 | 25689 | + "// break here.*" \ |
7566401a | 25690 | + "run java next-over-throw" |
3a58abaf | 25691 | + |
7566401a ER |
25692 | +# See whether we have the needed unwinder hooks. |
25693 | +set ok 1 | |
25694 | +gdb_test_multiple "print _Unwind_DebugHook" "check for unwinder hook in java" { | |
25695 | + -re "= .*_Unwind_DebugHook.*\r\n$gdb_prompt $" { | |
25696 | + pass "check for unwinder hook in java" | |
3a58abaf | 25697 | + } |
ab050a48 | 25698 | + -re "No symbol .* in current context.?\r\n$gdb_prompt $" { |
7566401a | 25699 | + # Pass the test so we don't get bogus fails in the results. |
ab050a48 BZ |
25700 | + setup_xfail *-*-* |
25701 | + fail "check for unwinder hook in java" | |
7566401a | 25702 | + set ok 0 |
3a58abaf | 25703 | + } |
7566401a ER |
25704 | +} |
25705 | +if {!$ok} { | |
25706 | + untested jnpe.exp | |
25707 | + return -1 | |
3a58abaf AM |
25708 | +} |
25709 | + | |
7566401a ER |
25710 | +gdb_test "handle SIGSEGV nostop noprint" \ |
25711 | + "SIGSEGV.*fault" \ | |
25712 | + "disable SIGSEGV for next-over-NPE" | |
25713 | + | |
ab050a48 BZ |
25714 | +# The line where we stop differ according to gcj; check just we did not already |
25715 | +# execute the catch point. | |
25716 | + | |
7566401a | 25717 | +gdb_test "next" \ |
ab050a48 | 25718 | + "" \ |
7566401a | 25719 | + "next over NPE" |
ab050a48 BZ |
25720 | + |
25721 | +gdb_breakpoint [gdb_get_line_number "catch point"] | |
25722 | +gdb_continue_to_breakpoint "catch point" ".*// catch point.*" | |
7566401a | 25723 | diff --git a/gdb/testsuite/gdb.java/jnpe.java b/gdb/testsuite/gdb.java/jnpe.java |
3a58abaf | 25724 | new file mode 100644 |
ab050a48 | 25725 | index 0000000..3524830 |
3a58abaf | 25726 | --- /dev/null |
7566401a ER |
25727 | +++ b/gdb/testsuite/gdb.java/jnpe.java |
25728 | @@ -0,0 +1,38 @@ | |
25729 | +// Test next-over-NPE. | |
25730 | +/* This testcase is part of GDB, the GNU debugger. | |
3a58abaf | 25731 | + |
7566401a | 25732 | + Copyright 2009 Free Software Foundation, Inc. |
3a58abaf | 25733 | + |
7566401a ER |
25734 | + This program is free software; you can redistribute it and/or modify |
25735 | + it under the terms of the GNU General Public License as published by | |
25736 | + the Free Software Foundation; either version 3 of the License, or | |
25737 | + (at your option) any later version. | |
3a58abaf | 25738 | + |
7566401a ER |
25739 | + This program is distributed in the hope that it will be useful, |
25740 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25741 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25742 | + GNU General Public License for more details. | |
3a58abaf | 25743 | + |
7566401a ER |
25744 | + You should have received a copy of the GNU General Public License |
25745 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25746 | + */ | |
3a58abaf | 25747 | + |
7566401a ER |
25748 | +public class jnpe |
25749 | +{ | |
25750 | + public static String npe () | |
25751 | + { | |
25752 | + return ((Object) null).toString(); | |
25753 | + } | |
3a58abaf | 25754 | + |
7566401a ER |
25755 | + public static void main (String[] args) |
25756 | + { | |
25757 | + try | |
25758 | + { | |
25759 | + System.out.println (npe ()); // break here | |
25760 | + } | |
25761 | + catch (NullPointerException n) | |
25762 | + { | |
ab050a48 | 25763 | + System.out.println ("success"); // catch point |
7566401a ER |
25764 | + } |
25765 | + } | |
25766 | +} | |
25767 | diff --git a/gdb/testsuite/gdb.opt/array-from-register-func.c b/gdb/testsuite/gdb.opt/array-from-register-func.c | |
25768 | new file mode 100644 | |
25769 | index 0000000..729f457 | |
25770 | --- /dev/null | |
25771 | +++ b/gdb/testsuite/gdb.opt/array-from-register-func.c | |
25772 | @@ -0,0 +1,22 @@ | |
25773 | +/* This file is part of GDB, the GNU debugger. | |
3a58abaf | 25774 | + |
7566401a | 25775 | + Copyright 2009 Free Software Foundation, Inc. |
3a58abaf | 25776 | + |
7566401a ER |
25777 | + This program is free software; you can redistribute it and/or modify |
25778 | + it under the terms of the GNU General Public License as published by | |
25779 | + the Free Software Foundation; either version 3 of the License, or | |
25780 | + (at your option) any later version. | |
3a58abaf | 25781 | + |
7566401a ER |
25782 | + This program is distributed in the hope that it will be useful, |
25783 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25784 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25785 | + GNU General Public License for more details. | |
3a58abaf | 25786 | + |
7566401a ER |
25787 | + You should have received a copy of the GNU General Public License |
25788 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
3a58abaf | 25789 | + |
7566401a ER |
25790 | +int |
25791 | +func (int *arr) | |
25792 | +{ | |
25793 | + return arr[0]; | |
25794 | +} | |
25795 | diff --git a/gdb/testsuite/gdb.opt/array-from-register.c b/gdb/testsuite/gdb.opt/array-from-register.c | |
3a58abaf | 25796 | new file mode 100644 |
7566401a | 25797 | index 0000000..3090e7e |
3a58abaf | 25798 | --- /dev/null |
7566401a ER |
25799 | +++ b/gdb/testsuite/gdb.opt/array-from-register.c |
25800 | @@ -0,0 +1,28 @@ | |
25801 | +/* This file is part of GDB, the GNU debugger. | |
3a58abaf | 25802 | + |
7566401a | 25803 | + Copyright 2009 Free Software Foundation, Inc. |
3a58abaf AM |
25804 | + |
25805 | + This program is free software; you can redistribute it and/or modify | |
25806 | + it under the terms of the GNU General Public License as published by | |
25807 | + the Free Software Foundation; either version 3 of the License, or | |
25808 | + (at your option) any later version. | |
25809 | + | |
25810 | + This program is distributed in the hope that it will be useful, | |
25811 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25812 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25813 | + GNU General Public License for more details. | |
25814 | + | |
25815 | + You should have received a copy of the GNU General Public License | |
25816 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
25817 | + | |
7566401a | 25818 | +extern int func (int *arr); |
3a58abaf | 25819 | + |
7566401a ER |
25820 | +int |
25821 | +main (void) | |
3a58abaf | 25822 | +{ |
7566401a ER |
25823 | + int arr[] = { 42 }; |
25824 | + | |
25825 | + func (arr); | |
25826 | + | |
25827 | + return 0; | |
3a58abaf | 25828 | +} |
7566401a | 25829 | diff --git a/gdb/testsuite/gdb.opt/array-from-register.exp b/gdb/testsuite/gdb.opt/array-from-register.exp |
3a58abaf | 25830 | new file mode 100644 |
7566401a | 25831 | index 0000000..f2de718 |
3a58abaf | 25832 | --- /dev/null |
7566401a ER |
25833 | +++ b/gdb/testsuite/gdb.opt/array-from-register.exp |
25834 | @@ -0,0 +1,33 @@ | |
25835 | +# Copyright 2009 Free Software Foundation, Inc. | |
25836 | +# | |
3a58abaf AM |
25837 | +# This program is free software; you can redistribute it and/or modify |
25838 | +# it under the terms of the GNU General Public License as published by | |
7566401a | 25839 | +# the Free Software Foundation; either version 2 of the License, or |
3a58abaf AM |
25840 | +# (at your option) any later version. |
25841 | +# | |
25842 | +# This program is distributed in the hope that it will be useful, | |
25843 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25844 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25845 | +# GNU General Public License for more details. | |
25846 | +# | |
25847 | +# You should have received a copy of the GNU General Public License | |
7566401a ER |
25848 | +# along with this program; if not, write to the Free Software |
25849 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25850 | +# | |
25851 | +# This file is part of the gdb testsuite. | |
3a58abaf | 25852 | + |
7566401a ER |
25853 | +if { [prepare_for_testing array-from-register.exp "array-from-register" \ |
25854 | + {array-from-register.c array-from-register-func.c} \ | |
25855 | + {debug optimize=-O2}] } { | |
3a58abaf AM |
25856 | + return -1 |
25857 | +} | |
25858 | + | |
7566401a ER |
25859 | +if ![runto func] then { |
25860 | + return -1 | |
3a58abaf AM |
25861 | +} |
25862 | + | |
7566401a | 25863 | +gdb_test "p arr" "\\$\[0-9\]+ = \\(int \\*\\) *0x\[0-9a-f\]+" |
3a58abaf | 25864 | + |
7566401a ER |
25865 | +# Seen regression: |
25866 | +# Address requested for identifier "arr" which is in register $rdi | |
25867 | +gdb_test "p arr\[0\]" "\\$\[0-9\]+ = 42" | |
25868 | diff --git a/gdb/testsuite/gdb.opt/fortran-string.exp b/gdb/testsuite/gdb.opt/fortran-string.exp | |
25869 | new file mode 100644 | |
25870 | index 0000000..f997eec | |
25871 | --- /dev/null | |
25872 | +++ b/gdb/testsuite/gdb.opt/fortran-string.exp | |
25873 | @@ -0,0 +1,41 @@ | |
25874 | +# Copyright 2009 Free Software Foundation, Inc. | |
3a58abaf | 25875 | + |
7566401a ER |
25876 | +# This program is free software; you can redistribute it and/or modify |
25877 | +# it under the terms of the GNU General Public License as published by | |
25878 | +# the Free Software Foundation; either version 2 of the License, or | |
25879 | +# (at your option) any later version. | |
25880 | +# | |
25881 | +# This program is distributed in the hope that it will be useful, | |
25882 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25883 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25884 | +# GNU General Public License for more details. | |
25885 | +# | |
25886 | +# You should have received a copy of the GNU General Public License | |
25887 | +# along with this program; if not, write to the Free Software | |
25888 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
3a58abaf | 25889 | + |
7566401a | 25890 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. |
3a58abaf | 25891 | + |
7566401a ER |
25892 | +# Test GDB can cope with Fortran strings having their length present in a CPU |
25893 | +# register. With -O0 the string length is passed on the stack. To make this | |
25894 | +# test meaningful the follow assertion should pass. It is not being checked | |
25895 | +# here as the "_s" symbol is compiler dependent: | |
25896 | +# (gdb) info address _s | |
25897 | +# Symbol "_s" is a variable in register XX. | |
3a58abaf | 25898 | + |
7566401a ER |
25899 | +set test fortran-string |
25900 | +set srcfile ${test}.f90 | |
25901 | +if { [prepare_for_testing ${test}.exp ${test} ${srcfile} {debug f77 additional_flags=-O2}] } { | |
25902 | + return -1 | |
3a58abaf AM |
25903 | +} |
25904 | + | |
7566401a ER |
25905 | +if ![runto MAIN__] then { |
25906 | + perror "couldn't run to breakpoint MAIN__" | |
25907 | + continue | |
25908 | +} | |
3a58abaf | 25909 | + |
7566401a ER |
25910 | +gdb_breakpoint [gdb_get_line_number "s = s"] |
25911 | +gdb_continue_to_breakpoint "s = s" | |
25912 | +gdb_test "frame" ".*s='foo'.*" | |
25913 | +gdb_test "ptype s" "type = character\\*3" | |
25914 | +gdb_test "p s" "\\$\[0-9\]* = 'foo'" | |
25915 | diff --git a/gdb/testsuite/gdb.opt/fortran-string.f90 b/gdb/testsuite/gdb.opt/fortran-string.f90 | |
25916 | new file mode 100644 | |
25917 | index 0000000..e48d520 | |
25918 | --- /dev/null | |
25919 | +++ b/gdb/testsuite/gdb.opt/fortran-string.f90 | |
25920 | @@ -0,0 +1,28 @@ | |
25921 | +! Copyright 2009 Free Software Foundation, Inc. | |
25922 | +! | |
25923 | +! This program is free software; you can redistribute it and/or modify | |
25924 | +! it under the terms of the GNU General Public License as published by | |
25925 | +! the Free Software Foundation; either version 2 of the License, or | |
25926 | +! (at your option) any later version. | |
25927 | +! | |
25928 | +! This program is distributed in the hope that it will be useful, | |
25929 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25930 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25931 | +! GNU General Public License for more details. | |
25932 | +! | |
25933 | +! You should have received a copy of the GNU General Public License | |
25934 | +! along with this program; if not, write to the Free Software | |
25935 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25936 | +! | |
25937 | +! Ihis file is the Fortran source file for dynamic.exp. | |
25938 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
25939 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
3a58abaf | 25940 | + |
7566401a ER |
25941 | + subroutine f(s) |
25942 | + character*(*) s | |
25943 | + s = s | |
25944 | + end | |
25945 | + | |
25946 | + program main | |
25947 | + call f ('foo') | |
25948 | + end | |
25949 | diff --git a/gdb/testsuite/gdb.python/py-cmd.exp b/gdb/testsuite/gdb.python/py-cmd.exp | |
25950 | index f6ef938..1032a2d 100644 | |
25951 | --- a/gdb/testsuite/gdb.python/py-cmd.exp | |
25952 | +++ b/gdb/testsuite/gdb.python/py-cmd.exp | |
25953 | @@ -20,36 +20,15 @@ if $tracelevel then { | |
25954 | strace $tracelevel | |
3a58abaf AM |
25955 | } |
25956 | ||
7566401a ER |
25957 | -# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}... |
25958 | -# Run a test named NAME, consisting of multiple lines of input. | |
25959 | -# After each input line INPUT, search for result line RESULT. | |
25960 | -# Succeed if all results are seen; fail otherwise. | |
25961 | -proc gdb_py_test_multiple {name args} { | |
25962 | - global gdb_prompt | |
25963 | - foreach {input result} $args { | |
25964 | - if {[gdb_test_multiple $input "$name - $input" { | |
25965 | - -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" { | |
25966 | - pass "$name - $input" | |
25967 | - } | |
25968 | - }]} { | |
25969 | - return 1 | |
25970 | - } | |
25971 | - } | |
25972 | - return 0 | |
25973 | -} | |
25974 | - | |
25975 | # Start with a fresh gdb. | |
3a58abaf | 25976 | |
7566401a ER |
25977 | gdb_exit |
25978 | gdb_start | |
25979 | gdb_reinitialize_dir $srcdir/$subdir | |
3a58abaf | 25980 | |
7566401a ER |
25981 | -gdb_test_multiple "python print 'hello, world!'" "verify python support" { |
25982 | - -re "not supported.*$gdb_prompt $" { | |
25983 | - unsupported "python support is disabled" | |
25984 | - return -1 | |
25985 | - } | |
25986 | - -re "$gdb_prompt $" {} | |
25987 | +if ![python_supported] then { | |
25988 | + unsupported "python support is disabled" | |
25989 | + return -1 | |
3a58abaf AM |
25990 | } |
25991 | ||
7566401a ER |
25992 | # Test a simple command. |
25993 | diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp | |
25994 | index a67eaa3..5380c0f 100644 | |
25995 | --- a/gdb/testsuite/gdb.python/py-frame.exp | |
25996 | +++ b/gdb/testsuite/gdb.python/py-frame.exp | |
25997 | @@ -20,40 +20,28 @@ if $tracelevel then { | |
25998 | strace $tracelevel | |
3a58abaf AM |
25999 | } |
26000 | ||
7566401a | 26001 | +# Start with a fresh gdb. |
3a58abaf | 26002 | + |
7566401a ER |
26003 | +gdb_exit |
26004 | +gdb_start | |
26005 | +gdb_reinitialize_dir $srcdir/$subdir | |
3a58abaf | 26006 | + |
7566401a ER |
26007 | +if ![python_supported] then { |
26008 | + unsupported "python support is disabled" | |
26009 | + return -1 | |
3a58abaf AM |
26010 | +} |
26011 | + | |
7566401a ER |
26012 | set testfile "py-frame" |
26013 | set srcfile ${testfile}.c | |
26014 | set binfile ${objdir}/${subdir}/${testfile} | |
26015 | + | |
26016 | if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
26017 | untested "Couldn't compile ${srcfile}" | |
26018 | return -1 | |
26019 | } | |
3a58abaf | 26020 | |
7566401a ER |
26021 | -# Run a command in GDB, and report a failure if a Python exception is thrown. |
26022 | -# If report_pass is true, report a pass if no exception is thrown. | |
26023 | -proc gdb_py_test_silent_cmd {cmd name report_pass} { | |
26024 | - global gdb_prompt | |
26025 | - | |
26026 | - gdb_test_multiple $cmd $name { | |
26027 | - -re "Traceback.*$gdb_prompt $" { fail $name } | |
26028 | - -re "$gdb_prompt $" { if $report_pass { pass $name } } | |
26029 | - } | |
26030 | -} | |
26031 | - | |
26032 | -# Start with a fresh gdb. | |
26033 | - | |
26034 | -gdb_exit | |
26035 | -gdb_start | |
26036 | -gdb_reinitialize_dir $srcdir/$subdir | |
26037 | gdb_load ${binfile} | |
3a58abaf | 26038 | |
7566401a ER |
26039 | -gdb_test_multiple "python print 'hello, world!'" "verify python support" { |
26040 | - -re "not supported.*$gdb_prompt $" { | |
26041 | - unsupported "python support is disabled" | |
26042 | - return -1 | |
26043 | - } | |
26044 | - -re "$gdb_prompt $" {} | |
26045 | -} | |
26046 | - | |
26047 | # The following tests require execution. | |
26048 | ||
26049 | if ![runto_main] then { | |
26050 | @@ -65,19 +53,20 @@ gdb_breakpoint "f2" | |
26051 | gdb_continue_to_breakpoint "breakpoint at f2" | |
26052 | gdb_test "up" "" "" | |
26053 | ||
26054 | -gdb_py_test_silent_cmd "python f1 = gdb.selected_frame ()" "get second frame" 0 | |
26055 | -gdb_py_test_silent_cmd "python f0 = f1.newer ()" "get first frame" 0 | |
26056 | +gdb_py_test_silent_cmd "python frames = gdb.selected_thread ().frames ()" "get frames list" 1 | |
26057 | +gdb_test "python print frames" "\\(<gdb.Frame object at 0x\[\[:xdigit:\]\]+>, <gdb.Frame object at 0x\[\[:xdigit:\]\]+>, <gdb.Frame object at 0x\[\[:xdigit:\]\]+>\\)" "verify frames list" | |
26058 | +gdb_py_test_silent_cmd "python f0 = frames\[0\]" "get first frame" 0 | |
26059 | +gdb_py_test_silent_cmd "python f1 = frames\[1\]" "get second frame" 0 | |
26060 | ||
26061 | gdb_test "python print 'result =', f0 == f1" " = False" "test equality comparison (false)" | |
26062 | gdb_test "python print 'result =', f0 == f0" " = True" "test equality comparison (true)" | |
26063 | -gdb_test "python print 'result =', f0 != f1" " = True" "test inequality comparison (true)" | |
26064 | -gdb_test "python print 'result =', f0 != f0" " = False" "test inequality comparison (false)" | |
26065 | gdb_test "python print 'result =', f0.is_valid ()" " = True" "test Frame.is_valid" | |
26066 | gdb_test "python print 'result =', f0.name ()" " = f2" "test Frame.name" | |
26067 | gdb_test "python print 'result =', f0.type () == gdb.NORMAL_FRAME" " = True" "test Frame.type" | |
26068 | gdb_test "python print 'result =', f0.unwind_stop_reason () == gdb.FRAME_UNWIND_NO_REASON" " = True" "test Frame.type" | |
26069 | gdb_test "python print 'result =', gdb.frame_stop_reason_string (gdb.FRAME_UNWIND_INNER_ID)" " = previous frame inner to this frame \\(corrupt stack\\?\\)" "test gdb.frame_stop_reason_string" | |
26070 | gdb_test "python print 'result =', f0.pc ()" " = \[0-9\]+" "test Frame.pc" | |
26071 | +gdb_test "python print 'result =', f0.function ()" " = symbol for f2" "test Frame.function" | |
26072 | gdb_test "python print 'result =', f0.older () == f1" " = True" "test Frame.older" | |
26073 | gdb_test "python print 'result =', f1.newer () == f0" " = True" "test Frame.newer" | |
26074 | gdb_test "python print 'result =', f0.read_var ('variable_which_surely_doesnt_exist')" \ | |
26075 | @@ -85,4 +74,7 @@ gdb_test "python print 'result =', f0.read_var ('variable_which_surely_doesnt_ex | |
26076 | "test Frame.read_var - error" | |
26077 | gdb_test "python print 'result =', f0.read_var ('a')" " = 1" "test Frame.read_var - success" | |
26078 | ||
26079 | +gdb_test "python print 'result =', gdb.selected_thread ().newest_frame () == f0" " = True" "test gdb.newest_frame" | |
26080 | gdb_test "python print 'result =', gdb.selected_frame () == f1" " = True" "test gdb.selected_frame" | |
26081 | + | |
26082 | +gdb_test "python print 'result =', f0.block ()" "<gdb.Block object at 0x\[\[:xdigit:\]\]+>" "test Frame.block" | |
26083 | diff --git a/gdb/testsuite/gdb.python/py-function.exp b/gdb/testsuite/gdb.python/py-function.exp | |
26084 | index 30fde7d..14cd90c 100644 | |
26085 | --- a/gdb/testsuite/gdb.python/py-function.exp | |
26086 | +++ b/gdb/testsuite/gdb.python/py-function.exp | |
26087 | @@ -20,36 +20,15 @@ if $tracelevel then { | |
26088 | strace $tracelevel | |
26089 | } | |
3a58abaf | 26090 | |
7566401a ER |
26091 | -# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}... |
26092 | -# Run a test named NAME, consisting of multiple lines of input. | |
26093 | -# After each input line INPUT, search for result line RESULT. | |
26094 | -# Succeed if all results are seen; fail otherwise. | |
26095 | -proc gdb_py_test_multiple {name args} { | |
26096 | - global gdb_prompt | |
26097 | - foreach {input result} $args { | |
26098 | - if {[gdb_test_multiple $input "$name - $input" { | |
26099 | - -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" { | |
26100 | - pass "$name - $input" | |
26101 | - } | |
26102 | - }]} { | |
26103 | - return 1 | |
26104 | - } | |
26105 | - } | |
26106 | - return 0 | |
26107 | -} | |
3a58abaf | 26108 | - |
7566401a | 26109 | # Start with a fresh gdb. |
3a58abaf | 26110 | |
7566401a ER |
26111 | gdb_exit |
26112 | gdb_start | |
26113 | gdb_reinitialize_dir $srcdir/$subdir | |
3a58abaf | 26114 | |
7566401a ER |
26115 | -gdb_test_multiple "python print 'hello, world!'" "verify python support" { |
26116 | - -re "not supported.*$gdb_prompt $" { | |
26117 | - unsupported "python support is disabled" | |
26118 | - return -1 | |
26119 | - } | |
26120 | - -re "$gdb_prompt $" {} | |
26121 | +if ![python_supported] then { | |
26122 | + unsupported "python support is disabled" | |
26123 | + return -1 | |
3a58abaf AM |
26124 | } |
26125 | ||
7566401a ER |
26126 | gdb_py_test_multiple "input convenience function" \ |
26127 | diff --git a/gdb/testsuite/gdb.python/py-inferior.c b/gdb/testsuite/gdb.python/py-inferior.c | |
26128 | new file mode 100644 | |
26129 | index 0000000..0b48299 | |
26130 | --- /dev/null | |
26131 | +++ b/gdb/testsuite/gdb.python/py-inferior.c | |
26132 | @@ -0,0 +1,49 @@ | |
26133 | +#include <stdio.h> | |
26134 | +#include <stdlib.h> | |
26135 | +#include <stdint.h> | |
26136 | +#include <string.h> | |
26137 | + | |
26138 | +#define CHUNK_SIZE 16000 /* same as findcmd.c's */ | |
26139 | +#define BUF_SIZE (2 * CHUNK_SIZE) /* at least two chunks */ | |
26140 | + | |
26141 | +static int8_t int8_search_buf[100]; | |
26142 | +static int16_t int16_search_buf[100]; | |
26143 | +static int32_t int32_search_buf[100]; | |
26144 | +static int64_t int64_search_buf[100]; | |
26145 | + | |
26146 | +static char *search_buf; | |
26147 | +static int search_buf_size; | |
26148 | + | |
26149 | +static int x; | |
26150 | + | |
26151 | + | |
26152 | +int f2 (int a) | |
3a58abaf | 26153 | +{ |
7566401a ER |
26154 | + char *str = "hello, testsuite"; |
26155 | + | |
26156 | + puts (str); /* Break here. */ | |
26157 | + | |
26158 | + return ++a; | |
3a58abaf AM |
26159 | +} |
26160 | + | |
7566401a | 26161 | +int f1 (int a, int b) |
3a58abaf | 26162 | +{ |
7566401a | 26163 | + return f2(a) + b; |
3a58abaf AM |
26164 | +} |
26165 | + | |
26166 | +static void | |
7566401a ER |
26167 | +init_bufs () |
26168 | +{ | |
26169 | + search_buf_size = BUF_SIZE; | |
26170 | + search_buf = malloc (search_buf_size); | |
26171 | + if (search_buf == NULL) | |
26172 | + exit (1); | |
26173 | + memset (search_buf, 'x', search_buf_size); | |
26174 | +} | |
3a58abaf | 26175 | + |
7566401a ER |
26176 | +int main (int argc, char *argv[]) |
26177 | +{ | |
26178 | + init_bufs (); | |
3a58abaf | 26179 | + |
7566401a ER |
26180 | + return f1 (1, 2); |
26181 | +} | |
26182 | diff --git a/gdb/testsuite/gdb.python/py-inferior.exp b/gdb/testsuite/gdb.python/py-inferior.exp | |
26183 | new file mode 100644 | |
26184 | index 0000000..719b178 | |
26185 | --- /dev/null | |
26186 | +++ b/gdb/testsuite/gdb.python/py-inferior.exp | |
26187 | @@ -0,0 +1,201 @@ | |
26188 | +# Copyright (C) 2009 Free Software Foundation, Inc. | |
3a58abaf | 26189 | + |
7566401a ER |
26190 | +# This program is free software; you can redistribute it and/or modify |
26191 | +# it under the terms of the GNU General Public License as published by | |
26192 | +# the Free Software Foundation; either version 3 of the License, or | |
26193 | +# (at your option) any later version. | |
26194 | +# | |
26195 | +# This program is distributed in the hope that it will be useful, | |
26196 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26197 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
26198 | +# GNU General Public License for more details. | |
26199 | +# | |
26200 | +# You should have received a copy of the GNU General Public License | |
26201 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 26202 | + |
7566401a ER |
26203 | +# This file is part of the GDB testsuite. It tests the mechanism |
26204 | +# exposing inferiors to Python. | |
3a58abaf | 26205 | + |
7566401a ER |
26206 | +if $tracelevel then { |
26207 | + strace $tracelevel | |
26208 | +} | |
3a58abaf | 26209 | + |
7566401a ER |
26210 | +# Start with a fresh gdb. |
26211 | + | |
26212 | +gdb_exit | |
26213 | +gdb_start | |
26214 | +gdb_reinitialize_dir $srcdir/$subdir | |
26215 | + | |
26216 | +if ![python_supported] then { | |
26217 | + unsupported "python support is disabled" | |
26218 | + return -1 | |
26219 | +} | |
26220 | + | |
26221 | +set testfile "py-inferior" | |
26222 | +set srcfile ${testfile}.c | |
26223 | +set binfile ${objdir}/${subdir}/${testfile} | |
26224 | + | |
26225 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
26226 | + untested "Couldn't compile ${srcfile}" | |
26227 | + return -1 | |
26228 | +} | |
26229 | + | |
26230 | +gdb_load ${binfile} | |
26231 | + | |
26232 | +# The following tests require execution. | |
26233 | + | |
26234 | +if ![runto_main] then { | |
26235 | + fail "Can't run to main" | |
26236 | + return 0 | |
26237 | +} | |
26238 | + | |
26239 | +runto [gdb_get_line_number "Break here."] | |
26240 | + | |
26241 | +# Test basic gdb.Inferior attributes and methods. | |
26242 | + | |
26243 | +gdb_py_test_silent_cmd "python inferiors = gdb.inferiors ()" "get inferiors list" 1 | |
26244 | +gdb_test "python print inferiors" "\\(<gdb.Inferior object at 0x\[\[:xdigit:\]\]+>,\\)" "verify inferiors list" | |
26245 | +gdb_py_test_silent_cmd "python i0 = inferiors\[0\]" "get first inferior" 0 | |
26246 | + | |
26247 | +gdb_test "python print 'result =', i0 == inferiors\[0\]" " = True" "test equality comparison (true)" | |
26248 | +gdb_test "python print 'result =', i0.num" " = \[0-9\]+" "test Inferior.num" | |
26249 | +gdb_test "python print 'result =', i0.pid" " = \[0-9\]+" "test Inferior.pid" | |
26250 | +gdb_test "python print 'result =', i0.was_attached" " = False" "test Inferior.was_attached" | |
26251 | +gdb_test "python print i0.threads ()" "\\(<gdb.InferiorThread object at 0x\[\[:xdigit:\]\]+>,\\)" "test Inferior.threads" | |
26252 | + | |
26253 | +# Test memory read and write operations. | |
26254 | + | |
26255 | +gdb_py_test_silent_cmd "python addr = gdb.selected_frame ().read_var ('str')" \ | |
26256 | + "read str address" 0 | |
26257 | +gdb_py_test_silent_cmd "python str = gdb.inferiors()\[0\].read_memory (addr, 5)" \ | |
26258 | + "read str contents" 1 | |
26259 | +gdb_py_test_silent_cmd "python str\[1\] = 'a'" "change str" 0 | |
26260 | +gdb_py_test_silent_cmd "python gdb.inferiors()\[0\].write_memory (addr, str)" \ | |
26261 | + "write str" 1 | |
26262 | +gdb_test "print str" " = 0x\[\[:xdigit:\]\]+ \"hallo, testsuite\"" \ | |
26263 | + "ensure str was changed in the inferior" | |
26264 | + | |
26265 | +# Test memory search. | |
26266 | + | |
26267 | +set hex_number {0x[0-9a-fA-F][0-9a-fA-F]*} | |
26268 | +set dec_number {[0-9]+} | |
26269 | +set history_prefix {[$][0-9]* = } | |
26270 | +set newline {[\r\n]+} | |
26271 | +set pattern_not_found "${newline}.]" | |
26272 | +set one_pattern_found "${newline}.${dec_number}L]" | |
26273 | +set two_patterns_found "${newline}.${dec_number}L, ${dec_number}L]" | |
26274 | + | |
26275 | +# Test string pattern. | |
26276 | + | |
26277 | +gdb_test "set *(int32_t*) &int8_search_buf\[10\] = 0x61616161" "" "" | |
26278 | +gdb_test "py search_buf = gdb.selected_frame ().read_var ('int8_search_buf')" "" "" | |
26279 | +gdb_test "py start_addr = search_buf.address" "" "" | |
26280 | +gdb_test "py length = search_buf.type.sizeof" "" "" | |
26281 | + | |
26282 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 'aaa')" \ | |
26283 | + "${two_patterns_found}" "find string pattern" | |
26284 | + | |
26285 | +# Test not finding pattern because search range too small, with | |
26286 | +# potential find at the edge of the range. | |
26287 | + | |
26288 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, 10+3, 'aaaa')" \ | |
26289 | + "${pattern_not_found}" "pattern not found at end of range" | |
26290 | + | |
26291 | +# Increase the search range by 1 and we should find the pattern. | |
26292 | + | |
26293 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, 10+3+1, \['a', 'a', 'a', 'a'\])" \ | |
26294 | + "${one_pattern_found}" "pattern found at end of range" | |
26295 | + | |
26296 | +# Test max-count with size, with different parameter position | |
26297 | + | |
26298 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, \[0x61, 0x61\], 1, 1)" \ | |
26299 | + "${one_pattern_found}" "size = 1, max_count = 1" | |
26300 | + | |
26301 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, \[0x61, 0x61\], 1, 2)" \ | |
26302 | + "${two_patterns_found}" "size = 1, max_count = 2, normal ordering" | |
26303 | + | |
26304 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, \[0x61, 0x61\], size = 1, max_count = 2)" \ | |
26305 | + "${two_patterns_found}" "size = 1, max_count = 2, normal ordering, with keywords" | |
26306 | + | |
26307 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, \[0x61, 0x61\], max_count = 2, size = 1)" \ | |
26308 | + "${two_patterns_found}" "size = 1, max_count = 2, inverted ordering" | |
26309 | + | |
26310 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, \['a', 'a'\], max_count = 2)" \ | |
26311 | + "${two_patterns_found}" "max_count = 2, with keyword" | |
26312 | + | |
26313 | +# Test 16-bit pattern. | |
26314 | + | |
26315 | +gdb_test "set int16_search_buf\[10\] = 0x1234" "" "" | |
26316 | +gdb_test "py search_buf = gdb.selected_frame ().read_var ('int16_search_buf')" "" "" | |
26317 | +gdb_test "py start_addr = search_buf.address" "" "" | |
26318 | +gdb_test "py length = search_buf.type.sizeof" "" "" | |
26319 | +gdb_test "py pattern = gdb.parse_and_eval ('(int16_t) 0x1234')" "" "" | |
26320 | + | |
26321 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 0x1234, 2)" \ | |
26322 | + "${one_pattern_found}" "find 16-bit pattern, with python pattern" | |
26323 | + | |
26324 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, pattern)" \ | |
26325 | + "${one_pattern_found}" "find 16-bit pattern, with value pattern" | |
26326 | + | |
26327 | +# Test 32-bit pattern. | |
26328 | + | |
26329 | +gdb_test "set int32_search_buf\[10\] = 0x12345678" "" "" | |
26330 | +gdb_test "py search_buf = gdb.selected_frame ().read_var ('int32_search_buf')" "" "" | |
26331 | +gdb_test "py start_addr = search_buf.address" "" "" | |
26332 | +gdb_test "py length = search_buf.type.sizeof" "" "" | |
26333 | +gdb_test "py pattern = gdb.parse_and_eval ('(int32_t) 0x12345678')" "" "" | |
26334 | + | |
26335 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 0x12345678, 4)" \ | |
26336 | + "${one_pattern_found}" "find 32-bit pattern, with python pattern" | |
26337 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, pattern)" \ | |
26338 | + "${one_pattern_found}" "find 32-bit pattern, with value pattern" | |
26339 | + | |
26340 | +# Test 64-bit pattern. | |
26341 | + | |
26342 | +gdb_test "set int64_search_buf\[10\] = 0xfedcba9876543210LL" "" "" | |
26343 | +gdb_test "py search_buf = gdb.selected_frame ().read_var ('int64_search_buf')" "" "" | |
26344 | +gdb_test "py start_addr = search_buf.address" "" "" | |
26345 | +gdb_test "py length = search_buf.type.sizeof" "" "" | |
26346 | +gdb_test "py pattern = gdb.parse_and_eval ('(int64_t) 0xfedcba9876543210LL')" "" "" | |
26347 | + | |
26348 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 0xfedcba9876543210, 8)" \ | |
26349 | + "${one_pattern_found}" "find 64-bit pattern, with python pattern" | |
26350 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, pattern)" \ | |
26351 | + "${one_pattern_found}" "find 64-bit pattern, with value pattern" | |
26352 | + | |
26353 | +# Test mixed-sized patterns. | |
26354 | + | |
26355 | +gdb_test "set *(int8_t*) &search_buf\[10\] = 0x62" "" "" | |
26356 | +gdb_test "set *(int16_t*) &search_buf\[11\] = 0x6363" "" "" | |
26357 | +gdb_test "set *(int32_t*) &search_buf\[13\] = 0x64646464" "" "" | |
26358 | +gdb_test "py search_buf = gdb.selected_frame ().read_var ('search_buf')" "" "" | |
26359 | +gdb_test "py start_addr = search_buf\[0\].address" "" "" | |
26360 | +gdb_test "py pattern1 = gdb.parse_and_eval ('(int8_t) 0x62')" "" "" | |
26361 | +gdb_test "py pattern2 = gdb.parse_and_eval ('(int16_t) 0x6363')" "" "" | |
26362 | +gdb_test "py pattern3 = gdb.parse_and_eval ('(int32_t) 0x64646464')" "" "" | |
26363 | + | |
26364 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, 100, \[pattern1, pattern2, pattern3\])" \ | |
26365 | + "${one_pattern_found}" "find mixed-sized pattern" | |
3a58abaf | 26366 | + |
7566401a ER |
26367 | +# Test search spanning a large range, in the particular case of native |
26368 | +# targets, test the search spanning multiple chunks. | |
26369 | +# Remote targets may implement the search differently. | |
3a58abaf | 26370 | + |
7566401a | 26371 | +set CHUNK_SIZE 16000 ; |
3a58abaf | 26372 | + |
7566401a ER |
26373 | +gdb_test "set *(int32_t*) &search_buf\[0*${CHUNK_SIZE}+100\] = 0x12345678" "" "" |
26374 | +gdb_test "set *(int32_t*) &search_buf\[1*${CHUNK_SIZE}+100\] = 0x12345678" "" "" | |
26375 | +gdb_test "py start_addr = gdb.selected_frame ().read_var ('search_buf')" "" "" | |
26376 | +gdb_test "py length = gdb.selected_frame ().read_var ('search_buf_size')" "" "" | |
3a58abaf | 26377 | + |
7566401a ER |
26378 | +gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 0x12345678, 4)" \ |
26379 | + "${two_patterns_found}" "search spanning large range" | |
3a58abaf | 26380 | + |
7566401a | 26381 | +# For native targets, test a pattern straddling a chunk boundary. |
3a58abaf | 26382 | + |
7566401a ER |
26383 | +if [isnative] { |
26384 | + gdb_test "set *(int32_t*) &search_buf\[${CHUNK_SIZE}-1\] = 0xfdb97531" "" "" | |
3a58abaf | 26385 | + |
7566401a ER |
26386 | + gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 0xfdb97531, 4)" \ |
26387 | + "${one_pattern_found}" "find pattern straddling chunk boundary" | |
26388 | +} | |
26389 | diff --git a/gdb/testsuite/gdb.python/py-infthread.c b/gdb/testsuite/gdb.python/py-infthread.c | |
26390 | new file mode 100644 | |
26391 | index 0000000..22eb9f2 | |
26392 | --- /dev/null | |
26393 | +++ b/gdb/testsuite/gdb.python/py-infthread.c | |
26394 | @@ -0,0 +1,14 @@ | |
26395 | +int f2 (int a) | |
26396 | +{ | |
26397 | + return ++a; | |
3a58abaf AM |
26398 | +} |
26399 | + | |
7566401a ER |
26400 | +int f1 (int a, int b) |
26401 | +{ | |
26402 | + return f2(a) + b; | |
26403 | +} | |
3a58abaf | 26404 | + |
7566401a | 26405 | +int main (int argc, char *argv[]) |
3a58abaf | 26406 | +{ |
7566401a ER |
26407 | + return f1 (1, 2); |
26408 | +} | |
26409 | diff --git a/gdb/testsuite/gdb.python/py-infthread.exp b/gdb/testsuite/gdb.python/py-infthread.exp | |
26410 | new file mode 100644 | |
26411 | index 0000000..e9d18b7 | |
26412 | --- /dev/null | |
26413 | +++ b/gdb/testsuite/gdb.python/py-infthread.exp | |
26414 | @@ -0,0 +1,58 @@ | |
26415 | +# Copyright (C) 2009 Free Software Foundation, Inc. | |
3a58abaf | 26416 | + |
7566401a ER |
26417 | +# This program is free software; you can redistribute it and/or modify |
26418 | +# it under the terms of the GNU General Public License as published by | |
26419 | +# the Free Software Foundation; either version 3 of the License, or | |
26420 | +# (at your option) any later version. | |
26421 | +# | |
26422 | +# This program is distributed in the hope that it will be useful, | |
26423 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26424 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
26425 | +# GNU General Public License for more details. | |
26426 | +# | |
26427 | +# You should have received a copy of the GNU General Public License | |
26428 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
3a58abaf | 26429 | + |
7566401a ER |
26430 | +# This file is part of the GDB testsuite. It tests the mechanism |
26431 | +# exposing inferior threads to Python. | |
3a58abaf | 26432 | + |
7566401a ER |
26433 | +if $tracelevel then { |
26434 | + strace $tracelevel | |
26435 | +} | |
3a58abaf | 26436 | + |
7566401a | 26437 | +# Start with a fresh gdb. |
3a58abaf | 26438 | + |
7566401a ER |
26439 | +gdb_exit |
26440 | +gdb_start | |
26441 | +gdb_reinitialize_dir $srcdir/$subdir | |
26442 | + | |
26443 | +if ![python_supported] then { | |
26444 | + unsupported "python support is disabled" | |
26445 | + return -1 | |
3a58abaf AM |
26446 | +} |
26447 | + | |
7566401a ER |
26448 | +set testfile "py-infthread" |
26449 | +set srcfile ${testfile}.c | |
26450 | +set binfile ${objdir}/${subdir}/${testfile} | |
3a58abaf | 26451 | + |
7566401a ER |
26452 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { |
26453 | + untested "Couldn't compile ${srcfile}" | |
26454 | + return -1 | |
26455 | +} | |
26456 | + | |
26457 | +gdb_load ${binfile} | |
3a58abaf | 26458 | + |
7566401a ER |
26459 | +# The following tests require execution. |
26460 | + | |
26461 | +if ![runto_main] then { | |
26462 | + fail "Can't run to main" | |
26463 | + return 0 | |
3a58abaf AM |
26464 | +} |
26465 | + | |
7566401a | 26466 | +runto [gdb_get_line_number "Break here."] |
3a58abaf | 26467 | + |
7566401a | 26468 | +# Test basic gdb.Inferior attributes and methods. |
3a58abaf | 26469 | + |
7566401a ER |
26470 | +gdb_py_test_silent_cmd "python t0 = gdb.selected_thread ()" "test gdb.selected_thread" 1 |
26471 | +gdb_test "python print t0" "\\<gdb.InferiorThread object at 0x\[\[:xdigit:\]\]+>" "verify InferiorThread object" | |
26472 | +gdb_test "python print 'result =', t0.num" " = \[0-9\]+" "test Inferior.num" | |
26473 | diff --git a/gdb/testsuite/gdb.python/py-prettyprint.exp b/gdb/testsuite/gdb.python/py-prettyprint.exp | |
26474 | index b4b3776..359c4ed 100644 | |
26475 | --- a/gdb/testsuite/gdb.python/py-prettyprint.exp | |
26476 | +++ b/gdb/testsuite/gdb.python/py-prettyprint.exp | |
26477 | @@ -27,12 +27,20 @@ set binfile ${objdir}/${subdir}/${testfile} | |
26478 | # Start with a fresh gdb. | |
26479 | gdb_exit | |
26480 | gdb_start | |
26481 | -gdb_test_multiple "python print 'hello, world!'" "verify python support" { | |
26482 | - -re "not supported.*$gdb_prompt $" { | |
26483 | - unsupported "python support is disabled" | |
26484 | - return -1 | |
26485 | - } | |
26486 | - -re "$gdb_prompt $" {} | |
26487 | +if ![python_supported] then { | |
26488 | + unsupported "python support is disabled" | |
26489 | + return -1 | |
26490 | +} | |
3a58abaf | 26491 | + |
7566401a ER |
26492 | +# Run a command in GDB, and report a failure if a Python exception is thrown. |
26493 | +# If report_pass is true, report a pass if no exception is thrown. | |
26494 | +proc gdb_py_test_silent_cmd {cmd name report_pass} { | |
26495 | + global gdb_prompt | |
26496 | + | |
26497 | + gdb_test_multiple $cmd $name { | |
26498 | + -re "Traceback.*$gdb_prompt $" { fail $name } | |
26499 | + -re "$gdb_prompt $" { if $report_pass { pass $name } } | |
26500 | + } | |
26501 | } | |
3a58abaf | 26502 | |
7566401a ER |
26503 | # Run a command in GDB, and report a failure if a Python exception is thrown. |
26504 | @@ -102,6 +110,8 @@ proc run_lang_tests {lang} { | |
3a58abaf | 26505 | |
7566401a | 26506 | gdb_test "print c" " = container $hex \"container\" with 2 elements = {$nl *.0. = 23,$nl *.1. = 72$nl}" |
3a58abaf | 26507 | |
7566401a ER |
26508 | + gdb_test "print nullstr" "RuntimeError: Error reading string from inferior.*" |
26509 | + | |
26510 | gdb_test "continue" "Program exited normally\." | |
26511 | } | |
3a58abaf | 26512 | |
7566401a ER |
26513 | diff --git a/gdb/testsuite/gdb.python/py-template.exp b/gdb/testsuite/gdb.python/py-template.exp |
26514 | index cea6ae0..c9a63d4 100644 | |
26515 | --- a/gdb/testsuite/gdb.python/py-template.exp | |
26516 | +++ b/gdb/testsuite/gdb.python/py-template.exp | |
26517 | @@ -20,6 +20,17 @@ if $tracelevel then { | |
26518 | strace $tracelevel | |
26519 | } | |
3a58abaf | 26520 | |
7566401a | 26521 | +# Start with a fresh gdb. |
3a58abaf | 26522 | + |
7566401a ER |
26523 | +gdb_exit |
26524 | +gdb_start | |
26525 | +gdb_reinitialize_dir $srcdir/$subdir | |
3a58abaf | 26526 | + |
7566401a ER |
26527 | +if ![python_supported] then { |
26528 | + unsupported "python support is disabled" | |
26529 | + return -1 | |
26530 | +} | |
26531 | + | |
26532 | set testfile "py-template" | |
26533 | set srcfile ${testfile}.cc | |
26534 | set binfile ${objdir}/${subdir}/${testfile} | |
26535 | @@ -29,20 +40,6 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ | |
26536 | return -1 | |
3a58abaf AM |
26537 | } |
26538 | ||
7566401a ER |
26539 | -# Start with a fresh gdb. |
26540 | - | |
26541 | -gdb_exit | |
26542 | -gdb_start | |
26543 | -gdb_reinitialize_dir $srcdir/$subdir | |
26544 | - | |
26545 | -gdb_test_multiple "python print 23" "verify python support" { | |
26546 | - -re "not supported.*$gdb_prompt $" { | |
26547 | - unsupported "python support is disabled" | |
26548 | - return -1 | |
26549 | - } | |
26550 | - -re "$gdb_prompt $" {} | |
26551 | -} | |
26552 | - | |
26553 | proc test_template_arg {type} { | |
26554 | global testfile srcdir subdir srcfile binfile | |
26555 | if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ | |
26556 | diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp | |
26557 | index 2958233..0de1cae 100644 | |
26558 | --- a/gdb/testsuite/gdb.python/py-value.exp | |
26559 | +++ b/gdb/testsuite/gdb.python/py-value.exp | |
26560 | @@ -292,6 +292,15 @@ proc test_value_after_death {} { | |
26561 | "print value's type" | |
3a58abaf AM |
26562 | } |
26563 | ||
7566401a ER |
26564 | +# Regression test for a cast failure. The bug was that if we cast a |
26565 | +# value to its own type, gdb could crash. This happened because we | |
26566 | +# could end up double-freeing a struct value. | |
26567 | +proc test_cast_regression {} { | |
26568 | + gdb_test "python v = gdb.Value(5)" "" "create value for cast test" | |
26569 | + gdb_test "python v = v.cast(v.type)" "" "cast value for cast test" | |
26570 | + gdb_test "python print v" "5" "print value for cast test" | |
26571 | +} | |
3a58abaf | 26572 | + |
7566401a ER |
26573 | # Regression test for invalid subscript operations. The bug was that |
26574 | # the type of the value was not being checked before allowing a | |
26575 | # subscript operation to proceed. | |
26576 | @@ -366,16 +375,23 @@ proc test_subscript_regression {lang} { | |
26577 | gdb_exit | |
26578 | gdb_start | |
26579 | gdb_reinitialize_dir $srcdir/$subdir | |
26580 | -gdb_load ${binfile} | |
26581 | ||
26582 | -gdb_test_multiple "python print 'hello, world!'" "verify python support" { | |
26583 | - -re "not supported.*$gdb_prompt $" { | |
26584 | - unsupported "python support is disabled" | |
26585 | - return -1 | |
26586 | - } | |
26587 | - -re "$gdb_prompt $" {} | |
26588 | +if ![python_supported] then { | |
26589 | + unsupported "python support is disabled" | |
26590 | + return -1 | |
3a58abaf AM |
26591 | } |
26592 | ||
7566401a ER |
26593 | +set testfile "py-value" |
26594 | +set srcfile ${testfile}.c | |
26595 | +set binfile ${objdir}/${subdir}/${testfile} | |
3a58abaf | 26596 | + |
7566401a ER |
26597 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { |
26598 | + untested "Couldn't compile ${srcfile}" | |
26599 | + return -1 | |
26600 | +} | |
26601 | + | |
26602 | +gdb_load ${binfile} | |
26603 | + | |
26604 | test_value_creation | |
26605 | test_value_numeric_ops | |
26606 | test_value_boolean | |
26607 | @@ -391,6 +407,7 @@ if ![runto_main] then { | |
3a58abaf | 26608 | |
7566401a ER |
26609 | test_value_in_inferior |
26610 | test_value_after_death | |
26611 | +test_cast_regression | |
26612 | ||
26613 | # The following test recompiles the binary to test either C or C++ | |
26614 | # values. | |
26615 | diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp | |
26616 | index 5223fc8..03e1eab 100644 | |
26617 | --- a/gdb/testsuite/gdb.python/python.exp | |
26618 | +++ b/gdb/testsuite/gdb.python/python.exp | |
26619 | @@ -26,30 +26,9 @@ gdb_exit | |
26620 | gdb_start | |
26621 | gdb_reinitialize_dir $srcdir/$subdir | |
26622 | ||
26623 | -gdb_test_multiple "python print 23" "verify python support" { | |
26624 | - -re "not supported.*$gdb_prompt $" { | |
26625 | - unsupported "python support is disabled" | |
26626 | - return -1 | |
26627 | - } | |
26628 | - -re "$gdb_prompt $" {} | |
26629 | -} | |
26630 | - | |
26631 | -# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}... | |
26632 | -# Run a test named NAME, consisting of multiple lines of input. | |
26633 | -# After each input line INPUT, search for result line RESULT. | |
26634 | -# Succeed if all results are seen; fail otherwise. | |
26635 | -proc gdb_py_test_multiple {name args} { | |
26636 | - global gdb_prompt | |
26637 | - foreach {input result} $args { | |
26638 | - if {[gdb_test_multiple $input "$name - $input" { | |
26639 | - -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" { | |
26640 | - pass "$name - $input" | |
26641 | - } | |
26642 | - }]} { | |
26643 | - return 1 | |
26644 | - } | |
26645 | - } | |
26646 | - return 0 | |
26647 | +if ![python_supported] then { | |
26648 | + unsupported "python support is disabled" | |
26649 | + return -1 | |
26650 | } | |
3a58abaf | 26651 | |
7566401a ER |
26652 | gdb_py_test_multiple "multi-line python command" \ |
26653 | diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-forkoff.c b/gdb/testsuite/gdb.threads/watchpoint-fork-forkoff.c | |
26654 | new file mode 100644 | |
26655 | index 0000000..4dc308b | |
26656 | --- /dev/null | |
26657 | +++ b/gdb/testsuite/gdb.threads/watchpoint-fork-forkoff.c | |
26658 | @@ -0,0 +1,175 @@ | |
26659 | +/* Test case for forgotten hw-watchpoints after fork()-off of a process. | |
3a58abaf | 26660 | + |
7566401a | 26661 | + Copyright 2008, 2009 Free Software Foundation, Inc. |
3a58abaf | 26662 | + |
7566401a | 26663 | + This file is part of GDB. |
3a58abaf | 26664 | + |
7566401a ER |
26665 | + This program is free software; you can redistribute it and/or modify |
26666 | + it under the terms of the GNU General Public License as published by | |
26667 | + the Free Software Foundation; either version 2 of the License, or | |
26668 | + (at your option) any later version. | |
3a58abaf | 26669 | + |
7566401a ER |
26670 | + This program is distributed in the hope that it will be useful, |
26671 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26672 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
26673 | + GNU General Public License for more details. | |
3a58abaf | 26674 | + |
7566401a ER |
26675 | + You should have received a copy of the GNU General Public License |
26676 | + along with this program; if not, write to the Free Software | |
26677 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
26678 | + Boston, MA 02111-1307, USA. */ | |
3a58abaf | 26679 | + |
7566401a ER |
26680 | +#include <string.h> |
26681 | +#include <errno.h> | |
26682 | + | |
26683 | +static void | |
26684 | +delay (void) | |
3a58abaf | 26685 | +{ |
7566401a ER |
26686 | + int i = usleep (1000000 / 100); |
26687 | + assert (i == 0 || errno == EINTR); | |
3a58abaf AM |
26688 | +} |
26689 | + | |
7566401a ER |
26690 | +#if defined FOLLOW_PARENT |
26691 | + | |
26692 | +static void | |
26693 | +forkoff (int nr) | |
26694 | +{ | |
26695 | + pid_t child, pid_got; | |
26696 | + int exit_code = 42 + nr; | |
26697 | + int status, i; | |
26698 | + | |
26699 | + child = fork (); | |
26700 | + switch (child) | |
26701 | + { | |
26702 | + case -1: | |
26703 | + assert (0); | |
26704 | + case 0: | |
26705 | + printf ("child%d: %d\n", nr, (int) getpid ()); | |
26706 | + /* Delay to get both the "child%d" and "parent%d" message printed without | |
26707 | + a race breaking expect by its endless wait on `$gdb_prompt$': | |
26708 | + Breakpoint 3, breakpoint () at ../../../gdb/testsuite/gdb.threads/watchpoint-fork.c:33 | |
26709 | + 33 } | |
26710 | + (gdb) parent2: 14223 */ | |
26711 | + i = sleep (1); | |
26712 | + assert (i == 0); | |
26713 | + | |
26714 | + /* We must not get caught here (against a forgotten breakpoint). */ | |
26715 | + var++; | |
26716 | + breakpoint (); | |
26717 | + | |
26718 | + _exit (exit_code); | |
26719 | + default: | |
26720 | + printf ("parent%d: %d\n", nr, (int) child); | |
26721 | + /* Delay to get both the "child%d" and "parent%d" message printed, see | |
26722 | + above. */ | |
26723 | + i = sleep (1); | |
26724 | + assert (i == 0); | |
26725 | + | |
26726 | + pid_got = wait (&status); | |
26727 | + assert (pid_got == child); | |
26728 | + assert (WIFEXITED (status)); | |
26729 | + assert (WEXITSTATUS (status) == exit_code); | |
26730 | + | |
26731 | + /* We must get caught here (against a false watchpoint removal). */ | |
26732 | + breakpoint (); | |
26733 | + } | |
26734 | +} | |
26735 | + | |
26736 | +#elif defined FOLLOW_CHILD | |
26737 | + | |
26738 | +static volatile int usr1_got; | |
26739 | + | |
26740 | +static void | |
26741 | +handler_usr1 (int signo) | |
3a58abaf | 26742 | +{ |
7566401a | 26743 | + usr1_got++; |
3a58abaf AM |
26744 | +} |
26745 | + | |
7566401a ER |
26746 | +static void |
26747 | +forkoff (int nr) | |
3a58abaf | 26748 | +{ |
7566401a ER |
26749 | + pid_t child; |
26750 | + int i, loop; | |
26751 | + struct sigaction act, oldact; | |
26752 | +#ifdef THREAD | |
26753 | + void *thread_result; | |
26754 | +#endif | |
26755 | + | |
26756 | + memset (&act, 0, sizeof act); | |
26757 | + act.sa_flags = SA_RESTART; | |
26758 | + act.sa_handler = handler_usr1; | |
26759 | + sigemptyset (&act.sa_mask); | |
26760 | + i = sigaction (SIGUSR1, &act, &oldact); | |
26761 | + assert (i == 0); | |
26762 | + | |
26763 | + child = fork (); | |
26764 | + switch (child) | |
26765 | + { | |
26766 | + case -1: | |
26767 | + assert (0); | |
26768 | + default: | |
26769 | + printf ("parent%d: %d\n", nr, (int) child); | |
26770 | + | |
26771 | + /* Sleep for a while to possibly get incorrectly ATTACH_THREADed by GDB | |
26772 | + tracing the child fork with no longer valid thread/lwp entries of the | |
26773 | + parent. */ | |
26774 | + | |
26775 | + i = sleep (2); | |
26776 | + assert (i == 0); | |
26777 | + | |
26778 | + /* We must not get caught here (against a forgotten breakpoint). */ | |
26779 | + | |
26780 | + var++; | |
26781 | + breakpoint (); | |
26782 | + | |
26783 | +#ifdef THREAD | |
26784 | + /* And neither got caught our thread. */ | |
26785 | + | |
26786 | + step = 99; | |
26787 | + i = pthread_join (thread, &thread_result); | |
26788 | + assert (i == 0); | |
26789 | + assert (thread_result == (void *) 99UL); | |
26790 | +#endif | |
26791 | + | |
26792 | + /* Be sure our child knows we did not get caught above. */ | |
26793 | + | |
26794 | + i = kill (child, SIGUSR1); | |
26795 | + assert (i == 0); | |
26796 | + | |
26797 | + /* Sleep for a while to check GDB's `info threads' no longer tracks us in | |
26798 | + the child fork. */ | |
26799 | + | |
26800 | + i = sleep (2); | |
26801 | + assert (i == 0); | |
26802 | + | |
26803 | + _exit (0); | |
26804 | + case 0: | |
26805 | + printf ("child%d: %d\n", nr, (int) getpid ()); | |
26806 | + | |
26807 | + /* Let the parent signal us about its success. Be careful of races. */ | |
26808 | + | |
26809 | + for (loop = 0; loop < 1000; loop++) | |
26810 | + { | |
26811 | + /* Parent either died (and USR1_GOT is zero) or it succeeded. */ | |
26812 | + if (kill (getppid (), 0) != 0) | |
26813 | + break; | |
26814 | + /* Parent succeeded? */ | |
26815 | + if (usr1_got) | |
26816 | + break; | |
26817 | + | |
26818 | + delay (); | |
26819 | + } | |
26820 | + assert (usr1_got); | |
26821 | + | |
26822 | + /* We must get caught here (against a false watchpoint removal). */ | |
26823 | + | |
26824 | + breakpoint (); | |
26825 | + } | |
26826 | + | |
26827 | + i = sigaction (SIGUSR1, &oldact, NULL); | |
26828 | + assert (i == 0); | |
3a58abaf AM |
26829 | +} |
26830 | + | |
7566401a ER |
26831 | +#else |
26832 | +# error "!FOLLOW_PARENT && !FOLLOW_CHILD" | |
26833 | +#endif | |
26834 | diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c b/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c | |
26835 | new file mode 100644 | |
26836 | index 0000000..edacfc0 | |
26837 | --- /dev/null | |
26838 | +++ b/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c | |
26839 | @@ -0,0 +1,157 @@ | |
26840 | +/* Test case for forgotten hw-watchpoints after fork()-off of a process. | |
3a58abaf | 26841 | + |
7566401a | 26842 | + Copyright 2008, 2009 Free Software Foundation, Inc. |
3a58abaf | 26843 | + |
7566401a | 26844 | + This file is part of GDB. |
3a58abaf | 26845 | + |
7566401a ER |
26846 | + This program is free software; you can redistribute it and/or modify |
26847 | + it under the terms of the GNU General Public License as published by | |
26848 | + the Free Software Foundation; either version 2 of the License, or | |
26849 | + (at your option) any later version. | |
3a58abaf | 26850 | + |
7566401a ER |
26851 | + This program is distributed in the hope that it will be useful, |
26852 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26853 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
26854 | + GNU General Public License for more details. | |
3a58abaf | 26855 | + |
7566401a ER |
26856 | + You should have received a copy of the GNU General Public License |
26857 | + along with this program; if not, write to the Free Software | |
26858 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
26859 | + Boston, MA 02111-1307, USA. */ | |
26860 | + | |
26861 | +#include <assert.h> | |
26862 | +#include <unistd.h> | |
26863 | +#include <sys/wait.h> | |
26864 | +#include <stdio.h> | |
26865 | +#include <stdlib.h> | |
26866 | +#include <pthread.h> | |
26867 | + | |
26868 | +#include <asm/unistd.h> | |
26869 | +#include <unistd.h> | |
26870 | +#define gettid() syscall (__NR_gettid) | |
26871 | + | |
26872 | +/* Non-atomic `var++' should not hurt as we synchronize the threads by the STEP | |
26873 | + variable. Hit-comments need to be duplicite there to catch both at-stops | |
26874 | + and behind-stops, depending on the target. */ | |
26875 | + | |
26876 | +static volatile int var; | |
3a58abaf AM |
26877 | + |
26878 | +static void | |
7566401a | 26879 | +dummy (void) |
3a58abaf | 26880 | +{ |
7566401a ER |
26881 | +} |
26882 | + | |
26883 | +static void | |
26884 | +breakpoint (void) | |
26885 | +{ | |
26886 | +} | |
26887 | + | |
26888 | +/* Include here the functions: | |
26889 | + static void forkoff (int nr); | |
26890 | + static void delay (void); */ | |
26891 | + | |
26892 | +static pthread_t thread; | |
26893 | +static volatile int step; | |
26894 | +#define THREAD | |
26895 | + | |
26896 | +#include "watchpoint-fork-forkoff.c" | |
26897 | + | |
26898 | +static void * | |
26899 | +start (void *arg) | |
26900 | +{ | |
26901 | + if (step >= 3) | |
26902 | + goto step_3; | |
26903 | + | |
26904 | + while (step != 1) | |
26905 | + delay (); | |
26906 | + | |
26907 | + var++; /* validity-thread-B */ | |
26908 | + dummy (); /* validity-thread-B */ | |
26909 | + step = 2; | |
26910 | + while (step != 3) | |
3a58abaf | 26911 | + { |
7566401a ER |
26912 | + if (step == 99) |
26913 | + goto step_99; | |
26914 | + delay (); | |
26915 | + } | |
3a58abaf | 26916 | + |
7566401a ER |
26917 | +step_3: |
26918 | + if (step >= 5) | |
26919 | + goto step_5; | |
3a58abaf | 26920 | + |
7566401a ER |
26921 | + var++; /* after-fork1-B */ |
26922 | + dummy (); /* after-fork1-B */ | |
26923 | + step = 4; | |
26924 | + while (step != 5) | |
26925 | + { | |
26926 | + if (step == 99) | |
26927 | + goto step_99; | |
26928 | + delay (); | |
3a58abaf | 26929 | + } |
3a58abaf | 26930 | + |
7566401a ER |
26931 | +step_5: |
26932 | + var++; /* after-fork2-B */ | |
26933 | + dummy (); /* after-fork2-B */ | |
26934 | + return (void *) 5UL; | |
3a58abaf | 26935 | + |
7566401a ER |
26936 | +step_99: |
26937 | + /* We must not get caught here (against a forgotten breakpoint). */ | |
26938 | + var++; | |
26939 | + breakpoint (); | |
26940 | + return (void *) 99UL; | |
3a58abaf AM |
26941 | +} |
26942 | + | |
7566401a ER |
26943 | +int |
26944 | +main (void) | |
3a58abaf | 26945 | +{ |
7566401a ER |
26946 | + int i; |
26947 | + void *thread_result; | |
26948 | + | |
26949 | + setbuf (stdout, NULL); | |
26950 | + printf ("main: %d\n", (int) gettid ()); | |
26951 | + | |
26952 | + /* General watchpoints validity. */ | |
26953 | + var++; /* validity-first */ | |
26954 | + dummy (); /* validity-first */ | |
26955 | + | |
26956 | + i = pthread_create (&thread, NULL, start, NULL); | |
26957 | + assert (i == 0); | |
26958 | + | |
26959 | + var++; /* validity-thread-A */ | |
26960 | + dummy (); /* validity-thread-A */ | |
26961 | + step = 1; | |
26962 | + while (step != 2) | |
26963 | + delay (); | |
26964 | + | |
26965 | + /* Hardware watchpoints got disarmed here. */ | |
26966 | + forkoff (1); | |
26967 | + | |
26968 | + var++; /* after-fork1-A */ | |
26969 | + dummy (); /* after-fork1-A */ | |
26970 | + step = 3; | |
26971 | +#ifdef FOLLOW_CHILD | |
26972 | + /* Spawn new thread as it was deleted in the child of FORK. */ | |
26973 | + i = pthread_create (&thread, NULL, start, NULL); | |
26974 | + assert (i == 0); | |
26975 | +#endif | |
26976 | + while (step != 4) | |
26977 | + delay (); | |
26978 | + | |
26979 | + /* A sanity check for double hardware watchpoints removal. */ | |
26980 | + forkoff (2); | |
26981 | + | |
26982 | + var++; /* after-fork2-A */ | |
26983 | + dummy (); /* after-fork2-A */ | |
26984 | + step = 5; | |
26985 | +#ifdef FOLLOW_CHILD | |
26986 | + /* Spawn new thread as it was deleted in the child of FORK. */ | |
26987 | + i = pthread_create (&thread, NULL, start, NULL); | |
26988 | + assert (i == 0); | |
26989 | +#endif | |
26990 | + | |
26991 | + i = pthread_join (thread, &thread_result); | |
26992 | + assert (i == 0); | |
26993 | + assert (thread_result == (void *) 5UL); | |
26994 | + | |
26995 | + return 0; | |
3a58abaf | 26996 | +} |
7566401a ER |
26997 | diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork.c b/gdb/testsuite/gdb.threads/watchpoint-fork.c |
26998 | new file mode 100644 | |
26999 | index 0000000..5f62e7f | |
27000 | --- /dev/null | |
27001 | +++ b/gdb/testsuite/gdb.threads/watchpoint-fork.c | |
27002 | @@ -0,0 +1,57 @@ | |
27003 | +/* Test case for forgotten hw-watchpoints after fork()-off of a process. | |
27004 | + | |
27005 | + Copyright 2008, 2009 Free Software Foundation, Inc. | |
27006 | + | |
27007 | + This file is part of GDB. | |
27008 | + | |
27009 | + This program is free software; you can redistribute it and/or modify | |
27010 | + it under the terms of the GNU General Public License as published by | |
27011 | + the Free Software Foundation; either version 2 of the License, or | |
27012 | + (at your option) any later version. | |
27013 | + | |
27014 | + This program is distributed in the hope that it will be useful, | |
27015 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27016 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
27017 | + GNU General Public License for more details. | |
27018 | + | |
27019 | + You should have received a copy of the GNU General Public License | |
27020 | + along with this program; if not, write to the Free Software | |
27021 | + Foundation, Inc., 59 Temple Place - Suite 330, | |
27022 | + Boston, MA 02111-1307, USA. */ | |
27023 | + | |
27024 | +#include <assert.h> | |
27025 | +#include <unistd.h> | |
27026 | +#include <sys/wait.h> | |
27027 | +#include <stdio.h> | |
27028 | +#include <stdlib.h> | |
27029 | + | |
27030 | +static volatile int var; | |
3a58abaf | 27031 | + |
3a58abaf | 27032 | +static void |
7566401a | 27033 | +breakpoint (void) |
3a58abaf | 27034 | +{ |
3a58abaf AM |
27035 | +} |
27036 | + | |
7566401a ER |
27037 | +/* Include here the function: |
27038 | + static void forkoff (int nr); */ | |
27039 | + | |
27040 | +#include "watchpoint-fork-forkoff.c" | |
27041 | + | |
27042 | +int | |
27043 | +main (void) | |
3a58abaf | 27044 | +{ |
7566401a ER |
27045 | + setbuf (stdout, NULL); |
27046 | + printf ("main: %d\n", (int) getpid ()); | |
27047 | + | |
27048 | + /* General watchpoints validity. */ | |
27049 | + var++; | |
27050 | + /* Hardware watchpoints got disarmed here. */ | |
27051 | + forkoff (1); | |
27052 | + /* This watchpoint got lost before. */ | |
27053 | + var++; | |
27054 | + /* A sanity check for double hardware watchpoints removal. */ | |
27055 | + forkoff (2); | |
27056 | + var++; | |
27057 | + | |
27058 | + return 0; | |
3a58abaf | 27059 | +} |
7566401a ER |
27060 | diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork.exp b/gdb/testsuite/gdb.threads/watchpoint-fork.exp |
27061 | new file mode 100644 | |
27062 | index 0000000..1dc93ab | |
27063 | --- /dev/null | |
27064 | +++ b/gdb/testsuite/gdb.threads/watchpoint-fork.exp | |
27065 | @@ -0,0 +1,130 @@ | |
27066 | +# Copyright 2008, 2009 Free Software Foundation, Inc. | |
27067 | + | |
27068 | +# This program is free software; you can redistribute it and/or modify | |
27069 | +# it under the terms of the GNU General Public License as published by | |
27070 | +# the Free Software Foundation; either version 3 of the License, or | |
27071 | +# (at your option) any later version. | |
27072 | +# | |
27073 | +# This program is distributed in the hope that it will be useful, | |
27074 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27075 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
27076 | +# GNU General Public License for more details. | |
27077 | +# | |
27078 | +# You should have received a copy of the GNU General Public License | |
27079 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
27080 | + | |
27081 | +# Test case for forgotten hw-watchpoints after fork()-off of a process. | |
27082 | + | |
27083 | +proc test {type symbol} { | |
27084 | + global objdir subdir srcdir | |
3a58abaf | 27085 | + |
7566401a | 27086 | + set test watchpoint-fork |
3a58abaf | 27087 | + |
7566401a ER |
27088 | + global pf_prefix |
27089 | + set prefix_test $pf_prefix | |
27090 | + lappend pf_prefix "$type:" | |
27091 | + set prefix_mt $pf_prefix | |
3a58abaf | 27092 | + |
7566401a ER |
27093 | + # no threads |
27094 | + | |
27095 | + set pf_prefix $prefix_mt | |
27096 | + lappend pf_prefix "singlethreaded:" | |
27097 | + | |
27098 | + set executable ${test}-${type} | |
27099 | + if { [gdb_compile ${srcdir}/${subdir}/${test}.c ${objdir}/${subdir}/${executable} executable [list debug additional_flags=-D$symbol]] != "" } { | |
27100 | + untested ${test}.exp | |
27101 | + return -1 | |
3a58abaf | 27102 | + } |
7566401a ER |
27103 | + clean_restart $executable |
27104 | + | |
27105 | + gdb_test "show detach-on-fork" "Whether gdb will detach the child of a fork is on." | |
27106 | + gdb_test "set follow-fork-mode $type" | |
27107 | + gdb_test "show follow-fork-mode" "Debugger response to a program call of fork or vfork is \"$type\"." | |
27108 | + # Testcase uses it for the `follow-fork-mode child' type. | |
27109 | + gdb_test "handle SIGUSR1 nostop noprint pass" | |
27110 | + | |
27111 | + if { ![runto_main] } then { | |
27112 | + gdb_suppress_tests | |
27113 | + return | |
3a58abaf | 27114 | + } |
3a58abaf | 27115 | + |
7566401a ER |
27116 | + # Install the watchpoint only after getting into MAIN - workaround some PPC |
27117 | + # problem. | |
27118 | + gdb_test "watch var" "atchpoint 2: var" "Set the watchpoint" | |
3a58abaf | 27119 | + |
7566401a ER |
27120 | + # It is never hit but it should not be left over in the fork()ed-off child. |
27121 | + gdb_breakpoint "breakpoint" | |
3a58abaf | 27122 | + |
7566401a ER |
27123 | + gdb_test "continue" \ |
27124 | + "atchpoint 2: var.*Old value = 0.*New value = 1.*forkoff *\\(1\\).*" "watchpoints work" | |
27125 | + gdb_test "continue" \ | |
27126 | + "reakpoint 3, breakpoint.*" "breakpoint after the first fork" | |
27127 | + gdb_test "continue" \ | |
27128 | + "atchpoint 2: var.*Old value = 1.*New value = 2.*forkoff *\\(2\\).*" "watchpoint after the first fork" | |
27129 | + gdb_test "continue" \ | |
27130 | + "reakpoint 3, breakpoint.*" "breakpoint after the second fork" | |
27131 | + gdb_test "continue" \ | |
27132 | + "atchpoint 2: var.*Old value = 2.*New value = 3.*return *0;" "watchpoint after the second fork" | |
27133 | + gdb_test "continue" "Continuing..*Program exited normally." "finish" | |
3a58abaf | 27134 | + |
3a58abaf | 27135 | + |
7566401a ER |
27136 | + # threads |
27137 | + | |
27138 | + set pf_prefix $prefix_mt | |
27139 | + lappend pf_prefix "multithreaded:" | |
27140 | + | |
27141 | + set executable ${test}-mt-${type} | |
27142 | + if { [gdb_compile_pthreads ${srcdir}/${subdir}/${test}-mt.c ${objdir}/${subdir}/${executable} executable [list debug additional_flags=-D$symbol]] != "" } { | |
27143 | + untested ${test}.exp | |
27144 | + return -1 | |
3a58abaf | 27145 | + } |
7566401a | 27146 | + clean_restart $executable |
3a58abaf | 27147 | + |
7566401a ER |
27148 | + gdb_test "set follow-fork-mode $type" |
27149 | + # Testcase uses it for the `follow-fork-mode child' type. | |
27150 | + gdb_test "handle SIGUSR1 nostop noprint pass" | |
3a58abaf | 27151 | + |
7566401a ER |
27152 | + if { ![runto_main] } then { |
27153 | + gdb_suppress_tests | |
27154 | + return | |
27155 | + } | |
3a58abaf | 27156 | + |
7566401a ER |
27157 | + # Install the watchpoint only after getting into MAIN - workaround some PPC |
27158 | + # problem. | |
27159 | + gdb_test "watch var" "atchpoint 2: var" "Set the watchpoint" | |
3a58abaf | 27160 | + |
7566401a ER |
27161 | + # It is never hit but it should not be left over in the fork()ed-off child. |
27162 | + gdb_breakpoint "breakpoint" | |
3a58abaf | 27163 | + |
7566401a ER |
27164 | + gdb_test "continue" \ |
27165 | + "atchpoint 2: var.*Old value = 0.*New value = 1.*validity-first.*" "singlethread watchpoints work" | |
27166 | + gdb_test "continue" \ | |
27167 | + "atchpoint 2: var.*Old value = 1.*New value = 2.*validity-thread-A.*" "multithreaded watchpoints work at A" | |
27168 | + gdb_test "continue" \ | |
27169 | + "atchpoint 2: var.*Old value = 2.*New value = 3.*validity-thread-B.*" "multithreaded watchpoints work at B" | |
27170 | + gdb_test "continue" \ | |
27171 | + "reakpoint 3, breakpoint.*" "breakpoint (A) after the first fork" | |
27172 | + gdb_test "continue" \ | |
27173 | + "atchpoint 2: var.*Old value = 3.*New value = 4.*after-fork1-A.*" "watchpoint A after the first fork" | |
27174 | + gdb_test "continue" \ | |
27175 | + "atchpoint 2: var.*Old value = 4.*New value = 5.*after-fork1-B.*" "watchpoint B after the first fork" | |
27176 | + gdb_test "continue" \ | |
27177 | + "reakpoint 3, breakpoint.*" "breakpoint (A) after the second fork" | |
27178 | + gdb_test "continue" \ | |
27179 | + "atchpoint 2: var.*Old value = 5.*New value = 6.*after-fork2-A.*" "watchpoint A after the second fork" | |
27180 | + gdb_test "continue" \ | |
27181 | + "atchpoint 2: var.*Old value = 6.*New value = 7.*after-fork2-B.*" "watchpoint B after the second fork" | |
27182 | + gdb_test "continue" "Continuing..*Program exited normally." "finish" | |
3a58abaf AM |
27183 | + |
27184 | + | |
7566401a | 27185 | + # cleanup |
3a58abaf | 27186 | + |
7566401a ER |
27187 | + set pf_prefix $prefix_test |
27188 | +} | |
3a58abaf | 27189 | + |
7566401a | 27190 | +test parent FOLLOW_PARENT |
3a58abaf | 27191 | + |
7566401a ER |
27192 | +# Only GNU/Linux is known to support `set follow-fork-mode child'. |
27193 | +if {[istarget "*-*-linux*"]} { | |
27194 | + test child FOLLOW_CHILD | |
27195 | +} | |
27196 | diff --git a/gdb/testsuite/gdb.threads/watchthreads-reorder.c b/gdb/testsuite/gdb.threads/watchthreads-reorder.c | |
27197 | new file mode 100644 | |
27198 | index 0000000..14f42d6 | |
27199 | --- /dev/null | |
27200 | +++ b/gdb/testsuite/gdb.threads/watchthreads-reorder.c | |
27201 | @@ -0,0 +1,366 @@ | |
27202 | +/* This testcase is part of GDB, the GNU debugger. | |
3a58abaf | 27203 | + |
7566401a | 27204 | + Copyright 2009 Free Software Foundation, Inc. |
3a58abaf | 27205 | + |
7566401a ER |
27206 | + This program is free software; you can redistribute it and/or modify |
27207 | + it under the terms of the GNU General Public License as published by | |
27208 | + the Free Software Foundation; either version 3 of the License, or | |
27209 | + (at your option) any later version. | |
3a58abaf | 27210 | + |
7566401a ER |
27211 | + This program is distributed in the hope that it will be useful, |
27212 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27213 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
27214 | + GNU General Public License for more details. | |
3a58abaf | 27215 | + |
7566401a ER |
27216 | + You should have received a copy of the GNU General Public License |
27217 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
3a58abaf | 27218 | + |
7566401a ER |
27219 | +#define _GNU_SOURCE |
27220 | +#include <pthread.h> | |
27221 | +#include <stdio.h> | |
27222 | +#include <limits.h> | |
27223 | +#include <errno.h> | |
27224 | +#include <stdlib.h> | |
27225 | +#include <string.h> | |
27226 | +#include <assert.h> | |
27227 | +#include <sys/types.h> | |
27228 | +#include <signal.h> | |
27229 | +#include <unistd.h> | |
27230 | +#include <asm/unistd.h> | |
3a58abaf | 27231 | + |
7566401a | 27232 | +#define gettid() syscall (__NR_gettid) |
3a58abaf | 27233 | + |
7566401a ER |
27234 | +/* Terminate always in the main task, it can lock up with SIGSTOPped GDB |
27235 | + otherwise. */ | |
27236 | +#define TIMEOUT (gettid () == getpid() ? 10 : 15) | |
3a58abaf | 27237 | + |
7566401a | 27238 | +static pthread_mutex_t gdbstop_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; |
3a58abaf | 27239 | + |
7566401a ER |
27240 | +static pid_t thread1_tid; |
27241 | +static pthread_cond_t thread1_tid_cond = PTHREAD_COND_INITIALIZER; | |
27242 | +static pthread_mutex_t thread1_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; | |
3a58abaf | 27243 | + |
7566401a ER |
27244 | +static pid_t thread2_tid; |
27245 | +static pthread_cond_t thread2_tid_cond = PTHREAD_COND_INITIALIZER; | |
27246 | +static pthread_mutex_t thread2_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; | |
3a58abaf | 27247 | + |
7566401a | 27248 | +static pthread_mutex_t terminate_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; |
3a58abaf | 27249 | + |
7566401a ER |
27250 | +static volatile int thread1_rwatch; |
27251 | +static volatile int thread2_rwatch; | |
3a58abaf | 27252 | + |
7566401a ER |
27253 | +static int unused1_rwatch; |
27254 | +static int unused2_rwatch; | |
3a58abaf | 27255 | + |
7566401a ER |
27256 | +/* Do not use alarm as it would create a ptrace event which would hang up us if |
27257 | + * we are being traced by GDB which we stopped ourselves. */ | |
3a58abaf | 27258 | + |
7566401a | 27259 | +static void timed_mutex_lock (pthread_mutex_t *mutex) |
3a58abaf | 27260 | +{ |
7566401a ER |
27261 | + int i; |
27262 | + struct timespec start, now; | |
3a58abaf | 27263 | + |
7566401a ER |
27264 | + i = clock_gettime (CLOCK_MONOTONIC, &start); |
27265 | + assert (i == 0); | |
27266 | + | |
27267 | + do | |
3a58abaf | 27268 | + { |
7566401a ER |
27269 | + i = pthread_mutex_trylock (mutex); |
27270 | + if (i == 0) | |
27271 | + return; | |
27272 | + assert (i == EBUSY); | |
3a58abaf | 27273 | + |
7566401a ER |
27274 | + i = clock_gettime (CLOCK_MONOTONIC, &now); |
27275 | + assert (i == 0); | |
27276 | + assert (now.tv_sec >= start.tv_sec); | |
27277 | + } | |
27278 | + while (now.tv_sec - start.tv_sec < TIMEOUT); | |
3a58abaf | 27279 | + |
7566401a ER |
27280 | + fprintf (stderr, "Timed out waiting for internal lock!\n"); |
27281 | + exit (EXIT_FAILURE); | |
3a58abaf AM |
27282 | +} |
27283 | + | |
7566401a ER |
27284 | +static void * |
27285 | +thread1_func (void *unused) | |
3a58abaf | 27286 | +{ |
7566401a ER |
27287 | + int i; |
27288 | + volatile int rwatch_store; | |
3a58abaf | 27289 | + |
7566401a ER |
27290 | + thread1_tid = gettid (); |
27291 | + i = pthread_cond_signal (&thread1_tid_cond); | |
27292 | + assert (i == 0); | |
3a58abaf | 27293 | + |
7566401a ER |
27294 | + /* Be sure GDB is already stopped before continuing. */ |
27295 | + timed_mutex_lock (&gdbstop_mutex); | |
27296 | + i = pthread_mutex_unlock (&gdbstop_mutex); | |
27297 | + assert (i == 0); | |
3a58abaf | 27298 | + |
7566401a | 27299 | + rwatch_store = thread1_rwatch; |
3a58abaf | 27300 | + |
7566401a ER |
27301 | + /* Be sure the "T (tracing stop)" test can proceed for both threads. */ |
27302 | + timed_mutex_lock (&terminate_mutex); | |
27303 | + i = pthread_mutex_unlock (&terminate_mutex); | |
27304 | + assert (i == 0); | |
27305 | + | |
27306 | + return NULL; | |
27307 | +} | |
27308 | + | |
27309 | +static void * | |
27310 | +thread2_func (void *unused) | |
27311 | +{ | |
3a58abaf | 27312 | + int i; |
7566401a | 27313 | + volatile int rwatch_store; |
3a58abaf | 27314 | + |
7566401a ER |
27315 | + thread2_tid = gettid (); |
27316 | + i = pthread_cond_signal (&thread2_tid_cond); | |
27317 | + assert (i == 0); | |
3a58abaf | 27318 | + |
7566401a ER |
27319 | + /* Be sure GDB is already stopped before continuing. */ |
27320 | + timed_mutex_lock (&gdbstop_mutex); | |
27321 | + i = pthread_mutex_unlock (&gdbstop_mutex); | |
27322 | + assert (i == 0); | |
3a58abaf | 27323 | + |
7566401a | 27324 | + rwatch_store = thread2_rwatch; |
3a58abaf | 27325 | + |
7566401a ER |
27326 | + /* Be sure the "T (tracing stop)" test can proceed for both threads. */ |
27327 | + timed_mutex_lock (&terminate_mutex); | |
27328 | + i = pthread_mutex_unlock (&terminate_mutex); | |
27329 | + assert (i == 0); | |
3a58abaf | 27330 | + |
7566401a ER |
27331 | + return NULL; |
27332 | +} | |
3a58abaf | 27333 | + |
7566401a ER |
27334 | +static const char * |
27335 | +proc_string (const char *filename, const char *line) | |
27336 | +{ | |
27337 | + FILE *f; | |
27338 | + static char buf[LINE_MAX]; | |
27339 | + size_t line_len = strlen (line); | |
3a58abaf | 27340 | + |
7566401a ER |
27341 | + f = fopen (filename, "r"); |
27342 | + if (f == NULL) | |
3a58abaf | 27343 | + { |
7566401a ER |
27344 | + fprintf (stderr, "fopen (\"%s\") for \"%s\": %s\n", filename, line, |
27345 | + strerror (errno)); | |
27346 | + exit (EXIT_FAILURE); | |
3a58abaf | 27347 | + } |
7566401a | 27348 | + while (errno = 0, fgets (buf, sizeof (buf), f)) |
3a58abaf | 27349 | + { |
7566401a | 27350 | + char *s; |
3a58abaf | 27351 | + |
7566401a ER |
27352 | + s = strchr (buf, '\n'); |
27353 | + assert (s != NULL); | |
27354 | + *s = 0; | |
3a58abaf | 27355 | + |
7566401a ER |
27356 | + if (strncmp (buf, line, line_len) != 0) |
27357 | + continue; | |
3a58abaf | 27358 | + |
7566401a | 27359 | + if (fclose (f)) |
3a58abaf | 27360 | + { |
7566401a ER |
27361 | + fprintf (stderr, "fclose (\"%s\") for \"%s\": %s\n", filename, line, |
27362 | + strerror (errno)); | |
27363 | + exit (EXIT_FAILURE); | |
3a58abaf AM |
27364 | + } |
27365 | + | |
7566401a | 27366 | + return &buf[line_len]; |
3a58abaf | 27367 | + } |
7566401a | 27368 | + if (errno != 0) |
3a58abaf | 27369 | + { |
7566401a ER |
27370 | + fprintf (stderr, "fgets (\"%s\": %s\n", filename, strerror (errno)); |
27371 | + exit (EXIT_FAILURE); | |
3a58abaf | 27372 | + } |
7566401a ER |
27373 | + fprintf (stderr, "\"%s\": No line \"%s\" found.\n", filename, line); |
27374 | + exit (EXIT_FAILURE); | |
3a58abaf | 27375 | +} |
7566401a ER |
27376 | + |
27377 | +static unsigned long | |
27378 | +proc_ulong (const char *filename, const char *line) | |
27379 | +{ | |
27380 | + const char *s = proc_string (filename, line); | |
27381 | + long retval; | |
27382 | + char *end; | |
27383 | + | |
27384 | + errno = 0; | |
27385 | + retval = strtol (s, &end, 10); | |
27386 | + if (retval < 0 || retval >= LONG_MAX || (end && *end)) | |
3a58abaf | 27387 | + { |
7566401a ER |
27388 | + fprintf (stderr, "\"%s\":\"%s\": %ld, %s\n", filename, line, retval, |
27389 | + strerror (errno)); | |
27390 | + exit (EXIT_FAILURE); | |
3a58abaf | 27391 | + } |
7566401a | 27392 | + return retval; |
3a58abaf AM |
27393 | +} |
27394 | + | |
7566401a ER |
27395 | +static void |
27396 | +state_wait (pid_t process, const char *wanted) | |
27397 | +{ | |
27398 | + char *filename; | |
27399 | + int i; | |
27400 | + struct timespec start, now; | |
27401 | + const char *state; | |
3a58abaf | 27402 | + |
7566401a ER |
27403 | + i = asprintf (&filename, "/proc/%lu/status", (unsigned long) process); |
27404 | + assert (i > 0); | |
3a58abaf | 27405 | + |
7566401a ER |
27406 | + i = clock_gettime (CLOCK_MONOTONIC, &start); |
27407 | + assert (i == 0); | |
3a58abaf | 27408 | + |
7566401a | 27409 | + do |
3a58abaf | 27410 | + { |
7566401a ER |
27411 | + state = proc_string (filename, "State:\t"); |
27412 | + if (strcmp (state, wanted) == 0) | |
27413 | + { | |
27414 | + free (filename); | |
27415 | + return; | |
27416 | + } | |
27417 | + | |
27418 | + if (sched_yield ()) | |
27419 | + { | |
27420 | + perror ("sched_yield()"); | |
27421 | + exit (EXIT_FAILURE); | |
27422 | + } | |
27423 | + | |
27424 | + i = clock_gettime (CLOCK_MONOTONIC, &now); | |
27425 | + assert (i == 0); | |
27426 | + assert (now.tv_sec >= start.tv_sec); | |
3a58abaf | 27427 | + } |
7566401a | 27428 | + while (now.tv_sec - start.tv_sec < TIMEOUT); |
3a58abaf | 27429 | + |
7566401a ER |
27430 | + fprintf (stderr, "Timed out waiting for PID %lu \"%s\" (now it is \"%s\")!\n", |
27431 | + (unsigned long) process, wanted, state); | |
27432 | + exit (EXIT_FAILURE); | |
3a58abaf AM |
27433 | +} |
27434 | + | |
7566401a ER |
27435 | +static volatile pid_t tracer = 0; |
27436 | +static pthread_t thread1, thread2; | |
27437 | + | |
3a58abaf | 27438 | +static void |
7566401a | 27439 | +cleanup (void) |
3a58abaf | 27440 | +{ |
7566401a | 27441 | + printf ("Resuming GDB PID %lu.\n", (unsigned long) tracer); |
3a58abaf | 27442 | + |
7566401a ER |
27443 | + if (tracer) |
27444 | + { | |
27445 | + int i; | |
27446 | + int tracer_save = tracer; | |
3a58abaf | 27447 | + |
7566401a | 27448 | + tracer = 0; |
3a58abaf | 27449 | + |
7566401a ER |
27450 | + i = kill (tracer_save, SIGCONT); |
27451 | + assert (i == 0); | |
27452 | + } | |
3a58abaf AM |
27453 | +} |
27454 | + | |
7566401a ER |
27455 | +int |
27456 | +main (int argc, char **argv) | |
3a58abaf | 27457 | +{ |
7566401a ER |
27458 | + int i; |
27459 | + int standalone = 0; | |
3a58abaf | 27460 | + |
7566401a ER |
27461 | + if (argc == 2 && strcmp (argv[1], "-s") == 0) |
27462 | + standalone = 1; | |
27463 | + else | |
27464 | + assert (argc == 1); | |
3a58abaf | 27465 | + |
7566401a ER |
27466 | + setbuf (stdout, NULL); |
27467 | + | |
27468 | + timed_mutex_lock (&gdbstop_mutex); | |
27469 | + | |
27470 | + timed_mutex_lock (&terminate_mutex); | |
27471 | + | |
27472 | + i = pthread_create (&thread1, NULL, thread1_func, NULL); | |
27473 | + assert (i == 0); | |
27474 | + | |
27475 | + i = pthread_create (&thread2, NULL, thread2_func, NULL); | |
27476 | + assert (i == 0); | |
27477 | + | |
27478 | + if (!standalone) | |
3a58abaf | 27479 | + { |
7566401a ER |
27480 | + tracer = proc_ulong ("/proc/self/status", "TracerPid:\t"); |
27481 | + if (tracer == 0) | |
27482 | + { | |
27483 | + fprintf (stderr, "The testcase must be run by GDB!\n"); | |
27484 | + exit (EXIT_FAILURE); | |
27485 | + } | |
27486 | + if (tracer != getppid ()) | |
3a58abaf | 27487 | + { |
7566401a ER |
27488 | + fprintf (stderr, "The testcase parent must be our GDB tracer!\n"); |
27489 | + exit (EXIT_FAILURE); | |
3a58abaf AM |
27490 | + } |
27491 | + } | |
7566401a ER |
27492 | + |
27493 | + /* SIGCONT our debugger in the case of our crash as we would deadlock | |
27494 | + otherwise. */ | |
27495 | + | |
27496 | + atexit (cleanup); | |
27497 | + | |
27498 | + printf ("Stopping GDB PID %lu.\n", (unsigned long) tracer); | |
27499 | + | |
27500 | + if (tracer) | |
3a58abaf | 27501 | + { |
7566401a ER |
27502 | + i = kill (tracer, SIGSTOP); |
27503 | + assert (i == 0); | |
27504 | + state_wait (tracer, "T (stopped)"); | |
3a58abaf | 27505 | + } |
3a58abaf | 27506 | + |
7566401a ER |
27507 | + timed_mutex_lock (&thread1_tid_mutex); |
27508 | + timed_mutex_lock (&thread2_tid_mutex); | |
3a58abaf | 27509 | + |
7566401a ER |
27510 | + /* Let the threads start. */ |
27511 | + i = pthread_mutex_unlock (&gdbstop_mutex); | |
27512 | + assert (i == 0); | |
3a58abaf | 27513 | + |
7566401a | 27514 | + printf ("Waiting till the threads initialize their TIDs.\n"); |
3a58abaf | 27515 | + |
7566401a ER |
27516 | + if (thread1_tid == 0) |
27517 | + { | |
27518 | + i = pthread_cond_wait (&thread1_tid_cond, &thread1_tid_mutex); | |
27519 | + assert (i == 0); | |
3a58abaf | 27520 | + |
7566401a ER |
27521 | + assert (thread1_tid > 0); |
27522 | + } | |
27523 | + | |
27524 | + if (thread2_tid == 0) | |
3a58abaf | 27525 | + { |
7566401a ER |
27526 | + i = pthread_cond_wait (&thread2_tid_cond, &thread2_tid_mutex); |
27527 | + assert (i == 0); | |
27528 | + | |
27529 | + assert (thread2_tid > 0); | |
3a58abaf | 27530 | + } |
3a58abaf | 27531 | + |
7566401a ER |
27532 | + printf ("Thread 1 TID = %lu, thread 2 TID = %lu, PID = %lu.\n", |
27533 | + (unsigned long) thread1_tid, (unsigned long) thread2_tid, | |
27534 | + (unsigned long) getpid ()); | |
27535 | + | |
27536 | + printf ("Waiting till the threads get trapped by the watchpoints.\n"); | |
3a58abaf | 27537 | + |
7566401a | 27538 | + if (tracer) |
3a58abaf | 27539 | + { |
7566401a ER |
27540 | + /* s390x-unknown-linux-gnu will fail with "R (running)". */ |
27541 | + | |
27542 | + state_wait (thread1_tid, "T (tracing stop)"); | |
27543 | + | |
27544 | + state_wait (thread2_tid, "T (tracing stop)"); | |
3a58abaf AM |
27545 | + } |
27546 | + | |
7566401a ER |
27547 | + cleanup (); |
27548 | + | |
27549 | + printf ("Joining the threads.\n"); | |
27550 | + | |
27551 | + i = pthread_mutex_unlock (&terminate_mutex); | |
27552 | + assert (i == 0); | |
27553 | + | |
27554 | + i = pthread_join (thread1, NULL); | |
27555 | + assert (i == 0); | |
27556 | + | |
27557 | + i = pthread_join (thread2, NULL); | |
27558 | + assert (i == 0); | |
27559 | + | |
27560 | + printf ("Exiting.\n"); /* break-at-exit */ | |
27561 | + | |
27562 | + /* Just prevent compiler `warning: \e$B!F\e(BunusedX_rwatch\e$B!G\e(B defined but not used'. */ | |
27563 | + unused1_rwatch = 1; | |
27564 | + unused2_rwatch = 2; | |
27565 | + | |
27566 | + return EXIT_SUCCESS; | |
27567 | +} | |
27568 | diff --git a/gdb/testsuite/gdb.threads/watchthreads-reorder.exp b/gdb/testsuite/gdb.threads/watchthreads-reorder.exp | |
27569 | new file mode 100644 | |
ab050a48 | 27570 | index 0000000..5ad1a4e |
7566401a ER |
27571 | --- /dev/null |
27572 | +++ b/gdb/testsuite/gdb.threads/watchthreads-reorder.exp | |
ab050a48 | 27573 | @@ -0,0 +1,105 @@ |
7566401a ER |
27574 | +# This testcase is part of GDB, the GNU debugger. |
27575 | + | |
27576 | +# Copyright 2009 Free Software Foundation, Inc. | |
27577 | + | |
27578 | +# This program is free software; you can redistribute it and/or modify | |
27579 | +# it under the terms of the GNU General Public License as published by | |
27580 | +# the Free Software Foundation; either version 3 of the License, or | |
27581 | +# (at your option) any later version. | |
27582 | +# | |
27583 | +# This program is distributed in the hope that it will be useful, | |
27584 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27585 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
27586 | +# GNU General Public License for more details. | |
27587 | +# | |
27588 | +# You should have received a copy of the GNU General Public License | |
27589 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
27590 | + | |
27591 | +# Test GDB can cope with two watchpoints being hit by different threads at the | |
27592 | +# same time, GDB reports one of them and after "continue" to report the other | |
27593 | +# one GDB should not be confused by differently set watchpoints that time. | |
27594 | +# This is the goal of "reorder1". "reorder0" tests the basic functionality of | |
27595 | +# two watchpoint being hit at the same time, without reordering them during the | |
27596 | +# stop. The formerly broken functionality is due to the all-stop mode default | |
27597 | +# "show breakpoint always-inserted" being "off". Formerly the remembered hit | |
27598 | +# could be assigned during continuation of a thread with pending SIGTRAP to the | |
27599 | +# different/new watchpoint, just based on the watchpoint/debug register number. | |
27600 | + | |
27601 | +if {[target_info exists gdb,no_hardware_watchpoints] | |
27602 | + || ![istarget *-*-linux*]} { | |
27603 | + return 0; | |
27604 | +} | |
27605 | + | |
27606 | +set testfile "watchthreads-reorder" | |
27607 | +set srcfile ${testfile}.c | |
27608 | +set binfile ${objdir}/${subdir}/${testfile} | |
27609 | +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" ${binfile} executable [list debug additional_flags=-lrt]] != "" } { | |
27610 | + return -1 | |
27611 | +} | |
27612 | + | |
27613 | +foreach reorder {0 1} { | |
27614 | + | |
27615 | + global pf_prefix | |
27616 | + set prefix_test $pf_prefix | |
27617 | + lappend pf_prefix "reorder$reorder:" | |
27618 | + | |
27619 | + clean_restart $testfile | |
27620 | + | |
27621 | + gdb_test "set can-use-hw-watchpoints 1" | |
27622 | + | |
27623 | + if ![runto_main] { | |
27624 | + gdb_suppress_tests | |
3a58abaf AM |
27625 | + } |
27626 | + | |
7566401a ER |
27627 | + # Use "rwatch" as "watch" would report the watchpoint changed just based on its |
27628 | + # read memory value during a stop by unrelated event. We are interested to not | |
27629 | + # to lose the hardware watchpoint trigger. | |
3a58abaf | 27630 | + |
7566401a ER |
27631 | + gdb_test "rwatch thread1_rwatch" "Hardware read watchpoint \[0-9\]+: thread1_rwatch" |
27632 | + gdb_test {set $rwatch1=$bpnum} | |
27633 | + set test "rwatch thread2_rwatch" | |
27634 | + gdb_test_multiple $test $test { | |
27635 | + -re "Target does not support this type of hardware watchpoint\\.\r\n$gdb_prompt $" { | |
27636 | + # ppc64 supports at most 1 hw watchpoints. | |
27637 | + unsupported $test | |
27638 | + return | |
27639 | + } | |
27640 | + -re "Hardware read watchpoint \[0-9\]+: thread2_rwatch\r\n$gdb_prompt $" { | |
27641 | + pass $test | |
27642 | + } | |
27643 | + } | |
27644 | + gdb_test {set $rwatch2=$bpnum} | |
27645 | + gdb_breakpoint [gdb_get_line_number "break-at-exit"] | |
27646 | + | |
27647 | + # The watchpoints can happen in arbitrary order depending on random: | |
27648 | + # SEL: Found 2 SIGTRAP events, selecting #[01] | |
27649 | + # As GDB contains no srand() on the specific host/OS it will behave always the | |
27650 | + # same. Such order cannot be guaranteed for GDB in general. | |
27651 | + | |
27652 | + gdb_test "continue" \ | |
27653 | + "Hardware read watchpoint \[0-9\]+: thread\[12\]_rwatch\r\n\r\nValue = 0\r\n0x\[0-9a-f\]+ in thread\[12\]_func .*" \ | |
27654 | + "continue a" | |
27655 | + | |
27656 | + if $reorder { | |
27657 | + gdb_test {delete $rwatch1} | |
27658 | + gdb_test {delete $rwatch2} | |
27659 | + | |
27660 | + gdb_test "rwatch unused1_rwatch" "Hardware read watchpoint \[0-9\]+: unused1_rwatch" | |
27661 | + gdb_test "rwatch unused2_rwatch" "Hardware read watchpoint \[0-9\]+: unused2_rwatch" | |
27662 | + | |
27663 | + gdb_test "rwatch thread1_rwatch" "Hardware read watchpoint \[0-9\]+: thread1_rwatch" | |
27664 | + gdb_test "rwatch thread2_rwatch" "Hardware read watchpoint \[0-9\]+: thread2_rwatch" | |
27665 | + } | |
27666 | + | |
27667 | + gdb_test "continue" \ | |
27668 | + "Hardware read watchpoint \[0-9\]+: thread\[12\]_rwatch\r\n\r\nValue = 0\r\n0x\[0-9a-f\]+ in thread\[12\]_func .*" \ | |
27669 | + "continue b" | |
27670 | + | |
ab050a48 BZ |
27671 | + # While the debug output itself is not checked in this testcase one bug was |
27672 | + # found in the DEBUG_INFRUN code path. | |
27673 | + gdb_test "set debug infrun 1" | |
27674 | + | |
7566401a ER |
27675 | + gdb_continue_to_breakpoint "break-at-exit" ".*break-at-exit.*" |
27676 | + | |
27677 | + set pf_prefix $prefix_test | |
27678 | +} | |
27679 | diff --git a/gdb/testsuite/lib/cp-support.exp b/gdb/testsuite/lib/cp-support.exp | |
27680 | index dbd2f59..44e1b51 100644 | |
27681 | --- a/gdb/testsuite/lib/cp-support.exp | |
27682 | +++ b/gdb/testsuite/lib/cp-support.exp | |
27683 | @@ -222,7 +222,7 @@ proc cp_test_ptype_class { in_command in_testname in_key in_tag in_class_table { | |
27684 | ||
27685 | set parse_okay 0 | |
27686 | gdb_test_multiple "$in_command" "$in_testname // parse failed" { | |
27687 | - -re "type = (struct|class)${wsopt}(\[A-Za-z0-9_\]*)${wsopt}((:\[^\{\]*)?)${wsopt}\{(.*)\}${wsopt}(\[^\r\n\]*)\[\r\n\]+$gdb_prompt $" { | |
27688 | + -re "type = (struct|class)${wsopt}(\[A-Za-z0-9_:\]*)${wsopt}((:\[^\{\]*)?)${wsopt}\{(.*)\}${wsopt}(\[^\r\n\]*)\[\r\n\]+$gdb_prompt $" { | |
27689 | set parse_okay 1 | |
27690 | set actual_key $expect_out(1,string) | |
27691 | set actual_tag $expect_out(2,string) | |
27692 | @@ -231,6 +231,7 @@ proc cp_test_ptype_class { in_command in_testname in_key in_tag in_class_table { | |
27693 | set actual_tail $expect_out(6,string) | |
27694 | } | |
27695 | } | |
27696 | + | |
27697 | if { ! $parse_okay } then { return } | |
27698 | ||
27699 | # Check the actual key. It would be nice to require that it match | |
27700 | diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp | |
27701 | index 0c93a73..d0c3493 100644 | |
27702 | --- a/gdb/testsuite/lib/gdb.exp | |
27703 | +++ b/gdb/testsuite/lib/gdb.exp | |
27704 | @@ -27,6 +27,7 @@ if {$tool == ""} { | |
27705 | } | |
27706 | ||
27707 | load_lib libgloss.exp | |
27708 | +load_lib python-support.exp | |
27709 | ||
27710 | global GDB | |
27711 | ||
27712 | diff --git a/gdb/testsuite/lib/python-support.exp b/gdb/testsuite/lib/python-support.exp | |
27713 | new file mode 100644 | |
27714 | index 0000000..b8e9836 | |
27715 | --- /dev/null | |
27716 | +++ b/gdb/testsuite/lib/python-support.exp | |
27717 | @@ -0,0 +1,53 @@ | |
27718 | +global python_supported_saved | |
27719 | + | |
27720 | +# Return 1 if Python scripting is supported in GDB, 0 if not. | |
27721 | +proc python_supported { } { | |
27722 | + global gdb_prompt | |
27723 | + global python_supported_saved | |
27724 | + | |
27725 | + if [info exists python_supported_saved] { | |
27726 | + verbose "python_supported: returning saved $python_supported_saved" 2 | |
27727 | + return $python_supported_saved | |
27728 | + } | |
27729 | + | |
27730 | + gdb_test_multiple "python print 'hello, world!'" "verify python support" { | |
27731 | + -re "not supported.*$gdb_prompt $" { | |
27732 | + return [set python_supported_saved 0] | |
27733 | + } | |
27734 | + -re "$gdb_prompt $" { | |
27735 | + return [set python_supported_saved 1] | |
27736 | + } | |
27737 | + } | |
27738 | + | |
27739 | + return [set python_supported_saved 0] | |
27740 | +} | |
27741 | + | |
27742 | +# Run a command in GDB, and report a failure if a Python exception is thrown. | |
27743 | +# If report_pass is true, report a pass if no exception is thrown. | |
27744 | +proc gdb_py_test_silent_cmd {cmd name report_pass} { | |
27745 | + global gdb_prompt | |
27746 | + | |
27747 | + gdb_test_multiple $cmd $name { | |
27748 | + -re "Traceback.*$gdb_prompt $" { fail $name } | |
27749 | + -re "$gdb_prompt $" { if $report_pass { pass $name } } | |
27750 | + } | |
27751 | +} | |
27752 | + | |
27753 | +# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}... | |
27754 | +# Run a test named NAME, consisting of multiple lines of input. | |
27755 | +# After each input line INPUT, search for result line RESULT. | |
27756 | +# Succeed if all results are seen; fail otherwise. | |
27757 | +proc gdb_py_test_multiple {name args} { | |
27758 | + global gdb_prompt | |
27759 | + | |
27760 | + foreach {input result} $args { | |
27761 | + if {[gdb_test_multiple $input "$name - $input" { | |
27762 | + -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" { | |
27763 | + pass "$name - $input" | |
27764 | + } | |
27765 | + }]} { | |
27766 | + return 1 | |
27767 | + } | |
27768 | + } | |
27769 | + return 0 | |
3a58abaf | 27770 | +} |
7566401a ER |
27771 | diff --git a/gdb/thread.c b/gdb/thread.c |
27772 | index 55b4b96..e0ad2d3 100644 | |
27773 | --- a/gdb/thread.c | |
27774 | +++ b/gdb/thread.c | |
27775 | @@ -61,7 +61,6 @@ static int thread_alive (struct thread_info *); | |
27776 | static void info_threads_command (char *, int); | |
27777 | static void thread_apply_command (char *, int); | |
27778 | static void restore_current_thread (ptid_t); | |
27779 | -static void prune_threads (void); | |
3a58abaf | 27780 | |
7566401a ER |
27781 | /* Frontend view of the thread state. Possible extensions: stepping, |
27782 | finishing, until(ling),... */ | |
27783 | @@ -497,16 +496,23 @@ thread_alive (struct thread_info *tp) | |
27784 | return 1; | |
27785 | } | |
3a58abaf | 27786 | |
7566401a ER |
27787 | -static void |
27788 | +void | |
27789 | prune_threads (void) | |
27790 | { | |
27791 | - struct thread_info *tp, *next; | |
27792 | + struct thread_info *tp; | |
27793 | + struct thread_info **prevp = &thread_list; | |
3a58abaf | 27794 | |
7566401a ER |
27795 | - for (tp = thread_list; tp; tp = next) |
27796 | + for (tp = *prevp; tp; tp = *prevp) | |
3a58abaf | 27797 | { |
7566401a ER |
27798 | - next = tp->next; |
27799 | + /* If the thread has died, free it and unlink it from the list. | |
27800 | + Otherwise, advance to the next thread. */ | |
27801 | if (!thread_alive (tp)) | |
27802 | - delete_thread (tp->ptid); | |
3a58abaf | 27803 | + { |
7566401a ER |
27804 | + *prevp = tp->next; |
27805 | + free_thread (tp); | |
3a58abaf | 27806 | + } |
7566401a ER |
27807 | + else |
27808 | + prevp = &tp->next; | |
27809 | } | |
27810 | } | |
3a58abaf | 27811 | |
7566401a ER |
27812 | diff --git a/gdb/top.c b/gdb/top.c |
27813 | index 1b4aa9d..3cfe57e 100644 | |
27814 | --- a/gdb/top.c | |
27815 | +++ b/gdb/top.c | |
27816 | @@ -349,6 +349,7 @@ void | |
27817 | prepare_execute_command (void) | |
27818 | { | |
27819 | free_all_values (); | |
27820 | + free_all_types (); | |
27821 | ||
27822 | /* With multiple threads running while the one we're examining is stopped, | |
27823 | the dcache can get stale without us being able to detect it. | |
27824 | diff --git a/gdb/typeprint.c b/gdb/typeprint.c | |
27825 | index f090231..fc15ec1 100644 | |
27826 | --- a/gdb/typeprint.c | |
27827 | +++ b/gdb/typeprint.c | |
27828 | @@ -35,6 +35,8 @@ | |
27829 | #include "gdb_string.h" | |
27830 | #include "exceptions.h" | |
27831 | #include "valprint.h" | |
27832 | +#include "dwarf2loc.h" | |
3a58abaf | 27833 | + |
7566401a | 27834 | #include <errno.h> |
3a58abaf | 27835 | |
7566401a ER |
27836 | extern void _initialize_typeprint (void); |
27837 | @@ -76,6 +78,9 @@ void | |
27838 | type_print (struct type *type, char *varstring, struct ui_file *stream, | |
27839 | int show) | |
27840 | { | |
27841 | + if (show >= 0) | |
27842 | + type = check_typedef (type); | |
3a58abaf | 27843 | + |
7566401a | 27844 | LA_PRINT_TYPE (type, varstring, stream, show, 0); |
3a58abaf | 27845 | } |
7566401a ER |
27846 | |
27847 | @@ -114,7 +119,8 @@ whatis_exp (char *exp, int show) | |
3a58abaf | 27848 | { |
7566401a ER |
27849 | struct expression *expr; |
27850 | struct value *val; | |
27851 | - struct cleanup *old_chain = NULL; | |
27852 | + /* Required at least for the object_address_set call. */ | |
27853 | + struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); | |
27854 | struct type *real_type = NULL; | |
27855 | struct type *type; | |
27856 | int full = 0; | |
27857 | @@ -125,12 +131,13 @@ whatis_exp (char *exp, int show) | |
27858 | if (exp) | |
27859 | { | |
27860 | expr = parse_expression (exp); | |
27861 | - old_chain = make_cleanup (free_current_contents, &expr); | |
27862 | + make_cleanup (free_current_contents, &expr); | |
27863 | val = evaluate_type (expr); | |
3a58abaf | 27864 | } |
7566401a ER |
27865 | else |
27866 | val = access_value_history (0); | |
3a58abaf | 27867 | |
7566401a ER |
27868 | + object_address_set (value_raw_address (val)); |
27869 | type = value_type (val); | |
27870 | ||
27871 | get_user_print_options (&opts); | |
27872 | @@ -167,8 +174,7 @@ whatis_exp (char *exp, int show) | |
27873 | type_print (type, "", gdb_stdout, show); | |
27874 | printf_filtered ("\n"); | |
27875 | ||
27876 | - if (exp) | |
27877 | - do_cleanups (old_chain); | |
27878 | + do_cleanups (old_chain); | |
27879 | } | |
27880 | ||
27881 | static void | |
27882 | diff --git a/gdb/typeprint.h b/gdb/typeprint.h | |
27883 | index f561310..d261c79 100644 | |
27884 | --- a/gdb/typeprint.h | |
27885 | +++ b/gdb/typeprint.h | |
27886 | @@ -20,10 +20,13 @@ | |
27887 | #ifndef TYPEPRINT_H | |
27888 | #define TYPEPRINT_H | |
27889 | ||
27890 | +enum language; | |
27891 | struct ui_file; | |
27892 | ||
27893 | void print_type_scalar (struct type * type, LONGEST, struct ui_file *); | |
27894 | ||
27895 | void c_type_print_varspec_suffix (struct type *, struct ui_file *, int, | |
27896 | int, int); | |
3a58abaf | 27897 | + |
7566401a ER |
27898 | +void c_type_print_args (struct type *, struct ui_file *, int, enum language); |
27899 | #endif | |
27900 | diff --git a/gdb/ui-file.c b/gdb/ui-file.c | |
27901 | index 527917c..07d959a 100644 | |
27902 | --- a/gdb/ui-file.c | |
27903 | +++ b/gdb/ui-file.c | |
27904 | @@ -22,6 +22,7 @@ | |
27905 | ||
27906 | #include "defs.h" | |
27907 | #include "ui-file.h" | |
27908 | +#include "gdb_obstack.h" | |
27909 | #include "gdb_string.h" | |
27910 | ||
27911 | #include <errno.h> | |
27912 | @@ -263,7 +264,7 @@ set_ui_file_data (struct ui_file *file, void *data, | |
3a58abaf AM |
27913 | } |
27914 | ||
7566401a ER |
27915 | /* ui_file utility function for converting a ``struct ui_file'' into |
27916 | - a memory buffer''. */ | |
27917 | + a memory buffer. */ | |
27918 | ||
27919 | struct accumulated_ui_file | |
27920 | { | |
27921 | @@ -297,6 +298,23 @@ ui_file_xstrdup (struct ui_file *file, long *length) | |
27922 | *length = acc.length; | |
27923 | return acc.buffer; | |
27924 | } | |
27925 | + | |
3a58abaf | 27926 | +static void |
7566401a | 27927 | +do_ui_file_obsavestring (void *context, const char *buffer, long length) |
3a58abaf | 27928 | +{ |
7566401a ER |
27929 | + struct obstack *obstack = (struct obstack *) context; |
27930 | + obstack_grow (obstack, buffer, length); | |
3a58abaf AM |
27931 | +} |
27932 | + | |
7566401a ER |
27933 | +char * |
27934 | +ui_file_obsavestring (struct ui_file *file, struct obstack *obstack, | |
27935 | + long *length) | |
3a58abaf | 27936 | +{ |
7566401a ER |
27937 | + ui_file_put (file, do_ui_file_obsavestring, obstack); |
27938 | + *length = obstack_object_size (obstack); | |
27939 | + obstack_1grow (obstack, '\0'); | |
27940 | + return obstack_finish (obstack); | |
3a58abaf | 27941 | +} |
7566401a ER |
27942 | \f |
27943 | /* A pure memory based ``struct ui_file'' that can be used an output | |
27944 | buffer. The buffers accumulated contents are available via | |
27945 | diff --git a/gdb/ui-file.h b/gdb/ui-file.h | |
27946 | index bf9915c..233206c 100644 | |
27947 | --- a/gdb/ui-file.h | |
27948 | +++ b/gdb/ui-file.h | |
27949 | @@ -19,6 +19,7 @@ | |
27950 | #ifndef UI_FILE_H | |
27951 | #define UI_FILE_H | |
27952 | ||
27953 | +struct obstack; | |
27954 | struct ui_file; | |
27955 | ||
27956 | /* Create a generic ui_file object with null methods. */ | |
27957 | @@ -77,7 +78,10 @@ extern void ui_file_put (struct ui_file *src, ui_file_put_method_ftype *write, v | |
27958 | minus that appended NUL. */ | |
27959 | extern char *ui_file_xstrdup (struct ui_file *file, long *length); | |
27960 | ||
27961 | - | |
27962 | +/* Similar to ui_file_xstrdup, but return a new string allocated on | |
27963 | + OBSTACK. */ | |
27964 | +extern char *ui_file_obsavestring (struct ui_file *file, | |
27965 | + struct obstack *obstack, long *length); | |
27966 | ||
27967 | extern long ui_file_read (struct ui_file *file, char *buf, long length_buf); | |
27968 | ||
27969 | diff --git a/gdb/utils.c b/gdb/utils.c | |
27970 | index 16ad084..3021a43 100644 | |
27971 | --- a/gdb/utils.c | |
27972 | +++ b/gdb/utils.c | |
27973 | @@ -2610,7 +2610,10 @@ fprintf_symbol_filtered (struct ui_file *stream, char *name, | |
27974 | As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO". | |
27975 | This "feature" is useful when searching for matching C++ function names | |
27976 | (such as if the user types 'break FOO', where FOO is a mangled C++ | |
27977 | - function). */ | |
27978 | + function). | |
3a58abaf | 27979 | + |
7566401a ER |
27980 | + As an extra-special hack, we do the same with ' ', so that |
27981 | + "FOO(ARGS) const" can match "FOO", too. */ | |
3a58abaf | 27982 | |
7566401a ER |
27983 | int |
27984 | strcmp_iw (const char *string1, const char *string2) | |
27985 | @@ -2635,7 +2638,7 @@ strcmp_iw (const char *string1, const char *string2) | |
27986 | string2++; | |
27987 | } | |
27988 | } | |
27989 | - return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0'); | |
27990 | + return (*string1 != ' ' && *string1 != '\0' && *string1 != '(') || (*string2 != '\0' && *string2 != '('); | |
3a58abaf AM |
27991 | } |
27992 | ||
7566401a ER |
27993 | /* This is like strcmp except that it ignores whitespace and treats |
27994 | diff --git a/gdb/valarith.c b/gdb/valarith.c | |
27995 | index a9c875d..12f6f07 100644 | |
27996 | --- a/gdb/valarith.c | |
27997 | +++ b/gdb/valarith.c | |
27998 | @@ -139,7 +139,6 @@ an integer nor a pointer of the same type.")); | |
27999 | struct value * | |
28000 | value_subscript (struct value *array, LONGEST index) | |
3a58abaf | 28001 | { |
7566401a ER |
28002 | - struct value *bound; |
28003 | int c_style = current_language->c_style_arrays; | |
28004 | struct type *tarray; | |
3a58abaf | 28005 | |
7566401a ER |
28006 | @@ -154,12 +153,26 @@ value_subscript (struct value *array, LONGEST index) |
28007 | get_discrete_bounds (range_type, &lowerbound, &upperbound); | |
3a58abaf | 28008 | |
7566401a ER |
28009 | if (VALUE_LVAL (array) != lval_memory) |
28010 | - return value_subscripted_rvalue (array, index, lowerbound); | |
28011 | + { | |
28012 | + if (index >= lowerbound && index <= upperbound) | |
28013 | + { | |
28014 | + CORE_ADDR element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tarray)); | |
28015 | + CORE_ADDR offset = (index - lowerbound) * element_size; | |
3a58abaf | 28016 | + |
7566401a ER |
28017 | + return value_subscripted_rvalue (array, offset); |
28018 | + } | |
28019 | + error (_("array or string index out of range")); | |
28020 | + } | |
3a58abaf | 28021 | |
7566401a ER |
28022 | if (c_style == 0) |
28023 | { | |
28024 | if (index >= lowerbound && index <= upperbound) | |
28025 | - return value_subscripted_rvalue (array, index, lowerbound); | |
28026 | + { | |
28027 | + CORE_ADDR element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tarray)); | |
28028 | + CORE_ADDR offset = (index - lowerbound) * element_size; | |
3a58abaf | 28029 | + |
7566401a ER |
28030 | + return value_subscripted_rvalue (array, offset); |
28031 | + } | |
28032 | /* Emit warning unless we have an array of unknown size. | |
28033 | An array of unknown size has lowerbound 0 and upperbound -1. */ | |
28034 | if (upperbound > -1) | |
28035 | @@ -178,33 +191,37 @@ value_subscript (struct value *array, LONGEST index) | |
28036 | error (_("not an array or string")); | |
28037 | } | |
3a58abaf | 28038 | |
7566401a ER |
28039 | -/* Return the value of EXPR[IDX], expr an aggregate rvalue |
28040 | - (eg, a vector register). This routine used to promote floats | |
28041 | - to doubles, but no longer does. */ | |
28042 | +/* Return the value of *((void *) ARRAY + ELEMENT), ARRAY an aggregate rvalue | |
28043 | + (eg, a vector register). This routine used to promote floats to doubles, | |
28044 | + but no longer does. OFFSET is zero-based with 0 for the lowermost existing | |
28045 | + element, it must be expressed in bytes (therefore multiplied by | |
28046 | + check_typedef (TYPE_TARGET_TYPE (array_type)). */ | |
3a58abaf | 28047 | |
7566401a ER |
28048 | struct value * |
28049 | -value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound) | |
28050 | +value_subscripted_rvalue (struct value *array, CORE_ADDR offset) | |
28051 | { | |
28052 | struct type *array_type = check_typedef (value_type (array)); | |
28053 | struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type)); | |
28054 | - unsigned int elt_size = TYPE_LENGTH (elt_type); | |
28055 | - unsigned int elt_offs = elt_size * longest_to_int (index - lowerbound); | |
28056 | struct value *v; | |
3a58abaf | 28057 | |
7566401a ER |
28058 | - if (index < lowerbound || elt_offs >= TYPE_LENGTH (array_type)) |
28059 | - error (_("no such vector element")); | |
28060 | + /* Do not check TYPE_LENGTH (array_type) as we may have been given the | |
28061 | + innermost dimension of a multi-dimensional Fortran array where its length | |
28062 | + is shorter than the possibly accessed element offset. */ | |
3a58abaf | 28063 | |
7566401a ER |
28064 | v = allocate_value (elt_type); |
28065 | if (VALUE_LVAL (array) == lval_memory && value_lazy (array)) | |
28066 | set_value_lazy (v, 1); | |
28067 | else | |
28068 | - memcpy (value_contents_writeable (v), | |
28069 | - value_contents (array) + elt_offs, elt_size); | |
28070 | + { | |
28071 | + unsigned int elt_size = TYPE_LENGTH (elt_type); | |
28072 | + memcpy (value_contents_writeable (v), | |
28073 | + value_contents (array) + offset, elt_size); | |
28074 | + } | |
3a58abaf | 28075 | |
7566401a ER |
28076 | set_value_component_location (v, array); |
28077 | VALUE_REGNUM (v) = VALUE_REGNUM (array); | |
28078 | VALUE_FRAME_ID (v) = VALUE_FRAME_ID (array); | |
28079 | - set_value_offset (v, value_offset (array) + elt_offs); | |
28080 | + set_value_offset (v, value_offset (array) + offset); | |
28081 | return v; | |
28082 | } | |
3a58abaf | 28083 | |
7566401a | 28084 | diff --git a/gdb/valops.c b/gdb/valops.c |
ab050a48 | 28085 | index 012ea6a..9b4d2a8 100644 |
7566401a ER |
28086 | --- a/gdb/valops.c |
28087 | +++ b/gdb/valops.c | |
28088 | @@ -38,6 +38,7 @@ | |
28089 | #include "cp-support.h" | |
28090 | #include "dfp.h" | |
28091 | #include "user-regs.h" | |
28092 | +#include "dwarf2loc.h" | |
3a58abaf | 28093 | |
7566401a ER |
28094 | #include <errno.h> |
28095 | #include "gdb_string.h" | |
28096 | @@ -369,8 +370,6 @@ value_cast (struct type *type, struct value *arg2) | |
28097 | new_length = val_length / element_length; | |
28098 | if (val_length % element_length != 0) | |
28099 | warning (_("array element type size does not divide object size in cast")); | |
28100 | - /* FIXME-type-allocation: need a way to free this type when | |
28101 | - we are done with it. */ | |
28102 | range_type = create_range_type ((struct type *) NULL, | |
28103 | TYPE_TARGET_TYPE (range_type), | |
28104 | low_bound, | |
28105 | @@ -565,6 +564,64 @@ value_one (struct type *type, enum lval_type lv) | |
28106 | return val; | |
28107 | } | |
3a58abaf | 28108 | |
7566401a | 28109 | +/* object_address_set must be already called before this function. */ |
3a58abaf AM |
28110 | + |
28111 | +const char * | |
7566401a | 28112 | +object_address_data_not_valid (struct type *type) |
3a58abaf | 28113 | +{ |
7566401a ER |
28114 | + /* Attributes are present only at the target type of a typedef. Make the |
28115 | + call conditional as it would otherwise loop through type_length_get. */ | |
28116 | + if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) | |
28117 | + CHECK_TYPEDEF (type); | |
3a58abaf | 28118 | + |
7566401a ER |
28119 | + /* DW_AT_associated has a preference over DW_AT_allocated. */ |
28120 | + if (TYPE_NOT_ASSOCIATED (type) | |
28121 | + || (TYPE_ASSOCIATED (type) != NULL | |
28122 | + && 0 == dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (type)))) | |
28123 | + return N_("object is not associated"); | |
28124 | + | |
28125 | + if (TYPE_NOT_ALLOCATED (type) | |
28126 | + || (TYPE_ALLOCATED (type) != NULL | |
28127 | + && 0 == dwarf_locexpr_baton_eval (TYPE_ALLOCATED (type)))) | |
28128 | + return N_("object is not allocated"); | |
3a58abaf | 28129 | + |
3a58abaf AM |
28130 | + return NULL; |
28131 | +} | |
28132 | + | |
7566401a ER |
28133 | +/* Return non-zero if the variable is valid. If it is valid the function |
28134 | + may store the data address (DW_AT_DATA_LOCATION) of TYPE at *ADDRESS_RETURN. | |
28135 | + You must set *ADDRESS_RETURN from value_raw_address (VAL) before calling this | |
28136 | + function. If no DW_AT_DATA_LOCATION is present for TYPE the address at | |
28137 | + *ADDRESS_RETURN is left unchanged. ADDRESS_RETURN must not be NULL, use | |
28138 | + object_address_data_not_valid () for just the data validity check. */ | |
3a58abaf | 28139 | + |
7566401a ER |
28140 | +int |
28141 | +object_address_get_data (struct type *type, CORE_ADDR *address_return) | |
3a58abaf | 28142 | +{ |
7566401a | 28143 | + gdb_assert (address_return != NULL); |
3a58abaf | 28144 | + |
7566401a | 28145 | + object_address_set (*address_return); |
3a58abaf | 28146 | + |
7566401a ER |
28147 | + /* TYPE_DATA_LOCATION_DWARF_BLOCK / TYPE_DATA_LOCATION_ADDR are present only |
28148 | + at the target type of a typedef. */ | |
28149 | + CHECK_TYPEDEF (type); | |
3a58abaf | 28150 | + |
7566401a ER |
28151 | + if (object_address_data_not_valid (type) != NULL) |
28152 | + { | |
28153 | + /* Do not try to evaluate DW_AT_data_location as it may even crash | |
28154 | + (it would just return the value zero in the gfortran case). */ | |
28155 | + return 0; | |
28156 | + } | |
3a58abaf | 28157 | + |
7566401a ER |
28158 | + if (TYPE_DATA_LOCATION_IS_ADDR (type)) |
28159 | + *address_return = TYPE_DATA_LOCATION_ADDR (type); | |
28160 | + else if (TYPE_DATA_LOCATION_DWARF_BLOCK (type) != NULL) | |
28161 | + *address_return | |
28162 | + = dwarf_locexpr_baton_eval (TYPE_DATA_LOCATION_DWARF_BLOCK (type)); | |
3a58abaf | 28163 | + |
7566401a ER |
28164 | + return 1; |
28165 | +} | |
3a58abaf | 28166 | + |
7566401a ER |
28167 | /* Helper function for value_at, value_at_lazy, and value_at_lazy_stack. */ |
28168 | ||
28169 | static struct value * | |
28170 | @@ -656,15 +713,21 @@ value_fetch_lazy (struct value *val) | |
28171 | } | |
28172 | else if (VALUE_LVAL (val) == lval_memory) | |
28173 | { | |
28174 | - CORE_ADDR addr = value_address (val); | |
28175 | - int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val))); | |
28176 | + CORE_ADDR addr = value_raw_address (val); | |
28177 | ||
28178 | - if (length) | |
28179 | + if (object_address_get_data (value_type (val), &addr)) | |
28180 | { | |
28181 | - if (value_stack (val)) | |
28182 | - read_stack (addr, value_contents_all_raw (val), length); | |
28183 | - else | |
28184 | - read_memory (addr, value_contents_all_raw (val), length); | |
28185 | + struct type *type = value_enclosing_type (val); | |
28186 | + int length = TYPE_LENGTH (check_typedef (type)); | |
3a58abaf | 28187 | + |
7566401a ER |
28188 | + if (length) |
28189 | + { | |
28190 | + addr += value_offset (val); | |
28191 | + if (value_stack (val)) | |
28192 | + read_stack (addr, value_contents_all_raw (val), length); | |
28193 | + else | |
28194 | + read_memory (addr, value_contents_all_raw (val), length); | |
28195 | + } | |
28196 | } | |
28197 | } | |
28198 | else if (VALUE_LVAL (val) == lval_register) | |
ab050a48 | 28199 | @@ -1072,7 +1135,18 @@ address_of_variable (struct symbol *var, struct block *b) |
7566401a ER |
28200 | if ((VALUE_LVAL (val) == lval_memory && value_lazy (val)) |
28201 | || TYPE_CODE (type) == TYPE_CODE_FUNC) | |
28202 | { | |
28203 | - CORE_ADDR addr = value_address (val); | |
28204 | + CORE_ADDR addr; | |
3a58abaf | 28205 | + |
7566401a ER |
28206 | + if (VALUE_LVAL (val) == lval_memory) |
28207 | + { | |
28208 | + addr = value_raw_address (val); | |
28209 | + if (!object_address_get_data (type, &addr)) | |
28210 | + error (_("Can't take address of memory lvalue \"%s\"."), | |
28211 | + SYMBOL_PRINT_NAME (var)); | |
28212 | + set_value_address (val, addr); | |
28213 | + } | |
3a58abaf | 28214 | + |
7566401a ER |
28215 | + addr = value_address (val); |
28216 | return value_from_pointer (lookup_pointer_type (type), addr); | |
28217 | } | |
28218 | ||
ab050a48 | 28219 | @@ -1178,6 +1252,7 @@ struct value * |
7566401a ER |
28220 | value_coerce_array (struct value *arg1) |
28221 | { | |
28222 | struct type *type = check_typedef (value_type (arg1)); | |
28223 | + CORE_ADDR address; | |
28224 | ||
28225 | /* If the user tries to do something requiring a pointer with an | |
28226 | array that has not yet been pushed to the target, then this would | |
ab050a48 | 28227 | @@ -1187,8 +1262,12 @@ value_coerce_array (struct value *arg1) |
7566401a ER |
28228 | if (VALUE_LVAL (arg1) != lval_memory) |
28229 | error (_("Attempt to take address of value not located in memory.")); | |
28230 | ||
28231 | + address = value_raw_address (arg1); | |
28232 | + if (!object_address_get_data (type, &address)) | |
28233 | + error (_("Attempt to take address of non-valid value.")); | |
3a58abaf | 28234 | + |
7566401a ER |
28235 | return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)), |
28236 | - value_address (arg1)); | |
28237 | + address + value_offset (arg1)); | |
28238 | } | |
28239 | ||
28240 | /* Given a value which is a function, return a value which is a pointer | |
ab050a48 | 28241 | @@ -2071,12 +2150,25 @@ find_overload_match (struct type **arg_types, int nargs, |
7566401a ER |
28242 | if (method) |
28243 | { | |
28244 | gdb_assert (obj); | |
3a58abaf | 28245 | + |
7566401a ER |
28246 | + /* OBJ may be a pointer value rather than the object itself. */ |
28247 | + obj = coerce_ref (obj); | |
28248 | + while (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_PTR) | |
28249 | + obj = coerce_ref (value_ind (obj)); | |
28250 | obj_type_name = TYPE_NAME (value_type (obj)); | |
28251 | - /* Hack: evaluate_subexp_standard often passes in a pointer | |
28252 | - value rather than the object itself, so try again. */ | |
28253 | - if ((!obj_type_name || !*obj_type_name) | |
28254 | - && (TYPE_CODE (value_type (obj)) == TYPE_CODE_PTR)) | |
28255 | - obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (value_type (obj))); | |
3a58abaf | 28256 | + |
7566401a ER |
28257 | + /* First check whether this is a data member, e.g. a pointer to |
28258 | + a function. */ | |
28259 | + if (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_STRUCT) | |
28260 | + { | |
28261 | + *valp = search_struct_field (name, obj, 0, | |
28262 | + check_typedef (value_type (obj)), 0); | |
28263 | + if (*valp) | |
28264 | + { | |
28265 | + *staticp = 1; | |
28266 | + return 0; | |
28267 | + } | |
28268 | + } | |
28269 | ||
28270 | fns_ptr = value_find_oload_method_list (&temp, name, | |
28271 | 0, &num_fns, | |
ab050a48 | 28272 | @@ -2096,16 +2188,29 @@ find_overload_match (struct type **arg_types, int nargs, |
7566401a ER |
28273 | } |
28274 | else | |
28275 | { | |
28276 | - const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym); | |
28277 | + const char *qualified_name = SYMBOL_NATURAL_NAME (fsym); | |
3a58abaf | 28278 | + |
7566401a ER |
28279 | + /* If we have a function with a C++ name, try to extract just |
28280 | + the function part. Do not try this for non-functions (e.g. | |
28281 | + function pointers). */ | |
28282 | + if (qualified_name | |
28283 | + && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC) | |
28284 | + { | |
28285 | + func_name = cp_func_name (qualified_name); | |
28286 | ||
28287 | - /* If we have a C++ name, try to extract just the function | |
28288 | - part. */ | |
28289 | - if (qualified_name) | |
28290 | - func_name = cp_func_name (qualified_name); | |
28291 | + /* If cp_func_name did not remove anything, the name of the | |
28292 | + symbol did not include scope or argument types - it was | |
28293 | + probably a C-style function. */ | |
28294 | + if (func_name && strcmp (func_name, qualified_name) == 0) | |
28295 | + { | |
28296 | + xfree (func_name); | |
28297 | + func_name = NULL; | |
28298 | + } | |
28299 | + } | |
28300 | ||
28301 | - /* If there was no C++ name, this must be a C-style function. | |
28302 | - Just return the same symbol. Do the same if cp_func_name | |
28303 | - fails for some reason. */ | |
28304 | + /* If there was no C++ name, this must be a C-style function or | |
28305 | + not a function at all. Just return the same symbol. Do the | |
28306 | + same if cp_func_name fails for some reason. */ | |
28307 | if (func_name == NULL) | |
28308 | { | |
28309 | *symp = fsym; | |
ab050a48 | 28310 | @@ -2536,8 +2641,8 @@ check_field (struct type *type, const char *name) |
7566401a ER |
28311 | the comment before value_struct_elt_for_reference. */ |
28312 | ||
28313 | struct value * | |
28314 | -value_aggregate_elt (struct type *curtype, | |
28315 | - char *name, int want_address, | |
28316 | +value_aggregate_elt (struct type *curtype, char *name, | |
28317 | + struct type *expect_type, int want_address, | |
28318 | enum noside noside) | |
28319 | { | |
28320 | switch (TYPE_CODE (curtype)) | |
ab050a48 | 28321 | @@ -2545,7 +2650,7 @@ value_aggregate_elt (struct type *curtype, |
7566401a ER |
28322 | case TYPE_CODE_STRUCT: |
28323 | case TYPE_CODE_UNION: | |
28324 | return value_struct_elt_for_reference (curtype, 0, curtype, | |
28325 | - name, NULL, | |
28326 | + name, expect_type, | |
28327 | want_address, noside); | |
28328 | case TYPE_CODE_NAMESPACE: | |
28329 | return value_namespace_elt (curtype, name, | |
ab050a48 | 28330 | @@ -2556,6 +2661,56 @@ value_aggregate_elt (struct type *curtype, |
7566401a ER |
28331 | } |
28332 | } | |
28333 | ||
28334 | +/* Compares the two method/function types T1 and T2 for "equality" | |
28335 | + with respect to the the methods' parameters. If the types of the | |
28336 | + two parameter lists are the same, returns 1; 0 otherwise. This | |
28337 | + comparison may ignore any artificial parameters in T1 if | |
28338 | + SKIP_ARTIFICIAL is non-zero. This function will ALWAYS skip | |
28339 | + the first artificial parameter in T1, assumed to be a 'this' pointer. | |
3a58abaf | 28340 | + |
7566401a ER |
28341 | + The type T2 is expected to have come from make_params (in eval.c). */ |
28342 | +static int | |
28343 | +compare_parameters (struct type *t1, struct type *t2, int skip_artificial) | |
3a58abaf | 28344 | +{ |
7566401a | 28345 | + int start = 0; |
3a58abaf | 28346 | + |
7566401a ER |
28347 | + if (TYPE_FIELD_ARTIFICIAL (t1, 0)) |
28348 | + ++start; | |
3a58abaf | 28349 | + |
7566401a ER |
28350 | + /* If skipping artificial fields, find the first real field |
28351 | + in T1. */ | |
28352 | + if (skip_artificial) | |
3a58abaf | 28353 | + { |
7566401a ER |
28354 | + while (start < TYPE_NFIELDS (t1) |
28355 | + && TYPE_FIELD_ARTIFICIAL (t1, start)) | |
28356 | + ++start; | |
3a58abaf | 28357 | + } |
3a58abaf | 28358 | + |
7566401a | 28359 | + /* Now compare parameters */ |
3a58abaf | 28360 | + |
7566401a ER |
28361 | + /* Special case: a method taking void. T1 will contain no |
28362 | + non-artificial fields, and T2 will contain TYPE_CODE_VOID. */ | |
28363 | + if ((TYPE_NFIELDS (t1) - start) == 0 && TYPE_NFIELDS (t2) == 1 | |
28364 | + && TYPE_CODE (TYPE_FIELD_TYPE (t2, 0)) == TYPE_CODE_VOID) | |
28365 | + return 1; | |
3a58abaf | 28366 | + |
7566401a | 28367 | + if ((TYPE_NFIELDS (t1) - start) == TYPE_NFIELDS (t2)) |
3a58abaf | 28368 | + { |
7566401a ER |
28369 | + int i; |
28370 | + for (i = 0; i < TYPE_NFIELDS (t2); ++i) | |
3a58abaf | 28371 | + { |
7566401a ER |
28372 | + if (rank_one_type (TYPE_FIELD_TYPE (t1, start + i), |
28373 | + TYPE_FIELD_TYPE (t2, i)) | |
28374 | + != 0) | |
28375 | + return 0; | |
3a58abaf AM |
28376 | + } |
28377 | + | |
7566401a | 28378 | + return 1; |
3a58abaf AM |
28379 | + } |
28380 | + | |
7566401a | 28381 | + return 0; |
3a58abaf AM |
28382 | +} |
28383 | + | |
7566401a ER |
28384 | /* C++: Given an aggregate type CURTYPE, and a member name NAME, |
28385 | return the address of this member as a "pointer to member" type. | |
28386 | If INTYPE is non-null, then it will be the type of the member we | |
ab050a48 | 28387 | @@ -2633,23 +2788,46 @@ value_struct_elt_for_reference (struct type *domain, int offset, |
7566401a ER |
28388 | } |
28389 | if (t_field_name && strcmp (t_field_name, name) == 0) | |
28390 | { | |
28391 | - int j = TYPE_FN_FIELDLIST_LENGTH (t, i); | |
28392 | + int j; | |
28393 | + int len = TYPE_FN_FIELDLIST_LENGTH (t, i); | |
28394 | struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i); | |
28395 | ||
28396 | check_stub_method_group (t, i); | |
28397 | ||
28398 | - if (intype == 0 && j > 1) | |
28399 | - error (_("non-unique member `%s' requires type instantiation"), name); | |
28400 | if (intype) | |
28401 | { | |
28402 | - while (j--) | |
28403 | - if (TYPE_FN_FIELD_TYPE (f, j) == intype) | |
28404 | - break; | |
28405 | - if (j < 0) | |
28406 | - error (_("no member function matches that type instantiation")); | |
28407 | - } | |
28408 | + for (j = 0; j < len; ++j) | |
28409 | + { | |
28410 | + if (compare_parameters (TYPE_FN_FIELD_TYPE (f, j), intype, 0) | |
28411 | + || compare_parameters (TYPE_FN_FIELD_TYPE (f, j), intype, 1)) | |
28412 | + break; | |
28413 | + } | |
3a58abaf | 28414 | + |
7566401a ER |
28415 | + if (j == len) |
28416 | + error (_("no member function matches that type instantiation")); } | |
28417 | else | |
28418 | - j = 0; | |
28419 | + { | |
28420 | + int ii; | |
28421 | + /* Skip artificial methods. This is necessary if, for example, | |
28422 | + the user wants to "print subclass::subclass" with only | |
28423 | + one defined user constructor. There is no ambiguity in this | |
28424 | + case. */ | |
28425 | + for (ii = 0; ii < TYPE_FN_FIELDLIST_LENGTH (t, i); | |
28426 | + ++ii) | |
28427 | + { | |
28428 | + if (TYPE_FN_FIELD_ARTIFICIAL (f, ii)) | |
28429 | + --len; | |
28430 | + } | |
3a58abaf | 28431 | + |
7566401a ER |
28432 | + /* Desired method is ambiguous if more than one method is |
28433 | + defined. */ | |
28434 | + if (len > 1) | |
28435 | + error (_("non-unique member `%s' requires type instantiation"), name); | |
3a58abaf | 28436 | + |
7566401a ER |
28437 | + /* This assumes, of course, that all artificial methods appear |
28438 | + BEFORE any concrete methods. */ | |
28439 | + j = TYPE_FN_FIELDLIST_LENGTH (t, i) - 1; | |
28440 | + } | |
28441 | ||
28442 | if (TYPE_FN_FIELD_STATIC_P (f, j)) | |
28443 | { | |
ab050a48 | 28444 | @@ -2763,7 +2941,7 @@ value_maybe_namespace_elt (const struct type *curtype, |
7566401a ER |
28445 | struct symbol *sym; |
28446 | struct value *result; | |
28447 | ||
28448 | - sym = cp_lookup_symbol_namespace (namespace_name, name, NULL, | |
28449 | + sym = cp_lookup_symbol_namespace(namespace_name, name, | |
28450 | get_selected_block (0), | |
28451 | VAR_DOMAIN); | |
28452 | ||
ab050a48 | 28453 | @@ -2907,7 +3085,7 @@ value_of_local (const char *name, int complain) |
7566401a ER |
28454 | |
28455 | /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER | |
28456 | symbol instead of the LOC_ARG one (if both exist). */ | |
28457 | - sym = lookup_block_symbol (b, name, NULL, VAR_DOMAIN); | |
28458 | + sym = lookup_block_symbol (b, name, VAR_DOMAIN); | |
28459 | if (sym == NULL) | |
28460 | { | |
28461 | if (complain) | |
ab050a48 | 28462 | @@ -2961,8 +3139,6 @@ value_slice (struct value *array, int lowbound, int length) |
7566401a ER |
28463 | || lowbound + length - 1 > upperbound) |
28464 | error (_("slice out of range")); | |
28465 | ||
28466 | - /* FIXME-type-allocation: need a way to free this type when we are | |
28467 | - done with it. */ | |
28468 | slice_range_type = create_range_type ((struct type *) NULL, | |
28469 | TYPE_TARGET_TYPE (range_type), | |
28470 | lowbound, | |
28471 | diff --git a/gdb/valprint.c b/gdb/valprint.c | |
28472 | index cbb5d94..f9634ea 100644 | |
28473 | --- a/gdb/valprint.c | |
28474 | +++ b/gdb/valprint.c | |
28475 | @@ -236,7 +236,6 @@ scalar_type_p (struct type *type) | |
28476 | case TYPE_CODE_STRUCT: | |
28477 | case TYPE_CODE_UNION: | |
28478 | case TYPE_CODE_SET: | |
28479 | - case TYPE_CODE_STRING: | |
28480 | case TYPE_CODE_BITSTRING: | |
28481 | return 0; | |
28482 | default: | |
28483 | @@ -1153,6 +1152,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr, | |
28484 | ||
28485 | for (; i < len && things_printed < options->print_max; i++) | |
28486 | { | |
28487 | + size_t elt_offset = i * eltlen; | |
28488 | if (i != 0) | |
28489 | { | |
28490 | if (options->prettyprint_arrays) | |
28491 | @@ -1172,7 +1172,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr, | |
28492 | rep1 = i + 1; | |
28493 | reps = 1; | |
28494 | while ((rep1 < len) && | |
28495 | - !memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen)) | |
28496 | + !memcmp (valaddr + elt_offset, valaddr + rep1 * eltlen, eltlen)) | |
28497 | { | |
28498 | ++reps; | |
28499 | ++rep1; | |
28500 | diff --git a/gdb/value.c b/gdb/value.c | |
28501 | index 589e03b..66013b7 100644 | |
28502 | --- a/gdb/value.c | |
28503 | +++ b/gdb/value.c | |
28504 | @@ -37,8 +37,10 @@ | |
28505 | #include "block.h" | |
28506 | #include "dfp.h" | |
28507 | #include "objfiles.h" | |
28508 | +#include "cli/cli-decode.h" | |
28509 | #include "valprint.h" | |
28510 | #include "cli/cli-decode.h" | |
28511 | +#include "observer.h" | |
28512 | ||
28513 | #include "python/python.h" | |
28514 | ||
28515 | @@ -170,6 +172,14 @@ struct value | |
28516 | taken off this list. */ | |
28517 | struct value *next; | |
28518 | ||
28519 | + /* The reference count. A value that is still on the `all_values' | |
28520 | + list will have a reference count of 0. A call to `release_value' | |
28521 | + will increment the reference count (and remove the value from the | |
28522 | + list, the first time). A call to `value_free' will decrement the | |
28523 | + reference count, and will free the value when there are no more | |
28524 | + references. */ | |
28525 | + int refcount; | |
3a58abaf | 28526 | + |
7566401a ER |
28527 | /* Register number if the value is from a register. */ |
28528 | short regnum; | |
28529 | ||
28530 | @@ -261,7 +271,9 @@ allocate_value_lazy (struct type *type) | |
28531 | val->next = all_values; | |
28532 | all_values = val; | |
28533 | val->type = type; | |
28534 | + type_incref (type); | |
28535 | val->enclosing_type = type; | |
28536 | + type_incref (type); | |
28537 | VALUE_LVAL (val) = not_lval; | |
28538 | val->location.address = 0; | |
28539 | VALUE_FRAME_ID (val) = null_frame_id; | |
28540 | @@ -346,6 +358,8 @@ value_type (struct value *value) | |
28541 | void | |
28542 | deprecated_set_value_type (struct value *value, struct type *type) | |
28543 | { | |
28544 | + type_incref (type); | |
28545 | + type_decref (value->type); | |
28546 | value->type = type; | |
28547 | } | |
28548 | ||
28549 | @@ -624,6 +638,9 @@ value_free (struct value *val) | |
28550 | if (val->parent != NULL) | |
28551 | value_free (val->parent); | |
28552 | ||
28553 | + type_decref (val->type); | |
28554 | + type_decref (val->enclosing_type); | |
3a58abaf | 28555 | + |
7566401a ER |
28556 | if (VALUE_LVAL (val) == lval_computed) |
28557 | { | |
28558 | struct lval_funcs *funcs = val->location.computed.funcs; | |
28559 | @@ -728,6 +745,9 @@ value_copy (struct value *arg) | |
28560 | val = allocate_value_lazy (encl_type); | |
28561 | else | |
28562 | val = allocate_value (encl_type); | |
3a58abaf | 28563 | + |
7566401a ER |
28564 | + type_incref (arg->type); |
28565 | + type_decref (val->type); | |
28566 | val->type = arg->type; | |
28567 | VALUE_LVAL (val) = VALUE_LVAL (arg); | |
28568 | val->location = arg->location; | |
28569 | @@ -763,12 +783,15 @@ value_copy (struct value *arg) | |
28570 | void | |
28571 | set_value_component_location (struct value *component, struct value *whole) | |
28572 | { | |
28573 | + CORE_ADDR addr; | |
3a58abaf | 28574 | + |
7566401a ER |
28575 | if (VALUE_LVAL (whole) == lval_internalvar) |
28576 | VALUE_LVAL (component) = lval_internalvar_component; | |
28577 | else | |
28578 | VALUE_LVAL (component) = VALUE_LVAL (whole); | |
28579 | ||
28580 | component->location = whole->location; | |
3a58abaf | 28581 | + |
7566401a ER |
28582 | if (VALUE_LVAL (whole) == lval_computed) |
28583 | { | |
28584 | struct lval_funcs *funcs = whole->location.computed.funcs; | |
28585 | @@ -776,6 +799,10 @@ set_value_component_location (struct value *component, struct value *whole) | |
28586 | if (funcs->copy_closure) | |
28587 | component->location.computed.closure = funcs->copy_closure (whole); | |
28588 | } | |
3a58abaf | 28589 | + |
7566401a ER |
28590 | + addr = value_raw_address (component); |
28591 | + object_address_get_data (value_type (whole), &addr); | |
28592 | + set_value_address (component, addr); | |
28593 | } | |
28594 | ||
28595 | \f | |
28596 | @@ -906,6 +933,29 @@ show_values (char *num_exp, int from_tty) | |
28597 | num_exp[1] = '\0'; | |
28598 | } | |
28599 | } | |
3a58abaf | 28600 | + |
7566401a | 28601 | +/* Sanity check for memory leaks and proper types reference counting. */ |
3a58abaf | 28602 | + |
7566401a ER |
28603 | +static void |
28604 | +value_history_cleanup (void *unused) | |
3a58abaf | 28605 | +{ |
7566401a ER |
28606 | + while (value_history_chain) |
28607 | + { | |
28608 | + struct value_history_chunk *chunk = value_history_chain; | |
28609 | + int i; | |
3a58abaf | 28610 | + |
7566401a ER |
28611 | + for (i = 0; i < ARRAY_SIZE (chunk->values); i++) |
28612 | + value_free (chunk->values[i]); | |
3a58abaf | 28613 | + |
7566401a ER |
28614 | + value_history_chain = chunk->next; |
28615 | + xfree (chunk); | |
28616 | + } | |
28617 | + value_history_count = 0; | |
3a58abaf | 28618 | + |
7566401a ER |
28619 | + /* Free the unreferenced types above. */ |
28620 | + free_all_values (); | |
28621 | + free_all_types (); | |
3a58abaf | 28622 | +} |
7566401a ER |
28623 | \f |
28624 | /* Internal variables. These are variables within the debugger | |
28625 | that hold values assigned by debugger commands. | |
28626 | @@ -1381,6 +1431,40 @@ call_internal_function (struct gdbarch *gdbarch, | |
28627 | return (*ifn->handler) (gdbarch, language, ifn->cookie, argc, argv); | |
28628 | } | |
28629 | ||
28630 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ | |
3a58abaf | 28631 | + |
7566401a ER |
28632 | +static void |
28633 | +value_types_mark_used (void) | |
3a58abaf | 28634 | +{ |
7566401a ER |
28635 | + struct internalvar *var; |
28636 | + struct value_history_chunk *chunk; | |
3a58abaf | 28637 | + |
7566401a ER |
28638 | + for (var = internalvars; var != NULL; var = var->next) |
28639 | + switch (var->kind) | |
28640 | + { | |
28641 | + case INTERNALVAR_VALUE: | |
28642 | + type_mark_used (value_type (var->u.value)); | |
28643 | + break; | |
3a58abaf | 28644 | + |
7566401a ER |
28645 | + case INTERNALVAR_INTEGER: |
28646 | + type_mark_used (var->u.integer.type); | |
28647 | + break; | |
3a58abaf | 28648 | + |
7566401a ER |
28649 | + case INTERNALVAR_POINTER: |
28650 | + type_mark_used (var->u.pointer.type); | |
28651 | + break; | |
28652 | + } | |
3a58abaf | 28653 | + |
7566401a ER |
28654 | + for (chunk = value_history_chain; chunk != NULL; chunk = chunk->next) |
28655 | + { | |
28656 | + int i; | |
3a58abaf | 28657 | + |
7566401a ER |
28658 | + for (i = 0; i < ARRAY_SIZE (chunk->values); i++) |
28659 | + if (chunk->values[i]) | |
28660 | + type_mark_used (value_type (chunk->values[i])); | |
28661 | + } | |
3a58abaf AM |
28662 | +} |
28663 | + | |
7566401a ER |
28664 | /* The 'function' command. This does nothing -- it is just a |
28665 | placeholder to let "help function NAME" work. This is also used as | |
28666 | the implementation of the sub-command that is created when | |
28667 | @@ -1428,11 +1512,10 @@ preserve_one_value (struct value *value, struct objfile *objfile, | |
28668 | htab_t copied_types) | |
28669 | { | |
28670 | if (TYPE_OBJFILE (value->type) == objfile) | |
28671 | - value->type = copy_type_recursive (objfile, value->type, copied_types); | |
28672 | + value->type = copy_type_recursive (value->type, copied_types); | |
28673 | ||
28674 | if (TYPE_OBJFILE (value->enclosing_type) == objfile) | |
28675 | - value->enclosing_type = copy_type_recursive (objfile, | |
28676 | - value->enclosing_type, | |
28677 | + value->enclosing_type = copy_type_recursive (value->enclosing_type, | |
28678 | copied_types); | |
28679 | } | |
28680 | ||
28681 | @@ -1447,13 +1530,13 @@ preserve_one_internalvar (struct internalvar *var, struct objfile *objfile, | |
28682 | case INTERNALVAR_INTEGER: | |
28683 | if (var->u.integer.type && TYPE_OBJFILE (var->u.integer.type) == objfile) | |
28684 | var->u.integer.type | |
28685 | - = copy_type_recursive (objfile, var->u.integer.type, copied_types); | |
28686 | + = copy_type_recursive (var->u.integer.type, copied_types); | |
28687 | break; | |
28688 | ||
28689 | case INTERNALVAR_POINTER: | |
28690 | if (TYPE_OBJFILE (var->u.pointer.type) == objfile) | |
28691 | var->u.pointer.type | |
28692 | - = copy_type_recursive (objfile, var->u.pointer.type, copied_types); | |
28693 | + = copy_type_recursive (var->u.pointer.type, copied_types); | |
28694 | break; | |
28695 | ||
28696 | case INTERNALVAR_VALUE: | |
28697 | @@ -1855,6 +1938,8 @@ value_change_enclosing_type (struct value *val, struct type *new_encl_type) | |
28698 | val->contents = | |
28699 | (gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type)); | |
28700 | ||
28701 | + type_incref (new_encl_type); | |
28702 | + type_decref (val->enclosing_type); | |
28703 | val->enclosing_type = new_encl_type; | |
28704 | return val; | |
28705 | } | |
28706 | @@ -1919,6 +2004,8 @@ value_primitive_field (struct value *arg1, int offset, | |
28707 | memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1), | |
28708 | TYPE_LENGTH (value_enclosing_type (arg1))); | |
28709 | } | |
28710 | + type_incref (type); | |
28711 | + type_decref (v->type); | |
28712 | v->type = type; | |
28713 | v->offset = value_offset (arg1); | |
28714 | v->embedded_offset = (offset + value_embedded_offset (arg1) | |
28715 | @@ -2177,6 +2264,42 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num) | |
28716 | } | |
28717 | ||
28718 | ||
28719 | +/* Pack NUM into BUF using a target format of TYPE. */ | |
3a58abaf | 28720 | + |
7566401a ER |
28721 | +void |
28722 | +pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num) | |
28723 | +{ | |
28724 | + enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); | |
28725 | + int len; | |
3a58abaf | 28726 | + |
7566401a ER |
28727 | + type = check_typedef (type); |
28728 | + len = TYPE_LENGTH (type); | |
3a58abaf | 28729 | + |
7566401a ER |
28730 | + switch (TYPE_CODE (type)) |
28731 | + { | |
28732 | + case TYPE_CODE_INT: | |
28733 | + case TYPE_CODE_CHAR: | |
28734 | + case TYPE_CODE_ENUM: | |
28735 | + case TYPE_CODE_FLAGS: | |
28736 | + case TYPE_CODE_BOOL: | |
28737 | + case TYPE_CODE_RANGE: | |
28738 | + case TYPE_CODE_MEMBERPTR: | |
28739 | + store_unsigned_integer (buf, len, byte_order, num); | |
28740 | + break; | |
3a58abaf | 28741 | + |
7566401a ER |
28742 | + case TYPE_CODE_REF: |
28743 | + case TYPE_CODE_PTR: | |
28744 | + store_typed_address (buf, type, (CORE_ADDR) num); | |
28745 | + break; | |
3a58abaf | 28746 | + |
7566401a ER |
28747 | + default: |
28748 | + error (_("\ | |
28749 | +Unexpected type (%d) encountered for unsigned integer constant."), | |
28750 | + TYPE_CODE (type)); | |
28751 | + } | |
28752 | +} | |
3a58abaf | 28753 | + |
3a58abaf | 28754 | + |
7566401a ER |
28755 | /* Convert C numbers into newly allocated values. */ |
28756 | ||
28757 | struct value * | |
28758 | @@ -2190,6 +2313,19 @@ value_from_longest (struct type *type, LONGEST num) | |
28759 | } | |
28760 | ||
28761 | ||
28762 | +/* Convert C unsigned numbers into newly allocated values. */ | |
3a58abaf | 28763 | + |
7566401a ER |
28764 | +struct value * |
28765 | +value_from_ulongest (struct type *type, ULONGEST num) | |
28766 | +{ | |
28767 | + struct value *val = allocate_value (type); | |
d566d21e | 28768 | + |
7566401a | 28769 | + pack_unsigned_long (value_contents_raw (val), type, num); |
d566d21e | 28770 | + |
7566401a ER |
28771 | + return val; |
28772 | +} | |
d566d21e | 28773 | + |
d566d21e | 28774 | + |
7566401a ER |
28775 | /* Create a value representing a pointer of type TYPE to the address |
28776 | ADDR. */ | |
28777 | struct value * | |
28778 | @@ -2348,4 +2484,8 @@ VARIABLE is already initialized.")); | |
28779 | add_prefix_cmd ("function", no_class, function_command, _("\ | |
28780 | Placeholder command for showing help on convenience functions."), | |
28781 | &functionlist, "function ", 0, &cmdlist); | |
d566d21e | 28782 | + |
7566401a | 28783 | + make_final_cleanup (value_history_cleanup, NULL); |
d566d21e | 28784 | + |
7566401a ER |
28785 | + observer_attach_mark_used (value_types_mark_used); |
28786 | } | |
28787 | diff --git a/gdb/value.h b/gdb/value.h | |
28788 | index 51e6960..48b30e4 100644 | |
28789 | --- a/gdb/value.h | |
28790 | +++ b/gdb/value.h | |
28791 | @@ -342,11 +342,16 @@ extern LONGEST unpack_field_as_long (struct type *type, | |
28792 | extern void pack_long (gdb_byte *buf, struct type *type, LONGEST num); | |
28793 | ||
28794 | extern struct value *value_from_longest (struct type *type, LONGEST num); | |
28795 | +extern struct value *value_from_ulongest (struct type *type, ULONGEST num); | |
28796 | extern struct value *value_from_pointer (struct type *type, CORE_ADDR addr); | |
28797 | extern struct value *value_from_double (struct type *type, DOUBLEST num); | |
28798 | extern struct value *value_from_decfloat (struct type *type, | |
28799 | const gdb_byte *decbytes); | |
28800 | ||
28801 | +extern const char *object_address_data_not_valid (struct type *type); | |
28802 | +extern int object_address_get_data (struct type *type, | |
28803 | + CORE_ADDR *address_return); | |
d566d21e | 28804 | + |
7566401a ER |
28805 | extern struct value *value_at (struct type *type, CORE_ADDR addr); |
28806 | extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr); | |
28807 | ||
28808 | @@ -436,6 +441,7 @@ extern struct value *value_struct_elt (struct value **argp, | |
28809 | ||
28810 | extern struct value *value_aggregate_elt (struct type *curtype, | |
28811 | char *name, | |
28812 | + struct type *expect_type, | |
28813 | int want_address, | |
28814 | enum noside noside); | |
3a58abaf | 28815 | |
7566401a ER |
28816 | @@ -681,7 +687,7 @@ extern struct value *value_allocate_space_in_inferior (int); |
28817 | extern struct value *value_of_local (const char *name, int complain); | |
3a58abaf | 28818 | |
7566401a ER |
28819 | extern struct value *value_subscripted_rvalue (struct value *array, |
28820 | - LONGEST index, int lowerbound); | |
28821 | + CORE_ADDR offset); | |
3a58abaf | 28822 | |
7566401a | 28823 | /* User function handler. */ |
3a58abaf | 28824 | |
7566401a ER |
28825 | diff --git a/gdb/varobj.c b/gdb/varobj.c |
28826 | index 8f22156..8fe72ca 100644 | |
28827 | --- a/gdb/varobj.c | |
28828 | +++ b/gdb/varobj.c | |
28829 | @@ -26,6 +26,8 @@ | |
28830 | #include "gdbcmd.h" | |
28831 | #include "block.h" | |
28832 | #include "valprint.h" | |
28833 | +#include "objfiles.h" | |
28834 | +#include "parser-defs.h" | |
3a58abaf | 28835 | |
7566401a ER |
28836 | #include "gdb_assert.h" |
28837 | #include "gdb_string.h" | |
28838 | @@ -253,6 +255,8 @@ static void free_variable (struct varobj *var); | |
3a58abaf | 28839 | |
7566401a | 28840 | static struct cleanup *make_cleanup_free_variable (struct varobj *var); |
3a58abaf | 28841 | |
7566401a ER |
28842 | +static struct cleanup *make_cleanup_uninstall_variable (struct varobj *var); |
28843 | + | |
28844 | static struct type *get_type (struct varobj *var); | |
3a58abaf | 28845 | |
7566401a ER |
28846 | static struct type *get_value_type (struct varobj *var); |
28847 | @@ -480,6 +484,8 @@ is_root_p (struct varobj *var) | |
28848 | struct cleanup * | |
28849 | varobj_ensure_python_env (struct varobj *var) | |
28850 | { | |
28851 | + gdb_assert (var->root->is_valid); | |
3a58abaf | 28852 | + |
7566401a ER |
28853 | return ensure_python_env (var->root->exp->gdbarch, |
28854 | var->root->exp->language_defn); | |
28855 | } | |
28856 | @@ -651,6 +657,7 @@ varobj_create (char *objname, | |
28857 | do_cleanups (old_chain); | |
28858 | return NULL; | |
28859 | } | |
28860 | + make_cleanup_uninstall_variable (var); | |
28861 | } | |
3a58abaf | 28862 | |
7566401a ER |
28863 | discard_cleanups (old_chain); |
28864 | @@ -821,7 +828,12 @@ varobj_get_display_hint (struct varobj *var) | |
28865 | char *result = NULL; | |
3a58abaf | 28866 | |
7566401a ER |
28867 | #if HAVE_PYTHON |
28868 | - struct cleanup *back_to = varobj_ensure_python_env (var); | |
28869 | + struct cleanup *back_to; | |
28870 | + | |
28871 | + if (!var->root->is_valid) | |
28872 | + return NULL; | |
28873 | + | |
28874 | + back_to = varobj_ensure_python_env (var); | |
28875 | ||
28876 | if (var->pretty_printer) | |
28877 | result = gdbpy_get_display_hint (var->pretty_printer); | |
28878 | @@ -2186,6 +2198,18 @@ make_cleanup_free_variable (struct varobj *var) | |
28879 | return make_cleanup (do_free_variable_cleanup, var); | |
28880 | } | |
3a58abaf | 28881 | |
7566401a ER |
28882 | +static void |
28883 | +do_uninstall_variable_cleanup (void *var) | |
28884 | +{ | |
28885 | + uninstall_variable (var); | |
28886 | +} | |
28887 | + | |
28888 | +static struct cleanup * | |
28889 | +make_cleanup_uninstall_variable (struct varobj *var) | |
28890 | +{ | |
28891 | + return make_cleanup (do_uninstall_variable_cleanup, var); | |
28892 | +} | |
28893 | + | |
28894 | /* This returns the type of the variable. It also skips past typedefs | |
28895 | to return the real type of the variable. | |
3a58abaf | 28896 | |
7566401a ER |
28897 | @@ -3442,6 +3466,19 @@ java_value_of_variable (struct varobj *var, enum varobj_display_formats format) |
28898 | return cplus_value_of_variable (var, format); | |
28899 | } | |
3a58abaf | 28900 | |
7566401a ER |
28901 | +/* Iterate all the existing VAROBJs and call the FUNC callback for them with an |
28902 | + arbitrary caller supplied DATA pointer. */ | |
28903 | + | |
28904 | +static void | |
28905 | +all_varobjs (void (*func) (struct varobj *var, void *data), void *data) | |
28906 | +{ | |
28907 | + struct vlist **vlp, *vl; | |
28908 | + | |
28909 | + for (vlp = varobj_table; vlp < varobj_table + VAROBJ_TABLE_SIZE; vlp++) | |
28910 | + for (vl = *vlp; vl != NULL; vl = vl->next) | |
28911 | + (*func) (vl->var, data); | |
28912 | +} | |
28913 | + | |
28914 | /* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them | |
28915 | with an arbitrary caller supplied DATA pointer. */ | |
3a58abaf | 28916 | |
7566401a ER |
28917 | @@ -3459,6 +3496,43 @@ all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data) |
28918 | (*func) (var_root->rootvar, data); | |
28919 | } | |
28920 | } | |
28921 | + | |
28922 | +/* Helper for varobj_types_mark_used. Call type_mark_used for any TYPEs | |
28923 | + referenced from this VAR. */ | |
28924 | + | |
28925 | +static void | |
28926 | +varobj_types_mark_used_iter (struct varobj *var, void *unused) | |
28927 | +{ | |
28928 | + /* Even FLOATING or IS_INVALID VARs with non-NULL TYPE references will | |
28929 | + free them in free_variable. Still EXP may also reference TYPEs | |
28930 | + but these belong to SYMBOLs which should be always associated with | |
28931 | + an OBJFILE (and therefore not useful to be type_mark_used). */ | |
28932 | + | |
28933 | + type_mark_used (var->type); | |
28934 | + if (var->value) | |
28935 | + type_mark_used (value_type (var->value)); | |
28936 | + | |
28937 | + /* Check VAROBJROOTs only once during the varobj_types_mark_used pass. */ | |
28938 | + | |
28939 | + if (var->root->rootvar == var) | |
28940 | + { | |
28941 | + if (var->root->exp) | |
28942 | + exp_types_mark_used (var->root->exp); | |
28943 | + } | |
28944 | +} | |
3a58abaf | 28945 | + |
7566401a | 28946 | +/* Call type_mark_used for any TYPEs referenced from this GDB source file. */ |
3a58abaf | 28947 | + |
7566401a ER |
28948 | +static void |
28949 | +varobj_types_mark_used (void) | |
28950 | +{ | |
28951 | + /* Check all the VAROBJs, even non-root ones. Child VAROBJs can reference | |
28952 | + types from other OBJFILEs through TYPE_IS_OPAQUE resolutions by | |
28953 | + check_typedef. Such types references will not be interconnected into the | |
28954 | + same TYPE_GROUP. */ | |
28955 | + | |
28956 | + all_varobjs (varobj_types_mark_used_iter, NULL); | |
28957 | +} | |
28958 | \f | |
28959 | extern void _initialize_varobj (void); | |
28960 | void | |
28961 | diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c | |
28962 | index c56ab86..dacf913 100644 | |
28963 | --- a/gdb/xcoffread.c | |
28964 | +++ b/gdb/xcoffread.c | |
28965 | @@ -3038,6 +3038,7 @@ static struct sym_fns xcoff_sym_fns = | |
28966 | xcoff_new_init, /* sym_new_init: init anything gbl to entire symtab */ | |
28967 | xcoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
28968 | xcoff_initial_scan, /* sym_read: read a symbol file into symtab */ | |
28969 | + NULL, /* sym_read_psymbols */ | |
28970 | xcoff_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
28971 | xcoff_symfile_offsets, /* sym_offsets: xlate offsets ext->int form */ | |
28972 | default_symfile_segments, /* sym_segments: Get segment information from |