]>
Commit | Line | Data |
---|---|---|
3a58abaf AM |
1 | http://sourceware.org/gdb/wiki/ProjectArcher |
2 | http://sourceware.org/gdb/wiki/ArcherBranchManagement | |
3 | ||
4 | GIT snapshot: | |
5 | commit a99e30d08ade4a2df0f943b036cd653bcd12b04d | |
6 | ||
7 | branch `archer' - the merge of branches: | |
8 | archer-jankratochvil-merge-expr | |
9 | archer-keiths-expr-cumulative | |
10 | (archer-swagiaal-using-directive) | |
11 | archer-jankratochvil-misc | |
12 | archer-jankratochvil-python | |
13 | archer-jankratochvil-type-refcount | |
14 | archer-tromey-python | |
15 | archer-jankratochvil-vla | |
16 | archer-jankratochvil-type-refcount | |
17 | archer-pmuldoon-exception-rewind-master | |
18 | archer-sergio-catch-syscall | |
19 | archer-tromey-charset | |
20 | archer-tromey-delayed-symfile | |
21 | ||
22 | ||
23 | diff --git a/gdb/Makefile.in b/gdb/Makefile.in | |
24 | index 74aa72e..c84a4ac 100644 | |
25 | --- a/gdb/Makefile.in | |
26 | +++ b/gdb/Makefile.in | |
27 | @@ -167,11 +167,20 @@ INTL_CFLAGS = @INCINTL@ | |
28 | ||
29 | # Where is the ICONV library? This can be empty if libc has iconv. | |
30 | LIBICONV = @LIBICONV@ | |
31 | +LIBICONV_INCLUDE = @LIBICONV_INCLUDE@ | |
32 | +LIBICONV_LIBDIR = @LIBICONV_LIBDIR@ | |
33 | ||
34 | # Did the user give us a --with-sysroot option? | |
35 | TARGET_SYSTEM_ROOT = @TARGET_SYSTEM_ROOT@ | |
36 | TARGET_SYSTEM_ROOT_DEFINE = @TARGET_SYSTEM_ROOT_DEFINE@ | |
37 | ||
38 | +# Did the user give us a --with-gdb-datadir option? | |
39 | +GDB_DATADIR_PATH = @GDB_DATADIR_PATH@ | |
40 | + | |
41 | +# The argument to --with-pythondir. If not given, this is | |
42 | +# GDB_DATADIR_PATH/python. | |
43 | +pythondir = @pythondir@ | |
44 | + | |
45 | # Helper code from gnulib. | |
46 | LIBGNU = gnulib/libgnu.a | |
47 | INCGNU = -I$(srcdir)/gnulib -Ignulib | |
48 | @@ -270,12 +279,34 @@ SUBDIR_TUI_CFLAGS= \ | |
49 | # | |
50 | SUBDIR_PYTHON_OBS = \ | |
51 | python.o \ | |
52 | + python-block.o \ | |
53 | + python-breakpoint.o \ | |
54 | python-cmd.o \ | |
55 | + python-frame.o \ | |
56 | + python-function.o \ | |
57 | + python-hooks.o \ | |
58 | + python-membuf.o \ | |
59 | + python-objfile.o \ | |
60 | + python-param.o \ | |
61 | + python-symbol.o \ | |
62 | + python-symtab.o \ | |
63 | + python-type.o \ | |
64 | python-utils.o \ | |
65 | python-value.o | |
66 | SUBDIR_PYTHON_SRCS = \ | |
67 | python/python.c \ | |
68 | + python/python-block.c \ | |
69 | + python/python-breakpoint.c \ | |
70 | python/python-cmd.c \ | |
71 | + python/python-frame.c \ | |
72 | + python/python-function.c \ | |
73 | + python/python-hooks.c \ | |
74 | + python/python-membuf.c \ | |
75 | + python/python-objfile.c \ | |
76 | + python/python-param.c \ | |
77 | + python/python-symbol.c \ | |
78 | + python/python-symtab.c \ | |
79 | + python/python-type.c \ | |
80 | python/python-utils.c \ | |
81 | python/python-value.c | |
82 | SUBDIR_PYTHON_DEPS = | |
83 | @@ -390,7 +421,8 @@ INTERNAL_CFLAGS_BASE = \ | |
84 | $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \ | |
85 | $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) \ | |
86 | $(BFD_CFLAGS) $(INCLUDE_CFLAGS) $(LIBDECNUMBER_CFLAGS) \ | |
87 | - $(INTL_CFLAGS) $(INCGNU) $(ENABLE_CFLAGS) $(INTERNAL_CPPFLAGS) | |
88 | + $(INTL_CFLAGS) $(INCGNU) $(ENABLE_CFLAGS) $(INTERNAL_CPPFLAGS) \ | |
89 | + $(LIBICONV_INCLUDE) | |
90 | INTERNAL_WARN_CFLAGS = $(INTERNAL_CFLAGS_BASE) $(GDB_WARN_CFLAGS) | |
91 | INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS) | |
92 | ||
93 | @@ -402,7 +434,7 @@ LDFLAGS = @LDFLAGS@ | |
94 | # I think it's perfectly reasonable for a user to set -pg in CFLAGS | |
95 | # and have it work; that's why CFLAGS is here. | |
96 | # PROFILE_CFLAGS is _not_ included, however, because we use monstartup. | |
97 | -INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(MH_LDFLAGS) $(LDFLAGS) $(CONFIG_LDFLAGS) | |
98 | +INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(MH_LDFLAGS) $(LDFLAGS) $(CONFIG_LDFLAGS) $(LIBICONV_LIBDIR) | |
99 | ||
100 | # If your system is missing alloca(), or, more likely, it's there but | |
101 | # it doesn't work, then refer to libiberty. | |
102 | @@ -663,6 +695,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ | |
103 | valarith.c valops.c valprint.c value.c varobj.c vec.c \ | |
104 | wrapper.c \ | |
105 | xml-tdesc.c xml-support.c \ | |
106 | + xml-syscall.c \ | |
107 | inferior.c | |
108 | ||
109 | LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c | |
110 | @@ -733,7 +766,8 @@ config/sparc/nm-sol2.h config/nm-linux.h config/mips/nm-irix5.h \ | |
111 | config/rs6000/nm-rs6000.h top.h bsd-kvm.h gdb-stabs.h reggroups.h \ | |
112 | annotate.h sim-regno.h dictionary.h dfp.h main.h frame-unwind.h \ | |
113 | remote-fileio.h i386-linux-tdep.h vax-tdep.h objc-lang.h \ | |
114 | -sentinel-frame.h bcache.h symfile.h windows-tdep.h linux-tdep.h | |
115 | +sentinel-frame.h bcache.h symfile.h windows-tdep.h linux-tdep.h xml-syscall.h \ | |
116 | +python/python.h python/python-internal.h | |
117 | ||
118 | # Header files that already have srcdir in them, or which are in objdir. | |
119 | ||
120 | @@ -812,10 +846,16 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ | |
121 | trad-frame.o \ | |
122 | tramp-frame.o \ | |
123 | solib.o solib-null.o \ | |
124 | - prologue-value.o memory-map.o xml-support.o \ | |
125 | + prologue-value.o memory-map.o xml-support.o xml-syscall.o \ | |
126 | target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \ | |
127 | inferior.o osdata.o | |
128 | ||
129 | +# Definitions for the syscall's XML files and dir | |
130 | +XML_SYSCALLS_DIR = syscalls/ | |
131 | +XML_SYSCALLS_FILES = gdb-syscalls.dtd \ | |
132 | + ppc-linux.xml ppc64-linux.xml \ | |
133 | + i386-linux.xml amd64-linux.xml | |
134 | + | |
135 | TSOBS = inflow.o | |
136 | ||
137 | SUBDIRS = @subdirs@ | |
138 | @@ -849,11 +889,38 @@ generated_files = config.h observer.h observer.inc ada-lex.c \ | |
139 | $(COMPILE) $< | |
140 | $(POSTCOMPILE) | |
141 | ||
142 | -all: gdb$(EXEEXT) $(CONFIG_ALL) | |
143 | +all: gdb$(EXEEXT) $(CONFIG_ALL) .gdbinit xml-syscall-copy | |
144 | @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do | |
145 | .PHONY: all-tui | |
146 | all-tui: $(TUI)$(EXEEXT) | |
147 | ||
148 | +xml-syscall-copy: | |
149 | + if [ "`cd $(srcdir) && pwd`" != "`pwd`" ] ; then \ | |
150 | + mkdir -p ./$(XML_SYSCALLS_DIR) ; \ | |
151 | + list='$(XML_SYSCALLS_FILES)' ; \ | |
152 | + for file in $$list ; do \ | |
153 | + f=$(srcdir)/$(XML_SYSCALLS_DIR)/$$file ; \ | |
154 | + if test -f $$f ; then \ | |
155 | + $(INSTALL_DATA) $$f \ | |
156 | + ./$(XML_SYSCALLS_DIR) ; \ | |
157 | + fi ; \ | |
158 | + done ; \ | |
159 | + fi ; | |
160 | + | |
161 | +# This target is responsible for properly installing the syscalls' | |
162 | +# XML files in the system. | |
163 | +xml-syscall-install: | |
164 | + $(SHELL) $(srcdir)/../mkinstalldirs \ | |
165 | + $(DESTDIR)$(GDB_DATADIR_PATH)/$(XML_SYSCALLS_DIR) ; \ | |
166 | + list='$(XML_SYSCALLS_FILES)' ; \ | |
167 | + for file in $$list ; do \ | |
168 | + f=$(srcdir)/$(XML_SYSCALLS_DIR)/$$file ; \ | |
169 | + if test -f $$f ; then \ | |
170 | + $(INSTALL_DATA) $$f \ | |
171 | + $(DESTDIR)$(GDB_DATADIR_PATH)/$(XML_SYSCALLS_DIR) ; \ | |
172 | + fi ; \ | |
173 | + done ; | |
174 | + | |
175 | installcheck: | |
176 | ||
177 | # The check target can not use subdir_do, because subdir_do does not | |
178 | @@ -907,8 +974,11 @@ gdb.z:gdb.1 | |
179 | # source file and doesn't care about rebuilding or just wants to save the | |
180 | # time it takes for make to check that all is up to date. | |
181 | # install-only is intended to address that need. | |
182 | -install: all install-only | |
183 | -install-only: $(CONFIG_INSTALL) | |
184 | +install: all install-only | |
185 | + | |
186 | +# The "install-only" target also installs the syscalls' XML files in | |
187 | +# the system. | |
188 | +install-only: $(CONFIG_INSTALL) xml-syscall-install | |
189 | transformed_name=`t='$(program_transform_name)'; \ | |
190 | echo gdb | sed -e "$$t"` ; \ | |
191 | if test "x$$transformed_name" = x; then \ | |
192 | @@ -1202,6 +1272,12 @@ stamp-h: config.in config.status | |
193 | CONFIG_LINKS= \ | |
194 | $(SHELL) config.status | |
195 | ||
196 | +.gdbinit: gdbinit.in config.status | |
197 | + CONFIG_FILES=".gdbinit:gdbinit.in" \ | |
198 | + CONFIG_COMMANDS= \ | |
199 | + CONFIG_HEADERS= \ | |
200 | + $(SHELL) config.status | |
201 | + | |
202 | config.status: configure configure.tgt configure.host | |
203 | $(SHELL) config.status --recheck | |
204 | ||
205 | @@ -1845,10 +1921,54 @@ python.o: $(srcdir)/python/python.c | |
206 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c | |
207 | $(POSTCOMPILE) | |
208 | ||
209 | +python-block.o: $(srcdir)/python/python-block.c | |
210 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-block.c | |
211 | + $(POSTCOMPILE) | |
212 | + | |
213 | +python-breakpoint.o: $(srcdir)/python/python-breakpoint.c | |
214 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-breakpoint.c | |
215 | + $(POSTCOMPILE) | |
216 | + | |
217 | python-cmd.o: $(srcdir)/python/python-cmd.c | |
218 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-cmd.c | |
219 | $(POSTCOMPILE) | |
220 | ||
221 | +python-frame.o: $(srcdir)/python/python-frame.c | |
222 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-frame.c | |
223 | + $(POSTCOMPILE) | |
224 | + | |
225 | +python-function.o: $(srcdir)/python/python-function.c | |
226 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-function.c | |
227 | + $(POSTCOMPILE) | |
228 | + | |
229 | +python-hooks.o: $(srcdir)/python/python-hooks.c | |
230 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-hooks.c | |
231 | + $(POSTCOMPILE) | |
232 | + | |
233 | +python-membuf.o: $(srcdir)/python/python-membuf.c | |
234 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-membuf.c | |
235 | + $(POSTCOMPILE) | |
236 | + | |
237 | +python-objfile.o: $(srcdir)/python/python-objfile.c | |
238 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-objfile.c | |
239 | + $(POSTCOMPILE) | |
240 | + | |
241 | +python-param.o: $(srcdir)/python/python-param.c | |
242 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-param.c | |
243 | + $(POSTCOMPILE) | |
244 | + | |
245 | +python-symbol.o: $(srcdir)/python/python-symbol.c | |
246 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-symbol.c | |
247 | + $(POSTCOMPILE) | |
248 | + | |
249 | +python-symtab.o: $(srcdir)/python/python-symtab.c | |
250 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-symtab.c | |
251 | + $(POSTCOMPILE) | |
252 | + | |
253 | +python-type.o: $(srcdir)/python/python-type.c | |
254 | + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-type.c | |
255 | + $(POSTCOMPILE) | |
256 | + | |
257 | python-utils.o: $(srcdir)/python/python-utils.c | |
258 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-utils.c | |
259 | $(POSTCOMPILE) | |
260 | @@ -1857,6 +1977,38 @@ python-value.o: $(srcdir)/python/python-value.c | |
261 | $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-value.c | |
262 | $(POSTCOMPILE) | |
263 | ||
264 | +# All python library files, with the "python/lib" stripped off. | |
265 | +# Note that we should only install files in the "gdb" module. | |
266 | +PY_FILES = gdb/FrameIterator.py gdb/command/alias.py \ | |
267 | + gdb/command/backtrace.py gdb/command/require.py \ | |
268 | + gdb/command/pahole.py gdb/command/__init__.py \ | |
269 | + gdb/command/ignore_errors.py gdb/command/save_breakpoints.py \ | |
270 | + gdb/libstdcxx/v6/printers.py gdb/libstdcxx/v6/__init__.py \ | |
271 | + gdb/libstdcxx/__init__.py gdb/function/caller_is.py \ | |
272 | + gdb/function/in_scope.py gdb/function/__init__.py gdb/backtrace.py \ | |
273 | + gdb/__init__.py | |
274 | + | |
275 | +# Install the Python library. Python library files go under | |
276 | +# $(pythondir). | |
277 | +install-python: | |
278 | + files='$(PY_FILES)'; for file in $$files; do \ | |
279 | + dir=`echo "$$file" | sed 's,/[^/]*$$,,'`; \ | |
280 | + $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(pythondir)/$$dir; \ | |
281 | + $(INSTALL_DATA) $(srcdir)/python/lib/$$file $(DESTDIR)$(pythondir)/$$file; \ | |
282 | + done | |
283 | + | |
284 | +# Other packages may have their files installed in $(pythondir). | |
285 | +uninstall-python: | |
286 | + files='$(PY_FILES)'; for file in $$files; do \ | |
287 | + slashdir=`echo "/$$file" | sed 's,/[^/]*$$,,'`; \ | |
288 | + rm -f $(DESTDIR)$(pythondir)/$$file; \ | |
289 | + while test "x$$file" != "x$$slashdir"; do \ | |
290 | + rmdir 2>/dev/null "$(DESTDIR)$(pythondir)$$slashdir"; \ | |
291 | + file="$$slashdir"; \ | |
292 | + slashdir=`echo "$$file" | sed 's,/[^/]*$$,,'`; \ | |
293 | + done \ | |
294 | + done | |
295 | + | |
296 | # | |
297 | # Dependency tracking. Most of this is conditional on GNU Make being | |
298 | # found by configure; if GNU Make is not found, we fall back to a | |
299 | diff --git a/gdb/NEWS b/gdb/NEWS | |
300 | index 9078412..3f084e7 100644 | |
301 | --- a/gdb/NEWS | |
302 | +++ b/gdb/NEWS | |
303 | @@ -3,6 +3,13 @@ | |
304 | ||
305 | *** Changes since GDB 6.8 | |
306 | ||
307 | +* GDB now has support for multi-byte and wide character sets on the | |
308 | +target. Strings whose character type is wchar_t, char16_t, or | |
309 | +char32_t are now correctly printed. GDB supports wide- and unicode- | |
310 | +literals in C, that is, L'x', L"string", u'x', u"string", U'x', and | |
311 | +U"string" syntax. And, GDB allows the "%ls" and "%lc" formats in | |
312 | +`printf'. | |
313 | + | |
314 | * GDB now supports automatic retrieval of shared library files from | |
315 | remote targets. To use this feature, specify a system root that begins | |
316 | with the `remote:' prefix, either via the `set sysroot' command or via | |
317 | @@ -182,6 +189,11 @@ set target-async | |
318 | with GDB while the target is running. "show target-async" displays the | |
319 | current state of asynchronous execution of the target. | |
320 | ||
321 | +set target-wide-charset | |
322 | +show target-wide-charset | |
323 | + The target-wide-charset is the name of the character set that GDB | |
324 | + uses when printing characters whose type is wchar_t. | |
325 | + | |
326 | set tcp auto-retry (on|off) | |
327 | show tcp auto-retry | |
328 | set tcp connect-timeout | |
329 | diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4 | |
330 | index 81b5d47..c2bd043 100644 | |
331 | --- a/gdb/acinclude.m4 | |
332 | +++ b/gdb/acinclude.m4 | |
333 | @@ -29,6 +29,9 @@ sinclude([../config/depstand.m4]) | |
334 | dnl For AM_LC_MESSAGES | |
335 | sinclude([../config/lcmessage.m4]) | |
336 | ||
337 | +dnl For AM_LANGINFO_CODESET. | |
338 | +sinclude([../config/codeset.m4]) | |
339 | + | |
340 | # | |
341 | # Sometimes the native compiler is a bogus stub for gcc or /usr/ucb/cc. This | |
342 | # makes configure think it's cross compiling. If --target wasn't used, then | |
343 | @@ -174,8 +177,8 @@ AC_DEFUN([AM_ICONV], | |
344 | AC_ARG_WITH([libiconv-prefix], | |
345 | [ --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib], [ | |
346 | for dir in `echo "$withval" | tr : ' '`; do | |
347 | - if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi | |
348 | - if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi | |
349 | + if test -d $dir/include; then LIBICONV_INCLUDE="-I$dir/include"; CPPFLAGS="$CPPFLAGS -I$dir/include"; fi | |
350 | + if test -d $dir/lib; then LIBICONV_LIBDIR="-L$dir/lib"; LDFLAGS="$LDFLAGS -L$dir/lib"; fi | |
351 | done | |
352 | ]) | |
353 | ||
354 | @@ -230,6 +233,8 @@ size_t iconv(); | |
355 | LIBICONV="-liconv" | |
356 | fi | |
357 | AC_SUBST(LIBICONV) | |
358 | + AC_SUBST(LIBICONV_INCLUDE) | |
359 | + AC_SUBST(LIBICONV_LIBDIR) | |
360 | ]) | |
361 | ||
362 | dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva | |
363 | diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c | |
364 | index 671cb35..edcee3f 100644 | |
365 | --- a/gdb/ada-lang.c | |
366 | +++ b/gdb/ada-lang.c | |
367 | @@ -486,7 +486,7 @@ coerce_unspec_val_to_type (struct value *val, struct type *type) | |
368 | set_value_component_location (result, val); | |
369 | set_value_bitsize (result, value_bitsize (val)); | |
370 | set_value_bitpos (result, value_bitpos (val)); | |
371 | - VALUE_ADDRESS (result) += value_offset (val); | |
372 | + set_value_address (result, value_address (val)); | |
373 | if (value_lazy (val) | |
374 | || TYPE_LENGTH (type) > TYPE_LENGTH (value_type (val))) | |
375 | set_value_lazy (result, 1); | |
376 | @@ -1328,7 +1328,7 @@ thin_data_pntr (struct value *val) | |
377 | value_copy (val)); | |
378 | else | |
379 | return value_from_longest (desc_data_type (thin_descriptor_type (type)), | |
380 | - VALUE_ADDRESS (val) + value_offset (val)); | |
381 | + value_address (val)); | |
382 | } | |
383 | ||
384 | /* True iff TYPE indicates a "thick" array pointer type. */ | |
385 | @@ -1393,7 +1393,7 @@ desc_bounds (struct value *arr) | |
386 | if (TYPE_CODE (type) == TYPE_CODE_PTR) | |
387 | addr = value_as_long (arr); | |
388 | else | |
389 | - addr = VALUE_ADDRESS (arr) + value_offset (arr); | |
390 | + addr = value_address (arr); | |
391 | ||
392 | return | |
393 | value_from_longest (lookup_pointer_type (bounds_type), | |
394 | @@ -1666,8 +1666,8 @@ ada_type_of_array (struct value *arr, int bounds) | |
395 | return NULL; | |
396 | while (arity > 0) | |
397 | { | |
398 | - struct type *range_type = alloc_type (objf); | |
399 | - struct type *array_type = alloc_type (objf); | |
400 | + struct type *range_type = alloc_type (objf, NULL); | |
401 | + struct type *array_type = alloc_type (objf, NULL); | |
402 | struct value *low = desc_one_bound (descriptor, arity, 0); | |
403 | struct value *high = desc_one_bound (descriptor, arity, 1); | |
404 | arity -= 1; | |
405 | @@ -1774,9 +1774,9 @@ packed_array_type (struct type *type, long *elt_bits) | |
406 | if (TYPE_CODE (type) != TYPE_CODE_ARRAY) | |
407 | return type; | |
408 | ||
409 | - new_type = alloc_type (TYPE_OBJFILE (type)); | |
410 | new_elt_type = packed_array_type (ada_check_typedef (TYPE_TARGET_TYPE (type)), | |
411 | elt_bits); | |
412 | + new_type = alloc_type (TYPE_OBJFILE (type), new_elt_type); | |
413 | create_array_type (new_type, new_elt_type, TYPE_INDEX_TYPE (type)); | |
414 | TYPE_FIELD_BITSIZE (new_type, 0) = *elt_bits; | |
415 | TYPE_NAME (new_type) = ada_type_name (type); | |
416 | @@ -1831,6 +1831,7 @@ decode_packed_array_type (struct type *type) | |
417 | return NULL; | |
418 | } | |
419 | shadow_type = SYMBOL_TYPE (sym); | |
420 | + CHECK_TYPEDEF (shadow_type); | |
421 | ||
422 | if (TYPE_CODE (shadow_type) != TYPE_CODE_ARRAY) | |
423 | { | |
424 | @@ -2005,10 +2006,9 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr, | |
425 | } | |
426 | else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj)) | |
427 | { | |
428 | - v = value_at (type, | |
429 | - VALUE_ADDRESS (obj) + value_offset (obj) + offset); | |
430 | + v = value_at (type, value_address (obj) + offset); | |
431 | bytes = (unsigned char *) alloca (len); | |
432 | - read_memory (VALUE_ADDRESS (v), bytes, len); | |
433 | + read_memory (value_address (v), bytes, len); | |
434 | } | |
435 | else | |
436 | { | |
437 | @@ -2018,15 +2018,18 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr, | |
438 | ||
439 | if (obj != NULL) | |
440 | { | |
441 | + CORE_ADDR new_addr; | |
442 | + | |
443 | set_value_component_location (v, obj); | |
444 | - VALUE_ADDRESS (v) += value_offset (obj) + offset; | |
445 | + new_addr = value_address (obj) + offset; | |
446 | set_value_bitpos (v, bit_offset + value_bitpos (obj)); | |
447 | set_value_bitsize (v, bit_size); | |
448 | if (value_bitpos (v) >= HOST_CHAR_BIT) | |
449 | { | |
450 | - VALUE_ADDRESS (v) += 1; | |
451 | + new_addr++; | |
452 | set_value_bitpos (v, value_bitpos (v) - HOST_CHAR_BIT); | |
453 | } | |
454 | + set_value_address (v, new_addr); | |
455 | } | |
456 | else | |
457 | set_value_bitsize (v, bit_size); | |
458 | @@ -2218,7 +2221,7 @@ ada_value_assign (struct value *toval, struct value *fromval) | |
459 | int from_size; | |
460 | char *buffer = (char *) alloca (len); | |
461 | struct value *val; | |
462 | - CORE_ADDR to_addr = VALUE_ADDRESS (toval) + value_offset (toval); | |
463 | + CORE_ADDR to_addr = value_address (toval); | |
464 | ||
465 | if (TYPE_CODE (type) == TYPE_CODE_FLT) | |
466 | fromval = value_cast (type, fromval); | |
467 | @@ -2259,8 +2262,7 @@ value_assign_to_component (struct value *container, struct value *component, | |
468 | struct value *val) | |
469 | { | |
470 | LONGEST offset_in_container = | |
471 | - (LONGEST) (VALUE_ADDRESS (component) + value_offset (component) | |
472 | - - VALUE_ADDRESS (container) - value_offset (container)); | |
473 | + (LONGEST) (value_address (component) - value_address (container)); | |
474 | int bit_offset_in_container = | |
475 | value_bitpos (component) - value_bitpos (container); | |
476 | int bits; | |
477 | @@ -3788,7 +3790,7 @@ parse_old_style_renaming (struct type *type, | |
478 | /* Return an lvalue containing the value VAL. This is the identity on | |
479 | lvalues, and otherwise has the side-effect of pushing a copy of VAL | |
480 | on the stack, using and updating *SP as the stack pointer, and | |
481 | - returning an lvalue whose VALUE_ADDRESS points to the copy. */ | |
482 | + returning an lvalue whose value_address points to the copy. */ | |
483 | ||
484 | static struct value * | |
485 | ensure_lval (struct value *val, CORE_ADDR *sp) | |
486 | @@ -3802,12 +3804,12 @@ ensure_lval (struct value *val, CORE_ADDR *sp) | |
487 | indicated. */ | |
488 | if (gdbarch_inner_than (current_gdbarch, 1, 2)) | |
489 | { | |
490 | - /* Stack grows downward. Align SP and VALUE_ADDRESS (val) after | |
491 | + /* Stack grows downward. Align SP and value_address (val) after | |
492 | reserving sufficient space. */ | |
493 | *sp -= len; | |
494 | if (gdbarch_frame_align_p (current_gdbarch)) | |
495 | *sp = gdbarch_frame_align (current_gdbarch, *sp); | |
496 | - VALUE_ADDRESS (val) = *sp; | |
497 | + set_value_address (val, *sp); | |
498 | } | |
499 | else | |
500 | { | |
501 | @@ -3815,14 +3817,14 @@ ensure_lval (struct value *val, CORE_ADDR *sp) | |
502 | then again, re-align the frame. */ | |
503 | if (gdbarch_frame_align_p (current_gdbarch)) | |
504 | *sp = gdbarch_frame_align (current_gdbarch, *sp); | |
505 | - VALUE_ADDRESS (val) = *sp; | |
506 | + set_value_address (val, *sp); | |
507 | *sp += len; | |
508 | if (gdbarch_frame_align_p (current_gdbarch)) | |
509 | *sp = gdbarch_frame_align (current_gdbarch, *sp); | |
510 | } | |
511 | VALUE_LVAL (val) = lval_memory; | |
512 | ||
513 | - write_memory (VALUE_ADDRESS (val), value_contents_raw (val), len); | |
514 | + write_memory (value_address (val), value_contents_raw (val), len); | |
515 | } | |
516 | ||
517 | return val; | |
518 | @@ -3911,12 +3913,12 @@ make_array_descriptor (struct type *type, struct value *arr, CORE_ADDR *sp) | |
519 | bounds = ensure_lval (bounds, sp); | |
520 | ||
521 | modify_general_field (value_contents_writeable (descriptor), | |
522 | - VALUE_ADDRESS (ensure_lval (arr, sp)), | |
523 | + value_address (ensure_lval (arr, sp)), | |
524 | fat_pntr_data_bitpos (desc_type), | |
525 | fat_pntr_data_bitsize (desc_type)); | |
526 | ||
527 | modify_general_field (value_contents_writeable (descriptor), | |
528 | - VALUE_ADDRESS (bounds), | |
529 | + value_address (bounds), | |
530 | fat_pntr_bounds_bitpos (desc_type), | |
531 | fat_pntr_bounds_bitsize (desc_type)); | |
532 | ||
533 | @@ -6790,7 +6792,7 @@ variant_field_index (struct type *type) | |
534 | static struct type * | |
535 | empty_record (struct objfile *objfile) | |
536 | { | |
537 | - struct type *type = alloc_type (objfile); | |
538 | + struct type *type = alloc_type (objfile, NULL); | |
539 | TYPE_CODE (type) = TYPE_CODE_STRUCT; | |
540 | TYPE_NFIELDS (type) = 0; | |
541 | TYPE_FIELDS (type) = NULL; | |
542 | @@ -6847,7 +6849,7 @@ ada_template_to_fixed_record_type_1 (struct type *type, | |
543 | nfields++; | |
544 | } | |
545 | ||
546 | - rtype = alloc_type (TYPE_OBJFILE (type)); | |
547 | + rtype = alloc_type (TYPE_OBJFILE (type), NULL); | |
548 | TYPE_CODE (rtype) = TYPE_CODE_STRUCT; | |
549 | INIT_CPLUS_SPECIFIC (rtype); | |
550 | TYPE_NFIELDS (rtype) = nfields; | |
551 | @@ -7034,7 +7036,8 @@ template_to_static_fixed_type (struct type *type0) | |
552 | new_type = static_unwrap_type (field_type); | |
553 | if (type == type0 && new_type != field_type) | |
554 | { | |
555 | - TYPE_TARGET_TYPE (type0) = type = alloc_type (TYPE_OBJFILE (type0)); | |
556 | + TYPE_TARGET_TYPE (type0) = type = alloc_type (TYPE_OBJFILE (type0), | |
557 | + NULL); | |
558 | TYPE_CODE (type) = TYPE_CODE (type0); | |
559 | INIT_CPLUS_SPECIFIC (type); | |
560 | TYPE_NFIELDS (type) = nfields; | |
561 | @@ -7079,7 +7082,7 @@ to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr, | |
562 | else | |
563 | dval = dval0; | |
564 | ||
565 | - rtype = alloc_type (TYPE_OBJFILE (type)); | |
566 | + rtype = alloc_type (TYPE_OBJFILE (type), NULL); | |
567 | TYPE_CODE (rtype) = TYPE_CODE_STRUCT; | |
568 | INIT_CPLUS_SPECIFIC (rtype); | |
569 | TYPE_NFIELDS (rtype) = nfields; | |
570 | @@ -7251,7 +7254,7 @@ to_fixed_array_type (struct type *type0, struct value *dval, | |
571 | if (elt_type0 == elt_type) | |
572 | result = type0; | |
573 | else | |
574 | - result = create_array_type (alloc_type (TYPE_OBJFILE (type0)), | |
575 | + result = create_array_type (alloc_type (TYPE_OBJFILE (type0), NULL), | |
576 | elt_type, TYPE_INDEX_TYPE (type0)); | |
577 | } | |
578 | else | |
579 | @@ -7281,7 +7284,7 @@ to_fixed_array_type (struct type *type0, struct value *dval, | |
580 | struct type *range_type = | |
581 | to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, i), | |
582 | dval, TYPE_OBJFILE (type0)); | |
583 | - result = create_array_type (alloc_type (TYPE_OBJFILE (type0)), | |
584 | + result = create_array_type (alloc_type (TYPE_OBJFILE (type0), NULL), | |
585 | result, range_type); | |
586 | } | |
587 | if (!ignore_too_big && TYPE_LENGTH (result) > varsize_limit) | |
588 | @@ -7523,7 +7526,7 @@ static struct value * | |
589 | ada_to_fixed_value (struct value *val) | |
590 | { | |
591 | return ada_to_fixed_value_create (value_type (val), | |
592 | - VALUE_ADDRESS (val) + value_offset (val), | |
593 | + value_address (val), | |
594 | val); | |
595 | } | |
596 | ||
597 | @@ -7869,7 +7872,7 @@ unwrap_value (struct value *val) | |
598 | return | |
599 | coerce_unspec_val_to_type | |
600 | (val, ada_to_fixed_type (raw_real_type, 0, | |
601 | - VALUE_ADDRESS (val) + value_offset (val), | |
602 | + value_address (val), | |
603 | NULL, 1)); | |
604 | } | |
605 | } | |
606 | @@ -9546,7 +9549,7 @@ to_fixed_range_type (char *name, struct value *dval, struct objfile *objfile) | |
607 | if (L < INT_MIN || U > INT_MAX) | |
608 | return raw_type; | |
609 | else | |
610 | - return create_range_type (alloc_type (objfile), raw_type, | |
611 | + return create_range_type (alloc_type (objfile, NULL), raw_type, | |
612 | discrete_type_low_bound (raw_type), | |
613 | discrete_type_high_bound (raw_type)); | |
614 | } | |
615 | @@ -9611,7 +9614,7 @@ to_fixed_range_type (char *name, struct value *dval, struct objfile *objfile) | |
616 | ||
617 | if (objfile == NULL) | |
618 | objfile = TYPE_OBJFILE (base_type); | |
619 | - type = create_range_type (alloc_type (objfile), base_type, L, U); | |
620 | + type = create_range_type (alloc_type (objfile, NULL), base_type, L, U); | |
621 | TYPE_NAME (type) = name; | |
622 | return type; | |
623 | } | |
624 | @@ -11009,9 +11012,9 @@ ada_language_arch_info (struct gdbarch *gdbarch, | |
625 | /* Not really used, but needed in the ada_language_defn. */ | |
626 | ||
627 | static void | |
628 | -emit_char (int c, struct ui_file *stream, int quoter) | |
629 | +emit_char (int c, struct type *type, struct ui_file *stream, int quoter) | |
630 | { | |
631 | - ada_emit_char (c, stream, quoter, 1); | |
632 | + ada_emit_char (c, type, stream, quoter, 1); | |
633 | } | |
634 | ||
635 | static int | |
636 | diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h | |
637 | index c7cc62a..fac027b 100644 | |
638 | --- a/gdb/ada-lang.h | |
639 | +++ b/gdb/ada-lang.h | |
640 | @@ -257,12 +257,12 @@ extern int ada_value_print (struct value *, struct ui_file *, | |
641 | ||
642 | /* Defined in ada-lang.c */ | |
643 | ||
644 | -extern void ada_emit_char (int, struct ui_file *, int, int); | |
645 | +extern void ada_emit_char (int, struct type *, struct ui_file *, int, int); | |
646 | ||
647 | -extern void ada_printchar (int, struct ui_file *); | |
648 | +extern void ada_printchar (int, struct type *, struct ui_file *); | |
649 | ||
650 | -extern void ada_printstr (struct ui_file *, const gdb_byte *, | |
651 | - unsigned int, int, int, | |
652 | +extern void ada_printstr (struct ui_file *, struct type *, const gdb_byte *, | |
653 | + unsigned int, int, | |
654 | const struct value_print_options *); | |
655 | ||
656 | struct value *ada_convert_actual (struct value *actual, | |
657 | diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c | |
658 | index 61ed06e..8b1639e 100644 | |
659 | --- a/gdb/ada-tasks.c | |
660 | +++ b/gdb/ada-tasks.c | |
661 | @@ -293,7 +293,7 @@ read_fat_string_value (char *dest, struct value *val, int max_len) | |
662 | ||
663 | /* Extract LEN characters from the fat string. */ | |
664 | array_val = value_ind (value_field (val, array_fieldno)); | |
665 | - read_memory (VALUE_ADDRESS (array_val), dest, len); | |
666 | + read_memory (value_address (array_val), dest, len); | |
667 | ||
668 | /* Add the NUL character to close the string. */ | |
669 | dest[len] = '\0'; | |
670 | diff --git a/gdb/ada-typeprint.c b/gdb/ada-typeprint.c | |
671 | index f00824a..ef665c4 100644 | |
672 | --- a/gdb/ada-typeprint.c | |
673 | +++ b/gdb/ada-typeprint.c | |
674 | @@ -357,16 +357,17 @@ print_array_type (struct type *type, struct ui_file *stream, int show, | |
675 | bitsize = 0; | |
676 | fprintf_filtered (stream, "array ("); | |
677 | ||
678 | + if (type == NULL) | |
679 | + { | |
680 | + fprintf_filtered (stream, _("<undecipherable array type>")); | |
681 | + return; | |
682 | + } | |
683 | + | |
684 | n_indices = -1; | |
685 | if (show < 0) | |
686 | fprintf_filtered (stream, "..."); | |
687 | else | |
688 | { | |
689 | - if (type == NULL) | |
690 | - { | |
691 | - fprintf_filtered (stream, _("<undecipherable array type>")); | |
692 | - return; | |
693 | - } | |
694 | if (ada_is_simple_array_type (type)) | |
695 | { | |
696 | struct type *range_desc_type = | |
697 | diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c | |
698 | index 9647971..cfa94a2 100644 | |
699 | --- a/gdb/ada-valprint.c | |
700 | +++ b/gdb/ada-valprint.c | |
701 | @@ -269,7 +269,8 @@ printable_val_type (struct type *type, const gdb_byte *valaddr) | |
702 | (1 or 2) of the character. */ | |
703 | ||
704 | void | |
705 | -ada_emit_char (int c, struct ui_file *stream, int quoter, int type_len) | |
706 | +ada_emit_char (int c, struct type *type, struct ui_file *stream, | |
707 | + int quoter, int type_len) | |
708 | { | |
709 | if (type_len != 2) | |
710 | type_len = 1; | |
711 | @@ -366,10 +367,10 @@ ada_print_floating (const gdb_byte *valaddr, struct type *type, | |
712 | } | |
713 | ||
714 | void | |
715 | -ada_printchar (int c, struct ui_file *stream) | |
716 | +ada_printchar (int c, struct type *type, struct ui_file *stream) | |
717 | { | |
718 | fputs_filtered ("'", stream); | |
719 | - ada_emit_char (c, stream, '\'', 1); | |
720 | + ada_emit_char (c, type, stream, '\'', 1); | |
721 | fputs_filtered ("'", stream); | |
722 | } | |
723 | ||
724 | @@ -411,7 +412,7 @@ ada_print_scalar (struct type *type, LONGEST val, struct ui_file *stream) | |
725 | break; | |
726 | ||
727 | case TYPE_CODE_CHAR: | |
728 | - LA_PRINT_CHAR ((unsigned char) val, stream); | |
729 | + LA_PRINT_CHAR ((unsigned char) val, type, stream); | |
730 | break; | |
731 | ||
732 | case TYPE_CODE_BOOL: | |
733 | @@ -454,7 +455,7 @@ ada_print_scalar (struct type *type, LONGEST val, struct ui_file *stream) | |
734 | */ | |
735 | ||
736 | static void | |
737 | -printstr (struct ui_file *stream, const gdb_byte *string, | |
738 | +printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string, | |
739 | unsigned int length, int force_ellipses, int type_len, | |
740 | const struct value_print_options *options) | |
741 | { | |
742 | @@ -506,7 +507,7 @@ printstr (struct ui_file *stream, const gdb_byte *string, | |
743 | in_quotes = 0; | |
744 | } | |
745 | fputs_filtered ("'", stream); | |
746 | - ada_emit_char (char_at (string, i, type_len), stream, '\'', | |
747 | + ada_emit_char (char_at (string, i, type_len), elttype, stream, '\'', | |
748 | type_len); | |
749 | fputs_filtered ("'", stream); | |
750 | fprintf_filtered (stream, _(" <repeats %u times>"), reps); | |
751 | @@ -524,7 +525,7 @@ printstr (struct ui_file *stream, const gdb_byte *string, | |
752 | fputs_filtered ("\"", stream); | |
753 | in_quotes = 1; | |
754 | } | |
755 | - ada_emit_char (char_at (string, i, type_len), stream, '"', | |
756 | + ada_emit_char (char_at (string, i, type_len), elttype, stream, '"', | |
757 | type_len); | |
758 | things_printed += 1; | |
759 | } | |
760 | @@ -544,11 +545,12 @@ printstr (struct ui_file *stream, const gdb_byte *string, | |
761 | } | |
762 | ||
763 | void | |
764 | -ada_printstr (struct ui_file *stream, const gdb_byte *string, | |
765 | - unsigned int length, int width, int force_ellipses, | |
766 | +ada_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, | |
767 | + unsigned int length, int force_ellipses, | |
768 | const struct value_print_options *options) | |
769 | { | |
770 | - printstr (stream, string, length, force_ellipses, width, options); | |
771 | + printstr (stream, type, string, length, force_ellipses, TYPE_LENGTH (type), | |
772 | + options); | |
773 | } | |
774 | ||
775 | ||
776 | @@ -637,7 +639,7 @@ ada_val_print_array (struct type *type, const gdb_byte *valaddr, | |
777 | len = temp_len; | |
778 | } | |
779 | ||
780 | - printstr (stream, valaddr, len, 0, eltlen, options); | |
781 | + printstr (stream, elttype, valaddr, len, 0, eltlen, options); | |
782 | result = len; | |
783 | } | |
784 | else | |
785 | @@ -688,7 +690,7 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, | |
786 | } | |
787 | else | |
788 | retn = ada_val_print_1 (value_type (val), value_contents (val), 0, | |
789 | - VALUE_ADDRESS (val), stream, recurse, options); | |
790 | + value_address (val), stream, recurse, options); | |
791 | value_free_to_mark (mark); | |
792 | return retn; | |
793 | } | |
794 | @@ -817,7 +819,7 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, | |
795 | { | |
796 | fputs_filtered (" ", stream); | |
797 | ada_printchar ((unsigned char) unpack_long (type, valaddr), | |
798 | - stream); | |
799 | + type, stream); | |
800 | } | |
801 | } | |
802 | return 0; | |
803 | @@ -904,7 +906,7 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0, | |
804 | deref_val_int)); | |
805 | val_print (value_type (deref_val), | |
806 | value_contents (deref_val), 0, | |
807 | - VALUE_ADDRESS (deref_val), stream, recurse + 1, | |
808 | + value_address (deref_val), stream, recurse + 1, | |
809 | options, current_language); | |
810 | } | |
811 | else | |
812 | @@ -944,7 +946,7 @@ ada_value_print (struct value *val0, struct ui_file *stream, | |
813 | const struct value_print_options *options) | |
814 | { | |
815 | const gdb_byte *valaddr = value_contents (val0); | |
816 | - CORE_ADDR address = VALUE_ADDRESS (val0) + value_offset (val0); | |
817 | + CORE_ADDR address = value_address (val0); | |
818 | struct type *type = | |
819 | ada_to_fixed_type (value_type (val0), valaddr, address, NULL, 1); | |
820 | struct value *val = | |
821 | diff --git a/gdb/auxv.c b/gdb/auxv.c | |
822 | index 5007cd0..241a6ac 100644 | |
823 | --- a/gdb/auxv.c | |
824 | +++ b/gdb/auxv.c | |
825 | @@ -247,7 +247,8 @@ fprint_target_auxv (struct ui_file *file, struct target_ops *ops) | |
826 | get_user_print_options (&opts); | |
827 | if (opts.addressprint) | |
828 | fprintf_filtered (file, "0x%s", paddr_nz (val)); | |
829 | - val_print_string (val, -1, 1, file, &opts); | |
830 | + val_print_string (builtin_type (target_gdbarch)->builtin_char, | |
831 | + val, -1, file, &opts); | |
832 | fprintf_filtered (file, "\n"); | |
833 | } | |
834 | break; | |
835 | diff --git a/gdb/block.c b/gdb/block.c | |
836 | index 8f0140c..d451769 100644 | |
837 | --- a/gdb/block.c | |
838 | +++ b/gdb/block.c | |
839 | @@ -207,24 +207,16 @@ block_set_scope (struct block *block, const char *scope, | |
840 | } | |
841 | ||
842 | /* This returns the first using directives associated to BLOCK, if | |
843 | - any. */ | |
844 | - | |
845 | -/* FIXME: carlton/2003-04-23: This uses the fact that we currently | |
846 | - only have using directives in static blocks, because we only | |
847 | - generate using directives from anonymous namespaces. Eventually, | |
848 | - when we support using directives everywhere, we'll want to replace | |
849 | - this by some iterator functions. */ | |
850 | + any. Each BLOCK_NAMESPACE()->USING already contains all the namespaces | |
851 | + imported at that code point - even those from its parent blocks. */ | |
852 | ||
853 | struct using_direct * | |
854 | block_using (const struct block *block) | |
855 | { | |
856 | - const struct block *static_block = block_static_block (block); | |
857 | - | |
858 | - if (static_block == NULL | |
859 | - || BLOCK_NAMESPACE (static_block) == NULL) | |
860 | + if (block == NULL || BLOCK_NAMESPACE (block) == NULL) | |
861 | return NULL; | |
862 | else | |
863 | - return BLOCK_NAMESPACE (static_block)->using; | |
864 | + return BLOCK_NAMESPACE (block)->using; | |
865 | } | |
866 | ||
867 | /* Set BLOCK's using member to USING; if needed, allocate memory via | |
868 | diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c | |
869 | index b23b294..531c43d 100644 | |
870 | --- a/gdb/breakpoint.c | |
871 | +++ b/gdb/breakpoint.c | |
872 | @@ -191,6 +191,8 @@ static int is_hardware_watchpoint (struct breakpoint *bpt); | |
873 | ||
874 | static void insert_breakpoint_locations (void); | |
875 | ||
876 | +static int syscall_catchpoint_p (struct breakpoint *b); | |
877 | + | |
878 | static const char * | |
879 | bpdisp_text (enum bpdisp disp) | |
880 | { | |
881 | @@ -341,6 +343,18 @@ set_breakpoint_count (int num) | |
882 | value_from_longest (builtin_type_int32, (LONGEST) num)); | |
883 | } | |
884 | ||
885 | +/* Used in run_command to reset syscall catchpoints fields. */ | |
886 | + | |
887 | +void | |
888 | +clear_syscall_catchpoints_info (void) | |
889 | +{ | |
890 | + struct breakpoint *b; | |
891 | + | |
892 | + ALL_BREAKPOINTS (b) | |
893 | + if (syscall_catchpoint_p (b)) | |
894 | + b->syscall_number = UNKNOWN_SYSCALL; | |
895 | +} | |
896 | + | |
897 | /* Used in run_command to zero the hit count when a new run starts. */ | |
898 | ||
899 | void | |
900 | @@ -523,6 +537,53 @@ get_number_or_range (char **pp) | |
901 | ||
902 | ||
903 | \f | |
904 | +/* Set break condition of breakpoint B to EXP. */ | |
905 | + | |
906 | +void | |
907 | +set_breakpoint_condition (struct breakpoint *b, char *exp, int from_tty) | |
908 | +{ | |
909 | + struct bp_location *loc = b->loc; | |
910 | + | |
911 | + for (; loc; loc = loc->next) | |
912 | + { | |
913 | + if (loc->cond) | |
914 | + { | |
915 | + xfree (loc->cond); | |
916 | + loc->cond = 0; | |
917 | + } | |
918 | + } | |
919 | + | |
920 | + if (b->cond_string != NULL) | |
921 | + xfree (b->cond_string); | |
922 | + | |
923 | + if (*exp == 0) | |
924 | + { | |
925 | + b->cond_string = NULL; | |
926 | + if (from_tty) | |
927 | + printf_filtered (_("Breakpoint %d now unconditional.\n"), b->number); | |
928 | + } | |
929 | + else | |
930 | + { | |
931 | + char *arg = exp; | |
932 | + | |
933 | + /* I don't know if it matters whether this is the string the user | |
934 | + typed in or the decompiled expression. */ | |
935 | + b->cond_string = savestring (arg, strlen (arg)); | |
936 | + b->condition_not_parsed = 0; | |
937 | + for (loc = b->loc; loc; loc = loc->next) | |
938 | + { | |
939 | + arg = exp; | |
940 | + loc->cond = | |
941 | + parse_exp_1 (&arg, block_for_pc (loc->address), 0); | |
942 | + if (*arg) | |
943 | + error (_("Junk at end of expression")); | |
944 | + } | |
945 | + } | |
946 | + | |
947 | + breakpoints_changed (); | |
948 | + observer_notify_breakpoint_modified (b->number); | |
949 | +} | |
950 | + | |
951 | /* condition N EXP -- set break condition of breakpoint N to EXP. */ | |
952 | ||
953 | static void | |
954 | @@ -543,42 +604,7 @@ condition_command (char *arg, int from_tty) | |
955 | ALL_BREAKPOINTS (b) | |
956 | if (b->number == bnum) | |
957 | { | |
958 | - struct bp_location *loc = b->loc; | |
959 | - for (; loc; loc = loc->next) | |
960 | - { | |
961 | - if (loc->cond) | |
962 | - { | |
963 | - xfree (loc->cond); | |
964 | - loc->cond = 0; | |
965 | - } | |
966 | - } | |
967 | - if (b->cond_string != NULL) | |
968 | - xfree (b->cond_string); | |
969 | - | |
970 | - if (*p == 0) | |
971 | - { | |
972 | - b->cond_string = NULL; | |
973 | - if (from_tty) | |
974 | - printf_filtered (_("Breakpoint %d now unconditional.\n"), bnum); | |
975 | - } | |
976 | - else | |
977 | - { | |
978 | - arg = p; | |
979 | - /* I don't know if it matters whether this is the string the user | |
980 | - typed in or the decompiled expression. */ | |
981 | - b->cond_string = savestring (arg, strlen (arg)); | |
982 | - b->condition_not_parsed = 0; | |
983 | - for (loc = b->loc; loc; loc = loc->next) | |
984 | - { | |
985 | - arg = p; | |
986 | - loc->cond = | |
987 | - parse_exp_1 (&arg, block_for_pc (loc->address), 0); | |
988 | - if (*arg) | |
989 | - error (_("Junk at end of expression")); | |
990 | - } | |
991 | - } | |
992 | - breakpoints_changed (); | |
993 | - observer_notify_breakpoint_modified (b->number); | |
994 | + set_breakpoint_condition (b, p, from_tty); | |
995 | return; | |
996 | } | |
997 | ||
998 | @@ -961,7 +987,7 @@ update_watchpoint (struct breakpoint *b, int reparse) | |
999 | int len, type; | |
1000 | struct bp_location *loc, **tmp; | |
1001 | ||
1002 | - addr = VALUE_ADDRESS (v) + value_offset (v); | |
1003 | + addr = value_address (v); | |
1004 | len = TYPE_LENGTH (value_type (v)); | |
1005 | type = hw_write; | |
1006 | if (b->type == bp_read_watchpoint) | |
1007 | @@ -3948,8 +3974,8 @@ check_duplicates_for (CORE_ADDR address, struct obj_section *section) | |
1008 | } | |
1009 | ||
1010 | /* If we found a permanent breakpoint at this address, go over the | |
1011 | - list again and declare all the other breakpoints there to be the | |
1012 | - duplicates. */ | |
1013 | + list again and declare all the other breakpoints there (except | |
1014 | + other permanent breakpoints) to be the duplicates. */ | |
1015 | if (perm_bp) | |
1016 | { | |
1017 | perm_bp->duplicate = 0; | |
1018 | @@ -3963,7 +3989,8 @@ check_duplicates_for (CORE_ADDR address, struct obj_section *section) | |
1019 | ALL_BP_LOCATIONS (b) | |
1020 | if (b != perm_bp) | |
1021 | { | |
1022 | - if (b->owner->enable_state != bp_disabled | |
1023 | + if (b->owner->enable_state != bp_permanent | |
1024 | + && b->owner->enable_state != bp_disabled | |
1025 | && b->owner->enable_state != bp_call_disabled | |
1026 | && b->enabled && !b->shlib_disabled | |
1027 | && b->address == address /* address / overlay match */ | |
1028 | @@ -4134,6 +4161,8 @@ set_raw_breakpoint_without_location (enum bptype bptype) | |
1029 | b->frame_id = null_frame_id; | |
1030 | b->forked_inferior_pid = null_ptid; | |
1031 | b->exec_pathname = NULL; | |
1032 | + b->syscalls_to_be_caught = NULL; | |
1033 | + b->syscall_number = UNKNOWN_SYSCALL; | |
1034 | b->ops = NULL; | |
1035 | b->condition_not_parsed = 0; | |
1036 | ||
1037 | @@ -4660,7 +4689,241 @@ static struct breakpoint_ops catch_vfork_breakpoint_ops = | |
1038 | print_mention_catch_vfork | |
1039 | }; | |
1040 | ||
1041 | -/* Create a new breakpoint of the bp_catchpoint kind and return it. | |
1042 | +/* We keep a count of the number of times the user has requested a | |
1043 | + particular syscall to be tracked, and pass this information to the | |
1044 | + target. This lets capable targets implement filtering directly. */ | |
1045 | + | |
1046 | +/* Number of times that "any" syscall is requested. */ | |
1047 | +static int any_syscall_count; | |
1048 | + | |
1049 | +/* Count of each system call. */ | |
1050 | +static int *syscalls_counts; | |
1051 | + | |
1052 | +/* Number of system entries in SYSCALLS_COUNTS. */ | |
1053 | +static int syscalls_size; | |
1054 | + | |
1055 | +/* This counts all syscall catch requests, so we can readily determine | |
1056 | + if any catching is necessary. */ | |
1057 | +static int total_syscalls_count; | |
1058 | + | |
1059 | +/* Implement the "insert" breakpoint_ops method for syscall | |
1060 | + catchpoints. */ | |
1061 | + | |
1062 | +static void | |
1063 | +insert_catch_syscall (struct breakpoint *b) | |
1064 | +{ | |
1065 | + ++total_syscalls_count; | |
1066 | + if (!b->syscalls_to_be_caught) | |
1067 | + ++any_syscall_count; | |
1068 | + else | |
1069 | + { | |
1070 | + struct syscall_filter *iter; | |
1071 | + for (iter = b->syscalls_to_be_caught; iter; iter = iter->next) | |
1072 | + { | |
1073 | + if (iter->syscall >= syscalls_size) | |
1074 | + { | |
1075 | + syscalls_counts = xrealloc (syscalls_counts, | |
1076 | + (iter->syscall + 1) * sizeof (int)); | |
1077 | + memset (&syscalls_counts[syscalls_size], 0, | |
1078 | + (iter->syscall + 1 - syscalls_size) * sizeof (int)); | |
1079 | + } | |
1080 | + ++syscalls_counts[iter->syscall]; | |
1081 | + } | |
1082 | + } | |
1083 | + | |
1084 | + target_set_syscall_catchpoint (PIDGET (inferior_ptid), | |
1085 | + total_syscalls_count != 0, | |
1086 | + any_syscall_count, | |
1087 | + syscalls_size, | |
1088 | + syscalls_counts); | |
1089 | +} | |
1090 | + | |
1091 | +/* Implement the "remove" breakpoint_ops method for syscall | |
1092 | + catchpoints. */ | |
1093 | + | |
1094 | +static int | |
1095 | +remove_catch_syscall (struct breakpoint *b) | |
1096 | +{ | |
1097 | + --total_syscalls_count; | |
1098 | + if (!b->syscalls_to_be_caught) | |
1099 | + --any_syscall_count; | |
1100 | + else | |
1101 | + { | |
1102 | + struct syscall_filter *iter; | |
1103 | + for (iter = b->syscalls_to_be_caught; iter; iter = iter->next) | |
1104 | + { | |
1105 | + if (iter->syscall >= syscalls_size) | |
1106 | + { | |
1107 | + /* Shouldn't happen. */ | |
1108 | + continue; | |
1109 | + } | |
1110 | + --syscalls_counts[iter->syscall]; | |
1111 | + } | |
1112 | + } | |
1113 | + | |
1114 | + return target_set_syscall_catchpoint (PIDGET (inferior_ptid), | |
1115 | + total_syscalls_count != 0, | |
1116 | + any_syscall_count, | |
1117 | + syscalls_size, | |
1118 | + syscalls_counts); | |
1119 | +} | |
1120 | + | |
1121 | +/* Implement the "breakpoint_hit" breakpoint_ops method for syscall | |
1122 | + catchpoints. */ | |
1123 | + | |
1124 | +static int | |
1125 | +breakpoint_hit_catch_syscall (struct breakpoint *b) | |
1126 | +{ | |
1127 | + /* We must check if we are catching specific syscalls in this breakpoint. | |
1128 | + If we are, then we must guarantee that the called syscall is the same | |
1129 | + syscall we are catching. */ | |
1130 | + int syscall_number = 0; | |
1131 | + | |
1132 | + if (!inferior_has_called_syscall (inferior_ptid, &syscall_number)) | |
1133 | + return 0; | |
1134 | + | |
1135 | + /* Now, checking if the syscall is the same. */ | |
1136 | + if (b->syscalls_to_be_caught) | |
1137 | + { | |
1138 | + struct syscall_filter *iter; | |
1139 | + for (iter = b->syscalls_to_be_caught; iter; iter = iter->next) | |
1140 | + if (syscall_number == iter->syscall) | |
1141 | + break; | |
1142 | + /* Not the same. */ | |
1143 | + if (!iter) | |
1144 | + return 0; | |
1145 | + } | |
1146 | + | |
1147 | + /* It's the same syscall. We can update the breakpoint struct | |
1148 | + with the correct information. */ | |
1149 | + b->syscall_number = syscall_number; | |
1150 | + | |
1151 | + return 1; | |
1152 | +} | |
1153 | + | |
1154 | +/* Implement the "print_it" breakpoint_ops method for syscall | |
1155 | + catchpoints. */ | |
1156 | + | |
1157 | +static enum print_stop_action | |
1158 | +print_it_catch_syscall (struct breakpoint *b) | |
1159 | +{ | |
1160 | + /* These are needed because we want to know in which state a | |
1161 | + syscall is. It can be in the TARGET_WAITKIND_SYSCALL_ENTRY | |
1162 | + or TARGET_WAITKIND_SYSCALL_RETURN, and depending on it we | |
1163 | + must print "called syscall" or "returned from syscall". */ | |
1164 | + ptid_t ptid; | |
1165 | + struct target_waitstatus last; | |
1166 | + struct syscall s; | |
1167 | + struct cleanup *old_chain; | |
1168 | + char *syscall_id; | |
1169 | + | |
1170 | + gdbarch_get_syscall_by_number (current_gdbarch, b->syscall_number, &s); | |
1171 | + | |
1172 | + get_last_target_status (&ptid, &last); | |
1173 | + | |
1174 | + annotate_catchpoint (b->number); | |
1175 | + | |
1176 | + if (s.name == NULL) | |
1177 | + syscall_id = xstrprintf ("%d", b->syscall_number); | |
1178 | + else | |
1179 | + syscall_id = xstrprintf ("'%s'", s.name); | |
1180 | + | |
1181 | + old_chain = make_cleanup (xfree, syscall_id); | |
1182 | + | |
1183 | + if (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY) | |
1184 | + printf_filtered (_("\nCatchpoint %d (call to syscall %s), "), | |
1185 | + b->number, syscall_id); | |
1186 | + else | |
1187 | + printf_filtered (_("\nCatchpoint %d (returned from syscall %s), "), | |
1188 | + b->number, syscall_id); | |
1189 | + | |
1190 | + do_cleanups (old_chain); | |
1191 | + | |
1192 | + return PRINT_SRC_AND_LOC; | |
1193 | +} | |
1194 | + | |
1195 | +/* Implement the "print_one" breakpoint_ops method for syscall | |
1196 | + catchpoints. */ | |
1197 | + | |
1198 | +static void | |
1199 | +print_one_catch_syscall (struct breakpoint *b, CORE_ADDR *last_addr) | |
1200 | +{ | |
1201 | + struct value_print_options opts; | |
1202 | + struct syscall s; | |
1203 | + | |
1204 | + gdbarch_get_syscall_by_number (current_gdbarch, b->syscall_number, &s); | |
1205 | + | |
1206 | + get_user_print_options (&opts); | |
1207 | + /* Field 4, the address, is omitted (which makes the columns | |
1208 | + not line up too nicely with the headers, but the effect | |
1209 | + is relatively readable). */ | |
1210 | + if (opts.addressprint) | |
1211 | + ui_out_field_skip (uiout, "addr"); | |
1212 | + annotate_field (5); | |
1213 | + ui_out_text (uiout, "syscall \""); | |
1214 | + if (b->syscall_number != UNKNOWN_SYSCALL) | |
1215 | + { | |
1216 | + if (s.name) | |
1217 | + ui_out_field_string (uiout, "what", s.name); | |
1218 | + else | |
1219 | + ui_out_field_int (uiout, "what", b->syscall_number); | |
1220 | + } | |
1221 | + else | |
1222 | + ui_out_field_string (uiout, "what", "<any syscall>"); | |
1223 | + ui_out_text (uiout, "\" "); | |
1224 | +} | |
1225 | + | |
1226 | +/* Implement the "print_mention" breakpoint_ops method for syscall | |
1227 | + catchpoints. */ | |
1228 | + | |
1229 | +static void | |
1230 | +print_mention_catch_syscall (struct breakpoint *b) | |
1231 | +{ | |
1232 | + if (b->syscalls_to_be_caught) | |
1233 | + { | |
1234 | + struct syscall_filter *iter; | |
1235 | + printf_filtered (_("Catchpoint %d (syscall(s)"), b->number); | |
1236 | + for (iter = b->syscalls_to_be_caught; iter; iter = iter->next) | |
1237 | + { | |
1238 | + struct syscall s; | |
1239 | + gdbarch_get_syscall_by_number (current_gdbarch, iter->syscall, &s); | |
1240 | + | |
1241 | + if (s.name) | |
1242 | + printf_filtered (" '%s'", s.name); | |
1243 | + else | |
1244 | + printf_filtered (" %d", iter->syscall); | |
1245 | + } | |
1246 | + printf_filtered (")"); | |
1247 | + } | |
1248 | + else | |
1249 | + printf_filtered (_("Catchpoint %d (any syscall)"), | |
1250 | + b->number); | |
1251 | +} | |
1252 | + | |
1253 | +/* The breakpoint_ops structure to be used in syscall catchpoints. */ | |
1254 | + | |
1255 | +static struct breakpoint_ops catch_syscall_breakpoint_ops = | |
1256 | +{ | |
1257 | + insert_catch_syscall, | |
1258 | + remove_catch_syscall, | |
1259 | + breakpoint_hit_catch_syscall, | |
1260 | + print_it_catch_syscall, | |
1261 | + print_one_catch_syscall, | |
1262 | + print_mention_catch_syscall | |
1263 | +}; | |
1264 | + | |
1265 | +/* Returns non-zero if 'b' is a syscall catchpoint. */ | |
1266 | + | |
1267 | +static int | |
1268 | +syscall_catchpoint_p (struct breakpoint *b) | |
1269 | +{ | |
1270 | + return (b->ops == &catch_syscall_breakpoint_ops); | |
1271 | +} | |
1272 | + | |
1273 | +/* Create a new breakpoint of the bp_catchpoint kind and return it, | |
1274 | + but does NOT mention it nor update the global location list. | |
1275 | + This is useful if you need to fill more fields in the | |
1276 | + struct breakpoint before calling mention. | |
1277 | ||
1278 | If TEMPFLAG is non-zero, then make the breakpoint temporary. | |
1279 | If COND_STRING is not NULL, then store it in the breakpoint. | |
1280 | @@ -4668,16 +4931,13 @@ static struct breakpoint_ops catch_vfork_breakpoint_ops = | |
1281 | to the catchpoint. */ | |
1282 | ||
1283 | static struct breakpoint * | |
1284 | -create_catchpoint (int tempflag, char *cond_string, | |
1285 | - struct breakpoint_ops *ops) | |
1286 | +create_catchpoint_without_mention (int tempflag, char *cond_string, | |
1287 | + struct breakpoint_ops *ops) | |
1288 | { | |
1289 | struct symtab_and_line sal; | |
1290 | struct breakpoint *b; | |
1291 | ||
1292 | init_sal (&sal); | |
1293 | - sal.pc = 0; | |
1294 | - sal.symtab = NULL; | |
1295 | - sal.line = 0; | |
1296 | ||
1297 | b = set_raw_breakpoint (sal, bp_catchpoint); | |
1298 | set_breakpoint_count (breakpoint_count + 1); | |
1299 | @@ -4691,6 +4951,23 @@ create_catchpoint (int tempflag, char *cond_string, | |
1300 | b->disposition = tempflag ? disp_del : disp_donttouch; | |
1301 | b->ops = ops; | |
1302 | ||
1303 | + return b; | |
1304 | +} | |
1305 | + | |
1306 | +/* Create a new breakpoint of the bp_catchpoint kind and return it. | |
1307 | + | |
1308 | + If TEMPFLAG is non-zero, then make the breakpoint temporary. | |
1309 | + If COND_STRING is not NULL, then store it in the breakpoint. | |
1310 | + OPS, if not NULL, is the breakpoint_ops structure associated | |
1311 | + to the catchpoint. */ | |
1312 | + | |
1313 | +static struct breakpoint * | |
1314 | +create_catchpoint (int tempflag, char *cond_string, | |
1315 | + struct breakpoint_ops *ops) | |
1316 | +{ | |
1317 | + struct breakpoint *b = | |
1318 | + create_catchpoint_without_mention (tempflag, cond_string, ops); | |
1319 | + | |
1320 | mention (b); | |
1321 | update_global_location_list (1); | |
1322 | ||
1323 | @@ -4775,6 +5052,23 @@ static struct breakpoint_ops catch_exec_breakpoint_ops = | |
1324 | print_mention_catch_exec | |
1325 | }; | |
1326 | ||
1327 | +static void | |
1328 | +create_syscall_event_catchpoint (int tempflag, struct syscall_filter *filter, | |
1329 | + struct breakpoint_ops *ops) | |
1330 | +{ | |
1331 | + struct breakpoint *b = | |
1332 | + create_catchpoint_without_mention (tempflag, NULL, ops); | |
1333 | + | |
1334 | + b->syscalls_to_be_caught = filter; | |
1335 | + /* We still don't know the syscall that will be caught :-). */ | |
1336 | + b->syscall_number = UNKNOWN_SYSCALL; | |
1337 | + | |
1338 | + /* Now, we have to mention the breakpoint and update the global | |
1339 | + location list. */ | |
1340 | + mention (b); | |
1341 | + update_global_location_list (1); | |
1342 | +} | |
1343 | + | |
1344 | static int | |
1345 | hw_breakpoint_used_count (void) | |
1346 | { | |
1347 | @@ -5188,7 +5482,6 @@ expand_line_sal_maybe (struct symtab_and_line sal) | |
1348 | struct symtabs_and_lines expanded; | |
1349 | CORE_ADDR original_pc = sal.pc; | |
1350 | char *original_function = NULL; | |
1351 | - int found; | |
1352 | int i; | |
1353 | ||
1354 | /* If we have explicit pc, don't expand. | |
1355 | @@ -5264,14 +5557,42 @@ expand_line_sal_maybe (struct symtab_and_line sal) | |
1356 | ||
1357 | if (original_pc) | |
1358 | { | |
1359 | - found = 0; | |
1360 | + /* Find all the other PCs for a line of code with multiple instances | |
1361 | + (locations). If the instruction is in the middle of an instruction | |
1362 | + block for source line GDB cannot safely find the same instruction in | |
1363 | + the other compiled instances of the same source line because the other | |
1364 | + instances may have been compiled completely differently. | |
1365 | + | |
1366 | + The testcase gdb.cp/expand-sals.exp shows that breaking at the return | |
1367 | + address in a caller of the current frame works for the current | |
1368 | + instance but the breakpoint cannot catch the point (instruction) where | |
1369 | + the callee returns in the other compiled instances of this source line. | |
1370 | + | |
1371 | + The current implementation will place the breakpoint at the expected | |
1372 | + returning address of the current instance of the caller. But the | |
1373 | + other instances will get the breakpoint at the first instruction of | |
1374 | + the source line - therefore before the call would be made. Another | |
1375 | + possibility would be to place the breakpoint in the other instances at | |
1376 | + the start of the next source line. | |
1377 | + | |
1378 | + A possible heuristics would compare the instructions length of each of | |
1379 | + the instances of the current source line and if it matches it would | |
1380 | + place the breakpoint at the same offset. Unfortunately a mistaken | |
1381 | + guess would possibly crash the inferior. */ | |
1382 | + | |
1383 | + CORE_ADDR best = -1; | |
1384 | + | |
1385 | + /* Find the nearest preceding PC and set it to ORIGINAL_PC. */ | |
1386 | for (i = 0; i < expanded.nelts; ++i) | |
1387 | - if (expanded.sals[i].pc == original_pc) | |
1388 | - { | |
1389 | - found = 1; | |
1390 | - break; | |
1391 | - } | |
1392 | - gdb_assert (found); | |
1393 | + if (expanded.sals[i].pc <= original_pc | |
1394 | + && (best == -1 || expanded.sals[best].pc < expanded.sals[i].pc)) | |
1395 | + best = i; | |
1396 | + | |
1397 | + if (best == -1) | |
1398 | + error (_("Cannot find the best address for %s out of the %d locations"), | |
1399 | + paddr (original_pc), expanded.nelts); | |
1400 | + | |
1401 | + expanded.sals[best].pc = original_pc; | |
1402 | } | |
1403 | ||
1404 | return expanded; | |
1405 | @@ -5310,8 +5631,6 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string, | |
1406 | cond_string, type, disposition, | |
1407 | thread, ignore_count, ops, from_tty, enabled); | |
1408 | } | |
1409 | - | |
1410 | - update_global_location_list (1); | |
1411 | } | |
1412 | ||
1413 | /* Parse ARG which is assumed to be a SAL specification possibly | |
1414 | @@ -5637,7 +5956,6 @@ break_command_really (char *arg, char *cond_string, int thread, | |
1415 | b->ops = ops; | |
1416 | b->enable_state = enabled ? bp_enabled : bp_disabled; | |
1417 | ||
1418 | - update_global_location_list (1); | |
1419 | mention (b); | |
1420 | } | |
1421 | ||
1422 | @@ -5649,6 +5967,11 @@ break_command_really (char *arg, char *cond_string, int thread, | |
1423 | discard_cleanups (breakpoint_chain); | |
1424 | /* But cleanup everything else. */ | |
1425 | do_cleanups (old_chain); | |
1426 | + | |
1427 | + /* Have already BREAKPOINT_CHAIN discarded as we may get an exception while | |
1428 | + inserting the breakpoints which would double-free the resources both by | |
1429 | + BREAKPOINT_CHAIN now and during DELETE_BREAKPOINT in the future. */ | |
1430 | + update_global_location_list (1); | |
1431 | } | |
1432 | ||
1433 | /* Set a breakpoint. | |
1434 | @@ -6131,7 +6454,7 @@ can_use_hardware_watchpoint (struct value *v) | |
1435 | || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT | |
1436 | && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) | |
1437 | { | |
1438 | - CORE_ADDR vaddr = VALUE_ADDRESS (v) + value_offset (v); | |
1439 | + CORE_ADDR vaddr = value_address (v); | |
1440 | int len = TYPE_LENGTH (value_type (v)); | |
1441 | ||
1442 | if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len)) | |
1443 | @@ -6668,6 +6991,122 @@ catch_ada_exception_command (char *arg, int from_tty, | |
1444 | from_tty); | |
1445 | } | |
1446 | ||
1447 | +/* Cleanup function for a syscall filter list. */ | |
1448 | +static void | |
1449 | +clean_up_filters (void *arg) | |
1450 | +{ | |
1451 | + struct syscall_filter *iter = *(struct syscall_filter **) arg; | |
1452 | + while (iter) | |
1453 | + { | |
1454 | + struct syscall_filter *next = iter->next; | |
1455 | + xfree (iter); | |
1456 | + iter = next; | |
1457 | + } | |
1458 | +} | |
1459 | + | |
1460 | +/* Splits the argument using space as delimiter. Returns an xmalloc'd | |
1461 | + filter list, or NULL if no filtering is required. */ | |
1462 | +static struct syscall_filter * | |
1463 | +catch_syscall_split_args (char *arg) | |
1464 | +{ | |
1465 | + struct syscall_filter *result = NULL; | |
1466 | + struct cleanup *cleanup = make_cleanup (clean_up_filters, &result); | |
1467 | + | |
1468 | + while (*arg != '\0') | |
1469 | + { | |
1470 | + int i, syscall_number; | |
1471 | + char *endptr; | |
1472 | + char cur_name[128]; | |
1473 | + struct syscall_filter *new_filter; | |
1474 | + struct syscall s; | |
1475 | + | |
1476 | + /* Skip whitespace. */ | |
1477 | + while (isspace (*arg)) | |
1478 | + arg++; | |
1479 | + | |
1480 | + for (i = 0; arg[i] && !isspace (arg[i]); ++i) | |
1481 | + cur_name[i] = arg[i]; | |
1482 | + cur_name[i] = '\0'; | |
1483 | + arg += i; | |
1484 | + | |
1485 | + /* Check if the user provided a syscall name or a number. */ | |
1486 | + syscall_number = (int) strtol (cur_name, &endptr, 10); | |
1487 | + if (*endptr == '\0') | |
1488 | + { | |
1489 | + gdbarch_get_syscall_by_number (current_gdbarch, | |
1490 | + syscall_number, &s); | |
1491 | + | |
1492 | + if (s.name == NULL) | |
1493 | + /* We can issue just a warning, but still create the catchpoint. | |
1494 | + This is because, even not knowing the syscall name that | |
1495 | + this number represents, we can still try to catch the syscall | |
1496 | + number. */ | |
1497 | + warning (_("The number '%d' does not represent a known syscall."), | |
1498 | + syscall_number); | |
1499 | + } | |
1500 | + else | |
1501 | + { | |
1502 | + /* We have a name. Let's check if it's valid and convert it | |
1503 | + to a number. */ | |
1504 | + gdbarch_get_syscall_by_name (current_gdbarch, cur_name, &s); | |
1505 | + | |
1506 | + if (s.number == UNKNOWN_SYSCALL) | |
1507 | + /* Here we have to issue an error instead of a warning, because | |
1508 | + GDB cannot do anything useful if there's no syscall number to | |
1509 | + be caught. */ | |
1510 | + error (_("Unknown syscall name '%s'."), cur_name); | |
1511 | + } | |
1512 | + | |
1513 | + /* Ok, it's valid. */ | |
1514 | + new_filter = XNEW (struct syscall_filter); | |
1515 | + new_filter->syscall = s.number; | |
1516 | + new_filter->next = result; | |
1517 | + result = new_filter; | |
1518 | + } | |
1519 | + | |
1520 | + discard_cleanups (cleanup); | |
1521 | + return result; | |
1522 | +} | |
1523 | + | |
1524 | +/* Implement the "catch syscall" command. */ | |
1525 | + | |
1526 | +static void | |
1527 | +catch_syscall_command_1 (char *arg, int from_tty, struct cmd_list_element *command) | |
1528 | +{ | |
1529 | + int tempflag; | |
1530 | + struct syscall_filter *filter; | |
1531 | + struct syscall s; | |
1532 | + | |
1533 | + /* Checking if the feature if supported. */ | |
1534 | + if (gdbarch_get_syscall_number_p (current_gdbarch) == 0) | |
1535 | + error (_("The feature 'catch syscall' is not supported on \ | |
1536 | +this architeture yet.")); | |
1537 | + | |
1538 | + tempflag = get_cmd_context (command) == CATCH_TEMPORARY; | |
1539 | + | |
1540 | + ep_skip_leading_whitespace (&arg); | |
1541 | + | |
1542 | + /* We need to do this first "dummy" translation in order | |
1543 | + to get the syscall XML file loaded or, most important, | |
1544 | + to display a warning to the user if there's no XML file | |
1545 | + for his/her architecture. */ | |
1546 | + gdbarch_get_syscall_by_number (current_gdbarch, 0, &s); | |
1547 | + | |
1548 | + /* The allowed syntax is: | |
1549 | + catch syscall | |
1550 | + catch syscall <name | number> [<name | number> ... <name | number>] | |
1551 | + | |
1552 | + Let's check if there's a syscall name. */ | |
1553 | + | |
1554 | + if (arg != NULL) | |
1555 | + filter = catch_syscall_split_args (arg); | |
1556 | + else | |
1557 | + filter = NULL; | |
1558 | + | |
1559 | + create_syscall_event_catchpoint (tempflag, filter, | |
1560 | + &catch_syscall_breakpoint_ops); | |
1561 | +} | |
1562 | + | |
1563 | /* Implement the "catch assert" command. */ | |
1564 | ||
1565 | static void | |
1566 | @@ -7134,6 +7573,7 @@ delete_breakpoint (struct breakpoint *bpt) | |
1567 | xfree (bpt->source_file); | |
1568 | if (bpt->exec_pathname != NULL) | |
1569 | xfree (bpt->exec_pathname); | |
1570 | + clean_up_filters (&bpt->syscalls_to_be_caught); | |
1571 | ||
1572 | /* Be sure no bpstat's are pointing at it after it's been freed. */ | |
1573 | /* FIXME, how can we find all bpstat's? | |
1574 | @@ -8041,6 +8481,56 @@ single_step_breakpoint_inserted_here_p (CORE_ADDR pc) | |
1575 | return 0; | |
1576 | } | |
1577 | ||
1578 | +/* Returns 0 if 'bp' is NOT a syscall catchpoint, | |
1579 | + non-zero otherwise. */ | |
1580 | +static int | |
1581 | +is_syscall_catchpoint_enabled (struct breakpoint *bp) | |
1582 | +{ | |
1583 | + if (syscall_catchpoint_p (bp) | |
1584 | + && bp->enable_state != bp_disabled | |
1585 | + && bp->enable_state != bp_call_disabled) | |
1586 | + return 1; | |
1587 | + else | |
1588 | + return 0; | |
1589 | +} | |
1590 | + | |
1591 | +int | |
1592 | +catch_syscall_enabled (void) | |
1593 | +{ | |
1594 | + return total_syscalls_count != 0; | |
1595 | +} | |
1596 | + | |
1597 | +int | |
1598 | +catching_syscall_number (int syscall_number) | |
1599 | +{ | |
1600 | + struct breakpoint *bp; | |
1601 | + | |
1602 | + ALL_BREAKPOINTS (bp) | |
1603 | + if (is_syscall_catchpoint_enabled (bp)) | |
1604 | + { | |
1605 | + if (bp->syscalls_to_be_caught) | |
1606 | + { | |
1607 | + struct syscall_filter *iter; | |
1608 | + for (iter = bp->syscalls_to_be_caught; iter; iter = iter->next) | |
1609 | + if (syscall_number == iter->syscall) | |
1610 | + return 1; | |
1611 | + } | |
1612 | + else | |
1613 | + return 1; | |
1614 | + } | |
1615 | + | |
1616 | + return 0; | |
1617 | +} | |
1618 | + | |
1619 | +/* Complete syscall names. Used by "catch syscall". */ | |
1620 | +static char ** | |
1621 | +catch_syscall_completer (struct cmd_list_element *self, char *text, char *word) | |
1622 | +{ | |
1623 | + const char **list = | |
1624 | + gdbarch_get_syscall_names (current_gdbarch); | |
1625 | + return (list == NULL) ? NULL : complete_on_enum (list, text, word); | |
1626 | +} | |
1627 | + | |
1628 | \f | |
1629 | /* This help string is used for the break, hbreak, tbreak and thbreak commands. | |
1630 | It is defined as a macro to prevent duplication. | |
1631 | @@ -8073,6 +8563,8 @@ static void | |
1632 | add_catch_command (char *name, char *docstring, | |
1633 | void (*sfunc) (char *args, int from_tty, | |
1634 | struct cmd_list_element *command), | |
1635 | + char **(*completion_function) (struct cmd_list_element *self, | |
1636 | + char *text, char *word), | |
1637 | void *user_data_catch, | |
1638 | void *user_data_tcatch) | |
1639 | { | |
1640 | @@ -8082,11 +8574,13 @@ add_catch_command (char *name, char *docstring, | |
1641 | &catch_cmdlist); | |
1642 | set_cmd_sfunc (command, sfunc); | |
1643 | set_cmd_context (command, user_data_catch); | |
1644 | + set_cmd_completer (command, completion_function); | |
1645 | ||
1646 | command = add_cmd (name, class_breakpoint, NULL, docstring, | |
1647 | &tcatch_cmdlist); | |
1648 | set_cmd_sfunc (command, sfunc); | |
1649 | set_cmd_context (command, user_data_tcatch); | |
1650 | + set_cmd_completer (command, completion_function); | |
1651 | } | |
1652 | ||
1653 | void | |
1654 | @@ -8361,36 +8855,50 @@ Set temporary catchpoints to catch events."), | |
1655 | Catch an exception, when caught.\n\ | |
1656 | With an argument, catch only exceptions with the given name."), | |
1657 | catch_catch_command, | |
1658 | + NULL, | |
1659 | CATCH_PERMANENT, | |
1660 | CATCH_TEMPORARY); | |
1661 | add_catch_command ("throw", _("\ | |
1662 | Catch an exception, when thrown.\n\ | |
1663 | With an argument, catch only exceptions with the given name."), | |
1664 | catch_throw_command, | |
1665 | + NULL, | |
1666 | CATCH_PERMANENT, | |
1667 | CATCH_TEMPORARY); | |
1668 | add_catch_command ("fork", _("Catch calls to fork."), | |
1669 | catch_fork_command_1, | |
1670 | + NULL, | |
1671 | (void *) (uintptr_t) catch_fork_permanent, | |
1672 | (void *) (uintptr_t) catch_fork_temporary); | |
1673 | add_catch_command ("vfork", _("Catch calls to vfork."), | |
1674 | catch_fork_command_1, | |
1675 | + NULL, | |
1676 | (void *) (uintptr_t) catch_vfork_permanent, | |
1677 | (void *) (uintptr_t) catch_vfork_temporary); | |
1678 | add_catch_command ("exec", _("Catch calls to exec."), | |
1679 | catch_exec_command_1, | |
1680 | + NULL, | |
1681 | CATCH_PERMANENT, | |
1682 | CATCH_TEMPORARY); | |
1683 | + add_catch_command ("syscall", _("\ | |
1684 | +Catch system calls.\n\ | |
1685 | +With an argument, catch only that syscall."), | |
1686 | + catch_syscall_command_1, | |
1687 | + catch_syscall_completer, | |
1688 | + CATCH_PERMANENT, | |
1689 | + CATCH_TEMPORARY); | |
1690 | add_catch_command ("exception", _("\ | |
1691 | Catch Ada exceptions, when raised.\n\ | |
1692 | With an argument, catch only exceptions with the given name."), | |
1693 | catch_ada_exception_command, | |
1694 | + NULL, | |
1695 | CATCH_PERMANENT, | |
1696 | CATCH_TEMPORARY); | |
1697 | add_catch_command ("assert", _("\ | |
1698 | Catch failed Ada assertions, when raised.\n\ | |
1699 | With an argument, catch only exceptions with the given name."), | |
1700 | catch_assert_command, | |
1701 | + NULL, | |
1702 | CATCH_PERMANENT, | |
1703 | CATCH_TEMPORARY); | |
1704 | ||
1705 | diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h | |
1706 | index 94287de..8552e1b 100644 | |
1707 | --- a/gdb/breakpoint.h | |
1708 | +++ b/gdb/breakpoint.h | |
1709 | @@ -33,7 +33,8 @@ struct block; | |
1710 | ||
1711 | #define BREAKPOINT_MAX 16 | |
1712 | \f | |
1713 | -/* Type of breakpoint. */ | |
1714 | + | |
1715 | +/* Type of breakpoint. */ | |
1716 | /* FIXME In the future, we should fold all other breakpoint-like things into | |
1717 | here. This includes: | |
1718 | ||
1719 | @@ -337,6 +338,17 @@ enum watchpoint_triggered | |
1720 | watch_triggered_yes | |
1721 | }; | |
1722 | ||
1723 | +/* A syscall filter is represented as a linked list of syscall | |
1724 | + numbers. */ | |
1725 | +struct syscall_filter | |
1726 | +{ | |
1727 | + /* The system call to accept. */ | |
1728 | + int syscall; | |
1729 | + | |
1730 | + /* The next filter. */ | |
1731 | + struct syscall_filter *next; | |
1732 | +}; | |
1733 | + | |
1734 | typedef struct bp_location *bp_location_p; | |
1735 | DEF_VEC_P(bp_location_p); | |
1736 | ||
1737 | @@ -442,6 +454,20 @@ struct breakpoint | |
1738 | triggered. */ | |
1739 | char *exec_pathname; | |
1740 | ||
1741 | + /* Syscall number used for the 'catch syscall' feature. | |
1742 | + If no syscall has been called, its value is UNKNOWN_SYSCALL. | |
1743 | + Otherwise, it holds the system call number in the target. | |
1744 | + | |
1745 | + This field is only valid immediately after this catchpoint has | |
1746 | + triggered. */ | |
1747 | + int syscall_number; | |
1748 | + | |
1749 | + /* Syscall numbers used for the 'catch syscall' feature. | |
1750 | + If no syscall has been specified for filtering, its value is NULL. | |
1751 | + Otherwise, it holds a list of all syscalls to be caught. | |
1752 | + The list elements are allocated with xmalloc. */ | |
1753 | + struct syscall_filter *syscalls_to_be_caught; | |
1754 | + | |
1755 | /* Methods associated with this breakpoint. */ | |
1756 | struct breakpoint_ops *ops; | |
1757 | ||
1758 | @@ -783,6 +809,8 @@ extern void enable_watchpoints_after_interactive_call_stop (void); | |
1759 | extern enum command_control_type commands_from_control_command | |
1760 | (char *arg, struct command_line *cmd); | |
1761 | ||
1762 | +extern void clear_syscall_catchpoints_info (void); | |
1763 | + | |
1764 | extern void clear_breakpoint_hit_counts (void); | |
1765 | ||
1766 | extern int get_number (char **); | |
1767 | @@ -857,7 +885,19 @@ extern int breakpoints_always_inserted_mode (void); | |
1768 | in our opinion won't ever trigger. */ | |
1769 | extern void breakpoint_retire_moribund (void); | |
1770 | ||
1771 | +/* Checks if we are catching syscalls or not. | |
1772 | + Returns 0 if not, greater than 0 if we are. */ | |
1773 | +extern int catch_syscall_enabled (void); | |
1774 | + | |
1775 | +/* Checks if we are catching syscalls with the specific | |
1776 | + syscall_number. Used for "filtering" the catchpoints. | |
1777 | + Returns 0 if not, greater than 0 if we are. */ | |
1778 | +extern int catching_syscall_number (int syscall_number); | |
1779 | + | |
1780 | /* Tell a breakpoint to be quiet. */ | |
1781 | extern void make_breakpoint_silent (struct breakpoint *); | |
1782 | ||
1783 | +/* Set break condition of breakpoint B to EXP. */ | |
1784 | +extern void set_breakpoint_condition (struct breakpoint *b, char *exp, int from_tty); | |
1785 | + | |
1786 | #endif /* !defined (BREAKPOINT_H) */ | |
1787 | diff --git a/gdb/buildsym.c b/gdb/buildsym.c | |
1788 | index 55ace15..2722daa 100644 | |
1789 | --- a/gdb/buildsym.c | |
1790 | +++ b/gdb/buildsym.c | |
1791 | @@ -384,6 +384,8 @@ finish_block (struct symbol *symbol, struct pending **listhead, | |
1792 | opblock = pblock; | |
1793 | } | |
1794 | ||
1795 | + block_set_using (block, using_directives, &objfile->objfile_obstack); | |
1796 | + | |
1797 | record_pending_block (objfile, block, opblock); | |
1798 | ||
1799 | return block; | |
1800 | @@ -815,10 +817,6 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr) | |
1801 | /* We shouldn't have any address map at this point. */ | |
1802 | gdb_assert (! pending_addrmap); | |
1803 | ||
1804 | - /* Set up support for C++ namespace support, in case we need it. */ | |
1805 | - | |
1806 | - cp_initialize_namespace (); | |
1807 | - | |
1808 | /* Initialize the list of sub source files with one entry for this | |
1809 | file (the top-level source file). */ | |
1810 | ||
1811 | @@ -1015,8 +1013,6 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) | |
1812 | finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr, | |
1813 | objfile); | |
1814 | blockvector = make_blockvector (objfile); | |
1815 | - cp_finalize_namespace (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK), | |
1816 | - &objfile->objfile_obstack); | |
1817 | } | |
1818 | ||
1819 | /* Read the line table if it has to be read separately. */ | |
1820 | @@ -1202,10 +1198,12 @@ push_context (int desc, CORE_ADDR valu) | |
1821 | new->params = param_symbols; | |
1822 | new->old_blocks = pending_blocks; | |
1823 | new->start_addr = valu; | |
1824 | + new->using_directives = using_directives; | |
1825 | new->name = NULL; | |
1826 | ||
1827 | local_symbols = NULL; | |
1828 | param_symbols = NULL; | |
1829 | + using_directives = NULL; | |
1830 | ||
1831 | return new; | |
1832 | } | |
1833 | diff --git a/gdb/buildsym.h b/gdb/buildsym.h | |
1834 | index bf23ecc..f542aca 100644 | |
1835 | --- a/gdb/buildsym.h | |
1836 | +++ b/gdb/buildsym.h | |
1837 | @@ -125,6 +125,10 @@ EXTERN struct pending *local_symbols; | |
1838 | ||
1839 | EXTERN struct pending *param_symbols; | |
1840 | ||
1841 | +/* using directives local to lexical context */ | |
1842 | + | |
1843 | +EXTERN struct using_direct *using_directives; | |
1844 | + | |
1845 | /* Stack representing unclosed lexical contexts (that will become | |
1846 | blocks, eventually). */ | |
1847 | ||
1848 | @@ -138,6 +142,10 @@ struct context_stack | |
1849 | ||
1850 | struct pending *params; | |
1851 | ||
1852 | + /* Pending using directives at the time we entered */ | |
1853 | + | |
1854 | + struct using_direct *using_directives; | |
1855 | + | |
1856 | /* Pointer into blocklist as of entry */ | |
1857 | ||
1858 | struct pending_block *old_blocks; | |
1859 | diff --git a/gdb/c-exp.y b/gdb/c-exp.y | |
1860 | index d4bbbcc..107452a 100644 | |
1861 | --- a/gdb/c-exp.y | |
1862 | +++ b/gdb/c-exp.y | |
1863 | @@ -119,6 +119,8 @@ static int yylex (void); | |
1864 | ||
1865 | void yyerror (char *); | |
1866 | ||
1867 | +/* Cleanup for 'nonempty_typelist' */ | |
1868 | +static struct cleanup *typelist_cleanup; | |
1869 | %} | |
1870 | ||
1871 | /* Although the yacc "value" of an expression is not used, | |
1872 | @@ -143,6 +145,7 @@ void yyerror (char *); | |
1873 | struct symbol *sym; | |
1874 | struct type *tval; | |
1875 | struct stoken sval; | |
1876 | + struct typed_stoken tsval; | |
1877 | struct ttype tsym; | |
1878 | struct symtoken ssym; | |
1879 | int voidval; | |
1880 | @@ -150,6 +153,7 @@ void yyerror (char *); | |
1881 | enum exp_opcode opcode; | |
1882 | struct internalvar *ivar; | |
1883 | ||
1884 | + struct stoken_vector svec; | |
1885 | struct type **tvec; | |
1886 | int *ivec; | |
1887 | } | |
1888 | @@ -182,11 +186,13 @@ static int parse_number (char *, int, int, YYSTYPE *); | |
1889 | Contexts where this distinction is not important can use the | |
1890 | nonterminal "name", which matches either NAME or TYPENAME. */ | |
1891 | ||
1892 | -%token <sval> STRING | |
1893 | +%token <tsval> STRING | |
1894 | +%token <tsval> CHAR | |
1895 | %token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */ | |
1896 | %token <voidval> COMPLETE | |
1897 | %token <tsym> TYPENAME | |
1898 | -%type <sval> name string_exp | |
1899 | +%type <sval> name | |
1900 | +%type <svec> string_exp | |
1901 | %type <ssym> name_not_typename | |
1902 | %type <tsym> typename | |
1903 | ||
1904 | @@ -399,6 +405,38 @@ arglist : arglist ',' exp %prec ABOVE_COMMA | |
1905 | { arglist_len++; } | |
1906 | ; | |
1907 | ||
1908 | +exp : exp '(' nonempty_typelist ')' | |
1909 | + { int i; | |
1910 | + /* What to do about freeing memory if | |
1911 | + there is an error during parsing? */ | |
1912 | + write_exp_elt_opcode (TYPE_INSTANCE); | |
1913 | + write_exp_elt_longcst ((LONGEST) $<ivec>3[0]); | |
1914 | + for (i = 0; i < $<ivec>3[0]; ++i) | |
1915 | + write_exp_elt_type ($<tvec>3[i + 1]); | |
1916 | + write_exp_elt_longcst((LONGEST) $<ivec>3[0]); | |
1917 | + write_exp_elt_opcode (TYPE_INSTANCE); | |
1918 | + do_cleanups (typelist_cleanup); | |
1919 | + } | |
1920 | + ; | |
1921 | + | |
1922 | +/* | |
1923 | +exp : BLOCKNAME '(' nonempty_typelist ')' | |
1924 | + { int i; | |
1925 | + write_exp_elt_opcode (TYPE_INSTANCE_LOOKUP); | |
1926 | + write_exp_elt_sym ($1.sym); | |
1927 | + write_exp_elt_opcode (TYPE_INSTANCE_LOOKUP); | |
1928 | + | |
1929 | + write_exp_elt_opcode (TYPE_INSTANCE); | |
1930 | + write_exp_elt_longcst ((LONGEST) $<ivec>3[0]); | |
1931 | + for (i = 0; i < $<ivec>3[0]; ++i) | |
1932 | + write_exp_elt_type ($<tvec>3[i + 1]); | |
1933 | + write_exp_elt_longcst((LONGEST) $<ivec>3[0]); | |
1934 | + write_exp_elt_opcode (TYPE_INSTANCE); | |
1935 | + do_cleanups (typelist_cleanup); | |
1936 | + } | |
1937 | + ; | |
1938 | +*/ | |
1939 | + | |
1940 | rcurly : '}' | |
1941 | { $$ = end_arglist () - 1; } | |
1942 | ; | |
1943 | @@ -524,6 +562,15 @@ exp : INT | |
1944 | write_exp_elt_opcode (OP_LONG); } | |
1945 | ; | |
1946 | ||
1947 | +exp : CHAR | |
1948 | + { | |
1949 | + struct stoken_vector vec; | |
1950 | + vec.len = 1; | |
1951 | + vec.tokens = &$1; | |
1952 | + write_exp_string_vector ($1.type, &vec); | |
1953 | + } | |
1954 | + ; | |
1955 | + | |
1956 | exp : NAME_OR_INT | |
1957 | { YYSTYPE val; | |
1958 | parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val); | |
1959 | @@ -572,48 +619,64 @@ string_exp: | |
1960 | string. Note that we follow the | |
1961 | NUL-termination convention of the | |
1962 | lexer. */ | |
1963 | - $$.length = $1.length; | |
1964 | - $$.ptr = malloc ($1.length + 1); | |
1965 | - memcpy ($$.ptr, $1.ptr, $1.length + 1); | |
1966 | + struct typed_stoken *vec = XNEW (struct typed_stoken); | |
1967 | + $$.len = 1; | |
1968 | + $$.tokens = vec; | |
1969 | + | |
1970 | + vec->type = $1.type; | |
1971 | + vec->length = $1.length; | |
1972 | + vec->ptr = malloc ($1.length + 1); | |
1973 | + memcpy (vec->ptr, $1.ptr, $1.length + 1); | |
1974 | } | |
1975 | ||
1976 | | string_exp STRING | |
1977 | { | |
1978 | /* Note that we NUL-terminate here, but just | |
1979 | for convenience. */ | |
1980 | - struct stoken t; | |
1981 | - t.length = $1.length + $2.length; | |
1982 | - t.ptr = malloc (t.length + 1); | |
1983 | - memcpy (t.ptr, $1.ptr, $1.length); | |
1984 | - memcpy (t.ptr + $1.length, $2.ptr, $2.length + 1); | |
1985 | - free ($1.ptr); | |
1986 | - $$ = t; | |
1987 | + char *p; | |
1988 | + ++$$.len; | |
1989 | + $$.tokens = realloc ($$.tokens, | |
1990 | + $$.len * sizeof (struct typed_stoken)); | |
1991 | + | |
1992 | + p = malloc ($2.length + 1); | |
1993 | + memcpy (p, $2.ptr, $2.length + 1); | |
1994 | + | |
1995 | + $$.tokens[$$.len - 1].type = $2.type; | |
1996 | + $$.tokens[$$.len - 1].length = $2.length; | |
1997 | + $$.tokens[$$.len - 1].ptr = p; | |
1998 | } | |
1999 | ; | |
2000 | ||
2001 | exp : string_exp | |
2002 | - { /* C strings are converted into array constants with | |
2003 | - an explicit null byte added at the end. Thus | |
2004 | - the array upper bound is the string length. | |
2005 | - There is no such thing in C as a completely empty | |
2006 | - string. */ | |
2007 | - char *sp = $1.ptr; int count = $1.length; | |
2008 | - while (count-- > 0) | |
2009 | + { | |
2010 | + int i; | |
2011 | + enum c_string_type type = C_STRING; | |
2012 | + | |
2013 | + for (i = 0; i < $1.len; ++i) | |
2014 | { | |
2015 | - write_exp_elt_opcode (OP_LONG); | |
2016 | - write_exp_elt_type (parse_type->builtin_char); | |
2017 | - write_exp_elt_longcst ((LONGEST)(*sp++)); | |
2018 | - write_exp_elt_opcode (OP_LONG); | |
2019 | + switch ($1.tokens[i].type) | |
2020 | + { | |
2021 | + case C_STRING: | |
2022 | + break; | |
2023 | + case C_WIDE_STRING: | |
2024 | + case C_STRING_16: | |
2025 | + case C_STRING_32: | |
2026 | + if (type != C_STRING | |
2027 | + && type != $1.tokens[i].type) | |
2028 | + error ("Undefined string concatenation."); | |
2029 | + type = $1.tokens[i].type; | |
2030 | + break; | |
2031 | + default: | |
2032 | + /* internal error */ | |
2033 | + internal_error (__FILE__, __LINE__, | |
2034 | + "unrecognized type in string concatenation"); | |
2035 | + } | |
2036 | } | |
2037 | - write_exp_elt_opcode (OP_LONG); | |
2038 | - write_exp_elt_type (parse_type->builtin_char); | |
2039 | - write_exp_elt_longcst ((LONGEST)'\0'); | |
2040 | - write_exp_elt_opcode (OP_LONG); | |
2041 | - write_exp_elt_opcode (OP_ARRAY); | |
2042 | - write_exp_elt_longcst ((LONGEST) 0); | |
2043 | - write_exp_elt_longcst ((LONGEST) ($1.length)); | |
2044 | - write_exp_elt_opcode (OP_ARRAY); | |
2045 | - free ($1.ptr); | |
2046 | + | |
2047 | + write_exp_string_vector (type, &$1); | |
2048 | + for (i = 0; i < $1.len; ++i) | |
2049 | + free ($1.tokens[i].ptr); | |
2050 | + free ($1.tokens); | |
2051 | } | |
2052 | ; | |
2053 | ||
2054 | @@ -713,12 +776,13 @@ qualified_name: typebase COLONCOLON name | |
2055 | ; | |
2056 | ||
2057 | variable: qualified_name | |
2058 | + | COLONCOLON qualified_name | |
2059 | | COLONCOLON name | |
2060 | { | |
2061 | char *name = copy_name ($2); | |
2062 | struct symbol *sym; | |
2063 | struct minimal_symbol *msymbol; | |
2064 | - | |
2065 | + | |
2066 | sym = | |
2067 | lookup_symbol (name, (const struct block *) NULL, | |
2068 | VAR_DOMAIN, (int *) NULL); | |
2069 | @@ -856,7 +920,7 @@ array_mod: '[' ']' | |
2070 | func_mod: '(' ')' | |
2071 | { $$ = 0; } | |
2072 | | '(' nonempty_typelist ')' | |
2073 | - { free ($2); $$ = 0; } | |
2074 | + { do_cleanups (typelist_cleanup); $$ = 0; } | |
2075 | ; | |
2076 | ||
2077 | /* We used to try to recognize pointer to member types here, but | |
2078 | @@ -1057,12 +1121,15 @@ typename: TYPENAME | |
2079 | nonempty_typelist | |
2080 | : type | |
2081 | { $$ = (struct type **) malloc (sizeof (struct type *) * 2); | |
2082 | + typelist_cleanup = make_cleanup (free, $$); | |
2083 | $<ivec>$[0] = 1; /* Number of types in vector */ | |
2084 | $$[1] = $1; | |
2085 | } | |
2086 | | nonempty_typelist ',' type | |
2087 | { int len = sizeof (struct type *) * (++($<ivec>1[0]) + 1); | |
2088 | $$ = (struct type **) realloc ((char *) $1, len); | |
2089 | + discard_cleanups (typelist_cleanup); | |
2090 | + typelist_cleanup = make_cleanup (free, $$); | |
2091 | $$[$<ivec>$[0]] = $3; | |
2092 | } | |
2093 | ; | |
2094 | @@ -1361,6 +1428,263 @@ parse_number (p, len, parsed_float, putithere) | |
2095 | return INT; | |
2096 | } | |
2097 | ||
2098 | +/* Temporary obstack used for holding strings. */ | |
2099 | +static struct obstack tempbuf; | |
2100 | +static int tempbuf_init; | |
2101 | + | |
2102 | +/* Parse a C escape sequence. The initial backslash of the sequence | |
2103 | + is at (*PTR)[-1]. *PTR will be updated to point to just after the | |
2104 | + last character of the sequence. If OUTPUT is not NULL, the | |
2105 | + translated form of the escape sequence will be written there. If | |
2106 | + OUTPUT is NULL, no output is written and the call will only affect | |
2107 | + *PTR. If an escape sequence is expressed in target bytes, then the | |
2108 | + entire sequence will simply be copied to OUTPUT. Return 1 if any | |
2109 | + character was emitted, 0 otherwise. */ | |
2110 | + | |
2111 | +int | |
2112 | +c_parse_escape (char **ptr, struct obstack *output) | |
2113 | +{ | |
2114 | + char *tokptr = *ptr; | |
2115 | + int result = 1; | |
2116 | + | |
2117 | + /* Some escape sequences undergo character set conversion. Those we | |
2118 | + translate here. */ | |
2119 | + switch (*tokptr) | |
2120 | + { | |
2121 | + /* Hex escapes do not undergo character set conversion, so keep | |
2122 | + the escape sequence for later. */ | |
2123 | + case 'x': | |
2124 | + if (output) | |
2125 | + obstack_grow_str (output, "\\x"); | |
2126 | + ++tokptr; | |
2127 | + if (!isxdigit (*tokptr)) | |
2128 | + error (_("\\x escape without a following hex digit")); | |
2129 | + while (isxdigit (*tokptr)) | |
2130 | + { | |
2131 | + if (output) | |
2132 | + obstack_1grow (output, *tokptr); | |
2133 | + ++tokptr; | |
2134 | + } | |
2135 | + break; | |
2136 | + | |
2137 | + /* Octal escapes do not undergo character set conversion, so | |
2138 | + keep the escape sequence for later. */ | |
2139 | + case '0': | |
2140 | + case '1': | |
2141 | + case '2': | |
2142 | + case '3': | |
2143 | + case '4': | |
2144 | + case '5': | |
2145 | + case '6': | |
2146 | + case '7': | |
2147 | + if (output) | |
2148 | + obstack_grow_str (output, "\\"); | |
2149 | + while (isdigit (*tokptr) && *tokptr != '8' && *tokptr != '9') | |
2150 | + { | |
2151 | + if (output) | |
2152 | + obstack_1grow (output, *tokptr); | |
2153 | + ++tokptr; | |
2154 | + } | |
2155 | + break; | |
2156 | + | |
2157 | + /* We handle UCNs later. We could handle them here, but that | |
2158 | + would mean a spurious error in the case where the UCN could | |
2159 | + be converted to the target charset but not the host | |
2160 | + charset. */ | |
2161 | + case 'u': | |
2162 | + case 'U': | |
2163 | + { | |
2164 | + char c = *tokptr; | |
2165 | + int i, len = c == 'U' ? 8 : 4; | |
2166 | + if (output) | |
2167 | + { | |
2168 | + obstack_1grow (output, '\\'); | |
2169 | + obstack_1grow (output, *tokptr); | |
2170 | + } | |
2171 | + ++tokptr; | |
2172 | + if (!isxdigit (*tokptr)) | |
2173 | + error (_("\\%c escape without a following hex digit"), c); | |
2174 | + for (i = 0; i < len && isxdigit (*tokptr); ++i) | |
2175 | + { | |
2176 | + if (output) | |
2177 | + obstack_1grow (output, *tokptr); | |
2178 | + ++tokptr; | |
2179 | + } | |
2180 | + } | |
2181 | + break; | |
2182 | + | |
2183 | + /* We must pass backslash through so that it does not | |
2184 | + cause quoting during the second expansion. */ | |
2185 | + case '\\': | |
2186 | + if (output) | |
2187 | + obstack_grow_str (output, "\\\\"); | |
2188 | + ++tokptr; | |
2189 | + break; | |
2190 | + | |
2191 | + /* Escapes which undergo conversion. */ | |
2192 | + case 'a': | |
2193 | + if (output) | |
2194 | + obstack_1grow (output, '\a'); | |
2195 | + ++tokptr; | |
2196 | + break; | |
2197 | + case 'b': | |
2198 | + if (output) | |
2199 | + obstack_1grow (output, '\b'); | |
2200 | + ++tokptr; | |
2201 | + break; | |
2202 | + case 'f': | |
2203 | + if (output) | |
2204 | + obstack_1grow (output, '\f'); | |
2205 | + ++tokptr; | |
2206 | + break; | |
2207 | + case 'n': | |
2208 | + if (output) | |
2209 | + obstack_1grow (output, '\n'); | |
2210 | + ++tokptr; | |
2211 | + break; | |
2212 | + case 'r': | |
2213 | + if (output) | |
2214 | + obstack_1grow (output, '\r'); | |
2215 | + ++tokptr; | |
2216 | + break; | |
2217 | + case 't': | |
2218 | + if (output) | |
2219 | + obstack_1grow (output, '\t'); | |
2220 | + ++tokptr; | |
2221 | + break; | |
2222 | + case 'v': | |
2223 | + if (output) | |
2224 | + obstack_1grow (output, '\v'); | |
2225 | + ++tokptr; | |
2226 | + break; | |
2227 | + | |
2228 | + /* GCC extension. */ | |
2229 | + case 'e': | |
2230 | + if (output) | |
2231 | + obstack_1grow (output, HOST_ESCAPE_CHAR); | |
2232 | + ++tokptr; | |
2233 | + break; | |
2234 | + | |
2235 | + /* Backslash-newline expands to nothing at all. */ | |
2236 | + case '\n': | |
2237 | + ++tokptr; | |
2238 | + result = 0; | |
2239 | + break; | |
2240 | + | |
2241 | + /* A few escapes just expand to the character itself. */ | |
2242 | + case '\'': | |
2243 | + case '\"': | |
2244 | + case '?': | |
2245 | + /* GCC extensions. */ | |
2246 | + case '(': | |
2247 | + case '{': | |
2248 | + case '[': | |
2249 | + case '%': | |
2250 | + /* Unrecognized escapes turn into the character itself. */ | |
2251 | + default: | |
2252 | + if (output) | |
2253 | + obstack_1grow (output, *tokptr); | |
2254 | + ++tokptr; | |
2255 | + break; | |
2256 | + } | |
2257 | + *ptr = tokptr; | |
2258 | + return result; | |
2259 | +} | |
2260 | + | |
2261 | +/* Parse a string or character literal from TOKPTR. The string or | |
2262 | + character may be wide or unicode. *OUTPTR is set to just after the | |
2263 | + end of the literal in the input string. The resulting token is | |
2264 | + stored in VALUE. This returns a token value, either STRING or | |
2265 | + CHAR, depending on what was parsed. *HOST_CHARS is set to the | |
2266 | + number of host characters in the literal. */ | |
2267 | +static int | |
2268 | +parse_string_or_char (char *tokptr, char **outptr, struct typed_stoken *value, | |
2269 | + int *host_chars) | |
2270 | +{ | |
2271 | + int quote, i; | |
2272 | + enum c_string_type type; | |
2273 | + | |
2274 | + /* Build the gdb internal form of the input string in tempbuf. Note | |
2275 | + that the buffer is null byte terminated *only* for the | |
2276 | + convenience of debugging gdb itself and printing the buffer | |
2277 | + contents when the buffer contains no embedded nulls. Gdb does | |
2278 | + not depend upon the buffer being null byte terminated, it uses | |
2279 | + the length string instead. This allows gdb to handle C strings | |
2280 | + (as well as strings in other languages) with embedded null | |
2281 | + bytes */ | |
2282 | + | |
2283 | + if (!tempbuf_init) | |
2284 | + tempbuf_init = 1; | |
2285 | + else | |
2286 | + obstack_free (&tempbuf, NULL); | |
2287 | + obstack_init (&tempbuf); | |
2288 | + | |
2289 | + /* Record the string type. */ | |
2290 | + if (*tokptr == 'L') | |
2291 | + { | |
2292 | + type = C_WIDE_STRING; | |
2293 | + ++tokptr; | |
2294 | + } | |
2295 | + else if (*tokptr == 'u') | |
2296 | + { | |
2297 | + type = C_STRING_16; | |
2298 | + ++tokptr; | |
2299 | + } | |
2300 | + else if (*tokptr == 'U') | |
2301 | + { | |
2302 | + type = C_STRING_32; | |
2303 | + ++tokptr; | |
2304 | + } | |
2305 | + else | |
2306 | + type = C_STRING; | |
2307 | + | |
2308 | + /* Skip the quote. */ | |
2309 | + quote = *tokptr; | |
2310 | + if (quote == '\'') | |
2311 | + type |= C_CHAR; | |
2312 | + ++tokptr; | |
2313 | + | |
2314 | + *host_chars = 0; | |
2315 | + | |
2316 | + while (*tokptr) | |
2317 | + { | |
2318 | + char c = *tokptr; | |
2319 | + if (c == '\\') | |
2320 | + { | |
2321 | + ++tokptr; | |
2322 | + *host_chars += c_parse_escape (&tokptr, &tempbuf); | |
2323 | + } | |
2324 | + else if (c == quote) | |
2325 | + break; | |
2326 | + else | |
2327 | + { | |
2328 | + obstack_1grow (&tempbuf, c); | |
2329 | + ++tokptr; | |
2330 | + /* FIXME: this does the wrong thing with multi-byte host | |
2331 | + characters. We could use mbrlen here, but that would | |
2332 | + make "set host-charset" a bit less useful. */ | |
2333 | + ++*host_chars; | |
2334 | + } | |
2335 | + } | |
2336 | + | |
2337 | + if (*tokptr != quote) | |
2338 | + { | |
2339 | + if (quote == '"') | |
2340 | + error ("Unterminated string in expression."); | |
2341 | + else | |
2342 | + error ("Unmatched single quote."); | |
2343 | + } | |
2344 | + ++tokptr; | |
2345 | + | |
2346 | + value->type = type; | |
2347 | + value->ptr = obstack_base (&tempbuf); | |
2348 | + value->length = obstack_object_size (&tempbuf); | |
2349 | + | |
2350 | + *outptr = tokptr; | |
2351 | + | |
2352 | + return quote == '"' ? STRING : CHAR; | |
2353 | +} | |
2354 | + | |
2355 | struct token | |
2356 | { | |
2357 | char *operator; | |
2358 | @@ -1526,23 +1850,33 @@ static int last_was_structop; | |
2359 | static int | |
2360 | yylex () | |
2361 | { | |
2362 | + /* name_prefix stores the full qualification of a variable that is | |
2363 | + specified in the expression. It is used to eleminate confusion | |
2364 | + during lookup.*/ | |
2365 | + static char* name_prefix = NULL; | |
2366 | + static int name_prefix_len = 0; | |
2367 | + static int terminate_prefix = 0; | |
2368 | + | |
2369 | int c; | |
2370 | int namelen; | |
2371 | unsigned int i; | |
2372 | char *tokstart; | |
2373 | - char *tokptr; | |
2374 | - int tempbufindex; | |
2375 | - static char *tempbuf; | |
2376 | - static int tempbufsize; | |
2377 | - char * token_string = NULL; | |
2378 | - int class_prefix = 0; | |
2379 | int saw_structop = last_was_structop; | |
2380 | char *copy; | |
2381 | ||
2382 | last_was_structop = 0; | |
2383 | - | |
2384 | + | |
2385 | retry: | |
2386 | - | |
2387 | + | |
2388 | + if(terminate_prefix || | |
2389 | + lexptr != name_prefix + name_prefix_len // Some token was skiped so clear name_prefix | |
2390 | + ){ | |
2391 | + name_prefix = NULL; | |
2392 | + name_prefix_len = 0; | |
2393 | + } | |
2394 | + | |
2395 | + terminate_prefix = 1; | |
2396 | + | |
2397 | /* Check if this is a macro invocation that we need to expand. */ | |
2398 | if (! scanning_macro_expansion ()) | |
2399 | { | |
2400 | @@ -1570,10 +1904,19 @@ yylex () | |
2401 | for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) | |
2402 | if (strncmp (tokstart, tokentab2[i].operator, 2) == 0) | |
2403 | { | |
2404 | + | |
2405 | + if(tokentab2[i].token == COLONCOLON){ | |
2406 | + name_prefix_len += 2; | |
2407 | + terminate_prefix = 0; | |
2408 | + if(name_prefix == NULL){ | |
2409 | + name_prefix = lexptr; | |
2410 | + } | |
2411 | + } | |
2412 | lexptr += 2; | |
2413 | yylval.opcode = tokentab2[i].opcode; | |
2414 | if (in_parse_field && tokentab2[i].token == ARROW) | |
2415 | last_was_structop = 1; | |
2416 | + | |
2417 | return tokentab2[i].token; | |
2418 | } | |
2419 | ||
2420 | @@ -1602,51 +1945,13 @@ yylex () | |
2421 | return 0; | |
2422 | ||
2423 | case ' ': | |
2424 | + name_prefix_len++; | |
2425 | + terminate_prefix = 0; | |
2426 | case '\t': | |
2427 | case '\n': | |
2428 | lexptr++; | |
2429 | goto retry; | |
2430 | ||
2431 | - case '\'': | |
2432 | - /* We either have a character constant ('0' or '\177' for example) | |
2433 | - or we have a quoted symbol reference ('foo(int,int)' in C++ | |
2434 | - for example). */ | |
2435 | - lexptr++; | |
2436 | - c = *lexptr++; | |
2437 | - if (c == '\\') | |
2438 | - c = parse_escape (&lexptr); | |
2439 | - else if (c == '\'') | |
2440 | - error ("Empty character constant."); | |
2441 | - else if (! host_char_to_target (c, &c)) | |
2442 | - { | |
2443 | - int toklen = lexptr - tokstart + 1; | |
2444 | - char *tok = alloca (toklen + 1); | |
2445 | - memcpy (tok, tokstart, toklen); | |
2446 | - tok[toklen] = '\0'; | |
2447 | - error ("There is no character corresponding to %s in the target " | |
2448 | - "character set `%s'.", tok, target_charset ()); | |
2449 | - } | |
2450 | - | |
2451 | - yylval.typed_val_int.val = c; | |
2452 | - yylval.typed_val_int.type = parse_type->builtin_char; | |
2453 | - | |
2454 | - c = *lexptr++; | |
2455 | - if (c != '\'') | |
2456 | - { | |
2457 | - namelen = skip_quoted (tokstart) - tokstart; | |
2458 | - if (namelen > 2) | |
2459 | - { | |
2460 | - lexptr = tokstart + namelen; | |
2461 | - if (lexptr[-1] != '\'') | |
2462 | - error ("Unmatched single quote."); | |
2463 | - namelen -= 2; | |
2464 | - tokstart++; | |
2465 | - goto tryname; | |
2466 | - } | |
2467 | - error ("Invalid character constant."); | |
2468 | - } | |
2469 | - return INT; | |
2470 | - | |
2471 | case '(': | |
2472 | paren_depth++; | |
2473 | lexptr++; | |
2474 | @@ -1764,70 +2069,33 @@ yylex () | |
2475 | lexptr++; | |
2476 | return c; | |
2477 | ||
2478 | + case 'L': | |
2479 | + case 'u': | |
2480 | + case 'U': | |
2481 | + if (tokstart[1] != '"' && tokstart[1] != '\'') | |
2482 | + break; | |
2483 | + /* Fall through. */ | |
2484 | + case '\'': | |
2485 | case '"': | |
2486 | - | |
2487 | - /* Build the gdb internal form of the input string in tempbuf, | |
2488 | - translating any standard C escape forms seen. Note that the | |
2489 | - buffer is null byte terminated *only* for the convenience of | |
2490 | - debugging gdb itself and printing the buffer contents when | |
2491 | - the buffer contains no embedded nulls. Gdb does not depend | |
2492 | - upon the buffer being null byte terminated, it uses the length | |
2493 | - string instead. This allows gdb to handle C strings (as well | |
2494 | - as strings in other languages) with embedded null bytes */ | |
2495 | - | |
2496 | - tokptr = ++tokstart; | |
2497 | - tempbufindex = 0; | |
2498 | - | |
2499 | - do { | |
2500 | - char *char_start_pos = tokptr; | |
2501 | - | |
2502 | - /* Grow the static temp buffer if necessary, including allocating | |
2503 | - the first one on demand. */ | |
2504 | - if (tempbufindex + 1 >= tempbufsize) | |
2505 | - { | |
2506 | - tempbuf = (char *) realloc (tempbuf, tempbufsize += 64); | |
2507 | - } | |
2508 | - switch (*tokptr) | |
2509 | + { | |
2510 | + int host_len; | |
2511 | + int result = parse_string_or_char (tokstart, &lexptr, &yylval.tsval, | |
2512 | + &host_len); | |
2513 | + if (result == CHAR) | |
2514 | { | |
2515 | - case '\0': | |
2516 | - case '"': | |
2517 | - /* Do nothing, loop will terminate. */ | |
2518 | - break; | |
2519 | - case '\\': | |
2520 | - tokptr++; | |
2521 | - c = parse_escape (&tokptr); | |
2522 | - if (c == -1) | |
2523 | + if (host_len == 0) | |
2524 | + error ("Empty character constant."); | |
2525 | + else if (host_len > 2 && c == '\'') | |
2526 | { | |
2527 | - continue; | |
2528 | + ++tokstart; | |
2529 | + namelen = lexptr - tokstart - 1; | |
2530 | + goto tryname; | |
2531 | } | |
2532 | - tempbuf[tempbufindex++] = c; | |
2533 | - break; | |
2534 | - default: | |
2535 | - c = *tokptr++; | |
2536 | - if (! host_char_to_target (c, &c)) | |
2537 | - { | |
2538 | - int len = tokptr - char_start_pos; | |
2539 | - char *copy = alloca (len + 1); | |
2540 | - memcpy (copy, char_start_pos, len); | |
2541 | - copy[len] = '\0'; | |
2542 | - | |
2543 | - error ("There is no character corresponding to `%s' " | |
2544 | - "in the target character set `%s'.", | |
2545 | - copy, target_charset ()); | |
2546 | - } | |
2547 | - tempbuf[tempbufindex++] = c; | |
2548 | - break; | |
2549 | + else if (host_len > 1) | |
2550 | + error ("Invalid character constant."); | |
2551 | } | |
2552 | - } while ((*tokptr != '"') && (*tokptr != '\0')); | |
2553 | - if (*tokptr++ != '"') | |
2554 | - { | |
2555 | - error ("Unterminated string in expression."); | |
2556 | - } | |
2557 | - tempbuf[tempbufindex] = '\0'; /* See note above */ | |
2558 | - yylval.sval.ptr = tempbuf; | |
2559 | - yylval.sval.length = tempbufindex; | |
2560 | - lexptr = tokptr; | |
2561 | - return (STRING); | |
2562 | + return result; | |
2563 | + } | |
2564 | } | |
2565 | ||
2566 | if (!(c == '_' || c == '$' | |
2567 | @@ -1836,11 +2104,13 @@ yylex () | |
2568 | error ("Invalid character '%c' in expression.", c); | |
2569 | ||
2570 | /* It's a name. See how long it is. */ | |
2571 | + | |
2572 | namelen = 0; | |
2573 | for (c = tokstart[namelen]; | |
2574 | (c == '_' || c == '$' || (c >= '0' && c <= '9') | |
2575 | || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');) | |
2576 | { | |
2577 | + | |
2578 | /* Template parameter lists are part of the name. | |
2579 | FIXME: This mishandles `print $a<4&&$a>3'. */ | |
2580 | ||
2581 | @@ -1904,14 +2174,29 @@ yylex () | |
2582 | currently as names of types; NAME for other symbols. | |
2583 | The caller is not constrained to care about the distinction. */ | |
2584 | { | |
2585 | + char *tmp = copy; | |
2586 | struct symbol *sym; | |
2587 | int is_a_field_of_this = 0; | |
2588 | int hextype; | |
2589 | ||
2590 | - sym = lookup_symbol (copy, expression_context_block, | |
2591 | + if(name_prefix != NULL){ | |
2592 | + tmp = savestring (name_prefix, name_prefix_len+namelen); | |
2593 | + } | |
2594 | + | |
2595 | + sym = lookup_symbol (tmp, expression_context_block, | |
2596 | VAR_DOMAIN, | |
2597 | parse_language->la_language == language_cplus | |
2598 | ? &is_a_field_of_this : (int *) NULL); | |
2599 | + | |
2600 | + /* keep this name as prefix for the next name */ | |
2601 | + if(sym){ | |
2602 | + if(name_prefix == NULL){ | |
2603 | + name_prefix = tokstart; | |
2604 | + } | |
2605 | + name_prefix_len += namelen; | |
2606 | + terminate_prefix = 0; | |
2607 | + } | |
2608 | + | |
2609 | /* Call lookup_symtab, not lookup_partial_symtab, in case there are | |
2610 | no psymtabs (coff, xcoff, or some future change to blow away the | |
2611 | psymtabs once once symbols are read). */ | |
2612 | @@ -1970,6 +2255,7 @@ yylex () | |
2613 | yylval.ssym.is_a_field_of_this = is_a_field_of_this; | |
2614 | if (in_parse_field && *lexptr == '\0') | |
2615 | saw_name_at_eof = 1; | |
2616 | + | |
2617 | return NAME; | |
2618 | } | |
2619 | } | |
2620 | diff --git a/gdb/c-lang.c b/gdb/c-lang.c | |
2621 | index 8b5410f..188755b 100644 | |
2622 | --- a/gdb/c-lang.c | |
2623 | +++ b/gdb/c-lang.c | |
2624 | @@ -33,48 +33,304 @@ | |
2625 | #include "demangle.h" | |
2626 | #include "cp-abi.h" | |
2627 | #include "cp-support.h" | |
2628 | +#include "gdb_obstack.h" | |
2629 | +#include <ctype.h> | |
2630 | +#include <wchar.h> | |
2631 | +#include <wctype.h> | |
2632 | ||
2633 | extern void _initialize_c_language (void); | |
2634 | -static void c_emit_char (int c, struct ui_file * stream, int quoter); | |
2635 | + | |
2636 | +/* Given a C string type, STR_TYPE, return the corresponding target | |
2637 | + character set name. */ | |
2638 | + | |
2639 | +static const char * | |
2640 | +charset_for_string_type (enum c_string_type str_type) | |
2641 | +{ | |
2642 | + switch (str_type & ~C_CHAR) | |
2643 | + { | |
2644 | + case C_STRING: | |
2645 | + return target_charset (); | |
2646 | + case C_WIDE_STRING: | |
2647 | + return target_wide_charset (); | |
2648 | + case C_STRING_16: | |
2649 | + /* FIXME: UCS-2 is not always correct. */ | |
2650 | + if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) | |
2651 | + return "UCS-2BE"; | |
2652 | + else | |
2653 | + return "UCS-2LE"; | |
2654 | + case C_STRING_32: | |
2655 | + /* FIXME: UCS-4 is not always correct. */ | |
2656 | + if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) | |
2657 | + return "UCS-4BE"; | |
2658 | + else | |
2659 | + return "UCS-4LE"; | |
2660 | + } | |
2661 | + internal_error (__FILE__, __LINE__, "unhandled c_string_type"); | |
2662 | +} | |
2663 | + | |
2664 | +/* Classify ELTTYPE according to what kind of character it is. Return | |
2665 | + the enum constant representing the character type. Also set | |
2666 | + *ENCODING to the name of the character set to use when converting | |
2667 | + characters of this type to the host character set. */ | |
2668 | + | |
2669 | +static enum c_string_type | |
2670 | +classify_type (struct type *elttype, const char **encoding) | |
2671 | +{ | |
2672 | + struct type *saved_type; | |
2673 | + enum c_string_type result; | |
2674 | + | |
2675 | + /* We do one or two passes -- one on ELTTYPE, and then maybe a | |
2676 | + second one on a typedef target. */ | |
2677 | + do | |
2678 | + { | |
2679 | + char *name = TYPE_NAME (elttype); | |
2680 | + | |
2681 | + if (TYPE_CODE (elttype) == TYPE_CODE_CHAR || !name) | |
2682 | + { | |
2683 | + result = C_CHAR; | |
2684 | + goto done; | |
2685 | + } | |
2686 | + | |
2687 | + if (!strcmp (name, "wchar_t")) | |
2688 | + { | |
2689 | + result = C_WIDE_CHAR; | |
2690 | + goto done; | |
2691 | + } | |
2692 | + | |
2693 | + if (!strcmp (name, "char16_t")) | |
2694 | + { | |
2695 | + result = C_CHAR_16; | |
2696 | + goto done; | |
2697 | + } | |
2698 | + | |
2699 | + if (!strcmp (name, "char32_t")) | |
2700 | + { | |
2701 | + result = C_CHAR_32; | |
2702 | + goto done; | |
2703 | + } | |
2704 | + | |
2705 | + saved_type = elttype; | |
2706 | + CHECK_TYPEDEF (elttype); | |
2707 | + } | |
2708 | + while (elttype != saved_type); | |
2709 | + | |
2710 | + /* Punt. */ | |
2711 | + result = C_CHAR; | |
2712 | + | |
2713 | + done: | |
2714 | + *encoding = charset_for_string_type (result); | |
2715 | + return result; | |
2716 | +} | |
2717 | + | |
2718 | +/* Return true if print_wchar can display W without resorting to a | |
2719 | + numeric escape, false otherwise. */ | |
2720 | + | |
2721 | +static int | |
2722 | +wchar_printable (wchar_t w) | |
2723 | +{ | |
2724 | + return (iswprint (w) | |
2725 | + || w == L'\a' || w == L'\b' || w == L'\f' || w == L'\n' | |
2726 | + || w == L'\r' || w == L'\t' || w == L'\v'); | |
2727 | +} | |
2728 | + | |
2729 | +/* A helper function that converts the contents of STRING to wide | |
2730 | + characters and then appends them to OUTPUT. */ | |
2731 | + | |
2732 | +static void | |
2733 | +append_string_as_wide (const char *string, struct obstack *output) | |
2734 | +{ | |
2735 | + for (; *string; ++string) | |
2736 | + { | |
2737 | + wchar_t w = btowc (*string); | |
2738 | + obstack_grow (output, &w, sizeof (wchar_t)); | |
2739 | + } | |
2740 | +} | |
2741 | + | |
2742 | +/* Print a wide character W to OUTPUT. ORIG is a pointer to the | |
2743 | + original (target) bytes representing the character, ORIG_LEN is the | |
2744 | + number of valid bytes. WIDTH is the number of bytes in a base | |
2745 | + characters of the type. OUTPUT is an obstack to which wide | |
2746 | + characters are emitted. QUOTER is a (narrow) character indicating | |
2747 | + the style of quotes surrounding the character to be printed. | |
2748 | + NEED_ESCAPE is an in/out flag which is used to track numeric | |
2749 | + escapes across calls. */ | |
2750 | + | |
2751 | +static void | |
2752 | +print_wchar (wint_t w, const gdb_byte *orig, int orig_len, | |
2753 | + int width, struct obstack *output, int quoter, | |
2754 | + int *need_escapep) | |
2755 | +{ | |
2756 | + int need_escape = *need_escapep; | |
2757 | + *need_escapep = 0; | |
2758 | + if (iswprint (w) && (!need_escape || (!iswdigit (w) | |
2759 | + && w != L'8' | |
2760 | + && w != L'9'))) | |
2761 | + { | |
2762 | + if (w == btowc (quoter) || w == L'\\') | |
2763 | + obstack_grow_wstr (output, L"\\"); | |
2764 | + obstack_grow (output, &w, sizeof (wchar_t)); | |
2765 | + } | |
2766 | + else | |
2767 | + { | |
2768 | + switch (w) | |
2769 | + { | |
2770 | + case L'\a': | |
2771 | + obstack_grow_wstr (output, L"\\a"); | |
2772 | + break; | |
2773 | + case L'\b': | |
2774 | + obstack_grow_wstr (output, L"\\b"); | |
2775 | + break; | |
2776 | + case L'\f': | |
2777 | + obstack_grow_wstr (output, L"\\f"); | |
2778 | + break; | |
2779 | + case L'\n': | |
2780 | + obstack_grow_wstr (output, L"\\n"); | |
2781 | + break; | |
2782 | + case L'\r': | |
2783 | + obstack_grow_wstr (output, L"\\r"); | |
2784 | + break; | |
2785 | + case L'\t': | |
2786 | + obstack_grow_wstr (output, L"\\t"); | |
2787 | + break; | |
2788 | + case L'\v': | |
2789 | + obstack_grow_wstr (output, L"\\v"); | |
2790 | + break; | |
2791 | + default: | |
2792 | + { | |
2793 | + int i; | |
2794 | + | |
2795 | + for (i = 0; i + width <= orig_len; i += width) | |
2796 | + { | |
2797 | + char octal[30]; | |
2798 | + ULONGEST value = extract_unsigned_integer (&orig[i], width); | |
2799 | + sprintf (octal, "\\%lo", (long) value); | |
2800 | + append_string_as_wide (octal, output); | |
2801 | + } | |
2802 | + /* If we somehow have extra bytes, print them now. */ | |
2803 | + while (i < orig_len) | |
2804 | + { | |
2805 | + char octal[5]; | |
2806 | + sprintf (octal, "\\%.3o", orig[i] & 0xff); | |
2807 | + append_string_as_wide (octal, output); | |
2808 | + ++i; | |
2809 | + } | |
2810 | + | |
2811 | + *need_escapep = 1; | |
2812 | + } | |
2813 | + break; | |
2814 | + } | |
2815 | + } | |
2816 | +} | |
2817 | ||
2818 | /* Print the character C on STREAM as part of the contents of a literal | |
2819 | string whose delimiter is QUOTER. Note that that format for printing | |
2820 | characters and strings is language specific. */ | |
2821 | ||
2822 | static void | |
2823 | -c_emit_char (int c, struct ui_file *stream, int quoter) | |
2824 | +c_emit_char (int c, struct type *type, struct ui_file *stream, int quoter) | |
2825 | { | |
2826 | - const char *escape; | |
2827 | - int host_char; | |
2828 | + struct obstack wchar_buf, output; | |
2829 | + struct cleanup *cleanups; | |
2830 | + const char *encoding; | |
2831 | + gdb_byte *buf; | |
2832 | + struct wchar_iterator *iter; | |
2833 | + int need_escape = 0; | |
2834 | ||
2835 | - c &= 0xFF; /* Avoid sign bit follies */ | |
2836 | + classify_type (type, &encoding); | |
2837 | ||
2838 | - escape = c_target_char_has_backslash_escape (c); | |
2839 | - if (escape) | |
2840 | - { | |
2841 | - if (quoter == '"' && strcmp (escape, "0") == 0) | |
2842 | - /* Print nulls embedded in double quoted strings as \000 to | |
2843 | - prevent ambiguity. */ | |
2844 | - fprintf_filtered (stream, "\\000"); | |
2845 | - else | |
2846 | - fprintf_filtered (stream, "\\%s", escape); | |
2847 | - } | |
2848 | - else if (target_char_to_host (c, &host_char) | |
2849 | - && host_char_print_literally (host_char)) | |
2850 | + buf = alloca (TYPE_LENGTH (type)); | |
2851 | + pack_long (buf, type, c); | |
2852 | + | |
2853 | + iter = make_wchar_iterator (buf, TYPE_LENGTH (type), encoding, | |
2854 | + TYPE_LENGTH (type)); | |
2855 | + cleanups = make_cleanup_wchar_iterator (iter); | |
2856 | + | |
2857 | + /* This holds the printable form of the wchar_t data. */ | |
2858 | + obstack_init (&wchar_buf); | |
2859 | + make_cleanup_obstack_free (&wchar_buf); | |
2860 | + | |
2861 | + while (1) | |
2862 | { | |
2863 | - if (host_char == '\\' || host_char == quoter) | |
2864 | - fputs_filtered ("\\", stream); | |
2865 | - fprintf_filtered (stream, "%c", host_char); | |
2866 | + int num_chars; | |
2867 | + wchar_t *chars; | |
2868 | + const gdb_byte *buf; | |
2869 | + size_t buflen; | |
2870 | + int print_escape = 1; | |
2871 | + enum wchar_iterate_result result; | |
2872 | + | |
2873 | + num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen); | |
2874 | + if (num_chars < 0) | |
2875 | + break; | |
2876 | + if (num_chars > 0) | |
2877 | + { | |
2878 | + /* If all characters are printable, print them. Otherwise, | |
2879 | + we're going to have to print an escape sequence. We | |
2880 | + check all characters because we want to print the target | |
2881 | + bytes in the escape sequence, and we don't know character | |
2882 | + boundaries there. */ | |
2883 | + int i; | |
2884 | + | |
2885 | + print_escape = 0; | |
2886 | + for (i = 0; i < num_chars; ++i) | |
2887 | + if (!wchar_printable (chars[i])) | |
2888 | + { | |
2889 | + print_escape = 1; | |
2890 | + break; | |
2891 | + } | |
2892 | + | |
2893 | + if (!print_escape) | |
2894 | + { | |
2895 | + for (i = 0; i < num_chars; ++i) | |
2896 | + print_wchar (chars[i], buf, buflen, TYPE_LENGTH (type), | |
2897 | + &wchar_buf, quoter, &need_escape); | |
2898 | + } | |
2899 | + } | |
2900 | + | |
2901 | + /* This handles the NUM_CHARS == 0 case as well. */ | |
2902 | + if (print_escape) | |
2903 | + print_wchar (WEOF, buf, buflen, TYPE_LENGTH (type), &wchar_buf, quoter, | |
2904 | + &need_escape); | |
2905 | } | |
2906 | - else | |
2907 | - fprintf_filtered (stream, "\\%.3o", (unsigned int) c); | |
2908 | + | |
2909 | + /* The output in the host encoding. */ | |
2910 | + obstack_init (&output); | |
2911 | + make_cleanup_obstack_free (&output); | |
2912 | + | |
2913 | + convert_between_encodings ("wchar_t", host_charset (), | |
2914 | + obstack_base (&wchar_buf), | |
2915 | + obstack_object_size (&wchar_buf), | |
2916 | + 1, &output, translit_char); | |
2917 | + obstack_1grow (&output, '\0'); | |
2918 | + | |
2919 | + fputs_filtered (obstack_base (&output), stream); | |
2920 | + | |
2921 | + do_cleanups (cleanups); | |
2922 | } | |
2923 | ||
2924 | void | |
2925 | -c_printchar (int c, struct ui_file *stream) | |
2926 | +c_printchar (int c, struct type *type, struct ui_file *stream) | |
2927 | { | |
2928 | + enum c_string_type str_type; | |
2929 | + const char *encoding; | |
2930 | + | |
2931 | + str_type = classify_type (type, &encoding); | |
2932 | + switch (str_type) | |
2933 | + { | |
2934 | + case C_CHAR: | |
2935 | + break; | |
2936 | + case C_WIDE_CHAR: | |
2937 | + fputc_filtered ('L', stream); | |
2938 | + break; | |
2939 | + case C_CHAR_16: | |
2940 | + fputc_filtered ('u', stream); | |
2941 | + break; | |
2942 | + case C_CHAR_32: | |
2943 | + fputc_filtered ('U', stream); | |
2944 | + break; | |
2945 | + } | |
2946 | + | |
2947 | fputc_filtered ('\'', stream); | |
2948 | - LA_EMIT_CHAR (c, stream, '\''); | |
2949 | + LA_EMIT_CHAR (c, type, stream, '\''); | |
2950 | fputc_filtered ('\'', stream); | |
2951 | } | |
2952 | ||
2953 | @@ -85,87 +341,206 @@ c_printchar (int c, struct ui_file *stream) | |
2954 | printing LENGTH characters, or if FORCE_ELLIPSES. */ | |
2955 | ||
2956 | void | |
2957 | -c_printstr (struct ui_file *stream, const gdb_byte *string, | |
2958 | - unsigned int length, int width, int force_ellipses, | |
2959 | +c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, | |
2960 | + unsigned int length, int force_ellipses, | |
2961 | const struct value_print_options *options) | |
2962 | { | |
2963 | unsigned int i; | |
2964 | unsigned int things_printed = 0; | |
2965 | int in_quotes = 0; | |
2966 | int need_comma = 0; | |
2967 | + int width = TYPE_LENGTH (type); | |
2968 | + struct obstack wchar_buf, output; | |
2969 | + struct cleanup *cleanup; | |
2970 | + enum c_string_type str_type; | |
2971 | + const char *encoding; | |
2972 | + struct wchar_iterator *iter; | |
2973 | + int finished = 0; | |
2974 | + int need_escape = 0; | |
2975 | ||
2976 | /* If the string was not truncated due to `set print elements', and | |
2977 | the last byte of it is a null, we don't print that, in traditional C | |
2978 | style. */ | |
2979 | if (!force_ellipses | |
2980 | && length > 0 | |
2981 | - && (extract_unsigned_integer (string + (length - 1) * width, width) | |
2982 | - == '\0')) | |
2983 | + && (extract_unsigned_integer (string + (length - 1) * width, width) == 0)) | |
2984 | length--; | |
2985 | ||
2986 | + str_type = classify_type (type, &encoding) & ~C_CHAR; | |
2987 | + switch (str_type) | |
2988 | + { | |
2989 | + case C_STRING: | |
2990 | + break; | |
2991 | + case C_WIDE_STRING: | |
2992 | + fputs_filtered ("L", stream); | |
2993 | + break; | |
2994 | + case C_STRING_16: | |
2995 | + fputs_filtered ("u", stream); | |
2996 | + break; | |
2997 | + case C_STRING_32: | |
2998 | + fputs_filtered ("U", stream); | |
2999 | + break; | |
3000 | + } | |
3001 | + | |
3002 | if (length == 0) | |
3003 | { | |
3004 | fputs_filtered ("\"\"", stream); | |
3005 | return; | |
3006 | } | |
3007 | ||
3008 | - for (i = 0; i < length && things_printed < options->print_max; ++i) | |
3009 | + if (length == -1) | |
3010 | + { | |
3011 | + unsigned long current_char = 1; | |
3012 | + for (i = 0; current_char; ++i) | |
3013 | + { | |
3014 | + QUIT; | |
3015 | + current_char = extract_unsigned_integer (string + i * width, width); | |
3016 | + } | |
3017 | + length = i; | |
3018 | + } | |
3019 | + | |
3020 | + /* Arrange to iterate over the characters, in wchar_t form. */ | |
3021 | + iter = make_wchar_iterator (string, length * width, encoding, width); | |
3022 | + cleanup = make_cleanup_wchar_iterator (iter); | |
3023 | + | |
3024 | + /* WCHAR_BUF is the obstack we use to represent the string in | |
3025 | + wchar_t form. */ | |
3026 | + obstack_init (&wchar_buf); | |
3027 | + make_cleanup_obstack_free (&wchar_buf); | |
3028 | + | |
3029 | + while (!finished && things_printed < options->print_max) | |
3030 | { | |
3031 | - /* Position of the character we are examining | |
3032 | - to see whether it is repeated. */ | |
3033 | - unsigned int rep1; | |
3034 | - /* Number of repetitions we have detected so far. */ | |
3035 | - unsigned int reps; | |
3036 | - unsigned long current_char; | |
3037 | + int num_chars; | |
3038 | + enum wchar_iterate_result result; | |
3039 | + wchar_t *chars; | |
3040 | + const gdb_byte *buf; | |
3041 | + size_t buflen; | |
3042 | ||
3043 | QUIT; | |
3044 | ||
3045 | if (need_comma) | |
3046 | { | |
3047 | - fputs_filtered (", ", stream); | |
3048 | + obstack_grow_wstr (&wchar_buf, L", "); | |
3049 | need_comma = 0; | |
3050 | } | |
3051 | ||
3052 | - current_char = extract_unsigned_integer (string + i * width, width); | |
3053 | + num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen); | |
3054 | + /* We only look at repetitions when we were able to convert a | |
3055 | + single character in isolation. This makes the code simpler | |
3056 | + and probably does the sensible thing in the majority of | |
3057 | + cases. */ | |
3058 | + while (num_chars == 1) | |
3059 | + { | |
3060 | + /* Count the number of repetitions. */ | |
3061 | + unsigned int reps = 0; | |
3062 | + wchar_t current_char = chars[0]; | |
3063 | + const gdb_byte *orig_buf = buf; | |
3064 | + int orig_len = buflen; | |
3065 | ||
3066 | - rep1 = i + 1; | |
3067 | - reps = 1; | |
3068 | - while (rep1 < length | |
3069 | - && extract_unsigned_integer (string + rep1 * width, width) | |
3070 | - == current_char) | |
3071 | + if (need_comma) | |
3072 | + { | |
3073 | + obstack_grow_wstr (&wchar_buf, L", "); | |
3074 | + need_comma = 0; | |
3075 | + } | |
3076 | + | |
3077 | + while (num_chars == 1 && current_char == chars[0]) | |
3078 | + { | |
3079 | + num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen); | |
3080 | + ++reps; | |
3081 | + } | |
3082 | + | |
3083 | + /* Emit CURRENT_CHAR according to the repetition count and | |
3084 | + options. */ | |
3085 | + if (reps > options->repeat_count_threshold) | |
3086 | + { | |
3087 | + if (in_quotes) | |
3088 | + { | |
3089 | + if (options->inspect_it) | |
3090 | + obstack_grow_wstr (&wchar_buf, L"\\\", "); | |
3091 | + else | |
3092 | + obstack_grow_wstr (&wchar_buf, L"\", "); | |
3093 | + in_quotes = 0; | |
3094 | + } | |
3095 | + obstack_grow_wstr (&wchar_buf, L"'"); | |
3096 | + need_escape = 0; | |
3097 | + print_wchar (current_char, orig_buf, orig_len, width, | |
3098 | + &wchar_buf, '\'', &need_escape); | |
3099 | + obstack_grow_wstr (&wchar_buf, L"'"); | |
3100 | + { | |
3101 | + /* Painful gyrations. */ | |
3102 | + int j; | |
3103 | + char *s = xstrprintf (_(" <repeats %u times>"), reps); | |
3104 | + for (j = 0; s[j]; ++j) | |
3105 | + { | |
3106 | + wchar_t w = btowc (s[j]); | |
3107 | + obstack_grow (&wchar_buf, &w, sizeof (wchar_t)); | |
3108 | + } | |
3109 | + xfree (s); | |
3110 | + } | |
3111 | + things_printed += options->repeat_count_threshold; | |
3112 | + need_comma = 1; | |
3113 | + } | |
3114 | + else | |
3115 | + { | |
3116 | + /* Saw the character one or more times, but fewer than | |
3117 | + the repetition threshold. */ | |
3118 | + if (!in_quotes) | |
3119 | + { | |
3120 | + if (options->inspect_it) | |
3121 | + obstack_grow_wstr (&wchar_buf, L"\\\""); | |
3122 | + else | |
3123 | + obstack_grow_wstr (&wchar_buf, L"\""); | |
3124 | + in_quotes = 1; | |
3125 | + need_escape = 0; | |
3126 | + } | |
3127 | + | |
3128 | + while (reps-- > 0) | |
3129 | + { | |
3130 | + print_wchar (current_char, orig_buf, orig_len, width, | |
3131 | + &wchar_buf, '"', &need_escape); | |
3132 | + ++things_printed; | |
3133 | + } | |
3134 | + } | |
3135 | + } | |
3136 | + | |
3137 | + /* NUM_CHARS and the other outputs from wchar_iterate are valid | |
3138 | + here regardless of which branch was taken above. */ | |
3139 | + if (num_chars < 0) | |
3140 | { | |
3141 | - ++rep1; | |
3142 | - ++reps; | |
3143 | + /* Hit EOF. */ | |
3144 | + finished = 1; | |
3145 | + break; | |
3146 | } | |
3147 | ||
3148 | - if (reps > options->repeat_count_threshold) | |
3149 | + switch (result) | |
3150 | { | |
3151 | - if (in_quotes) | |
3152 | + case wchar_iterate_invalid: | |
3153 | + if (!in_quotes) | |
3154 | { | |
3155 | if (options->inspect_it) | |
3156 | - fputs_filtered ("\\\", ", stream); | |
3157 | + obstack_grow_wstr (&wchar_buf, L"\\\""); | |
3158 | else | |
3159 | - fputs_filtered ("\", ", stream); | |
3160 | - in_quotes = 0; | |
3161 | + obstack_grow_wstr (&wchar_buf, L"\""); | |
3162 | + in_quotes = 1; | |
3163 | } | |
3164 | - LA_PRINT_CHAR (current_char, stream); | |
3165 | - fprintf_filtered (stream, _(" <repeats %u times>"), reps); | |
3166 | - i = rep1 - 1; | |
3167 | - things_printed += options->repeat_count_threshold; | |
3168 | - need_comma = 1; | |
3169 | - } | |
3170 | - else | |
3171 | - { | |
3172 | - if (!in_quotes) | |
3173 | + need_escape = 0; | |
3174 | + print_wchar (WEOF, buf, buflen, width, &wchar_buf, '"', &need_escape); | |
3175 | + break; | |
3176 | + | |
3177 | + case wchar_iterate_incomplete: | |
3178 | + if (in_quotes) | |
3179 | { | |
3180 | if (options->inspect_it) | |
3181 | - fputs_filtered ("\\\"", stream); | |
3182 | + obstack_grow_wstr (&wchar_buf, L"\\\","); | |
3183 | else | |
3184 | - fputs_filtered ("\"", stream); | |
3185 | - in_quotes = 1; | |
3186 | + obstack_grow_wstr (&wchar_buf, L"\","); | |
3187 | + in_quotes = 0; | |
3188 | } | |
3189 | - LA_EMIT_CHAR (current_char, stream, '"'); | |
3190 | - ++things_printed; | |
3191 | + obstack_grow_wstr (&wchar_buf, L" <incomplete sequence "); | |
3192 | + print_wchar (WEOF, buf, buflen, width, &wchar_buf, 0, &need_escape); | |
3193 | + obstack_grow_wstr (&wchar_buf, L">"); | |
3194 | + finished = 1; | |
3195 | + break; | |
3196 | } | |
3197 | } | |
3198 | ||
3199 | @@ -173,13 +548,27 @@ c_printstr (struct ui_file *stream, const gdb_byte *string, | |
3200 | if (in_quotes) | |
3201 | { | |
3202 | if (options->inspect_it) | |
3203 | - fputs_filtered ("\\\"", stream); | |
3204 | + obstack_grow_wstr (&wchar_buf, L"\\\""); | |
3205 | else | |
3206 | - fputs_filtered ("\"", stream); | |
3207 | + obstack_grow_wstr (&wchar_buf, L"\""); | |
3208 | } | |
3209 | ||
3210 | - if (force_ellipses || i < length) | |
3211 | - fputs_filtered ("...", stream); | |
3212 | + if (force_ellipses || !finished) | |
3213 | + obstack_grow_wstr (&wchar_buf, L"..."); | |
3214 | + | |
3215 | + /* OUTPUT is where we collect `char's for printing. */ | |
3216 | + obstack_init (&output); | |
3217 | + make_cleanup_obstack_free (&output); | |
3218 | + | |
3219 | + convert_between_encodings ("wchar_t", host_charset (), | |
3220 | + obstack_base (&wchar_buf), | |
3221 | + obstack_object_size (&wchar_buf), | |
3222 | + 1, &output, translit_char); | |
3223 | + obstack_1grow (&output, '\0'); | |
3224 | + | |
3225 | + fputs_filtered (obstack_base (&output), stream); | |
3226 | + | |
3227 | + do_cleanups (cleanup); | |
3228 | } | |
3229 | ||
3230 | /* Obtain a C string from the inferior storing it in a newly allocated | |
3231 | @@ -298,7 +687,285 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length, | |
3232 | } | |
3233 | ||
3234 | \f | |
3235 | -/* Preprocessing and parsing C and C++ expressions. */ | |
3236 | +/* Evaluating C and C++ expressions. */ | |
3237 | + | |
3238 | +/* Convert a UCN. The digits of the UCN start at P and extend no | |
3239 | + farther than LIMIT. DEST_CHARSET is the name of the character set | |
3240 | + into which the UCN should be converted. The results are written to | |
3241 | + OUTPUT. LENGTH is the maximum length of the UCN, either 4 or 8. | |
3242 | + Returns a pointer to just after the final digit of the UCN. */ | |
3243 | + | |
3244 | +static char * | |
3245 | +convert_ucn (char *p, char *limit, const char *dest_charset, | |
3246 | + struct obstack *output, int length) | |
3247 | +{ | |
3248 | + unsigned long result = 0; | |
3249 | + gdb_byte data[4]; | |
3250 | + int i; | |
3251 | + | |
3252 | + for (i = 0; i < length && p < limit && isxdigit (*p); ++i, ++p) | |
3253 | + result = (result << 4) + host_hex_value (*p); | |
3254 | + | |
3255 | + for (i = 3; i >= 0; --i) | |
3256 | + { | |
3257 | + data[i] = result & 0xff; | |
3258 | + result >>= 8; | |
3259 | + } | |
3260 | + | |
3261 | + convert_between_encodings ("UCS-4BE", dest_charset, data, 4, 4, output, | |
3262 | + translit_none); | |
3263 | + | |
3264 | + return p; | |
3265 | +} | |
3266 | + | |
3267 | +/* Emit a character, VALUE, which was specified numerically, to | |
3268 | + OUTPUT. TYPE is the target character type. */ | |
3269 | + | |
3270 | +static void | |
3271 | +emit_numeric_character (struct type *type, unsigned long value, | |
3272 | + struct obstack *output) | |
3273 | +{ | |
3274 | + gdb_byte *buffer; | |
3275 | + | |
3276 | + buffer = alloca (TYPE_LENGTH (type)); | |
3277 | + pack_long (buffer, type, value); | |
3278 | + obstack_grow (output, buffer, TYPE_LENGTH (type)); | |
3279 | +} | |
3280 | + | |
3281 | +/* Convert an octal escape sequence. TYPE is the target character | |
3282 | + type. The digits of the escape sequence begin at P and extend no | |
3283 | + farther than LIMIT. The result is written to OUTPUT. Returns a | |
3284 | + pointer to just after the final digit of the escape sequence. */ | |
3285 | + | |
3286 | +static char * | |
3287 | +convert_octal (struct type *type, char *p, char *limit, struct obstack *output) | |
3288 | +{ | |
3289 | + unsigned long value = 0; | |
3290 | + | |
3291 | + while (p < limit && isdigit (*p) && *p != '8' && *p != '9') | |
3292 | + { | |
3293 | + value = 8 * value + host_hex_value (*p); | |
3294 | + ++p; | |
3295 | + } | |
3296 | + | |
3297 | + emit_numeric_character (type, value, output); | |
3298 | + | |
3299 | + return p; | |
3300 | +} | |
3301 | + | |
3302 | +/* Convert a hex escape sequence. TYPE is the target character type. | |
3303 | + The digits of the escape sequence begin at P and extend no farther | |
3304 | + than LIMIT. The result is written to OUTPUT. Returns a pointer to | |
3305 | + just after the final digit of the escape sequence. */ | |
3306 | + | |
3307 | +static char * | |
3308 | +convert_hex (struct type *type, char *p, char *limit, struct obstack *output) | |
3309 | +{ | |
3310 | + unsigned long value = 0; | |
3311 | + | |
3312 | + while (p < limit && isxdigit (*p)) | |
3313 | + { | |
3314 | + value = 16 * value + host_hex_value (*p); | |
3315 | + ++p; | |
3316 | + } | |
3317 | + | |
3318 | + emit_numeric_character (type, value, output); | |
3319 | + | |
3320 | + return p; | |
3321 | +} | |
3322 | + | |
3323 | +#define ADVANCE \ | |
3324 | + do { \ | |
3325 | + ++p; \ | |
3326 | + if (p == limit) \ | |
3327 | + error (_("Malformed escape sequence")); \ | |
3328 | + } while (0) | |
3329 | + | |
3330 | +/* Convert an escape sequence to a target format. TYPE is the target | |
3331 | + character type to use, and DEST_CHARSET is the name of the target | |
3332 | + character set. The backslash of the escape sequence is at *P, and | |
3333 | + the escape sequence will not extend past LIMIT. The results are | |
3334 | + written to OUTPUT. Returns a pointer to just past the final | |
3335 | + character of the escape sequence. */ | |
3336 | + | |
3337 | +static char * | |
3338 | +convert_escape (struct type *type, const char *dest_charset, | |
3339 | + char *p, char *limit, struct obstack *output) | |
3340 | +{ | |
3341 | + /* Skip the backslash. */ | |
3342 | + ADVANCE; | |
3343 | + | |
3344 | + switch (*p) | |
3345 | + { | |
3346 | + case '\\': | |
3347 | + obstack_1grow (output, '\\'); | |
3348 | + ++p; | |
3349 | + break; | |
3350 | + | |
3351 | + case 'x': | |
3352 | + ADVANCE; | |
3353 | + if (!isxdigit (*p)) | |
3354 | + error (_("\\x used with no following hex digits.")); | |
3355 | + p = convert_hex (type, p, limit, output); | |
3356 | + break; | |
3357 | + | |
3358 | + case '0': | |
3359 | + case '1': | |
3360 | + case '2': | |
3361 | + case '3': | |
3362 | + case '4': | |
3363 | + case '5': | |
3364 | + case '6': | |
3365 | + case '7': | |
3366 | + p = convert_octal (type, p, limit, output); | |
3367 | + break; | |
3368 | + | |
3369 | + case 'u': | |
3370 | + case 'U': | |
3371 | + { | |
3372 | + int length = *p == 'u' ? 4 : 8; | |
3373 | + ADVANCE; | |
3374 | + if (!isxdigit (*p)) | |
3375 | + error (_("\\u used with no following hex digits")); | |
3376 | + p = convert_ucn (p, limit, dest_charset, output, length); | |
3377 | + } | |
3378 | + } | |
3379 | + | |
3380 | + return p; | |
3381 | +} | |
3382 | + | |
3383 | +/* Given a single string from a (C-specific) OP_STRING list, convert | |
3384 | + it to a target string, handling escape sequences specially. The | |
3385 | + output is written to OUTPUT. DATA is the input string, which has | |
3386 | + length LEN. DEST_CHARSET is the name of the target character set, | |
3387 | + and TYPE is the type of target character to use. */ | |
3388 | + | |
3389 | +static void | |
3390 | +parse_one_string (struct obstack *output, char *data, int len, | |
3391 | + const char *dest_charset, struct type *type) | |
3392 | +{ | |
3393 | + char *limit; | |
3394 | + | |
3395 | + limit = data + len; | |
3396 | + | |
3397 | + while (data < limit) | |
3398 | + { | |
3399 | + char *p = data; | |
3400 | + /* Look for next escape, or the end of the input. */ | |
3401 | + while (p < limit && *p != '\\') | |
3402 | + ++p; | |
3403 | + /* If we saw a run of characters, convert them all. */ | |
3404 | + if (p > data) | |
3405 | + convert_between_encodings (host_charset (), dest_charset, | |
3406 | + data, p - data, 1, output, translit_none); | |
3407 | + /* If we saw an escape, convert it. */ | |
3408 | + if (p < limit) | |
3409 | + p = convert_escape (type, dest_charset, p, limit, output); | |
3410 | + data = p; | |
3411 | + } | |
3412 | +} | |
3413 | + | |
3414 | +/* Expression evaluator for the C language family. Most operations | |
3415 | + are delegated to evaluate_subexp_standard; see that function for a | |
3416 | + description of the arguments. */ | |
3417 | + | |
3418 | +static struct value * | |
3419 | +evaluate_subexp_c (struct type *expect_type, struct expression *exp, | |
3420 | + int *pos, enum noside noside) | |
3421 | +{ | |
3422 | + enum exp_opcode op = exp->elts[*pos].opcode; | |
3423 | + | |
3424 | + switch (op) | |
3425 | + { | |
3426 | + case OP_STRING: | |
3427 | + { | |
3428 | + int oplen, limit; | |
3429 | + struct type *type; | |
3430 | + struct obstack output; | |
3431 | + struct cleanup *cleanup; | |
3432 | + struct value *result; | |
3433 | + enum c_string_type dest_type; | |
3434 | + const char *dest_charset; | |
3435 | + | |
3436 | + obstack_init (&output); | |
3437 | + cleanup = make_cleanup_obstack_free (&output); | |
3438 | + | |
3439 | + ++*pos; | |
3440 | + oplen = longest_to_int (exp->elts[*pos].longconst); | |
3441 | + | |
3442 | + ++*pos; | |
3443 | + limit = *pos + BYTES_TO_EXP_ELEM (oplen + 1); | |
3444 | + dest_type | |
3445 | + = (enum c_string_type) longest_to_int (exp->elts[*pos].longconst); | |
3446 | + switch (dest_type & ~C_CHAR) | |
3447 | + { | |
3448 | + case C_STRING: | |
3449 | + type = language_string_char_type (current_language, | |
3450 | + current_gdbarch); | |
3451 | + break; | |
3452 | + case C_WIDE_STRING: | |
3453 | + type = lookup_typename ("wchar_t", NULL, 0); | |
3454 | + break; | |
3455 | + case C_STRING_16: | |
3456 | + type = lookup_typename ("char16_t", NULL, 0); | |
3457 | + break; | |
3458 | + case C_STRING_32: | |
3459 | + type = lookup_typename ("char32_t", NULL, 0); | |
3460 | + break; | |
3461 | + default: | |
3462 | + internal_error (__FILE__, __LINE__, "unhandled c_string_type"); | |
3463 | + } | |
3464 | + dest_charset = charset_for_string_type (dest_type); | |
3465 | + | |
3466 | + ++*pos; | |
3467 | + while (*pos < limit) | |
3468 | + { | |
3469 | + int len; | |
3470 | + | |
3471 | + len = longest_to_int (exp->elts[*pos].longconst); | |
3472 | + | |
3473 | + ++*pos; | |
3474 | + if (noside != EVAL_SKIP) | |
3475 | + parse_one_string (&output, &exp->elts[*pos].string, len, | |
3476 | + dest_charset, type); | |
3477 | + *pos += BYTES_TO_EXP_ELEM (len); | |
3478 | + } | |
3479 | + | |
3480 | + /* Skip the trailing length and opcode. */ | |
3481 | + *pos += 2; | |
3482 | + | |
3483 | + if (noside == EVAL_SKIP) | |
3484 | + return NULL; | |
3485 | + | |
3486 | + if ((dest_type & C_CHAR) != 0) | |
3487 | + { | |
3488 | + LONGEST value; | |
3489 | + | |
3490 | + if (obstack_object_size (&output) != TYPE_LENGTH (type)) | |
3491 | + error (_("Could not convert character constant to target character set")); | |
3492 | + value = unpack_long (type, obstack_base (&output)); | |
3493 | + result = value_from_longest (type, value); | |
3494 | + } | |
3495 | + else | |
3496 | + { | |
3497 | + int i; | |
3498 | + /* Write the terminating character. */ | |
3499 | + for (i = 0; i < TYPE_LENGTH (type); ++i) | |
3500 | + obstack_1grow (&output, 0); | |
3501 | + result = value_typed_string (obstack_base (&output), | |
3502 | + obstack_object_size (&output), | |
3503 | + type); | |
3504 | + } | |
3505 | + do_cleanups (cleanup); | |
3506 | + return result; | |
3507 | + } | |
3508 | + break; | |
3509 | + | |
3510 | + default: | |
3511 | + break; | |
3512 | + } | |
3513 | + return evaluate_subexp_standard (expect_type, exp, pos, noside); | |
3514 | +} | |
3515 | ||
3516 | ||
3517 | \f | |
3518 | @@ -396,6 +1063,15 @@ c_language_arch_info (struct gdbarch *gdbarch, | |
3519 | lai->bool_type_default = builtin->builtin_int; | |
3520 | } | |
3521 | ||
3522 | +static const struct exp_descriptor exp_descriptor_c = | |
3523 | +{ | |
3524 | + print_subexp_standard, | |
3525 | + operator_length_standard, | |
3526 | + op_name_standard, | |
3527 | + dump_subexp_body_standard, | |
3528 | + evaluate_subexp_c | |
3529 | +}; | |
3530 | + | |
3531 | const struct language_defn c_language_defn = | |
3532 | { | |
3533 | "c", /* Language name */ | |
3534 | @@ -405,7 +1081,7 @@ const struct language_defn c_language_defn = | |
3535 | case_sensitive_on, | |
3536 | array_row_major, | |
3537 | macro_expansion_c, | |
3538 | - &exp_descriptor_standard, | |
3539 | + &exp_descriptor_c, | |
3540 | c_parse, | |
3541 | c_error, | |
3542 | null_post_parser, | |
3543 | @@ -524,7 +1200,7 @@ const struct language_defn cplus_language_defn = | |
3544 | case_sensitive_on, | |
3545 | array_row_major, | |
3546 | macro_expansion_c, | |
3547 | - &exp_descriptor_standard, | |
3548 | + &exp_descriptor_c, | |
3549 | c_parse, | |
3550 | c_error, | |
3551 | null_post_parser, | |
3552 | @@ -562,7 +1238,7 @@ const struct language_defn asm_language_defn = | |
3553 | case_sensitive_on, | |
3554 | array_row_major, | |
3555 | macro_expansion_c, | |
3556 | - &exp_descriptor_standard, | |
3557 | + &exp_descriptor_c, | |
3558 | c_parse, | |
3559 | c_error, | |
3560 | null_post_parser, | |
3561 | @@ -605,7 +1281,7 @@ const struct language_defn minimal_language_defn = | |
3562 | case_sensitive_on, | |
3563 | array_row_major, | |
3564 | macro_expansion_c, | |
3565 | - &exp_descriptor_standard, | |
3566 | + &exp_descriptor_c, | |
3567 | c_parse, | |
3568 | c_error, | |
3569 | null_post_parser, | |
3570 | diff --git a/gdb/c-lang.h b/gdb/c-lang.h | |
3571 | index 06c5767..ba9d996 100644 | |
3572 | --- a/gdb/c-lang.h | |
3573 | +++ b/gdb/c-lang.h | |
3574 | @@ -29,9 +29,38 @@ struct language_arch_info; | |
3575 | #include "macroexp.h" | |
3576 | ||
3577 | ||
3578 | -extern int c_parse (void); /* Defined in c-exp.y */ | |
3579 | - | |
3580 | -extern void c_error (char *); /* Defined in c-exp.y */ | |
3581 | +/* The various kinds of C string and character. Note that these | |
3582 | + values are chosen so that they may be or'd together in certain | |
3583 | + ways. */ | |
3584 | +enum c_string_type | |
3585 | + { | |
3586 | + /* An ordinary string: "value". */ | |
3587 | + C_STRING = 0, | |
3588 | + /* A wide string: L"value". */ | |
3589 | + C_WIDE_STRING = 1, | |
3590 | + /* A 16-bit Unicode string: u"value". */ | |
3591 | + C_STRING_16 = 2, | |
3592 | + /* A 32-bit Unicode string: U"value". */ | |
3593 | + C_STRING_32 = 3, | |
3594 | + /* An ordinary char: 'v'. This can also be or'd with one of the | |
3595 | + above to form the corresponding CHAR value from a STRING | |
3596 | + value. */ | |
3597 | + C_CHAR = 4, | |
3598 | + /* A wide char: L'v'. */ | |
3599 | + C_WIDE_CHAR = 5, | |
3600 | + /* A 16-bit Unicode char: u'v'. */ | |
3601 | + C_CHAR_16 = 6, | |
3602 | + /* A 32-bit Unicode char: U'v'. */ | |
3603 | + C_CHAR_32 = 7 | |
3604 | + }; | |
3605 | + | |
3606 | +/* Defined in c-exp.y. */ | |
3607 | + | |
3608 | +extern int c_parse (void); | |
3609 | + | |
3610 | +extern void c_error (char *); | |
3611 | + | |
3612 | +extern int c_parse_escape (char **, struct obstack *); | |
3613 | ||
3614 | /* Defined in c-typeprint.c */ | |
3615 | extern void c_print_type (struct type *, char *, struct ui_file *, int, | |
3616 | @@ -48,10 +77,10 @@ extern int c_value_print (struct value *, struct ui_file *, | |
3617 | ||
3618 | /* These are in c-lang.c: */ | |
3619 | ||
3620 | -extern void c_printchar (int, struct ui_file *); | |
3621 | +extern void c_printchar (int, struct type *, struct ui_file *); | |
3622 | ||
3623 | -extern void c_printstr (struct ui_file * stream, const gdb_byte *string, | |
3624 | - unsigned int length, int width, | |
3625 | +extern void c_printstr (struct ui_file * stream, struct type *elttype, | |
3626 | + const gdb_byte *string, unsigned int length, | |
3627 | int force_ellipses, | |
3628 | const struct value_print_options *options); | |
3629 | ||
3630 | diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c | |
3631 | index 0929516..c005fe4 100644 | |
3632 | --- a/gdb/c-typeprint.c | |
3633 | +++ b/gdb/c-typeprint.c | |
3634 | @@ -40,8 +40,6 @@ static void cp_type_print_method_args (struct type *mtype, char *prefix, | |
3635 | char *varstring, int staticp, | |
3636 | struct ui_file *stream); | |
3637 | ||
3638 | -static void c_type_print_args (struct type *, struct ui_file *); | |
3639 | - | |
3640 | static void cp_type_print_derivation_info (struct ui_file *, struct type *); | |
3641 | ||
3642 | static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int, | |
3643 | @@ -199,6 +197,23 @@ cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring, | |
3644 | fprintf_filtered (stream, "void"); | |
3645 | ||
3646 | fprintf_filtered (stream, ")"); | |
3647 | + | |
3648 | + /* For non-static methods, read qualifiers from the type of | |
3649 | + THIS. */ | |
3650 | + if (!staticp) | |
3651 | + { | |
3652 | + struct type *domain; | |
3653 | + | |
3654 | + gdb_assert (nargs > 0); | |
3655 | + gdb_assert (TYPE_CODE (args[0].type) == TYPE_CODE_PTR); | |
3656 | + domain = TYPE_TARGET_TYPE (args[0].type); | |
3657 | + | |
3658 | + if (TYPE_CONST (domain)) | |
3659 | + fprintf_filtered (stream, " const"); | |
3660 | + | |
3661 | + if (TYPE_VOLATILE (domain)) | |
3662 | + fprintf_filtered (stream, " volatile"); | |
3663 | + } | |
3664 | } | |
3665 | ||
3666 | ||
3667 | @@ -354,10 +369,12 @@ c_type_print_modifier (struct type *type, struct ui_file *stream, | |
3668 | ||
3669 | /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD | |
3670 | or TYPE_CODE_FUNC, to STREAM. Artificial arguments, such as "this" | |
3671 | - in non-static methods, are displayed. */ | |
3672 | + in non-static methods, are displayed if SHOW_ARTIFICIAL is | |
3673 | + non-zero. */ | |
3674 | ||
3675 | -static void | |
3676 | -c_type_print_args (struct type *type, struct ui_file *stream) | |
3677 | +void | |
3678 | +c_type_print_args (struct type *type, struct ui_file *stream, | |
3679 | + int show_artificial) | |
3680 | { | |
3681 | int i, len; | |
3682 | struct field *args; | |
3683 | @@ -369,6 +386,9 @@ c_type_print_args (struct type *type, struct ui_file *stream) | |
3684 | ||
3685 | for (i = 0; i < TYPE_NFIELDS (type); i++) | |
3686 | { | |
3687 | + if (TYPE_FIELD_ARTIFICIAL (type, i) && !show_artificial) | |
3688 | + continue; | |
3689 | + | |
3690 | if (printed_any) | |
3691 | { | |
3692 | fprintf_filtered (stream, ", "); | |
3693 | @@ -559,7 +579,12 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, | |
3694 | fprintf_filtered (stream, ")"); | |
3695 | ||
3696 | fprintf_filtered (stream, "["); | |
3697 | - if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0 | |
3698 | + if (TYPE_ARRAY_BOUND_IS_DWARF_BLOCK (type, 1)) | |
3699 | + { | |
3700 | + /* No _() - printed sources should not be locale dependent. */ | |
3701 | + fprintf_filtered (stream, "variable"); | |
3702 | + } | |
3703 | + else if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0 | |
3704 | && !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)) | |
3705 | fprintf_filtered (stream, "%d", | |
3706 | (TYPE_LENGTH (type) | |
3707 | @@ -592,7 +617,7 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, | |
3708 | if (passed_a_ptr) | |
3709 | fprintf_filtered (stream, ")"); | |
3710 | if (!demangled_args) | |
3711 | - c_type_print_args (type, stream); | |
3712 | + c_type_print_args (type, stream, 1); | |
3713 | c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, | |
3714 | passed_a_ptr, 0); | |
3715 | break; | |
3716 | diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c | |
3717 | index 0b616f7..3433da2 100644 | |
3718 | --- a/gdb/c-valprint.c | |
3719 | +++ b/gdb/c-valprint.c | |
3720 | @@ -55,6 +55,18 @@ print_function_pointer_address (CORE_ADDR address, struct ui_file *stream, | |
3721 | } | |
3722 | ||
3723 | ||
3724 | +/* A helper for textual_element_type. This checks the name of the | |
3725 | + typedef. This is bogus but it isn't apparent that the compiler | |
3726 | + provides us the help we may need. */ | |
3727 | + | |
3728 | +static int | |
3729 | +textual_name (const char *name) | |
3730 | +{ | |
3731 | + return (!strcmp (name, "wchar_t") | |
3732 | + || !strcmp (name, "char16_t") | |
3733 | + || !strcmp (name, "char32_t")); | |
3734 | +} | |
3735 | + | |
3736 | /* Apply a heuristic to decide whether an array of TYPE or a pointer | |
3737 | to TYPE should be printed as a textual string. Return non-zero if | |
3738 | it should, or zero if it should be treated as an array of integers | |
3739 | @@ -77,6 +89,15 @@ textual_element_type (struct type *type, char format) | |
3740 | /* TYPE_CODE_CHAR is always textual. */ | |
3741 | if (TYPE_CODE (true_type) == TYPE_CODE_CHAR) | |
3742 | return 1; | |
3743 | + /* Any other character-like types must be integral. */ | |
3744 | + if (TYPE_CODE (true_type) != TYPE_CODE_INT) | |
3745 | + return 0; | |
3746 | + | |
3747 | + /* Check the names of the type and the typedef. */ | |
3748 | + if (TYPE_NAME (type) && textual_name (TYPE_NAME (type))) | |
3749 | + return 1; | |
3750 | + if (TYPE_NAME (true_type) && textual_name (TYPE_NAME (true_type))) | |
3751 | + return 1; | |
3752 | ||
3753 | if (format == 's') | |
3754 | { | |
3755 | @@ -115,7 +136,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
3756 | { | |
3757 | unsigned int i = 0; /* Number of characters printed */ | |
3758 | unsigned len; | |
3759 | - struct type *elttype; | |
3760 | + struct type *elttype, *unresolved_elttype; | |
3761 | + struct type *unresolved_type = type; | |
3762 | unsigned eltlen; | |
3763 | LONGEST val; | |
3764 | CORE_ADDR addr; | |
3765 | @@ -124,8 +146,9 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
3766 | switch (TYPE_CODE (type)) | |
3767 | { | |
3768 | case TYPE_CODE_ARRAY: | |
3769 | - elttype = check_typedef (TYPE_TARGET_TYPE (type)); | |
3770 | - if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) | |
3771 | + unresolved_elttype = TYPE_TARGET_TYPE (type); | |
3772 | + elttype = check_typedef (unresolved_elttype); | |
3773 | + if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0) | |
3774 | { | |
3775 | eltlen = TYPE_LENGTH (elttype); | |
3776 | len = TYPE_LENGTH (type) / eltlen; | |
3777 | @@ -135,7 +158,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
3778 | } | |
3779 | ||
3780 | /* Print arrays of textual chars with a string syntax. */ | |
3781 | - if (textual_element_type (elttype, options->format)) | |
3782 | + if (textual_element_type (unresolved_elttype, options->format)) | |
3783 | { | |
3784 | /* If requested, look for the first null char and only print | |
3785 | elements up to it. */ | |
3786 | @@ -143,15 +166,19 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
3787 | { | |
3788 | unsigned int temp_len; | |
3789 | ||
3790 | - /* Look for a NULL char. */ | |
3791 | for (temp_len = 0; | |
3792 | - (valaddr + embedded_offset)[temp_len] | |
3793 | - && temp_len < len && temp_len < options->print_max; | |
3794 | - temp_len++); | |
3795 | + (temp_len < len | |
3796 | + && temp_len < options->print_max | |
3797 | + && extract_unsigned_integer (valaddr + embedded_offset | |
3798 | + + temp_len * eltlen, | |
3799 | + eltlen) == 0); | |
3800 | + ++temp_len) | |
3801 | + ; | |
3802 | len = temp_len; | |
3803 | } | |
3804 | ||
3805 | - LA_PRINT_STRING (stream, valaddr + embedded_offset, len, eltlen, 0, options); | |
3806 | + LA_PRINT_STRING (stream, unresolved_elttype, | |
3807 | + valaddr + embedded_offset, len, 0, options); | |
3808 | i = len; | |
3809 | } | |
3810 | else | |
3811 | @@ -209,7 +236,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
3812 | print_function_pointer_address (addr, stream, options->addressprint); | |
3813 | break; | |
3814 | } | |
3815 | - elttype = check_typedef (TYPE_TARGET_TYPE (type)); | |
3816 | + unresolved_elttype = TYPE_TARGET_TYPE (type); | |
3817 | + elttype = check_typedef (unresolved_elttype); | |
3818 | { | |
3819 | addr = unpack_pointer (type, valaddr + embedded_offset); | |
3820 | print_unpacked_pointer: | |
3821 | @@ -228,12 +256,11 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
3822 | ||
3823 | /* For a pointer to a textual type, also print the string | |
3824 | pointed to, unless pointer is null. */ | |
3825 | - /* FIXME: need to handle wchar_t here... */ | |
3826 | ||
3827 | - if (textual_element_type (elttype, options->format) | |
3828 | + if (textual_element_type (unresolved_elttype, options->format) | |
3829 | && addr != 0) | |
3830 | { | |
3831 | - i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream, | |
3832 | + i = val_print_string (unresolved_elttype, addr, -1, stream, | |
3833 | options); | |
3834 | } | |
3835 | else if (cp_is_vtbl_member (type)) | |
3836 | @@ -268,7 +295,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
3837 | } | |
3838 | else | |
3839 | { | |
3840 | - wtype = TYPE_TARGET_TYPE (type); | |
3841 | + wtype = unresolved_elttype; | |
3842 | } | |
3843 | vt_val = value_at (wtype, vt_address); | |
3844 | common_val_print (vt_val, stream, recurse + 1, options, | |
3845 | @@ -442,11 +469,11 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
3846 | Since we don't know whether the value is really intended to | |
3847 | be used as an integer or a character, print the character | |
3848 | equivalent as well. */ | |
3849 | - if (textual_element_type (type, options->format)) | |
3850 | + if (textual_element_type (unresolved_type, options->format)) | |
3851 | { | |
3852 | fputs_filtered (" ", stream); | |
3853 | LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset), | |
3854 | - stream); | |
3855 | + unresolved_type, stream); | |
3856 | } | |
3857 | } | |
3858 | break; | |
3859 | @@ -468,7 +495,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
3860 | else | |
3861 | fprintf_filtered (stream, "%d", (int) val); | |
3862 | fputs_filtered (" ", stream); | |
3863 | - LA_PRINT_CHAR ((unsigned char) val, stream); | |
3864 | + LA_PRINT_CHAR ((unsigned char) val, unresolved_type, stream); | |
3865 | } | |
3866 | break; | |
3867 | ||
3868 | @@ -540,7 +567,7 @@ int | |
3869 | c_value_print (struct value *val, struct ui_file *stream, | |
3870 | const struct value_print_options *options) | |
3871 | { | |
3872 | - struct type *type, *real_type; | |
3873 | + struct type *type, *real_type, *val_type; | |
3874 | int full, top, using_enc; | |
3875 | struct value_print_options opts = *options; | |
3876 | ||
3877 | @@ -553,7 +580,11 @@ c_value_print (struct value *val, struct ui_file *stream, | |
3878 | C++: if it is a member pointer, we will take care | |
3879 | of that when we print it. */ | |
3880 | ||
3881 | - type = check_typedef (value_type (val)); | |
3882 | + /* Preserve the original type before stripping typedefs. We prefer | |
3883 | + to pass down the original type when possible, but for local | |
3884 | + checks it is better to look past the typedefs. */ | |
3885 | + val_type = value_type (val); | |
3886 | + type = check_typedef (val_type); | |
3887 | ||
3888 | if (TYPE_CODE (type) == TYPE_CODE_PTR | |
3889 | || TYPE_CODE (type) == TYPE_CODE_REF) | |
3890 | @@ -561,11 +592,12 @@ c_value_print (struct value *val, struct ui_file *stream, | |
3891 | /* Hack: remove (char *) for char strings. Their | |
3892 | type is indicated by the quoted string anyway. | |
3893 | (Don't use textual_element_type here; quoted strings | |
3894 | - are always exactly (char *). */ | |
3895 | - if (TYPE_CODE (type) == TYPE_CODE_PTR | |
3896 | - && TYPE_NAME (type) == NULL | |
3897 | - && TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL | |
3898 | - && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char") == 0) | |
3899 | + are always exactly (char *), (wchar_t *), or the like. */ | |
3900 | + if (TYPE_CODE (val_type) == TYPE_CODE_PTR | |
3901 | + && TYPE_NAME (val_type) == NULL | |
3902 | + && TYPE_NAME (TYPE_TARGET_TYPE (val_type)) != NULL | |
3903 | + && (strcmp (TYPE_NAME (TYPE_TARGET_TYPE (val_type)), "char") == 0 | |
3904 | + || textual_name (TYPE_NAME (TYPE_TARGET_TYPE (val_type))))) | |
3905 | { | |
3906 | /* Print nothing */ | |
3907 | } | |
3908 | @@ -608,6 +640,7 @@ c_value_print (struct value *val, struct ui_file *stream, | |
3909 | } | |
3910 | type_print (type, "", stream, -1); | |
3911 | fprintf_filtered (stream, ") "); | |
3912 | + val_type = type; | |
3913 | } | |
3914 | else | |
3915 | { | |
3916 | @@ -635,7 +668,7 @@ c_value_print (struct value *val, struct ui_file *stream, | |
3917 | /* Print out object: enclosing type is same as real_type if full */ | |
3918 | return val_print (value_enclosing_type (val), | |
3919 | value_contents_all (val), 0, | |
3920 | - VALUE_ADDRESS (val), stream, 0, | |
3921 | + value_address (val), stream, 0, | |
3922 | &opts, current_language); | |
3923 | /* Note: When we look up RTTI entries, we don't get any information on | |
3924 | const or volatile attributes */ | |
3925 | @@ -647,14 +680,14 @@ c_value_print (struct value *val, struct ui_file *stream, | |
3926 | TYPE_NAME (value_enclosing_type (val))); | |
3927 | return val_print (value_enclosing_type (val), | |
3928 | value_contents_all (val), 0, | |
3929 | - VALUE_ADDRESS (val), stream, 0, | |
3930 | + value_address (val), stream, 0, | |
3931 | &opts, current_language); | |
3932 | } | |
3933 | /* Otherwise, we end up at the return outside this "if" */ | |
3934 | } | |
3935 | ||
3936 | - return val_print (type, value_contents_all (val), | |
3937 | + return val_print (val_type, value_contents_all (val), | |
3938 | value_embedded_offset (val), | |
3939 | - VALUE_ADDRESS (val) + value_offset (val), | |
3940 | + value_address (val), | |
3941 | stream, 0, &opts, current_language); | |
3942 | } | |
3943 | diff --git a/gdb/charset-list.h b/gdb/charset-list.h | |
3944 | new file mode 100644 | |
3945 | index 0000000..59c64c5 | |
3946 | --- /dev/null | |
3947 | +++ b/gdb/charset-list.h | |
3948 | @@ -0,0 +1,1190 @@ | |
3949 | +/* List of character set names for GDB. | |
3950 | + | |
3951 | + Copyright (C) 2009 Free Software Foundation, Inc. | |
3952 | + | |
3953 | + This file is part of GDB. | |
3954 | + | |
3955 | + This program is free software; you can redistribute it and/or modify | |
3956 | + it under the terms of the GNU General Public License as published by | |
3957 | + the Free Software Foundation; either version 3 of the License, or | |
3958 | + (at your option) any later version. | |
3959 | + | |
3960 | + This program is distributed in the hope that it will be useful, | |
3961 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
3962 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
3963 | + GNU General Public License for more details. | |
3964 | + | |
3965 | + You should have received a copy of the GNU General Public License | |
3966 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
3967 | + | |
3968 | +/* Note that the first entry must always be "auto". | |
3969 | + The remaining entries were created by running this script: | |
3970 | + | |
3971 | + iconv -l | sed -e '/[/]...*$/d' -e 's@^\(.*\)//$@"\1", \\@' | |
3972 | + | |
3973 | + .. and then removing the final backslash. It would be nice to | |
3974 | + separate narrow and wide character sets, but there is no good way | |
3975 | + to do that. */ | |
3976 | +#define DEFAULT_CHARSET_NAMES \ | |
3977 | +"auto", \ | |
3978 | +"437", \ | |
3979 | +"500", \ | |
3980 | +"500V1", \ | |
3981 | +"850", \ | |
3982 | +"851", \ | |
3983 | +"852", \ | |
3984 | +"855", \ | |
3985 | +"856", \ | |
3986 | +"857", \ | |
3987 | +"860", \ | |
3988 | +"861", \ | |
3989 | +"862", \ | |
3990 | +"863", \ | |
3991 | +"864", \ | |
3992 | +"865", \ | |
3993 | +"866", \ | |
3994 | +"866NAV", \ | |
3995 | +"869", \ | |
3996 | +"874", \ | |
3997 | +"904", \ | |
3998 | +"1026", \ | |
3999 | +"1046", \ | |
4000 | +"1047", \ | |
4001 | +"8859_1", \ | |
4002 | +"8859_2", \ | |
4003 | +"8859_3", \ | |
4004 | +"8859_4", \ | |
4005 | +"8859_5", \ | |
4006 | +"8859_6", \ | |
4007 | +"8859_7", \ | |
4008 | +"8859_8", \ | |
4009 | +"8859_9", \ | |
4010 | +"10646-1:1993", \ | |
4011 | +"ANSI_X3.4-1968", \ | |
4012 | +"ANSI_X3.4-1986", \ | |
4013 | +"ANSI_X3.4", \ | |
4014 | +"ANSI_X3.110-1983", \ | |
4015 | +"ANSI_X3.110", \ | |
4016 | +"ARABIC", \ | |
4017 | +"ARABIC7", \ | |
4018 | +"ARMSCII-8", \ | |
4019 | +"ASCII", \ | |
4020 | +"ASMO-708", \ | |
4021 | +"ASMO_449", \ | |
4022 | +"BALTIC", \ | |
4023 | +"BIG-5", \ | |
4024 | +"BIG-FIVE", \ | |
4025 | +"BIG5-HKSCS", \ | |
4026 | +"BIG5", \ | |
4027 | +"BIG5HKSCS", \ | |
4028 | +"BIGFIVE", \ | |
4029 | +"BRF", \ | |
4030 | +"BS_4730", \ | |
4031 | +"CA", \ | |
4032 | +"CN-BIG5", \ | |
4033 | +"CN-GB", \ | |
4034 | +"CN", \ | |
4035 | +"CP-AR", \ | |
4036 | +"CP-GR", \ | |
4037 | +"CP-HU", \ | |
4038 | +"CP037", \ | |
4039 | +"CP038", \ | |
4040 | +"CP273", \ | |
4041 | +"CP274", \ | |
4042 | +"CP275", \ | |
4043 | +"CP278", \ | |
4044 | +"CP280", \ | |
4045 | +"CP281", \ | |
4046 | +"CP282", \ | |
4047 | +"CP284", \ | |
4048 | +"CP285", \ | |
4049 | +"CP290", \ | |
4050 | +"CP297", \ | |
4051 | +"CP367", \ | |
4052 | +"CP420", \ | |
4053 | +"CP423", \ | |
4054 | +"CP424", \ | |
4055 | +"CP437", \ | |
4056 | +"CP500", \ | |
4057 | +"CP737", \ | |
4058 | +"CP775", \ | |
4059 | +"CP803", \ | |
4060 | +"CP813", \ | |
4061 | +"CP819", \ | |
4062 | +"CP850", \ | |
4063 | +"CP851", \ | |
4064 | +"CP852", \ | |
4065 | +"CP855", \ | |
4066 | +"CP856", \ | |
4067 | +"CP857", \ | |
4068 | +"CP860", \ | |
4069 | +"CP861", \ | |
4070 | +"CP862", \ | |
4071 | +"CP863", \ | |
4072 | +"CP864", \ | |
4073 | +"CP865", \ | |
4074 | +"CP866", \ | |
4075 | +"CP866NAV", \ | |
4076 | +"CP868", \ | |
4077 | +"CP869", \ | |
4078 | +"CP870", \ | |
4079 | +"CP871", \ | |
4080 | +"CP874", \ | |
4081 | +"CP875", \ | |
4082 | +"CP880", \ | |
4083 | +"CP891", \ | |
4084 | +"CP901", \ | |
4085 | +"CP902", \ | |
4086 | +"CP903", \ | |
4087 | +"CP904", \ | |
4088 | +"CP905", \ | |
4089 | +"CP912", \ | |
4090 | +"CP915", \ | |
4091 | +"CP916", \ | |
4092 | +"CP918", \ | |
4093 | +"CP920", \ | |
4094 | +"CP921", \ | |
4095 | +"CP922", \ | |
4096 | +"CP930", \ | |
4097 | +"CP932", \ | |
4098 | +"CP933", \ | |
4099 | +"CP935", \ | |
4100 | +"CP936", \ | |
4101 | +"CP937", \ | |
4102 | +"CP939", \ | |
4103 | +"CP949", \ | |
4104 | +"CP950", \ | |
4105 | +"CP1004", \ | |
4106 | +"CP1008", \ | |
4107 | +"CP1025", \ | |
4108 | +"CP1026", \ | |
4109 | +"CP1046", \ | |
4110 | +"CP1047", \ | |
4111 | +"CP1070", \ | |
4112 | +"CP1079", \ | |
4113 | +"CP1081", \ | |
4114 | +"CP1084", \ | |
4115 | +"CP1089", \ | |
4116 | +"CP1097", \ | |
4117 | +"CP1112", \ | |
4118 | +"CP1122", \ | |
4119 | +"CP1123", \ | |
4120 | +"CP1124", \ | |
4121 | +"CP1125", \ | |
4122 | +"CP1129", \ | |
4123 | +"CP1130", \ | |
4124 | +"CP1132", \ | |
4125 | +"CP1133", \ | |
4126 | +"CP1137", \ | |
4127 | +"CP1140", \ | |
4128 | +"CP1141", \ | |
4129 | +"CP1142", \ | |
4130 | +"CP1143", \ | |
4131 | +"CP1144", \ | |
4132 | +"CP1145", \ | |
4133 | +"CP1146", \ | |
4134 | +"CP1147", \ | |
4135 | +"CP1148", \ | |
4136 | +"CP1149", \ | |
4137 | +"CP1153", \ | |
4138 | +"CP1154", \ | |
4139 | +"CP1155", \ | |
4140 | +"CP1156", \ | |
4141 | +"CP1157", \ | |
4142 | +"CP1158", \ | |
4143 | +"CP1160", \ | |
4144 | +"CP1161", \ | |
4145 | +"CP1162", \ | |
4146 | +"CP1163", \ | |
4147 | +"CP1164", \ | |
4148 | +"CP1166", \ | |
4149 | +"CP1167", \ | |
4150 | +"CP1250", \ | |
4151 | +"CP1251", \ | |
4152 | +"CP1252", \ | |
4153 | +"CP1253", \ | |
4154 | +"CP1254", \ | |
4155 | +"CP1255", \ | |
4156 | +"CP1256", \ | |
4157 | +"CP1257", \ | |
4158 | +"CP1258", \ | |
4159 | +"CP1282", \ | |
4160 | +"CP1361", \ | |
4161 | +"CP1364", \ | |
4162 | +"CP1371", \ | |
4163 | +"CP1388", \ | |
4164 | +"CP1390", \ | |
4165 | +"CP1399", \ | |
4166 | +"CP4517", \ | |
4167 | +"CP4899", \ | |
4168 | +"CP4909", \ | |
4169 | +"CP4971", \ | |
4170 | +"CP5347", \ | |
4171 | +"CP9030", \ | |
4172 | +"CP9066", \ | |
4173 | +"CP9448", \ | |
4174 | +"CP10007", \ | |
4175 | +"CP12712", \ | |
4176 | +"CP16804", \ | |
4177 | +"CPIBM861", \ | |
4178 | +"CSA7-1", \ | |
4179 | +"CSA7-2", \ | |
4180 | +"CSASCII", \ | |
4181 | +"CSA_T500-1983", \ | |
4182 | +"CSA_T500", \ | |
4183 | +"CSA_Z243.4-1985-1", \ | |
4184 | +"CSA_Z243.4-1985-2", \ | |
4185 | +"CSA_Z243.419851", \ | |
4186 | +"CSA_Z243.419852", \ | |
4187 | +"CSDECMCS", \ | |
4188 | +"CSEBCDICATDE", \ | |
4189 | +"CSEBCDICATDEA", \ | |
4190 | +"CSEBCDICCAFR", \ | |
4191 | +"CSEBCDICDKNO", \ | |
4192 | +"CSEBCDICDKNOA", \ | |
4193 | +"CSEBCDICES", \ | |
4194 | +"CSEBCDICESA", \ | |
4195 | +"CSEBCDICESS", \ | |
4196 | +"CSEBCDICFISE", \ | |
4197 | +"CSEBCDICFISEA", \ | |
4198 | +"CSEBCDICFR", \ | |
4199 | +"CSEBCDICIT", \ | |
4200 | +"CSEBCDICPT", \ | |
4201 | +"CSEBCDICUK", \ | |
4202 | +"CSEBCDICUS", \ | |
4203 | +"CSEUCKR", \ | |
4204 | +"CSEUCPKDFMTJAPANESE", \ | |
4205 | +"CSGB2312", \ | |
4206 | +"CSHPROMAN8", \ | |
4207 | +"CSIBM037", \ | |
4208 | +"CSIBM038", \ | |
4209 | +"CSIBM273", \ | |
4210 | +"CSIBM274", \ | |
4211 | +"CSIBM275", \ | |
4212 | +"CSIBM277", \ | |
4213 | +"CSIBM278", \ | |
4214 | +"CSIBM280", \ | |
4215 | +"CSIBM281", \ | |
4216 | +"CSIBM284", \ | |
4217 | +"CSIBM285", \ | |
4218 | +"CSIBM290", \ | |
4219 | +"CSIBM297", \ | |
4220 | +"CSIBM420", \ | |
4221 | +"CSIBM423", \ | |
4222 | +"CSIBM424", \ | |
4223 | +"CSIBM500", \ | |
4224 | +"CSIBM803", \ | |
4225 | +"CSIBM851", \ | |
4226 | +"CSIBM855", \ | |
4227 | +"CSIBM856", \ | |
4228 | +"CSIBM857", \ | |
4229 | +"CSIBM860", \ | |
4230 | +"CSIBM863", \ | |
4231 | +"CSIBM864", \ | |
4232 | +"CSIBM865", \ | |
4233 | +"CSIBM866", \ | |
4234 | +"CSIBM868", \ | |
4235 | +"CSIBM869", \ | |
4236 | +"CSIBM870", \ | |
4237 | +"CSIBM871", \ | |
4238 | +"CSIBM880", \ | |
4239 | +"CSIBM891", \ | |
4240 | +"CSIBM901", \ | |
4241 | +"CSIBM902", \ | |
4242 | +"CSIBM903", \ | |
4243 | +"CSIBM904", \ | |
4244 | +"CSIBM905", \ | |
4245 | +"CSIBM918", \ | |
4246 | +"CSIBM921", \ | |
4247 | +"CSIBM922", \ | |
4248 | +"CSIBM930", \ | |
4249 | +"CSIBM932", \ | |
4250 | +"CSIBM933", \ | |
4251 | +"CSIBM935", \ | |
4252 | +"CSIBM937", \ | |
4253 | +"CSIBM939", \ | |
4254 | +"CSIBM943", \ | |
4255 | +"CSIBM1008", \ | |
4256 | +"CSIBM1025", \ | |
4257 | +"CSIBM1026", \ | |
4258 | +"CSIBM1097", \ | |
4259 | +"CSIBM1112", \ | |
4260 | +"CSIBM1122", \ | |
4261 | +"CSIBM1123", \ | |
4262 | +"CSIBM1124", \ | |
4263 | +"CSIBM1129", \ | |
4264 | +"CSIBM1130", \ | |
4265 | +"CSIBM1132", \ | |
4266 | +"CSIBM1133", \ | |
4267 | +"CSIBM1137", \ | |
4268 | +"CSIBM1140", \ | |
4269 | +"CSIBM1141", \ | |
4270 | +"CSIBM1142", \ | |
4271 | +"CSIBM1143", \ | |
4272 | +"CSIBM1144", \ | |
4273 | +"CSIBM1145", \ | |
4274 | +"CSIBM1146", \ | |
4275 | +"CSIBM1147", \ | |
4276 | +"CSIBM1148", \ | |
4277 | +"CSIBM1149", \ | |
4278 | +"CSIBM1153", \ | |
4279 | +"CSIBM1154", \ | |
4280 | +"CSIBM1155", \ | |
4281 | +"CSIBM1156", \ | |
4282 | +"CSIBM1157", \ | |
4283 | +"CSIBM1158", \ | |
4284 | +"CSIBM1160", \ | |
4285 | +"CSIBM1161", \ | |
4286 | +"CSIBM1163", \ | |
4287 | +"CSIBM1164", \ | |
4288 | +"CSIBM1166", \ | |
4289 | +"CSIBM1167", \ | |
4290 | +"CSIBM1364", \ | |
4291 | +"CSIBM1371", \ | |
4292 | +"CSIBM1388", \ | |
4293 | +"CSIBM1390", \ | |
4294 | +"CSIBM1399", \ | |
4295 | +"CSIBM4517", \ | |
4296 | +"CSIBM4899", \ | |
4297 | +"CSIBM4909", \ | |
4298 | +"CSIBM4971", \ | |
4299 | +"CSIBM5347", \ | |
4300 | +"CSIBM9030", \ | |
4301 | +"CSIBM9066", \ | |
4302 | +"CSIBM9448", \ | |
4303 | +"CSIBM12712", \ | |
4304 | +"CSIBM16804", \ | |
4305 | +"CSIBM11621162", \ | |
4306 | +"CSISO4UNITEDKINGDOM", \ | |
4307 | +"CSISO10SWEDISH", \ | |
4308 | +"CSISO11SWEDISHFORNAMES", \ | |
4309 | +"CSISO14JISC6220RO", \ | |
4310 | +"CSISO15ITALIAN", \ | |
4311 | +"CSISO16PORTUGESE", \ | |
4312 | +"CSISO17SPANISH", \ | |
4313 | +"CSISO18GREEK7OLD", \ | |
4314 | +"CSISO19LATINGREEK", \ | |
4315 | +"CSISO21GERMAN", \ | |
4316 | +"CSISO25FRENCH", \ | |
4317 | +"CSISO27LATINGREEK1", \ | |
4318 | +"CSISO49INIS", \ | |
4319 | +"CSISO50INIS8", \ | |
4320 | +"CSISO51INISCYRILLIC", \ | |
4321 | +"CSISO58GB1988", \ | |
4322 | +"CSISO60DANISHNORWEGIAN", \ | |
4323 | +"CSISO60NORWEGIAN1", \ | |
4324 | +"CSISO61NORWEGIAN2", \ | |
4325 | +"CSISO69FRENCH", \ | |
4326 | +"CSISO84PORTUGUESE2", \ | |
4327 | +"CSISO85SPANISH2", \ | |
4328 | +"CSISO86HUNGARIAN", \ | |
4329 | +"CSISO88GREEK7", \ | |
4330 | +"CSISO89ASMO449", \ | |
4331 | +"CSISO90", \ | |
4332 | +"CSISO92JISC62991984B", \ | |
4333 | +"CSISO99NAPLPS", \ | |
4334 | +"CSISO103T618BIT", \ | |
4335 | +"CSISO111ECMACYRILLIC", \ | |
4336 | +"CSISO121CANADIAN1", \ | |
4337 | +"CSISO122CANADIAN2", \ | |
4338 | +"CSISO139CSN369103", \ | |
4339 | +"CSISO141JUSIB1002", \ | |
4340 | +"CSISO143IECP271", \ | |
4341 | +"CSISO150", \ | |
4342 | +"CSISO150GREEKCCITT", \ | |
4343 | +"CSISO151CUBA", \ | |
4344 | +"CSISO153GOST1976874", \ | |
4345 | +"CSISO646DANISH", \ | |
4346 | +"CSISO2022CN", \ | |
4347 | +"CSISO2022JP", \ | |
4348 | +"CSISO2022JP2", \ | |
4349 | +"CSISO2022KR", \ | |
4350 | +"CSISO2033", \ | |
4351 | +"CSISO5427CYRILLIC", \ | |
4352 | +"CSISO5427CYRILLIC1981", \ | |
4353 | +"CSISO5428GREEK", \ | |
4354 | +"CSISO10367BOX", \ | |
4355 | +"CSISOLATIN1", \ | |
4356 | +"CSISOLATIN2", \ | |
4357 | +"CSISOLATIN3", \ | |
4358 | +"CSISOLATIN4", \ | |
4359 | +"CSISOLATIN5", \ | |
4360 | +"CSISOLATIN6", \ | |
4361 | +"CSISOLATINARABIC", \ | |
4362 | +"CSISOLATINCYRILLIC", \ | |
4363 | +"CSISOLATINGREEK", \ | |
4364 | +"CSISOLATINHEBREW", \ | |
4365 | +"CSKOI8R", \ | |
4366 | +"CSKSC5636", \ | |
4367 | +"CSMACINTOSH", \ | |
4368 | +"CSNATSDANO", \ | |
4369 | +"CSNATSSEFI", \ | |
4370 | +"CSN_369103", \ | |
4371 | +"CSPC8CODEPAGE437", \ | |
4372 | +"CSPC775BALTIC", \ | |
4373 | +"CSPC850MULTILINGUAL", \ | |
4374 | +"CSPC862LATINHEBREW", \ | |
4375 | +"CSPCP852", \ | |
4376 | +"CSSHIFTJIS", \ | |
4377 | +"CSUCS4", \ | |
4378 | +"CSUNICODE", \ | |
4379 | +"CSWINDOWS31J", \ | |
4380 | +"CUBA", \ | |
4381 | +"CWI-2", \ | |
4382 | +"CWI", \ | |
4383 | +"CYRILLIC", \ | |
4384 | +"DE", \ | |
4385 | +"DEC-MCS", \ | |
4386 | +"DEC", \ | |
4387 | +"DECMCS", \ | |
4388 | +"DIN_66003", \ | |
4389 | +"DK", \ | |
4390 | +"DS2089", \ | |
4391 | +"DS_2089", \ | |
4392 | +"E13B", \ | |
4393 | +"EBCDIC-AT-DE-A", \ | |
4394 | +"EBCDIC-AT-DE", \ | |
4395 | +"EBCDIC-BE", \ | |
4396 | +"EBCDIC-BR", \ | |
4397 | +"EBCDIC-CA-FR", \ | |
4398 | +"EBCDIC-CP-AR1", \ | |
4399 | +"EBCDIC-CP-AR2", \ | |
4400 | +"EBCDIC-CP-BE", \ | |
4401 | +"EBCDIC-CP-CA", \ | |
4402 | +"EBCDIC-CP-CH", \ | |
4403 | +"EBCDIC-CP-DK", \ | |
4404 | +"EBCDIC-CP-ES", \ | |
4405 | +"EBCDIC-CP-FI", \ | |
4406 | +"EBCDIC-CP-FR", \ | |
4407 | +"EBCDIC-CP-GB", \ | |
4408 | +"EBCDIC-CP-GR", \ | |
4409 | +"EBCDIC-CP-HE", \ | |
4410 | +"EBCDIC-CP-IS", \ | |
4411 | +"EBCDIC-CP-IT", \ | |
4412 | +"EBCDIC-CP-NL", \ | |
4413 | +"EBCDIC-CP-NO", \ | |
4414 | +"EBCDIC-CP-ROECE", \ | |
4415 | +"EBCDIC-CP-SE", \ | |
4416 | +"EBCDIC-CP-TR", \ | |
4417 | +"EBCDIC-CP-US", \ | |
4418 | +"EBCDIC-CP-WT", \ | |
4419 | +"EBCDIC-CP-YU", \ | |
4420 | +"EBCDIC-CYRILLIC", \ | |
4421 | +"EBCDIC-DK-NO-A", \ | |
4422 | +"EBCDIC-DK-NO", \ | |
4423 | +"EBCDIC-ES-A", \ | |
4424 | +"EBCDIC-ES-S", \ | |
4425 | +"EBCDIC-ES", \ | |
4426 | +"EBCDIC-FI-SE-A", \ | |
4427 | +"EBCDIC-FI-SE", \ | |
4428 | +"EBCDIC-FR", \ | |
4429 | +"EBCDIC-GREEK", \ | |
4430 | +"EBCDIC-INT", \ | |
4431 | +"EBCDIC-INT1", \ | |
4432 | +"EBCDIC-IS-FRISS", \ | |
4433 | +"EBCDIC-IT", \ | |
4434 | +"EBCDIC-JP-E", \ | |
4435 | +"EBCDIC-JP-KANA", \ | |
4436 | +"EBCDIC-PT", \ | |
4437 | +"EBCDIC-UK", \ | |
4438 | +"EBCDIC-US", \ | |
4439 | +"EBCDICATDE", \ | |
4440 | +"EBCDICATDEA", \ | |
4441 | +"EBCDICCAFR", \ | |
4442 | +"EBCDICDKNO", \ | |
4443 | +"EBCDICDKNOA", \ | |
4444 | +"EBCDICES", \ | |
4445 | +"EBCDICESA", \ | |
4446 | +"EBCDICESS", \ | |
4447 | +"EBCDICFISE", \ | |
4448 | +"EBCDICFISEA", \ | |
4449 | +"EBCDICFR", \ | |
4450 | +"EBCDICISFRISS", \ | |
4451 | +"EBCDICIT", \ | |
4452 | +"EBCDICPT", \ | |
4453 | +"EBCDICUK", \ | |
4454 | +"EBCDICUS", \ | |
4455 | +"ECMA-114", \ | |
4456 | +"ECMA-118", \ | |
4457 | +"ECMA-128", \ | |
4458 | +"ECMA-CYRILLIC", \ | |
4459 | +"ECMACYRILLIC", \ | |
4460 | +"ELOT_928", \ | |
4461 | +"ES", \ | |
4462 | +"ES2", \ | |
4463 | +"EUC-CN", \ | |
4464 | +"EUC-JISX0213", \ | |
4465 | +"EUC-JP-MS", \ | |
4466 | +"EUC-JP", \ | |
4467 | +"EUC-KR", \ | |
4468 | +"EUC-TW", \ | |
4469 | +"EUCCN", \ | |
4470 | +"EUCJP-MS", \ | |
4471 | +"EUCJP-OPEN", \ | |
4472 | +"EUCJP-WIN", \ | |
4473 | +"EUCJP", \ | |
4474 | +"EUCKR", \ | |
4475 | +"EUCTW", \ | |
4476 | +"FI", \ | |
4477 | +"FR", \ | |
4478 | +"GB", \ | |
4479 | +"GB2312", \ | |
4480 | +"GB13000", \ | |
4481 | +"GB18030", \ | |
4482 | +"GBK", \ | |
4483 | +"GB_1988-80", \ | |
4484 | +"GB_198880", \ | |
4485 | +"GEORGIAN-ACADEMY", \ | |
4486 | +"GEORGIAN-PS", \ | |
4487 | +"GOST_19768-74", \ | |
4488 | +"GOST_19768", \ | |
4489 | +"GOST_1976874", \ | |
4490 | +"GREEK-CCITT", \ | |
4491 | +"GREEK", \ | |
4492 | +"GREEK7-OLD", \ | |
4493 | +"GREEK7", \ | |
4494 | +"GREEK7OLD", \ | |
4495 | +"GREEK8", \ | |
4496 | +"GREEKCCITT", \ | |
4497 | +"HEBREW", \ | |
4498 | +"HP-GREEK8", \ | |
4499 | +"HP-ROMAN8", \ | |
4500 | +"HP-ROMAN9", \ | |
4501 | +"HP-THAI8", \ | |
4502 | +"HP-TURKISH8", \ | |
4503 | +"HPGREEK8", \ | |
4504 | +"HPROMAN8", \ | |
4505 | +"HPROMAN9", \ | |
4506 | +"HPTHAI8", \ | |
4507 | +"HPTURKISH8", \ | |
4508 | +"HU", \ | |
4509 | +"IBM-803", \ | |
4510 | +"IBM-856", \ | |
4511 | +"IBM-901", \ | |
4512 | +"IBM-902", \ | |
4513 | +"IBM-921", \ | |
4514 | +"IBM-922", \ | |
4515 | +"IBM-930", \ | |
4516 | +"IBM-932", \ | |
4517 | +"IBM-933", \ | |
4518 | +"IBM-935", \ | |
4519 | +"IBM-937", \ | |
4520 | +"IBM-939", \ | |
4521 | +"IBM-943", \ | |
4522 | +"IBM-1008", \ | |
4523 | +"IBM-1025", \ | |
4524 | +"IBM-1046", \ | |
4525 | +"IBM-1047", \ | |
4526 | +"IBM-1097", \ | |
4527 | +"IBM-1112", \ | |
4528 | +"IBM-1122", \ | |
4529 | +"IBM-1123", \ | |
4530 | +"IBM-1124", \ | |
4531 | +"IBM-1129", \ | |
4532 | +"IBM-1130", \ | |
4533 | +"IBM-1132", \ | |
4534 | +"IBM-1133", \ | |
4535 | +"IBM-1137", \ | |
4536 | +"IBM-1140", \ | |
4537 | +"IBM-1141", \ | |
4538 | +"IBM-1142", \ | |
4539 | +"IBM-1143", \ | |
4540 | +"IBM-1144", \ | |
4541 | +"IBM-1145", \ | |
4542 | +"IBM-1146", \ | |
4543 | +"IBM-1147", \ | |
4544 | +"IBM-1148", \ | |
4545 | +"IBM-1149", \ | |
4546 | +"IBM-1153", \ | |
4547 | +"IBM-1154", \ | |
4548 | +"IBM-1155", \ | |
4549 | +"IBM-1156", \ | |
4550 | +"IBM-1157", \ | |
4551 | +"IBM-1158", \ | |
4552 | +"IBM-1160", \ | |
4553 | +"IBM-1161", \ | |
4554 | +"IBM-1162", \ | |
4555 | +"IBM-1163", \ | |
4556 | +"IBM-1164", \ | |
4557 | +"IBM-1166", \ | |
4558 | +"IBM-1167", \ | |
4559 | +"IBM-1364", \ | |
4560 | +"IBM-1371", \ | |
4561 | +"IBM-1388", \ | |
4562 | +"IBM-1390", \ | |
4563 | +"IBM-1399", \ | |
4564 | +"IBM-4517", \ | |
4565 | +"IBM-4899", \ | |
4566 | +"IBM-4909", \ | |
4567 | +"IBM-4971", \ | |
4568 | +"IBM-5347", \ | |
4569 | +"IBM-9030", \ | |
4570 | +"IBM-9066", \ | |
4571 | +"IBM-9448", \ | |
4572 | +"IBM-12712", \ | |
4573 | +"IBM-16804", \ | |
4574 | +"IBM037", \ | |
4575 | +"IBM038", \ | |
4576 | +"IBM256", \ | |
4577 | +"IBM273", \ | |
4578 | +"IBM274", \ | |
4579 | +"IBM275", \ | |
4580 | +"IBM277", \ | |
4581 | +"IBM278", \ | |
4582 | +"IBM280", \ | |
4583 | +"IBM281", \ | |
4584 | +"IBM284", \ | |
4585 | +"IBM285", \ | |
4586 | +"IBM290", \ | |
4587 | +"IBM297", \ | |
4588 | +"IBM367", \ | |
4589 | +"IBM420", \ | |
4590 | +"IBM423", \ | |
4591 | +"IBM424", \ | |
4592 | +"IBM437", \ | |
4593 | +"IBM500", \ | |
4594 | +"IBM775", \ | |
4595 | +"IBM803", \ | |
4596 | +"IBM813", \ | |
4597 | +"IBM819", \ | |
4598 | +"IBM848", \ | |
4599 | +"IBM850", \ | |
4600 | +"IBM851", \ | |
4601 | +"IBM852", \ | |
4602 | +"IBM855", \ | |
4603 | +"IBM856", \ | |
4604 | +"IBM857", \ | |
4605 | +"IBM860", \ | |
4606 | +"IBM861", \ | |
4607 | +"IBM862", \ | |
4608 | +"IBM863", \ | |
4609 | +"IBM864", \ | |
4610 | +"IBM865", \ | |
4611 | +"IBM866", \ | |
4612 | +"IBM866NAV", \ | |
4613 | +"IBM868", \ | |
4614 | +"IBM869", \ | |
4615 | +"IBM870", \ | |
4616 | +"IBM871", \ | |
4617 | +"IBM874", \ | |
4618 | +"IBM875", \ | |
4619 | +"IBM880", \ | |
4620 | +"IBM891", \ | |
4621 | +"IBM901", \ | |
4622 | +"IBM902", \ | |
4623 | +"IBM903", \ | |
4624 | +"IBM904", \ | |
4625 | +"IBM905", \ | |
4626 | +"IBM912", \ | |
4627 | +"IBM915", \ | |
4628 | +"IBM916", \ | |
4629 | +"IBM918", \ | |
4630 | +"IBM920", \ | |
4631 | +"IBM921", \ | |
4632 | +"IBM922", \ | |
4633 | +"IBM930", \ | |
4634 | +"IBM932", \ | |
4635 | +"IBM933", \ | |
4636 | +"IBM935", \ | |
4637 | +"IBM937", \ | |
4638 | +"IBM939", \ | |
4639 | +"IBM943", \ | |
4640 | +"IBM1004", \ | |
4641 | +"IBM1008", \ | |
4642 | +"IBM1025", \ | |
4643 | +"IBM1026", \ | |
4644 | +"IBM1046", \ | |
4645 | +"IBM1047", \ | |
4646 | +"IBM1089", \ | |
4647 | +"IBM1097", \ | |
4648 | +"IBM1112", \ | |
4649 | +"IBM1122", \ | |
4650 | +"IBM1123", \ | |
4651 | +"IBM1124", \ | |
4652 | +"IBM1129", \ | |
4653 | +"IBM1130", \ | |
4654 | +"IBM1132", \ | |
4655 | +"IBM1133", \ | |
4656 | +"IBM1137", \ | |
4657 | +"IBM1140", \ | |
4658 | +"IBM1141", \ | |
4659 | +"IBM1142", \ | |
4660 | +"IBM1143", \ | |
4661 | +"IBM1144", \ | |
4662 | +"IBM1145", \ | |
4663 | +"IBM1146", \ | |
4664 | +"IBM1147", \ | |
4665 | +"IBM1148", \ | |
4666 | +"IBM1149", \ | |
4667 | +"IBM1153", \ | |
4668 | +"IBM1154", \ | |
4669 | +"IBM1155", \ | |
4670 | +"IBM1156", \ | |
4671 | +"IBM1157", \ | |
4672 | +"IBM1158", \ | |
4673 | +"IBM1160", \ | |
4674 | +"IBM1161", \ | |
4675 | +"IBM1162", \ | |
4676 | +"IBM1163", \ | |
4677 | +"IBM1164", \ | |
4678 | +"IBM1166", \ | |
4679 | +"IBM1167", \ | |
4680 | +"IBM1364", \ | |
4681 | +"IBM1371", \ | |
4682 | +"IBM1388", \ | |
4683 | +"IBM1390", \ | |
4684 | +"IBM1399", \ | |
4685 | +"IBM4517", \ | |
4686 | +"IBM4899", \ | |
4687 | +"IBM4909", \ | |
4688 | +"IBM4971", \ | |
4689 | +"IBM5347", \ | |
4690 | +"IBM9030", \ | |
4691 | +"IBM9066", \ | |
4692 | +"IBM9448", \ | |
4693 | +"IBM12712", \ | |
4694 | +"IBM16804", \ | |
4695 | +"IEC_P27-1", \ | |
4696 | +"IEC_P271", \ | |
4697 | +"INIS-8", \ | |
4698 | +"INIS-CYRILLIC", \ | |
4699 | +"INIS", \ | |
4700 | +"INIS8", \ | |
4701 | +"INISCYRILLIC", \ | |
4702 | +"ISIRI-3342", \ | |
4703 | +"ISIRI3342", \ | |
4704 | +"ISO-2022-CN-EXT", \ | |
4705 | +"ISO-2022-CN", \ | |
4706 | +"ISO-2022-JP-2", \ | |
4707 | +"ISO-2022-JP-3", \ | |
4708 | +"ISO-2022-JP", \ | |
4709 | +"ISO-2022-KR", \ | |
4710 | +"ISO-8859-1", \ | |
4711 | +"ISO-8859-2", \ | |
4712 | +"ISO-8859-3", \ | |
4713 | +"ISO-8859-4", \ | |
4714 | +"ISO-8859-5", \ | |
4715 | +"ISO-8859-6", \ | |
4716 | +"ISO-8859-7", \ | |
4717 | +"ISO-8859-8", \ | |
4718 | +"ISO-8859-9", \ | |
4719 | +"ISO-8859-9E", \ | |
4720 | +"ISO-8859-10", \ | |
4721 | +"ISO-8859-11", \ | |
4722 | +"ISO-8859-13", \ | |
4723 | +"ISO-8859-14", \ | |
4724 | +"ISO-8859-15", \ | |
4725 | +"ISO-8859-16", \ | |
4726 | +"ISO-10646", \ | |
4727 | +"ISO-CELTIC", \ | |
4728 | +"ISO-IR-4", \ | |
4729 | +"ISO-IR-6", \ | |
4730 | +"ISO-IR-8-1", \ | |
4731 | +"ISO-IR-9-1", \ | |
4732 | +"ISO-IR-10", \ | |
4733 | +"ISO-IR-11", \ | |
4734 | +"ISO-IR-14", \ | |
4735 | +"ISO-IR-15", \ | |
4736 | +"ISO-IR-16", \ | |
4737 | +"ISO-IR-17", \ | |
4738 | +"ISO-IR-18", \ | |
4739 | +"ISO-IR-19", \ | |
4740 | +"ISO-IR-21", \ | |
4741 | +"ISO-IR-25", \ | |
4742 | +"ISO-IR-27", \ | |
4743 | +"ISO-IR-37", \ | |
4744 | +"ISO-IR-49", \ | |
4745 | +"ISO-IR-50", \ | |
4746 | +"ISO-IR-51", \ | |
4747 | +"ISO-IR-54", \ | |
4748 | +"ISO-IR-55", \ | |
4749 | +"ISO-IR-57", \ | |
4750 | +"ISO-IR-60", \ | |
4751 | +"ISO-IR-61", \ | |
4752 | +"ISO-IR-69", \ | |
4753 | +"ISO-IR-84", \ | |
4754 | +"ISO-IR-85", \ | |
4755 | +"ISO-IR-86", \ | |
4756 | +"ISO-IR-88", \ | |
4757 | +"ISO-IR-89", \ | |
4758 | +"ISO-IR-90", \ | |
4759 | +"ISO-IR-92", \ | |
4760 | +"ISO-IR-98", \ | |
4761 | +"ISO-IR-99", \ | |
4762 | +"ISO-IR-100", \ | |
4763 | +"ISO-IR-101", \ | |
4764 | +"ISO-IR-103", \ | |
4765 | +"ISO-IR-109", \ | |
4766 | +"ISO-IR-110", \ | |
4767 | +"ISO-IR-111", \ | |
4768 | +"ISO-IR-121", \ | |
4769 | +"ISO-IR-122", \ | |
4770 | +"ISO-IR-126", \ | |
4771 | +"ISO-IR-127", \ | |
4772 | +"ISO-IR-138", \ | |
4773 | +"ISO-IR-139", \ | |
4774 | +"ISO-IR-141", \ | |
4775 | +"ISO-IR-143", \ | |
4776 | +"ISO-IR-144", \ | |
4777 | +"ISO-IR-148", \ | |
4778 | +"ISO-IR-150", \ | |
4779 | +"ISO-IR-151", \ | |
4780 | +"ISO-IR-153", \ | |
4781 | +"ISO-IR-155", \ | |
4782 | +"ISO-IR-156", \ | |
4783 | +"ISO-IR-157", \ | |
4784 | +"ISO-IR-166", \ | |
4785 | +"ISO-IR-179", \ | |
4786 | +"ISO-IR-193", \ | |
4787 | +"ISO-IR-197", \ | |
4788 | +"ISO-IR-199", \ | |
4789 | +"ISO-IR-203", \ | |
4790 | +"ISO-IR-209", \ | |
4791 | +"ISO-IR-226", \ | |
4792 | +"ISO646-CA", \ | |
4793 | +"ISO646-CA2", \ | |
4794 | +"ISO646-CN", \ | |
4795 | +"ISO646-CU", \ | |
4796 | +"ISO646-DE", \ | |
4797 | +"ISO646-DK", \ | |
4798 | +"ISO646-ES", \ | |
4799 | +"ISO646-ES2", \ | |
4800 | +"ISO646-FI", \ | |
4801 | +"ISO646-FR", \ | |
4802 | +"ISO646-FR1", \ | |
4803 | +"ISO646-GB", \ | |
4804 | +"ISO646-HU", \ | |
4805 | +"ISO646-IT", \ | |
4806 | +"ISO646-JP-OCR-B", \ | |
4807 | +"ISO646-JP", \ | |
4808 | +"ISO646-KR", \ | |
4809 | +"ISO646-NO", \ | |
4810 | +"ISO646-NO2", \ | |
4811 | +"ISO646-PT", \ | |
4812 | +"ISO646-PT2", \ | |
4813 | +"ISO646-SE", \ | |
4814 | +"ISO646-SE2", \ | |
4815 | +"ISO646-US", \ | |
4816 | +"ISO646-YU", \ | |
4817 | +"ISO2022CN", \ | |
4818 | +"ISO2022CNEXT", \ | |
4819 | +"ISO2022JP", \ | |
4820 | +"ISO2022JP2", \ | |
4821 | +"ISO2022KR", \ | |
4822 | +"ISO6937", \ | |
4823 | +"ISO8859-1", \ | |
4824 | +"ISO8859-2", \ | |
4825 | +"ISO8859-3", \ | |
4826 | +"ISO8859-4", \ | |
4827 | +"ISO8859-5", \ | |
4828 | +"ISO8859-6", \ | |
4829 | +"ISO8859-7", \ | |
4830 | +"ISO8859-8", \ | |
4831 | +"ISO8859-9", \ | |
4832 | +"ISO8859-9E", \ | |
4833 | +"ISO8859-10", \ | |
4834 | +"ISO8859-11", \ | |
4835 | +"ISO8859-13", \ | |
4836 | +"ISO8859-14", \ | |
4837 | +"ISO8859-15", \ | |
4838 | +"ISO8859-16", \ | |
4839 | +"ISO11548-1", \ | |
4840 | +"ISO88591", \ | |
4841 | +"ISO88592", \ | |
4842 | +"ISO88593", \ | |
4843 | +"ISO88594", \ | |
4844 | +"ISO88595", \ | |
4845 | +"ISO88596", \ | |
4846 | +"ISO88597", \ | |
4847 | +"ISO88598", \ | |
4848 | +"ISO88599", \ | |
4849 | +"ISO88599E", \ | |
4850 | +"ISO885910", \ | |
4851 | +"ISO885911", \ | |
4852 | +"ISO885913", \ | |
4853 | +"ISO885914", \ | |
4854 | +"ISO885915", \ | |
4855 | +"ISO885916", \ | |
4856 | +"ISO_646.IRV:1991", \ | |
4857 | +"ISO_2033-1983", \ | |
4858 | +"ISO_2033", \ | |
4859 | +"ISO_5427-EXT", \ | |
4860 | +"ISO_5427", \ | |
4861 | +"ISO_5427:1981", \ | |
4862 | +"ISO_5427EXT", \ | |
4863 | +"ISO_5428", \ | |
4864 | +"ISO_5428:1980", \ | |
4865 | +"ISO_6937-2", \ | |
4866 | +"ISO_6937-2:1983", \ | |
4867 | +"ISO_6937", \ | |
4868 | +"ISO_6937:1992", \ | |
4869 | +"ISO_8859-1", \ | |
4870 | +"ISO_8859-1:1987", \ | |
4871 | +"ISO_8859-2", \ | |
4872 | +"ISO_8859-2:1987", \ | |
4873 | +"ISO_8859-3", \ | |
4874 | +"ISO_8859-3:1988", \ | |
4875 | +"ISO_8859-4", \ | |
4876 | +"ISO_8859-4:1988", \ | |
4877 | +"ISO_8859-5", \ | |
4878 | +"ISO_8859-5:1988", \ | |
4879 | +"ISO_8859-6", \ | |
4880 | +"ISO_8859-6:1987", \ | |
4881 | +"ISO_8859-7", \ | |
4882 | +"ISO_8859-7:1987", \ | |
4883 | +"ISO_8859-7:2003", \ | |
4884 | +"ISO_8859-8", \ | |
4885 | +"ISO_8859-8:1988", \ | |
4886 | +"ISO_8859-9", \ | |
4887 | +"ISO_8859-9:1989", \ | |
4888 | +"ISO_8859-9E", \ | |
4889 | +"ISO_8859-10", \ | |
4890 | +"ISO_8859-10:1992", \ | |
4891 | +"ISO_8859-14", \ | |
4892 | +"ISO_8859-14:1998", \ | |
4893 | +"ISO_8859-15", \ | |
4894 | +"ISO_8859-15:1998", \ | |
4895 | +"ISO_8859-16", \ | |
4896 | +"ISO_8859-16:2001", \ | |
4897 | +"ISO_9036", \ | |
4898 | +"ISO_10367-BOX", \ | |
4899 | +"ISO_10367BOX", \ | |
4900 | +"ISO_11548-1", \ | |
4901 | +"ISO_69372", \ | |
4902 | +"IT", \ | |
4903 | +"JIS_C6220-1969-RO", \ | |
4904 | +"JIS_C6229-1984-B", \ | |
4905 | +"JIS_C62201969RO", \ | |
4906 | +"JIS_C62291984B", \ | |
4907 | +"JOHAB", \ | |
4908 | +"JP-OCR-B", \ | |
4909 | +"JP", \ | |
4910 | +"JS", \ | |
4911 | +"JUS_I.B1.002", \ | |
4912 | +"KOI-7", \ | |
4913 | +"KOI-8", \ | |
4914 | +"KOI8-R", \ | |
4915 | +"KOI8-RU", \ | |
4916 | +"KOI8-T", \ | |
4917 | +"KOI8-U", \ | |
4918 | +"KOI8", \ | |
4919 | +"KOI8R", \ | |
4920 | +"KOI8U", \ | |
4921 | +"KSC5636", \ | |
4922 | +"L1", \ | |
4923 | +"L2", \ | |
4924 | +"L3", \ | |
4925 | +"L4", \ | |
4926 | +"L5", \ | |
4927 | +"L6", \ | |
4928 | +"L7", \ | |
4929 | +"L8", \ | |
4930 | +"L10", \ | |
4931 | +"LATIN-9", \ | |
4932 | +"LATIN-GREEK-1", \ | |
4933 | +"LATIN-GREEK", \ | |
4934 | +"LATIN1", \ | |
4935 | +"LATIN2", \ | |
4936 | +"LATIN3", \ | |
4937 | +"LATIN4", \ | |
4938 | +"LATIN5", \ | |
4939 | +"LATIN6", \ | |
4940 | +"LATIN7", \ | |
4941 | +"LATIN8", \ | |
4942 | +"LATIN10", \ | |
4943 | +"LATINGREEK", \ | |
4944 | +"LATINGREEK1", \ | |
4945 | +"MAC-CENTRALEUROPE", \ | |
4946 | +"MAC-CYRILLIC", \ | |
4947 | +"MAC-IS", \ | |
4948 | +"MAC-SAMI", \ | |
4949 | +"MAC-UK", \ | |
4950 | +"MAC", \ | |
4951 | +"MACCYRILLIC", \ | |
4952 | +"MACINTOSH", \ | |
4953 | +"MACIS", \ | |
4954 | +"MACUK", \ | |
4955 | +"MACUKRAINIAN", \ | |
4956 | +"MIK", \ | |
4957 | +"MS-ANSI", \ | |
4958 | +"MS-ARAB", \ | |
4959 | +"MS-CYRL", \ | |
4960 | +"MS-EE", \ | |
4961 | +"MS-GREEK", \ | |
4962 | +"MS-HEBR", \ | |
4963 | +"MS-MAC-CYRILLIC", \ | |
4964 | +"MS-TURK", \ | |
4965 | +"MS932", \ | |
4966 | +"MS936", \ | |
4967 | +"MSCP949", \ | |
4968 | +"MSCP1361", \ | |
4969 | +"MSMACCYRILLIC", \ | |
4970 | +"MSZ_7795.3", \ | |
4971 | +"MS_KANJI", \ | |
4972 | +"NAPLPS", \ | |
4973 | +"NATS-DANO", \ | |
4974 | +"NATS-SEFI", \ | |
4975 | +"NATSDANO", \ | |
4976 | +"NATSSEFI", \ | |
4977 | +"NC_NC0010", \ | |
4978 | +"NC_NC00-10", \ | |
4979 | +"NC_NC00-10:81", \ | |
4980 | +"NF_Z_62-010", \ | |
4981 | +"NF_Z_62-010_(1973)", \ | |
4982 | +"NF_Z_62-010_1973", \ | |
4983 | +"NF_Z_62010", \ | |
4984 | +"NF_Z_62010_1973", \ | |
4985 | +"NO", \ | |
4986 | +"NO2", \ | |
4987 | +"NS_4551-1", \ | |
4988 | +"NS_4551-2", \ | |
4989 | +"NS_45511", \ | |
4990 | +"NS_45512", \ | |
4991 | +"OS2LATIN1", \ | |
4992 | +"OSF00010001", \ | |
4993 | +"OSF00010002", \ | |
4994 | +"OSF00010003", \ | |
4995 | +"OSF00010004", \ | |
4996 | +"OSF00010005", \ | |
4997 | +"OSF00010006", \ | |
4998 | +"OSF00010007", \ | |
4999 | +"OSF00010008", \ | |
5000 | +"OSF00010009", \ | |
5001 | +"OSF0001000A", \ | |
5002 | +"OSF00010020", \ | |
5003 | +"OSF00010100", \ | |
5004 | +"OSF00010101", \ | |
5005 | +"OSF00010102", \ | |
5006 | +"OSF00010104", \ | |
5007 | +"OSF00010105", \ | |
5008 | +"OSF00010106", \ | |
5009 | +"OSF00030010", \ | |
5010 | +"OSF0004000A", \ | |
5011 | +"OSF0005000A", \ | |
5012 | +"OSF05010001", \ | |
5013 | +"OSF100201A4", \ | |
5014 | +"OSF100201A8", \ | |
5015 | +"OSF100201B5", \ | |
5016 | +"OSF100201F4", \ | |
5017 | +"OSF100203B5", \ | |
5018 | +"OSF1002011C", \ | |
5019 | +"OSF1002011D", \ | |
5020 | +"OSF1002035D", \ | |
5021 | +"OSF1002035E", \ | |
5022 | +"OSF1002035F", \ | |
5023 | +"OSF1002036B", \ | |
5024 | +"OSF1002037B", \ | |
5025 | +"OSF10010001", \ | |
5026 | +"OSF10010004", \ | |
5027 | +"OSF10010006", \ | |
5028 | +"OSF10020025", \ | |
5029 | +"OSF10020111", \ | |
5030 | +"OSF10020115", \ | |
5031 | +"OSF10020116", \ | |
5032 | +"OSF10020118", \ | |
5033 | +"OSF10020122", \ | |
5034 | +"OSF10020129", \ | |
5035 | +"OSF10020352", \ | |
5036 | +"OSF10020354", \ | |
5037 | +"OSF10020357", \ | |
5038 | +"OSF10020359", \ | |
5039 | +"OSF10020360", \ | |
5040 | +"OSF10020364", \ | |
5041 | +"OSF10020365", \ | |
5042 | +"OSF10020366", \ | |
5043 | +"OSF10020367", \ | |
5044 | +"OSF10020370", \ | |
5045 | +"OSF10020387", \ | |
5046 | +"OSF10020388", \ | |
5047 | +"OSF10020396", \ | |
5048 | +"OSF10020402", \ | |
5049 | +"OSF10020417", \ | |
5050 | +"PT", \ | |
5051 | +"PT2", \ | |
5052 | +"PT154", \ | |
5053 | +"R8", \ | |
5054 | +"R9", \ | |
5055 | +"RK1048", \ | |
5056 | +"ROMAN8", \ | |
5057 | +"ROMAN9", \ | |
5058 | +"RUSCII", \ | |
5059 | +"SE", \ | |
5060 | +"SE2", \ | |
5061 | +"SEN_850200_B", \ | |
5062 | +"SEN_850200_C", \ | |
5063 | +"SHIFT-JIS", \ | |
5064 | +"SHIFT_JIS", \ | |
5065 | +"SHIFT_JISX0213", \ | |
5066 | +"SJIS-OPEN", \ | |
5067 | +"SJIS-WIN", \ | |
5068 | +"SJIS", \ | |
5069 | +"SS636127", \ | |
5070 | +"STRK1048-2002", \ | |
5071 | +"ST_SEV_358-88", \ | |
5072 | +"T.61-8BIT", \ | |
5073 | +"T.61", \ | |
5074 | +"T.618BIT", \ | |
5075 | +"TCVN-5712", \ | |
5076 | +"TCVN", \ | |
5077 | +"TCVN5712-1", \ | |
5078 | +"TCVN5712-1:1993", \ | |
5079 | +"THAI8", \ | |
5080 | +"TIS-620", \ | |
5081 | +"TIS620-0", \ | |
5082 | +"TIS620.2529-1", \ | |
5083 | +"TIS620.2533-0", \ | |
5084 | +"TIS620", \ | |
5085 | +"TS-5881", \ | |
5086 | +"TSCII", \ | |
5087 | +"TURKISH8", \ | |
5088 | +"UCS-2", \ | |
5089 | +"UCS-2BE", \ | |
5090 | +"UCS-2LE", \ | |
5091 | +"UCS-4", \ | |
5092 | +"UCS-4BE", \ | |
5093 | +"UCS-4LE", \ | |
5094 | +"UCS2", \ | |
5095 | +"UCS4", \ | |
5096 | +"UHC", \ | |
5097 | +"UJIS", \ | |
5098 | +"UK", \ | |
5099 | +"UNICODE", \ | |
5100 | +"UNICODEBIG", \ | |
5101 | +"UNICODELITTLE", \ | |
5102 | +"US-ASCII", \ | |
5103 | +"US", \ | |
5104 | +"UTF-7", \ | |
5105 | +"UTF-8", \ | |
5106 | +"UTF-16", \ | |
5107 | +"UTF-16BE", \ | |
5108 | +"UTF-16LE", \ | |
5109 | +"UTF-32", \ | |
5110 | +"UTF-32BE", \ | |
5111 | +"UTF-32LE", \ | |
5112 | +"UTF7", \ | |
5113 | +"UTF8", \ | |
5114 | +"UTF16", \ | |
5115 | +"UTF16BE", \ | |
5116 | +"UTF16LE", \ | |
5117 | +"UTF32", \ | |
5118 | +"UTF32BE", \ | |
5119 | +"UTF32LE", \ | |
5120 | +"VISCII", \ | |
5121 | +"WCHAR_T", \ | |
5122 | +"WIN-SAMI-2", \ | |
5123 | +"WINBALTRIM", \ | |
5124 | +"WINDOWS-31J", \ | |
5125 | +"WINDOWS-874", \ | |
5126 | +"WINDOWS-936", \ | |
5127 | +"WINDOWS-1250", \ | |
5128 | +"WINDOWS-1251", \ | |
5129 | +"WINDOWS-1252", \ | |
5130 | +"WINDOWS-1253", \ | |
5131 | +"WINDOWS-1254", \ | |
5132 | +"WINDOWS-1255", \ | |
5133 | +"WINDOWS-1256", \ | |
5134 | +"WINDOWS-1257", \ | |
5135 | +"WINDOWS-1258", \ | |
5136 | +"WINSAMI2", \ | |
5137 | +"WS2", \ | |
5138 | +"YU", | |
5139 | diff --git a/gdb/charset.c b/gdb/charset.c | |
5140 | index 32eb9c3..4850fbf 100644 | |
5141 | --- a/gdb/charset.c | |
5142 | +++ b/gdb/charset.c | |
5143 | @@ -21,6 +21,9 @@ | |
5144 | #include "charset.h" | |
5145 | #include "gdbcmd.h" | |
5146 | #include "gdb_assert.h" | |
5147 | +#include "gdb_obstack.h" | |
5148 | +#include "charset-list.h" | |
5149 | +#include "vec.h" | |
5150 | ||
5151 | #include <stddef.h> | |
5152 | #include "gdb_string.h" | |
5153 | @@ -33,15 +36,20 @@ | |
5154 | \f | |
5155 | /* How GDB's character set support works | |
5156 | ||
5157 | - GDB has two global settings: | |
5158 | + GDB has three global settings: | |
5159 | ||
5160 | - The `current host character set' is the character set GDB should | |
5161 | use in talking to the user, and which (hopefully) the user's | |
5162 | - terminal knows how to display properly. | |
5163 | + terminal knows how to display properly. Most users should not | |
5164 | + change this. | |
5165 | ||
5166 | - The `current target character set' is the character set the | |
5167 | program being debugged uses. | |
5168 | ||
5169 | + - The `current target wide character set' is the wide character set | |
5170 | + the program being debugged uses, that is, the encoding used for | |
5171 | + wchar_t. | |
5172 | + | |
5173 | There are commands to set each of these, and mechanisms for | |
5174 | choosing reasonable default values. GDB has a global list of | |
5175 | character sets that it can use as its host or target character | |
5176 | @@ -57,118 +65,37 @@ | |
5177 | characters the user enters in expressions (mostly host->target | |
5178 | conversions), | |
5179 | ||
5180 | - and so on. | |
5181 | - | |
5182 | - Now, many of these operations are specific to a particular | |
5183 | - host/target character set pair. If GDB supports N character sets, | |
5184 | - there are N^2 possible pairs. This means that, the larger GDB's | |
5185 | - repertoire of character sets gets, the more expensive it gets to add | |
5186 | - new character sets. | |
5187 | - | |
5188 | - To make sure that GDB can do the right thing for every possible | |
5189 | - pairing of host and target character set, while still allowing | |
5190 | - GDB's repertoire to scale, we use a two-tiered approach: | |
5191 | - | |
5192 | - - We maintain a global table of "translations" --- groups of | |
5193 | - functions specific to a particular pair of character sets. | |
5194 | - | |
5195 | - - However, a translation can be incomplete: some functions can be | |
5196 | - omitted. Where there is not a translation to specify exactly | |
5197 | - what function to use, we provide reasonable defaults. The | |
5198 | - default behaviors try to use the "iconv" library functions, which | |
5199 | - support a wide range of character sets. However, even if iconv | |
5200 | - is not available, there are fallbacks to support trivial | |
5201 | - translations: when the host and target character sets are the | |
5202 | - same. */ | |
5203 | - | |
5204 | -\f | |
5205 | -/* The character set and translation structures. */ | |
5206 | - | |
5207 | - | |
5208 | -/* A character set GDB knows about. GDB only supports character sets | |
5209 | - with stateless encodings, in which every character is one byte | |
5210 | - long. */ | |
5211 | -struct charset { | |
5212 | - | |
5213 | - /* A singly-linked list of all known charsets. */ | |
5214 | - struct charset *next; | |
5215 | - | |
5216 | - /* The name of the character set. Comparisons on character set | |
5217 | - names are case-sensitive. */ | |
5218 | - const char *name; | |
5219 | - | |
5220 | - /* Non-zero iff this character set can be used as a host character | |
5221 | - set. At present, GDB basically assumes that the host character | |
5222 | - set is a superset of ASCII. */ | |
5223 | - int valid_host_charset; | |
5224 | - | |
5225 | - /* Pointers to charset-specific functions that depend only on a | |
5226 | - single character set, and data pointers to pass to them. */ | |
5227 | - int (*host_char_print_literally) (void *baton, | |
5228 | - int host_char); | |
5229 | - void *host_char_print_literally_baton; | |
5230 | - | |
5231 | - int (*target_char_to_control_char) (void *baton, | |
5232 | - int target_char, | |
5233 | - int *target_ctrl_char); | |
5234 | - void *target_char_to_control_char_baton; | |
5235 | -}; | |
5236 | - | |
5237 | - | |
5238 | -/* A translation from one character set to another. */ | |
5239 | -struct translation { | |
5240 | - | |
5241 | - /* A singly-linked list of all known translations. */ | |
5242 | - struct translation *next; | |
5243 | - | |
5244 | - /* This structure describes functions going from the FROM character | |
5245 | - set to the TO character set. Comparisons on character set names | |
5246 | - are case-sensitive. */ | |
5247 | - const char *from, *to; | |
5248 | - | |
5249 | - /* Pointers to translation-specific functions, and data pointers to | |
5250 | - pass to them. These pointers can be zero, indicating that GDB | |
5251 | - should fall back on the default behavior. We hope the default | |
5252 | - behavior will be correct for many from/to pairs, reducing the | |
5253 | - number of translations that need to be registered explicitly. */ | |
5254 | - | |
5255 | - /* TARGET_CHAR is in the `from' charset. | |
5256 | - Returns a string in the `to' charset. */ | |
5257 | - const char *(*c_target_char_has_backslash_escape) (void *baton, | |
5258 | - int target_char); | |
5259 | - void *c_target_char_has_backslash_escape_baton; | |
5260 | - | |
5261 | - /* HOST_CHAR is in the `from' charset. | |
5262 | - TARGET_CHAR points to a char in the `to' charset. */ | |
5263 | - int (*c_parse_backslash) (void *baton, int host_char, int *target_char); | |
5264 | - void *c_parse_backslash_baton; | |
5265 | - | |
5266 | - /* This is used for the host_char_to_target and target_char_to_host | |
5267 | - functions. */ | |
5268 | - int (*convert_char) (void *baton, int from, int *to); | |
5269 | - void *convert_char_baton; | |
5270 | -}; | |
5271 | - | |
5272 | + and so on. | |
5273 | + | |
5274 | + To avoid excessive code duplication and maintenance efforts, | |
5275 | + GDB simply requires a capable iconv function. Users on platforms | |
5276 | + without a suitable iconv can use the GNU iconv library. */ | |
5277 | ||
5278 | \f | |
5279 | /* The global lists of character sets and translations. */ | |
5280 | ||
5281 | ||
5282 | -#ifndef GDB_DEFAULT_HOST_CHARSET | |
5283 | -#define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1" | |
5284 | -#endif | |
5285 | - | |
5286 | #ifndef GDB_DEFAULT_TARGET_CHARSET | |
5287 | #define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1" | |
5288 | #endif | |
5289 | ||
5290 | -static const char *host_charset_name = GDB_DEFAULT_HOST_CHARSET; | |
5291 | +#ifndef GDB_DEFAULT_TARGET_WIDE_CHARSET | |
5292 | +#define GDB_DEFAULT_TARGET_WIDE_CHARSET "UCS-4" | |
5293 | +#endif | |
5294 | + | |
5295 | +static const char *auto_host_charset_name = GDB_DEFAULT_HOST_CHARSET; | |
5296 | +static const char *host_charset_name = "auto"; | |
5297 | static void | |
5298 | show_host_charset_name (struct ui_file *file, int from_tty, | |
5299 | struct cmd_list_element *c, | |
5300 | const char *value) | |
5301 | { | |
5302 | - fprintf_filtered (file, _("The host character set is \"%s\".\n"), value); | |
5303 | + if (!strcmp (value, "auto")) | |
5304 | + fprintf_filtered (file, | |
5305 | + _("The host character set is \"auto; currently %s\".\n"), | |
5306 | + auto_host_charset_name); | |
5307 | + else | |
5308 | + fprintf_filtered (file, _("The host character set is \"%s\".\n"), value); | |
5309 | } | |
5310 | ||
5311 | static const char *target_charset_name = GDB_DEFAULT_TARGET_CHARSET; | |
5312 | @@ -180,1060 +107,534 @@ show_target_charset_name (struct ui_file *file, int from_tty, | |
5313 | value); | |
5314 | } | |
5315 | ||
5316 | - | |
5317 | -static const char *host_charset_enum[] = | |
5318 | +static const char *target_wide_charset_name = GDB_DEFAULT_TARGET_WIDE_CHARSET; | |
5319 | +static void | |
5320 | +show_target_wide_charset_name (struct ui_file *file, int from_tty, | |
5321 | + struct cmd_list_element *c, const char *value) | |
5322 | { | |
5323 | - "ASCII", | |
5324 | - "ISO-8859-1", | |
5325 | - 0 | |
5326 | -}; | |
5327 | + fprintf_filtered (file, _("The target wide character set is \"%s\".\n"), | |
5328 | + value); | |
5329 | +} | |
5330 | ||
5331 | -static const char *target_charset_enum[] = | |
5332 | +static const char *default_charset_names[] = | |
5333 | { | |
5334 | - "ASCII", | |
5335 | - "ISO-8859-1", | |
5336 | - "EBCDIC-US", | |
5337 | - "IBM1047", | |
5338 | + DEFAULT_CHARSET_NAMES | |
5339 | 0 | |
5340 | }; | |
5341 | ||
5342 | -/* The global list of all the charsets GDB knows about. */ | |
5343 | -static struct charset *all_charsets; | |
5344 | +static const char **charset_enum; | |
5345 | ||
5346 | +\f | |
5347 | +/* If the target wide character set has big- or little-endian | |
5348 | + variants, these are the corresponding names. */ | |
5349 | +static const char *target_wide_charset_be_name; | |
5350 | +static const char *target_wide_charset_le_name; | |
5351 | ||
5352 | -static void | |
5353 | -register_charset (struct charset *cs) | |
5354 | -{ | |
5355 | - struct charset **ptr; | |
5356 | - | |
5357 | - /* Put the new charset on the end, so that the list ends up in the | |
5358 | - same order as the registrations in the _initialize function. */ | |
5359 | - for (ptr = &all_charsets; *ptr; ptr = &(*ptr)->next) | |
5360 | - ; | |
5361 | - | |
5362 | - cs->next = 0; | |
5363 | - *ptr = cs; | |
5364 | -} | |
5365 | - | |
5366 | +/* A helper function for validate which sets the target wide big- and | |
5367 | + little-endian character set names, if possible. */ | |
5368 | ||
5369 | -static struct charset * | |
5370 | -lookup_charset (const char *name) | |
5371 | +static void | |
5372 | +set_be_le_names (void) | |
5373 | { | |
5374 | - struct charset *cs; | |
5375 | + int i, len; | |
5376 | ||
5377 | - for (cs = all_charsets; cs; cs = cs->next) | |
5378 | - if (! strcmp (name, cs->name)) | |
5379 | - return cs; | |
5380 | + target_wide_charset_le_name = NULL; | |
5381 | + target_wide_charset_be_name = NULL; | |
5382 | ||
5383 | - return NULL; | |
5384 | + len = strlen (target_wide_charset_name); | |
5385 | + for (i = 0; charset_enum[i]; ++i) | |
5386 | + { | |
5387 | + if (strncmp (target_wide_charset_name, charset_enum[i], len)) | |
5388 | + continue; | |
5389 | + if ((charset_enum[i][len] == 'B' | |
5390 | + || charset_enum[i][len] == 'L') | |
5391 | + && charset_enum[i][len + 1] == 'E' | |
5392 | + && charset_enum[i][len + 2] == '\0') | |
5393 | + { | |
5394 | + if (charset_enum[i][len] == 'B') | |
5395 | + target_wide_charset_be_name = charset_enum[i]; | |
5396 | + else | |
5397 | + target_wide_charset_le_name = charset_enum[i]; | |
5398 | + } | |
5399 | + } | |
5400 | } | |
5401 | ||
5402 | - | |
5403 | -/* The global list of translations. */ | |
5404 | -static struct translation *all_translations; | |
5405 | - | |
5406 | +/* 'Set charset', 'set host-charset', 'set target-charset', 'set | |
5407 | + target-wide-charset', 'set charset' sfunc's. */ | |
5408 | ||
5409 | static void | |
5410 | -register_translation (struct translation *t) | |
5411 | +validate (void) | |
5412 | { | |
5413 | - t->next = all_translations; | |
5414 | - all_translations = t; | |
5415 | -} | |
5416 | - | |
5417 | - | |
5418 | -static struct translation * | |
5419 | -lookup_translation (const char *from, const char *to) | |
5420 | -{ | |
5421 | - struct translation *t; | |
5422 | - | |
5423 | - for (t = all_translations; t; t = t->next) | |
5424 | - if (! strcmp (from, t->from) | |
5425 | - && ! strcmp (to, t->to)) | |
5426 | - return t; | |
5427 | + iconv_t desc; | |
5428 | + const char *host_cset = host_charset (); | |
5429 | ||
5430 | - return 0; | |
5431 | -} | |
5432 | - | |
5433 | - | |
5434 | -\f | |
5435 | -/* Constructing charsets. */ | |
5436 | - | |
5437 | -/* Allocate, initialize and return a straightforward charset. | |
5438 | - Use this function, rather than creating the structures yourself, | |
5439 | - so that we can add new fields to the structure in the future without | |
5440 | - having to tweak all the old charset descriptions. */ | |
5441 | -static struct charset * | |
5442 | -simple_charset (const char *name, | |
5443 | - int valid_host_charset, | |
5444 | - int (*host_char_print_literally) (void *baton, int host_char), | |
5445 | - void *host_char_print_literally_baton, | |
5446 | - int (*target_char_to_control_char) (void *baton, | |
5447 | - int target_char, | |
5448 | - int *target_ctrl_char), | |
5449 | - void *target_char_to_control_char_baton) | |
5450 | -{ | |
5451 | - struct charset *cs = xmalloc (sizeof (*cs)); | |
5452 | + desc = iconv_open (target_wide_charset_name, host_cset); | |
5453 | + if (desc == (iconv_t) -1) | |
5454 | + error ("Cannot convert between character sets `%s' and `%s'", | |
5455 | + target_wide_charset_name, host_cset); | |
5456 | + iconv_close (desc); | |
5457 | ||
5458 | - memset (cs, 0, sizeof (*cs)); | |
5459 | - cs->name = name; | |
5460 | - cs->valid_host_charset = valid_host_charset; | |
5461 | - cs->host_char_print_literally = host_char_print_literally; | |
5462 | - cs->host_char_print_literally_baton = host_char_print_literally_baton; | |
5463 | - cs->target_char_to_control_char = target_char_to_control_char; | |
5464 | - cs->target_char_to_control_char_baton = target_char_to_control_char_baton; | |
5465 | + desc = iconv_open (target_charset_name, host_cset); | |
5466 | + if (desc == (iconv_t) -1) | |
5467 | + error ("Cannot convert between character sets `%s' and `%s'", | |
5468 | + target_charset_name, host_cset); | |
5469 | + iconv_close (desc); | |
5470 | ||
5471 | - return cs; | |
5472 | + set_be_le_names (); | |
5473 | } | |
5474 | ||
5475 | - | |
5476 | -\f | |
5477 | -/* ASCII functions. */ | |
5478 | - | |
5479 | -static int | |
5480 | -ascii_print_literally (void *baton, int c) | |
5481 | +/* This is the sfunc for the 'set charset' command. */ | |
5482 | +static void | |
5483 | +set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c) | |
5484 | { | |
5485 | - c &= 0xff; | |
5486 | - | |
5487 | - return (0x20 <= c && c <= 0x7e); | |
5488 | + /* CAREFUL: set the target charset here as well. */ | |
5489 | + target_charset_name = host_charset_name; | |
5490 | + validate (); | |
5491 | } | |
5492 | ||
5493 | - | |
5494 | -static int | |
5495 | -ascii_to_control (void *baton, int c, int *ctrl_char) | |
5496 | +/* 'set host-charset' command sfunc. We need a wrapper here because | |
5497 | + the function needs to have a specific signature. */ | |
5498 | +static void | |
5499 | +set_host_charset_sfunc (char *charset, int from_tty, | |
5500 | + struct cmd_list_element *c) | |
5501 | { | |
5502 | - *ctrl_char = (c & 037); | |
5503 | - return 1; | |
5504 | + validate (); | |
5505 | } | |
5506 | ||
5507 | -\f | |
5508 | -/* ISO-8859 family functions. */ | |
5509 | - | |
5510 | - | |
5511 | -static int | |
5512 | -iso_8859_print_literally (void *baton, int c) | |
5513 | +/* Wrapper for the 'set target-charset' command. */ | |
5514 | +static void | |
5515 | +set_target_charset_sfunc (char *charset, int from_tty, | |
5516 | + struct cmd_list_element *c) | |
5517 | { | |
5518 | - c &= 0xff; | |
5519 | - | |
5520 | - return ((0x20 <= c && c <= 0x7e) /* ascii printables */ | |
5521 | - || (! sevenbit_strings && 0xA0 <= c)); /* iso 8859 printables */ | |
5522 | + validate (); | |
5523 | } | |
5524 | ||
5525 | - | |
5526 | -static int | |
5527 | -iso_8859_to_control (void *baton, int c, int *ctrl_char) | |
5528 | +/* Wrapper for the 'set target-wide-charset' command. */ | |
5529 | +static void | |
5530 | +set_target_wide_charset_sfunc (char *charset, int from_tty, | |
5531 | + struct cmd_list_element *c) | |
5532 | { | |
5533 | - *ctrl_char = (c & 0200) | (c & 037); | |
5534 | - return 1; | |
5535 | + validate (); | |
5536 | } | |
5537 | ||
5538 | - | |
5539 | -/* Construct an ISO-8859-like character set. */ | |
5540 | -static struct charset * | |
5541 | -iso_8859_family_charset (const char *name) | |
5542 | +/* sfunc for the 'show charset' command. */ | |
5543 | +static void | |
5544 | +show_charset (struct ui_file *file, int from_tty, struct cmd_list_element *c, | |
5545 | + const char *name) | |
5546 | { | |
5547 | - return simple_charset (name, 1, | |
5548 | - iso_8859_print_literally, 0, | |
5549 | - iso_8859_to_control, 0); | |
5550 | + show_host_charset_name (file, from_tty, c, host_charset_name); | |
5551 | + show_target_charset_name (file, from_tty, c, target_charset_name); | |
5552 | + show_target_wide_charset_name (file, from_tty, c, target_wide_charset_name); | |
5553 | } | |
5554 | ||
5555 | - | |
5556 | \f | |
5557 | -/* EBCDIC family functions. */ | |
5558 | - | |
5559 | - | |
5560 | -static int | |
5561 | -ebcdic_print_literally (void *baton, int c) | |
5562 | -{ | |
5563 | - c &= 0xff; | |
5564 | - | |
5565 | - return (64 <= c && c <= 254); | |
5566 | -} | |
5567 | - | |
5568 | +/* Accessor functions. */ | |
5569 | ||
5570 | -static int | |
5571 | -ebcdic_to_control (void *baton, int c, int *ctrl_char) | |
5572 | +const char * | |
5573 | +host_charset (void) | |
5574 | { | |
5575 | - /* There are no control character equivalents in EBCDIC. Use | |
5576 | - numeric escapes. */ | |
5577 | - return 0; | |
5578 | + if (!strcmp (host_charset_name, "auto")) | |
5579 | + return auto_host_charset_name; | |
5580 | + return host_charset_name; | |
5581 | } | |
5582 | ||
5583 | - | |
5584 | -/* Construct an EBCDIC-like character set. */ | |
5585 | -static struct charset * | |
5586 | -ebcdic_family_charset (const char *name) | |
5587 | +const char * | |
5588 | +target_charset (void) | |
5589 | { | |
5590 | - return simple_charset (name, 0, | |
5591 | - ebcdic_print_literally, 0, | |
5592 | - ebcdic_to_control, 0); | |
5593 | + return target_charset_name; | |
5594 | } | |
5595 | - | |
5596 | - | |
5597 | - | |
5598 | - | |
5599 | -\f | |
5600 | -/* Fallback functions using iconv. */ | |
5601 | - | |
5602 | -#if defined(HAVE_ICONV) | |
5603 | ||
5604 | -struct cached_iconv { | |
5605 | - struct charset *from, *to; | |
5606 | - iconv_t i; | |
5607 | -}; | |
5608 | - | |
5609 | - | |
5610 | -/* Make sure the iconv cache *CI contains an iconv descriptor | |
5611 | - translating from FROM to TO. If it already does, fine; otherwise, | |
5612 | - close any existing descriptor, and open up a new one. On success, | |
5613 | - return zero; on failure, return -1 and set errno. */ | |
5614 | -static int | |
5615 | -check_iconv_cache (struct cached_iconv *ci, | |
5616 | - struct charset *from, | |
5617 | - struct charset *to) | |
5618 | +const char * | |
5619 | +target_wide_charset (void) | |
5620 | { | |
5621 | - iconv_t i; | |
5622 | - | |
5623 | - /* Does the cached iconv descriptor match the conversion we're trying | |
5624 | - to do now? */ | |
5625 | - if (ci->from == from | |
5626 | - && ci->to == to | |
5627 | - && ci->i != (iconv_t) 0) | |
5628 | - return 0; | |
5629 | - | |
5630 | - /* It doesn't. If we actually had any iconv descriptor open at | |
5631 | - all, close it now. */ | |
5632 | - if (ci->i != (iconv_t) 0) | |
5633 | + if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) | |
5634 | { | |
5635 | - i = ci->i; | |
5636 | - ci->i = (iconv_t) 0; | |
5637 | - | |
5638 | - if (iconv_close (i) == -1) | |
5639 | - error (_("Error closing `iconv' descriptor for " | |
5640 | - "`%s'-to-`%s' character conversion: %s"), | |
5641 | - ci->from->name, ci->to->name, safe_strerror (errno)); | |
5642 | + if (target_wide_charset_be_name) | |
5643 | + return target_wide_charset_be_name; | |
5644 | } | |
5645 | - | |
5646 | - /* Open a new iconv descriptor for the required conversion. */ | |
5647 | - i = iconv_open (to->name, from->name); | |
5648 | - if (i == (iconv_t) -1) | |
5649 | - return -1; | |
5650 | - | |
5651 | - ci->i = i; | |
5652 | - ci->from = from; | |
5653 | - ci->to = to; | |
5654 | - | |
5655 | - return 0; | |
5656 | -} | |
5657 | - | |
5658 | - | |
5659 | -/* Convert FROM_CHAR using the cached iconv conversion *CI. Return | |
5660 | - non-zero if the conversion was successful, zero otherwise. */ | |
5661 | -static int | |
5662 | -cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char) | |
5663 | -{ | |
5664 | - char from; | |
5665 | - ICONV_CONST char *from_ptr = &from; | |
5666 | - char to, *to_ptr = &to; | |
5667 | - size_t from_left = sizeof (from), to_left = sizeof (to); | |
5668 | - | |
5669 | - gdb_assert (ci->i != (iconv_t) 0); | |
5670 | - | |
5671 | - from = from_char; | |
5672 | - if (iconv (ci->i, &from_ptr, &from_left, &to_ptr, &to_left) | |
5673 | - == (size_t) -1) | |
5674 | + else | |
5675 | { | |
5676 | - /* These all suggest that the input or output character sets | |
5677 | - have multi-byte encodings of some characters, which means | |
5678 | - it's unsuitable for use as a GDB character set. We should | |
5679 | - never have selected it. */ | |
5680 | - gdb_assert (errno != E2BIG && errno != EINVAL); | |
5681 | - | |
5682 | - /* This suggests a bug in the code managing *CI. */ | |
5683 | - gdb_assert (errno != EBADF); | |
5684 | - | |
5685 | - /* This seems to mean that there is no equivalent character in | |
5686 | - the `to' character set. */ | |
5687 | - if (errno == EILSEQ) | |
5688 | - return 0; | |
5689 | - | |
5690 | - /* Anything else is mysterious. */ | |
5691 | - internal_error (__FILE__, __LINE__, | |
5692 | - _("Error converting character `%d' from `%s' to `%s' " | |
5693 | - "character set: %s"), | |
5694 | - from_char, ci->from->name, ci->to->name, | |
5695 | - safe_strerror (errno)); | |
5696 | + if (target_wide_charset_le_name) | |
5697 | + return target_wide_charset_le_name; | |
5698 | } | |
5699 | ||
5700 | - /* If the pointers weren't advanced across the input, that also | |
5701 | - suggests something was wrong. */ | |
5702 | - gdb_assert (from_left == 0 && to_left == 0); | |
5703 | - | |
5704 | - *to_char = (unsigned char) to; | |
5705 | - return 1; | |
5706 | + return target_wide_charset_name; | |
5707 | } | |
5708 | ||
5709 | - | |
5710 | -static void | |
5711 | -register_iconv_charsets (void) | |
5712 | -{ | |
5713 | - /* Here we should check whether various character sets were | |
5714 | - recognized by the local iconv implementation. | |
5715 | - | |
5716 | - The first implementation registered a bunch of character sets | |
5717 | - recognized by iconv, but then we discovered that iconv on Solaris | |
5718 | - and iconv on GNU/Linux had no character sets in common. So we | |
5719 | - replaced them with the hard-coded tables that appear later in the | |
5720 | - file. */ | |
5721 | -} | |
5722 | - | |
5723 | -#endif /* defined (HAVE_ICONV) */ | |
5724 | - | |
5725 | \f | |
5726 | -/* Fallback routines for systems without iconv. */ | |
5727 | +/* Host character set management. For the time being, we assume that | |
5728 | + the host character set is some superset of ASCII. */ | |
5729 | ||
5730 | -#if ! defined (HAVE_ICONV) | |
5731 | -struct cached_iconv { char nothing; }; | |
5732 | - | |
5733 | -static int | |
5734 | -check_iconv_cache (struct cached_iconv *ci, | |
5735 | - struct charset *from, | |
5736 | - struct charset *to) | |
5737 | +char | |
5738 | +host_letter_to_control_character (char c) | |
5739 | { | |
5740 | - errno = EINVAL; | |
5741 | - return -1; | |
5742 | + if (c == '?') | |
5743 | + return 0177; | |
5744 | + return c & 0237; | |
5745 | } | |
5746 | ||
5747 | -static int | |
5748 | -cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char) | |
5749 | -{ | |
5750 | - /* This function should never be called. */ | |
5751 | - gdb_assert (0); | |
5752 | -} | |
5753 | +/* Convert a host character, C, to its hex value. C must already have | |
5754 | + been validated using isxdigit. */ | |
5755 | ||
5756 | -static void | |
5757 | -register_iconv_charsets (void) | |
5758 | -{ | |
5759 | -} | |
5760 | - | |
5761 | -#endif /* ! defined(HAVE_ICONV) */ | |
5762 | - | |
5763 | -\f | |
5764 | -/* Default trivial conversion functions. */ | |
5765 | - | |
5766 | -static int | |
5767 | -identity_either_char_to_other (void *baton, int either_char, int *other_char) | |
5768 | +int | |
5769 | +host_hex_value (char c) | |
5770 | { | |
5771 | - *other_char = either_char; | |
5772 | - return 1; | |
5773 | + if (isdigit (c)) | |
5774 | + return c - '0'; | |
5775 | + if (c >= 'a' && c <= 'f') | |
5776 | + return 10 + c - 'a'; | |
5777 | + gdb_assert (c >= 'A' && c <= 'F'); | |
5778 | + return 10 + c - 'A'; | |
5779 | } | |
5780 | ||
5781 | - | |
5782 | \f | |
5783 | -/* Default non-trivial conversion functions. */ | |
5784 | - | |
5785 | - | |
5786 | -static char backslashable[] = "abfnrtv"; | |
5787 | -static char *backslashed[] = {"a", "b", "f", "n", "r", "t", "v", "0"}; | |
5788 | -static char represented[] = "\a\b\f\n\r\t\v"; | |
5789 | - | |
5790 | - | |
5791 | -/* Translate TARGET_CHAR into the host character set, and see if it | |
5792 | - matches any of our standard escape sequences. */ | |
5793 | -static const char * | |
5794 | -default_c_target_char_has_backslash_escape (void *baton, int target_char) | |
5795 | -{ | |
5796 | - int host_char; | |
5797 | - const char *ix; | |
5798 | - | |
5799 | - /* If target_char has no equivalent in the host character set, | |
5800 | - assume it doesn't have a backslashed form. */ | |
5801 | - if (! target_char_to_host (target_char, &host_char)) | |
5802 | - return NULL; | |
5803 | - | |
5804 | - ix = strchr (represented, host_char); | |
5805 | - if (ix) | |
5806 | - return backslashed[ix - represented]; | |
5807 | - else | |
5808 | - return NULL; | |
5809 | -} | |
5810 | - | |
5811 | - | |
5812 | -/* Translate the backslash the way we would in the host character set, | |
5813 | - and then try to translate that into the target character set. */ | |
5814 | -static int | |
5815 | -default_c_parse_backslash (void *baton, int host_char, int *target_char) | |
5816 | -{ | |
5817 | - const char *ix; | |
5818 | - | |
5819 | - ix = strchr (backslashable, host_char); | |
5820 | - | |
5821 | - if (! ix) | |
5822 | - return 0; | |
5823 | - else | |
5824 | - return host_char_to_target (represented[ix - backslashable], | |
5825 | - target_char); | |
5826 | -} | |
5827 | +/* Public character management functions. */ | |
5828 | ||
5829 | +/* A cleanup function which is run to close an iconv descriptor. */ | |
5830 | ||
5831 | -/* Convert using a cached iconv descriptor. */ | |
5832 | -static int | |
5833 | -iconv_convert (void *baton, int from_char, int *to_char) | |
5834 | +static void | |
5835 | +cleanup_iconv (void *p) | |
5836 | { | |
5837 | - struct cached_iconv *ci = baton; | |
5838 | - return cached_iconv_convert (ci, from_char, to_char); | |
5839 | + iconv_t *descp = p; | |
5840 | + iconv_close (*descp); | |
5841 | } | |
5842 | ||
5843 | +void | |
5844 | +convert_between_encodings (const char *from, const char *to, | |
5845 | + const gdb_byte *bytes, unsigned int num_bytes, | |
5846 | + int width, struct obstack *output, | |
5847 | + enum transliterations translit) | |
5848 | +{ | |
5849 | + iconv_t desc; | |
5850 | + struct cleanup *cleanups; | |
5851 | + size_t inleft; | |
5852 | + char *inp; | |
5853 | + unsigned int space_request; | |
5854 | + | |
5855 | + /* Often, the host and target charsets will be the same. */ | |
5856 | + if (!strcmp (from, to)) | |
5857 | + { | |
5858 | + obstack_grow (output, bytes, num_bytes); | |
5859 | + return; | |
5860 | + } | |
5861 | ||
5862 | -\f | |
5863 | -/* Conversion tables. */ | |
5864 | - | |
5865 | - | |
5866 | -/* I'd much rather fall back on iconv whenever possible. But the | |
5867 | - character set names you use with iconv aren't standardized at all, | |
5868 | - a lot of platforms have really meager character set coverage, etc. | |
5869 | - I wanted to have at least something we could use to exercise the | |
5870 | - test suite on all platforms. | |
5871 | - | |
5872 | - In the long run, we should have a configure-time process explore | |
5873 | - somehow which character sets the host platform supports, and some | |
5874 | - arrangement that allows GDB users to use platform-indepedent names | |
5875 | - for character sets. */ | |
5876 | - | |
5877 | - | |
5878 | -/* We generated these tables using iconv on a GNU/Linux machine. */ | |
5879 | - | |
5880 | - | |
5881 | -static int ascii_to_iso_8859_1_table[] = { | |
5882 | - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ | |
5883 | - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */ | |
5884 | - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */ | |
5885 | - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */ | |
5886 | - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 80 */ | |
5887 | - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 96 */ | |
5888 | - 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 112 */ | |
5889 | - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 128 */ | |
5890 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */ | |
5891 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */ | |
5892 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */ | |
5893 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ | |
5894 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */ | |
5895 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */ | |
5896 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */ | |
5897 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */ | |
5898 | -}; | |
5899 | - | |
5900 | - | |
5901 | -static int ascii_to_ebcdic_us_table[] = { | |
5902 | - 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */ | |
5903 | - 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */ | |
5904 | - 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */ | |
5905 | - 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */ | |
5906 | - 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */ | |
5907 | - 215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109, /* 96 */ | |
5908 | - 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */ | |
5909 | - 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */ | |
5910 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */ | |
5911 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */ | |
5912 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */ | |
5913 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ | |
5914 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */ | |
5915 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */ | |
5916 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */ | |
5917 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */ | |
5918 | -}; | |
5919 | - | |
5920 | - | |
5921 | -static int ascii_to_ibm1047_table[] = { | |
5922 | - 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */ | |
5923 | - 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */ | |
5924 | - 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */ | |
5925 | - 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */ | |
5926 | - 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */ | |
5927 | - 215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109, /* 96 */ | |
5928 | - 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */ | |
5929 | - 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */ | |
5930 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */ | |
5931 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */ | |
5932 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */ | |
5933 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ | |
5934 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */ | |
5935 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */ | |
5936 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */ | |
5937 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */ | |
5938 | -}; | |
5939 | - | |
5940 | - | |
5941 | -static int iso_8859_1_to_ascii_table[] = { | |
5942 | - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ | |
5943 | - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */ | |
5944 | - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */ | |
5945 | - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */ | |
5946 | - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 80 */ | |
5947 | - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 96 */ | |
5948 | - 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 112 */ | |
5949 | - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 128 */ | |
5950 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */ | |
5951 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */ | |
5952 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */ | |
5953 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ | |
5954 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */ | |
5955 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */ | |
5956 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */ | |
5957 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */ | |
5958 | -}; | |
5959 | - | |
5960 | - | |
5961 | -static int iso_8859_1_to_ebcdic_us_table[] = { | |
5962 | - 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */ | |
5963 | - 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */ | |
5964 | - 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */ | |
5965 | - 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */ | |
5966 | - 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */ | |
5967 | - 215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109, /* 96 */ | |
5968 | - 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */ | |
5969 | - 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */ | |
5970 | - 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, /* 144 */ | |
5971 | - 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,255, /* 160 */ | |
5972 | - -1, -1, 74, -1, -1, -1,106, -1, -1, -1, -1, -1, 95, -1, -1, -1, /* 176 */ | |
5973 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ | |
5974 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */ | |
5975 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */ | |
5976 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */ | |
5977 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 256 */ | |
5978 | -}; | |
5979 | - | |
5980 | - | |
5981 | -static int iso_8859_1_to_ibm1047_table[] = { | |
5982 | - 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, /* 16 */ | |
5983 | - 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */ | |
5984 | - 64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */ | |
5985 | - 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */ | |
5986 | - 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */ | |
5987 | - 215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109, /* 96 */ | |
5988 | - 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */ | |
5989 | - 151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161, 7, /* 128 */ | |
5990 | - 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, /* 144 */ | |
5991 | - 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,255, /* 160 */ | |
5992 | - 65,170, 74,177,159,178,106,181,187,180,154,138,176,202,175,188, /* 176 */ | |
5993 | - 144,143,234,250,190,160,182,179,157,218,155,139,183,184,185,171, /* 192 */ | |
5994 | - 100,101, 98,102, 99,103,158,104,116,113,114,115,120,117,118,119, /* 208 */ | |
5995 | - 172,105,237,238,235,239,236,191,128,253,254,251,252,186,174, 89, /* 224 */ | |
5996 | - 68, 69, 66, 70, 67, 71,156, 72, 84, 81, 82, 83, 88, 85, 86, 87, /* 240 */ | |
5997 | - 140, 73,205,206,203,207,204,225,112,221,222,219,220,141,142,223 /* 256 */ | |
5998 | -}; | |
5999 | - | |
6000 | - | |
6001 | -static int ebcdic_us_to_ascii_table[] = { | |
6002 | - 0, 1, 2, 3, -1, 9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15, /* 16 */ | |
6003 | - 16, 17, 18, 19, -1, -1, 8, -1, 24, 25, -1, -1, 28, 29, 30, 31, /* 32 */ | |
6004 | - -1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1, 5, 6, 7, /* 48 */ | |
6005 | - -1, -1, 22, -1, -1, -1, -1, 4, -1, -1, -1, -1, 20, 21, -1, 26, /* 64 */ | |
6006 | - 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124, /* 80 */ | |
6007 | - 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, -1, /* 96 */ | |
6008 | - 45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63, /* 112 */ | |
6009 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */ | |
6010 | - -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */ | |
6011 | - -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */ | |
6012 | - -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1, /* 176 */ | |
6013 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ | |
6014 | - 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */ | |
6015 | - 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */ | |
6016 | - 92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */ | |
6017 | - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1 /* 256 */ | |
6018 | -}; | |
6019 | - | |
6020 | - | |
6021 | -static int ebcdic_us_to_iso_8859_1_table[] = { | |
6022 | - 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15, /* 16 */ | |
6023 | - 16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31, /* 32 */ | |
6024 | - 128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7, /* 48 */ | |
6025 | - 144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26, /* 64 */ | |
6026 | - 32, -1, -1, -1, -1, -1, -1, -1, -1, -1,162, 46, 60, 40, 43,124, /* 80 */ | |
6027 | - 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59,172, /* 96 */ | |
6028 | - 45, 47, -1, -1, -1, -1, -1, -1, -1, -1,166, 44, 37, 95, 62, 63, /* 112 */ | |
6029 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */ | |
6030 | - -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */ | |
6031 | - -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */ | |
6032 | - -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1, /* 176 */ | |
6033 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ | |
6034 | - 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */ | |
6035 | - 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */ | |
6036 | - 92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */ | |
6037 | - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,159 /* 256 */ | |
6038 | -}; | |
6039 | - | |
6040 | - | |
6041 | -static int ebcdic_us_to_ibm1047_table[] = { | |
6042 | - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ | |
6043 | - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */ | |
6044 | - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */ | |
6045 | - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */ | |
6046 | - 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79, /* 80 */ | |
6047 | - 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94,176, /* 96 */ | |
6048 | - 96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111, /* 112 */ | |
6049 | - -1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127, /* 128 */ | |
6050 | - -1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1, /* 144 */ | |
6051 | - -1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1, /* 160 */ | |
6052 | - -1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1, /* 176 */ | |
6053 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ | |
6054 | - 192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1, /* 208 */ | |
6055 | - 208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1, /* 224 */ | |
6056 | - 224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1, /* 240 */ | |
6057 | - 240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255 /* 256 */ | |
6058 | -}; | |
6059 | - | |
6060 | - | |
6061 | -static int ibm1047_to_ascii_table[] = { | |
6062 | - 0, 1, 2, 3, -1, 9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15, /* 16 */ | |
6063 | - 16, 17, 18, 19, -1, -1, 8, -1, 24, 25, -1, -1, 28, 29, 30, 31, /* 32 */ | |
6064 | - -1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1, 5, 6, 7, /* 48 */ | |
6065 | - -1, -1, 22, -1, -1, -1, -1, 4, -1, -1, -1, -1, 20, 21, -1, 26, /* 64 */ | |
6066 | - 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124, /* 80 */ | |
6067 | - 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, 94, /* 96 */ | |
6068 | - 45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63, /* 112 */ | |
6069 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */ | |
6070 | - -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */ | |
6071 | - -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */ | |
6072 | - -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, 91, -1, -1, /* 176 */ | |
6073 | - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, /* 192 */ | |
6074 | - 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */ | |
6075 | - 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */ | |
6076 | - 92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */ | |
6077 | - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1 /* 256 */ | |
6078 | -}; | |
6079 | - | |
6080 | - | |
6081 | -static int ibm1047_to_iso_8859_1_table[] = { | |
6082 | - 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15, /* 16 */ | |
6083 | - 16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31, /* 32 */ | |
6084 | - 128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7, /* 48 */ | |
6085 | - 144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26, /* 64 */ | |
6086 | - 32,160,226,228,224,225,227,229,231,241,162, 46, 60, 40, 43,124, /* 80 */ | |
6087 | - 38,233,234,235,232,237,238,239,236,223, 33, 36, 42, 41, 59, 94, /* 96 */ | |
6088 | - 45, 47,194,196,192,193,195,197,199,209,166, 44, 37, 95, 62, 63, /* 112 */ | |
6089 | - 248,201,202,203,200,205,206,207,204, 96, 58, 35, 64, 39, 61, 34, /* 128 */ | |
6090 | - 216, 97, 98, 99,100,101,102,103,104,105,171,187,240,253,254,177, /* 144 */ | |
6091 | - 176,106,107,108,109,110,111,112,113,114,170,186,230,184,198,164, /* 160 */ | |
6092 | - 181,126,115,116,117,118,119,120,121,122,161,191,208, 91,222,174, /* 176 */ | |
6093 | - 172,163,165,183,169,167,182,188,189,190,221,168,175, 93,180,215, /* 192 */ | |
6094 | - 123, 65, 66, 67, 68, 69, 70, 71, 72, 73,173,244,246,242,243,245, /* 208 */ | |
6095 | - 125, 74, 75, 76, 77, 78, 79, 80, 81, 82,185,251,252,249,250,255, /* 224 */ | |
6096 | - 92,247, 83, 84, 85, 86, 87, 88, 89, 90,178,212,214,210,211,213, /* 240 */ | |
6097 | - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,179,219,220,217,218,159 /* 256 */ | |
6098 | -}; | |
6099 | - | |
6100 | - | |
6101 | -static int ibm1047_to_ebcdic_us_table[] = { | |
6102 | - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ | |
6103 | - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */ | |
6104 | - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */ | |
6105 | - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */ | |
6106 | - 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79, /* 80 */ | |
6107 | - 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94, -1, /* 96 */ | |
6108 | - 96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111, /* 112 */ | |
6109 | - -1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127, /* 128 */ | |
6110 | - -1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1, /* 144 */ | |
6111 | - -1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1, /* 160 */ | |
6112 | - -1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1, /* 176 */ | |
6113 | - 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */ | |
6114 | - 192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1, /* 208 */ | |
6115 | - 208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1, /* 224 */ | |
6116 | - 224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1, /* 240 */ | |
6117 | - 240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255 /* 256 */ | |
6118 | -}; | |
6119 | + desc = iconv_open (to, from); | |
6120 | + if (desc == (iconv_t) -1) | |
6121 | + perror_with_name ("Converting character sets"); | |
6122 | + cleanups = make_cleanup (cleanup_iconv, &desc); | |
6123 | ||
6124 | + inleft = num_bytes; | |
6125 | + inp = (char *) bytes; | |
6126 | ||
6127 | -static int | |
6128 | -table_convert_char (void *baton, int from, int *to) | |
6129 | -{ | |
6130 | - int *table = (int *) baton; | |
6131 | + space_request = num_bytes; | |
6132 | ||
6133 | - if (0 <= from && from <= 255 | |
6134 | - && table[from] != -1) | |
6135 | + while (inleft > 0) | |
6136 | { | |
6137 | - *to = table[from]; | |
6138 | - return 1; | |
6139 | + char *outp; | |
6140 | + size_t outleft, r; | |
6141 | + int old_size; | |
6142 | + | |
6143 | + old_size = obstack_object_size (output); | |
6144 | + obstack_blank (output, space_request); | |
6145 | + | |
6146 | + outp = obstack_base (output) + old_size; | |
6147 | + outleft = space_request; | |
6148 | + | |
6149 | + r = iconv (desc, &inp, &inleft, &outp, &outleft); | |
6150 | + | |
6151 | + /* Now make sure that the object on the obstack only includes | |
6152 | + bytes we have converted. */ | |
6153 | + obstack_blank (output, - (int) outleft); | |
6154 | + | |
6155 | + if (r == (size_t) -1) | |
6156 | + { | |
6157 | + switch (errno) | |
6158 | + { | |
6159 | + case EILSEQ: | |
6160 | + { | |
6161 | + int i; | |
6162 | + | |
6163 | + /* Invalid input sequence. */ | |
6164 | + if (translit == translit_none) | |
6165 | + error (_("Could not convert character to `%s' character set"), | |
6166 | + to); | |
6167 | + | |
6168 | + /* We emit escape sequence for the bytes, skip them, | |
6169 | + and try again. */ | |
6170 | + for (i = 0; i < width; ++i) | |
6171 | + { | |
6172 | + char octal[5]; | |
6173 | + | |
6174 | + sprintf (octal, "\\%.3o", *inp & 0xff); | |
6175 | + obstack_grow_str (output, octal); | |
6176 | + | |
6177 | + ++inp; | |
6178 | + --inleft; | |
6179 | + } | |
6180 | + } | |
6181 | + break; | |
6182 | + | |
6183 | + case E2BIG: | |
6184 | + /* We ran out of space in the output buffer. Make it | |
6185 | + bigger next time around. */ | |
6186 | + space_request *= 2; | |
6187 | + break; | |
6188 | + | |
6189 | + case EINVAL: | |
6190 | + /* Incomplete input sequence. FIXME: ought to report this | |
6191 | + to the caller somehow. */ | |
6192 | + inleft = 0; | |
6193 | + break; | |
6194 | + | |
6195 | + default: | |
6196 | + perror_with_name ("Internal error while converting character sets"); | |
6197 | + } | |
6198 | + } | |
6199 | } | |
6200 | - else | |
6201 | - return 0; | |
6202 | -} | |
6203 | - | |
6204 | ||
6205 | -static struct translation * | |
6206 | -table_translation (const char *from, const char *to, int *table, | |
6207 | - const char *(*c_target_char_has_backslash_escape) | |
6208 | - (void *baton, int target_char), | |
6209 | - void *c_target_char_has_backslash_escape_baton, | |
6210 | - int (*c_parse_backslash) (void *baton, | |
6211 | - int host_char, | |
6212 | - int *target_char), | |
6213 | - void *c_parse_backslash_baton) | |
6214 | -{ | |
6215 | - struct translation *t = xmalloc (sizeof (*t)); | |
6216 | - | |
6217 | - memset (t, 0, sizeof (*t)); | |
6218 | - t->from = from; | |
6219 | - t->to = to; | |
6220 | - t->c_target_char_has_backslash_escape = c_target_char_has_backslash_escape; | |
6221 | - t->c_target_char_has_backslash_escape_baton | |
6222 | - = c_target_char_has_backslash_escape_baton; | |
6223 | - t->c_parse_backslash = c_parse_backslash; | |
6224 | - t->c_parse_backslash_baton = c_parse_backslash_baton; | |
6225 | - t->convert_char = table_convert_char; | |
6226 | - t->convert_char_baton = (void *) table; | |
6227 | - | |
6228 | - return t; | |
6229 | + do_cleanups (cleanups); | |
6230 | } | |
6231 | ||
6232 | - | |
6233 | -static struct translation * | |
6234 | -simple_table_translation (const char *from, const char *to, int *table) | |
6235 | -{ | |
6236 | - return table_translation (from, to, table, 0, 0, 0, 0); | |
6237 | -} | |
6238 | - | |
6239 | - | |
6240 | \f | |
6241 | -/* Setting and retrieving the host and target charsets. */ | |
6242 | - | |
6243 | - | |
6244 | -/* The current host and target character sets. */ | |
6245 | -static struct charset *current_host_charset, *current_target_charset; | |
6246 | - | |
6247 | -/* The current functions and batons we should use for the functions in | |
6248 | - charset.h. */ | |
6249 | - | |
6250 | -static const char *(*c_target_char_has_backslash_escape_func) | |
6251 | - (void *baton, int target_char); | |
6252 | -static void *c_target_char_has_backslash_escape_baton; | |
6253 | - | |
6254 | -static int (*c_parse_backslash_func) (void *baton, | |
6255 | - int host_char, | |
6256 | - int *target_char); | |
6257 | -static void *c_parse_backslash_baton; | |
6258 | - | |
6259 | -static int (*host_char_to_target_func) (void *baton, | |
6260 | - int host_char, | |
6261 | - int *target_char); | |
6262 | -static void *host_char_to_target_baton; | |
6263 | - | |
6264 | -static int (*target_char_to_host_func) (void *baton, | |
6265 | - int target_char, | |
6266 | - int *host_char); | |
6267 | -static void *target_char_to_host_baton; | |
6268 | ||
6269 | - | |
6270 | -/* Cached iconv conversions, that might be useful to fallback | |
6271 | - routines. */ | |
6272 | -static struct cached_iconv cached_iconv_host_to_target; | |
6273 | -static struct cached_iconv cached_iconv_target_to_host; | |
6274 | - | |
6275 | -\f | |
6276 | -/* Charset structures manipulation functions. */ | |
6277 | - | |
6278 | -static struct charset * | |
6279 | -lookup_charset_or_error (const char *name) | |
6280 | +/* An iterator that returns host wchar_t's from a target string. */ | |
6281 | +struct wchar_iterator | |
6282 | { | |
6283 | - struct charset *cs = lookup_charset (name); | |
6284 | + /* The underlying iconv descriptor. */ | |
6285 | + iconv_t desc; | |
6286 | ||
6287 | - if (! cs) | |
6288 | - error (_("GDB doesn't know of any character set named `%s'."), name); | |
6289 | + /* The input string. This is updated as convert characters. */ | |
6290 | + char *input; | |
6291 | + /* The number of bytes remaining in the input. */ | |
6292 | + size_t bytes; | |
6293 | ||
6294 | - return cs; | |
6295 | -} | |
6296 | + /* The width of an input character. */ | |
6297 | + size_t width; | |
6298 | ||
6299 | -static void | |
6300 | -check_valid_host_charset (struct charset *cs) | |
6301 | -{ | |
6302 | - if (! cs->valid_host_charset) | |
6303 | - error (_("GDB can't use `%s' as its host character set."), cs->name); | |
6304 | -} | |
6305 | + /* The output buffer and its size. */ | |
6306 | + wchar_t *out; | |
6307 | + size_t out_size; | |
6308 | +}; | |
6309 | ||
6310 | -/* Set the host and target character sets to HOST and TARGET. */ | |
6311 | -static void | |
6312 | -set_host_and_target_charsets (struct charset *host, struct charset *target) | |
6313 | +/* Create a new iterator. */ | |
6314 | +struct wchar_iterator * | |
6315 | +make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset, | |
6316 | + size_t width) | |
6317 | { | |
6318 | - struct translation *h2t, *t2h; | |
6319 | - | |
6320 | - /* If they're not both initialized yet, then just do nothing for | |
6321 | - now. As soon as we're done running our initialize function, | |
6322 | - everything will be initialized. */ | |
6323 | - if (! host || ! target) | |
6324 | - { | |
6325 | - current_host_charset = host; | |
6326 | - current_target_charset = target; | |
6327 | - return; | |
6328 | - } | |
6329 | - | |
6330 | - h2t = lookup_translation (host->name, target->name); | |
6331 | - t2h = lookup_translation (target->name, host->name); | |
6332 | - | |
6333 | - /* If the translations don't provide conversion functions, make sure | |
6334 | - iconv can back them up. Do this *before* modifying any state. */ | |
6335 | - if (host != target) | |
6336 | - { | |
6337 | - if (! h2t || ! h2t->convert_char) | |
6338 | - { | |
6339 | - if (check_iconv_cache (&cached_iconv_host_to_target, host, target) | |
6340 | - < 0) | |
6341 | - error (_("GDB can't convert from the `%s' character set to `%s'."), | |
6342 | - host->name, target->name); | |
6343 | - } | |
6344 | - if (! t2h || ! t2h->convert_char) | |
6345 | - { | |
6346 | - if (check_iconv_cache (&cached_iconv_target_to_host, target, host) | |
6347 | - < 0) | |
6348 | - error (_("GDB can't convert from the `%s' character set to `%s'."), | |
6349 | - target->name, host->name); | |
6350 | - } | |
6351 | - } | |
6352 | - | |
6353 | - if (t2h && t2h->c_target_char_has_backslash_escape) | |
6354 | - { | |
6355 | - c_target_char_has_backslash_escape_func | |
6356 | - = t2h->c_target_char_has_backslash_escape; | |
6357 | - c_target_char_has_backslash_escape_baton | |
6358 | - = t2h->c_target_char_has_backslash_escape_baton; | |
6359 | - } | |
6360 | - else | |
6361 | - c_target_char_has_backslash_escape_func | |
6362 | - = default_c_target_char_has_backslash_escape; | |
6363 | - | |
6364 | - if (h2t && h2t->c_parse_backslash) | |
6365 | - { | |
6366 | - c_parse_backslash_func = h2t->c_parse_backslash; | |
6367 | - c_parse_backslash_baton = h2t->c_parse_backslash_baton; | |
6368 | - } | |
6369 | - else | |
6370 | - c_parse_backslash_func = default_c_parse_backslash; | |
6371 | - | |
6372 | - if (h2t && h2t->convert_char) | |
6373 | - { | |
6374 | - host_char_to_target_func = h2t->convert_char; | |
6375 | - host_char_to_target_baton = h2t->convert_char_baton; | |
6376 | - } | |
6377 | - else if (host == target) | |
6378 | - host_char_to_target_func = identity_either_char_to_other; | |
6379 | - else | |
6380 | - { | |
6381 | - host_char_to_target_func = iconv_convert; | |
6382 | - host_char_to_target_baton = &cached_iconv_host_to_target; | |
6383 | - } | |
6384 | + struct wchar_iterator *result; | |
6385 | + iconv_t desc; | |
6386 | ||
6387 | - if (t2h && t2h->convert_char) | |
6388 | - { | |
6389 | - target_char_to_host_func = t2h->convert_char; | |
6390 | - target_char_to_host_baton = t2h->convert_char_baton; | |
6391 | - } | |
6392 | - else if (host == target) | |
6393 | - target_char_to_host_func = identity_either_char_to_other; | |
6394 | - else | |
6395 | - { | |
6396 | - target_char_to_host_func = iconv_convert; | |
6397 | - target_char_to_host_baton = &cached_iconv_target_to_host; | |
6398 | - } | |
6399 | + desc = iconv_open ("wchar_t", charset); | |
6400 | + if (desc == (iconv_t) -1) | |
6401 | + perror_with_name ("Converting character sets"); | |
6402 | ||
6403 | - current_host_charset = host; | |
6404 | - current_target_charset = target; | |
6405 | -} | |
6406 | - | |
6407 | -/* Do the real work of setting the host charset. */ | |
6408 | -static void | |
6409 | -set_host_charset (const char *charset) | |
6410 | -{ | |
6411 | - struct charset *cs = lookup_charset_or_error (charset); | |
6412 | - check_valid_host_charset (cs); | |
6413 | - set_host_and_target_charsets (cs, current_target_charset); | |
6414 | -} | |
6415 | + result = XNEW (struct wchar_iterator); | |
6416 | + result->desc = desc; | |
6417 | + result->input = (char *) input; | |
6418 | + result->bytes = bytes; | |
6419 | + result->width = width; | |
6420 | ||
6421 | -/* Do the real work of setting the target charset. */ | |
6422 | -static void | |
6423 | -set_target_charset (const char *charset) | |
6424 | -{ | |
6425 | - struct charset *cs = lookup_charset_or_error (charset); | |
6426 | + result->out = XNEW (wchar_t); | |
6427 | + result->out_size = 1; | |
6428 | ||
6429 | - set_host_and_target_charsets (current_host_charset, cs); | |
6430 | + return result; | |
6431 | } | |
6432 | ||
6433 | -\f | |
6434 | -/* 'Set charset', 'set host-charset', 'set target-charset', 'show | |
6435 | - charset' sfunc's. */ | |
6436 | - | |
6437 | -/* This is the sfunc for the 'set charset' command. */ | |
6438 | static void | |
6439 | -set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c) | |
6440 | +do_cleanup_iterator (void *p) | |
6441 | { | |
6442 | - struct charset *cs = lookup_charset_or_error (host_charset_name); | |
6443 | - check_valid_host_charset (cs); | |
6444 | - /* CAREFUL: set the target charset here as well. */ | |
6445 | - target_charset_name = host_charset_name; | |
6446 | - set_host_and_target_charsets (cs, cs); | |
6447 | -} | |
6448 | + struct wchar_iterator *iter = p; | |
6449 | ||
6450 | -/* 'set host-charset' command sfunc. We need a wrapper here because | |
6451 | - the function needs to have a specific signature. */ | |
6452 | -static void | |
6453 | -set_host_charset_sfunc (char *charset, int from_tty, | |
6454 | - struct cmd_list_element *c) | |
6455 | -{ | |
6456 | - set_host_charset (host_charset_name); | |
6457 | + iconv_close (iter->desc); | |
6458 | + xfree (iter->out); | |
6459 | + xfree (iter); | |
6460 | } | |
6461 | ||
6462 | -/* Wrapper for the 'set target-charset' command. */ | |
6463 | -static void | |
6464 | -set_target_charset_sfunc (char *charset, int from_tty, | |
6465 | - struct cmd_list_element *c) | |
6466 | +struct cleanup * | |
6467 | +make_cleanup_wchar_iterator (struct wchar_iterator *iter) | |
6468 | { | |
6469 | - set_target_charset (target_charset_name); | |
6470 | + return make_cleanup (do_cleanup_iterator, iter); | |
6471 | } | |
6472 | ||
6473 | -/* sfunc for the 'show charset' command. */ | |
6474 | -static void | |
6475 | -show_charset (struct ui_file *file, int from_tty, struct cmd_list_element *c, | |
6476 | - const char *name) | |
6477 | -{ | |
6478 | - if (current_host_charset == current_target_charset) | |
6479 | - fprintf_filtered (file, | |
6480 | - _("The current host and target character set is `%s'.\n"), | |
6481 | - host_charset ()); | |
6482 | - else | |
6483 | +int | |
6484 | +wchar_iterate (struct wchar_iterator *iter, | |
6485 | + enum wchar_iterate_result *out_result, | |
6486 | + wchar_t **out_chars, | |
6487 | + const gdb_byte **ptr, | |
6488 | + size_t *len) | |
6489 | +{ | |
6490 | + size_t out_request; | |
6491 | + | |
6492 | + /* Try to convert some characters. At first we try to convert just | |
6493 | + a single character. The reason for this is that iconv does not | |
6494 | + necessarily update its outgoing arguments when it encounters an | |
6495 | + invalid input sequence -- but we want to reliably report this to | |
6496 | + our caller so it can emit an escape sequence. */ | |
6497 | + out_request = 1; | |
6498 | + while (iter->bytes > 0) | |
6499 | { | |
6500 | - fprintf_filtered (file, _("The current host character set is `%s'.\n"), | |
6501 | - host_charset ()); | |
6502 | - fprintf_filtered (file, _("The current target character set is `%s'.\n"), | |
6503 | - target_charset ()); | |
6504 | + char *outptr = (char *) &iter->out[0]; | |
6505 | + char *orig_inptr = iter->input; | |
6506 | + size_t orig_in = iter->bytes; | |
6507 | + size_t out_avail = out_request * sizeof (wchar_t); | |
6508 | + size_t num; | |
6509 | + wchar_t result; | |
6510 | + | |
6511 | + size_t r = iconv (iter->desc, (char **) &iter->input, &iter->bytes, | |
6512 | + &outptr, &out_avail); | |
6513 | + if (r == (size_t) -1) | |
6514 | + { | |
6515 | + switch (errno) | |
6516 | + { | |
6517 | + case EILSEQ: | |
6518 | + /* Invalid input sequence. Skip it, and let the caller | |
6519 | + know about it. */ | |
6520 | + *out_result = wchar_iterate_invalid; | |
6521 | + *ptr = iter->input; | |
6522 | + *len = iter->width; | |
6523 | + iter->input += iter->width; | |
6524 | + iter->bytes -= iter->width; | |
6525 | + return 0; | |
6526 | + | |
6527 | + case E2BIG: | |
6528 | + /* We ran out of space. We still might have converted a | |
6529 | + character; if so, return it. Otherwise, grow the | |
6530 | + buffer and try again. */ | |
6531 | + if (out_avail < out_request * sizeof (wchar_t)) | |
6532 | + break; | |
6533 | + | |
6534 | + ++out_request; | |
6535 | + if (out_request > iter->out_size) | |
6536 | + { | |
6537 | + iter->out_size = out_request; | |
6538 | + iter->out = xrealloc (iter->out, | |
6539 | + out_request * sizeof (wchar_t)); | |
6540 | + } | |
6541 | + continue; | |
6542 | + | |
6543 | + case EINVAL: | |
6544 | + /* Incomplete input sequence. Let the caller know, and | |
6545 | + arrange for future calls to see EOF. */ | |
6546 | + *out_result = wchar_iterate_incomplete; | |
6547 | + *ptr = iter->input; | |
6548 | + *len = iter->bytes; | |
6549 | + iter->bytes = 0; | |
6550 | + return 0; | |
6551 | + | |
6552 | + default: | |
6553 | + perror_with_name ("Internal error while converting character sets"); | |
6554 | + } | |
6555 | + } | |
6556 | + | |
6557 | + /* We converted something. */ | |
6558 | + num = out_request - out_avail / sizeof (wchar_t); | |
6559 | + *out_result = wchar_iterate_ok; | |
6560 | + *out_chars = iter->out; | |
6561 | + *ptr = orig_inptr; | |
6562 | + *len = orig_in - iter->bytes; | |
6563 | + return num; | |
6564 | } | |
6565 | + | |
6566 | + /* Really done. */ | |
6567 | + *out_result = wchar_iterate_eof; | |
6568 | + return -1; | |
6569 | } | |
6570 | ||
6571 | \f | |
6572 | -/* Accessor functions. */ | |
6573 | +/* The charset.c module initialization function. */ | |
6574 | ||
6575 | -const char * | |
6576 | -host_charset (void) | |
6577 | -{ | |
6578 | - return current_host_charset->name; | |
6579 | -} | |
6580 | +extern initialize_file_ftype _initialize_charset; /* -Wmissing-prototype */ | |
6581 | ||
6582 | -const char * | |
6583 | -target_charset (void) | |
6584 | -{ | |
6585 | - return current_target_charset->name; | |
6586 | -} | |
6587 | +typedef char *char_ptr; | |
6588 | +DEF_VEC_P (char_ptr); | |
6589 | ||
6590 | +static VEC (char_ptr) *charsets; | |
6591 | ||
6592 | -\f | |
6593 | -/* Public character management functions. */ | |
6594 | +#ifdef HAVE_ICONVLIST | |
6595 | ||
6596 | +/* A helper function that adds some character sets to the vector of | |
6597 | + all character sets. This is a callback function for iconvlist. */ | |
6598 | ||
6599 | -const char * | |
6600 | -c_target_char_has_backslash_escape (int target_char) | |
6601 | +static int | |
6602 | +add_one (unsigned int count, const char *const *names, void *data) | |
6603 | { | |
6604 | - return ((*c_target_char_has_backslash_escape_func) | |
6605 | - (c_target_char_has_backslash_escape_baton, target_char)); | |
6606 | -} | |
6607 | + unsigned int i; | |
6608 | ||
6609 | + for (i = 0; i < count; ++i) | |
6610 | + VEC_safe_push (char_ptr, charsets, xstrdup (names[i])); | |
6611 | ||
6612 | -int | |
6613 | -c_parse_backslash (int host_char, int *target_char) | |
6614 | -{ | |
6615 | - return (*c_parse_backslash_func) (c_parse_backslash_baton, | |
6616 | - host_char, target_char); | |
6617 | + return 0; | |
6618 | } | |
6619 | ||
6620 | - | |
6621 | -int | |
6622 | -host_char_print_literally (int host_char) | |
6623 | +static void | |
6624 | +find_charset_names (void) | |
6625 | { | |
6626 | - return ((*current_host_charset->host_char_print_literally) | |
6627 | - (current_host_charset->host_char_print_literally_baton, | |
6628 | - host_char)); | |
6629 | + iconvlist (add_one, NULL); | |
6630 | + VEC_safe_push (char_ptr, charsets, NULL); | |
6631 | } | |
6632 | ||
6633 | +#else | |
6634 | ||
6635 | -int | |
6636 | -target_char_to_control_char (int target_char, int *target_ctrl_char) | |
6637 | +static void | |
6638 | +find_charset_names (void) | |
6639 | { | |
6640 | - return ((*current_target_charset->target_char_to_control_char) | |
6641 | - (current_target_charset->target_char_to_control_char_baton, | |
6642 | - target_char, target_ctrl_char)); | |
6643 | -} | |
6644 | + FILE *in; | |
6645 | ||
6646 | + in = popen ("iconv -l", "r"); | |
6647 | + /* It is ok to ignore errors; we'll fall back on a default. */ | |
6648 | + if (!in) | |
6649 | + return; | |
6650 | ||
6651 | -int | |
6652 | -host_char_to_target (int host_char, int *target_char) | |
6653 | -{ | |
6654 | - return ((*host_char_to_target_func) | |
6655 | - (host_char_to_target_baton, host_char, target_char)); | |
6656 | -} | |
6657 | + /* POSIX says that iconv -l uses an unspecified format. We parse | |
6658 | + the glibc format; feel free to add others as needed. */ | |
6659 | + while (!feof (in)) | |
6660 | + { | |
6661 | + /* The size of buf is chosen arbitrarily. A character set name | |
6662 | + longer than this would not be very nice. */ | |
6663 | + char buf[80]; | |
6664 | + int len; | |
6665 | + char *r = fgets (buf, sizeof (buf), in); | |
6666 | + if (!r) | |
6667 | + break; | |
6668 | + len = strlen (r); | |
6669 | + if (len <= 3) | |
6670 | + continue; | |
6671 | + if (buf[len - 2] == '/' && buf[len - 3] == '/') | |
6672 | + buf[len - 3] = '\0'; | |
6673 | + VEC_safe_push (char_ptr, charsets, xstrdup (buf)); | |
6674 | + } | |
6675 | ||
6676 | + pclose (in); | |
6677 | ||
6678 | -int | |
6679 | -target_char_to_host (int target_char, int *host_char) | |
6680 | -{ | |
6681 | - return ((*target_char_to_host_func) | |
6682 | - (target_char_to_host_baton, target_char, host_char)); | |
6683 | + VEC_safe_push (char_ptr, charsets, NULL); | |
6684 | } | |
6685 | ||
6686 | - | |
6687 | -\f | |
6688 | -/* The charset.c module initialization function. */ | |
6689 | - | |
6690 | -extern initialize_file_ftype _initialize_charset; /* -Wmissing-prototype */ | |
6691 | +#endif /* HAVE_ICONVLIST */ | |
6692 | ||
6693 | void | |
6694 | _initialize_charset (void) | |
6695 | { | |
6696 | struct cmd_list_element *new_cmd; | |
6697 | ||
6698 | - /* Register all the character set GDB knows about. | |
6699 | - | |
6700 | - You should use the same names that iconv does, where possible, to | |
6701 | - take advantage of the iconv-based default behaviors. | |
6702 | - | |
6703 | - CAUTION: if you register a character set, you must also register | |
6704 | - as many translations as are necessary to make that character set | |
6705 | - interoperate correctly with all the other character sets. We do | |
6706 | - provide default behaviors when no translation is available, or | |
6707 | - when a translation's function pointer for a particular operation | |
6708 | - is zero. Hopefully, these defaults will be correct often enough | |
6709 | - that we won't need to provide too many translations. */ | |
6710 | - register_charset (simple_charset ("ASCII", 1, | |
6711 | - ascii_print_literally, 0, | |
6712 | - ascii_to_control, 0)); | |
6713 | - register_charset (iso_8859_family_charset ("ISO-8859-1")); | |
6714 | - register_charset (ebcdic_family_charset ("EBCDIC-US")); | |
6715 | - register_charset (ebcdic_family_charset ("IBM1047")); | |
6716 | - register_iconv_charsets (); | |
6717 | - | |
6718 | - { | |
6719 | - struct { char *from; char *to; int *table; } tlist[] = { | |
6720 | - { "ASCII", "ISO-8859-1", ascii_to_iso_8859_1_table }, | |
6721 | - { "ASCII", "EBCDIC-US", ascii_to_ebcdic_us_table }, | |
6722 | - { "ASCII", "IBM1047", ascii_to_ibm1047_table }, | |
6723 | - { "ISO-8859-1", "ASCII", iso_8859_1_to_ascii_table }, | |
6724 | - { "ISO-8859-1", "EBCDIC-US", iso_8859_1_to_ebcdic_us_table }, | |
6725 | - { "ISO-8859-1", "IBM1047", iso_8859_1_to_ibm1047_table }, | |
6726 | - { "EBCDIC-US", "ASCII", ebcdic_us_to_ascii_table }, | |
6727 | - { "EBCDIC-US", "ISO-8859-1", ebcdic_us_to_iso_8859_1_table }, | |
6728 | - { "EBCDIC-US", "IBM1047", ebcdic_us_to_ibm1047_table }, | |
6729 | - { "IBM1047", "ASCII", ibm1047_to_ascii_table }, | |
6730 | - { "IBM1047", "ISO-8859-1", ibm1047_to_iso_8859_1_table }, | |
6731 | - { "IBM1047", "EBCDIC-US", ibm1047_to_ebcdic_us_table } | |
6732 | - }; | |
6733 | - | |
6734 | - int i; | |
6735 | - | |
6736 | - for (i = 0; i < (sizeof (tlist) / sizeof (tlist[0])); i++) | |
6737 | - register_translation (simple_table_translation (tlist[i].from, | |
6738 | - tlist[i].to, | |
6739 | - tlist[i].table)); | |
6740 | - } | |
6741 | - | |
6742 | - set_host_charset (host_charset_name); | |
6743 | - set_target_charset (target_charset_name); | |
6744 | + /* The first element is always "auto"; then we skip it for the | |
6745 | + commands where it is not allowed. */ | |
6746 | + VEC_safe_push (char_ptr, charsets, "auto"); | |
6747 | + find_charset_names (); | |
6748 | + | |
6749 | + if (VEC_length (char_ptr, charsets) > 1) | |
6750 | + charset_enum = default_charset_names; | |
6751 | + else | |
6752 | + charset_enum = (const char **) VEC_address (char_ptr, charsets); | |
6753 | + | |
6754 | +#ifdef HAVE_LANGINFO_CODESET | |
6755 | + auto_host_charset_name = nl_langinfo (CODESET); | |
6756 | + target_charset_name = auto_host_charset_name; | |
6757 | + | |
6758 | + set_be_le_names (); | |
6759 | +#endif | |
6760 | ||
6761 | add_setshow_enum_cmd ("charset", class_support, | |
6762 | - host_charset_enum, &host_charset_name, _("\ | |
6763 | + &charset_enum[1], &host_charset_name, _("\ | |
6764 | Set the host and target character sets."), _("\ | |
6765 | Show the host and target character sets."), _("\ | |
6766 | The `host character set' is the one used by the system GDB is running on.\n\ | |
6767 | @@ -1249,7 +650,7 @@ To see a list of the character sets GDB supports, type `set charset <TAB>'."), | |
6768 | &setlist, &showlist); | |
6769 | ||
6770 | add_setshow_enum_cmd ("host-charset", class_support, | |
6771 | - host_charset_enum, &host_charset_name, _("\ | |
6772 | + charset_enum, &host_charset_name, _("\ | |
6773 | Set the host character set."), _("\ | |
6774 | Show the host character set."), _("\ | |
6775 | The `host character set' is the one used by the system GDB is running on.\n\ | |
6776 | @@ -1261,7 +662,7 @@ To see a list of the character sets GDB supports, type `set host-charset <TAB>'. | |
6777 | &setlist, &showlist); | |
6778 | ||
6779 | add_setshow_enum_cmd ("target-charset", class_support, | |
6780 | - target_charset_enum, &target_charset_name, _("\ | |
6781 | + &charset_enum[1], &target_charset_name, _("\ | |
6782 | Set the target character set."), _("\ | |
6783 | Show the target character set."), _("\ | |
6784 | The `target character set' is the one used by the program being debugged.\n\ | |
6785 | @@ -1271,4 +672,19 @@ To see a list of the character sets GDB supports, type `set target-charset'<TAB> | |
6786 | set_target_charset_sfunc, | |
6787 | show_target_charset_name, | |
6788 | &setlist, &showlist); | |
6789 | + | |
6790 | + add_setshow_enum_cmd ("target-wide-charset", class_support, | |
6791 | + &charset_enum[1], &target_wide_charset_name, | |
6792 | + _("\ | |
6793 | +Set the target wide character set."), _("\ | |
6794 | +Show the target wide character set."), _("\ | |
6795 | +The `target wide character set' is the one used by the program being debugged.\n\ | |
6796 | +In particular it is the encoding used by `wchar_t'.\n\ | |
6797 | +GDB translates characters and strings between the host and target\n\ | |
6798 | +character sets as needed.\n\ | |
6799 | +To see a list of the character sets GDB supports, type\n\ | |
6800 | +`set target-wide-charset'<TAB>"), | |
6801 | + set_target_wide_charset_sfunc, | |
6802 | + show_target_wide_charset_name, | |
6803 | + &setlist, &showlist); | |
6804 | } | |
6805 | diff --git a/gdb/charset.h b/gdb/charset.h | |
6806 | index 21780b6..2455355 100644 | |
6807 | --- a/gdb/charset.h | |
6808 | +++ b/gdb/charset.h | |
6809 | @@ -19,6 +19,7 @@ | |
6810 | #ifndef CHARSET_H | |
6811 | #define CHARSET_H | |
6812 | ||
6813 | +#include <wchar.h> | |
6814 | ||
6815 | /* If the target program uses a different character set than the host, | |
6816 | GDB has some support for translating between the two; GDB converts | |
6817 | @@ -26,82 +27,123 @@ | |
6818 | them, and converts characters and strings appearing in expressions | |
6819 | entered by the user to the target character set. | |
6820 | ||
6821 | - At the moment, GDB only supports single-byte, stateless character | |
6822 | - sets. This includes the ISO-8859 family (ASCII extended with | |
6823 | - accented characters, and (I think) Cyrillic, for European | |
6824 | - languages), and the EBCDIC family (used on IBM's mainframes). | |
6825 | - Unfortunately, it excludes many Asian scripts, the fixed- and | |
6826 | - variable-width Unicode encodings, and other desireable things. | |
6827 | - Patches are welcome! (For example, it would be nice if the Java | |
6828 | - string support could simply get absorbed into some more general | |
6829 | - multi-byte encoding support.) | |
6830 | - | |
6831 | - Furthermore, GDB's code pretty much assumes that the host character | |
6832 | - set is some superset of ASCII; there are plenty if ('0' + n) | |
6833 | - expressions and the like. | |
6834 | - | |
6835 | - When the `iconv' library routine supports a character set meeting | |
6836 | - the requirements above, it's easy to plug an entry into GDB's table | |
6837 | - that uses iconv to handle the details. */ | |
6838 | + GDB's code pretty much assumes that the host character set is some | |
6839 | + superset of ASCII; there are plenty if ('0' + n) expressions and | |
6840 | + the like. */ | |
6841 | ||
6842 | /* Return the name of the current host/target character set. The | |
6843 | result is owned by the charset module; the caller should not free | |
6844 | it. */ | |
6845 | const char *host_charset (void); | |
6846 | const char *target_charset (void); | |
6847 | - | |
6848 | -/* In general, the set of C backslash escapes (\n, \f) is specific to | |
6849 | - the character set. Not all character sets will have form feed | |
6850 | - characters, for example. | |
6851 | - | |
6852 | - The following functions allow GDB to parse and print control | |
6853 | - characters in a character-set-independent way. They are both | |
6854 | - language-specific (to C and C++) and character-set-specific. | |
6855 | - Putting them here is a compromise. */ | |
6856 | - | |
6857 | - | |
6858 | -/* If the target character TARGET_CHAR have a backslash escape in the | |
6859 | - C language (i.e., a character like 'n' or 't'), return the host | |
6860 | - character string that should follow the backslash. Otherwise, | |
6861 | - return zero. | |
6862 | - | |
6863 | - When this function returns non-zero, the string it returns is | |
6864 | - statically allocated; the caller is not responsible for freeing it. */ | |
6865 | -const char *c_target_char_has_backslash_escape (int target_char); | |
6866 | - | |
6867 | - | |
6868 | -/* If the host character HOST_CHAR is a valid backslash escape in the | |
6869 | - C language for the target character set, return non-zero, and set | |
6870 | - *TARGET_CHAR to the target character the backslash escape represents. | |
6871 | - Otherwise, return zero. */ | |
6872 | -int c_parse_backslash (int host_char, int *target_char); | |
6873 | - | |
6874 | - | |
6875 | -/* Return non-zero if the host character HOST_CHAR can be printed | |
6876 | - literally --- that is, if it can be readably printed as itself in a | |
6877 | - character or string constant. Return zero if it should be printed | |
6878 | - using some kind of numeric escape, like '\031' in C, '^(25)' in | |
6879 | - Chill, or #25 in Pascal. */ | |
6880 | -int host_char_print_literally (int host_char); | |
6881 | - | |
6882 | - | |
6883 | -/* If the host character HOST_CHAR has an equivalent in the target | |
6884 | - character set, set *TARGET_CHAR to that equivalent, and return | |
6885 | - non-zero. Otherwise, return zero. */ | |
6886 | -int host_char_to_target (int host_char, int *target_char); | |
6887 | - | |
6888 | - | |
6889 | -/* If the target character TARGET_CHAR has an equivalent in the host | |
6890 | - character set, set *HOST_CHAR to that equivalent, and return | |
6891 | - non-zero. Otherwise, return zero. */ | |
6892 | -int target_char_to_host (int target_char, int *host_char); | |
6893 | - | |
6894 | - | |
6895 | -/* If the target character TARGET_CHAR has a corresponding control | |
6896 | - character (also in the target character set), set *TARGET_CTRL_CHAR | |
6897 | - to the control character, and return non-zero. Otherwise, return | |
6898 | - zero. */ | |
6899 | -int target_char_to_control_char (int target_char, int *target_ctrl_char); | |
6900 | - | |
6901 | +const char *target_wide_charset (void); | |
6902 | + | |
6903 | +/* These values are used to specify the type of transliteration done | |
6904 | + by convert_between_encodings. */ | |
6905 | +enum transliterations | |
6906 | + { | |
6907 | + /* Error on failure to convert. */ | |
6908 | + translit_none, | |
6909 | + /* Transliterate to host char. */ | |
6910 | + translit_char | |
6911 | + }; | |
6912 | + | |
6913 | +/* Convert between two encodings. | |
6914 | + | |
6915 | + FROM is the name of the source encoding. | |
6916 | + TO is the name of the target encoding. | |
6917 | + BYTES holds the bytes to convert; this is assumed to be characters | |
6918 | + in the target encoding. | |
6919 | + NUM_BYTES is the number of bytes. | |
6920 | + WIDTH is the width of a character from the FROM charset, in bytes. | |
6921 | + For a variable width encoding, WIDTH should be the size of a "base | |
6922 | + character". | |
6923 | + OUTPUT is an obstack where the converted data is written. The | |
6924 | + caller is responsible for initializing the obstack, and for | |
6925 | + destroying the obstack should an error occur. | |
6926 | + TRANSLIT specifies how invalid conversions should be handled. */ | |
6927 | +void convert_between_encodings (const char *from, const char *to, | |
6928 | + const gdb_byte *bytes, unsigned int num_bytes, | |
6929 | + int width, struct obstack *output, | |
6930 | + enum transliterations translit); | |
6931 | + | |
6932 | + | |
6933 | +/* These values are used by wchar_iterate to report errors. */ | |
6934 | +enum wchar_iterate_result | |
6935 | + { | |
6936 | + /* Ordinary return. */ | |
6937 | + wchar_iterate_ok, | |
6938 | + /* Invalid input sequence. */ | |
6939 | + wchar_iterate_invalid, | |
6940 | + /* Incomplete input sequence at the end of the input. */ | |
6941 | + wchar_iterate_incomplete, | |
6942 | + /* EOF. */ | |
6943 | + wchar_iterate_eof | |
6944 | + }; | |
6945 | + | |
6946 | +/* Declaration of the opaque wchar iterator type. */ | |
6947 | +struct wchar_iterator; | |
6948 | + | |
6949 | +/* Create a new character iterator which returns wchar_t's. INPUT is | |
6950 | + the input buffer. BYTES is the number of bytes in the input | |
6951 | + buffer. CHARSET is the name of the character set in which INPUT is | |
6952 | + encoded. WIDTH is the number of bytes in a base character of | |
6953 | + CHARSET. | |
6954 | + | |
6955 | + This function either returns a new character set iterator, or calls | |
6956 | + error. The result can be freed using a cleanup; see | |
6957 | + make_cleanup_wchar_iterator. */ | |
6958 | +struct wchar_iterator *make_wchar_iterator (const gdb_byte *input, size_t bytes, | |
6959 | + const char *charset, | |
6960 | + size_t width); | |
6961 | + | |
6962 | +/* Return a new cleanup suitable for destroying the wchar iterator | |
6963 | + ITER. */ | |
6964 | +struct cleanup *make_cleanup_wchar_iterator (struct wchar_iterator *iter); | |
6965 | + | |
6966 | +/* Perform a single iteration of a wchar_t iterator. | |
6967 | + | |
6968 | + Returns the number of characters converted. A negative result | |
6969 | + means that EOF has been reached. A positive result indicates the | |
6970 | + number of valid wchar_ts in the result; *OUT_CHARS is updated to | |
6971 | + point to the first valid character. | |
6972 | + | |
6973 | + In all cases aside from EOF, *PTR is set to point to the first | |
6974 | + converted target byte. *LEN is set to the number of bytes | |
6975 | + converted. | |
6976 | + | |
6977 | + A zero result means one of several unusual results. *OUT_RESULT is | |
6978 | + set to indicate the type of un-ordinary return. | |
6979 | + | |
6980 | + wchar_iterate_invalid means that an invalid input character was | |
6981 | + seen. The iterator is advanced by WIDTH (the argument to | |
6982 | + make_wchar_iterator) bytes. | |
6983 | + | |
6984 | + wchar_iterate_incomplete means that an incomplete character was | |
6985 | + seen at the end of the input sequence. | |
6986 | + | |
6987 | + wchar_iterate_eof means that all bytes were successfully | |
6988 | + converted. The other output arguments are not set. */ | |
6989 | +int wchar_iterate (struct wchar_iterator *iter, | |
6990 | + enum wchar_iterate_result *out_result, | |
6991 | + wchar_t **out_chars, | |
6992 | + const gdb_byte **ptr, size_t *len); | |
6993 | + | |
6994 | +\f | |
6995 | + | |
6996 | +/* GDB needs to know a few details of its execution character set. | |
6997 | + This knowledge is isolated here and in charset.c. */ | |
6998 | + | |
6999 | +/* The escape character. */ | |
7000 | +#define HOST_ESCAPE_CHAR 27 | |
7001 | + | |
7002 | +/* Convert a letter, like 'c', to its corresponding control | |
7003 | + character. */ | |
7004 | +char host_letter_to_control_character (char c); | |
7005 | + | |
7006 | +/* Convert a hex digit character to its numeric value. E.g., 'f' is | |
7007 | + converted to 15. This function assumes that C is a valid hex | |
7008 | + digit. Both upper- and lower-case letters are recognized. */ | |
7009 | +int host_hex_value (char c); | |
7010 | ||
7011 | #endif /* CHARSET_H */ | |
7012 | diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c | |
7013 | index 4d9c4f3..5fbe398 100644 | |
7014 | --- a/gdb/cli/cli-cmds.c | |
7015 | +++ b/gdb/cli/cli-cmds.c | |
7016 | @@ -45,6 +45,8 @@ | |
7017 | #include "cli/cli-setshow.h" | |
7018 | #include "cli/cli-cmds.h" | |
7019 | ||
7020 | +#include "python/python.h" | |
7021 | + | |
7022 | #ifdef TUI | |
7023 | #include "tui/tui.h" /* For tui_active et.al. */ | |
7024 | #endif | |
7025 | @@ -178,6 +180,7 @@ struct cmd_list_element *showchecklist; | |
7026 | ||
7027 | /* Command tracing state. */ | |
7028 | ||
7029 | +static int source_python = 0; | |
7030 | int source_verbose = 0; | |
7031 | int trace_commands = 0; | |
7032 | \f | |
7033 | @@ -439,6 +442,7 @@ source_script (char *file, int from_tty) | |
7034 | struct cleanup *old_cleanups; | |
7035 | char *full_pathname = NULL; | |
7036 | int fd; | |
7037 | + int is_python; | |
7038 | ||
7039 | if (file == NULL || *file == 0) | |
7040 | { | |
7041 | @@ -471,8 +475,16 @@ source_script (char *file, int from_tty) | |
7042 | } | |
7043 | } | |
7044 | ||
7045 | + is_python = source_python; | |
7046 | + if (strlen (file) > 3 && !strcmp (&file[strlen (file) - 3], ".py")) | |
7047 | + is_python = 1; | |
7048 | + | |
7049 | stream = fdopen (fd, FOPEN_RT); | |
7050 | - script_from_file (stream, file); | |
7051 | + | |
7052 | + if (is_python) | |
7053 | + source_python_script (stream, file); | |
7054 | + else | |
7055 | + script_from_file (stream, file); | |
7056 | ||
7057 | do_cleanups (old_cleanups); | |
7058 | } | |
7059 | @@ -486,15 +498,30 @@ source_verbose_cleanup (void *old_value) | |
7060 | xfree (old_value); | |
7061 | } | |
7062 | ||
7063 | +/* A helper for source_command. Look for an argument in *ARGS. | |
7064 | + Update *ARGS by stripping leading whitespace. If an argument is | |
7065 | + found, return it (a character). Otherwise, return 0. */ | |
7066 | +static int | |
7067 | +find_argument (char **args) | |
7068 | +{ | |
7069 | + int result = 0; | |
7070 | + while (isspace ((*args)[0])) | |
7071 | + ++*args; | |
7072 | + if ((*args)[0] == '-' && isalpha ((*args)[1])) | |
7073 | + { | |
7074 | + result = (*args)[1]; | |
7075 | + *args += 3; | |
7076 | + } | |
7077 | + return result; | |
7078 | +} | |
7079 | + | |
7080 | static void | |
7081 | source_command (char *args, int from_tty) | |
7082 | { | |
7083 | struct cleanup *old_cleanups; | |
7084 | - char *file = args; | |
7085 | - int *old_source_verbose = xmalloc (sizeof(int)); | |
7086 | ||
7087 | - *old_source_verbose = source_verbose; | |
7088 | - old_cleanups = make_cleanup (source_verbose_cleanup, old_source_verbose); | |
7089 | + old_cleanups = make_cleanup_restore_integer (&source_verbose); | |
7090 | + make_cleanup_restore_integer (&source_python); | |
7091 | ||
7092 | /* -v causes the source command to run in verbose mode. | |
7093 | We still have to be able to handle filenames with spaces in a | |
7094 | @@ -502,23 +529,28 @@ source_command (char *args, int from_tty) | |
7095 | ||
7096 | if (args) | |
7097 | { | |
7098 | - /* Make sure leading white space does not break the comparisons. */ | |
7099 | - while (isspace(args[0])) | |
7100 | - args++; | |
7101 | - | |
7102 | - /* Is -v the first thing in the string? */ | |
7103 | - if (args[0] == '-' && args[1] == 'v' && isspace (args[2])) | |
7104 | + while (1) | |
7105 | { | |
7106 | - source_verbose = 1; | |
7107 | - | |
7108 | - /* Trim -v and whitespace from the filename. */ | |
7109 | - file = &args[3]; | |
7110 | - while (isspace (file[0])) | |
7111 | - file++; | |
7112 | + int arg = find_argument (&args); | |
7113 | + if (!arg) | |
7114 | + break; | |
7115 | + switch (arg) | |
7116 | + { | |
7117 | + case 'v': | |
7118 | + source_verbose = 1; | |
7119 | + break; | |
7120 | + case 'p': | |
7121 | + source_python = 1; | |
7122 | + break; | |
7123 | + default: | |
7124 | + error (_("unrecognized option -%c"), arg); | |
7125 | + } | |
7126 | } | |
7127 | } | |
7128 | ||
7129 | - source_script (file, from_tty); | |
7130 | + source_script (args, from_tty); | |
7131 | + | |
7132 | + do_cleanups (old_cleanups); | |
7133 | } | |
7134 | ||
7135 | ||
7136 | @@ -1282,7 +1314,9 @@ Read commands from a file named FILE.\n\ | |
7137 | Optional -v switch (before the filename) causes each command in\n\ | |
7138 | FILE to be echoed as it is executed.\n\ | |
7139 | Note that the file \"%s\" is read automatically in this way\n\ | |
7140 | -when GDB is started."), gdbinit); | |
7141 | +when GDB is started.\n\ | |
7142 | +Optional -p switch (before the filename) causes FILE to be evaluated\n\ | |
7143 | +as Python code."), gdbinit); | |
7144 | c = add_cmd ("source", class_support, source_command, | |
7145 | source_help_text, &cmdlist); | |
7146 | set_cmd_completer (c, filename_completer); | |
7147 | diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c | |
7148 | index ee29f2a..96e6111 100644 | |
7149 | --- a/gdb/cli/cli-dump.c | |
7150 | +++ b/gdb/cli/cli-dump.c | |
7151 | @@ -296,7 +296,7 @@ dump_value_to_file (char *cmd, char *mode, char *file_format) | |
7152 | ||
7153 | if (VALUE_LVAL (val)) | |
7154 | { | |
7155 | - vaddr = VALUE_ADDRESS (val); | |
7156 | + vaddr = value_address (val); | |
7157 | } | |
7158 | else | |
7159 | { | |
7160 | diff --git a/gdb/coffread.c b/gdb/coffread.c | |
7161 | index 6059d68..47ee601 100644 | |
7162 | --- a/gdb/coffread.c | |
7163 | +++ b/gdb/coffread.c | |
7164 | @@ -346,7 +346,7 @@ coff_alloc_type (int index) | |
7165 | We will fill it in later if we find out how. */ | |
7166 | if (type == NULL) | |
7167 | { | |
7168 | - type = alloc_type (current_objfile); | |
7169 | + type = alloc_type (current_objfile, NULL); | |
7170 | *type_addr = type; | |
7171 | } | |
7172 | return type; | |
7173 | @@ -2101,6 +2101,7 @@ static struct sym_fns coff_sym_fns = | |
7174 | coff_new_init, /* sym_new_init: init anything gbl to entire symtab */ | |
7175 | coff_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
7176 | coff_symfile_read, /* sym_read: read a symbol file into symtab */ | |
7177 | + NULL, /* sym_read_psymbols */ | |
7178 | coff_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
7179 | default_symfile_offsets, /* sym_offsets: xlate external to internal form */ | |
7180 | default_symfile_segments, /* sym_segments: Get segment information from | |
7181 | diff --git a/gdb/config.in b/gdb/config.in | |
7182 | index 6aaf77a..0c8ccab 100644 | |
7183 | --- a/gdb/config.in | |
7184 | +++ b/gdb/config.in | |
7185 | @@ -42,6 +42,12 @@ | |
7186 | language is requested. */ | |
7187 | #undef ENABLE_NLS | |
7188 | ||
7189 | +/* Global directory for GDB data files. */ | |
7190 | +#undef GDB_DATADIR | |
7191 | + | |
7192 | +/* Define if GDB datadir should be relocated when GDB is moved. */ | |
7193 | +#undef GDB_DATADIR_RELOCATABLE | |
7194 | + | |
7195 | /* Define to be a string naming the default host character set. */ | |
7196 | #undef GDB_DEFAULT_HOST_CHARSET | |
7197 | ||
7198 | @@ -169,12 +175,18 @@ | |
7199 | /* Define if you have the iconv() function. */ | |
7200 | #undef HAVE_ICONV | |
7201 | ||
7202 | +/* Define to 1 if you have the `iconvlist' function. */ | |
7203 | +#undef HAVE_ICONVLIST | |
7204 | + | |
7205 | /* Define if your compiler supports the #include_next directive. */ | |
7206 | #undef HAVE_INCLUDE_NEXT | |
7207 | ||
7208 | /* Define to 1 if you have the <inttypes.h> header file. */ | |
7209 | #undef HAVE_INTTYPES_H | |
7210 | ||
7211 | +/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */ | |
7212 | +#undef HAVE_LANGINFO_CODESET | |
7213 | + | |
7214 | /* Define if your <locale.h> file defines LC_MESSAGES. */ | |
7215 | #undef HAVE_LC_MESSAGES | |
7216 | ||
7217 | @@ -618,6 +630,9 @@ | |
7218 | 'ptrdiff_t'. */ | |
7219 | #undef PTRDIFF_T_SUFFIX | |
7220 | ||
7221 | +/* Define to install path for Python sources */ | |
7222 | +#undef PYTHONDIR | |
7223 | + | |
7224 | /* Bug reporting address */ | |
7225 | #undef REPORT_BUGS_TO | |
7226 | ||
7227 | diff --git a/gdb/configure b/gdb/configure | |
7228 | index 7579c84..3a5b582 100755 | |
7229 | --- a/gdb/configure | |
7230 | +++ b/gdb/configure | |
7231 | @@ -314,7 +314,7 @@ ac_subdirs_all="$ac_subdirs_all doc testsuite" | |
7232 | ac_subdirs_all="$ac_subdirs_all gdbtk" | |
7233 | ac_subdirs_all="$ac_subdirs_all multi-ice" | |
7234 | ac_subdirs_all="$ac_subdirs_all gdbserver" | |
7235 | -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP RANLIB ac_ct_RANLIB build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os am__leading_dot DEPDIR CCDEPMODE MAKE GMAKE_TRUE GMAKE_FALSE SET_MAKE USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT localedir GL_COND_LIBTOOL_TRUE GL_COND_LIBTOOL_FALSE GNULIB_MEMMEM GNULIB_MEMPCPY GNULIB_MEMRCHR GNULIB_STPCPY GNULIB_STPNCPY GNULIB_STRCHRNUL GNULIB_STRDUP GNULIB_STRNDUP GNULIB_STRNLEN GNULIB_STRPBRK GNULIB_STRSEP GNULIB_STRSTR GNULIB_STRCASESTR GNULIB_STRTOK_R GNULIB_MBSLEN GNULIB_MBSNLEN GNULIB_MBSCHR GNULIB_MBSRCHR GNULIB_MBSSTR GNULIB_MBSCASECMP GNULIB_MBSNCASECMP GNULIB_MBSPCASECMP GNULIB_MBSCASESTR GNULIB_MBSCSPN GNULIB_MBSPBRK GNULIB_MBSSPN GNULIB_MBSSEP GNULIB_MBSTOK_R GNULIB_STRERROR GNULIB_STRSIGNAL HAVE_DECL_MEMMEM HAVE_MEMPCPY HAVE_DECL_MEMRCHR HAVE_STPCPY HAVE_STPNCPY HAVE_STRCHRNUL HAVE_DECL_STRDUP HAVE_STRNDUP HAVE_DECL_STRNDUP HAVE_DECL_STRNLEN HAVE_STRPBRK HAVE_STRSEP HAVE_STRCASESTR HAVE_DECL_STRTOK_R HAVE_DECL_STRERROR HAVE_DECL_STRSIGNAL REPLACE_STRERROR REPLACE_STRSIGNAL REPLACE_MEMMEM REPLACE_STRCASESTR REPLACE_STRSTR HAVE_LONG_LONG_INT HAVE_UNSIGNED_LONG_LONG_INT HAVE_INTTYPES_H HAVE_SYS_TYPES_H INCLUDE_NEXT NEXT_STDINT_H HAVE_STDINT_H HAVE_SYS_INTTYPES_H HAVE_SYS_BITYPES_H BITSIZEOF_PTRDIFF_T BITSIZEOF_SIG_ATOMIC_T BITSIZEOF_SIZE_T BITSIZEOF_WCHAR_T BITSIZEOF_WINT_T HAVE_SIGNED_SIG_ATOMIC_T HAVE_SIGNED_WCHAR_T HAVE_SIGNED_WINT_T PTRDIFF_T_SUFFIX SIG_ATOMIC_T_SUFFIX SIZE_T_SUFFIX WCHAR_T_SUFFIX WINT_T_SUFFIX STDINT_H NEXT_STRING_H GNULIB_WCWIDTH HAVE_DECL_WCWIDTH REPLACE_WCWIDTH WCHAR_H HAVE_WCHAR_H NEXT_WCHAR_H LIBGNU_LIBDEPS LIBGNU_LTLIBDEPS GNULIB_STDINT_H PACKAGE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK AMTAR am__tar am__untar am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH am__fastdepCC_TRUE am__fastdepCC_FALSE subdirs TARGET_OBS PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI LN_S YACC AR ac_ct_AR DLLTOOL ac_ct_DLLTOOL WINDRES ac_ct_WINDRES MIG ac_ct_MIG READLINE READLINE_DEPS READLINE_CFLAGS HAVE_LIBEXPAT LIBEXPAT LTLIBEXPAT PYTHON_CFLAGS ALLOCA CONFIG_LDFLAGS TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE WARN_CFLAGS WERROR_CFLAGS SER_HARDWIRE WIN32LIBS LIBGUI GUI_CFLAGS_X WIN32LDAPP TCL_VERSION TCL_PATCH_LEVEL TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_INCLUDE TCL_LIBRARY TCL_DEPS TK_VERSION TK_BIN_DIR TK_SRC_DIR TK_LIB_FILE TK_LIB_FLAG TK_LIB_SPEC TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_STUB_LIB_SPEC TK_INCLUDE TK_LIBRARY TK_DEPS TK_XINCLUDES X_CFLAGS X_LDFLAGS X_LIBS GDBTKLIBS GDBTK_CFLAGS GDBTK_SRC_DIR SIM SIM_OBS ENABLE_CFLAGS PROFILE_CFLAGS CONFIG_OBS CONFIG_DEPS CONFIG_SRCS CONFIG_ALL CONFIG_CLEAN CONFIG_INSTALL CONFIG_UNINSTALL target_subdir frags nm_h LIBICONV LIBOBJS LTLIBOBJS gl_LIBOBJS gl_LTLIBOBJS gltests_LIBOBJS gltests_LTLIBOBJS' | |
7236 | +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP RANLIB ac_ct_RANLIB build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os am__leading_dot DEPDIR CCDEPMODE MAKE GMAKE_TRUE GMAKE_FALSE SET_MAKE USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT localedir GL_COND_LIBTOOL_TRUE GL_COND_LIBTOOL_FALSE GNULIB_MEMMEM GNULIB_MEMPCPY GNULIB_MEMRCHR GNULIB_STPCPY GNULIB_STPNCPY GNULIB_STRCHRNUL GNULIB_STRDUP GNULIB_STRNDUP GNULIB_STRNLEN GNULIB_STRPBRK GNULIB_STRSEP GNULIB_STRSTR GNULIB_STRCASESTR GNULIB_STRTOK_R GNULIB_MBSLEN GNULIB_MBSNLEN GNULIB_MBSCHR GNULIB_MBSRCHR GNULIB_MBSSTR GNULIB_MBSCASECMP GNULIB_MBSNCASECMP GNULIB_MBSPCASECMP GNULIB_MBSCASESTR GNULIB_MBSCSPN GNULIB_MBSPBRK GNULIB_MBSSPN GNULIB_MBSSEP GNULIB_MBSTOK_R GNULIB_STRERROR GNULIB_STRSIGNAL HAVE_DECL_MEMMEM HAVE_MEMPCPY HAVE_DECL_MEMRCHR HAVE_STPCPY HAVE_STPNCPY HAVE_STRCHRNUL HAVE_DECL_STRDUP HAVE_STRNDUP HAVE_DECL_STRNDUP HAVE_DECL_STRNLEN HAVE_STRPBRK HAVE_STRSEP HAVE_STRCASESTR HAVE_DECL_STRTOK_R HAVE_DECL_STRERROR HAVE_DECL_STRSIGNAL REPLACE_STRERROR REPLACE_STRSIGNAL REPLACE_MEMMEM REPLACE_STRCASESTR REPLACE_STRSTR HAVE_LONG_LONG_INT HAVE_UNSIGNED_LONG_LONG_INT HAVE_INTTYPES_H HAVE_SYS_TYPES_H INCLUDE_NEXT NEXT_STDINT_H HAVE_STDINT_H HAVE_SYS_INTTYPES_H HAVE_SYS_BITYPES_H BITSIZEOF_PTRDIFF_T BITSIZEOF_SIG_ATOMIC_T BITSIZEOF_SIZE_T BITSIZEOF_WCHAR_T BITSIZEOF_WINT_T HAVE_SIGNED_SIG_ATOMIC_T HAVE_SIGNED_WCHAR_T HAVE_SIGNED_WINT_T PTRDIFF_T_SUFFIX SIG_ATOMIC_T_SUFFIX SIZE_T_SUFFIX WCHAR_T_SUFFIX WINT_T_SUFFIX STDINT_H NEXT_STRING_H GNULIB_WCWIDTH HAVE_DECL_WCWIDTH REPLACE_WCWIDTH WCHAR_H HAVE_WCHAR_H NEXT_WCHAR_H LIBGNU_LIBDEPS LIBGNU_LTLIBDEPS GNULIB_STDINT_H PACKAGE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK AMTAR am__tar am__untar am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH am__fastdepCC_TRUE am__fastdepCC_FALSE GDB_DATADIR_PATH pythondir subdirs TARGET_OBS PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI LN_S YACC AR ac_ct_AR DLLTOOL ac_ct_DLLTOOL WINDRES ac_ct_WINDRES MIG ac_ct_MIG LIBICONV LIBICONV_INCLUDE LIBICONV_LIBDIR READLINE READLINE_DEPS READLINE_CFLAGS HAVE_LIBEXPAT LIBEXPAT LTLIBEXPAT PYTHON_CFLAGS ALLOCA CONFIG_LDFLAGS TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE WARN_CFLAGS WERROR_CFLAGS SER_HARDWIRE WIN32LIBS LIBGUI GUI_CFLAGS_X WIN32LDAPP TCL_VERSION TCL_PATCH_LEVEL TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_INCLUDE TCL_LIBRARY TCL_DEPS TK_VERSION TK_BIN_DIR TK_SRC_DIR TK_LIB_FILE TK_LIB_FLAG TK_LIB_SPEC TK_STUB_LIB_FILE TK_STUB_LIB_FLAG TK_STUB_LIB_SPEC TK_INCLUDE TK_LIBRARY TK_DEPS TK_XINCLUDES X_CFLAGS X_LDFLAGS X_LIBS GDBTKLIBS GDBTK_CFLAGS GDBTK_SRC_DIR SIM SIM_OBS ENABLE_CFLAGS PROFILE_CFLAGS CONFIG_OBS CONFIG_DEPS CONFIG_SRCS CONFIG_ALL CONFIG_CLEAN CONFIG_INSTALL CONFIG_UNINSTALL target_subdir frags nm_h LIBOBJS LTLIBOBJS gl_LIBOBJS gl_LTLIBOBJS gltests_LIBOBJS gltests_LTLIBOBJS' | |
7237 | ac_subst_files='host_makefile_frag' | |
7238 | ac_pwd=`pwd` | |
7239 | ||
7240 | @@ -882,9 +882,14 @@ Optional Packages: | |
7241 | --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] | |
7242 | --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) | |
7243 | --with-separate-debug-dir=path Look for global separate debug info in this path LIBDIR/debug | |
7244 | + --with-gdb-datadir look for global separate data files in this path | |
7245 | + [DATADIR/gdb] | |
7246 | + --with-pythondir install Python data files in this path | |
7247 | + [DATADIR/gdb/python] | |
7248 | --with-libunwind Use libunwind frame unwinding support | |
7249 | --with-pkgversion=PKG Use PKG in the version string in place of "GDB" | |
7250 | --with-bugurl=URL Direct users to URL to report a bug | |
7251 | + --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib | |
7252 | --with-system-readline use installed readline library | |
7253 | --with-expat include expat support (auto/yes/no) | |
7254 | --with-gnu-ld assume the C compiler uses GNU ld default=no | |
7255 | @@ -899,7 +904,6 @@ Optional Packages: | |
7256 | --with-tcl directory containing tcl configuration (tclConfig.sh) | |
7257 | --with-tk directory containing tk configuration (tkConfig.sh) | |
7258 | --with-x use the X Window System | |
7259 | - --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib | |
7260 | ||
7261 | Some influential environment variables: | |
7262 | CC C compiler command | |
7263 | @@ -7130,6 +7134,75 @@ _ACEOF | |
7264 | ;; | |
7265 | esac | |
7266 | ||
7267 | +# GDB's datadir relocation | |
7268 | + | |
7269 | +gdbdatadir=${datadir}/gdb | |
7270 | + | |
7271 | + | |
7272 | +# Check whether --with-gdb-datadir or --without-gdb-datadir was given. | |
7273 | +if test "${with_gdb_datadir+set}" = set; then | |
7274 | + withval="$with_gdb_datadir" | |
7275 | + gdbdatadir="${withval}" | |
7276 | +fi; | |
7277 | + | |
7278 | + | |
7279 | + test "x$prefix" = xNONE && prefix="$ac_default_prefix" | |
7280 | + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' | |
7281 | + ac_define_dir=`eval echo $gdbdatadir` | |
7282 | + ac_define_dir=`eval echo $ac_define_dir` | |
7283 | + | |
7284 | +cat >>confdefs.h <<_ACEOF | |
7285 | +#define GDB_DATADIR "$ac_define_dir" | |
7286 | +_ACEOF | |
7287 | + | |
7288 | + | |
7289 | + | |
7290 | +if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then | |
7291 | + if test "x$prefix" = xNONE; then | |
7292 | + test_prefix=/usr/local | |
7293 | + else | |
7294 | + test_prefix=$prefix | |
7295 | + fi | |
7296 | +else | |
7297 | + test_prefix=$exec_prefix | |
7298 | +fi | |
7299 | + | |
7300 | +case ${gdbdatadir} in | |
7301 | + "${test_prefix}"|"${test_prefix}/"*|\ | |
7302 | + '${exec_prefix}'|'${exec_prefix}/'*) | |
7303 | + | |
7304 | +cat >>confdefs.h <<\_ACEOF | |
7305 | +#define GDB_DATADIR_RELOCATABLE 1 | |
7306 | +_ACEOF | |
7307 | + | |
7308 | + ;; | |
7309 | +esac | |
7310 | +GDB_DATADIR_PATH=${gdbdatadir} | |
7311 | + | |
7312 | + | |
7313 | + | |
7314 | +# Check whether --with-pythondir or --without-pythondir was given. | |
7315 | +if test "${with_pythondir+set}" = set; then | |
7316 | + withval="$with_pythondir" | |
7317 | + pythondir="${withval}" | |
7318 | +else | |
7319 | + pythondir=no | |
7320 | +fi; | |
7321 | + | |
7322 | +# If the user passed in a path, define it. Otherwise, compute it at | |
7323 | +# runtime based on the possibly-relocatable datadir. | |
7324 | +if test "$pythondir" = "no"; then | |
7325 | + pythondir='$(GDB_DATADIR_PATH)/python' | |
7326 | +else | |
7327 | + | |
7328 | +cat >>confdefs.h <<_ACEOF | |
7329 | +#define PYTHONDIR "$pythondir" | |
7330 | +_ACEOF | |
7331 | + | |
7332 | +fi | |
7333 | + | |
7334 | + | |
7335 | + | |
7336 | ||
7337 | ||
7338 | subdirs="$subdirs doc testsuite" | |
7339 | @@ -9989,6 +10062,226 @@ if test "$ac_cv_search_dlgetmodinfo" != no; then | |
7340 | fi | |
7341 | ||
7342 | ||
7343 | + | |
7344 | + | |
7345 | + | |
7346 | +# Check whether --with-libiconv-prefix or --without-libiconv-prefix was given. | |
7347 | +if test "${with_libiconv_prefix+set}" = set; then | |
7348 | + withval="$with_libiconv_prefix" | |
7349 | + | |
7350 | + for dir in `echo "$withval" | tr : ' '`; do | |
7351 | + if test -d $dir/include; then LIBICONV_INCLUDE="-I$dir/include"; CPPFLAGS="$CPPFLAGS -I$dir/include"; fi | |
7352 | + if test -d $dir/lib; then LIBICONV_LIBDIR="-L$dir/lib"; LDFLAGS="$LDFLAGS -L$dir/lib"; fi | |
7353 | + done | |
7354 | + | |
7355 | +fi; | |
7356 | + | |
7357 | + echo "$as_me:$LINENO: checking for iconv" >&5 | |
7358 | +echo $ECHO_N "checking for iconv... $ECHO_C" >&6 | |
7359 | +if test "${am_cv_func_iconv+set}" = set; then | |
7360 | + echo $ECHO_N "(cached) $ECHO_C" >&6 | |
7361 | +else | |
7362 | + | |
7363 | + am_cv_func_iconv="no, consider installing GNU libiconv" | |
7364 | + am_cv_lib_iconv=no | |
7365 | + cat >conftest.$ac_ext <<_ACEOF | |
7366 | +/* confdefs.h. */ | |
7367 | +_ACEOF | |
7368 | +cat confdefs.h >>conftest.$ac_ext | |
7369 | +cat >>conftest.$ac_ext <<_ACEOF | |
7370 | +/* end confdefs.h. */ | |
7371 | +#include <stdlib.h> | |
7372 | +#include <iconv.h> | |
7373 | +int | |
7374 | +main () | |
7375 | +{ | |
7376 | +iconv_t cd = iconv_open("",""); | |
7377 | + iconv(cd,NULL,NULL,NULL,NULL); | |
7378 | + iconv_close(cd); | |
7379 | + ; | |
7380 | + return 0; | |
7381 | +} | |
7382 | +_ACEOF | |
7383 | +rm -f conftest.$ac_objext conftest$ac_exeext | |
7384 | +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 | |
7385 | + (eval $ac_link) 2>conftest.er1 | |
7386 | + ac_status=$? | |
7387 | + grep -v '^ *+' conftest.er1 >conftest.err | |
7388 | + rm -f conftest.er1 | |
7389 | + cat conftest.err >&5 | |
7390 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7391 | + (exit $ac_status); } && | |
7392 | + { ac_try='test -z "$ac_c_werror_flag" | |
7393 | + || test ! -s conftest.err' | |
7394 | + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7395 | + (eval $ac_try) 2>&5 | |
7396 | + ac_status=$? | |
7397 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7398 | + (exit $ac_status); }; } && | |
7399 | + { ac_try='test -s conftest$ac_exeext' | |
7400 | + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7401 | + (eval $ac_try) 2>&5 | |
7402 | + ac_status=$? | |
7403 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7404 | + (exit $ac_status); }; }; then | |
7405 | + am_cv_func_iconv=yes | |
7406 | +else | |
7407 | + echo "$as_me: failed program was:" >&5 | |
7408 | +sed 's/^/| /' conftest.$ac_ext >&5 | |
7409 | + | |
7410 | +fi | |
7411 | +rm -f conftest.err conftest.$ac_objext \ | |
7412 | + conftest$ac_exeext conftest.$ac_ext | |
7413 | + if test "$am_cv_func_iconv" != yes; then | |
7414 | + am_save_LIBS="$LIBS" | |
7415 | + LIBS="$LIBS -liconv" | |
7416 | + cat >conftest.$ac_ext <<_ACEOF | |
7417 | +/* confdefs.h. */ | |
7418 | +_ACEOF | |
7419 | +cat confdefs.h >>conftest.$ac_ext | |
7420 | +cat >>conftest.$ac_ext <<_ACEOF | |
7421 | +/* end confdefs.h. */ | |
7422 | +#include <stdlib.h> | |
7423 | +#include <iconv.h> | |
7424 | +int | |
7425 | +main () | |
7426 | +{ | |
7427 | +iconv_t cd = iconv_open("",""); | |
7428 | + iconv(cd,NULL,NULL,NULL,NULL); | |
7429 | + iconv_close(cd); | |
7430 | + ; | |
7431 | + return 0; | |
7432 | +} | |
7433 | +_ACEOF | |
7434 | +rm -f conftest.$ac_objext conftest$ac_exeext | |
7435 | +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 | |
7436 | + (eval $ac_link) 2>conftest.er1 | |
7437 | + ac_status=$? | |
7438 | + grep -v '^ *+' conftest.er1 >conftest.err | |
7439 | + rm -f conftest.er1 | |
7440 | + cat conftest.err >&5 | |
7441 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7442 | + (exit $ac_status); } && | |
7443 | + { ac_try='test -z "$ac_c_werror_flag" | |
7444 | + || test ! -s conftest.err' | |
7445 | + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7446 | + (eval $ac_try) 2>&5 | |
7447 | + ac_status=$? | |
7448 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7449 | + (exit $ac_status); }; } && | |
7450 | + { ac_try='test -s conftest$ac_exeext' | |
7451 | + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7452 | + (eval $ac_try) 2>&5 | |
7453 | + ac_status=$? | |
7454 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7455 | + (exit $ac_status); }; }; then | |
7456 | + am_cv_lib_iconv=yes | |
7457 | + am_cv_func_iconv=yes | |
7458 | +else | |
7459 | + echo "$as_me: failed program was:" >&5 | |
7460 | +sed 's/^/| /' conftest.$ac_ext >&5 | |
7461 | + | |
7462 | +fi | |
7463 | +rm -f conftest.err conftest.$ac_objext \ | |
7464 | + conftest$ac_exeext conftest.$ac_ext | |
7465 | + LIBS="$am_save_LIBS" | |
7466 | + fi | |
7467 | + | |
7468 | +fi | |
7469 | +echo "$as_me:$LINENO: result: $am_cv_func_iconv" >&5 | |
7470 | +echo "${ECHO_T}$am_cv_func_iconv" >&6 | |
7471 | + if test "$am_cv_func_iconv" = yes; then | |
7472 | + | |
7473 | +cat >>confdefs.h <<\_ACEOF | |
7474 | +#define HAVE_ICONV 1 | |
7475 | +_ACEOF | |
7476 | + | |
7477 | + echo "$as_me:$LINENO: checking for iconv declaration" >&5 | |
7478 | +echo $ECHO_N "checking for iconv declaration... $ECHO_C" >&6 | |
7479 | + if test "${am_cv_proto_iconv+set}" = set; then | |
7480 | + echo $ECHO_N "(cached) $ECHO_C" >&6 | |
7481 | +else | |
7482 | + | |
7483 | + cat >conftest.$ac_ext <<_ACEOF | |
7484 | +/* confdefs.h. */ | |
7485 | +_ACEOF | |
7486 | +cat confdefs.h >>conftest.$ac_ext | |
7487 | +cat >>conftest.$ac_ext <<_ACEOF | |
7488 | +/* end confdefs.h. */ | |
7489 | + | |
7490 | +#include <stdlib.h> | |
7491 | +#include <iconv.h> | |
7492 | +extern | |
7493 | +#ifdef __cplusplus | |
7494 | +"C" | |
7495 | +#endif | |
7496 | +#if defined(__STDC__) || defined(__cplusplus) | |
7497 | +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); | |
7498 | +#else | |
7499 | +size_t iconv(); | |
7500 | +#endif | |
7501 | + | |
7502 | +int | |
7503 | +main () | |
7504 | +{ | |
7505 | + | |
7506 | + ; | |
7507 | + return 0; | |
7508 | +} | |
7509 | +_ACEOF | |
7510 | +rm -f conftest.$ac_objext | |
7511 | +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 | |
7512 | + (eval $ac_compile) 2>conftest.er1 | |
7513 | + ac_status=$? | |
7514 | + grep -v '^ *+' conftest.er1 >conftest.err | |
7515 | + rm -f conftest.er1 | |
7516 | + cat conftest.err >&5 | |
7517 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7518 | + (exit $ac_status); } && | |
7519 | + { ac_try='test -z "$ac_c_werror_flag" | |
7520 | + || test ! -s conftest.err' | |
7521 | + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7522 | + (eval $ac_try) 2>&5 | |
7523 | + ac_status=$? | |
7524 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7525 | + (exit $ac_status); }; } && | |
7526 | + { ac_try='test -s conftest.$ac_objext' | |
7527 | + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7528 | + (eval $ac_try) 2>&5 | |
7529 | + ac_status=$? | |
7530 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7531 | + (exit $ac_status); }; }; then | |
7532 | + am_cv_proto_iconv_arg1="" | |
7533 | +else | |
7534 | + echo "$as_me: failed program was:" >&5 | |
7535 | +sed 's/^/| /' conftest.$ac_ext >&5 | |
7536 | + | |
7537 | +am_cv_proto_iconv_arg1="const" | |
7538 | +fi | |
7539 | +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext | |
7540 | + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" | |
7541 | +fi | |
7542 | + | |
7543 | + am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` | |
7544 | + echo "$as_me:$LINENO: result: ${ac_t:- | |
7545 | + }$am_cv_proto_iconv" >&5 | |
7546 | +echo "${ECHO_T}${ac_t:- | |
7547 | + }$am_cv_proto_iconv" >&6 | |
7548 | + | |
7549 | +cat >>confdefs.h <<_ACEOF | |
7550 | +#define ICONV_CONST $am_cv_proto_iconv_arg1 | |
7551 | +_ACEOF | |
7552 | + | |
7553 | + fi | |
7554 | + LIBICONV= | |
7555 | + if test "$am_cv_lib_iconv" = yes; then | |
7556 | + LIBICONV="-liconv" | |
7557 | + fi | |
7558 | + | |
7559 | + | |
7560 | + | |
7561 | + | |
7562 | + | |
7563 | # On alpha-osf, it appears that libtermcap and libcurses are not compatible. | |
7564 | # There is a very specific comment in /usr/include/curses.h explaining that | |
7565 | # termcap routines built into libcurses must not be used. | |
7566 | @@ -11418,6 +11711,8 @@ _ACEOF | |
7567 | CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_PYTHON_OBS)" | |
7568 | CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_PYTHON_DEPS)" | |
7569 | CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_PYTHON_SRCS)" | |
7570 | + CONFIG_INSTALL="$CONFIG_INSTALL install-python" | |
7571 | + CONFIG_UNINSTALL="$CONFIG_UNINSTALL uninstall-python" | |
7572 | ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_PYTHON_CFLAGS)" | |
7573 | ||
7574 | # Flags needed to compile Python code (taken from python-config --cflags). | |
7575 | @@ -15445,10 +15740,11 @@ fi | |
7576 | ||
7577 | ||
7578 | ||
7579 | + | |
7580 | for ac_func in canonicalize_file_name realpath getrusage getuid \ | |
7581 | getgid poll pread64 sbrk setpgid setpgrp setsid \ | |
7582 | sigaction sigprocmask sigsetmask socketpair syscall \ | |
7583 | - ttrace wborder setlocale | |
7584 | + ttrace wborder setlocale iconvlist | |
7585 | do | |
7586 | as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` | |
7587 | echo "$as_me:$LINENO: checking for $ac_func" >&5 | |
7588 | @@ -15550,6 +15846,70 @@ fi | |
7589 | done | |
7590 | ||
7591 | ||
7592 | + echo "$as_me:$LINENO: checking for nl_langinfo and CODESET" >&5 | |
7593 | +echo $ECHO_N "checking for nl_langinfo and CODESET... $ECHO_C" >&6 | |
7594 | +if test "${am_cv_langinfo_codeset+set}" = set; then | |
7595 | + echo $ECHO_N "(cached) $ECHO_C" >&6 | |
7596 | +else | |
7597 | + cat >conftest.$ac_ext <<_ACEOF | |
7598 | +/* confdefs.h. */ | |
7599 | +_ACEOF | |
7600 | +cat confdefs.h >>conftest.$ac_ext | |
7601 | +cat >>conftest.$ac_ext <<_ACEOF | |
7602 | +/* end confdefs.h. */ | |
7603 | +#include <langinfo.h> | |
7604 | +int | |
7605 | +main () | |
7606 | +{ | |
7607 | +char* cs = nl_langinfo(CODESET); | |
7608 | + ; | |
7609 | + return 0; | |
7610 | +} | |
7611 | +_ACEOF | |
7612 | +rm -f conftest.$ac_objext conftest$ac_exeext | |
7613 | +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 | |
7614 | + (eval $ac_link) 2>conftest.er1 | |
7615 | + ac_status=$? | |
7616 | + grep -v '^ *+' conftest.er1 >conftest.err | |
7617 | + rm -f conftest.er1 | |
7618 | + cat conftest.err >&5 | |
7619 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7620 | + (exit $ac_status); } && | |
7621 | + { ac_try='test -z "$ac_c_werror_flag" | |
7622 | + || test ! -s conftest.err' | |
7623 | + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7624 | + (eval $ac_try) 2>&5 | |
7625 | + ac_status=$? | |
7626 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7627 | + (exit $ac_status); }; } && | |
7628 | + { ac_try='test -s conftest$ac_exeext' | |
7629 | + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7630 | + (eval $ac_try) 2>&5 | |
7631 | + ac_status=$? | |
7632 | + echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7633 | + (exit $ac_status); }; }; then | |
7634 | + am_cv_langinfo_codeset=yes | |
7635 | +else | |
7636 | + echo "$as_me: failed program was:" >&5 | |
7637 | +sed 's/^/| /' conftest.$ac_ext >&5 | |
7638 | + | |
7639 | +am_cv_langinfo_codeset=no | |
7640 | +fi | |
7641 | +rm -f conftest.err conftest.$ac_objext \ | |
7642 | + conftest$ac_exeext conftest.$ac_ext | |
7643 | + | |
7644 | +fi | |
7645 | +echo "$as_me:$LINENO: result: $am_cv_langinfo_codeset" >&5 | |
7646 | +echo "${ECHO_T}$am_cv_langinfo_codeset" >&6 | |
7647 | + if test $am_cv_langinfo_codeset = yes; then | |
7648 | + | |
7649 | +cat >>confdefs.h <<\_ACEOF | |
7650 | +#define HAVE_LANGINFO_CODESET 1 | |
7651 | +_ACEOF | |
7652 | + | |
7653 | + fi | |
7654 | + | |
7655 | + | |
7656 | # Check the return and argument types of ptrace. No canned test for | |
7657 | # this, so roll our own. | |
7658 | gdb_ptrace_headers=' | |
7659 | @@ -20776,230 +21136,11 @@ done | |
7660 | ||
7661 | ||
7662 | ||
7663 | - | |
7664 | cat >>confdefs.h <<\_ACEOF | |
7665 | -#define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1" | |
7666 | +#define GDB_DEFAULT_HOST_CHARSET "UTF-8" | |
7667 | _ACEOF | |
7668 | ||
7669 | ||
7670 | - | |
7671 | - | |
7672 | - | |
7673 | -# Check whether --with-libiconv-prefix or --without-libiconv-prefix was given. | |
7674 | -if test "${with_libiconv_prefix+set}" = set; then | |
7675 | - withval="$with_libiconv_prefix" | |
7676 | - | |
7677 | - for dir in `echo "$withval" | tr : ' '`; do | |
7678 | - if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi | |
7679 | - if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi | |
7680 | - done | |
7681 | - | |
7682 | -fi; | |
7683 | - | |
7684 | - echo "$as_me:$LINENO: checking for iconv" >&5 | |
7685 | -echo $ECHO_N "checking for iconv... $ECHO_C" >&6 | |
7686 | -if test "${am_cv_func_iconv+set}" = set; then | |
7687 | - echo $ECHO_N "(cached) $ECHO_C" >&6 | |
7688 | -else | |
7689 | - | |
7690 | - am_cv_func_iconv="no, consider installing GNU libiconv" | |
7691 | - am_cv_lib_iconv=no | |
7692 | - cat >conftest.$ac_ext <<_ACEOF | |
7693 | -/* confdefs.h. */ | |
7694 | -_ACEOF | |
7695 | -cat confdefs.h >>conftest.$ac_ext | |
7696 | -cat >>conftest.$ac_ext <<_ACEOF | |
7697 | -/* end confdefs.h. */ | |
7698 | -#include <stdlib.h> | |
7699 | -#include <iconv.h> | |
7700 | -int | |
7701 | -main () | |
7702 | -{ | |
7703 | -iconv_t cd = iconv_open("",""); | |
7704 | - iconv(cd,NULL,NULL,NULL,NULL); | |
7705 | - iconv_close(cd); | |
7706 | - ; | |
7707 | - return 0; | |
7708 | -} | |
7709 | -_ACEOF | |
7710 | -rm -f conftest.$ac_objext conftest$ac_exeext | |
7711 | -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 | |
7712 | - (eval $ac_link) 2>conftest.er1 | |
7713 | - ac_status=$? | |
7714 | - grep -v '^ *+' conftest.er1 >conftest.err | |
7715 | - rm -f conftest.er1 | |
7716 | - cat conftest.err >&5 | |
7717 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7718 | - (exit $ac_status); } && | |
7719 | - { ac_try='test -z "$ac_c_werror_flag" | |
7720 | - || test ! -s conftest.err' | |
7721 | - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7722 | - (eval $ac_try) 2>&5 | |
7723 | - ac_status=$? | |
7724 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7725 | - (exit $ac_status); }; } && | |
7726 | - { ac_try='test -s conftest$ac_exeext' | |
7727 | - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7728 | - (eval $ac_try) 2>&5 | |
7729 | - ac_status=$? | |
7730 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7731 | - (exit $ac_status); }; }; then | |
7732 | - am_cv_func_iconv=yes | |
7733 | -else | |
7734 | - echo "$as_me: failed program was:" >&5 | |
7735 | -sed 's/^/| /' conftest.$ac_ext >&5 | |
7736 | - | |
7737 | -fi | |
7738 | -rm -f conftest.err conftest.$ac_objext \ | |
7739 | - conftest$ac_exeext conftest.$ac_ext | |
7740 | - if test "$am_cv_func_iconv" != yes; then | |
7741 | - am_save_LIBS="$LIBS" | |
7742 | - LIBS="$LIBS -liconv" | |
7743 | - cat >conftest.$ac_ext <<_ACEOF | |
7744 | -/* confdefs.h. */ | |
7745 | -_ACEOF | |
7746 | -cat confdefs.h >>conftest.$ac_ext | |
7747 | -cat >>conftest.$ac_ext <<_ACEOF | |
7748 | -/* end confdefs.h. */ | |
7749 | -#include <stdlib.h> | |
7750 | -#include <iconv.h> | |
7751 | -int | |
7752 | -main () | |
7753 | -{ | |
7754 | -iconv_t cd = iconv_open("",""); | |
7755 | - iconv(cd,NULL,NULL,NULL,NULL); | |
7756 | - iconv_close(cd); | |
7757 | - ; | |
7758 | - return 0; | |
7759 | -} | |
7760 | -_ACEOF | |
7761 | -rm -f conftest.$ac_objext conftest$ac_exeext | |
7762 | -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 | |
7763 | - (eval $ac_link) 2>conftest.er1 | |
7764 | - ac_status=$? | |
7765 | - grep -v '^ *+' conftest.er1 >conftest.err | |
7766 | - rm -f conftest.er1 | |
7767 | - cat conftest.err >&5 | |
7768 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7769 | - (exit $ac_status); } && | |
7770 | - { ac_try='test -z "$ac_c_werror_flag" | |
7771 | - || test ! -s conftest.err' | |
7772 | - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7773 | - (eval $ac_try) 2>&5 | |
7774 | - ac_status=$? | |
7775 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7776 | - (exit $ac_status); }; } && | |
7777 | - { ac_try='test -s conftest$ac_exeext' | |
7778 | - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7779 | - (eval $ac_try) 2>&5 | |
7780 | - ac_status=$? | |
7781 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7782 | - (exit $ac_status); }; }; then | |
7783 | - am_cv_lib_iconv=yes | |
7784 | - am_cv_func_iconv=yes | |
7785 | -else | |
7786 | - echo "$as_me: failed program was:" >&5 | |
7787 | -sed 's/^/| /' conftest.$ac_ext >&5 | |
7788 | - | |
7789 | -fi | |
7790 | -rm -f conftest.err conftest.$ac_objext \ | |
7791 | - conftest$ac_exeext conftest.$ac_ext | |
7792 | - LIBS="$am_save_LIBS" | |
7793 | - fi | |
7794 | - | |
7795 | -fi | |
7796 | -echo "$as_me:$LINENO: result: $am_cv_func_iconv" >&5 | |
7797 | -echo "${ECHO_T}$am_cv_func_iconv" >&6 | |
7798 | - if test "$am_cv_func_iconv" = yes; then | |
7799 | - | |
7800 | -cat >>confdefs.h <<\_ACEOF | |
7801 | -#define HAVE_ICONV 1 | |
7802 | -_ACEOF | |
7803 | - | |
7804 | - echo "$as_me:$LINENO: checking for iconv declaration" >&5 | |
7805 | -echo $ECHO_N "checking for iconv declaration... $ECHO_C" >&6 | |
7806 | - if test "${am_cv_proto_iconv+set}" = set; then | |
7807 | - echo $ECHO_N "(cached) $ECHO_C" >&6 | |
7808 | -else | |
7809 | - | |
7810 | - cat >conftest.$ac_ext <<_ACEOF | |
7811 | -/* confdefs.h. */ | |
7812 | -_ACEOF | |
7813 | -cat confdefs.h >>conftest.$ac_ext | |
7814 | -cat >>conftest.$ac_ext <<_ACEOF | |
7815 | -/* end confdefs.h. */ | |
7816 | - | |
7817 | -#include <stdlib.h> | |
7818 | -#include <iconv.h> | |
7819 | -extern | |
7820 | -#ifdef __cplusplus | |
7821 | -"C" | |
7822 | -#endif | |
7823 | -#if defined(__STDC__) || defined(__cplusplus) | |
7824 | -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); | |
7825 | -#else | |
7826 | -size_t iconv(); | |
7827 | -#endif | |
7828 | - | |
7829 | -int | |
7830 | -main () | |
7831 | -{ | |
7832 | - | |
7833 | - ; | |
7834 | - return 0; | |
7835 | -} | |
7836 | -_ACEOF | |
7837 | -rm -f conftest.$ac_objext | |
7838 | -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 | |
7839 | - (eval $ac_compile) 2>conftest.er1 | |
7840 | - ac_status=$? | |
7841 | - grep -v '^ *+' conftest.er1 >conftest.err | |
7842 | - rm -f conftest.er1 | |
7843 | - cat conftest.err >&5 | |
7844 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7845 | - (exit $ac_status); } && | |
7846 | - { ac_try='test -z "$ac_c_werror_flag" | |
7847 | - || test ! -s conftest.err' | |
7848 | - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7849 | - (eval $ac_try) 2>&5 | |
7850 | - ac_status=$? | |
7851 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7852 | - (exit $ac_status); }; } && | |
7853 | - { ac_try='test -s conftest.$ac_objext' | |
7854 | - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7855 | - (eval $ac_try) 2>&5 | |
7856 | - ac_status=$? | |
7857 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7858 | - (exit $ac_status); }; }; then | |
7859 | - am_cv_proto_iconv_arg1="" | |
7860 | -else | |
7861 | - echo "$as_me: failed program was:" >&5 | |
7862 | -sed 's/^/| /' conftest.$ac_ext >&5 | |
7863 | - | |
7864 | -am_cv_proto_iconv_arg1="const" | |
7865 | -fi | |
7866 | -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext | |
7867 | - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" | |
7868 | -fi | |
7869 | - | |
7870 | - am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` | |
7871 | - echo "$as_me:$LINENO: result: ${ac_t:- | |
7872 | - }$am_cv_proto_iconv" >&5 | |
7873 | -echo "${ECHO_T}${ac_t:- | |
7874 | - }$am_cv_proto_iconv" >&6 | |
7875 | - | |
7876 | -cat >>confdefs.h <<_ACEOF | |
7877 | -#define ICONV_CONST $am_cv_proto_iconv_arg1 | |
7878 | -_ACEOF | |
7879 | - | |
7880 | - fi | |
7881 | - LIBICONV= | |
7882 | - if test "$am_cv_lib_iconv" = yes; then | |
7883 | - LIBICONV="-liconv" | |
7884 | - fi | |
7885 | - | |
7886 | - | |
7887 | - | |
7888 | ac_config_files="$ac_config_files Makefile .gdbinit:gdbinit.in gnulib/Makefile" | |
7889 | ac_config_commands="$ac_config_commands default" | |
7890 | cat >confcache <<\_ACEOF | |
7891 | @@ -21865,6 +22006,8 @@ s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t | |
7892 | s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t | |
7893 | s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t | |
7894 | s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t | |
7895 | +s,@GDB_DATADIR_PATH@,$GDB_DATADIR_PATH,;t t | |
7896 | +s,@pythondir@,$pythondir,;t t | |
7897 | s,@subdirs@,$subdirs,;t t | |
7898 | s,@TARGET_OBS@,$TARGET_OBS,;t t | |
7899 | s,@PKGVERSION@,$PKGVERSION,;t t | |
7900 | @@ -21880,6 +22023,9 @@ s,@WINDRES@,$WINDRES,;t t | |
7901 | s,@ac_ct_WINDRES@,$ac_ct_WINDRES,;t t | |
7902 | s,@MIG@,$MIG,;t t | |
7903 | s,@ac_ct_MIG@,$ac_ct_MIG,;t t | |
7904 | +s,@LIBICONV@,$LIBICONV,;t t | |
7905 | +s,@LIBICONV_INCLUDE@,$LIBICONV_INCLUDE,;t t | |
7906 | +s,@LIBICONV_LIBDIR@,$LIBICONV_LIBDIR,;t t | |
7907 | s,@READLINE@,$READLINE,;t t | |
7908 | s,@READLINE_DEPS@,$READLINE_DEPS,;t t | |
7909 | s,@READLINE_CFLAGS@,$READLINE_CFLAGS,;t t | |
7910 | @@ -21944,7 +22090,6 @@ s,@CONFIG_UNINSTALL@,$CONFIG_UNINSTALL,;t t | |
7911 | s,@target_subdir@,$target_subdir,;t t | |
7912 | s,@frags@,$frags,;t t | |
7913 | s,@nm_h@,$nm_h,;t t | |
7914 | -s,@LIBICONV@,$LIBICONV,;t t | |
7915 | s,@LIBOBJS@,$LIBOBJS,;t t | |
7916 | s,@LTLIBOBJS@,$LTLIBOBJS,;t t | |
7917 | s,@gl_LIBOBJS@,$gl_LIBOBJS,;t t | |
7918 | diff --git a/gdb/configure.ac b/gdb/configure.ac | |
7919 | index 3f81ff2..ff76053 100644 | |
7920 | --- a/gdb/configure.ac | |
7921 | +++ b/gdb/configure.ac | |
7922 | @@ -1,6 +1,6 @@ | |
7923 | dnl Autoconf configure script for GDB, the GNU debugger. | |
7924 | dnl Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | |
7925 | -dnl 2005, 2006, 2007, 2008 | |
7926 | +dnl 2005, 2006, 2007, 2008, 2009 | |
7927 | dnl Free Software Foundation, Inc. | |
7928 | dnl | |
7929 | dnl This file is part of GDB. | |
7930 | @@ -118,6 +118,51 @@ case ${debugdir} in | |
7931 | ;; | |
7932 | esac | |
7933 | ||
7934 | +# GDB's datadir relocation | |
7935 | + | |
7936 | +gdbdatadir=${datadir}/gdb | |
7937 | + | |
7938 | +AC_ARG_WITH([gdb-datadir], | |
7939 | + [AS_HELP_STRING([--with-gdb-datadir], | |
7940 | + [look for global separate data files in this path [DATADIR/gdb]])], [gdbdatadir="${withval}"]) | |
7941 | + | |
7942 | +AC_DEFINE_DIR(GDB_DATADIR, gdbdatadir, | |
7943 | + [Global directory for GDB data files. ]) | |
7944 | + | |
7945 | +if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then | |
7946 | + if test "x$prefix" = xNONE; then | |
7947 | + test_prefix=/usr/local | |
7948 | + else | |
7949 | + test_prefix=$prefix | |
7950 | + fi | |
7951 | +else | |
7952 | + test_prefix=$exec_prefix | |
7953 | +fi | |
7954 | + | |
7955 | +case ${gdbdatadir} in | |
7956 | + "${test_prefix}"|"${test_prefix}/"*|\ | |
7957 | + '${exec_prefix}'|'${exec_prefix}/'*) | |
7958 | + AC_DEFINE(GDB_DATADIR_RELOCATABLE, 1, [Define if GDB datadir should be relocated when GDB is moved.]) | |
7959 | + ;; | |
7960 | +esac | |
7961 | +GDB_DATADIR_PATH=${gdbdatadir} | |
7962 | +AC_SUBST(GDB_DATADIR_PATH) | |
7963 | + | |
7964 | +AC_ARG_WITH([pythondir], | |
7965 | + [AS_HELP_STRING([--with-pythondir], | |
7966 | + [install Python data files in this path [DATADIR/gdb/python]])], [pythondir="${withval}"], [pythondir=no]) | |
7967 | + | |
7968 | +# If the user passed in a path, define it. Otherwise, compute it at | |
7969 | +# runtime based on the possibly-relocatable datadir. | |
7970 | +if test "$pythondir" = "no"; then | |
7971 | + pythondir='$(GDB_DATADIR_PATH)/python' | |
7972 | +else | |
7973 | + AC_DEFINE_UNQUOTED(PYTHONDIR, "$pythondir", | |
7974 | + [Define to install path for Python sources]) | |
7975 | +fi | |
7976 | +AC_SUBST(pythondir) | |
7977 | + | |
7978 | + | |
7979 | AC_CONFIG_SUBDIRS(doc testsuite) | |
7980 | ||
7981 | # Check whether to support alternative target configurations | |
7982 | @@ -430,6 +475,8 @@ AC_SEARCH_LIBS(zlibVersion, z, [AC_CHECK_HEADERS(zlib.h)]) | |
7983 | # On HP/UX we may need libxpdl for dlgetmodinfo (used by solib-pa64.c). | |
7984 | AC_SEARCH_LIBS(dlgetmodinfo, [dl xpdl]) | |
7985 | ||
7986 | +AM_ICONV | |
7987 | + | |
7988 | # On alpha-osf, it appears that libtermcap and libcurses are not compatible. | |
7989 | # There is a very specific comment in /usr/include/curses.h explaining that | |
7990 | # termcap routines built into libcurses must not be used. | |
7991 | @@ -649,6 +696,8 @@ if test "${have_libpython}" = yes; then | |
7992 | CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_PYTHON_OBS)" | |
7993 | CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_PYTHON_DEPS)" | |
7994 | CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_PYTHON_SRCS)" | |
7995 | + CONFIG_INSTALL="$CONFIG_INSTALL install-python" | |
7996 | + CONFIG_UNINSTALL="$CONFIG_UNINSTALL uninstall-python" | |
7997 | ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_PYTHON_CFLAGS)" | |
7998 | ||
7999 | # Flags needed to compile Python code (taken from python-config --cflags). | |
8000 | @@ -776,7 +825,8 @@ AC_FUNC_VFORK | |
8001 | AC_CHECK_FUNCS([canonicalize_file_name realpath getrusage getuid \ | |
8002 | getgid poll pread64 sbrk setpgid setpgrp setsid \ | |
8003 | sigaction sigprocmask sigsetmask socketpair syscall \ | |
8004 | - ttrace wborder setlocale]) | |
8005 | + ttrace wborder setlocale iconvlist]) | |
8006 | +AM_LANGINFO_CODESET | |
8007 | ||
8008 | # Check the return and argument types of ptrace. No canned test for | |
8009 | # this, so roll our own. | |
8010 | @@ -1930,17 +1980,10 @@ dnl Check for exe extension set on certain hosts (e.g. Win32) | |
8011 | AC_EXEEXT | |
8012 | ||
8013 | dnl Detect the character set used by this host. | |
8014 | - | |
8015 | -dnl At the moment, we just assume it's ISO-8859-1 (which is a | |
8016 | -dnl superset of ASCII containing the characters needed for French, | |
8017 | -dnl German, Spanish, Italian, and possibly others), but if were | |
8018 | -dnl *were* to support any host character sets other than ISO-8859-1, | |
8019 | -dnl here's where we'd detect it. | |
8020 | -AC_DEFINE(GDB_DEFAULT_HOST_CHARSET, "ISO-8859-1", | |
8021 | +dnl At the moment, we just assume it's UTF-8. | |
8022 | +AC_DEFINE(GDB_DEFAULT_HOST_CHARSET, "UTF-8", | |
8023 | [Define to be a string naming the default host character set.]) | |
8024 | ||
8025 | -AM_ICONV | |
8026 | - | |
8027 | AC_OUTPUT(Makefile .gdbinit:gdbinit.in gnulib/Makefile, | |
8028 | [ | |
8029 | dnl Autoconf doesn't provide a mechanism for modifying definitions | |
8030 | diff --git a/gdb/configure.tgt b/gdb/configure.tgt | |
8031 | index 65c3e25..f0cca7d 100644 | |
8032 | --- a/gdb/configure.tgt | |
8033 | +++ b/gdb/configure.tgt | |
8034 | @@ -36,7 +36,7 @@ alpha*-*-osf*) | |
8035 | alpha*-*-linux*) | |
8036 | # Target: Little-endian Alpha running Linux | |
8037 | gdb_target_obs="alpha-tdep.o alpha-mdebug-tdep.o alpha-linux-tdep.o \ | |
8038 | - solib.o solib-svr4.o" | |
8039 | + solib.o solib-svr4.o linux-tdep.o" | |
8040 | ;; | |
8041 | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu) | |
8042 | # Target: FreeBSD/alpha | |
8043 | @@ -63,7 +63,7 @@ alpha*-*-*) | |
8044 | am33_2.0*-*-linux*) | |
8045 | # Target: Matsushita mn10300 (AM33) running Linux | |
8046 | gdb_target_obs="mn10300-tdep.o mn10300-linux-tdep.o corelow.o \ | |
8047 | - solib.o solib-svr4.o" | |
8048 | + solib.o solib-svr4.o linux-tdep.o" | |
8049 | ;; | |
8050 | ||
8051 | arm*-wince-pe | arm*-*-mingw32ce*) | |
8052 | @@ -128,7 +128,7 @@ hppa*-*-hpux*) | |
8053 | hppa*-*-linux*) | |
8054 | # Target: HP PA-RISC running Linux | |
8055 | gdb_target_obs="hppa-tdep.o hppa-linux-tdep.o glibc-tdep.o \ | |
8056 | - solib.o solib-svr4.o symfile-mem.o" | |
8057 | + solib.o solib-svr4.o symfile-mem.o linux-tdep.o" | |
8058 | ;; | |
8059 | hppa*-*-netbsd*) | |
8060 | # Target: NetBSD/hppa | |
8061 | @@ -218,7 +218,7 @@ i[34567]86-*-*) | |
8062 | ia64-*-linux*) | |
8063 | # Target: Intel IA-64 running GNU/Linux | |
8064 | gdb_target_obs="ia64-tdep.o ia64-linux-tdep.o \ | |
8065 | - solib.o solib-svr4.o symfile-mem.o" | |
8066 | + solib.o solib-svr4.o symfile-mem.o linux-tdep.o" | |
8067 | build_gdbserver=yes | |
8068 | ;; | |
8069 | ia64*-*-*) | |
8070 | @@ -242,7 +242,8 @@ m32c-*-*) | |
8071 | m32r*-*-linux*) | |
8072 | # Target: Renesas M32R running GNU/Linux | |
8073 | gdb_target_obs="m32r-tdep.o m32r-linux-tdep.o remote-m32r-sdi.o \ | |
8074 | - glibc-tdep.o solib.o solib-svr4.o symfile-mem.o" | |
8075 | + glibc-tdep.o solib.o solib-svr4.o symfile-mem.o \ | |
8076 | + linux-tdep.o" | |
8077 | gdb_sim=../sim/m32r/libsim.a | |
8078 | build_gdbserver=yes | |
8079 | ;; | |
8080 | @@ -267,7 +268,7 @@ fido-*-elf*) | |
8081 | m68*-*-linux*) | |
8082 | # Target: Motorola m68k with a.out and ELF | |
8083 | gdb_target_obs="m68k-tdep.o m68klinux-tdep.o solib.o solib-svr4.o \ | |
8084 | - glibc-tdep.o symfile-mem.o" | |
8085 | + glibc-tdep.o symfile-mem.o linux-tdep.o" | |
8086 | build_gdbserver=yes | |
8087 | ;; | |
8088 | m68*-*-netbsd* | m68*-*-knetbsd*-gnu) | |
8089 | @@ -303,7 +304,8 @@ mips*-sgi-irix6*) | |
8090 | mips*-*-linux*) | |
8091 | # Target: Linux/MIPS | |
8092 | gdb_target_obs="mips-tdep.o mips-linux-tdep.o glibc-tdep.o \ | |
8093 | - corelow.o solib.o solib-svr4.o symfile-mem.o" | |
8094 | + corelow.o solib.o solib-svr4.o symfile-mem.o \ | |
8095 | + linux-tdep.o" | |
8096 | gdb_sim=../sim/mips/libsim.a | |
8097 | build_gdbserver=yes | |
8098 | ;; | |
8099 | @@ -354,7 +356,8 @@ powerpc-*-aix* | rs6000-*-*) | |
8100 | powerpc-*-linux* | powerpc64-*-linux*) | |
8101 | # Target: PowerPC running Linux | |
8102 | gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \ | |
8103 | - solib.o solib-svr4.o corelow.o symfile-mem.o" | |
8104 | + solib.o solib-svr4.o corelow.o symfile-mem.o \ | |
8105 | + linux-tdep.o" | |
8106 | gdb_sim=../sim/ppc/libsim.a | |
8107 | build_gdbserver=yes | |
8108 | ;; | |
8109 | @@ -381,7 +384,8 @@ score-*-*) | |
8110 | sh*-*-linux*) | |
8111 | # Target: GNU/Linux Super-H | |
8112 | gdb_target_obs="sh-tdep.o sh64-tdep.o sh-linux-tdep.o monitor.o \ | |
8113 | - dsrec.o solib.o solib-svr4.o symfile-mem.o glibc-tdep.o" | |
8114 | + dsrec.o solib.o solib-svr4.o symfile-mem.o glibc-tdep.o \ | |
8115 | + linux-tdep.o" | |
8116 | gdb_sim=../sim/sh/libsim.a | |
8117 | build_gdbserver=yes | |
8118 | ;; | |
8119 | @@ -409,13 +413,14 @@ sh*) | |
8120 | sparc-*-linux*) | |
8121 | # Target: GNU/Linux SPARC | |
8122 | gdb_target_obs="sparc-tdep.o sparc-sol2-tdep.o sol2-tdep.o \ | |
8123 | - sparc-linux-tdep.o solib.o solib-svr4.o symfile-mem.o" | |
8124 | + sparc-linux-tdep.o solib.o solib-svr4.o symfile-mem.o \ | |
8125 | + linux-tdep.o" | |
8126 | ;; | |
8127 | sparc64-*-linux*) | |
8128 | # Target: GNU/Linux UltraSPARC | |
8129 | gdb_target_obs="sparc64-tdep.o sparc64-sol2-tdep.o sol2-tdep.o \ | |
8130 | sparc64-linux-tdep.o sparc-tdep.o sparc-sol2-tdep.o \ | |
8131 | - sparc-linux-tdep.o solib.o solib-svr4.o" | |
8132 | + sparc-linux-tdep.o solib.o solib-svr4.o linux-tdep.o" | |
8133 | build_gdbserver=yes | |
8134 | ;; | |
8135 | sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu) | |
8136 | @@ -542,7 +547,8 @@ x86_64-*-openbsd*) | |
8137 | xtensa*-*-linux*) gdb_target=linux | |
8138 | # Target: GNU/Linux Xtensa | |
8139 | gdb_target_obs="xtensa-tdep.o xtensa-config.o xtensa-linux-tdep.o \ | |
8140 | - solib.o solib-svr4.o corelow.o symfile-mem.o" | |
8141 | + solib.o solib-svr4.o corelow.o symfile-mem.o \ | |
8142 | + linux-tdep.o" | |
8143 | build_gdbserver=yes | |
8144 | ;; | |
8145 | xtensa*) | |
8146 | diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y | |
8147 | index 5f5ee3a..a8f8f30 100644 | |
8148 | --- a/gdb/cp-name-parser.y | |
8149 | +++ b/gdb/cp-name-parser.y | |
8150 | @@ -1,7 +1,6 @@ | |
8151 | /* YACC parser for C++ names, for GDB. | |
8152 | ||
8153 | - Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 | |
8154 | - Free Software Foundation, Inc. | |
8155 | + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. | |
8156 | ||
8157 | Parts of the lexer are based on c-exp.y from GDB. | |
8158 | ||
8159 | @@ -501,7 +500,7 @@ operator : OPERATOR NEW | |
8160 | | OPERATOR ARROW | |
8161 | { $$ = make_operator ("->", 2); } | |
8162 | | OPERATOR '(' ')' | |
8163 | - { $$ = make_operator ("()", 0); } | |
8164 | + { $$ = make_operator ("()", 2); } | |
8165 | | OPERATOR '[' ']' | |
8166 | { $$ = make_operator ("[]", 2); } | |
8167 | ; | |
8168 | diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c | |
8169 | index c6c5617..4b84348 100644 | |
8170 | --- a/gdb/cp-namespace.c | |
8171 | +++ b/gdb/cp-namespace.c | |
8172 | @@ -30,26 +30,13 @@ | |
8173 | #include "dictionary.h" | |
8174 | #include "command.h" | |
8175 | #include "frame.h" | |
8176 | +#include "buildsym.h" | |
8177 | ||
8178 | /* List of using directives that are active in the current file. */ | |
8179 | ||
8180 | -static struct using_direct *using_list; | |
8181 | - | |
8182 | -static struct using_direct *cp_add_using (const char *name, | |
8183 | - unsigned int inner_len, | |
8184 | - unsigned int outer_len, | |
8185 | - struct using_direct *next); | |
8186 | - | |
8187 | static struct using_direct *cp_copy_usings (struct using_direct *using, | |
8188 | struct obstack *obstack); | |
8189 | ||
8190 | -static struct symbol *lookup_namespace_scope (const char *name, | |
8191 | - const char *linkage_name, | |
8192 | - const struct block *block, | |
8193 | - const domain_enum domain, | |
8194 | - const char *scope, | |
8195 | - int scope_len); | |
8196 | - | |
8197 | static struct symbol *lookup_symbol_file (const char *name, | |
8198 | const char *linkage_name, | |
8199 | const struct block *block, | |
8200 | @@ -78,31 +65,6 @@ static struct symbol *lookup_possible_namespace_symbol (const char *name); | |
8201 | ||
8202 | static void maintenance_cplus_namespace (char *args, int from_tty); | |
8203 | ||
8204 | -/* Set up support for dealing with C++ namespace info in the current | |
8205 | - symtab. */ | |
8206 | - | |
8207 | -void cp_initialize_namespace () | |
8208 | -{ | |
8209 | - using_list = NULL; | |
8210 | -} | |
8211 | - | |
8212 | -/* Add all the using directives we've gathered to the current symtab. | |
8213 | - STATIC_BLOCK should be the symtab's static block; OBSTACK is used | |
8214 | - for allocation. */ | |
8215 | - | |
8216 | -void | |
8217 | -cp_finalize_namespace (struct block *static_block, | |
8218 | - struct obstack *obstack) | |
8219 | -{ | |
8220 | - if (using_list != NULL) | |
8221 | - { | |
8222 | - block_set_using (static_block, | |
8223 | - cp_copy_usings (using_list, obstack), | |
8224 | - obstack); | |
8225 | - using_list = NULL; | |
8226 | - } | |
8227 | -} | |
8228 | - | |
8229 | /* Check to see if SYMBOL refers to an object contained within an | |
8230 | anonymous namespace; if so, add an appropriate using directive. */ | |
8231 | ||
8232 | @@ -136,14 +98,17 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol) | |
8233 | "(anonymous namespace)", | |
8234 | ANONYMOUS_NAMESPACE_LEN) == 0) | |
8235 | { | |
8236 | + int outer_len = (previous_component == 0 ? 0 : previous_component - 2); | |
8237 | + char outer[outer_len+1]; | |
8238 | + | |
8239 | + strncpy(outer, name, outer_len); | |
8240 | + | |
8241 | + outer[outer_len] = '\0'; | |
8242 | /* We've found a component of the name that's an | |
8243 | anonymous namespace. So add symbols in it to the | |
8244 | namespace given by the previous component if there is | |
8245 | one, or to the global namespace if there isn't. */ | |
8246 | - cp_add_using_directive (name, | |
8247 | - previous_component == 0 | |
8248 | - ? 0 : previous_component - 2, | |
8249 | - next_component); | |
8250 | + cp_add_using_directive (outer, name, "", "", 0); | |
8251 | } | |
8252 | /* The "+ 2" is for the "::". */ | |
8253 | previous_component = next_component + 2; | |
8254 | @@ -154,32 +119,27 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol) | |
8255 | } | |
8256 | } | |
8257 | ||
8258 | -/* Add a using directive to using_list. NAME is the start of a string | |
8259 | - that should contain the namespaces we want to add as initial | |
8260 | - substrings, OUTER_LENGTH is the end of the outer namespace, and | |
8261 | - INNER_LENGTH is the end of the inner namespace. If the using | |
8262 | - directive in question has already been added, don't add it | |
8263 | - twice. */ | |
8264 | +/* Add a using directive to using_list. If the using directive in question | |
8265 | + has already been added, don't add it twice. */ | |
8266 | ||
8267 | void | |
8268 | -cp_add_using_directive (const char *name, unsigned int outer_length, | |
8269 | - unsigned int inner_length) | |
8270 | +cp_add_using_directive (const char *outer, const char *inner, const char* alias, | |
8271 | + const char *declaration, const int line_number) | |
8272 | { | |
8273 | struct using_direct *current; | |
8274 | struct using_direct *new; | |
8275 | ||
8276 | /* Has it already been added? */ | |
8277 | ||
8278 | - for (current = using_list; current != NULL; current = current->next) | |
8279 | + for (current = using_directives; current != NULL; current = current->next) | |
8280 | { | |
8281 | - if ((strncmp (current->inner, name, inner_length) == 0) | |
8282 | - && (strlen (current->inner) == inner_length) | |
8283 | - && (strlen (current->outer) == outer_length)) | |
8284 | + if (strcmp (current->inner, inner) == 0 | |
8285 | + && strcmp (current->outer, outer) == 0) | |
8286 | return; | |
8287 | } | |
8288 | ||
8289 | - using_list = cp_add_using (name, inner_length, outer_length, | |
8290 | - using_list); | |
8291 | + using_directives = cp_add_using (outer, inner, alias, declaration, | |
8292 | + line_number,using_directives); | |
8293 | } | |
8294 | ||
8295 | /* Record the namespace that the function defined by SYMBOL was | |
8296 | @@ -230,26 +190,31 @@ cp_is_anonymous (const char *namespace) | |
8297 | != NULL); | |
8298 | } | |
8299 | ||
8300 | -/* Create a new struct using direct whose inner namespace is the | |
8301 | - initial substring of NAME of leng INNER_LEN and whose outer | |
8302 | - namespace is the initial substring of NAME of length OUTER_LENGTH. | |
8303 | +/* Create a new struct using direct whose inner namespace is INNER | |
8304 | + and whose outer namespace is OUTER. ALIAS is the name of the imported | |
8305 | + namespace in the current scope. If ALIAS is an empty string then the | |
8306 | + namespace is known by its original name. | |
8307 | Set its next member in the linked list to NEXT; allocate all memory | |
8308 | using xmalloc. It copies the strings, so NAME can be a temporary | |
8309 | string. */ | |
8310 | ||
8311 | -static struct using_direct * | |
8312 | -cp_add_using (const char *name, | |
8313 | - unsigned int inner_len, | |
8314 | - unsigned int outer_len, | |
8315 | +struct using_direct * | |
8316 | +cp_add_using (const char *outer, | |
8317 | + const char *inner, | |
8318 | + const char *alias, | |
8319 | + const char *declaration, | |
8320 | + const int line_number, | |
8321 | struct using_direct *next) | |
8322 | { | |
8323 | struct using_direct *retval; | |
8324 | ||
8325 | - gdb_assert (outer_len < inner_len); | |
8326 | - | |
8327 | retval = xmalloc (sizeof (struct using_direct)); | |
8328 | - retval->inner = savestring (name, inner_len); | |
8329 | - retval->outer = savestring (name, outer_len); | |
8330 | + retval->inner = savestring (inner, strlen(inner)); | |
8331 | + retval->outer = savestring (outer, strlen(outer)); | |
8332 | + retval->alias = savestring (alias, strlen(alias)); | |
8333 | + retval->declaration = savestring (declaration, strlen(declaration)); | |
8334 | + retval->line_number = line_number; | |
8335 | + | |
8336 | retval->next = next; | |
8337 | ||
8338 | return retval; | |
8339 | @@ -274,7 +239,11 @@ cp_copy_usings (struct using_direct *using, | |
8340 | retval->inner = obsavestring (using->inner, strlen (using->inner), | |
8341 | obstack); | |
8342 | retval->outer = obsavestring (using->outer, strlen (using->outer), | |
8343 | - obstack); | |
8344 | + obstack); | |
8345 | + retval->alias = obsavestring (using->alias, strlen (using->alias), | |
8346 | + obstack); | |
8347 | + retval->declaration = obsavestring (using->declaration, strlen (using->declaration), | |
8348 | + obstack); | |
8349 | retval->next = cp_copy_usings (using->next, obstack); | |
8350 | ||
8351 | xfree (using->inner); | |
8352 | @@ -299,8 +268,14 @@ cp_lookup_symbol_nonlocal (const char *name, | |
8353 | const struct block *block, | |
8354 | const domain_enum domain) | |
8355 | { | |
8356 | - return lookup_namespace_scope (name, linkage_name, block, domain, | |
8357 | - block_scope (block), 0); | |
8358 | + | |
8359 | + struct symbol* sym = lookup_namespace_scope(name, linkage_name, block, | |
8360 | + domain, block_scope(block), 0); | |
8361 | + | |
8362 | + if (sym != NULL) | |
8363 | + return sym; | |
8364 | + | |
8365 | + return lookup_symbol_file(name, linkage_name, block, domain, 0); | |
8366 | } | |
8367 | ||
8368 | /* Lookup NAME at namespace scope (or, in C terms, in static and | |
8369 | @@ -318,7 +293,7 @@ cp_lookup_symbol_nonlocal (const char *name, | |
8370 | "A::x", and if that call fails, then the first call looks for | |
8371 | "x". */ | |
8372 | ||
8373 | -static struct symbol * | |
8374 | +struct symbol * | |
8375 | lookup_namespace_scope (const char *name, | |
8376 | const char *linkage_name, | |
8377 | const struct block *block, | |
8378 | @@ -354,10 +329,43 @@ lookup_namespace_scope (const char *name, | |
8379 | namespace = alloca (scope_len + 1); | |
8380 | strncpy (namespace, scope, scope_len); | |
8381 | namespace[scope_len] = '\0'; | |
8382 | - return cp_lookup_symbol_namespace (namespace, name, linkage_name, | |
8383 | + return cp_lookup_symbol_namespace_incremental (namespace, name, linkage_name, | |
8384 | block, domain); | |
8385 | } | |
8386 | ||
8387 | +/* Searches the for the given NAME in the given NAMESPACE, using import | |
8388 | + statements implied by the given BLOCK, *and its' parents*. */ | |
8389 | +struct symbol * | |
8390 | +cp_lookup_symbol_namespace_incremental (const char *namespace, | |
8391 | + const char *name, | |
8392 | + const char *linkage_name, | |
8393 | + const struct block *block, | |
8394 | + const domain_enum domain) | |
8395 | +{ | |
8396 | + struct symbol *sym; | |
8397 | + const struct block *global_block = block_global_block (block); | |
8398 | + | |
8399 | + /* Check if either no block is specified or it's a global block. */ | |
8400 | + | |
8401 | + if (global_block == NULL) | |
8402 | + return NULL; | |
8403 | + | |
8404 | + while (block != global_block) | |
8405 | + { | |
8406 | + sym = cp_lookup_symbol_namespace (namespace, name, linkage_name, block, domain); | |
8407 | + | |
8408 | + if (sym != NULL) | |
8409 | + return sym; | |
8410 | + | |
8411 | + block = BLOCK_SUPERBLOCK (block); | |
8412 | + } | |
8413 | + | |
8414 | + /* We've reached the global block without finding a result. */ | |
8415 | + | |
8416 | + return NULL; | |
8417 | +} | |
8418 | + | |
8419 | + | |
8420 | /* Look up NAME in the C++ namespace NAMESPACE, applying the using | |
8421 | directives that are active in BLOCK. Other arguments are as in | |
8422 | cp_lookup_symbol_nonlocal. */ | |
8423 | @@ -370,7 +378,7 @@ cp_lookup_symbol_namespace (const char *namespace, | |
8424 | const domain_enum domain) | |
8425 | { | |
8426 | const struct using_direct *current; | |
8427 | - struct symbol *sym; | |
8428 | + struct symbol *sym = NULL; | |
8429 | ||
8430 | /* First, go through the using directives. If any of them add new | |
8431 | names to the namespace we're searching in, see if we can find a | |
8432 | @@ -380,15 +388,42 @@ cp_lookup_symbol_namespace (const char *namespace, | |
8433 | current != NULL; | |
8434 | current = current->next) | |
8435 | { | |
8436 | - if (strcmp (namespace, current->outer) == 0) | |
8437 | + | |
8438 | + int current_line = find_pc_line (get_frame_pc (get_current_frame ()), 0).line; | |
8439 | + | |
8440 | + if (strcmp (namespace, current->outer) == 0 && current->line_number < current_line) | |
8441 | { | |
8442 | - sym = cp_lookup_symbol_namespace (current->inner, | |
8443 | - name, | |
8444 | - linkage_name, | |
8445 | - block, | |
8446 | - domain); | |
8447 | - if (sym != NULL) | |
8448 | + | |
8449 | + if(strcmp ("", current->declaration) != 0){ | |
8450 | + if(strcmp (name, current->declaration) == 0){ | |
8451 | + sym = cp_lookup_symbol_namespace (current->inner, | |
8452 | + name, | |
8453 | + linkage_name, | |
8454 | + block, | |
8455 | + domain); | |
8456 | + } | |
8457 | + | |
8458 | + }else{ | |
8459 | + /* Check for aliases */ | |
8460 | + if(strcmp (name, current->alias) == 0){ | |
8461 | + sym = cp_lookup_symbol_namespace (namespace, | |
8462 | + current->inner, | |
8463 | + linkage_name, | |
8464 | + block, | |
8465 | + domain); | |
8466 | + }else{ | |
8467 | + if(strcmp ("", current->alias) == 0){ | |
8468 | + sym = cp_lookup_symbol_namespace (current->inner, | |
8469 | + name, | |
8470 | + linkage_name, | |
8471 | + block, | |
8472 | + domain); | |
8473 | + } | |
8474 | + } | |
8475 | + } | |
8476 | + if (sym != NULL){ | |
8477 | return sym; | |
8478 | + } | |
8479 | } | |
8480 | } | |
8481 | ||
8482 | @@ -398,8 +433,10 @@ cp_lookup_symbol_namespace (const char *namespace, | |
8483 | ||
8484 | if (namespace[0] == '\0') | |
8485 | { | |
8486 | - return lookup_symbol_file (name, linkage_name, block, | |
8487 | - domain, 0); | |
8488 | + sym = lookup_symbol_file (name, linkage_name, | |
8489 | + block, domain, | |
8490 | + cp_is_anonymous (namespace)); | |
8491 | + return sym; | |
8492 | } | |
8493 | else | |
8494 | { | |
8495 | diff --git a/gdb/cp-support.c b/gdb/cp-support.c | |
8496 | index bf42636..9f04c86 100644 | |
8497 | --- a/gdb/cp-support.c | |
8498 | +++ b/gdb/cp-support.c | |
8499 | @@ -175,7 +175,8 @@ mangled_name_to_comp (const char *mangled_name, int options, | |
8500 | return ret; | |
8501 | } | |
8502 | ||
8503 | -/* Return the name of the class containing method PHYSNAME. */ | |
8504 | +/* Return the name of the class or namespace containing | |
8505 | + function, method, or variable PHYSNAME. */ | |
8506 | ||
8507 | char * | |
8508 | cp_class_name_from_physname (const char *physname) | |
8509 | diff --git a/gdb/cp-support.h b/gdb/cp-support.h | |
8510 | index 837ca6c..23f8d5b 100644 | |
8511 | --- a/gdb/cp-support.h | |
8512 | +++ b/gdb/cp-support.h | |
8513 | @@ -38,14 +38,28 @@ struct demangle_component; | |
8514 | ||
8515 | /* This struct is designed to store data from using directives. It | |
8516 | says that names from namespace INNER should be visible within | |
8517 | - namespace OUTER. OUTER should always be a strict initial substring | |
8518 | - of INNER. These form a linked list; NEXT is the next element of | |
8519 | - the list. */ | |
8520 | + namespace OUTER These form a linked list; NEXT is the next element of | |
8521 | + the list. ALIAS is set to a non empty string if the imported namespace | |
8522 | + has been aliased.Eg: | |
8523 | + namespace C=A::B; | |
8524 | + ALIAS = "C" | |
8525 | + DECLARATION is the name of the imported declaration, if this import | |
8526 | + statement represents one. Eg: | |
8527 | + using A::x; | |
8528 | + Where x is variable in namespace A. declaration is set to x. | |
8529 | +*/ | |
8530 | ||
8531 | struct using_direct | |
8532 | { | |
8533 | char *inner; | |
8534 | char *outer; | |
8535 | + | |
8536 | + char *alias; | |
8537 | + | |
8538 | + char *declaration; | |
8539 | + | |
8540 | + int line_number; | |
8541 | + | |
8542 | struct using_direct *next; | |
8543 | }; | |
8544 | ||
8545 | @@ -54,6 +68,7 @@ struct using_direct | |
8546 | ||
8547 | extern char *cp_canonicalize_string (const char *string); | |
8548 | ||
8549 | + | |
8550 | extern char *cp_class_name_from_physname (const char *physname); | |
8551 | ||
8552 | extern char *method_name_from_physname (const char *physname); | |
8553 | @@ -76,9 +91,18 @@ extern struct type *cp_lookup_rtti_type (const char *name, | |
8554 | ||
8555 | extern int cp_is_anonymous (const char *namespace); | |
8556 | ||
8557 | -extern void cp_add_using_directive (const char *name, | |
8558 | - unsigned int outer_length, | |
8559 | - unsigned int inner_length); | |
8560 | +extern void cp_add_using_directive (const char *outer, | |
8561 | + const char *inner, | |
8562 | + const char *alias, | |
8563 | + const char *declaration, | |
8564 | + const int line_number); | |
8565 | + | |
8566 | +extern struct using_direct *cp_add_using (const char *outer, | |
8567 | + const char *inner, | |
8568 | + const char *alias, | |
8569 | + const char *declaration, | |
8570 | + const int line_number, | |
8571 | + struct using_direct *next); | |
8572 | ||
8573 | extern void cp_initialize_namespace (void); | |
8574 | ||
8575 | @@ -98,6 +122,19 @@ extern struct symbol *cp_lookup_symbol_nonlocal (const char *name, | |
8576 | const struct block *block, | |
8577 | const domain_enum domain); | |
8578 | ||
8579 | +extern struct symbol *lookup_namespace_scope (const char *name, | |
8580 | + const char *linkage_name, | |
8581 | + const struct block *block, | |
8582 | + const domain_enum domain, | |
8583 | + const char *scope, | |
8584 | + int scope_len); | |
8585 | + | |
8586 | +extern struct symbol *cp_lookup_symbol_namespace_incremental (const char *namespace, | |
8587 | + const char *name, | |
8588 | + const char *linkage_name, | |
8589 | + const struct block *block, | |
8590 | + const domain_enum domain); | |
8591 | + | |
8592 | extern struct symbol *cp_lookup_symbol_namespace (const char *namespace, | |
8593 | const char *name, | |
8594 | const char *linkage_name, | |
8595 | diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c | |
8596 | index 8b7d868..dcd32cb 100644 | |
8597 | --- a/gdb/cp-valprint.c | |
8598 | +++ b/gdb/cp-valprint.c | |
8599 | @@ -461,6 +461,7 @@ cp_print_static_field (struct type *type, | |
8600 | if (TYPE_CODE (type) == TYPE_CODE_STRUCT) | |
8601 | { | |
8602 | CORE_ADDR *first_dont_print; | |
8603 | + CORE_ADDR addr; | |
8604 | int i; | |
8605 | ||
8606 | first_dont_print | |
8607 | @@ -470,7 +471,7 @@ cp_print_static_field (struct type *type, | |
8608 | ||
8609 | while (--i >= 0) | |
8610 | { | |
8611 | - if (VALUE_ADDRESS (val) == first_dont_print[i]) | |
8612 | + if (value_address (val) == first_dont_print[i]) | |
8613 | { | |
8614 | fputs_filtered ("<same as static member of an already" | |
8615 | " seen type>", | |
8616 | @@ -479,12 +480,13 @@ cp_print_static_field (struct type *type, | |
8617 | } | |
8618 | } | |
8619 | ||
8620 | - obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val), | |
8621 | + addr = value_address (val); | |
8622 | + obstack_grow (&dont_print_statmem_obstack, (char *) &addr, | |
8623 | sizeof (CORE_ADDR)); | |
8624 | ||
8625 | CHECK_TYPEDEF (type); | |
8626 | cp_print_value_fields (type, type, value_contents_all (val), | |
8627 | - value_embedded_offset (val), VALUE_ADDRESS (val), | |
8628 | + value_embedded_offset (val), value_address (val), | |
8629 | stream, recurse, options, NULL, 1); | |
8630 | return; | |
8631 | } | |
8632 | @@ -492,7 +494,7 @@ cp_print_static_field (struct type *type, | |
8633 | opts = *options; | |
8634 | opts.deref_ref = 0; | |
8635 | val_print (type, value_contents_all (val), | |
8636 | - value_embedded_offset (val), VALUE_ADDRESS (val), | |
8637 | + value_embedded_offset (val), value_address (val), | |
8638 | stream, recurse, &opts, current_language); | |
8639 | } | |
8640 | ||
8641 | diff --git a/gdb/dbxread.c b/gdb/dbxread.c | |
8642 | index 115bdef..7f756af 100644 | |
8643 | --- a/gdb/dbxread.c | |
8644 | +++ b/gdb/dbxread.c | |
8645 | @@ -1,6 +1,6 @@ | |
8646 | /* Read dbx symbol tables and convert to internal format, for GDB. | |
8647 | Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, | |
8648 | - 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008. | |
8649 | + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008, 2009. | |
8650 | Free Software Foundation, Inc. | |
8651 | ||
8652 | This file is part of GDB. | |
8653 | @@ -1188,6 +1188,8 @@ read_dbx_symtab (struct objfile *objfile) | |
8654 | struct internal_nlist nlist; | |
8655 | CORE_ADDR text_addr; | |
8656 | int text_size; | |
8657 | + char *sym_name; | |
8658 | + int sym_len; | |
8659 | ||
8660 | char *namestring; | |
8661 | int nsl; | |
8662 | @@ -1681,6 +1683,28 @@ pos %d"), | |
8663 | if (!p) | |
8664 | continue; /* Not a debugging symbol. */ | |
8665 | ||
8666 | + sym_len = 0; | |
8667 | + if (psymtab_language == language_cplus) | |
8668 | + { | |
8669 | + char *new_name, *name = alloca (p - namestring + 1); | |
8670 | + memcpy (name, namestring, p - namestring); | |
8671 | + name[p - namestring] = '\0'; | |
8672 | + new_name = cp_canonicalize_string (name); | |
8673 | + if (new_name != NULL) | |
8674 | + { | |
8675 | + sym_len = strlen (new_name); | |
8676 | + sym_name = obsavestring (new_name, sym_len, | |
8677 | + &objfile->objfile_obstack); | |
8678 | + xfree (new_name); | |
8679 | + } | |
8680 | + } | |
8681 | + | |
8682 | + if (sym_len == 0) | |
8683 | + { | |
8684 | + sym_name = namestring; | |
8685 | + sym_len = p - namestring; | |
8686 | + } | |
8687 | + | |
8688 | /* Main processing section for debugging symbols which | |
8689 | the initial read through the symbol tables needs to worry | |
8690 | about. If we reach this point, the symbol which we are | |
8691 | @@ -1698,7 +1722,7 @@ pos %d"), | |
8692 | namestring = gdbarch_static_transform_name (gdbarch, | |
8693 | namestring); | |
8694 | ||
8695 | - add_psymbol_to_list (namestring, p - namestring, | |
8696 | + add_psymbol_to_list (sym_name, sym_len, | |
8697 | VAR_DOMAIN, LOC_STATIC, | |
8698 | &objfile->static_psymbols, | |
8699 | 0, nlist.n_value, | |
8700 | @@ -1710,7 +1734,7 @@ pos %d"), | |
8701 | data_sect_index); | |
8702 | /* The addresses in these entries are reported to be | |
8703 | wrong. See the code that reads 'G's for symtabs. */ | |
8704 | - add_psymbol_to_list (namestring, p - namestring, | |
8705 | + add_psymbol_to_list (sym_name, sym_len, | |
8706 | VAR_DOMAIN, LOC_STATIC, | |
8707 | &objfile->global_psymbols, | |
8708 | 0, nlist.n_value, | |
8709 | @@ -1728,7 +1752,7 @@ pos %d"), | |
8710 | || (p == namestring + 1 | |
8711 | && namestring[0] != ' ')) | |
8712 | { | |
8713 | - add_psymbol_to_list (namestring, p - namestring, | |
8714 | + add_psymbol_to_list (sym_name, sym_len, | |
8715 | STRUCT_DOMAIN, LOC_TYPEDEF, | |
8716 | &objfile->static_psymbols, | |
8717 | nlist.n_value, 0, | |
8718 | @@ -1736,7 +1760,7 @@ pos %d"), | |
8719 | if (p[2] == 't') | |
8720 | { | |
8721 | /* Also a typedef with the same name. */ | |
8722 | - add_psymbol_to_list (namestring, p - namestring, | |
8723 | + add_psymbol_to_list (sym_name, sym_len, | |
8724 | VAR_DOMAIN, LOC_TYPEDEF, | |
8725 | &objfile->static_psymbols, | |
8726 | nlist.n_value, 0, | |
8727 | @@ -1749,7 +1773,7 @@ pos %d"), | |
8728 | case 't': | |
8729 | if (p != namestring) /* a name is there, not just :T... */ | |
8730 | { | |
8731 | - add_psymbol_to_list (namestring, p - namestring, | |
8732 | + add_psymbol_to_list (sym_name, sym_len, | |
8733 | VAR_DOMAIN, LOC_TYPEDEF, | |
8734 | &objfile->static_psymbols, | |
8735 | nlist.n_value, 0, | |
8736 | @@ -1829,7 +1853,7 @@ pos %d"), | |
8737 | ||
8738 | case 'c': | |
8739 | /* Constant, e.g. from "const" in Pascal. */ | |
8740 | - add_psymbol_to_list (namestring, p - namestring, | |
8741 | + add_psymbol_to_list (sym_name, sym_len, | |
8742 | VAR_DOMAIN, LOC_CONST, | |
8743 | &objfile->static_psymbols, nlist.n_value, | |
8744 | 0, psymtab_language, objfile); | |
8745 | @@ -1893,7 +1917,7 @@ pos %d"), | |
8746 | pst->textlow = nlist.n_value; | |
8747 | textlow_not_set = 0; | |
8748 | } | |
8749 | - add_psymbol_to_list (namestring, p - namestring, | |
8750 | + add_psymbol_to_list (sym_name, sym_len, | |
8751 | VAR_DOMAIN, LOC_BLOCK, | |
8752 | &objfile->static_psymbols, | |
8753 | 0, nlist.n_value, | |
8754 | @@ -1961,7 +1985,7 @@ pos %d"), | |
8755 | pst->textlow = nlist.n_value; | |
8756 | textlow_not_set = 0; | |
8757 | } | |
8758 | - add_psymbol_to_list (namestring, p - namestring, | |
8759 | + add_psymbol_to_list (sym_name, sym_len, | |
8760 | VAR_DOMAIN, LOC_BLOCK, | |
8761 | &objfile->global_psymbols, | |
8762 | 0, nlist.n_value, | |
8763 | @@ -3547,6 +3571,7 @@ static struct sym_fns aout_sym_fns = | |
8764 | dbx_new_init, /* sym_new_init: init anything gbl to entire symtab */ | |
8765 | dbx_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
8766 | dbx_symfile_read, /* sym_read: read a symbol file into symtab */ | |
8767 | + NULL, /* sym_read_psymbols */ | |
8768 | dbx_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
8769 | default_symfile_offsets, /* sym_offsets: parse user's offsets to | |
8770 | internal form */ | |
8771 | diff --git a/gdb/defs.h b/gdb/defs.h | |
8772 | index 845b320..ad6e7d7 100644 | |
8773 | --- a/gdb/defs.h | |
8774 | +++ b/gdb/defs.h | |
8775 | @@ -151,6 +151,9 @@ extern int dbx_commands; | |
8776 | /* System root path, used to find libraries etc. */ | |
8777 | extern char *gdb_sysroot; | |
8778 | ||
8779 | +/* GDB datadir, used to store data files. */ | |
8780 | +extern char *gdb_datadir; | |
8781 | + | |
8782 | /* Search path for separate debug files. */ | |
8783 | extern char *debug_file_directory; | |
8784 | ||
8785 | @@ -366,6 +369,9 @@ extern struct cleanup *make_cleanup_fclose (FILE *file); | |
8786 | ||
8787 | extern struct cleanup *make_cleanup_bfd_close (bfd *abfd); | |
8788 | ||
8789 | +struct obstack; | |
8790 | +extern struct cleanup *make_cleanup_obstack_free (struct obstack *obstack); | |
8791 | + | |
8792 | extern struct cleanup *make_cleanup_restore_integer (int *variable); | |
8793 | ||
8794 | extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); | |
8795 | diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo | |
8796 | index 10e7388..d2c0f1e 100644 | |
8797 | --- a/gdb/doc/gdb.texinfo | |
8798 | +++ b/gdb/doc/gdb.texinfo | |
8799 | @@ -955,8 +955,10 @@ Connect to process ID @var{number}, as with the @code{attach} command. | |
8800 | @itemx -x @var{file} | |
8801 | @cindex @code{--command} | |
8802 | @cindex @code{-x} | |
8803 | -Execute @value{GDBN} commands from file @var{file}. @xref{Command | |
8804 | -Files,, Command files}. | |
8805 | +Execute commands from file @var{file}. If @var{file} ends in | |
8806 | +@samp{.py}, then the file is evaluated as Python code. If Python | |
8807 | +support is not enabled in this @value{GDBN}, then an error occurs. | |
8808 | +@xref{Command Files,, Command files}. | |
8809 | ||
8810 | @item -eval-command @var{command} | |
8811 | @itemx -ex @var{command} | |
8812 | @@ -1148,6 +1150,16 @@ for remote debugging. | |
8813 | Run using @var{device} for your program's standard input and output. | |
8814 | @c FIXME: kingdon thinks there is more to -tty. Investigate. | |
8815 | ||
8816 | +@item -P | |
8817 | +@cindex @code{-P} | |
8818 | +@itemx --python | |
8819 | +@cindex @code{--python} | |
8820 | +Change interpretation of command line so that the argument immediately | |
8821 | +following this switch is taken to be the name of a Python script file. | |
8822 | +This option stops option processing; subsequent options are passed to | |
8823 | +Python as @code{sys.argv}. This option is only available if Python | |
8824 | +scripting support was enabled when @value{GDBN} was configured. | |
8825 | + | |
8826 | @c resolve the situation of these eventually | |
8827 | @item -tui | |
8828 | @cindex @code{--tui} | |
8829 | @@ -3636,6 +3648,98 @@ A failed Ada assertion. | |
8830 | A call to @code{exec}. This is currently only available for HP-UX | |
8831 | and @sc{gnu}/Linux. | |
8832 | ||
8833 | +@item syscall | |
8834 | +@itemx syscall @r{[}@var{name} @r{|} @var{number}@r{]} @r{...} | |
8835 | +@cindex break on a system call. | |
8836 | +A call to or return from a @code{syscall}. If no argument is specified, | |
8837 | +then it catches a call to or return from any system call. | |
8838 | + | |
8839 | +@var{name} can be any valid system call name in the system. You can | |
8840 | +use the @value{GDBN} command-line completion facilities to list the | |
8841 | +available choices. @xref{Completion,, Command Completion}, for | |
8842 | +details on how to do this. | |
8843 | + | |
8844 | +You may also specify the system call numerically. This may be useful | |
8845 | +if @value{GDBN} does not fully support your system's list of system | |
8846 | +calls. | |
8847 | + | |
8848 | +The example below illustrates how this command works if you don't provide | |
8849 | +arguments to it: | |
8850 | + | |
8851 | +@smallexample | |
8852 | +(@value{GDBP}) catch syscall | |
8853 | +Catchpoint 1 (syscall) | |
8854 | +(@value{GDBP}) r | |
8855 | +Starting program: /tmp/catch-syscall | |
8856 | + | |
8857 | +Catchpoint 1 (call to syscall 'close'), 0xffffe424 in __kernel_vsyscall () | |
8858 | +(@value{GDBP}) c | |
8859 | +Continuing. | |
8860 | + | |
8861 | +Catchpoint 1 (returned from syscall 'close'), 0xffffe424 in __kernel_vsyscall () | |
8862 | +(@value{GDBP}) | |
8863 | +@end smallexample | |
8864 | + | |
8865 | +Here is an example of catching a system call by name: | |
8866 | + | |
8867 | +@smallexample | |
8868 | +(@value{GDBP}) catch syscall chroot | |
8869 | +Catchpoint 1 (syscall(s) 'chroot') | |
8870 | +(@value{GDBP}) r | |
8871 | +Starting program: /tmp/catch-syscall | |
8872 | + | |
8873 | +Catchpoint 1 (call to syscall 'chroot'), 0xffffe424 in __kernel_vsyscall () | |
8874 | +(@value{GDBP}) c | |
8875 | +Continuing. | |
8876 | + | |
8877 | +Catchpoint 1 (returned from syscall 'chroot'), 0xffffe424 in __kernel_vsyscall () | |
8878 | +(@value{GDBP}) | |
8879 | +@end smallexample | |
8880 | + | |
8881 | +And last but not least, an example of specifying a system call | |
8882 | +numerically: | |
8883 | + | |
8884 | +@smallexample | |
8885 | +(@value{GDBP}) catch syscall 252 | |
8886 | +Catchpoint 1 (syscall(s) 'exit_group') | |
8887 | +(@value{GDBP}) r | |
8888 | +Starting program: /tmp/catch-syscall | |
8889 | + | |
8890 | +Catchpoint 1 (call to syscall 'exit_group'), 0xffffe424 in __kernel_vsyscall () | |
8891 | +(@value{GDBP}) c | |
8892 | +Continuing. | |
8893 | + | |
8894 | +Program exited normally. | |
8895 | +(@value{GDBP}) | |
8896 | +@end smallexample | |
8897 | + | |
8898 | +If you configure @value{GDBN} using the @samp{--without-expat} option, | |
8899 | +it will not be able to display syscall names. Also, if your | |
8900 | +architecture does not have an XML file describing its system calls, | |
8901 | +you will not be able to see the syscall names. In either case, you | |
8902 | +will see a warning like this: | |
8903 | + | |
8904 | +@smallexample | |
8905 | +(@value{GDBP}) catch syscall | |
8906 | +warning: Could not open "syscalls/i386-linux.xml" | |
8907 | +warning: Could not load the syscall XML file 'syscalls/i386-linux.xml'. | |
8908 | +GDB will not be able to display syscall names. | |
8909 | +Catchpoint 1 (syscall) | |
8910 | +(@value{GDBP}) | |
8911 | +@end smallexample | |
8912 | + | |
8913 | +Of course, the file name will change depending on your architecture and system. | |
8914 | + | |
8915 | +Still using the example above, you can also try to catch a syscall by its | |
8916 | +number. In this case, you would see something like: | |
8917 | + | |
8918 | +@smallexample | |
8919 | +(@value{GDBP}) catch syscall 252 | |
8920 | +Catchpoint 1 (syscall(s) 252) | |
8921 | +@end smallexample | |
8922 | + | |
8923 | +Again, in this case @value{GDBN} would not be able to display syscall's names. | |
8924 | + | |
8925 | @item fork | |
8926 | A call to @code{fork}. This is currently only available for HP-UX | |
8927 | and @sc{gnu}/Linux. | |
8928 | @@ -4711,6 +4815,24 @@ the program to report that some thread has stopped before prompting for | |
8929 | another command. In background execution, @value{GDBN} immediately gives | |
8930 | a command prompt so that you can issue other commands while your program runs. | |
8931 | ||
8932 | +You need to explicitly enable asynchronous mode before you can use | |
8933 | +background execution commands. You can use these commands to | |
8934 | +manipulate the asynchronous mode setting: | |
8935 | + | |
8936 | +@table @code | |
8937 | +@kindex set target-async | |
8938 | +@item set target-async on | |
8939 | +Enable asynchronous mode. | |
8940 | +@item set target-async off | |
8941 | +Disable asynchronous mode. | |
8942 | +@kindex show target-async | |
8943 | +@item show target-async | |
8944 | +Show the current target-async setting. | |
8945 | +@end table | |
8946 | + | |
8947 | +If the target doesn't support async mode, @value{GDBN} issues an error | |
8948 | +message if you attempt to use the background execution commands. | |
8949 | + | |
8950 | To specify background execution, add a @code{&} to the command. For example, | |
8951 | the background form of the @code{continue} command is @code{continue&}, or | |
8952 | just @code{c&}. The execution commands that accept background execution | |
8953 | @@ -4776,11 +4898,6 @@ only the current thread. To stop the whole program in non-stop mode, | |
8954 | use @code{interrupt -a}. | |
8955 | @end table | |
8956 | ||
8957 | -You may need to explicitly enable async mode before you can use background | |
8958 | -execution commands, with the @code{set target-async 1} command. If the | |
8959 | -target doesn't support async mode, @value{GDBN} issues an error message | |
8960 | -if you attempt to use the background execution commands. | |
8961 | - | |
8962 | @node Thread-Specific Breakpoints | |
8963 | @subsection Thread-Specific Breakpoints | |
8964 | ||
8965 | @@ -6536,6 +6653,12 @@ Without this format, @value{GDBN} displays pointers to and arrays of | |
8966 | @code{char}, @w{@code{unsigned char}}, and @w{@code{signed char}} as | |
8967 | strings. Single-byte members of a vector are displayed as an integer | |
8968 | array. | |
8969 | + | |
8970 | +@item r | |
8971 | +@cindex raw printing | |
8972 | +Print using the @samp{raw} formatting. By default, @value{GDBN} will | |
8973 | +use a type-specific pretty-printer. The @samp{r} format bypasses any | |
8974 | +pretty-printer which might exist for the value's type. | |
8975 | @end table | |
8976 | ||
8977 | For example, to print the program counter in hex (@pxref{Registers}), type | |
8978 | @@ -7408,6 +7531,20 @@ On HP-UX systems, if you refer to a function or variable name that | |
8979 | begins with a dollar sign, @value{GDBN} searches for a user or system | |
8980 | name first, before it searches for a convenience variable. | |
8981 | ||
8982 | +@cindex convenience functions | |
8983 | +@value{GDBN} also supplies some @dfn{convenience functions}. These | |
8984 | +have a syntax similar to convenience variables. A convenience | |
8985 | +function can be used in an expression just like an ordinary function; | |
8986 | +however, a convenience function is implemented internally to | |
8987 | +@value{GDBN}. | |
8988 | + | |
8989 | +@table @code | |
8990 | +@item help function | |
8991 | +@kindex help function | |
8992 | +@cindex show all convenience functions | |
8993 | +Print a list of all convenience functions. | |
8994 | +@end table | |
8995 | + | |
8996 | @node Registers | |
8997 | @section Registers | |
8998 | ||
8999 | @@ -7931,13 +8068,17 @@ support: | |
9000 | @table @code | |
9001 | @item set target-charset @var{charset} | |
9002 | @kindex set target-charset | |
9003 | -Set the current target character set to @var{charset}. We list the | |
9004 | -character set names @value{GDBN} recognizes below, but if you type | |
9005 | -@code{set target-charset} followed by @key{TAB}@key{TAB}, @value{GDBN} will | |
9006 | -list the target character sets it supports. | |
9007 | -@end table | |
9008 | +Set the current target character set to @var{charset}. If you type | |
9009 | +@code{set target-charset} followed by @key{TAB}@key{TAB}, @value{GDBN} | |
9010 | +will list the target character sets it supports. | |
9011 | + | |
9012 | +@item set target-wide-charset @var{charset} | |
9013 | +@kindex set target-wide-charset | |
9014 | +Set the current target wide character set to @var{charset}. The | |
9015 | +target wide character set is the character set used by @code{wchar_t}. | |
9016 | +If you type @code{set target-charset} followed by @key{TAB}@key{TAB}, | |
9017 | +@value{GDBN} will list the target character sets it supports. | |
9018 | ||
9019 | -@table @code | |
9020 | @item set host-charset @var{charset} | |
9021 | @kindex set host-charset | |
9022 | Set the current host character set to @var{charset}. | |
9023 | @@ -7947,10 +8088,9 @@ system it is running on; you can override that default using the | |
9024 | @code{set host-charset} command. | |
9025 | ||
9026 | @value{GDBN} can only use certain character sets as its host character | |
9027 | -set. We list the character set names @value{GDBN} recognizes below, and | |
9028 | -indicate which can be host character sets, but if you type | |
9029 | -@code{set target-charset} followed by @key{TAB}@key{TAB}, @value{GDBN} will | |
9030 | -list the host character sets it supports. | |
9031 | +set. If you type @code{set target-charset} followed by | |
9032 | +@key{TAB}@key{TAB}, @value{GDBN} will list the host character sets it | |
9033 | +supports. | |
9034 | ||
9035 | @item set charset @var{charset} | |
9036 | @kindex set charset | |
9037 | @@ -7974,37 +8114,6 @@ Show the name of the current target charset. | |
9038 | ||
9039 | @end table | |
9040 | ||
9041 | -@value{GDBN} currently includes support for the following character | |
9042 | -sets: | |
9043 | - | |
9044 | -@table @code | |
9045 | - | |
9046 | -@item ASCII | |
9047 | -@cindex ASCII character set | |
9048 | -Seven-bit U.S. @sc{ascii}. @value{GDBN} can use this as its host | |
9049 | -character set. | |
9050 | - | |
9051 | -@item ISO-8859-1 | |
9052 | -@cindex ISO 8859-1 character set | |
9053 | -@cindex ISO Latin 1 character set | |
9054 | -The ISO Latin 1 character set. This extends @sc{ascii} with accented | |
9055 | -characters needed for French, German, and Spanish. @value{GDBN} can use | |
9056 | -this as its host character set. | |
9057 | - | |
9058 | -@item EBCDIC-US | |
9059 | -@itemx IBM1047 | |
9060 | -@cindex EBCDIC character set | |
9061 | -@cindex IBM1047 character set | |
9062 | -Variants of the @sc{ebcdic} character set, used on some of IBM's | |
9063 | -mainframe operating systems. (@sc{gnu}/Linux on the S/390 uses U.S. @sc{ascii}.) | |
9064 | -@value{GDBN} cannot use these as its host character set. | |
9065 | - | |
9066 | -@end table | |
9067 | - | |
9068 | -Note that these are all single-byte character sets. More work inside | |
9069 | -@value{GDBN} is needed to support multi-byte or variable-width character | |
9070 | -encodings, like the UTF-8 and UCS-2 encodings of Unicode. | |
9071 | - | |
9072 | Here is an example of @value{GDBN}'s character set support in action. | |
9073 | Assume that the following source code has been placed in the file | |
9074 | @file{charset-test.c}: | |
9075 | @@ -12510,6 +12619,12 @@ It is possible for the function you call via the @code{print} or | |
9076 | the function, or if you passed it incorrect arguments). What happens | |
9077 | in that case is controlled by the @code{set unwindonsignal} command. | |
9078 | ||
9079 | +Similarly, with a C++ program it is possible for the function you | |
9080 | +call via the @code{print} or @code{call} command to generate an | |
9081 | +exception that is not handled due to the constraints of the dummy | |
9082 | +frame. What happens in that case is controlled by the | |
9083 | +@code{set unwind-on-terminating-exception} command. | |
9084 | + | |
9085 | @table @code | |
9086 | @item set unwindonsignal | |
9087 | @kindex set unwindonsignal | |
9088 | @@ -12526,6 +12641,23 @@ received. | |
9089 | @kindex show unwindonsignal | |
9090 | Show the current setting of stack unwinding in the functions called by | |
9091 | @value{GDBN}. | |
9092 | + | |
9093 | +@item set unwind-on-terminating-exception | |
9094 | +@kindex set unwind-on-terminating-exception | |
9095 | +@cindex unwind stack in called functions | |
9096 | +@cindex call dummy stack unwinding on unhandled exception. | |
9097 | +Set unwinding of the stack if a C++ exception is raised but unhandled | |
9098 | +while in a function that @value{GDBN} called in the program being | |
9099 | +debugged. If set to on (the default), @value{GDBN} unwinds the stack | |
9100 | +it created for the call and restores the context to what it was before | |
9101 | +the call. If set to off, @value{GDBN} the exception is delivered to | |
9102 | +the default C++ exception handler. | |
9103 | + | |
9104 | +@item show unwind-on-terminating-exception | |
9105 | +@kindex show unwind-on-terminating-exception | |
9106 | +Show the current setting of stack unwinding in the functions called by | |
9107 | +@value{GDBN}. | |
9108 | + | |
9109 | @end table | |
9110 | ||
9111 | @cindex weak alias functions | |
9112 | @@ -17815,7 +17947,7 @@ command: | |
9113 | @table @code | |
9114 | @kindex source | |
9115 | @cindex execute commands from a file | |
9116 | -@item source [@code{-v}] @var{filename} | |
9117 | +@item source [@code{-v}] [@code{-p}] @var{filename} | |
9118 | Execute the command file @var{filename}. | |
9119 | @end table | |
9120 | ||
9121 | @@ -17832,6 +17964,11 @@ If @code{-v}, for verbose mode, is given then @value{GDBN} displays | |
9122 | each command as it is executed. The option must be given before | |
9123 | @var{filename}, and is interpreted as part of the filename anywhere else. | |
9124 | ||
9125 | +If @var{filename} ends in @samp{.py}, or if @code{-p}, for Python, is | |
9126 | +given then @value{GDBN} evaluates the contents of the file as Python | |
9127 | +code. If Python support is not compiled in to @value{GDBN}, then an | |
9128 | +error occurs. | |
9129 | + | |
9130 | Commands that would ask for confirmation if used interactively proceed | |
9131 | without asking when used in a command file. Many @value{GDBN} commands that | |
9132 | normally print messages to say what they are doing omit the messages | |
9133 | @@ -18093,8 +18230,6 @@ containing @code{end}. For example: | |
9134 | ||
9135 | @smallexample | |
9136 | (@value{GDBP}) python | |
9137 | -Type python script | |
9138 | -End with a line saying just "end". | |
9139 | >print 23 | |
9140 | >end | |
9141 | 23 | |
9142 | @@ -18107,6 +18242,14 @@ in a Python script. This can be controlled using @code{maint set | |
9143 | python print-stack}: if @code{on}, the default, then Python stack | |
9144 | printing is enabled; if @code{off}, then Python stack printing is | |
9145 | disabled. | |
9146 | + | |
9147 | +@kindex maint set python auto-load | |
9148 | +@item maint set python auto-load | |
9149 | +By default, @value{GDBN} will attempt to automatically load Python | |
9150 | +code when an object file is opened. This can be controlled using | |
9151 | +@code{maint set python auto-load}: if @code{on}, the default, then | |
9152 | +Python auto-loading is enabled; if @code{off}, then Python | |
9153 | +auto-loading is disabled. | |
9154 | @end table | |
9155 | ||
9156 | @node Python API | |
9157 | @@ -18114,6 +18257,14 @@ disabled. | |
9158 | @cindex python api | |
9159 | @cindex programming in python | |
9160 | ||
9161 | +You can get quick online help for @value{GDBN}'s Python API by issuing | |
9162 | +the command @w{@kbd{python help (gdb)}}. | |
9163 | + | |
9164 | +Functions and methods which have two or more optional arguments allow | |
9165 | +them to be specified using keyword syntax. This allows passing some | |
9166 | +optional arguments while skipping others. Example: | |
9167 | +@w{@code{gdb.some_function ('foo', bar = 1, baz = 2)}}. | |
9168 | + | |
9169 | @cindex python stdout | |
9170 | @cindex python pagination | |
9171 | At startup, @value{GDBN} overrides Python's @code{sys.stdout} and | |
9172 | @@ -18125,8 +18276,17 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown. | |
9173 | @menu | |
9174 | * Basic Python:: Basic Python Functions. | |
9175 | * Exception Handling:: | |
9176 | -* Values From Inferior:: | |
9177 | +* Auto-loading:: Automatically loading Python code. | |
9178 | +* Values From Inferior:: Python representation of values. | |
9179 | +* Types From Inferior:: Python representation of types. | |
9180 | +* Pretty Printing:: Pretty-printing values. | |
9181 | +* Threads In Python:: Accessing inferior threads from Python. | |
9182 | * Commands In Python:: Implementing new commands in Python. | |
9183 | +* Parameters In Python:: Adding new @value{GDBN} parameters. | |
9184 | +* Functions In Python:: Writing new convenience functions. | |
9185 | +* Objfiles In Python:: Object files. | |
9186 | +* Breakpoints In Python:: Manipulating breakpoints using Python. | |
9187 | +* Frames In Python:: Acessing inferior stack frames from Python. | |
9188 | @end menu | |
9189 | ||
9190 | @node Basic Python | |
9191 | @@ -18152,10 +18312,30 @@ command as having originated from the user invoking it interactively. | |
9192 | It must be a boolean value. If omitted, it defaults to @code{False}. | |
9193 | @end defun | |
9194 | ||
9195 | -@findex gdb.get_parameter | |
9196 | -@defun get_parameter parameter | |
9197 | -Return the value of a @value{GDBN} parameter. @var{parameter} is a | |
9198 | -string naming the parameter to look up; @var{parameter} may contain | |
9199 | +@findex gdb.current_objfile | |
9200 | +@defun current_objfile | |
9201 | +When auto-loading a Python script (@pxref{Auto-loading}), @value{GDBN} | |
9202 | +sets the ``current objfile'' to the corresponding objfile. This | |
9203 | +function returns the current objfile. If there is no current objfile, | |
9204 | +this function returns @code{None}. | |
9205 | +@end defun | |
9206 | + | |
9207 | +@findex gdb.breakpoints | |
9208 | +@defun breakpoints | |
9209 | +Return a sequence holding all of @value{GDBN}'s breakpoints. | |
9210 | +@xref{Breakpoints In Python}, for more information. | |
9211 | +@end defun | |
9212 | + | |
9213 | +@findex gdb.objfiles | |
9214 | +@defun objfiles | |
9215 | +Return a sequence of all the objfiles current known to @value{GDBN}. | |
9216 | +@xref{Objfiles In Python}. | |
9217 | +@end defun | |
9218 | + | |
9219 | +@findex gdb.parameter | |
9220 | +@defun parameter name | |
9221 | +Return the value of the named @value{GDBN} parameter. @var{name} is a | |
9222 | +string naming the parameter to look up; @var{name} may contain | |
9223 | spaces if the parameter has a multi-part name. For example, | |
9224 | @samp{print object} is a valid parameter name. | |
9225 | ||
9226 | @@ -18179,6 +18359,28 @@ If no exception is raised, the return value is always an instance of | |
9227 | @code{gdb.Value} (@pxref{Values From Inferior}). | |
9228 | @end defun | |
9229 | ||
9230 | +@findex gdb.parse_and_eval | |
9231 | +@defun parse_and_eval expression | |
9232 | +Parse @var{expression} as an expression in the current language, | |
9233 | +evaluate it, and return the result as a @code{gdb.Value}. | |
9234 | +@var{expression} must be a string. | |
9235 | +@end defun | |
9236 | + | |
9237 | +@findex gdb.post_event | |
9238 | +@defun post_event event | |
9239 | +Put @var{event}, a callable object taking no arguments, into | |
9240 | +@value{GDBN}'s internal event queue. This callable will be invoked at | |
9241 | +some later point, during @value{GDBN}'s event processing. Events | |
9242 | +posted using @code{post_event} will be run in the order in which they | |
9243 | +were posted; however, there is no way to know when they will be | |
9244 | +processed relative to other events inside @value{GDBN}. | |
9245 | + | |
9246 | +@value{GDBN} is not thread-safe. If your Python program uses multiple | |
9247 | +threads, you must be careful to only call @value{GDBN}-specific | |
9248 | +functions in the main @value{GDBN} thread. @code{post_event} ensures | |
9249 | +this. | |
9250 | +@end defun | |
9251 | + | |
9252 | @findex gdb.write | |
9253 | @defun write string | |
9254 | Print a string to @value{GDBN}'s paginated standard output stream. | |
9255 | @@ -18193,6 +18395,66 @@ Flush @value{GDBN}'s paginated standard output stream. Flushing | |
9256 | function. | |
9257 | @end defun | |
9258 | ||
9259 | +@findex gdb.frames | |
9260 | +@defun frames | |
9261 | +Return a tuple of all frame objects. | |
9262 | +@end defun | |
9263 | + | |
9264 | +@findex gdb.newest_frame | |
9265 | +@defun newest_frame | |
9266 | +Return the newest frame object. | |
9267 | +@end defun | |
9268 | + | |
9269 | +@findex gdb.selected_frame | |
9270 | +@defun selected_frame | |
9271 | +Return the selected frame object. | |
9272 | +@end defun | |
9273 | + | |
9274 | +@findex gdb.frame_stop_reason_string | |
9275 | +@defun frame_stop_reason_string @var{reason} | |
9276 | +Return a string explaining the reason why @value{GDBN} stopped unwinding | |
9277 | +frames, as expressed by the given @var{reason} code (an integer, see the | |
9278 | +@code{unwind_stop_reason} method in | |
9279 | +@xref{Frames In Python,,Accessing inferior stack frames from Python}.) | |
9280 | +@end defun | |
9281 | + | |
9282 | +@findex gdb.read_memory | |
9283 | +@defun read_memory @var{address} @var{length} | |
9284 | +Read @var{length} bytes of memory from the inferior, starting at @var{address}. | |
9285 | +Returns a buffer object, which behaves much like an array or a string. It | |
9286 | +can be modified and given to the @code{gdb.write_memory} function. | |
9287 | +@end defun | |
9288 | + | |
9289 | +@findex gdb.write_memory | |
9290 | +@defun write_memory @var{address} @var{buffer} @r{[}@var{length}@r{]} | |
9291 | +Write the contents of @var{buffer} (a Python object which supports the buffer | |
9292 | +protocol, i.e., a string, an array or the object returned from | |
9293 | +@code{gdb.read_memory}) to the inferior, starting at @var{address}. If given, | |
9294 | +@var{length} determines the number of bytes from @var{buffer} to be written. | |
9295 | +@end defun | |
9296 | + | |
9297 | +@findex gdb.search_memory | |
9298 | +@defun search_memory @var{address} @var{length} @var{pattern} @r{[}@var{size}@r{]} @r{[}@var{max_count}@r{]} | |
9299 | +Search a region of the inferior memory starting at @var{address} with the given | |
9300 | +@var{length}. @var{pattern} can be a string, a byte array, a buffer object, | |
9301 | +a number, a @code{gdb.Value} object (@pxref{Values From Inferior}) or a list | |
9302 | +or tuple with elements in any combination of those types. If @var{size} is | |
9303 | +given and is non-zero, it specifies the size in bytes of a Python scalar or | |
9304 | +@code{gdb.Value} in the search pattern. If @var{size} is zero or not specified, | |
9305 | + it is taken from the value's type in the current language. | |
9306 | +This is useful when one wants to specify the search | |
9307 | +pattern as a mixture of types. | |
9308 | +Note that this means, for example, that in the case of C-like languages | |
9309 | +a search for an untyped 0x42 will search for @samp{(int) 0x42} | |
9310 | +which is typically four bytes. @var{max_count} is the highest number of matches | |
9311 | +to search for. | |
9312 | +@end defun | |
9313 | + | |
9314 | +@findex gdb.solib_address | |
9315 | +@defun solib_address @var{address} | |
9316 | +Return the name of the shared library holding the given address, or None. | |
9317 | +@end defun | |
9318 | + | |
9319 | @node Exception Handling | |
9320 | @subsubsection Exception Handling | |
9321 | @cindex python exceptions | |
9322 | @@ -18224,6 +18486,44 @@ message as its value, and the Python call stack backtrace at the | |
9323 | Python statement closest to where the @value{GDBN} error occured as the | |
9324 | traceback. | |
9325 | ||
9326 | +@node Auto-loading | |
9327 | +@subsubsection Auto-loading | |
9328 | + | |
9329 | +When a new object file (@pxref{Objfiles In Python}) is read (for | |
9330 | +example, due to the @code{file} command, or because the inferior has | |
9331 | +loaded a shared library), @value{GDBN} will look for a file named by | |
9332 | +adding @samp{-gdb.py} to the object file's real name (the name formed | |
9333 | +after following all symlinks and resolving @code{.} and @code{..} | |
9334 | +components). If this file exists and is readable, @value{GDBN} will | |
9335 | +evaluate it as a Python script. | |
9336 | + | |
9337 | +If this file does not exist, and if the parameter | |
9338 | +@code{debug-file-directory} is set, then @value{GDBN} will append the | |
9339 | +object file's real name to the value of this parameter, and try again. | |
9340 | + | |
9341 | +Finally, if this file does not exist, then @value{GDBN} will look in | |
9342 | +subdirectory of @code{gdb_datadir} (whose value is available from | |
9343 | +@code{maint show gdb_datadir}). Specifically, @value{GDBN} will take | |
9344 | +the value of @code{gdb_datadir}, append @samp{python/auto-load}, and | |
9345 | +then append the object file's real name. | |
9346 | + | |
9347 | +Also, if a separate debug file is used, @value{GDBN} will look for the | |
9348 | +@samp{-gdb.py} file both in the directory associated with the | |
9349 | +application and the directory associated with the separate debug file. | |
9350 | + | |
9351 | +When reading a @samp{-gdb.py} file, @value{GDBN} sets the ``current | |
9352 | +objfile''. This is available via the @code{gdb.current_objfile} | |
9353 | +function. This can be useful for registering objfile-specific | |
9354 | +pretty-printers. | |
9355 | + | |
9356 | +This feature is useful for supplying application-specific debugging | |
9357 | +commands and scripts. It can be disabled using @code{maint set python | |
9358 | +auto-load}. | |
9359 | + | |
9360 | +@value{GDBN} does not track which files it has already auto-loaded. | |
9361 | +So, your @samp{-gdb.py} file should take care to ensure that it may be | |
9362 | +evaluated multiple times without error. | |
9363 | + | |
9364 | @node Values From Inferior | |
9365 | @subsubsection Values From Inferior | |
9366 | @cindex values from inferior, with Python | |
9367 | @@ -18258,8 +18558,21 @@ bar = some_val['foo'] | |
9368 | ||
9369 | Again, @code{bar} will also be a @code{gdb.Value} object. | |
9370 | ||
9371 | -For pointer data types, @code{gdb.Value} provides a method for | |
9372 | -dereferencing the pointer to obtain the object it points to. | |
9373 | +The following methods are provided: | |
9374 | + | |
9375 | +@table @code | |
9376 | +@defmethod Value address | |
9377 | +If the @code{gdb.Value} object is addressable, this will return a new | |
9378 | +@code{gdb.Value} object representing the address. Otherwise, this | |
9379 | +will throw an exception. | |
9380 | +@end defmethod | |
9381 | + | |
9382 | +@defmethod Value cast type | |
9383 | +Cast the @code{gdb.Value} to the type represented by @var{type}, and | |
9384 | +return a new @code{gdb.Value}. @var{type} must be a @code{gdb.Type} | |
9385 | +object. If the cast cannot be performed for some reason, an exception | |
9386 | +is thrown. | |
9387 | +@end defmethod | |
9388 | ||
9389 | @defmethod Value dereference | |
9390 | This method returns a new @code{gdb.Value} object whose contents is | |
9391 | @@ -18282,7 +18595,7 @@ The result @code{bar} will be a @code{gdb.Value} object holding the | |
9392 | value pointed to by @code{foo}. | |
9393 | @end defmethod | |
9394 | ||
9395 | -@defmethod Value string @r{[}encoding @r{[}errors@r{]}@r{]} | |
9396 | +@defmethod Value string @r{[}encoding@r{]} @r{[}errors@r{]} | |
9397 | If this @code{gdb.Value} represents a string, then this method | |
9398 | converts the contents to a Python string. Otherwise, this method will | |
9399 | throw an exception. | |
9400 | @@ -18309,6 +18622,468 @@ The optional @var{errors} argument is the same as the corresponding | |
9401 | argument to Python's @code{string.decode} method. | |
9402 | @end defmethod | |
9403 | ||
9404 | +@defmethod Value type | |
9405 | +Return the type of this @code{gdb.Value}. The result is a | |
9406 | +@code{gdb.Type} object. | |
9407 | +@end defmethod | |
9408 | +@end table | |
9409 | + | |
9410 | +@node Types From Inferior | |
9411 | +@subsubsection Types From Inferior | |
9412 | + | |
9413 | +@cindex gdb.Type | |
9414 | +@value{GDBN} represents types from the inferior using the class | |
9415 | +@code{gdb.Type}. | |
9416 | + | |
9417 | +The following methods are provided: | |
9418 | + | |
9419 | +@table @code | |
9420 | +@defmethod Type Type [name [block]] | |
9421 | +Construct a new instance of @code{gdb.Type}. | |
9422 | + | |
9423 | +If @var{name} is given, it specifies the name of a type to look up in | |
9424 | +the inferior. | |
9425 | + | |
9426 | +If @var{block} is given, then @var{name} is looked up in that scope. | |
9427 | +Otherwise, it is searched for globally. | |
9428 | +@end defmethod | |
9429 | + | |
9430 | +@defmethod Type code | |
9431 | +Return the type code for this type. The type code will be one of the | |
9432 | +@code{TYPE_CODE_} constants defined below. | |
9433 | +@end defmethod | |
9434 | + | |
9435 | +@defmethod Type fields | |
9436 | +For structure and union types, this method returns the fields. Range | |
9437 | +types have two fields, the minimum and maximum values. Enum types | |
9438 | +have one field per enum constant. Function and method types have one | |
9439 | +field per parameter. The base types of C++ classes are also | |
9440 | +represented as fields. If the type has no fields, or does not fit | |
9441 | +into one of these categories, an empty sequence will be returned. | |
9442 | + | |
9443 | +Each field is an object, with some pre-defined attributes: | |
9444 | +@table @code | |
9445 | +@item bitpos | |
9446 | +This attribute is not available for @code{static} fields. For | |
9447 | +non-@code{static} fields, the value is the bit position of the field. | |
9448 | + | |
9449 | +@item name | |
9450 | +The name of the field, or @code{None} for anonymous fields. | |
9451 | + | |
9452 | +@item artificial | |
9453 | +This is @code{True} if the field is artificial, usually meaning that | |
9454 | +it was provided by the compiler and not the user. This attribute is | |
9455 | +always provided, and is @code{False} if the field is not artificial. | |
9456 | + | |
9457 | +@item bitsize | |
9458 | +If the field is packed, or is a bitfield, then this will have a | |
9459 | +non-zero value, which is the size of the field in bits. Otherwise, | |
9460 | +this will be zero; in this case the field's size is given by its type. | |
9461 | + | |
9462 | +@item type | |
9463 | +The type of the field. | |
9464 | +@end table | |
9465 | +@end defmethod | |
9466 | + | |
9467 | +@defmethod Type const | |
9468 | +Return a new @code{gdb.Type} object which represents a | |
9469 | +@code{const}-qualified variant of this type. | |
9470 | +@end defmethod | |
9471 | + | |
9472 | +@defmethod Type volatile | |
9473 | +Return a new @code{gdb.Type} object which represents a | |
9474 | +@code{volatile}-qualified variant of this type. | |
9475 | +@end defmethod | |
9476 | + | |
9477 | +@defmethod Type unqualified | |
9478 | +Return a new @code{gdb.Type} object which represents an unqualified | |
9479 | +variant of this type. That is, the result is neither @code{const} nor | |
9480 | +@code{volatile}. | |
9481 | +@end defmethod | |
9482 | + | |
9483 | +@defmethod Type reference | |
9484 | +Return a new @code{gdb.Type} object which represents a reference to this | |
9485 | +type. | |
9486 | +@end defmethod | |
9487 | + | |
9488 | +@defmethod Type sizeof | |
9489 | +Return the size of this type, in target @code{char} units. Usually, a | |
9490 | +target's @code{char} type will be an 8-bit byte. However, on some | |
9491 | +unusual platforms, this type may have a different size. | |
9492 | +@end defmethod | |
9493 | + | |
9494 | +@defmethod Type strip_typedefs | |
9495 | +Return a new @code{gdb.Type} that represents the real type, | |
9496 | +after removing all layers of typedefs. | |
9497 | +@end defmethod | |
9498 | + | |
9499 | +@defmethod Type tag | |
9500 | +Return the tag name for this type. The tag name is the name after | |
9501 | +@code{struct}, @code{union}, or @code{enum} in C; not all languages | |
9502 | +have this concept. If this type has no tag name, then @code{None} is | |
9503 | +returned. | |
9504 | +@end defmethod | |
9505 | + | |
9506 | +@defmethod Type target | |
9507 | +Return a new @code{gdb.Type} object which represents the target type | |
9508 | +of this type. | |
9509 | + | |
9510 | +For a pointer type, the target type is the type of the pointed-to | |
9511 | +object. For an array type, the target type is the type of the | |
9512 | +elements of the array. For a function type, the target type is the | |
9513 | +type of the return value. For a complex type, the target type is the | |
9514 | +type of the elements. For a typedef, the target type is the aliased | |
9515 | +type. | |
9516 | +@end defmethod | |
9517 | + | |
9518 | +@defmethod Type template_argument n [block] | |
9519 | +If this @code{gdb.Type} is a template type, this will return a new | |
9520 | +@code{gdb.Type} which represents the type of the @var{n}th template | |
9521 | +argument. | |
9522 | + | |
9523 | +If this @code{gdb.Type} is not a template type, this will throw an | |
9524 | +exception. | |
9525 | + | |
9526 | +If @var{block} is given, then @var{name} is looked up in that scope. | |
9527 | +Otherwise, it is searched for globally. | |
9528 | +@end defmethod | |
9529 | +@end table | |
9530 | + | |
9531 | + | |
9532 | +Each type has a code, which indicates what category this type falls | |
9533 | +into. The available type categories are represented by constants | |
9534 | +defined in the @code{gdb} module: | |
9535 | + | |
9536 | +@table @code | |
9537 | +@findex TYPE_CODE_PTR | |
9538 | +@findex gdb.TYPE_CODE_PTR | |
9539 | +@item TYPE_CODE_PTR | |
9540 | +The type is a pointer. | |
9541 | + | |
9542 | +@findex TYPE_CODE_ARRAY | |
9543 | +@findex gdb.TYPE_CODE_ARRAY | |
9544 | +@item TYPE_CODE_ARRAY | |
9545 | +The type is an array. | |
9546 | + | |
9547 | +@findex TYPE_CODE_STRUCT | |
9548 | +@findex gdb.TYPE_CODE_STRUCT | |
9549 | +@item TYPE_CODE_STRUCT | |
9550 | +The type is a structure. | |
9551 | + | |
9552 | +@findex TYPE_CODE_UNION | |
9553 | +@findex gdb.TYPE_CODE_UNION | |
9554 | +@item TYPE_CODE_UNION | |
9555 | +The type is a union. | |
9556 | + | |
9557 | +@findex TYPE_CODE_ENUM | |
9558 | +@findex gdb.TYPE_CODE_ENUM | |
9559 | +@item TYPE_CODE_ENUM | |
9560 | +The type is an enum. | |
9561 | + | |
9562 | +@findex TYPE_CODE_FLAGS | |
9563 | +@findex gdb.TYPE_CODE_FLAGS | |
9564 | +@item TYPE_CODE_FLAGS | |
9565 | +A bit flags type. | |
9566 | +@c FIXME: what is this? | |
9567 | + | |
9568 | +@findex TYPE_CODE_FUNC | |
9569 | +@findex gdb.TYPE_CODE_FUNC | |
9570 | +@item TYPE_CODE_FUNC | |
9571 | +The type is a function. | |
9572 | + | |
9573 | +@findex TYPE_CODE_INT | |
9574 | +@findex gdb.TYPE_CODE_INT | |
9575 | +@item TYPE_CODE_INT | |
9576 | +The type is an integer type. | |
9577 | + | |
9578 | +@findex TYPE_CODE_FLT | |
9579 | +@findex gdb.TYPE_CODE_FLT | |
9580 | +@item TYPE_CODE_FLT | |
9581 | +A floating point type. | |
9582 | + | |
9583 | +@findex TYPE_CODE_VOID | |
9584 | +@findex gdb.TYPE_CODE_VOID | |
9585 | +@item TYPE_CODE_VOID | |
9586 | +The special type @code{void}. | |
9587 | + | |
9588 | +@findex TYPE_CODE_SET | |
9589 | +@findex gdb.TYPE_CODE_SET | |
9590 | +@item TYPE_CODE_SET | |
9591 | +A Pascal set type. | |
9592 | + | |
9593 | +@findex TYPE_CODE_RANGE | |
9594 | +@findex gdb.TYPE_CODE_RANGE | |
9595 | +@item TYPE_CODE_RANGE | |
9596 | +A range type, that is, an integer type with bounds. | |
9597 | + | |
9598 | +@findex TYPE_CODE_STRING | |
9599 | +@findex gdb.TYPE_CODE_STRING | |
9600 | +@item TYPE_CODE_STRING | |
9601 | +A string type. Note that this is only used for certain languages with | |
9602 | +language-defined string types; C strings are not represented this way. | |
9603 | + | |
9604 | +@findex TYPE_CODE_BITSTRING | |
9605 | +@findex gdb.TYPE_CODE_BITSTRING | |
9606 | +@item TYPE_CODE_BITSTRING | |
9607 | +A string of bits. | |
9608 | + | |
9609 | +@findex TYPE_CODE_ERROR | |
9610 | +@findex gdb.TYPE_CODE_ERROR | |
9611 | +@item TYPE_CODE_ERROR | |
9612 | +An unknown or erroneous type. | |
9613 | + | |
9614 | +@findex TYPE_CODE_METHOD | |
9615 | +@findex gdb.TYPE_CODE_METHOD | |
9616 | +@item TYPE_CODE_METHOD | |
9617 | +A C++ method type. | |
9618 | + | |
9619 | +@findex TYPE_CODE_METHODPTR | |
9620 | +@findex gdb.TYPE_CODE_METHODPTR | |
9621 | +@item TYPE_CODE_METHODPTR | |
9622 | +A pointer-to-member-function. | |
9623 | + | |
9624 | +@findex TYPE_CODE_MEMBERPTR | |
9625 | +@findex gdb.TYPE_CODE_MEMBERPTR | |
9626 | +@item TYPE_CODE_MEMBERPTR | |
9627 | +A pointer-to-member. | |
9628 | + | |
9629 | +@findex TYPE_CODE_REF | |
9630 | +@findex gdb.TYPE_CODE_REF | |
9631 | +@item TYPE_CODE_REF | |
9632 | +A reference type. | |
9633 | + | |
9634 | +@findex TYPE_CODE_CHAR | |
9635 | +@findex gdb.TYPE_CODE_CHAR | |
9636 | +@item TYPE_CODE_CHAR | |
9637 | +A character type. | |
9638 | + | |
9639 | +@findex TYPE_CODE_BOOL | |
9640 | +@findex gdb.TYPE_CODE_BOOL | |
9641 | +@item TYPE_CODE_BOOL | |
9642 | +A boolean type. | |
9643 | + | |
9644 | +@findex TYPE_CODE_COMPLEX | |
9645 | +@findex gdb.TYPE_CODE_COMPLEX | |
9646 | +@item TYPE_CODE_COMPLEX | |
9647 | +A complex float type. | |
9648 | + | |
9649 | +@findex TYPE_CODE_TYPEDEF | |
9650 | +@findex gdb.TYPE_CODE_TYPEDEF | |
9651 | +@item TYPE_CODE_TYPEDEF | |
9652 | +A typedef to some other type. | |
9653 | + | |
9654 | +@findex TYPE_CODE_TEMPLATE | |
9655 | +@findex gdb.TYPE_CODE_TEMPLATE | |
9656 | +@item TYPE_CODE_TEMPLATE | |
9657 | +A C++ template type. Note that this is not used for a template | |
9658 | +instantiation; those appear as ordinary struct types. | |
9659 | +@c FIXME I hope that is true | |
9660 | + | |
9661 | +@findex TYPE_CODE_TEMPLATE_ARG | |
9662 | +@findex gdb.TYPE_CODE_TEMPLATE_ARG | |
9663 | +@item TYPE_CODE_TEMPLATE_ARG | |
9664 | +A C++ template argument. | |
9665 | +@c FIXME: is this ever used? | |
9666 | + | |
9667 | +@findex TYPE_CODE_NAMESPACE | |
9668 | +@findex gdb.TYPE_CODE_NAMESPACE | |
9669 | +@item TYPE_CODE_NAMESPACE | |
9670 | +A C++ namespace. | |
9671 | + | |
9672 | +@findex TYPE_CODE_DECFLOAT | |
9673 | +@findex gdb.TYPE_CODE_DECFLOAT | |
9674 | +@item TYPE_CODE_DECFLOAT | |
9675 | +A decimal floating point type. | |
9676 | + | |
9677 | +@findex TYPE_CODE_INTERNAL_FUNCTION | |
9678 | +@findex gdb.TYPE_CODE_INTERNAL_FUNCTION | |
9679 | +@item TYPE_CODE_INTERNAL_FUNCTION | |
9680 | +A function internal to @value{GDBN}. This is the type used to represent | |
9681 | +convenience functions. | |
9682 | +@end table | |
9683 | + | |
9684 | +@node Pretty Printing | |
9685 | +@subsubsection Pretty Printing | |
9686 | + | |
9687 | +@value{GDBN} provides a mechanism to allow pretty-printing of values | |
9688 | +using Python code. This mechanism works for both MI and the CLI. | |
9689 | + | |
9690 | +A pretty-printer is an object that implements a specific interface. | |
9691 | +There is no predefined base class for pretty-printers. | |
9692 | + | |
9693 | +@defop Operation {pretty printer} __init__ (self, val) | |
9694 | +When printing a value, @value{GDBN} constructs an instance of the | |
9695 | +pretty-printer. @var{val} is the value to be printed, an instance of | |
9696 | +@code{gdb.Value}. | |
9697 | +@end defop | |
9698 | + | |
9699 | +@defop Operation {pretty printer} children (self) | |
9700 | +When printing a value, @value{GDBN} will call this method to compute | |
9701 | +the children of the value passed to the object's constructor. | |
9702 | + | |
9703 | +This method must return an object conforming to the Python iterator | |
9704 | +protocol. Each element returned by the iterator must be a tuple | |
9705 | +holding two elements. The first element is the ``name'' of the child; | |
9706 | +the second element is the child's value. The value can be any Python | |
9707 | +object which is convertible to a @value{GDBN} value. | |
9708 | + | |
9709 | +This method is optional. If it does not exist, @value{GDBN} will act | |
9710 | +as though the value has no children. | |
9711 | +@end defop | |
9712 | + | |
9713 | +@defop Operation {pretty printer} display_hint (self) | |
9714 | +This method must return a string. The CLI may use this to change the | |
9715 | +formatting of children of a value. The result will also be supplied | |
9716 | +to an MI consumer as a @samp{displayhint} attribute of the variable | |
9717 | +being printed. | |
9718 | + | |
9719 | +Some display hints are predefined by @value{GDBN}: | |
9720 | + | |
9721 | +@table @samp | |
9722 | +@item array | |
9723 | +Indicate that the object being printed is ``array-like''. The CLI | |
9724 | +uses this to respect parameters such as @code{set print elements} and | |
9725 | +@code{set print array}. | |
9726 | + | |
9727 | +@item map | |
9728 | +Indicate that the object being printed is ``map-like'', and that the | |
9729 | +children of this value can be assumed to alternate between keys and | |
9730 | +values. | |
9731 | + | |
9732 | +@item string | |
9733 | +Indicate that the object being printed is ``string-like''. If the | |
9734 | +printer's @code{to_string} method returns a Python string of some | |
9735 | +kind, then @value{GDBN} will call its internal language-specific | |
9736 | +string-printing function to format the string. For the CLI this means | |
9737 | +adding quotation marks, possibly escaping some characters, respecting | |
9738 | +@code{set print elements}, and the like. | |
9739 | +@end table | |
9740 | +@end defop | |
9741 | + | |
9742 | +@defop Operation {pretty printer} to_string (self) | |
9743 | +@value{GDBN} will call this method to display the string | |
9744 | +representation of the value passed to the object's constructor. | |
9745 | + | |
9746 | +When printing from the CLI, if the @code{to_string} method exists, | |
9747 | +then @value{GDBN} will prepend its result to the values returned by | |
9748 | +@code{children}. | |
9749 | + | |
9750 | +If this method returns a string, it is printed verbatim. Otherwise, | |
9751 | +the result is converted to a @code{gdb.Value}, following the usual | |
9752 | +algorithm. Then @value{GDBN} prints this value; this may possibly | |
9753 | +result in a call to another pretty-printer. If the result is not | |
9754 | +convertible to @code{gdb.Value}, an exception is raised. | |
9755 | +@end defop | |
9756 | + | |
9757 | +@subsubsection Selecting Pretty-Printers | |
9758 | + | |
9759 | +The Python list @code{gdb.pretty_printers} contains an array of | |
9760 | +functions that have been registered via addition as a pretty-printer. | |
9761 | +Each function will be called with a @code{gdb.Value} to be | |
9762 | +pretty-printed. Each @code{gdb.Objfile} also contains a | |
9763 | +@code{pretty_printers} attribute. A function on one of these lists | |
9764 | +takes a single @code{gdb.Value} argument and returns a pretty-printer | |
9765 | +object conforming to the interface definition above. If this function | |
9766 | +cannot create a pretty-printer for the value, it should return | |
9767 | +@code{None}. | |
9768 | + | |
9769 | +@value{GDBN} first checks the @code{pretty_printers} attribute of each | |
9770 | +@code{gdb.Objfile} and iteratively calls each function in the list for | |
9771 | +that @code{gdb.Objfile} until it receives a pretty-printer object. | |
9772 | +After these @code{gdb.Objfile} have been exhausted, it tries the | |
9773 | +global @code{gdb.pretty-printers} list, again calling each function | |
9774 | +until an object is returned. | |
9775 | + | |
9776 | +The order in which the objfiles are searched is not specified. | |
9777 | +Functions are always invoked from the head of the | |
9778 | +@code{gdb.pretty-printers} list, and iterated over sequentially until | |
9779 | +the end of the list, or a printer object is returned. | |
9780 | + | |
9781 | +Here is an example showing how a @code{std::string} printer might be | |
9782 | +written: | |
9783 | + | |
9784 | +@smallexample | |
9785 | +class StdStringPrinter: | |
9786 | + "Print a std::string" | |
9787 | + | |
9788 | + def __init__ (self, val): | |
9789 | + self.val = val | |
9790 | + | |
9791 | + def to_string (self): | |
9792 | + return self.val['_M_dataplus']['_M_p'] | |
9793 | +@end smallexample | |
9794 | + | |
9795 | +And here is an example showing how a lookup function for | |
9796 | +the printer example above might be written. | |
9797 | + | |
9798 | +@smallexample | |
9799 | +def str_lookup_function (val): | |
9800 | + | |
9801 | + lookup_tag = val.type ().tag () | |
9802 | + regex = re.compile ("^std::basic_string<char,.*>$") | |
9803 | + if lookup_tag == None: | |
9804 | + return None | |
9805 | + if regex.match (lookup_tag): | |
9806 | + return StdStringPrinter (val) | |
9807 | + | |
9808 | + return None | |
9809 | +@end smallexample | |
9810 | + | |
9811 | +The example lookup function extracts the value's type, and attempts to | |
9812 | +match it to a type that it can pretty-print. If it is a type the | |
9813 | +printer can pretty-print, it will return a printer object. If not, it | |
9814 | +returns: @code{None}. | |
9815 | + | |
9816 | +We recommend that you put your core pretty-printers into a versioned | |
9817 | +python package, and then restrict your auto-loaded code to idempotent | |
9818 | +behavior -- for example, just @code{import}s of your printer modules, | |
9819 | +followed by a call to a register pretty-printers with the current | |
9820 | +objfile. This approach will scale more nicely to multiple inferiors, | |
9821 | +potentially using different library versions. | |
9822 | + | |
9823 | +For example, in addition to the above, this code might appear in | |
9824 | +@code{gdb.libstdcxx.v6}: | |
9825 | + | |
9826 | +@smallexample | |
9827 | +def register_printers (objfile): | |
9828 | + objfile.pretty_printers.add (str_lookup_function) | |
9829 | +@end smallexample | |
9830 | + | |
9831 | +And then the corresponding contents of the auto-load file would be: | |
9832 | + | |
9833 | +@smallexample | |
9834 | +import gdb.libstdcxx.v6 | |
9835 | +gdb.libstdcxx.v6.register_printers (gdb.current_objfile ()) | |
9836 | +@end smallexample | |
9837 | + | |
9838 | +@node Threads In Python | |
9839 | +@subsubsection Threads In Python | |
9840 | + | |
9841 | +Python scripts can access information about the inferior's threads | |
9842 | +using some functions provided by @value{GDBN}. Like all of | |
9843 | +@value{GDBN}'s Python additions, these are in the @code{gdb} module: | |
9844 | + | |
9845 | +@findex gdb.threads | |
9846 | +@defun threads | |
9847 | +This function returns a tuple holding all the thread IDs which are | |
9848 | +valid when the function is called. If there are no valid threads, | |
9849 | +this will return @code{None}. | |
9850 | +@end defun | |
9851 | + | |
9852 | +@findex gdb.current_thread | |
9853 | +@defun current_thread | |
9854 | +This function returns the thread ID of the selected thread. If there | |
9855 | +is no selected thread, this will return @code{None}. | |
9856 | +@end defun | |
9857 | + | |
9858 | +@findex gdb.switch_to_thread | |
9859 | +@defun switch_to_thread id | |
9860 | +This changes @value{GDBN}'s currently selected thread to the thread | |
9861 | +given by @var{id}. @var{id} must be a valid thread ID as returned by | |
9862 | +@code{threads}. If @var{id} is invalid, this function throws an | |
9863 | +exception. | |
9864 | +@end defun | |
9865 | + | |
9866 | @node Commands In Python | |
9867 | @subsubsection Commands In Python | |
9868 | ||
9869 | @@ -18320,7 +19095,7 @@ You can implement new @value{GDBN} CLI commands in Python. A CLI | |
9870 | command is implemented using an instance of the @code{gdb.Command} | |
9871 | class, most commonly using a subclass. | |
9872 | ||
9873 | -@defmethod Command __init__ name @var{command-class} @r{[}@var{completer-class} @var{prefix}@r{]} | |
9874 | +@defmethod Command __init__ name @var{command_class} @r{[}@var{completer_class}@r{]} @r{[}@var{prefix}@r{]} | |
9875 | The object initializer for @code{Command} registers the new command | |
9876 | with @value{GDBN}. This initializer is normally invoked from the | |
9877 | subclass' own @code{__init__} method. | |
9878 | @@ -18332,11 +19107,11 @@ an exception is raised. | |
9879 | ||
9880 | There is no support for multi-line commands. | |
9881 | ||
9882 | -@var{command-class} should be one of the @samp{COMMAND_} constants | |
9883 | +@var{command_class} should be one of the @samp{COMMAND_} constants | |
9884 | defined below. This argument tells @value{GDBN} how to categorize the | |
9885 | new command in the help system. | |
9886 | ||
9887 | -@var{completer-class} is an optional argument. If given, it should be | |
9888 | +@var{completer_class} is an optional argument. If given, it should be | |
9889 | one of the @samp{COMPLETE_} constants defined below. This argument | |
9890 | tells @value{GDBN} how to perform completion for this command. If not | |
9891 | given, @value{GDBN} will attempt to complete using the object's | |
9892 | @@ -18563,6 +19338,374 @@ registration of the command with @value{GDBN}. Depending on how the | |
9893 | Python code is read into @value{GDBN}, you may need to import the | |
9894 | @code{gdb} module explicitly. | |
9895 | ||
9896 | + | |
9897 | +@node Parameters In Python | |
9898 | +@subsubsection Parameters In Python | |
9899 | + | |
9900 | +@cindex parameters in python | |
9901 | +@cindex python parameters | |
9902 | +@tindex gdb.Parameter | |
9903 | +@tindex Parameter | |
9904 | +You can implement new @value{GDBN} parameters using Python. A new | |
9905 | +parameter is implemented as an instance of the @code{gdb.Parameter} | |
9906 | +class. Parameters are exposed to the user via the @code{set} and | |
9907 | +@code{show} commands. | |
9908 | + | |
9909 | +@defmethod Parameter __init__ name @var{command-class} @var{parameter-class} @r{[}@var{enum-sequence}@r{]} | |
9910 | +The object initializer for @code{Parameter} registers the new | |
9911 | +parameter with @value{GDBN}. This initializer is normally invoked | |
9912 | +from the subclass' own @code{__init__} method. | |
9913 | + | |
9914 | +@var{name} is the name of the new parameter. If @var{name} consists | |
9915 | +of multiple words, then the initial words are looked for as prefix | |
9916 | +commands. In this case, if one of the prefix commands does not exist, | |
9917 | +an exception is raised. | |
9918 | + | |
9919 | +@var{command-class} should be one of the @samp{COMMAND_} constants | |
9920 | +(@pxref{Commands In Python}). This argument tells @value{GDBN} how to | |
9921 | +categorize the new parameter in the help system. | |
9922 | + | |
9923 | +@var{parameter-class} should be one of the @samp{PARAM_} constants | |
9924 | +defined below. This argument tells @value{GDBN} the type of the new | |
9925 | +parameter; this information is used for input validation and | |
9926 | +completion. | |
9927 | + | |
9928 | +If @var{parameter-class} is @code{PARAM_ENUM}, then | |
9929 | +@var{enum-sequence} must be a sequence of strings. These strings | |
9930 | +represent the possible values for the parameter. | |
9931 | + | |
9932 | +If @var{parameter-class} is not @code{PARAM_ENUM}, then the presence | |
9933 | +of a fourth argument will cause an exception to be thrown. | |
9934 | + | |
9935 | +The help text for the new parameter is taken from the Python | |
9936 | +documentation string for the parameter's class, if there is one. If | |
9937 | +there is no documentation string, a default value is used. | |
9938 | +@end defmethod | |
9939 | + | |
9940 | +@defivar Parameter set_doc | |
9941 | +If this attribute exists, and is a string, then its value is used as | |
9942 | +the help text for this parameter's @code{set} command. The value is | |
9943 | +examined when @code{Parameter.__init__} is invoked; subsequent changes | |
9944 | +have no effect. | |
9945 | +@end defivar | |
9946 | + | |
9947 | +@defivar Parameter show_doc | |
9948 | +If this attribute exists, and is a string, then its value is used as | |
9949 | +the help text for this parameter's @code{show} command. The value is | |
9950 | +examined when @code{Parameter.__init__} is invoked; subsequent changes | |
9951 | +have no effect. | |
9952 | +@end defivar | |
9953 | + | |
9954 | +@defivar Parameter value | |
9955 | +The @code{value} attribute holds the underlying value of the | |
9956 | +parameter. It can be read and assigned to just as any other | |
9957 | +attribute. @value{GDBN} does validation when assignments are made. | |
9958 | +@end defivar | |
9959 | + | |
9960 | + | |
9961 | +When a new parameter is defined, its type must be specified. The | |
9962 | +available types are represented by constants defined in the @code{gdb} | |
9963 | +module: | |
9964 | + | |
9965 | +@table @code | |
9966 | +@findex PARAM_BOOLEAN | |
9967 | +@findex gdb.PARAM_BOOLEAN | |
9968 | +@item PARAM_BOOLEAN | |
9969 | +The value is a plain boolean. The Python boolean values, @code{True} | |
9970 | +and @code{False} are the only valid values. | |
9971 | + | |
9972 | +@findex PARAM_AUTO_BOOLEAN | |
9973 | +@findex gdb.PARAM_AUTO_BOOLEAN | |
9974 | +@item PARAM_AUTO_BOOLEAN | |
9975 | +The value has three possible states: true, false, and @samp{auto}. In | |
9976 | +Python, true and false are represented using boolean constants, and | |
9977 | +@samp{auto} is represented using @code{None}. | |
9978 | + | |
9979 | +@findex PARAM_UINTEGER | |
9980 | +@findex gdb.PARAM_UINTEGER | |
9981 | +@item PARAM_UINTEGER | |
9982 | +The value is an unsigned integer. The value of 0 should be | |
9983 | +interpreted to mean ``unlimited''. | |
9984 | + | |
9985 | +@findex PARAM_INTEGER | |
9986 | +@findex gdb.PARAM_INTEGER | |
9987 | +@item PARAM_INTEGER | |
9988 | +The value is a signed integer. The value of 0 should be interpreted | |
9989 | +to mean ``unlimited''. | |
9990 | + | |
9991 | +@findex PARAM_STRING | |
9992 | +@findex gdb.PARAM_STRING | |
9993 | +@item PARAM_STRING | |
9994 | +The value is a string. When the user modifies the string, escapes are | |
9995 | +translated. | |
9996 | + | |
9997 | +@findex PARAM_STRING_NOESCAPE | |
9998 | +@findex gdb.PARAM_STRING_NOESCAPE | |
9999 | +@item PARAM_STRING_NOESCAPE | |
10000 | +The value is a string. When the user modifies the string, escapes are | |
10001 | +passed through untranslated. | |
10002 | + | |
10003 | +@findex PARAM_OPTIONAL_FILENAME | |
10004 | +@findex gdb.PARAM_OPTIONAL_FILENAME | |
10005 | +@item PARAM_OPTIONAL_FILENAME | |
10006 | +The value is a either a filename (a string), or @code{None}. | |
10007 | + | |
10008 | +@findex PARAM_FILENAME | |
10009 | +@findex gdb.PARAM_FILENAME | |
10010 | +@item PARAM_FILENAME | |
10011 | +The value is a filename (a string). | |
10012 | + | |
10013 | +@findex PARAM_ZINTEGER | |
10014 | +@findex gdb.PARAM_ZINTEGER | |
10015 | +@item PARAM_ZINTEGER | |
10016 | +The value is an integer. This is like @code{PARAM_INTEGER}, except 0 | |
10017 | +is interpreted as itself. | |
10018 | + | |
10019 | +@findex PARAM_ENUM | |
10020 | +@findex gdb.PARAM_ENUM | |
10021 | +@item PARAM_ENUM | |
10022 | +The value is a string, which must be one of a collection string | |
10023 | +constants provided when the parameter is created. | |
10024 | +@end table | |
10025 | + | |
10026 | +@node Functions In Python | |
10027 | +@subsubsection Writing new convenience functions | |
10028 | + | |
10029 | +@cindex writing convenience functions | |
10030 | +@cindex convenience functions in python | |
10031 | +@cindex python convenience functions | |
10032 | +@tindex gdb.Function | |
10033 | +@tindex Function | |
10034 | +You can implement new convenience functions (@pxref{Convenience Vars}) | |
10035 | +in Python. A convenience function is an instance of a subclass of the | |
10036 | +class @code{gdb.Function}. | |
10037 | + | |
10038 | +@defmethod Function __init__ name | |
10039 | +The initializer for @code{Function} registers the new function with | |
10040 | +@value{GDBN}. The argument @var{name} is the name of the function, | |
10041 | +a string. The function will be visible to the user as a convenience | |
10042 | +variable of type @code{internal function}, whose name is the same as | |
10043 | +the given @var{name}. | |
10044 | + | |
10045 | +The documentation for the new function is taken from the documentation | |
10046 | +string for the new class. | |
10047 | +@end defmethod | |
10048 | + | |
10049 | +@defmethod Function invoke @var{*args} | |
10050 | +When a convenience function is evaluated, its arguments are converted | |
10051 | +to instances of @code{gdb.Value}, and then the function's | |
10052 | +@code{invoke} method is called. Note that @value{GDBN} does not | |
10053 | +predetermine the arity of convenience functions. Instead, all | |
10054 | +available arguments are passed to @code{invoke}, following the | |
10055 | +standard Python calling convention. In particular, a convenience | |
10056 | +function can have default values for parameters without ill effect. | |
10057 | + | |
10058 | +The return value of this method is used as its value in the enclosing | |
10059 | +expression. If an ordinary Python value is returned, it is converted | |
10060 | +to a @code{gdb.Value} following the usual rules. | |
10061 | +@end defmethod | |
10062 | + | |
10063 | +The following code snippet shows how a trivial convenience function can | |
10064 | +be implemented in Python: | |
10065 | + | |
10066 | +@smallexample | |
10067 | +class Greet (gdb.Function): | |
10068 | + """Return string to greet someone. | |
10069 | +Takes a name as argument.""" | |
10070 | + | |
10071 | + def __init__ (self): | |
10072 | + super (Greet, self).__init__ ("greet") | |
10073 | + | |
10074 | + def invoke (self, name): | |
10075 | + return "Hello, %s!" % name.string () | |
10076 | + | |
10077 | +Greet () | |
10078 | +@end smallexample | |
10079 | + | |
10080 | +The last line instantiates the class, and is necessary to trigger the | |
10081 | +registration of the function with @value{GDBN}. Depending on how the | |
10082 | +Python code is read into @value{GDBN}, you may need to import the | |
10083 | +@code{gdb} module explicitly. | |
10084 | + | |
10085 | +@node Objfiles In Python | |
10086 | +@subsubsection Objfiles In Python | |
10087 | + | |
10088 | +@cindex objfiles in python | |
10089 | +@cindex python objfiles | |
10090 | +@tindex gdb.Objfile | |
10091 | +@tindex Objfile | |
10092 | +@value{GDBN} loads symbols for an inferior from various | |
10093 | +symbol-containing files. These include the primary executable file, | |
10094 | +any shared libraries used by the inferior, and any separate debug info | |
10095 | +files. @value{GDBN} calls these symbol-containing files | |
10096 | +@dfn{objfiles}. | |
10097 | + | |
10098 | +Each objfile is represented by an instance of the @code{gdb.Objfile} | |
10099 | +class. | |
10100 | + | |
10101 | +@defivar Objfile filename | |
10102 | +The file name of the objfile as a string. | |
10103 | +@end defivar | |
10104 | + | |
10105 | +@defivar Objfile pretty_printers | |
10106 | +The @code{pretty_printers} attribute is used to look up | |
10107 | +pretty-printers by type. This is a dictionary which maps regular | |
10108 | +expressions (strings) to pretty-printing objects. @xref{Pretty | |
10109 | +Printing}, for more information. | |
10110 | +@end defivar | |
10111 | + | |
10112 | +@node Breakpoints In Python | |
10113 | +@subsubsection Manipulating breakpoints using Python | |
10114 | + | |
10115 | +@cindex breakpoints in python | |
10116 | +@cindex python breakpoints | |
10117 | +@tindex gdb.Breakpoint | |
10118 | +@tindex Breakpoint | |
10119 | +Python code can manipulate breakpoints via the @code{gdb.Breakpoint} | |
10120 | +class. | |
10121 | + | |
10122 | +@defmethod Breakpoint __init__ location | |
10123 | +Create a new breakpoint. @var{location} is a string naming the | |
10124 | +location of the breakpoint. The contents can be any location | |
10125 | +recognized by the @code{break} command. | |
10126 | +@end defmethod | |
10127 | + | |
10128 | +@defmethod Breakpoint is_valid | |
10129 | +Return @code{True} if this @code{Breakpoint} object is valid, | |
10130 | +@code{False} otherwise. A @code{Breakpoint} object can become invalid | |
10131 | +if the user deletes the breakpoint. In this case, the object still | |
10132 | +exists, but the underlying breakpoint does not. | |
10133 | +@end defmethod | |
10134 | + | |
10135 | +@defivar Breakpoint enabled | |
10136 | +This attribute is @code{True} if the breakpoint is enabled, and | |
10137 | +@code{False} otherwise. This attribute is writable. | |
10138 | +@end defivar | |
10139 | + | |
10140 | +@defivar Breakpoint silent | |
10141 | +This attribute is @code{True} if the breakpoint is silent, and | |
10142 | +@code{False} otherwise. This attribute is writable. | |
10143 | + | |
10144 | +Note that a breakpoint can also be silent if it has commands and the | |
10145 | +first command is @code{silent}. This is not reported by the | |
10146 | +@code{silent} attribute. | |
10147 | +@end defivar | |
10148 | + | |
10149 | +@defivar Breakpoint thread | |
10150 | +If the breakpoint is thread-specific, this attribute holds the thread | |
10151 | +id. If the breakpoint is not thread-specific, this attribute is | |
10152 | +@code{None}. This attribute is writable. | |
10153 | +@end defivar | |
10154 | + | |
10155 | +@defivar Breakpoint ignore_count | |
10156 | +This attribute holds the ignore count for the breakpoint, an integer. | |
10157 | +This attribute is writable. | |
10158 | +@end defivar | |
10159 | + | |
10160 | +@defivar Breakpoint number | |
10161 | +This attribute holds the breakpoint's number -- the identifier used by | |
10162 | +the user to manipulate the breakpoint. This attribute is not writable. | |
10163 | +@end defivar | |
10164 | + | |
10165 | +@defivar Breakpoint hit_count | |
10166 | +This attribute holds the hit count for the breakpoint, an integer. | |
10167 | +This attribute is writable, but currently it can only be set to zero. | |
10168 | +@end defivar | |
10169 | + | |
10170 | +@defivar Breakpoint location | |
10171 | +This attribute holds the location of the breakpoint, as specified by | |
10172 | +the user. It is a string. This attribute is not writable. | |
10173 | +@end defivar | |
10174 | + | |
10175 | +@defivar Breakpoint condition | |
10176 | +This attribute holds the condition of the breakpoint, as specified by | |
10177 | +the user. It is a string. If there is no condition, this attribute's | |
10178 | +value is @code{None}. This attribute is writable. | |
10179 | +@end defivar | |
10180 | + | |
10181 | +@defivar Breakpoint commands | |
10182 | +This attribute holds the commands attached to the breakpoint. If | |
10183 | +there are commands, this returns a string holding all the commands, | |
10184 | +separated by newlines. If there are no commands, this attribute is | |
10185 | +@code{None}. This attribute is not writable. | |
10186 | +@end defivar | |
10187 | + | |
10188 | +@node Frames In Python | |
10189 | +@subsubsection Accessing inferior stack frames from Python. | |
10190 | + | |
10191 | +@cindex frames in python | |
10192 | +@tindex gdb.Frame | |
10193 | +@tindex Frame | |
10194 | +When the debugged program stops, @value{GDBN} is able to analyse its call | |
10195 | +stack (@pxref{Frames,,Stack frames}). The @code{gdb.Frame} class | |
10196 | +represents a frame in the stack. You can get a tuple containing all the | |
10197 | +frames in the stack with the @code{gdb.frames} function, the newest | |
10198 | +frame with the @code{gdb.newest_frame} function, and the selected frame | |
10199 | +with the @code{gdb.selected_frame} function | |
10200 | +(see @xref{Selection,,Selecting a Frame}.) See | |
10201 | +@xref{Basic Python,,Basic Python}. | |
10202 | + | |
10203 | +A @code{gdb.Frame} object has the following methods: | |
10204 | + | |
10205 | +@table @code | |
10206 | +@defmethod Frame equals @code{frame} | |
10207 | +Compare frames. | |
10208 | +@end defmethod | |
10209 | + | |
10210 | +@defmethod Frame is_valid | |
10211 | +Returns true if the @code{gdb.Frame} object is valid, false if not. | |
10212 | +A frame object can become invalid if the frame it refers to doesn't | |
10213 | +exist anymore in the inferior. All @code{gdb.Frame} methods will throw | |
10214 | +an exception if it is invalid at the time the method call is made. | |
10215 | +@end defmethod | |
10216 | + | |
10217 | +@defmethod Frame name | |
10218 | +Returns the function name of the frame, or @code{None} if it can't be | |
10219 | +obtained. | |
10220 | +@end defmethod | |
10221 | + | |
10222 | +@defmethod Frame type | |
10223 | +Returns the type of the frame. The value can be one of | |
10224 | +@code{gdb.NORMAL_FRAME}, @code{gdb.DUMMY_FRAME}, @code{gdb.SIGTRAMP_FRAME} | |
10225 | +or @code{gdb.SENTINEL_FRAME}. | |
10226 | +@end defmethod | |
10227 | + | |
10228 | +@defmethod Frame unwind_stop_reason | |
10229 | +Return an integer representing the reason why it's not possible to find | |
10230 | +frames older than this. Use @code{gdb.frame_stop_reason_string} to convert | |
10231 | +the value returned by this function to a string. | |
10232 | +@end defmethod | |
10233 | + | |
10234 | +@defmethod Frame pc | |
10235 | +Returns the frame's resume address. | |
10236 | +@end defmethod | |
10237 | + | |
10238 | +@defmethod Frame block | |
10239 | +Returns the frame's code block. @c (see @xref{Block,,Code Blocks and Scopes}). | |
10240 | +@end defmethod | |
10241 | + | |
10242 | +@defmethod Frame address_in_block | |
10243 | +Returns an address which falls within the frame's code block. | |
10244 | +@end defmethod | |
10245 | + | |
10246 | +@defmethod Frame older | |
10247 | +Return the frame immediately older (outer) to this frame. | |
10248 | +@end defmethod | |
10249 | + | |
10250 | +@defmethod Frame newer | |
10251 | +Return the frame immediately newer (inner) to this frame. | |
10252 | +@end defmethod | |
10253 | + | |
10254 | +@defmethod Frame find_sal | |
10255 | +Return the frame's symtab and line object. @c (see @xref{Symtab_and_line,, Symtab and line}). | |
10256 | +@end defmethod | |
10257 | + | |
10258 | +@defmethod Frame read_var @var{variable} | |
10259 | +Return the value of the given variable in this frame. @code{variable} can be | |
10260 | +either a string or a @code{gdb.Symbol} object. @c (@pxref{Symbols In Python}). | |
10261 | +@end defmethod | |
10262 | +@end table | |
10263 | + | |
10264 | @node Interpreters | |
10265 | @chapter Command Interpreters | |
10266 | @cindex command interpreters | |
10267 | @@ -22273,6 +23416,103 @@ Unfreezing a variable does not update it, only subsequent | |
10268 | (gdb) | |
10269 | @end smallexample | |
10270 | ||
10271 | +@subheading The @code{-var-set-visualizer} command | |
10272 | +@findex -var-set-visualizer | |
10273 | +@anchor{-var-set-visualizer} | |
10274 | + | |
10275 | +@subsubheading Synopsis | |
10276 | + | |
10277 | +@smallexample | |
10278 | + -var-set-visualizer @var{name} @var{visualizer} | |
10279 | +@end smallexample | |
10280 | + | |
10281 | +@subheading The @code{-var-set-child-range} command | |
10282 | +@findex -var-set-child-range | |
10283 | +@anchor{-var-set-child-range} | |
10284 | + | |
10285 | +Set a visualizer for the variable object @var{name}. | |
10286 | + | |
10287 | +@var{visualizer} is the visualizer to use. The special value | |
10288 | +@samp{None} means to disable any visualizer in use. | |
10289 | + | |
10290 | +If not @samp{None}, @var{visualizer} must be a Python expression. | |
10291 | +This expression must evaluate to a callable object which accepts a | |
10292 | +single argument. @value{GDBN} will call this object with the value of | |
10293 | +the varobj @var{name} as an argument. This function must return an | |
10294 | +object which conforms to the pretty-printing interface (@pxref{Pretty | |
10295 | +Printing}). | |
10296 | + | |
10297 | +The pre-defined function @code{gdb.default_visualizer} may be used | |
10298 | +to select a visualizer according to the type of the varobj. This is | |
10299 | +called when a varobj is created, and so ordinarily is not needed. | |
10300 | + | |
10301 | +@code{gdb.default_visualizer} looks in the global dictionary named | |
10302 | +@code{gdb.pretty_printers}. | |
10303 | + | |
10304 | +This feature is only available if Python support is enabled. | |
10305 | + | |
10306 | +@subsubheading Example | |
10307 | + | |
10308 | +Resetting the visualizer: | |
10309 | + | |
10310 | +@smallexample | |
10311 | +(gdb) | |
10312 | +-var-set-visualizer V None | |
10313 | +^done | |
10314 | +@end smallexample | |
10315 | + | |
10316 | +Reselecting the default (type-based) visualizer: | |
10317 | + | |
10318 | +@smallexample | |
10319 | +(gdb) | |
10320 | +-var-set-visualizer V gdb.default_visualizer | |
10321 | +^done | |
10322 | +@end smallexample | |
10323 | + | |
10324 | +Suppose @code{SomeClass} is a visualizer class. A lambda expression | |
10325 | +can be used to instantiate this class for a varobj: | |
10326 | + | |
10327 | +@smallexample | |
10328 | +(gdb) | |
10329 | +-var-set-visualizer V "lambda val: SomeClass()" | |
10330 | +^done | |
10331 | +@end smallexample | |
10332 | + | |
10333 | +@subsubheading Synopsis | |
10334 | + | |
10335 | +@smallexample | |
10336 | + -var-set-child-range @var{name} @var{from} @var{to} | |
10337 | +@end smallexample | |
10338 | + | |
10339 | +Select a sub-range of the children of the variable object @var{name}; | |
10340 | +future calls to @code{-var-list-children} will only report the | |
10341 | +selected range of children. This allows an MI consumer to avoid | |
10342 | +inefficiencies if the varobj has very many children. | |
10343 | + | |
10344 | +If either @var{from} or @var{to} is less than zero, then sub-range | |
10345 | +selection is disabled, and @code{-var-list-children} will report all | |
10346 | +children. | |
10347 | + | |
10348 | +Otherwise, @var{from} and @var{to} are indexes into the array of | |
10349 | +children. Children starting at @var{from} and stopping jsut before | |
10350 | +@var{to} will be reported. | |
10351 | + | |
10352 | +@subsubheading Example | |
10353 | + | |
10354 | +@smallexample | |
10355 | +(gdb) | |
10356 | + -var-list-children n | |
10357 | + ^done,numchild=3,children=[@{name="a",numchild=0,type="int"@}, | |
10358 | + @{name="b",numchild=0,type="int"@}, | |
10359 | + @{name="c",numchild=0,type="int"@}] | |
10360 | +(gdb) | |
10361 | + -var-set-child-range n 1 2 | |
10362 | +(gdb) | |
10363 | + -var-list-children n | |
10364 | + ^done,numchild=3,children=[@{name="b",numchild=0,type="int"@}, | |
10365 | + @{name="c",numchild=0,type="int"@}] | |
10366 | +@end smallexample | |
10367 | + | |
10368 | ||
10369 | @c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
10370 | @node GDB/MI Data Manipulation | |
10371 | @@ -23832,6 +25072,10 @@ as possible presense of the @code{frozen} field in the output | |
10372 | of @code{-varobj-create}. | |
10373 | @item pending-breakpoints | |
10374 | Indicates presence of the @option{-f} option to the @code{-break-insert} command. | |
10375 | +@item python | |
10376 | +Indicates presence of Python scripting support, Python-based | |
10377 | +pretty-printing commands, and possible presence of the | |
10378 | +@samp{display_hint} field in the output of @code{-var-list-children} | |
10379 | @item thread-info | |
10380 | Indicates presence of the @code{-thread-info} command. | |
10381 | ||
10382 | @@ -25402,28 +26646,6 @@ data in a @file{gmon.out} file, be sure to move it to a safe location. | |
10383 | Configuring with @samp{--enable-profiling} arranges for @value{GDBN} to be | |
10384 | compiled with the @samp{-pg} compiler option. | |
10385 | ||
10386 | -@kindex maint set linux-async | |
10387 | -@kindex maint show linux-async | |
10388 | -@cindex asynchronous support | |
10389 | -@item maint set linux-async | |
10390 | -@itemx maint show linux-async | |
10391 | -Control the GNU/Linux native asynchronous support | |
10392 | -(@pxref{Background Execution}) of @value{GDBN}. | |
10393 | - | |
10394 | -GNU/Linux native asynchronous support will be disabled until you use | |
10395 | -the @samp{maint set linux-async} command to enable it. | |
10396 | - | |
10397 | -@kindex maint set remote-async | |
10398 | -@kindex maint show remote-async | |
10399 | -@cindex asynchronous support | |
10400 | -@item maint set remote-async | |
10401 | -@itemx maint show remote-async | |
10402 | -Control the remote asynchronous support | |
10403 | -(@pxref{Background Execution}) of @value{GDBN}. | |
10404 | - | |
10405 | -Remote asynchronous support will be disabled until you use | |
10406 | -the @samp{maint set remote-async} command to enable it. | |
10407 | - | |
10408 | @kindex maint show-debug-regs | |
10409 | @cindex x86 hardware debug registers | |
10410 | @item maint show-debug-regs | |
10411 | diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c | |
10412 | index ce11d89..eaa6a13 100644 | |
10413 | --- a/gdb/dwarf2-frame.c | |
10414 | +++ b/gdb/dwarf2-frame.c | |
10415 | @@ -38,6 +38,7 @@ | |
10416 | ||
10417 | #include "complaints.h" | |
10418 | #include "dwarf2-frame.h" | |
10419 | +#include "addrmap.h" | |
10420 | ||
10421 | struct comp_unit; | |
10422 | ||
10423 | @@ -1499,6 +1500,14 @@ dwarf2_frame_find_fde (CORE_ADDR *pc) | |
10424 | struct dwarf2_fde *fde; | |
10425 | CORE_ADDR offset; | |
10426 | ||
10427 | + if (objfile->quick_addrmap) | |
10428 | + { | |
10429 | + if (!addrmap_find (objfile->quick_addrmap, *pc)) | |
10430 | + continue; | |
10431 | + } | |
10432 | + /* FIXME: Read-in only .debug_frame/.eh_frame without .debug_info? */ | |
10433 | + require_partial_symbols (objfile); | |
10434 | + | |
10435 | fde = objfile_data (objfile, dwarf2_frame_objfile_data); | |
10436 | if (fde == NULL) | |
10437 | continue; | |
10438 | diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c | |
10439 | index 75a4ec7..aa8ab33 100644 | |
10440 | --- a/gdb/dwarf2expr.c | |
10441 | +++ b/gdb/dwarf2expr.c | |
10442 | @@ -752,6 +752,13 @@ execute_stack_op (struct dwarf_expr_context *ctx, | |
10443 | ctx->initialized = 0; | |
10444 | goto no_push; | |
10445 | ||
10446 | + case DW_OP_push_object_address: | |
10447 | + if (ctx->get_object_address == NULL) | |
10448 | + error (_("DWARF-2 expression error: DW_OP_push_object_address must " | |
10449 | + "have a value to push.")); | |
10450 | + result = (ctx->get_object_address) (ctx->baton); | |
10451 | + break; | |
10452 | + | |
10453 | default: | |
10454 | error (_("Unhandled dwarf expression opcode 0x%x"), op); | |
10455 | } | |
10456 | diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h | |
10457 | index 7047922..a287b6f 100644 | |
10458 | --- a/gdb/dwarf2expr.h | |
10459 | +++ b/gdb/dwarf2expr.h | |
10460 | @@ -67,10 +67,10 @@ struct dwarf_expr_context | |
10461 | The result must be live until the current expression evaluation | |
10462 | is complete. */ | |
10463 | unsigned char *(*get_subr) (void *baton, off_t offset, size_t *length); | |
10464 | +#endif | |
10465 | ||
10466 | /* Return the `object address' for DW_OP_push_object_address. */ | |
10467 | CORE_ADDR (*get_object_address) (void *baton); | |
10468 | -#endif | |
10469 | ||
10470 | /* The current depth of dwarf expression recursion, via DW_OP_call*, | |
10471 | DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum | |
10472 | diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c | |
10473 | index cad3db8..2251e48 100644 | |
10474 | --- a/gdb/dwarf2loc.c | |
10475 | +++ b/gdb/dwarf2loc.c | |
10476 | @@ -107,6 +107,9 @@ struct dwarf_expr_baton | |
10477 | { | |
10478 | struct frame_info *frame; | |
10479 | struct objfile *objfile; | |
10480 | + /* From DW_TAG_variable's DW_AT_location (not DW_TAG_type's | |
10481 | + DW_AT_data_location) for DW_OP_push_object_address. */ | |
10482 | + CORE_ADDR object_address; | |
10483 | }; | |
10484 | ||
10485 | /* Helper functions for dwarf2_evaluate_loc_desc. */ | |
10486 | @@ -163,22 +166,32 @@ dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length) | |
10487 | *start = find_location_expression (symbaton, length, | |
10488 | get_frame_address_in_block (frame)); | |
10489 | } | |
10490 | - else | |
10491 | + else if (SYMBOL_OPS (framefunc) == &dwarf2_locexpr_funcs) | |
10492 | { | |
10493 | struct dwarf2_locexpr_baton *symbaton; | |
10494 | + | |
10495 | symbaton = SYMBOL_LOCATION_BATON (framefunc); | |
10496 | - if (symbaton != NULL) | |
10497 | - { | |
10498 | - *length = symbaton->size; | |
10499 | - *start = symbaton->data; | |
10500 | - } | |
10501 | - else | |
10502 | - *start = NULL; | |
10503 | + gdb_assert (symbaton != NULL); | |
10504 | + *start = symbaton->data; | |
10505 | + *length = symbaton->size; | |
10506 | + } | |
10507 | + else if (SYMBOL_OPS (framefunc) == &dwarf2_missing_funcs) | |
10508 | + { | |
10509 | + struct dwarf2_locexpr_baton *symbaton; | |
10510 | + | |
10511 | + symbaton = SYMBOL_LOCATION_BATON (framefunc); | |
10512 | + gdb_assert (symbaton == NULL); | |
10513 | + *start = NULL; | |
10514 | + *length = 0; /* unused */ | |
10515 | } | |
10516 | + else | |
10517 | + internal_error (__FILE__, __LINE__, | |
10518 | + _("Unsupported SYMBOL_OPS %p for \"%s\""), | |
10519 | + SYMBOL_OPS (framefunc), SYMBOL_PRINT_NAME (framefunc)); | |
10520 | ||
10521 | if (*start == NULL) | |
10522 | error (_("Could not find the frame base for \"%s\"."), | |
10523 | - SYMBOL_NATURAL_NAME (framefunc)); | |
10524 | + SYMBOL_PRINT_NAME (framefunc)); | |
10525 | } | |
10526 | ||
10527 | /* Using the objfile specified in BATON, find the address for the | |
10528 | @@ -191,6 +204,119 @@ dwarf_expr_tls_address (void *baton, CORE_ADDR offset) | |
10529 | return target_translate_tls_address (debaton->objfile, offset); | |
10530 | } | |
10531 | ||
10532 | +static CORE_ADDR | |
10533 | +dwarf_expr_object_address (void *baton) | |
10534 | +{ | |
10535 | + struct dwarf_expr_baton *debaton = baton; | |
10536 | + | |
10537 | + /* The message is suppressed in DWARF_BLOCK_EXEC. */ | |
10538 | + if (debaton->object_address == 0) | |
10539 | + error (_("Cannot resolve DW_OP_push_object_address for a missing object")); | |
10540 | + | |
10541 | + return debaton->object_address; | |
10542 | +} | |
10543 | + | |
10544 | +/* Address of the variable we are currently referring to. It is set from | |
10545 | + DW_TAG_variable's DW_AT_location (not DW_TAG_type's DW_AT_data_location) for | |
10546 | + DW_OP_push_object_address. */ | |
10547 | + | |
10548 | +static CORE_ADDR object_address; | |
10549 | + | |
10550 | +/* Callers use object_address_set while their callers use the result set so we | |
10551 | + cannot run the cleanup at the local block of our direct caller. Still we | |
10552 | + should reset OBJECT_ADDRESS at least for the next GDB command. */ | |
10553 | + | |
10554 | +static void | |
10555 | +object_address_cleanup (void *prev_save_voidp) | |
10556 | +{ | |
10557 | + CORE_ADDR *prev_save = prev_save_voidp; | |
10558 | + | |
10559 | + object_address = *prev_save; | |
10560 | + xfree (prev_save); | |
10561 | +} | |
10562 | + | |
10563 | +/* Set the base address - DW_AT_location - of a variable. It is being later | |
10564 | + used to derive other object addresses by DW_OP_push_object_address. | |
10565 | + | |
10566 | + It would be useful to sanity check ADDRESS - such as for some objects with | |
10567 | + unset VALUE_ADDRESS - but some valid addresses may be zero (such as first | |
10568 | + objects in relocatable .o files). */ | |
10569 | + | |
10570 | +void | |
10571 | +object_address_set (CORE_ADDR address) | |
10572 | +{ | |
10573 | + CORE_ADDR *prev_save; | |
10574 | + | |
10575 | + prev_save = xmalloc (sizeof *prev_save); | |
10576 | + *prev_save = object_address; | |
10577 | + make_cleanup (object_address_cleanup, prev_save); | |
10578 | + | |
10579 | + object_address = address; | |
10580 | +} | |
10581 | + | |
10582 | +/* Evaluate DWARF expression at DATA ... DATA + SIZE with its result readable | |
10583 | + by dwarf_expr_fetch (RETVAL, 0). FRAME parameter can be NULL to call | |
10584 | + get_selected_frame to find it. Returned dwarf_expr_context freeing is | |
10585 | + pushed on the cleanup chain. */ | |
10586 | + | |
10587 | +static struct dwarf_expr_context * | |
10588 | +dwarf_expr_prep_ctx (struct frame_info *frame, gdb_byte *data, | |
10589 | + unsigned short size, struct dwarf2_per_cu_data *per_cu) | |
10590 | +{ | |
10591 | + struct dwarf_expr_context *ctx; | |
10592 | + struct dwarf_expr_baton baton; | |
10593 | + | |
10594 | + if (!frame) | |
10595 | + frame = get_selected_frame (NULL); | |
10596 | + | |
10597 | + baton.frame = frame; | |
10598 | + baton.objfile = dwarf2_per_cu_objfile (per_cu); | |
10599 | + baton.object_address = object_address; | |
10600 | + | |
10601 | + ctx = new_dwarf_expr_context (); | |
10602 | + ctx->gdbarch = get_objfile_arch (baton.objfile); | |
10603 | + ctx->addr_size = dwarf2_per_cu_addr_size (per_cu); | |
10604 | + ctx->baton = &baton; | |
10605 | + ctx->read_reg = dwarf_expr_read_reg; | |
10606 | + ctx->read_mem = dwarf_expr_read_mem; | |
10607 | + ctx->get_frame_base = dwarf_expr_frame_base; | |
10608 | + ctx->get_tls_address = dwarf_expr_tls_address; | |
10609 | + ctx->get_object_address = dwarf_expr_object_address; | |
10610 | + | |
10611 | + make_cleanup ((make_cleanup_ftype *) free_dwarf_expr_context, ctx); | |
10612 | + | |
10613 | + dwarf_expr_eval (ctx, data, size); | |
10614 | + | |
10615 | + /* It was used only during dwarf_expr_eval. */ | |
10616 | + ctx->baton = NULL; | |
10617 | + | |
10618 | + return ctx; | |
10619 | +} | |
10620 | + | |
10621 | +/* Evaluate DWARF expression at DLBATON expecting it produces exactly one | |
10622 | + CORE_ADDR result on the DWARF stack stack. */ | |
10623 | + | |
10624 | +CORE_ADDR | |
10625 | +dwarf_locexpr_baton_eval (struct dwarf2_locexpr_baton *dlbaton) | |
10626 | +{ | |
10627 | + struct dwarf_expr_context *ctx; | |
10628 | + CORE_ADDR retval; | |
10629 | + struct cleanup *back_to = make_cleanup (null_cleanup, 0); | |
10630 | + | |
10631 | + ctx = dwarf_expr_prep_ctx (NULL, dlbaton->data, dlbaton->size, | |
10632 | + dlbaton->per_cu); | |
10633 | + if (ctx->num_pieces > 0) | |
10634 | + error (_("DW_OP_*piece is unsupported for DW_FORM_block")); | |
10635 | + else if (ctx->in_reg) | |
10636 | + error (_("Register result is unsupported for DW_FORM_block")); | |
10637 | + | |
10638 | + retval = dwarf_expr_fetch (ctx, 0); | |
10639 | + | |
10640 | + do_cleanups (back_to); | |
10641 | + | |
10642 | + return retval; | |
10643 | +} | |
10644 | + | |
10645 | /* Evaluate a location description, starting at DATA and with length | |
10646 | SIZE, to find the current location of variable VAR in the context | |
10647 | of FRAME. */ | |
10648 | @@ -200,8 +326,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, | |
10649 | struct dwarf2_per_cu_data *per_cu) | |
10650 | { | |
10651 | struct value *retval; | |
10652 | - struct dwarf_expr_baton baton; | |
10653 | struct dwarf_expr_context *ctx; | |
10654 | + struct cleanup *back_to = make_cleanup (null_cleanup, 0); | |
10655 | ||
10656 | if (size == 0) | |
10657 | { | |
10658 | @@ -211,19 +337,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, | |
10659 | return retval; | |
10660 | } | |
10661 | ||
10662 | - baton.frame = frame; | |
10663 | - baton.objfile = dwarf2_per_cu_objfile (per_cu); | |
10664 | + ctx = dwarf_expr_prep_ctx (frame, data, size, per_cu); | |
10665 | ||
10666 | - ctx = new_dwarf_expr_context (); | |
10667 | - ctx->gdbarch = get_objfile_arch (baton.objfile); | |
10668 | - ctx->addr_size = dwarf2_per_cu_addr_size (per_cu); | |
10669 | - ctx->baton = &baton; | |
10670 | - ctx->read_reg = dwarf_expr_read_reg; | |
10671 | - ctx->read_mem = dwarf_expr_read_mem; | |
10672 | - ctx->get_frame_base = dwarf_expr_frame_base; | |
10673 | - ctx->get_tls_address = dwarf_expr_tls_address; | |
10674 | - | |
10675 | - dwarf_expr_eval (ctx, data, size); | |
10676 | if (ctx->num_pieces > 0) | |
10677 | { | |
10678 | int i; | |
10679 | @@ -261,15 +376,19 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, | |
10680 | { | |
10681 | CORE_ADDR address = dwarf_expr_fetch (ctx, 0); | |
10682 | ||
10683 | + /* object_address_set called here is required in ALLOCATE_VALUE's | |
10684 | + CHECK_TYPEDEF for the object's possible DW_OP_push_object_address. */ | |
10685 | + object_address_set (address); | |
10686 | + | |
10687 | retval = allocate_value (SYMBOL_TYPE (var)); | |
10688 | VALUE_LVAL (retval) = lval_memory; | |
10689 | set_value_lazy (retval, 1); | |
10690 | - VALUE_ADDRESS (retval) = address; | |
10691 | + set_value_address (retval, address); | |
10692 | } | |
10693 | ||
10694 | set_value_initialized (retval, ctx->initialized); | |
10695 | ||
10696 | - free_dwarf_expr_context (ctx); | |
10697 | + do_cleanups (back_to); | |
10698 | ||
10699 | return retval; | |
10700 | } | |
10701 | @@ -587,7 +706,7 @@ static int | |
10702 | loclist_describe_location (struct symbol *symbol, struct ui_file *stream) | |
10703 | { | |
10704 | /* FIXME: Could print the entire list of locations. */ | |
10705 | - fprintf_filtered (stream, "a variable with multiple locations"); | |
10706 | + fprintf_filtered (stream, _("a variable with multiple locations")); | |
10707 | return 1; | |
10708 | } | |
10709 | ||
10710 | @@ -603,16 +722,56 @@ loclist_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax, | |
10711 | ||
10712 | data = find_location_expression (dlbaton, &size, ax->scope); | |
10713 | if (data == NULL) | |
10714 | - error (_("Variable \"%s\" is not available."), SYMBOL_NATURAL_NAME (symbol)); | |
10715 | + error (_("Variable \"%s\" is not available."), SYMBOL_PRINT_NAME (symbol)); | |
10716 | ||
10717 | dwarf2_tracepoint_var_ref (symbol, ax, value, data, size); | |
10718 | } | |
10719 | ||
10720 | -/* The set of location functions used with the DWARF-2 expression | |
10721 | - evaluator and location lists. */ | |
10722 | +/* The set of location functions used with the DWARF-2 location lists. */ | |
10723 | const struct symbol_ops dwarf2_loclist_funcs = { | |
10724 | loclist_read_variable, | |
10725 | loclist_read_needs_frame, | |
10726 | loclist_describe_location, | |
10727 | loclist_tracepoint_var_ref | |
10728 | }; | |
10729 | + | |
10730 | +static struct value * | |
10731 | +missing_read_variable (struct symbol *symbol, struct frame_info *frame) | |
10732 | +{ | |
10733 | + struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); | |
10734 | + | |
10735 | + gdb_assert (dlbaton == NULL); | |
10736 | + error (_("Unable to resolve variable \"%s\""), SYMBOL_PRINT_NAME (symbol)); | |
10737 | +} | |
10738 | + | |
10739 | +static int | |
10740 | +missing_read_needs_frame (struct symbol *symbol) | |
10741 | +{ | |
10742 | + return 0; | |
10743 | +} | |
10744 | + | |
10745 | +static int | |
10746 | +missing_describe_location (struct symbol *symbol, struct ui_file *stream) | |
10747 | +{ | |
10748 | + fprintf_filtered (stream, _("a variable we are unable to resolve")); | |
10749 | + return 1; | |
10750 | +} | |
10751 | + | |
10752 | +static void | |
10753 | +missing_tracepoint_var_ref (struct symbol *symbol, struct agent_expr *ax, | |
10754 | + struct axs_value *value) | |
10755 | +{ | |
10756 | + struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); | |
10757 | + | |
10758 | + gdb_assert (dlbaton == NULL); | |
10759 | + error (_("Unable to resolve variable \"%s\""), SYMBOL_PRINT_NAME (symbol)); | |
10760 | +} | |
10761 | + | |
10762 | +/* The set of location functions used with the DWARF-2 evaluator when we are | |
10763 | + unable to resolve the symbols. */ | |
10764 | +const struct symbol_ops dwarf2_missing_funcs = { | |
10765 | + missing_read_variable, | |
10766 | + missing_read_needs_frame, | |
10767 | + missing_describe_location, | |
10768 | + missing_tracepoint_var_ref | |
10769 | +}; | |
10770 | diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h | |
10771 | index 76577f1..bf46761 100644 | |
10772 | --- a/gdb/dwarf2loc.h | |
10773 | +++ b/gdb/dwarf2loc.h | |
10774 | @@ -71,5 +71,11 @@ struct dwarf2_loclist_baton | |
10775 | ||
10776 | extern const struct symbol_ops dwarf2_locexpr_funcs; | |
10777 | extern const struct symbol_ops dwarf2_loclist_funcs; | |
10778 | +extern const struct symbol_ops dwarf2_missing_funcs; | |
10779 | + | |
10780 | +extern void object_address_set (CORE_ADDR address); | |
10781 | + | |
10782 | +extern CORE_ADDR dwarf_locexpr_baton_eval | |
10783 | + (struct dwarf2_locexpr_baton *dlbaton); | |
10784 | ||
10785 | #endif /* dwarf2loc.h */ | |
10786 | diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c | |
10787 | index 55868da..de93d08 100644 | |
10788 | --- a/gdb/dwarf2read.c | |
10789 | +++ b/gdb/dwarf2read.c | |
10790 | @@ -1,8 +1,7 @@ | |
10791 | /* DWARF 2 debugging format support for GDB. | |
10792 | ||
10793 | Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, | |
10794 | - 2004, 2005, 2006, 2007, 2008, 2009 | |
10795 | - Free Software Foundation, Inc. | |
10796 | + 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. | |
10797 | ||
10798 | Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, | |
10799 | Inc. with support from Florida State University (under contract | |
10800 | @@ -47,6 +46,9 @@ | |
10801 | #include "command.h" | |
10802 | #include "gdbcmd.h" | |
10803 | #include "addrmap.h" | |
10804 | +#include "f-lang.h" | |
10805 | +#include "c-lang.h" | |
10806 | +#include "typeprint.h" | |
10807 | ||
10808 | #include <fcntl.h> | |
10809 | #include "gdb_string.h" | |
10810 | @@ -103,7 +105,7 @@ typedef struct pubnames_header | |
10811 | _PUBNAMES_HEADER; | |
10812 | #define _ACTUAL_PUBNAMES_HEADER_SIZE 13 | |
10813 | ||
10814 | -/* .debug_pubnames header | |
10815 | +/* .debug_aranges header | |
10816 | Because of alignment constraints, this structure has padding and cannot | |
10817 | be mapped directly onto the beginning of the .debug_info section. */ | |
10818 | typedef struct aranges_header | |
10819 | @@ -299,9 +301,6 @@ struct dwarf2_cu | |
10820 | /* Hash table holding all the loaded partial DIEs. */ | |
10821 | htab_t partial_dies; | |
10822 | ||
10823 | - /* `.debug_ranges' offset for this `DW_TAG_compile_unit' DIE. */ | |
10824 | - unsigned int ranges_offset; | |
10825 | - | |
10826 | /* Storage for things with the same lifetime as this read-in compilation | |
10827 | unit, including partial DIEs. */ | |
10828 | struct obstack comp_unit_obstack; | |
10829 | @@ -349,9 +348,6 @@ struct dwarf2_cu | |
10830 | DIEs for namespaces, we don't need to try to infer them | |
10831 | from mangled names. */ | |
10832 | unsigned int has_namespace_info : 1; | |
10833 | - | |
10834 | - /* Field `ranges_offset' is filled in; flag as the value may be zero. */ | |
10835 | - unsigned int has_ranges_offset : 1; | |
10836 | }; | |
10837 | ||
10838 | /* Persistent data held for a compilation unit, even when not | |
10839 | @@ -451,17 +447,12 @@ struct partial_die_info | |
10840 | /* DWARF-2 tag for this DIE. */ | |
10841 | ENUM_BITFIELD(dwarf_tag) tag : 16; | |
10842 | ||
10843 | - /* Language code associated with this DIE. This is only used | |
10844 | - for the compilation unit DIE. */ | |
10845 | - unsigned int language : 8; | |
10846 | - | |
10847 | /* Assorted flags describing the data found in this DIE. */ | |
10848 | unsigned int has_children : 1; | |
10849 | unsigned int is_external : 1; | |
10850 | unsigned int is_declaration : 1; | |
10851 | unsigned int has_type : 1; | |
10852 | unsigned int has_specification : 1; | |
10853 | - unsigned int has_stmt_list : 1; | |
10854 | unsigned int has_pc_info : 1; | |
10855 | ||
10856 | /* Flag set if the SCOPE field of this structure has been | |
10857 | @@ -472,10 +463,12 @@ struct partial_die_info | |
10858 | unsigned int has_byte_size : 1; | |
10859 | ||
10860 | /* The name of this DIE. Normally the value of DW_AT_name, but | |
10861 | - sometimes DW_TAG_MIPS_linkage_name or a string computed in some | |
10862 | - other fashion. */ | |
10863 | + sometimes a default name for unnamed DIEs. */ | |
10864 | char *name; | |
10865 | - char *dirname; | |
10866 | + | |
10867 | + /* The linkage name of this DIE, from DW_AT_MIPS_linkage_name, or | |
10868 | + NULL if no linkage name was present. */ | |
10869 | + char *linkage_name; | |
10870 | ||
10871 | /* The scope to prepend to our children. This is generally | |
10872 | allocated on the comp_unit_obstack, so will disappear | |
10873 | @@ -498,9 +491,6 @@ struct partial_die_info | |
10874 | DW_AT_extension). */ | |
10875 | unsigned int spec_offset; | |
10876 | ||
10877 | - /* If HAS_STMT_LIST, the offset of the Line Number Information data. */ | |
10878 | - unsigned int line_offset; | |
10879 | - | |
10880 | /* Pointers to this DIE's parent, first child, and next sibling, | |
10881 | if any. */ | |
10882 | struct partial_die_info *die_parent, *die_child, *die_sibling; | |
10883 | @@ -523,6 +513,15 @@ struct attr_abbrev | |
10884 | ENUM_BITFIELD(dwarf_form) form : 16; | |
10885 | }; | |
10886 | ||
10887 | +/* Additional GDB-specific attribute forms. */ | |
10888 | +enum | |
10889 | + { | |
10890 | + /* A string which has been updated to GDB's internal | |
10891 | + representation (e.g. converted to canonical form) and does not | |
10892 | + need to be updated again. */ | |
10893 | + GDB_FORM_cached_string = 0xff | |
10894 | + }; | |
10895 | + | |
10896 | /* Attributes have a name and a value */ | |
10897 | struct attribute | |
10898 | { | |
10899 | @@ -756,7 +755,7 @@ static void dwarf2_create_include_psymtab (char *, struct partial_symtab *, | |
10900 | struct objfile *); | |
10901 | ||
10902 | static void dwarf2_build_include_psymtabs (struct dwarf2_cu *, | |
10903 | - struct partial_die_info *, | |
10904 | + struct die_info *, | |
10905 | struct partial_symtab *); | |
10906 | ||
10907 | static void dwarf2_build_psymtabs_hard (struct objfile *, int); | |
10908 | @@ -768,6 +767,9 @@ static void scan_partial_symbols (struct partial_die_info *, | |
10909 | static void add_partial_symbol (struct partial_die_info *, | |
10910 | struct dwarf2_cu *); | |
10911 | ||
10912 | +static gdb_byte *read_comp_unit_head (struct comp_unit_head *, gdb_byte *, | |
10913 | + bfd *); | |
10914 | + | |
10915 | static int pdi_needs_namespace (enum dwarf_tag tag); | |
10916 | ||
10917 | static void add_partial_namespace (struct partial_die_info *pdi, | |
10918 | @@ -794,6 +796,10 @@ static void dwarf2_psymtab_to_symtab (struct partial_symtab *); | |
10919 | ||
10920 | static void psymtab_to_symtab_1 (struct partial_symtab *); | |
10921 | ||
10922 | +static gdb_byte *dwarf2_read_section_1 (struct objfile *objfile, | |
10923 | + struct obstack *obstack, | |
10924 | + asection *sectp); | |
10925 | + | |
10926 | gdb_byte *dwarf2_read_section (struct objfile *, asection *); | |
10927 | ||
10928 | static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu); | |
10929 | @@ -929,7 +935,8 @@ static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *, | |
10930 | struct dwarf2_cu *, struct partial_symtab *); | |
10931 | ||
10932 | static int dwarf2_get_pc_bounds (struct die_info *, | |
10933 | - CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *); | |
10934 | + CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *, | |
10935 | + struct partial_symtab *pst); | |
10936 | ||
10937 | static void get_scope_pc_bounds (struct die_info *, | |
10938 | CORE_ADDR *, CORE_ADDR *, | |
10939 | @@ -962,6 +969,8 @@ static void read_namespace (struct die_info *die, struct dwarf2_cu *); | |
10940 | ||
10941 | static void read_module (struct die_info *die, struct dwarf2_cu *cu); | |
10942 | ||
10943 | +static void read_import_statement (struct die_info *die, struct dwarf2_cu *); | |
10944 | + | |
10945 | static const char *namespace_name (struct die_info *die, | |
10946 | int *is_anonymous, struct dwarf2_cu *); | |
10947 | ||
10948 | @@ -993,6 +1002,9 @@ static void process_die (struct die_info *, struct dwarf2_cu *); | |
10949 | ||
10950 | static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *); | |
10951 | ||
10952 | +static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *, | |
10953 | + struct obstack *); | |
10954 | + | |
10955 | static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *); | |
10956 | ||
10957 | static struct die_info *dwarf2_extension (struct die_info *die, | |
10958 | @@ -1030,7 +1042,14 @@ static void store_in_ref_table (struct die_info *, | |
10959 | ||
10960 | static unsigned int dwarf2_get_ref_die_offset (struct attribute *); | |
10961 | ||
10962 | -static int dwarf2_get_attr_constant_value (struct attribute *, int); | |
10963 | +enum dwarf2_get_attr_constant_value | |
10964 | + { | |
10965 | + dwarf2_attr_unknown, | |
10966 | + dwarf2_attr_const, | |
10967 | + dwarf2_attr_block | |
10968 | + }; | |
10969 | +static enum dwarf2_get_attr_constant_value dwarf2_get_attr_constant_value | |
10970 | + (struct attribute *attr, int *val_return); | |
10971 | ||
10972 | static struct die_info *follow_die_ref (struct die_info *, | |
10973 | struct attribute *, | |
10974 | @@ -1085,6 +1104,9 @@ static void age_cached_comp_units (void); | |
10975 | ||
10976 | static void free_one_cached_comp_unit (void *); | |
10977 | ||
10978 | +static void fetch_die_type_attrs (struct die_info *die, struct type *type, | |
10979 | + struct dwarf2_cu *cu); | |
10980 | + | |
10981 | static struct type *set_die_type (struct die_info *, struct type *, | |
10982 | struct dwarf2_cu *); | |
10983 | ||
10984 | @@ -1104,19 +1126,28 @@ static void dwarf2_clear_marks (struct dwarf2_per_cu_data *); | |
10985 | ||
10986 | static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu); | |
10987 | ||
10988 | +static struct dwarf2_locexpr_baton *dwarf2_attr_to_locexpr_baton | |
10989 | + (struct attribute *attr, struct dwarf2_cu *cu); | |
10990 | + | |
10991 | /* Try to locate the sections we need for DWARF 2 debugging | |
10992 | information and return true if we have enough to do something. */ | |
10993 | ||
10994 | int | |
10995 | dwarf2_has_info (struct objfile *objfile) | |
10996 | { | |
10997 | - struct dwarf2_per_objfile *data; | |
10998 | + int update_sizes = 0; | |
10999 | ||
11000 | /* Initialize per-objfile state. */ | |
11001 | - data = obstack_alloc (&objfile->objfile_obstack, sizeof (*data)); | |
11002 | - memset (data, 0, sizeof (*data)); | |
11003 | - set_objfile_data (objfile, dwarf2_objfile_data_key, data); | |
11004 | - dwarf2_per_objfile = data; | |
11005 | + dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key); | |
11006 | + if (!dwarf2_per_objfile) | |
11007 | + { | |
11008 | + struct dwarf2_per_objfile *data | |
11009 | + = obstack_alloc (&objfile->objfile_obstack, sizeof (*data)); | |
11010 | + memset (data, 0, sizeof (*data)); | |
11011 | + set_objfile_data (objfile, dwarf2_objfile_data_key, data); | |
11012 | + dwarf2_per_objfile = data; | |
11013 | + update_sizes = 1; | |
11014 | + } | |
11015 | ||
11016 | dwarf_info_section = 0; | |
11017 | dwarf_abbrev_section = 0; | |
11018 | @@ -1127,8 +1158,9 @@ dwarf2_has_info (struct objfile *objfile) | |
11019 | dwarf_eh_frame_section = 0; | |
11020 | dwarf_ranges_section = 0; | |
11021 | dwarf_loc_section = 0; | |
11022 | + dwarf_aranges_section = 0; | |
11023 | ||
11024 | - bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL); | |
11025 | + bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, &update_sizes); | |
11026 | return (dwarf_info_section != NULL && dwarf_abbrev_section != NULL); | |
11027 | } | |
11028 | ||
11029 | @@ -1149,51 +1181,61 @@ section_is_p (asection *sectp, const char *name) | |
11030 | in. */ | |
11031 | ||
11032 | static void | |
11033 | -dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr) | |
11034 | +dwarf2_locate_sections (bfd *abfd, asection *sectp, void *user_data) | |
11035 | { | |
11036 | + int update_sizes = * (int *) user_data; | |
11037 | if (section_is_p (sectp, INFO_SECTION)) | |
11038 | { | |
11039 | - dwarf2_per_objfile->info_size = bfd_get_section_size (sectp); | |
11040 | + if (update_sizes) | |
11041 | + dwarf2_per_objfile->info_size = bfd_get_section_size (sectp); | |
11042 | dwarf_info_section = sectp; | |
11043 | } | |
11044 | else if (section_is_p (sectp, ABBREV_SECTION)) | |
11045 | { | |
11046 | - dwarf2_per_objfile->abbrev_size = bfd_get_section_size (sectp); | |
11047 | + if (update_sizes) | |
11048 | + dwarf2_per_objfile->abbrev_size = bfd_get_section_size (sectp); | |
11049 | dwarf_abbrev_section = sectp; | |
11050 | } | |
11051 | else if (section_is_p (sectp, LINE_SECTION)) | |
11052 | { | |
11053 | - dwarf2_per_objfile->line_size = bfd_get_section_size (sectp); | |
11054 | + if (update_sizes) | |
11055 | + dwarf2_per_objfile->line_size = bfd_get_section_size (sectp); | |
11056 | dwarf_line_section = sectp; | |
11057 | } | |
11058 | else if (section_is_p (sectp, PUBNAMES_SECTION)) | |
11059 | { | |
11060 | - dwarf2_per_objfile->pubnames_size = bfd_get_section_size (sectp); | |
11061 | + if (update_sizes) | |
11062 | + dwarf2_per_objfile->pubnames_size = bfd_get_section_size (sectp); | |
11063 | dwarf_pubnames_section = sectp; | |
11064 | } | |
11065 | else if (section_is_p (sectp, ARANGES_SECTION)) | |
11066 | { | |
11067 | - dwarf2_per_objfile->aranges_size = bfd_get_section_size (sectp); | |
11068 | + if (update_sizes) | |
11069 | + dwarf2_per_objfile->aranges_size = bfd_get_section_size (sectp); | |
11070 | dwarf_aranges_section = sectp; | |
11071 | } | |
11072 | else if (section_is_p (sectp, LOC_SECTION)) | |
11073 | { | |
11074 | - dwarf2_per_objfile->loc_size = bfd_get_section_size (sectp); | |
11075 | + if (update_sizes) | |
11076 | + dwarf2_per_objfile->loc_size = bfd_get_section_size (sectp); | |
11077 | dwarf_loc_section = sectp; | |
11078 | } | |
11079 | else if (section_is_p (sectp, MACINFO_SECTION)) | |
11080 | { | |
11081 | - dwarf2_per_objfile->macinfo_size = bfd_get_section_size (sectp); | |
11082 | + if (update_sizes) | |
11083 | + dwarf2_per_objfile->macinfo_size = bfd_get_section_size (sectp); | |
11084 | dwarf_macinfo_section = sectp; | |
11085 | } | |
11086 | else if (section_is_p (sectp, STR_SECTION)) | |
11087 | { | |
11088 | - dwarf2_per_objfile->str_size = bfd_get_section_size (sectp); | |
11089 | + if (update_sizes) | |
11090 | + dwarf2_per_objfile->str_size = bfd_get_section_size (sectp); | |
11091 | dwarf_str_section = sectp; | |
11092 | } | |
11093 | else if (section_is_p (sectp, FRAME_SECTION)) | |
11094 | { | |
11095 | - dwarf2_per_objfile->frame_size = bfd_get_section_size (sectp); | |
11096 | + if (update_sizes) | |
11097 | + dwarf2_per_objfile->frame_size = bfd_get_section_size (sectp); | |
11098 | dwarf_frame_section = sectp; | |
11099 | } | |
11100 | else if (section_is_p (sectp, EH_FRAME_SECTION)) | |
11101 | @@ -1201,13 +1243,15 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr) | |
11102 | flagword aflag = bfd_get_section_flags (ignore_abfd, sectp); | |
11103 | if (aflag & SEC_HAS_CONTENTS) | |
11104 | { | |
11105 | - dwarf2_per_objfile->eh_frame_size = bfd_get_section_size (sectp); | |
11106 | + if (update_sizes) | |
11107 | + dwarf2_per_objfile->eh_frame_size = bfd_get_section_size (sectp); | |
11108 | dwarf_eh_frame_section = sectp; | |
11109 | } | |
11110 | } | |
11111 | else if (section_is_p (sectp, RANGES_SECTION)) | |
11112 | { | |
11113 | - dwarf2_per_objfile->ranges_size = bfd_get_section_size (sectp); | |
11114 | + if (update_sizes) | |
11115 | + dwarf2_per_objfile->ranges_size = bfd_get_section_size (sectp); | |
11116 | dwarf_ranges_section = sectp; | |
11117 | } | |
11118 | ||
11119 | @@ -1250,6 +1294,86 @@ dwarf2_resize_section (asection *sectp, bfd_size_type new_size) | |
11120 | sectp->name); | |
11121 | } | |
11122 | ||
11123 | +/* A cleanup that frees an obstack. */ | |
11124 | +static void | |
11125 | +finalize_obstack (void *o) | |
11126 | +{ | |
11127 | + struct obstack *ob = o; | |
11128 | + obstack_free (o, 0); | |
11129 | +} | |
11130 | + | |
11131 | +/* Read the .debug_aranges section and construct an address map. */ | |
11132 | + | |
11133 | +void | |
11134 | +dwarf2_create_quick_addrmap (struct objfile *objfile) | |
11135 | +{ | |
11136 | + char *aranges_buffer, *aranges_ptr; | |
11137 | + bfd *abfd = objfile->obfd; | |
11138 | + CORE_ADDR baseaddr; | |
11139 | + struct cleanup *old; | |
11140 | + struct obstack temp_obstack; | |
11141 | + struct addrmap *mutable_map; | |
11142 | + | |
11143 | + if (!dwarf_aranges_section) | |
11144 | + return; | |
11145 | + | |
11146 | + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); | |
11147 | + | |
11148 | + aranges_buffer = dwarf2_read_section_1 (objfile, NULL, dwarf_aranges_section); | |
11149 | + aranges_ptr = aranges_buffer; | |
11150 | + old = make_cleanup (xfree, aranges_buffer); | |
11151 | + | |
11152 | + obstack_init (&temp_obstack); | |
11153 | + make_cleanup (finalize_obstack, &temp_obstack); | |
11154 | + mutable_map = addrmap_create_mutable (&temp_obstack); | |
11155 | + | |
11156 | + while ((aranges_ptr - aranges_buffer) < dwarf2_per_objfile->aranges_size) | |
11157 | + { | |
11158 | + struct comp_unit_head cu_header; | |
11159 | + unsigned int bytes_read, segment_size, delta; | |
11160 | + LONGEST info_offset; | |
11161 | + struct dwarf2_cu cu; | |
11162 | + | |
11163 | + cu_header.initial_length_size = 0; | |
11164 | + aranges_ptr = read_comp_unit_head (&cu_header, aranges_ptr, abfd); | |
11165 | + | |
11166 | + segment_size = read_1_byte (abfd, aranges_ptr); | |
11167 | + aranges_ptr += 1; | |
11168 | + | |
11169 | + /* Align the pointer to twice the pointer size. I didn't see | |
11170 | + this in the spec but it appears to be required. */ | |
11171 | + delta = (aranges_ptr - aranges_buffer) % (2 * cu_header.addr_size); | |
11172 | + delta = (2 * cu_header.addr_size - delta) % (2 * cu_header.addr_size); | |
11173 | + aranges_ptr += delta; | |
11174 | + | |
11175 | + memset (&cu, 0, sizeof (cu)); | |
11176 | + cu.header.addr_size = cu_header.addr_size; | |
11177 | + | |
11178 | + while (1) | |
11179 | + { | |
11180 | + CORE_ADDR address, length; | |
11181 | + | |
11182 | + address = read_address (abfd, aranges_ptr, &cu, &bytes_read); | |
11183 | + aranges_ptr += bytes_read; | |
11184 | + | |
11185 | + length = read_address (abfd, aranges_ptr, &cu, &bytes_read); | |
11186 | + aranges_ptr += bytes_read; | |
11187 | + | |
11188 | + if (address == 0 && length == 0) | |
11189 | + break; | |
11190 | + | |
11191 | + address += baseaddr; | |
11192 | + | |
11193 | + addrmap_set_empty (mutable_map, address, address + length, objfile); | |
11194 | + } | |
11195 | + } | |
11196 | + | |
11197 | + objfile->quick_addrmap = addrmap_create_fixed (mutable_map, | |
11198 | + &objfile->objfile_obstack); | |
11199 | + do_cleanups (old); | |
11200 | +} | |
11201 | + | |
11202 | + | |
11203 | /* Build a partial symbol table. */ | |
11204 | ||
11205 | void | |
11206 | @@ -1453,22 +1577,24 @@ dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst, | |
11207 | ||
11208 | /* Read the Line Number Program data and extract the list of files | |
11209 | included by the source file represented by PST. Build an include | |
11210 | - partial symtab for each of these included files. | |
11211 | - | |
11212 | - This procedure assumes that there *is* a Line Number Program in | |
11213 | - the given CU. Callers should check that PDI->HAS_STMT_LIST is set | |
11214 | - before calling this procedure. */ | |
11215 | + partial symtab for each of these included files. */ | |
11216 | ||
11217 | static void | |
11218 | dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, | |
11219 | - struct partial_die_info *pdi, | |
11220 | + struct die_info *die, | |
11221 | struct partial_symtab *pst) | |
11222 | { | |
11223 | struct objfile *objfile = cu->objfile; | |
11224 | bfd *abfd = objfile->obfd; | |
11225 | - struct line_header *lh; | |
11226 | + struct line_header *lh = NULL; | |
11227 | + struct attribute *attr; | |
11228 | ||
11229 | - lh = dwarf_decode_line_header (pdi->line_offset, abfd, cu); | |
11230 | + attr = dwarf2_attr (die, DW_AT_stmt_list, cu); | |
11231 | + if (attr) | |
11232 | + { | |
11233 | + unsigned int line_offset = DW_UNSND (attr); | |
11234 | + lh = dwarf_decode_line_header (line_offset, abfd, cu); | |
11235 | + } | |
11236 | if (lh == NULL) | |
11237 | return; /* No linetable, so no includes. */ | |
11238 | ||
11239 | @@ -1477,6 +1603,36 @@ dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, | |
11240 | free_line_header (lh); | |
11241 | } | |
11242 | ||
11243 | +/* Find the base address of the compilation unit for range lists and | |
11244 | + location lists. It will normally be specified by DW_AT_low_pc. | |
11245 | + In DWARF-3 draft 4, the base address could be overridden by | |
11246 | + DW_AT_entry_pc. It's been removed, but GCC still uses this for | |
11247 | + compilation units with discontinuous ranges. */ | |
11248 | + | |
11249 | +static void | |
11250 | +dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu) | |
11251 | +{ | |
11252 | + struct attribute *attr; | |
11253 | + | |
11254 | + cu->base_known = 0; | |
11255 | + cu->base_address = 0; | |
11256 | + | |
11257 | + attr = dwarf2_attr (die, DW_AT_entry_pc, cu); | |
11258 | + if (attr) | |
11259 | + { | |
11260 | + cu->base_address = DW_ADDR (attr); | |
11261 | + cu->base_known = 1; | |
11262 | + } | |
11263 | + else | |
11264 | + { | |
11265 | + attr = dwarf2_attr (die, DW_AT_low_pc, cu); | |
11266 | + if (attr) | |
11267 | + { | |
11268 | + cu->base_address = DW_ADDR (attr); | |
11269 | + cu->base_known = 1; | |
11270 | + } | |
11271 | + } | |
11272 | +} | |
11273 | ||
11274 | /* Build the partial symbol table by doing a quick pass through the | |
11275 | .debug_info and .debug_abbrev sections. */ | |
11276 | @@ -1489,7 +1645,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) | |
11277 | bfd *abfd = objfile->obfd; | |
11278 | gdb_byte *info_ptr; | |
11279 | gdb_byte *beg_of_comp_unit; | |
11280 | - struct partial_die_info comp_unit_die; | |
11281 | + struct die_info *comp_unit_die; | |
11282 | struct partial_symtab *pst; | |
11283 | struct cleanup *back_to; | |
11284 | CORE_ADDR baseaddr; | |
11285 | @@ -1523,9 +1679,12 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) | |
11286 | { | |
11287 | struct cleanup *back_to_inner; | |
11288 | struct dwarf2_cu cu; | |
11289 | - struct abbrev_info *abbrev; | |
11290 | unsigned int bytes_read; | |
11291 | struct dwarf2_per_cu_data *this_cu; | |
11292 | + int has_children, has_pc_info; | |
11293 | + struct attribute *attr; | |
11294 | + const char *name; | |
11295 | + CORE_ADDR best_lowpc, best_highpc; | |
11296 | ||
11297 | beg_of_comp_unit = info_ptr; | |
11298 | ||
11299 | @@ -1551,11 +1710,10 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) | |
11300 | this_cu = dwarf2_find_comp_unit (cu.header.offset, objfile); | |
11301 | ||
11302 | /* Read the compilation unit die */ | |
11303 | - abbrev = peek_die_abbrev (info_ptr, &bytes_read, &cu); | |
11304 | - info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, | |
11305 | - abfd, info_ptr, &cu); | |
11306 | + info_ptr = read_full_die (&comp_unit_die, abfd, info_ptr, &cu, | |
11307 | + &has_children); | |
11308 | ||
11309 | - if (comp_unit_die.tag == DW_TAG_partial_unit) | |
11310 | + if (comp_unit_die->tag == DW_TAG_partial_unit) | |
11311 | { | |
11312 | info_ptr = (beg_of_comp_unit + cu.header.length | |
11313 | + cu.header.initial_length_size); | |
11314 | @@ -1564,20 +1722,27 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) | |
11315 | } | |
11316 | ||
11317 | /* Set the language we're debugging */ | |
11318 | - set_cu_language (comp_unit_die.language, &cu); | |
11319 | + attr = dwarf2_attr (comp_unit_die, DW_AT_language, &cu); | |
11320 | + if (attr != NULL) | |
11321 | + set_cu_language (DW_UNSND (attr), &cu); | |
11322 | + else | |
11323 | + set_cu_language (language_minimal, &cu); | |
11324 | ||
11325 | /* Allocate a new partial symbol table structure */ | |
11326 | - pst = start_psymtab_common (objfile, objfile->section_offsets, | |
11327 | - comp_unit_die.name ? comp_unit_die.name : "", | |
11328 | + attr = dwarf2_attr (comp_unit_die, DW_AT_name, &cu); | |
11329 | + if (attr != NULL) | |
11330 | + name = DW_STRING (attr); | |
11331 | + else | |
11332 | + name = ""; | |
11333 | + pst = start_psymtab_common (objfile, objfile->section_offsets, name, | |
11334 | /* TEXTLOW and TEXTHIGH are set below. */ | |
11335 | 0, | |
11336 | objfile->global_psymbols.next, | |
11337 | objfile->static_psymbols.next); | |
11338 | ||
11339 | - if (comp_unit_die.dirname) | |
11340 | - pst->dirname = obsavestring (comp_unit_die.dirname, | |
11341 | - strlen (comp_unit_die.dirname), | |
11342 | - &objfile->objfile_obstack); | |
11343 | + attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, &cu); | |
11344 | + if (attr != NULL) | |
11345 | + pst->dirname = xstrdup (DW_STRING (attr)); | |
11346 | ||
11347 | pst->read_symtab_private = (char *) this_cu; | |
11348 | ||
11349 | @@ -1607,24 +1772,17 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) | |
11350 | ||
11351 | /* Possibly set the default values of LOWPC and HIGHPC from | |
11352 | `DW_AT_ranges'. */ | |
11353 | - if (cu.has_ranges_offset) | |
11354 | - { | |
11355 | - if (dwarf2_ranges_read (cu.ranges_offset, &comp_unit_die.lowpc, | |
11356 | - &comp_unit_die.highpc, &cu, pst)) | |
11357 | - comp_unit_die.has_pc_info = 1; | |
11358 | - } | |
11359 | - else if (comp_unit_die.has_pc_info | |
11360 | - && comp_unit_die.lowpc < comp_unit_die.highpc) | |
11361 | - /* Store the contiguous range if it is not empty; it can be empty for | |
11362 | - CUs with no code. */ | |
11363 | - addrmap_set_empty (objfile->psymtabs_addrmap, | |
11364 | - comp_unit_die.lowpc + baseaddr, | |
11365 | - comp_unit_die.highpc + baseaddr - 1, pst); | |
11366 | + has_pc_info = 0; | |
11367 | + | |
11368 | + if (dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc, &best_highpc, &cu, | |
11369 | + pst)) | |
11370 | + has_pc_info = 1; | |
11371 | + dwarf2_find_base_address (comp_unit_die, &cu); | |
11372 | ||
11373 | /* Check if comp unit has_children. | |
11374 | If so, read the rest of the partial symbols from this comp unit. | |
11375 | If not, there's no more debug_info for this comp unit. */ | |
11376 | - if (comp_unit_die.has_children) | |
11377 | + if (has_children) | |
11378 | { | |
11379 | struct partial_die_info *first_die; | |
11380 | CORE_ADDR lowpc, highpc; | |
11381 | @@ -1634,8 +1792,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) | |
11382 | ||
11383 | first_die = load_partial_dies (abfd, info_ptr, 1, &cu); | |
11384 | ||
11385 | - scan_partial_symbols (first_die, &lowpc, &highpc, | |
11386 | - ! comp_unit_die.has_pc_info, &cu); | |
11387 | + scan_partial_symbols (first_die, &lowpc, &highpc, ! has_pc_info, &cu); | |
11388 | ||
11389 | /* If we didn't find a lowpc, set it to highpc to avoid | |
11390 | complaints from `maint check'. */ | |
11391 | @@ -1644,14 +1801,14 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) | |
11392 | ||
11393 | /* If the compilation unit didn't have an explicit address range, | |
11394 | then use the information extracted from its child dies. */ | |
11395 | - if (! comp_unit_die.has_pc_info) | |
11396 | + if (! has_pc_info) | |
11397 | { | |
11398 | - comp_unit_die.lowpc = lowpc; | |
11399 | - comp_unit_die.highpc = highpc; | |
11400 | + best_lowpc = lowpc; | |
11401 | + best_highpc = highpc; | |
11402 | } | |
11403 | } | |
11404 | - pst->textlow = comp_unit_die.lowpc + baseaddr; | |
11405 | - pst->texthigh = comp_unit_die.highpc + baseaddr; | |
11406 | + pst->textlow = best_lowpc + baseaddr; | |
11407 | + pst->texthigh = best_highpc + baseaddr; | |
11408 | ||
11409 | pst->n_global_syms = objfile->global_psymbols.next - | |
11410 | (objfile->global_psymbols.list + pst->globals_offset); | |
11411 | @@ -1667,12 +1824,9 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) | |
11412 | info_ptr = beg_of_comp_unit + cu.header.length | |
11413 | + cu.header.initial_length_size; | |
11414 | ||
11415 | - if (comp_unit_die.has_stmt_list) | |
11416 | - { | |
11417 | - /* Get the list of files included in the current compilation unit, | |
11418 | - and build a psymtab for each of them. */ | |
11419 | - dwarf2_build_include_psymtabs (&cu, &comp_unit_die, pst); | |
11420 | - } | |
11421 | + /* Get the list of files included in the current compilation unit, | |
11422 | + and build a psymtab for each of them. */ | |
11423 | + dwarf2_build_include_psymtabs (&cu, comp_unit_die, pst); | |
11424 | ||
11425 | do_cleanups (back_to_inner); | |
11426 | } | |
11427 | @@ -1690,11 +1844,12 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile) | |
11428 | { | |
11429 | bfd *abfd = objfile->obfd; | |
11430 | gdb_byte *info_ptr, *beg_of_comp_unit; | |
11431 | - struct partial_die_info comp_unit_die; | |
11432 | + struct die_info *comp_unit_die; | |
11433 | struct dwarf2_cu *cu; | |
11434 | - struct abbrev_info *abbrev; | |
11435 | unsigned int bytes_read; | |
11436 | struct cleanup *back_to; | |
11437 | + struct attribute *attr; | |
11438 | + int has_children; | |
11439 | ||
11440 | info_ptr = dwarf2_per_objfile->info_buffer + this_cu->offset; | |
11441 | beg_of_comp_unit = info_ptr; | |
11442 | @@ -1716,12 +1871,15 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile) | |
11443 | back_to = make_cleanup (dwarf2_free_abbrev_table, cu); | |
11444 | ||
11445 | /* Read the compilation unit die. */ | |
11446 | - abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu); | |
11447 | - info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, | |
11448 | - abfd, info_ptr, cu); | |
11449 | + info_ptr = read_full_die (&comp_unit_die, abfd, info_ptr, cu, | |
11450 | + &has_children); | |
11451 | ||
11452 | /* Set the language we're debugging. */ | |
11453 | - set_cu_language (comp_unit_die.language, cu); | |
11454 | + attr = dwarf2_attr (comp_unit_die, DW_AT_language, cu); | |
11455 | + if (attr) | |
11456 | + set_cu_language (DW_UNSND (attr), cu); | |
11457 | + else | |
11458 | + set_cu_language (language_minimal, cu); | |
11459 | ||
11460 | /* Link this compilation unit into the compilation unit tree. */ | |
11461 | this_cu->cu = cu; | |
11462 | @@ -1731,7 +1889,7 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile) | |
11463 | /* Check if comp unit has_children. | |
11464 | If so, read the rest of the partial symbols from this comp unit. | |
11465 | If not, there's no more debug_info for this comp unit. */ | |
11466 | - if (comp_unit_die.has_children) | |
11467 | + if (has_children) | |
11468 | load_partial_dies (abfd, info_ptr, 0, cu); | |
11469 | ||
11470 | do_cleanups (back_to); | |
11471 | @@ -1948,7 +2106,7 @@ partial_die_parent_scope (struct partial_die_info *pdi, | |
11472 | ignoring them. */ | |
11473 | complaint (&symfile_complaints, | |
11474 | _("unhandled containing DIE tag %d for DIE at %d"), | |
11475 | - parent->tag, pdi->offset); | |
11476 | + parent->tag, real_pdi->offset); | |
11477 | parent->scope = grandparent_scope; | |
11478 | } | |
11479 | ||
11480 | @@ -1963,12 +2121,37 @@ partial_die_full_name (struct partial_die_info *pdi, | |
11481 | struct dwarf2_cu *cu) | |
11482 | { | |
11483 | char *parent_scope; | |
11484 | + struct partial_die_info *real_pdi; | |
11485 | ||
11486 | - parent_scope = partial_die_parent_scope (pdi, cu); | |
11487 | - if (parent_scope == NULL) | |
11488 | - return NULL; | |
11489 | - else | |
11490 | + /* We need to look at our parent DIE; if we have a DW_AT_specification, | |
11491 | + then this means the parent of the specification DIE. | |
11492 | + partial_die_parent_scope does this loop also, but we do it here | |
11493 | + since we need to examine real_pdi->parent ourselves. */ | |
11494 | + | |
11495 | + real_pdi = pdi; | |
11496 | + while (real_pdi->has_specification) | |
11497 | + real_pdi = find_partial_die (real_pdi->spec_offset, cu); | |
11498 | + | |
11499 | + parent_scope = partial_die_parent_scope (real_pdi, cu); | |
11500 | + if (parent_scope != NULL) | |
11501 | return typename_concat (NULL, parent_scope, pdi->name, cu); | |
11502 | + | |
11503 | + if (!cu->has_namespace_info && pdi->linkage_name | |
11504 | + && !real_pdi->die_parent) | |
11505 | + { | |
11506 | + char *actual_scope | |
11507 | + = language_class_name_from_physname (cu->language_defn, | |
11508 | + pdi->linkage_name); | |
11509 | + if (actual_scope != NULL) | |
11510 | + { | |
11511 | + char *actual_name = typename_concat (NULL, actual_scope, | |
11512 | + pdi->name, cu); | |
11513 | + xfree (actual_scope); | |
11514 | + return actual_name; | |
11515 | + } | |
11516 | + } | |
11517 | + | |
11518 | + return NULL; | |
11519 | } | |
11520 | ||
11521 | static void | |
11522 | @@ -1984,7 +2167,9 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) | |
11523 | ||
11524 | baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); | |
11525 | ||
11526 | - if (pdi_needs_namespace (pdi->tag)) | |
11527 | + if (pdi->linkage_name != NULL) | |
11528 | + actual_name = pdi->linkage_name; | |
11529 | + else if (pdi_needs_namespace (pdi->tag)) | |
11530 | { | |
11531 | actual_name = partial_die_full_name (pdi, cu); | |
11532 | if (actual_name) | |
11533 | @@ -2133,9 +2318,8 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) | |
11534 | if (cu->language == language_cplus | |
11535 | && cu->has_namespace_info == 0 | |
11536 | && psym != NULL | |
11537 | - && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL) | |
11538 | - cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym), | |
11539 | - objfile); | |
11540 | + && pdi->linkage_name != NULL) | |
11541 | + cp_check_possible_namespace_symbols (actual_name, objfile); | |
11542 | ||
11543 | if (built_actual_name) | |
11544 | xfree (actual_name); | |
11545 | @@ -2158,6 +2342,14 @@ pdi_needs_namespace (enum dwarf_tag tag) | |
11546 | case DW_TAG_union_type: | |
11547 | case DW_TAG_enumeration_type: | |
11548 | case DW_TAG_enumerator: | |
11549 | + case DW_TAG_subprogram: | |
11550 | + case DW_TAG_variable: | |
11551 | + return 1; | |
11552 | + case DW_TAG_member: | |
11553 | + /* The only time we will encounter member variables in this | |
11554 | + function is when we are creating a "linkage" name for them; | |
11555 | + therefore they must be static members, so they do need a | |
11556 | + class prefix. */ | |
11557 | return 1; | |
11558 | default: | |
11559 | return 0; | |
11560 | @@ -2290,11 +2482,11 @@ guess_structure_name (struct partial_die_info *struct_pdi, | |
11561 | ||
11562 | while (child_pdi != NULL) | |
11563 | { | |
11564 | - if (child_pdi->tag == DW_TAG_subprogram) | |
11565 | + if (child_pdi->tag == DW_TAG_subprogram && child_pdi->linkage_name) | |
11566 | { | |
11567 | char *actual_class_name | |
11568 | = language_class_name_from_physname (cu->language_defn, | |
11569 | - child_pdi->name); | |
11570 | + child_pdi->linkage_name); | |
11571 | if (actual_class_name != NULL) | |
11572 | { | |
11573 | struct_pdi->name | |
11574 | @@ -2741,7 +2933,6 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) | |
11575 | CORE_ADDR lowpc, highpc; | |
11576 | struct symtab *symtab; | |
11577 | struct cleanup *back_to; | |
11578 | - struct attribute *attr; | |
11579 | CORE_ADDR baseaddr; | |
11580 | ||
11581 | baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); | |
11582 | @@ -2751,30 +2942,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) | |
11583 | ||
11584 | cu->list_in_scope = &file_symbols; | |
11585 | ||
11586 | - /* Find the base address of the compilation unit for range lists and | |
11587 | - location lists. It will normally be specified by DW_AT_low_pc. | |
11588 | - In DWARF-3 draft 4, the base address could be overridden by | |
11589 | - DW_AT_entry_pc. It's been removed, but GCC still uses this for | |
11590 | - compilation units with discontinuous ranges. */ | |
11591 | - | |
11592 | - cu->base_known = 0; | |
11593 | - cu->base_address = 0; | |
11594 | - | |
11595 | - attr = dwarf2_attr (cu->dies, DW_AT_entry_pc, cu); | |
11596 | - if (attr) | |
11597 | - { | |
11598 | - cu->base_address = DW_ADDR (attr); | |
11599 | - cu->base_known = 1; | |
11600 | - } | |
11601 | - else | |
11602 | - { | |
11603 | - attr = dwarf2_attr (cu->dies, DW_AT_low_pc, cu); | |
11604 | - if (attr) | |
11605 | - { | |
11606 | - cu->base_address = DW_ADDR (attr); | |
11607 | - cu->base_known = 1; | |
11608 | - } | |
11609 | - } | |
11610 | + dwarf2_find_base_address (cu->dies, cu); | |
11611 | ||
11612 | /* Do line number decoding in read_file_scope () */ | |
11613 | process_die (cu->dies, cu); | |
11614 | @@ -2805,6 +2973,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) | |
11615 | static void | |
11616 | process_die (struct die_info *die, struct dwarf2_cu *cu) | |
11617 | { | |
11618 | + | |
11619 | switch (die->tag) | |
11620 | { | |
11621 | case DW_TAG_padding: | |
11622 | @@ -2849,6 +3018,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) | |
11623 | ||
11624 | case DW_TAG_base_type: | |
11625 | case DW_TAG_subrange_type: | |
11626 | + case DW_TAG_typedef: | |
11627 | /* Add a typedef symbol for the type definition, if it has a | |
11628 | DW_AT_name. */ | |
11629 | new_symbol (die, read_type_die (die, cu), cu); | |
11630 | @@ -2867,14 +3037,12 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) | |
11631 | break; | |
11632 | case DW_TAG_imported_declaration: | |
11633 | case DW_TAG_imported_module: | |
11634 | - /* FIXME: carlton/2002-10-16: Eventually, we should use the | |
11635 | - information contained in these. DW_TAG_imported_declaration | |
11636 | - dies shouldn't have children; DW_TAG_imported_module dies | |
11637 | - shouldn't in the C++ case, but conceivably could in the | |
11638 | - Fortran case. */ | |
11639 | processing_has_namespace_info = 1; | |
11640 | - complaint (&symfile_complaints, _("unsupported tag: '%s'"), | |
11641 | - dwarf_tag_name (die->tag)); | |
11642 | + if (die->child != NULL && (die->tag == DW_TAG_imported_declaration | |
11643 | + || cu->language != language_fortran)) | |
11644 | + complaint (&symfile_complaints, _("Tag '%s' has unexpected children"), | |
11645 | + dwarf_tag_name (die->tag)); | |
11646 | + read_import_statement (die, cu); | |
11647 | break; | |
11648 | default: | |
11649 | new_symbol (die, NULL, cu); | |
11650 | @@ -2904,22 +3072,130 @@ dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu) | |
11651 | return name; | |
11652 | ||
11653 | /* If no prefix is necessary for this type of DIE, return the | |
11654 | - unqualified name. The other three tags listed could be handled | |
11655 | - in pdi_needs_namespace, but that requires broader changes. */ | |
11656 | - if (!pdi_needs_namespace (die->tag) | |
11657 | - && die->tag != DW_TAG_subprogram | |
11658 | - && die->tag != DW_TAG_variable | |
11659 | - && die->tag != DW_TAG_member) | |
11660 | + unqualified name. */ | |
11661 | + if (!pdi_needs_namespace (die->tag)) | |
11662 | return name; | |
11663 | ||
11664 | prefix = determine_prefix (die, cu); | |
11665 | if (*prefix != '\0') | |
11666 | - name = typename_concat (&cu->objfile->objfile_obstack, prefix, | |
11667 | - name, cu); | |
11668 | + { | |
11669 | + char *prefixed_name = typename_concat (NULL, prefix, name, cu); | |
11670 | + buf = mem_fileopen (); | |
11671 | + fputs_unfiltered (prefixed_name, buf); | |
11672 | + xfree (prefixed_name); | |
11673 | + } | |
11674 | + | |
11675 | + if (cu->language == language_cplus && die->tag == DW_TAG_subprogram) | |
11676 | + { | |
11677 | + struct type *type = read_type_die (die, cu); | |
11678 | + | |
11679 | + if (buf == NULL) | |
11680 | + { | |
11681 | + buf = mem_fileopen (); | |
11682 | + fputs_unfiltered (name, buf); | |
11683 | + } | |
11684 | + | |
11685 | + c_type_print_args (type, buf, 0); | |
11686 | + } | |
11687 | + | |
11688 | + if (buf != NULL) | |
11689 | + { | |
11690 | + long length; | |
11691 | + name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, | |
11692 | + &length); | |
11693 | + ui_file_delete (buf); | |
11694 | + } | |
11695 | ||
11696 | return name; | |
11697 | } | |
11698 | ||
11699 | +/* read the given die's decl_line number. Return -1 if in case of an error */ | |
11700 | +static int dwarf2_read_decl_line (struct die_info *die, struct dwarf2_cu *cu){ | |
11701 | + struct attribute *line_attr; | |
11702 | + | |
11703 | + line_attr = dwarf2_attr (die, DW_AT_decl_line, cu); | |
11704 | + if (line_attr){ | |
11705 | + return DW_UNSND (line_attr); | |
11706 | + } | |
11707 | + | |
11708 | + return -1; | |
11709 | +} | |
11710 | + | |
11711 | +/* Read the import statement specified by the given die and record it. */ | |
11712 | + | |
11713 | +static void | |
11714 | +read_import_statement (struct die_info *die, struct dwarf2_cu *cu) | |
11715 | +{ | |
11716 | + struct attribute *import_attr; | |
11717 | + struct die_info *imported_die; | |
11718 | + const char *imported_name; | |
11719 | + const char *imported_name_prefix; | |
11720 | + char *canonical_name; | |
11721 | + const char *import_alias; | |
11722 | + const char *imported_declaration = ""; | |
11723 | + const char *import_prefix; | |
11724 | + | |
11725 | + int line_number = -1; | |
11726 | + | |
11727 | + int is_anonymous = 0; | |
11728 | + | |
11729 | + import_attr = dwarf2_attr (die, DW_AT_import, cu); | |
11730 | + if (import_attr == NULL) | |
11731 | + { | |
11732 | + complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"), | |
11733 | + dwarf_tag_name (die->tag)); | |
11734 | + return; | |
11735 | + } | |
11736 | + | |
11737 | + imported_die = follow_die_ref (die, import_attr, &cu); | |
11738 | + imported_name = namespace_name (imported_die, &is_anonymous, cu); | |
11739 | + if (imported_name == NULL) | |
11740 | + { | |
11741 | + /* C++ imports from std:: DW_TAG_base_type with no DW_AT_name - why? */ | |
11742 | + return; | |
11743 | + } | |
11744 | + | |
11745 | + /* Figure out the local name after import. */ | |
11746 | + import_alias = dwarf2_name(die, cu); | |
11747 | + if(import_alias == NULL){ | |
11748 | + import_alias = ""; | |
11749 | + } | |
11750 | + | |
11751 | + /* Determine the line number at which the import was made */ | |
11752 | + line_number = dwarf2_read_decl_line(die, cu); | |
11753 | + | |
11754 | + /* Figure out where the statement is being imported to */ | |
11755 | + import_prefix = determine_prefix (die, cu); | |
11756 | + | |
11757 | + /* | |
11758 | + Figure out what the scope of the imported die is and prepend it | |
11759 | + to the name of the imported die | |
11760 | + */ | |
11761 | + imported_name_prefix = determine_prefix (imported_die, cu); | |
11762 | + | |
11763 | + if(imported_die->tag != DW_TAG_namespace){ | |
11764 | + imported_declaration = imported_name; | |
11765 | + canonical_name = (char*)imported_name_prefix; | |
11766 | + }else{ | |
11767 | + if(strlen (imported_name_prefix) > 0){ | |
11768 | + canonical_name = alloca (strlen (imported_name_prefix) + 2 + strlen (imported_name) + 1); | |
11769 | + strcpy (canonical_name, imported_name_prefix); | |
11770 | + strcat (canonical_name, "::"); | |
11771 | + strcat (canonical_name, imported_name); | |
11772 | + }else{ | |
11773 | + canonical_name = alloca (strlen (imported_name) + 1); | |
11774 | + strcpy (canonical_name, imported_name); | |
11775 | + } | |
11776 | + } | |
11777 | + | |
11778 | + using_directives = cp_add_using (import_prefix, | |
11779 | + canonical_name, | |
11780 | + import_alias, | |
11781 | + imported_declaration, | |
11782 | + line_number, | |
11783 | + using_directives); | |
11784 | +} | |
11785 | + | |
11786 | static void | |
11787 | initialize_cu_func_list (struct dwarf2_cu *cu) | |
11788 | { | |
11789 | @@ -3076,6 +3352,103 @@ add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc, | |
11790 | cu->last_fn = thisfn; | |
11791 | } | |
11792 | ||
11793 | +static int | |
11794 | +unsigned_int_compar (const void *ap, const void *bp) | |
11795 | +{ | |
11796 | + unsigned int a = *(unsigned int *) ap; | |
11797 | + unsigned int b = *(unsigned int *) bp; | |
11798 | + | |
11799 | + return (a > b) - (b > a); | |
11800 | +} | |
11801 | + | |
11802 | +static void explore_abstract_origin(struct die_info *die, struct dwarf2_cu *cu, unsigned* die_children_p){ | |
11803 | + struct attribute *attr; | |
11804 | + unsigned die_children = *die_children_p; | |
11805 | + struct die_info *child_die; | |
11806 | + | |
11807 | + attr = dwarf2_attr (die, DW_AT_abstract_origin, cu); | |
11808 | + | |
11809 | + /* GCC currently uses DW_AT_specification to indicate die inheritence | |
11810 | + in the case of import statements. The following is to accommodate that */ | |
11811 | + if(!attr){ | |
11812 | + attr = dwarf2_attr (die, DW_AT_specification, cu); | |
11813 | + } | |
11814 | + | |
11815 | + if (attr) | |
11816 | + { | |
11817 | + /* For the list of CHILD_DIEs. */ | |
11818 | + unsigned *offsets; | |
11819 | + unsigned *offsets_end, *offsetp; | |
11820 | + struct die_info *origin_die, *origin_child_die; | |
11821 | + struct cleanup *cleanups; | |
11822 | + | |
11823 | + origin_die = follow_die_ref (die, attr, &cu); | |
11824 | + if (die->tag != origin_die->tag) | |
11825 | + complaint (&symfile_complaints, | |
11826 | + _("DIE 0x%x and its abstract origin 0x%x have different " | |
11827 | + "tags"), | |
11828 | + die->offset, origin_die->offset); | |
11829 | + | |
11830 | + offsets = xmalloc (sizeof (*offsets) * die_children); | |
11831 | + cleanups = make_cleanup (xfree, offsets); | |
11832 | + | |
11833 | + offsets_end = offsets; | |
11834 | + child_die = die->child; | |
11835 | + while (child_die && child_die->tag) | |
11836 | + { | |
11837 | + attr = dwarf2_attr (child_die, DW_AT_abstract_origin, cu); | |
11838 | + if (!attr) | |
11839 | + complaint (&symfile_complaints, | |
11840 | + _("Child DIE 0x%x of DIE 0x%x has missing " | |
11841 | + "DW_AT_abstract_origin"), | |
11842 | + child_die->offset, die->offset); | |
11843 | + else | |
11844 | + { | |
11845 | + struct die_info *child_origin_die; | |
11846 | + | |
11847 | + child_origin_die = follow_die_ref (child_die, attr, &cu); | |
11848 | + if (child_die->tag != child_origin_die->tag) | |
11849 | + complaint (&symfile_complaints, | |
11850 | + _("Child DIE 0x%x and its abstract origin 0x%x have " | |
11851 | + "different tags"), | |
11852 | + child_die->offset, child_origin_die->offset); | |
11853 | + *offsets_end++ = child_origin_die->offset; | |
11854 | + } | |
11855 | + child_die = sibling_die (child_die); | |
11856 | + } | |
11857 | + qsort (offsets, offsets_end - offsets, sizeof (*offsets), | |
11858 | + unsigned_int_compar); | |
11859 | + /* Disabled as excessively expensive - check if we may ever complain. */ | |
11860 | + if (0) | |
11861 | + { | |
11862 | + for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++) | |
11863 | + if (offsetp[-1] == *offsetp) | |
11864 | + complaint (&symfile_complaints, | |
11865 | + _("Child DIEs of DIE 0x%x duplicitly abstract-origin " | |
11866 | + "referenced DIE 0x%x"), | |
11867 | + die->offset, *offsetp); | |
11868 | + } | |
11869 | + | |
11870 | + offsetp = offsets; | |
11871 | + origin_child_die = origin_die->child; | |
11872 | + while (origin_child_die && origin_child_die->tag) | |
11873 | + { | |
11874 | + /* Is origin_child_die referenced by any of the DIE children? */ | |
11875 | + while (offsetp < offsets_end && *offsetp < origin_child_die->offset) | |
11876 | + offsetp++; | |
11877 | + if (offsetp >= offsets_end || *offsetp > origin_child_die->offset) | |
11878 | + { | |
11879 | + /* Found that origin_child_die is really not referenced. */ | |
11880 | + process_die (origin_child_die, cu); | |
11881 | + } | |
11882 | + origin_child_die = sibling_die (origin_child_die); | |
11883 | + } | |
11884 | + | |
11885 | + do_cleanups (cleanups); | |
11886 | + } | |
11887 | + | |
11888 | +} | |
11889 | + | |
11890 | static void | |
11891 | read_func_scope (struct die_info *die, struct dwarf2_cu *cu) | |
11892 | { | |
11893 | @@ -3088,16 +3461,27 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) | |
11894 | char *name; | |
11895 | CORE_ADDR baseaddr; | |
11896 | struct block *block; | |
11897 | + unsigned die_children = 0; | |
11898 | ||
11899 | baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); | |
11900 | ||
11901 | - name = dwarf2_linkage_name (die, cu); | |
11902 | + name = dwarf2_name (die, cu); | |
11903 | ||
11904 | /* Ignore functions with missing or empty names and functions with | |
11905 | missing or invalid low and high pc attributes. */ | |
11906 | - if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu)) | |
11907 | + if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)){ | |
11908 | + /* explore abstract origins if present. They might contain useful information | |
11909 | + such as import statements. */ | |
11910 | + child_die = die->child; | |
11911 | + while (child_die && child_die->tag) | |
11912 | + { | |
11913 | + child_die = sibling_die (child_die); | |
11914 | + die_children++; | |
11915 | + } | |
11916 | + explore_abstract_origin(die, cu, &die_children); | |
11917 | return; | |
11918 | - | |
11919 | + } | |
11920 | + | |
11921 | lowpc += baseaddr; | |
11922 | highpc += baseaddr; | |
11923 | ||
11924 | @@ -3124,16 +3508,91 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) | |
11925 | ||
11926 | cu->list_in_scope = &local_symbols; | |
11927 | ||
11928 | - if (die->child != NULL) | |
11929 | + child_die = die->child; | |
11930 | + die_children = 0; | |
11931 | + while (child_die && child_die->tag) | |
11932 | { | |
11933 | + process_die (child_die, cu); | |
11934 | + child_die = sibling_die (child_die); | |
11935 | + die_children++; | |
11936 | + } | |
11937 | + | |
11938 | + attr = dwarf2_attr (die, DW_AT_abstract_origin, cu); | |
11939 | + if (attr) | |
11940 | + { | |
11941 | + /* For the list of CHILD_DIEs. */ | |
11942 | + unsigned *offsets; | |
11943 | + unsigned *offsets_end, *offsetp; | |
11944 | + struct die_info *origin_die, *origin_child_die; | |
11945 | + struct cleanup *cleanups; | |
11946 | + | |
11947 | + origin_die = follow_die_ref (die, attr, &cu); | |
11948 | + if (die->tag != origin_die->tag) | |
11949 | + complaint (&symfile_complaints, | |
11950 | + _("DIE 0x%x and its abstract origin 0x%x have different " | |
11951 | + "tags"), | |
11952 | + die->offset, origin_die->offset); | |
11953 | + | |
11954 | + offsets = xmalloc (sizeof (*offsets) * die_children); | |
11955 | + cleanups = make_cleanup (xfree, offsets); | |
11956 | + | |
11957 | + offsets_end = offsets; | |
11958 | child_die = die->child; | |
11959 | while (child_die && child_die->tag) | |
11960 | { | |
11961 | - process_die (child_die, cu); | |
11962 | + attr = dwarf2_attr (child_die, DW_AT_abstract_origin, cu); | |
11963 | + if (!attr) | |
11964 | + complaint (&symfile_complaints, | |
11965 | + _("Child DIE 0x%x of DIE 0x%x has missing " | |
11966 | + "DW_AT_abstract_origin"), | |
11967 | + child_die->offset, die->offset); | |
11968 | + else | |
11969 | + { | |
11970 | + struct die_info *child_origin_die; | |
11971 | + | |
11972 | + child_origin_die = follow_die_ref (child_die, attr, &cu); | |
11973 | + if (child_die->tag != child_origin_die->tag) | |
11974 | + complaint (&symfile_complaints, | |
11975 | + _("Child DIE 0x%x and its abstract origin 0x%x have " | |
11976 | + "different tags"), | |
11977 | + child_die->offset, child_origin_die->offset); | |
11978 | + *offsets_end++ = child_origin_die->offset; | |
11979 | + } | |
11980 | child_die = sibling_die (child_die); | |
11981 | } | |
11982 | + qsort (offsets, offsets_end - offsets, sizeof (*offsets), | |
11983 | + unsigned_int_compar); | |
11984 | + /* Disabled as excessively expensive - check if we may ever complain. */ | |
11985 | + if (0) | |
11986 | + { | |
11987 | + for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++) | |
11988 | + if (offsetp[-1] == *offsetp) | |
11989 | + complaint (&symfile_complaints, | |
11990 | + _("Child DIEs of DIE 0x%x duplicitly abstract-origin " | |
11991 | + "referenced DIE 0x%x"), | |
11992 | + die->offset, *offsetp); | |
11993 | + } | |
11994 | + | |
11995 | + offsetp = offsets; | |
11996 | + origin_child_die = origin_die->child; | |
11997 | + while (origin_child_die && origin_child_die->tag) | |
11998 | + { | |
11999 | + /* Is origin_child_die referenced by any of the DIE children? */ | |
12000 | + while (offsetp < offsets_end && *offsetp < origin_child_die->offset) | |
12001 | + offsetp++; | |
12002 | + if (offsetp >= offsets_end || *offsetp > origin_child_die->offset) | |
12003 | + { | |
12004 | + /* Found that origin_child_die is really not referenced. */ | |
12005 | + process_die (origin_child_die, cu); | |
12006 | + } | |
12007 | + origin_child_die = sibling_die (origin_child_die); | |
12008 | + } | |
12009 | + | |
12010 | + do_cleanups (cleanups); | |
12011 | } | |
12012 | ||
12013 | + explore_abstract_origin(die, cu, &die_children); | |
12014 | + | |
12015 | new = pop_context (); | |
12016 | /* Make a block for the local symbols within. */ | |
12017 | block = finish_block (new->name, &local_symbols, new->old_blocks, | |
12018 | @@ -3154,6 +3613,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) | |
12019 | back to building a containing block's symbol lists. */ | |
12020 | local_symbols = new->locals; | |
12021 | param_symbols = new->params; | |
12022 | + using_directives = new->using_directives; | |
12023 | ||
12024 | /* If we've finished processing a top-level function, subsequent | |
12025 | symbols go in the file symbol list. */ | |
12026 | @@ -3180,7 +3640,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) | |
12027 | as multiple lexical blocks? Handling children in a sane way would | |
12028 | be nasty. Might be easier to properly extend generic blocks to | |
12029 | describe ranges. */ | |
12030 | - if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu)) | |
12031 | + if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)) | |
12032 | return; | |
12033 | lowpc += baseaddr; | |
12034 | highpc += baseaddr; | |
12035 | @@ -3216,6 +3676,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) | |
12036 | dwarf2_record_block_ranges (die, block, baseaddr, cu); | |
12037 | } | |
12038 | local_symbols = new->locals; | |
12039 | + using_directives = new->using_directives; | |
12040 | } | |
12041 | ||
12042 | /* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET. | |
12043 | @@ -3351,7 +3812,8 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return, | |
12044 | discontinuous, i.e. derived from DW_AT_ranges information. */ | |
12045 | static int | |
12046 | dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, | |
12047 | - CORE_ADDR *highpc, struct dwarf2_cu *cu) | |
12048 | + CORE_ADDR *highpc, struct dwarf2_cu *cu, | |
12049 | + struct partial_symtab *pst) | |
12050 | { | |
12051 | struct attribute *attr; | |
12052 | CORE_ADDR low = 0; | |
12053 | @@ -3379,7 +3841,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, | |
12054 | { | |
12055 | /* Value of the DW_AT_ranges attribute is the offset in the | |
12056 | .debug_ranges section. */ | |
12057 | - if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, NULL)) | |
12058 | + if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, pst)) | |
12059 | return 0; | |
12060 | /* Found discontinuous range of addresses. */ | |
12061 | ret = -1; | |
12062 | @@ -3418,7 +3880,7 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die, | |
12063 | CORE_ADDR low, high; | |
12064 | struct die_info *child = die->child; | |
12065 | ||
12066 | - if (dwarf2_get_pc_bounds (die, &low, &high, cu)) | |
12067 | + if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL)) | |
12068 | { | |
12069 | *lowpc = min (*lowpc, low); | |
12070 | *highpc = max (*highpc, high); | |
12071 | @@ -3455,7 +3917,7 @@ get_scope_pc_bounds (struct die_info *die, | |
12072 | CORE_ADDR best_high = (CORE_ADDR) 0; | |
12073 | CORE_ADDR current_low, current_high; | |
12074 | ||
12075 | - if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu)) | |
12076 | + if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu, NULL)) | |
12077 | { | |
12078 | best_low = current_low; | |
12079 | best_high = current_high; | |
12080 | @@ -3750,8 +4212,14 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, | |
12081 | if (fieldname == NULL) | |
12082 | return; | |
12083 | ||
12084 | - /* Get physical name. */ | |
12085 | + /* Get physical name. We prefer the linkage name if one was specified, | |
12086 | + because this lets GDB find a non-debugging version of the symbol. | |
12087 | + Otherwise construct the full name from type information. Ideally, | |
12088 | + when GDB supports canonicalization of C++ symbol names, we will not | |
12089 | + need the linkage name for anything. */ | |
12090 | physname = dwarf2_linkage_name (die, cu); | |
12091 | + if (physname == NULL) | |
12092 | + physname = (char *) dwarf2_full_name (die, cu); | |
12093 | ||
12094 | /* The name is already allocated along with this objfile, so we don't | |
12095 | need to duplicate it for the type. */ | |
12096 | @@ -3881,8 +4349,14 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, | |
12097 | if (fieldname == NULL) | |
12098 | return; | |
12099 | ||
12100 | - /* Get the mangled name. */ | |
12101 | + /* Get physical name. We prefer the linkage name if one was specified, | |
12102 | + because this lets GDB find a non-debugging version of the symbol. | |
12103 | + Otherwise construct the full name from type information. Ideally, | |
12104 | + when GDB supports canonicalization of C++ symbol names, we will not | |
12105 | + need the linkage name for anything. */ | |
12106 | physname = dwarf2_linkage_name (die, cu); | |
12107 | + if (physname == NULL) | |
12108 | + physname = (char *) dwarf2_full_name (die, cu); | |
12109 | ||
12110 | /* Look up member function name in fieldlist. */ | |
12111 | for (i = 0; i < fip->nfnfields; i++) | |
12112 | @@ -3926,7 +4400,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, | |
12113 | /* The name is already allocated along with this objfile, so we don't | |
12114 | need to duplicate it for the type. */ | |
12115 | fnp->physname = physname ? physname : ""; | |
12116 | - fnp->type = alloc_type (objfile); | |
12117 | + fnp->type = alloc_type (objfile, NULL); | |
12118 | this_type = read_type_die (die, cu); | |
12119 | if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC) | |
12120 | { | |
12121 | @@ -4110,7 +4584,7 @@ quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu) | |
12122 | return NULL; | |
12123 | ||
12124 | domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0)); | |
12125 | - type = alloc_type (objfile); | |
12126 | + type = alloc_type (objfile, NULL); | |
12127 | smash_to_method_type (type, domain_type, TYPE_TARGET_TYPE (pfn_type), | |
12128 | TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type), | |
12129 | TYPE_VARARGS (pfn_type)); | |
12130 | @@ -4147,7 +4621,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) | |
12131 | if (type) | |
12132 | return type; | |
12133 | ||
12134 | - type = alloc_type (objfile); | |
12135 | + type = alloc_type (objfile, NULL); | |
12136 | INIT_CPLUS_SPECIFIC (type); | |
12137 | name = dwarf2_name (die, cu); | |
12138 | if (name != NULL) | |
12139 | @@ -4360,7 +4834,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) | |
12140 | struct attribute *attr; | |
12141 | const char *name; | |
12142 | ||
12143 | - type = alloc_type (objfile); | |
12144 | + type = alloc_type (objfile, NULL); | |
12145 | ||
12146 | TYPE_CODE (type) = TYPE_CODE_ENUM; | |
12147 | name = dwarf2_full_name (die, cu); | |
12148 | @@ -4410,10 +4884,15 @@ determine_class_name (struct die_info *die, struct dwarf2_cu *cu) | |
12149 | { | |
12150 | if (child->tag == DW_TAG_subprogram) | |
12151 | { | |
12152 | - char *phys_prefix | |
12153 | + char *phys_prefix; | |
12154 | + char *linkage_name = dwarf2_linkage_name (child, cu); | |
12155 | + | |
12156 | + if (linkage_name == NULL) | |
12157 | + continue; | |
12158 | + | |
12159 | + phys_prefix | |
12160 | = language_class_name_from_physname (cu->language_defn, | |
12161 | - dwarf2_linkage_name | |
12162 | - (child, cu)); | |
12163 | + linkage_name); | |
12164 | ||
12165 | if (phys_prefix != NULL) | |
12166 | { | |
12167 | @@ -4510,6 +4989,29 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) | |
12168 | new_symbol (die, this_type, cu); | |
12169 | } | |
12170 | ||
12171 | +/* Create a new array dimension referencing its target type TYPE. | |
12172 | + | |
12173 | + Multidimensional arrays are internally represented as a stack of | |
12174 | + singledimensional arrays being referenced by their TYPE_TARGET_TYPE. */ | |
12175 | + | |
12176 | +static struct type * | |
12177 | +create_single_array_dimension (struct type *type, struct type *range_type, | |
12178 | + struct die_info *die, struct dwarf2_cu *cu) | |
12179 | +{ | |
12180 | + type = create_array_type (NULL, type, range_type); | |
12181 | + | |
12182 | + /* These generic type attributes need to be fetched by | |
12183 | + evaluate_subexp_standard <multi_f77_subscript>'s call of | |
12184 | + value_subscripted_rvalue only for the innermost array type. */ | |
12185 | + fetch_die_type_attrs (die, type, cu); | |
12186 | + | |
12187 | + /* These generic type attributes are checked for allocated/associated | |
12188 | + validity while accessing FIELD_LOC_KIND_DWARF_BLOCK. */ | |
12189 | + fetch_die_type_attrs (die, range_type, cu); | |
12190 | + | |
12191 | + return type; | |
12192 | +} | |
12193 | + | |
12194 | /* Extract all information from a DW_TAG_array_type DIE and put it in | |
12195 | the DIE's type field. For now, this only handles one dimensional | |
12196 | arrays. */ | |
12197 | @@ -4523,7 +5025,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) | |
12198 | struct type *element_type, *range_type, *index_type; | |
12199 | struct type **range_types = NULL; | |
12200 | struct attribute *attr; | |
12201 | - int ndim = 0; | |
12202 | + int ndim = 0, i; | |
12203 | struct cleanup *back_to; | |
12204 | char *name; | |
12205 | ||
12206 | @@ -4570,16 +5072,11 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) | |
12207 | type = element_type; | |
12208 | ||
12209 | if (read_array_order (die, cu) == DW_ORD_col_major) | |
12210 | - { | |
12211 | - int i = 0; | |
12212 | - while (i < ndim) | |
12213 | - type = create_array_type (NULL, type, range_types[i++]); | |
12214 | - } | |
12215 | - else | |
12216 | - { | |
12217 | - while (ndim-- > 0) | |
12218 | - type = create_array_type (NULL, type, range_types[ndim]); | |
12219 | - } | |
12220 | + for (i = 0; i < ndim; i++) | |
12221 | + type = create_single_array_dimension (type, range_types[i], die, cu); | |
12222 | + else /* (read_array_order (die, cu) == DW_ORD_row_major) */ | |
12223 | + for (i = ndim - 1; i >= 0; i--) | |
12224 | + type = create_single_array_dimension (type, range_types[i], die, cu); | |
12225 | ||
12226 | /* Understand Dwarf2 support for vector types (like they occur on | |
12227 | the PowerPC w/ AltiVec). Gcc just adds another attribute to the | |
12228 | @@ -4646,12 +5143,14 @@ read_set_type (struct die_info *die, struct dwarf2_cu *cu) | |
12229 | return set_die_type (die, set_type, cu); | |
12230 | } | |
12231 | ||
12232 | -/* First cut: install each common block member as a global variable. */ | |
12233 | +/* Create appropriate locally-scoped variables for all the DW_TAG_common_block | |
12234 | + entries. Create also TYPE_CODE_STRUCT listing all such variables to be | |
12235 | + available for `info common'. COMMON_BLOCK_DOMAIN is used to sepate the | |
12236 | + common blocks name namespace from regular variable names. */ | |
12237 | ||
12238 | static void | |
12239 | read_common_block (struct die_info *die, struct dwarf2_cu *cu) | |
12240 | { | |
12241 | - struct die_info *child_die; | |
12242 | struct attribute *attr; | |
12243 | struct symbol *sym; | |
12244 | CORE_ADDR base = (CORE_ADDR) 0; | |
12245 | @@ -4676,10 +5175,40 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) | |
12246 | } | |
12247 | if (die->child != NULL) | |
12248 | { | |
12249 | + struct objfile *objfile = cu->objfile; | |
12250 | + struct die_info *child_die; | |
12251 | + struct type *type; | |
12252 | + struct field *field; | |
12253 | + char *name; | |
12254 | + struct symbol *sym; | |
12255 | + | |
12256 | + type = alloc_type (objfile, NULL); | |
12257 | + TYPE_CODE (type) = TYPE_CODE_STRUCT; | |
12258 | + /* Artificial type to be used only by `info common'. */ | |
12259 | + TYPE_NAME (type) = "<common>"; | |
12260 | + | |
12261 | child_die = die->child; | |
12262 | while (child_die && child_die->tag) | |
12263 | { | |
12264 | + TYPE_NFIELDS (type)++; | |
12265 | + child_die = sibling_die (child_die); | |
12266 | + } | |
12267 | + | |
12268 | + TYPE_FIELDS (type) = obstack_alloc (&objfile->objfile_obstack, | |
12269 | + sizeof (*TYPE_FIELDS (type)) | |
12270 | + * TYPE_NFIELDS (type)); | |
12271 | + memset (TYPE_FIELDS (type), 0, sizeof (*TYPE_FIELDS (type)) | |
12272 | + * TYPE_NFIELDS (type)); | |
12273 | + | |
12274 | + field = TYPE_FIELDS (type); | |
12275 | + child_die = die->child; | |
12276 | + while (child_die && child_die->tag) | |
12277 | + { | |
12278 | + /* Create the symbol in the DW_TAG_common_block block in the current | |
12279 | + symbol scope. */ | |
12280 | sym = new_symbol (child_die, NULL, cu); | |
12281 | + | |
12282 | + /* Undocumented in DWARF3, when it can be present? */ | |
12283 | attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu); | |
12284 | if (attr) | |
12285 | { | |
12286 | @@ -4687,8 +5216,25 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) | |
12287 | base + decode_locdesc (DW_BLOCK (attr), cu); | |
12288 | add_symbol_to_list (sym, &global_symbols); | |
12289 | } | |
12290 | + | |
12291 | + if (SYMBOL_CLASS (sym) == LOC_STATIC) | |
12292 | + SET_FIELD_PHYSADDR (*field, SYMBOL_VALUE_ADDRESS (sym)); | |
12293 | + else | |
12294 | + SET_FIELD_PHYSNAME (*field, SYMBOL_LINKAGE_NAME (sym)); | |
12295 | + FIELD_TYPE (*field) = SYMBOL_TYPE (sym); | |
12296 | + FIELD_NAME (*field) = SYMBOL_NATURAL_NAME (sym); | |
12297 | + field++; | |
12298 | child_die = sibling_die (child_die); | |
12299 | } | |
12300 | + | |
12301 | + /* TYPE_LENGTH (type) is left 0 - it is only a virtual structure even | |
12302 | + with no consecutive address space. */ | |
12303 | + | |
12304 | + sym = new_symbol (die, type, cu); | |
12305 | + /* SYMBOL_VALUE_ADDRESS never gets used as all its fields are static. */ | |
12306 | + SYMBOL_VALUE_ADDRESS (sym) = base; | |
12307 | + | |
12308 | + set_die_type (die, type, cu); | |
12309 | } | |
12310 | } | |
12311 | ||
12312 | @@ -4756,9 +5302,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu) | |
12313 | if (is_anonymous) | |
12314 | { | |
12315 | const char *previous_prefix = determine_prefix (die, cu); | |
12316 | - cp_add_using_directive (TYPE_NAME (type), | |
12317 | - strlen (previous_prefix), | |
12318 | - strlen (TYPE_NAME (type))); | |
12319 | + cp_add_using_directive (previous_prefix, TYPE_NAME (type), "", "", dwarf2_read_decl_line(die, cu)); | |
12320 | } | |
12321 | } | |
12322 | ||
12323 | @@ -4951,29 +5495,95 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu) | |
12324 | struct objfile *objfile = cu->objfile; | |
12325 | struct type *type, *range_type, *index_type, *char_type; | |
12326 | struct attribute *attr; | |
12327 | - unsigned int length; | |
12328 | + int length; | |
12329 | + | |
12330 | + index_type = builtin_type_int32; | |
12331 | + /* RANGE_TYPE is allocated from OBJFILE, not OBJFILE_INTERNAL. */ | |
12332 | + range_type = alloc_type (objfile, index_type); | |
12333 | + /* LOW_BOUND and HIGH_BOUND are set for real below. */ | |
12334 | + range_type = create_range_type (range_type, index_type, 0, -1); | |
12335 | + | |
12336 | + /* C/C++ should probably have the low bound 0 but C/C++ does not use | |
12337 | + DW_TAG_string_type. */ | |
12338 | + TYPE_LOW_BOUND (range_type) = 1; | |
12339 | ||
12340 | attr = dwarf2_attr (die, DW_AT_string_length, cu); | |
12341 | - if (attr) | |
12342 | - { | |
12343 | - length = DW_UNSND (attr); | |
12344 | - } | |
12345 | - else | |
12346 | - { | |
12347 | - /* check for the DW_AT_byte_size attribute */ | |
12348 | + switch (dwarf2_get_attr_constant_value (attr, &length)) | |
12349 | + { | |
12350 | + case dwarf2_attr_const: | |
12351 | + /* We currently do not support a constant address where the location | |
12352 | + should be read from - DWARF2_ATTR_BLOCK is expected instead. See | |
12353 | + DWARF for the DW_AT_STRING_LENGTH vs. DW_AT_BYTE_SIZE difference. */ | |
12354 | + /* PASSTHRU */ | |
12355 | + case dwarf2_attr_unknown: | |
12356 | attr = dwarf2_attr (die, DW_AT_byte_size, cu); | |
12357 | - if (attr) | |
12358 | - { | |
12359 | - length = DW_UNSND (attr); | |
12360 | - } | |
12361 | - else | |
12362 | - { | |
12363 | - length = 1; | |
12364 | - } | |
12365 | + switch (dwarf2_get_attr_constant_value (attr, &length)) | |
12366 | + { | |
12367 | + case dwarf2_attr_unknown: | |
12368 | + length = 1; | |
12369 | + /* PASSTHRU */ | |
12370 | + case dwarf2_attr_const: | |
12371 | + TYPE_HIGH_BOUND (range_type) = length; | |
12372 | + break; | |
12373 | + case dwarf2_attr_block: | |
12374 | + TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 1); | |
12375 | + TYPE_FIELD_DWARF_BLOCK (range_type, 1) = | |
12376 | + dwarf2_attr_to_locexpr_baton (attr, cu); | |
12377 | + TYPE_DYNAMIC (range_type) = 1; | |
12378 | + break; | |
12379 | + } | |
12380 | + break; | |
12381 | + case dwarf2_attr_block: | |
12382 | + /* Security check for a size overflow. */ | |
12383 | + if (DW_BLOCK (attr)->size + 2 < DW_BLOCK (attr)->size) | |
12384 | + { | |
12385 | + TYPE_HIGH_BOUND (range_type) = 1; | |
12386 | + break; | |
12387 | + } | |
12388 | + /* Extend the DWARF block by a new DW_OP_deref/DW_OP_deref_size | |
12389 | + instruction as DW_AT_string_length specifies the length location, not | |
12390 | + its value. */ | |
12391 | + { | |
12392 | + struct dwarf2_locexpr_baton *length_baton; | |
12393 | + struct attribute *size_attr; | |
12394 | + | |
12395 | + length_baton = obstack_alloc (&cu->comp_unit_obstack, | |
12396 | + sizeof (*length_baton)); | |
12397 | + length_baton->per_cu = cu->per_cu; | |
12398 | + length_baton->data = obstack_alloc (&cu->comp_unit_obstack, | |
12399 | + DW_BLOCK (attr)->size + 2); | |
12400 | + memcpy (length_baton->data, DW_BLOCK (attr)->data, | |
12401 | + DW_BLOCK (attr)->size); | |
12402 | + | |
12403 | + /* DW_AT_BYTE_SIZE existing together with DW_AT_STRING_LENGTH specifies | |
12404 | + the size of an integer to fetch. */ | |
12405 | + | |
12406 | + size_attr = dwarf2_attr (die, DW_AT_byte_size, cu); | |
12407 | + if (size_attr) | |
12408 | + { | |
12409 | + length_baton->size = DW_BLOCK (attr)->size + 2; | |
12410 | + length_baton->data[DW_BLOCK (attr)->size] = DW_OP_deref_size; | |
12411 | + length_baton->data[DW_BLOCK (attr)->size + 1] | |
12412 | + = DW_UNSND (size_attr); | |
12413 | + if (length_baton->data[DW_BLOCK (attr)->size + 1] | |
12414 | + != DW_UNSND (size_attr)) | |
12415 | + complaint (&symfile_complaints, | |
12416 | + _("DW_AT_string_length's DW_AT_byte_size integer " | |
12417 | + "exceeds the byte size storage")); | |
12418 | + } | |
12419 | + else | |
12420 | + { | |
12421 | + length_baton->size = DW_BLOCK (attr)->size + 1; | |
12422 | + length_baton->data[DW_BLOCK (attr)->size] = DW_OP_deref; | |
12423 | + } | |
12424 | + | |
12425 | + TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 1); | |
12426 | + TYPE_FIELD_DWARF_BLOCK (range_type, 1) = length_baton; | |
12427 | + TYPE_DYNAMIC (range_type) = 1; | |
12428 | + } | |
12429 | + break; | |
12430 | } | |
12431 | ||
12432 | - index_type = builtin_type_int32; | |
12433 | - range_type = create_range_type (NULL, index_type, 1, length); | |
12434 | type = create_string_type (NULL, range_type); | |
12435 | ||
12436 | return set_die_type (die, type, cu); | |
12437 | @@ -5067,7 +5677,6 @@ static struct type * | |
12438 | read_typedef (struct die_info *die, struct dwarf2_cu *cu) | |
12439 | { | |
12440 | struct objfile *objfile = cu->objfile; | |
12441 | - struct attribute *attr; | |
12442 | const char *name = NULL; | |
12443 | struct type *this_type; | |
12444 | ||
12445 | @@ -5175,8 +5784,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) | |
12446 | struct type *base_type; | |
12447 | struct type *range_type; | |
12448 | struct attribute *attr; | |
12449 | - int low = 0; | |
12450 | - int high = -1; | |
12451 | + int low, high, byte_stride_int; | |
12452 | + enum dwarf2_get_attr_constant_value high_type; | |
12453 | char *name; | |
12454 | ||
12455 | base_type = die_type (die, cu); | |
12456 | @@ -5189,42 +5798,90 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) | |
12457 | 0, NULL, cu->objfile); | |
12458 | } | |
12459 | ||
12460 | - if (cu->language == language_fortran) | |
12461 | - { | |
12462 | - /* FORTRAN implies a lower bound of 1, if not given. */ | |
12463 | - low = 1; | |
12464 | - } | |
12465 | + /* LOW_BOUND and HIGH_BOUND are set for real below. */ | |
12466 | + range_type = create_range_type (NULL, base_type, 0, -1); | |
12467 | ||
12468 | - /* FIXME: For variable sized arrays either of these could be | |
12469 | - a variable rather than a constant value. We'll allow it, | |
12470 | - but we don't know how to handle it. */ | |
12471 | attr = dwarf2_attr (die, DW_AT_lower_bound, cu); | |
12472 | - if (attr) | |
12473 | - low = dwarf2_get_attr_constant_value (attr, 0); | |
12474 | + switch (dwarf2_get_attr_constant_value (attr, &low)) | |
12475 | + { | |
12476 | + case dwarf2_attr_unknown: | |
12477 | + if (cu->language == language_fortran) | |
12478 | + { | |
12479 | + /* FORTRAN implies a lower bound of 1, if not given. */ | |
12480 | + low = 1; | |
12481 | + } | |
12482 | + else | |
12483 | + { | |
12484 | + /* According to DWARF we should assume the value 0 only for | |
12485 | + LANGUAGE_C and LANGUAGE_CPLUS. */ | |
12486 | + low = 0; | |
12487 | + } | |
12488 | + /* PASSTHRU */ | |
12489 | + case dwarf2_attr_const: | |
12490 | + TYPE_LOW_BOUND (range_type) = low; | |
12491 | + if (low >= 0) | |
12492 | + TYPE_UNSIGNED (range_type) = 1; | |
12493 | + break; | |
12494 | + case dwarf2_attr_block: | |
12495 | + TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 0); | |
12496 | + TYPE_FIELD_DWARF_BLOCK (range_type, 0) = dwarf2_attr_to_locexpr_baton | |
12497 | + (attr, cu); | |
12498 | + TYPE_DYNAMIC (range_type) = 1; | |
12499 | + /* For setting a default if DW_AT_UPPER_BOUND would be missing. */ | |
12500 | + low = 0; | |
12501 | + break; | |
12502 | + } | |
12503 | ||
12504 | attr = dwarf2_attr (die, DW_AT_upper_bound, cu); | |
12505 | - if (attr) | |
12506 | - { | |
12507 | - if (attr->form == DW_FORM_block1) | |
12508 | - { | |
12509 | - /* GCC encodes arrays with unspecified or dynamic length | |
12510 | - with a DW_FORM_block1 attribute. | |
12511 | - FIXME: GDB does not yet know how to handle dynamic | |
12512 | - arrays properly, treat them as arrays with unspecified | |
12513 | - length for now. | |
12514 | - | |
12515 | - FIXME: jimb/2003-09-22: GDB does not really know | |
12516 | - how to handle arrays of unspecified length | |
12517 | - either; we just represent them as zero-length | |
12518 | - arrays. Choose an appropriate upper bound given | |
12519 | - the lower bound we've computed above. */ | |
12520 | - high = low - 1; | |
12521 | - } | |
12522 | - else | |
12523 | - high = dwarf2_get_attr_constant_value (attr, 1); | |
12524 | + high_type = dwarf2_get_attr_constant_value (attr, &high); | |
12525 | + if (high_type == dwarf2_attr_unknown) | |
12526 | + { | |
12527 | + attr = dwarf2_attr (die, DW_AT_count, cu); | |
12528 | + high_type = dwarf2_get_attr_constant_value (attr, &high); | |
12529 | + /* It does not hurt but it is needlessly ineffective in check_typedef. */ | |
12530 | + if (high_type != dwarf2_attr_unknown) | |
12531 | + { | |
12532 | + TYPE_RANGE_HIGH_BOUND_IS_COUNT (range_type) = 1; | |
12533 | + TYPE_DYNAMIC (range_type) = 1; | |
12534 | + } | |
12535 | + /* Pass it now as the regular DW_AT_upper_bound. */ | |
12536 | + } | |
12537 | + switch (high_type) | |
12538 | + { | |
12539 | + case dwarf2_attr_unknown: | |
12540 | + TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (range_type) = 1; | |
12541 | + high = low - 1; | |
12542 | + /* PASSTHRU */ | |
12543 | + case dwarf2_attr_const: | |
12544 | + TYPE_HIGH_BOUND (range_type) = high; | |
12545 | + break; | |
12546 | + case dwarf2_attr_block: | |
12547 | + TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 1); | |
12548 | + TYPE_FIELD_DWARF_BLOCK (range_type, 1) = dwarf2_attr_to_locexpr_baton | |
12549 | + (attr, cu); | |
12550 | + TYPE_DYNAMIC (range_type) = 1; | |
12551 | + break; | |
12552 | } | |
12553 | ||
12554 | - range_type = create_range_type (NULL, base_type, low, high); | |
12555 | + /* DW_AT_bit_stride is currently unsupported as we count in bytes. */ | |
12556 | + attr = dwarf2_attr (die, DW_AT_byte_stride, cu); | |
12557 | + switch (dwarf2_get_attr_constant_value (attr, &byte_stride_int)) | |
12558 | + { | |
12559 | + case dwarf2_attr_unknown: | |
12560 | + break; | |
12561 | + case dwarf2_attr_const: | |
12562 | + if (byte_stride_int == 0) | |
12563 | + complaint (&symfile_complaints, | |
12564 | + _("Found DW_AT_byte_stride with unsupported value 0")); | |
12565 | + TYPE_BYTE_STRIDE (range_type) = byte_stride_int; | |
12566 | + break; | |
12567 | + case dwarf2_attr_block: | |
12568 | + TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 2); | |
12569 | + TYPE_FIELD_DWARF_BLOCK (range_type, 2) = dwarf2_attr_to_locexpr_baton | |
12570 | + (attr, cu); | |
12571 | + TYPE_DYNAMIC (range_type) = 1; | |
12572 | + break; | |
12573 | + } | |
12574 | ||
12575 | name = dwarf2_name (die, cu); | |
12576 | if (name) | |
12577 | @@ -5386,10 +6043,13 @@ read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd, | |
12578 | } | |
12579 | ||
12580 | /* Decompress a section that was compressed using zlib. Store the | |
12581 | - decompressed buffer, and its size, in OUTBUF and OUTSIZE. */ | |
12582 | + decompressed buffer, and its size, in OUTBUF and OUTSIZE. The | |
12583 | + result is allocated on OBSTACK; if OBSTACK is NULL, xmalloc is | |
12584 | + used. */ | |
12585 | ||
12586 | static void | |
12587 | -zlib_decompress_section (struct objfile *objfile, asection *sectp, | |
12588 | +zlib_decompress_section (struct objfile *objfile, struct obstack *obstack, | |
12589 | + asection *sectp, | |
12590 | gdb_byte **outbuf, bfd_size_type *outsize) | |
12591 | { | |
12592 | bfd *abfd = objfile->obfd; | |
12593 | @@ -5405,6 +6065,7 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp, | |
12594 | z_stream strm; | |
12595 | int rc; | |
12596 | int header_size = 12; | |
12597 | + struct cleanup *old = NULL; | |
12598 | ||
12599 | if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 | |
12600 | || bfd_bread (compressed_buffer, compressed_size, abfd) != compressed_size) | |
12601 | @@ -5434,8 +6095,13 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp, | |
12602 | strm.avail_in = compressed_size - header_size; | |
12603 | strm.next_in = (Bytef*) compressed_buffer + header_size; | |
12604 | strm.avail_out = uncompressed_size; | |
12605 | - uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack, | |
12606 | - uncompressed_size); | |
12607 | + if (obstack) | |
12608 | + uncompressed_buffer = obstack_alloc (obstack, uncompressed_size); | |
12609 | + else | |
12610 | + { | |
12611 | + uncompressed_buffer = xmalloc (uncompressed_size); | |
12612 | + old = make_cleanup (xfree, uncompressed_buffer); | |
12613 | + } | |
12614 | rc = inflateInit (&strm); | |
12615 | while (strm.avail_in > 0) | |
12616 | { | |
12617 | @@ -5456,6 +6122,8 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp, | |
12618 | error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"), | |
12619 | bfd_get_filename (abfd), rc); | |
12620 | ||
12621 | + if (old) | |
12622 | + discard_cleanups (old); | |
12623 | xfree (compressed_buffer); | |
12624 | *outbuf = uncompressed_buffer; | |
12625 | *outsize = uncompressed_size; | |
12626 | @@ -5463,17 +6131,20 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp, | |
12627 | } | |
12628 | ||
12629 | ||
12630 | -/* Read the contents of the section at OFFSET and of size SIZE from the | |
12631 | - object file specified by OBJFILE into the objfile_obstack and return it. | |
12632 | - If the section is compressed, uncompress it before returning. */ | |
12633 | +/* Read the contents of the section at OFFSET and of size SIZE from | |
12634 | + the object file specified by OBJFILE into OBSTACK and return it. | |
12635 | + If OBSTACK is NULL, xmalloc is used instead. If the section is | |
12636 | + compressed, uncompress it before returning. */ | |
12637 | ||
12638 | -gdb_byte * | |
12639 | -dwarf2_read_section (struct objfile *objfile, asection *sectp) | |
12640 | +static gdb_byte * | |
12641 | +dwarf2_read_section_1 (struct objfile *objfile, struct obstack *obstack, | |
12642 | + asection *sectp) | |
12643 | { | |
12644 | bfd *abfd = objfile->obfd; | |
12645 | gdb_byte *buf, *retbuf; | |
12646 | bfd_size_type size = bfd_get_section_size (sectp); | |
12647 | unsigned char header[4]; | |
12648 | + struct cleanup *old = NULL; | |
12649 | ||
12650 | if (size == 0) | |
12651 | return NULL; | |
12652 | @@ -5486,30 +6157,49 @@ dwarf2_read_section (struct objfile *objfile, asection *sectp) | |
12653 | /* Upon decompression, update the buffer and its size. */ | |
12654 | if (strncmp (header, "ZLIB", sizeof (header)) == 0) | |
12655 | { | |
12656 | - zlib_decompress_section (objfile, sectp, &buf, &size); | |
12657 | + zlib_decompress_section (objfile, obstack, sectp, &buf, &size); | |
12658 | dwarf2_resize_section (sectp, size); | |
12659 | return buf; | |
12660 | } | |
12661 | } | |
12662 | ||
12663 | /* If we get here, we are a normal, not-compressed section. */ | |
12664 | - buf = obstack_alloc (&objfile->objfile_obstack, size); | |
12665 | + if (obstack) | |
12666 | + buf = obstack_alloc (obstack, size); | |
12667 | + else | |
12668 | + { | |
12669 | + buf = xmalloc (size); | |
12670 | + old = make_cleanup (xfree, buf); | |
12671 | + } | |
12672 | /* When debugging .o files, we may need to apply relocations; see | |
12673 | http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html . | |
12674 | We never compress sections in .o files, so we only need to | |
12675 | try this when the section is not compressed. */ | |
12676 | retbuf = symfile_relocate_debug_section (abfd, sectp, buf); | |
12677 | if (retbuf != NULL) | |
12678 | - return retbuf; | |
12679 | + { | |
12680 | + if (old) | |
12681 | + discard_cleanups (old); | |
12682 | + return retbuf; | |
12683 | + } | |
12684 | ||
12685 | if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 | |
12686 | || bfd_bread (buf, size, abfd) != size) | |
12687 | error (_("Dwarf Error: Can't read DWARF data from '%s'"), | |
12688 | bfd_get_filename (abfd)); | |
12689 | ||
12690 | + if (old) | |
12691 | + discard_cleanups (old); | |
12692 | + | |
12693 | return buf; | |
12694 | } | |
12695 | ||
12696 | +gdb_byte * | |
12697 | +dwarf2_read_section (struct objfile *objfile, asection *sectp) | |
12698 | +{ | |
12699 | + return dwarf2_read_section_1 (objfile, &objfile->objfile_obstack, sectp); | |
12700 | +} | |
12701 | + | |
12702 | /* In DWARF version 2, the description of the debugging information is | |
12703 | stored in a separate .debug_abbrev section. Before we read any | |
12704 | dies from a section we read in all abbreviations and install them | |
12705 | @@ -5914,15 +6604,6 @@ read_partial_die (struct partial_die_info *part_die, | |
12706 | struct attribute attr; | |
12707 | int has_low_pc_attr = 0; | |
12708 | int has_high_pc_attr = 0; | |
12709 | - CORE_ADDR base_address = 0; | |
12710 | - enum | |
12711 | - { | |
12712 | - base_address_none, | |
12713 | - base_address_low_pc, | |
12714 | - /* Overrides BASE_ADDRESS_LOW_PC. */ | |
12715 | - base_address_entry_pc | |
12716 | - } | |
12717 | - base_address_type = base_address_none; | |
12718 | ||
12719 | memset (part_die, 0, sizeof (struct partial_die_info)); | |
12720 | ||
12721 | @@ -5945,47 +6626,35 @@ read_partial_die (struct partial_die_info *part_die, | |
12722 | switch (attr.name) | |
12723 | { | |
12724 | case DW_AT_name: | |
12725 | - | |
12726 | - /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name. */ | |
12727 | - if (part_die->name == NULL) | |
12728 | - part_die->name = DW_STRING (&attr); | |
12729 | - break; | |
12730 | - case DW_AT_comp_dir: | |
12731 | - if (part_die->dirname == NULL) | |
12732 | - part_die->dirname = DW_STRING (&attr); | |
12733 | + switch (part_die->tag) | |
12734 | + { | |
12735 | + case DW_TAG_compile_unit: | |
12736 | + /* Compilation units have a DW_AT_name that is a filename, not | |
12737 | + a source language identifier. */ | |
12738 | + case DW_TAG_enumeration_type: | |
12739 | + case DW_TAG_enumerator: | |
12740 | + /* These tags always have simple identifiers already; no need | |
12741 | + to canonicalize them. */ | |
12742 | + part_die->name = DW_STRING (&attr); | |
12743 | + break; | |
12744 | + default: | |
12745 | + part_die->name | |
12746 | + = dwarf2_canonicalize_name (DW_STRING (&attr), cu, | |
12747 | + &cu->comp_unit_obstack); | |
12748 | + break; | |
12749 | + } | |
12750 | break; | |
12751 | case DW_AT_MIPS_linkage_name: | |
12752 | - part_die->name = DW_STRING (&attr); | |
12753 | + part_die->linkage_name = DW_STRING (&attr); | |
12754 | break; | |
12755 | case DW_AT_low_pc: | |
12756 | has_low_pc_attr = 1; | |
12757 | part_die->lowpc = DW_ADDR (&attr); | |
12758 | - if (part_die->tag == DW_TAG_compile_unit | |
12759 | - && base_address_type < base_address_low_pc) | |
12760 | - { | |
12761 | - base_address = DW_ADDR (&attr); | |
12762 | - base_address_type = base_address_low_pc; | |
12763 | - } | |
12764 | break; | |
12765 | case DW_AT_high_pc: | |
12766 | has_high_pc_attr = 1; | |
12767 | part_die->highpc = DW_ADDR (&attr); | |
12768 | break; | |
12769 | - case DW_AT_entry_pc: | |
12770 | - if (part_die->tag == DW_TAG_compile_unit | |
12771 | - && base_address_type < base_address_entry_pc) | |
12772 | - { | |
12773 | - base_address = DW_ADDR (&attr); | |
12774 | - base_address_type = base_address_entry_pc; | |
12775 | - } | |
12776 | - break; | |
12777 | - case DW_AT_ranges: | |
12778 | - if (part_die->tag == DW_TAG_compile_unit) | |
12779 | - { | |
12780 | - cu->ranges_offset = DW_UNSND (&attr); | |
12781 | - cu->has_ranges_offset = 1; | |
12782 | - } | |
12783 | - break; | |
12784 | case DW_AT_location: | |
12785 | /* Support the .debug_loc offsets */ | |
12786 | if (attr_form_is_block (&attr)) | |
12787 | @@ -6002,9 +6671,6 @@ read_partial_die (struct partial_die_info *part_die, | |
12788 | "partial symbol information"); | |
12789 | } | |
12790 | break; | |
12791 | - case DW_AT_language: | |
12792 | - part_die->language = DW_UNSND (&attr); | |
12793 | - break; | |
12794 | case DW_AT_external: | |
12795 | part_die->is_external = DW_UNSND (&attr); | |
12796 | break; | |
12797 | @@ -6029,10 +6695,6 @@ read_partial_die (struct partial_die_info *part_die, | |
12798 | part_die->sibling = dwarf2_per_objfile->info_buffer | |
12799 | + dwarf2_get_ref_die_offset (&attr); | |
12800 | break; | |
12801 | - case DW_AT_stmt_list: | |
12802 | - part_die->has_stmt_list = 1; | |
12803 | - part_die->line_offset = DW_UNSND (&attr); | |
12804 | - break; | |
12805 | case DW_AT_byte_size: | |
12806 | part_die->has_byte_size = 1; | |
12807 | break; | |
12808 | @@ -6074,13 +6736,6 @@ read_partial_die (struct partial_die_info *part_die, | |
12809 | || dwarf2_per_objfile->has_section_at_zero)) | |
12810 | part_die->has_pc_info = 1; | |
12811 | ||
12812 | - if (base_address_type != base_address_none && !cu->base_known) | |
12813 | - { | |
12814 | - gdb_assert (part_die->tag == DW_TAG_compile_unit); | |
12815 | - cu->base_known = 1; | |
12816 | - cu->base_address = base_address; | |
12817 | - } | |
12818 | - | |
12819 | return info_ptr; | |
12820 | } | |
12821 | ||
12822 | @@ -6173,7 +6828,9 @@ fixup_partial_die (struct partial_die_info *part_die, | |
12823 | /* If we found a reference attribute and the DIE has no name, try | |
12824 | to find a name in the referred to DIE. */ | |
12825 | ||
12826 | - if (part_die->name == NULL && part_die->has_specification) | |
12827 | + if (part_die->has_specification | |
12828 | + && (part_die->name == NULL || part_die->linkage_name == NULL | |
12829 | + || !part_die->is_external)) | |
12830 | { | |
12831 | struct partial_die_info *spec_die; | |
12832 | ||
12833 | @@ -6189,6 +6846,9 @@ fixup_partial_die (struct partial_die_info *part_die, | |
12834 | if (spec_die->is_external) | |
12835 | part_die->is_external = spec_die->is_external; | |
12836 | } | |
12837 | + | |
12838 | + if (spec_die->linkage_name) | |
12839 | + part_die->linkage_name = spec_die->linkage_name; | |
12840 | } | |
12841 | ||
12842 | /* Set default names for some unnamed DIEs. */ | |
12843 | @@ -7512,10 +8172,12 @@ var_decode_location (struct attribute *attr, struct symbol *sym, | |
12844 | (i.e. when the value of a register or memory location is | |
12845 | referenced, or a thread-local block, etc.). Then again, it might | |
12846 | not be worthwhile. I'm assuming that it isn't unless performance | |
12847 | - or memory numbers show me otherwise. */ | |
12848 | + or memory numbers show me otherwise. | |
12849 | + | |
12850 | + SYMBOL_CLASS may get overriden by dwarf2_symbol_mark_computed. */ | |
12851 | ||
12852 | - dwarf2_symbol_mark_computed (attr, sym, cu); | |
12853 | SYMBOL_CLASS (sym) = LOC_COMPUTED; | |
12854 | + dwarf2_symbol_mark_computed (attr, sym, cu); | |
12855 | } | |
12856 | ||
12857 | /* Given a pointer to a DWARF information entry, figure out if we need | |
12858 | @@ -7538,20 +8200,43 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) | |
12859 | baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); | |
12860 | ||
12861 | if (die->tag != DW_TAG_namespace) | |
12862 | - name = dwarf2_linkage_name (die, cu); | |
12863 | + name = dwarf2_name (die, cu); | |
12864 | else | |
12865 | name = TYPE_NAME (type); | |
12866 | ||
12867 | if (name) | |
12868 | { | |
12869 | + const char *linkagename; | |
12870 | + | |
12871 | sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, | |
12872 | sizeof (struct symbol)); | |
12873 | OBJSTAT (objfile, n_syms++); | |
12874 | memset (sym, 0, sizeof (struct symbol)); | |
12875 | + /* Some methods are called without checking SYMBOL_OPS validity. */ | |
12876 | + SYMBOL_OPS (sym) = &dwarf2_missing_funcs; | |
12877 | ||
12878 | - /* Cache this symbol's name and the name's demangled form (if any). */ | |
12879 | SYMBOL_LANGUAGE (sym) = cu->language; | |
12880 | - SYMBOL_SET_NAMES (sym, name, strlen (name), objfile); | |
12881 | + | |
12882 | + /* Cache this symbol's name and the name's demangled form (if any). */ | |
12883 | + | |
12884 | + linkagename = dwarf2_linkage_name (die, cu); | |
12885 | + if (linkagename) | |
12886 | + /* We use the linkage name if available, for the same reason | |
12887 | + we used it for TYPE_FN_FIELD_PHYSNAME earlier in this file. | |
12888 | + This usage can be removed someday. */ | |
12889 | + SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), objfile); | |
12890 | + else if (die->tag == DW_TAG_namespace) | |
12891 | + SYMBOL_SET_LINKAGE_NAME (sym, name); | |
12892 | + else | |
12893 | + { | |
12894 | + linkagename = dwarf2_full_name (die, cu); | |
12895 | + | |
12896 | + /* Set just the "linkage" name to the fully qualified name. | |
12897 | + While this is not really a linkage name, it should match | |
12898 | + the demangled version of the corresponding minimal symbol | |
12899 | + if there is one. */ | |
12900 | + SYMBOL_SET_LINKAGE_NAME (sym, (char *) linkagename); | |
12901 | + } | |
12902 | ||
12903 | /* Default assumptions. | |
12904 | Use the passed type or decode it from the die. */ | |
12905 | @@ -7637,7 +8322,15 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) | |
12906 | if (attr) | |
12907 | { | |
12908 | var_decode_location (attr, sym, cu); | |
12909 | - attr2 = dwarf2_attr (die, DW_AT_external, cu); | |
12910 | + | |
12911 | + /* Fortran explicitely imports any global symbols to the local | |
12912 | + scope by DW_TAG_common_block. DW_AT_external means for | |
12913 | + Fortran the variable is importable versus it is automatically | |
12914 | + imported. */ | |
12915 | + if (cu->language == language_fortran) | |
12916 | + attr2 = NULL; | |
12917 | + else | |
12918 | + attr2 = dwarf2_attr (die, DW_AT_external, cu); | |
12919 | if (attr2 && (DW_UNSND (attr2) != 0)) | |
12920 | add_symbol_to_list (sym, &global_symbols); | |
12921 | else | |
12922 | @@ -7780,6 +8473,11 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) | |
12923 | SYMBOL_CLASS (sym) = LOC_TYPEDEF; | |
12924 | add_symbol_to_list (sym, &global_symbols); | |
12925 | break; | |
12926 | + case DW_TAG_common_block: | |
12927 | + SYMBOL_CLASS (sym) = LOC_STATIC; | |
12928 | + SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN; | |
12929 | + add_symbol_to_list (sym, cu->list_in_scope); | |
12930 | + break; | |
12931 | default: | |
12932 | /* Not a tag we recognize. Hopefully we aren't processing | |
12933 | trash data, but since we must specifically ignore things | |
12934 | @@ -8048,6 +8746,9 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu) | |
12935 | break; | |
12936 | } | |
12937 | ||
12938 | + if (this_type) | |
12939 | + finalize_type (this_type); | |
12940 | + | |
12941 | return this_type; | |
12942 | } | |
12943 | ||
12944 | @@ -8128,6 +8829,19 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu) | |
12945 | members; no typedefs, no member functions, et cetera. | |
12946 | So it does not need a prefix. */ | |
12947 | return ""; | |
12948 | + | |
12949 | + case DW_TAG_subprogram: | |
12950 | + /* A class's symbol, or a variable's symbol, will live | |
12951 | + directly in a function's block, so no prefix is | |
12952 | + appropriate. However, what about methods of a | |
12953 | + function-local class? They end up in the global symbol | |
12954 | + table because they are separate functions... their mangling | |
12955 | + normally would make them inaccessible. They'll show up | |
12956 | + wrong in breakpoints too. This is a symptom of the | |
12957 | + inconsistent way we handle symbol tables. Namespaces and | |
12958 | + classes should have dictionaries just like blocks do. */ | |
12959 | + return ""; | |
12960 | + | |
12961 | default: | |
12962 | return determine_prefix (parent, cu); | |
12963 | } | |
12964 | @@ -8192,23 +8906,62 @@ dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu) | |
12965 | attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); | |
12966 | if (attr && DW_STRING (attr)) | |
12967 | return DW_STRING (attr); | |
12968 | - attr = dwarf2_attr (die, DW_AT_name, cu); | |
12969 | - if (attr && DW_STRING (attr)) | |
12970 | - return DW_STRING (attr); | |
12971 | return NULL; | |
12972 | } | |
12973 | ||
12974 | /* Get name of a die, return NULL if not found. */ | |
12975 | ||
12976 | static char * | |
12977 | +dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu, | |
12978 | + struct obstack *obstack) | |
12979 | +{ | |
12980 | + if (cu->language == language_cplus) | |
12981 | + { | |
12982 | + char *canon_name = cp_canonicalize_string (name); | |
12983 | + | |
12984 | + if (canon_name != NULL) | |
12985 | + { | |
12986 | + if (strcmp (canon_name, name) != 0) | |
12987 | + name = obsavestring (canon_name, strlen (canon_name), | |
12988 | + obstack); | |
12989 | + xfree (canon_name); | |
12990 | + } | |
12991 | + } | |
12992 | + | |
12993 | + return name; | |
12994 | +} | |
12995 | + | |
12996 | +/* Get name of a die, return NULL if not found. */ | |
12997 | + | |
12998 | +static char * | |
12999 | dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) | |
13000 | { | |
13001 | struct attribute *attr; | |
13002 | ||
13003 | attr = dwarf2_attr (die, DW_AT_name, cu); | |
13004 | - if (attr && DW_STRING (attr)) | |
13005 | - return DW_STRING (attr); | |
13006 | - return NULL; | |
13007 | + if (!attr || !DW_STRING (attr)) | |
13008 | + return NULL; | |
13009 | + | |
13010 | + switch (die->tag) | |
13011 | + { | |
13012 | + case DW_TAG_compile_unit: | |
13013 | + /* Compilation units have a DW_AT_name that is a filename, not | |
13014 | + a source language identifier. */ | |
13015 | + case DW_TAG_enumeration_type: | |
13016 | + case DW_TAG_enumerator: | |
13017 | + /* These tags always have simple identifiers already; no need | |
13018 | + to canonicalize them. */ | |
13019 | + return DW_STRING (attr); | |
13020 | + default: | |
13021 | + if (attr->form != GDB_FORM_cached_string) | |
13022 | + { | |
13023 | + DW_STRING (attr) | |
13024 | + = dwarf2_canonicalize_name (DW_STRING (attr), cu, | |
13025 | + &cu->objfile->objfile_obstack); | |
13026 | + attr->form = GDB_FORM_cached_string; | |
13027 | + } | |
13028 | + return DW_STRING (attr); | |
13029 | + } | |
13030 | } | |
13031 | ||
13032 | /* Return the die that this die in an extension of, or NULL if there | |
13033 | @@ -8703,6 +9456,8 @@ dwarf_form_name (unsigned form) | |
13034 | return "DW_FORM_ref_udata"; | |
13035 | case DW_FORM_indirect: | |
13036 | return "DW_FORM_indirect"; | |
13037 | + case GDB_FORM_cached_string: | |
13038 | + return "GDB_FORM_cached_string"; | |
13039 | default: | |
13040 | return "DW_FORM_<unknown>"; | |
13041 | } | |
13042 | @@ -9248,6 +10003,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) | |
13043 | break; | |
13044 | case DW_FORM_string: | |
13045 | case DW_FORM_strp: | |
13046 | + case GDB_FORM_cached_string: | |
13047 | fprintf_unfiltered (f, "string: \"%s\"", | |
13048 | DW_STRING (&die->attrs[i]) | |
13049 | ? DW_STRING (&die->attrs[i]) : ""); | |
13050 | @@ -9353,26 +10109,35 @@ dwarf2_get_ref_die_offset (struct attribute *attr) | |
13051 | return result; | |
13052 | } | |
13053 | ||
13054 | -/* Return the constant value held by the given attribute. Return -1 | |
13055 | - if the value held by the attribute is not constant. */ | |
13056 | +/* (*val_return) is filled only if returning dwarf2_attr_const. */ | |
13057 | ||
13058 | -static int | |
13059 | -dwarf2_get_attr_constant_value (struct attribute *attr, int default_value) | |
13060 | +static enum dwarf2_get_attr_constant_value | |
13061 | +dwarf2_get_attr_constant_value (struct attribute *attr, int *val_return) | |
13062 | { | |
13063 | + if (attr == NULL) | |
13064 | + return dwarf2_attr_unknown; | |
13065 | if (attr->form == DW_FORM_sdata) | |
13066 | - return DW_SND (attr); | |
13067 | - else if (attr->form == DW_FORM_udata | |
13068 | - || attr->form == DW_FORM_data1 | |
13069 | - || attr->form == DW_FORM_data2 | |
13070 | - || attr->form == DW_FORM_data4 | |
13071 | - || attr->form == DW_FORM_data8) | |
13072 | - return DW_UNSND (attr); | |
13073 | - else | |
13074 | { | |
13075 | - complaint (&symfile_complaints, _("Attribute value is not a constant (%s)"), | |
13076 | - dwarf_form_name (attr->form)); | |
13077 | - return default_value; | |
13078 | + *val_return = DW_SND (attr); | |
13079 | + return dwarf2_attr_const; | |
13080 | } | |
13081 | + if (attr->form == DW_FORM_udata | |
13082 | + || attr->form == DW_FORM_data1 | |
13083 | + || attr->form == DW_FORM_data2 | |
13084 | + || attr->form == DW_FORM_data4 | |
13085 | + || attr->form == DW_FORM_data8) | |
13086 | + { | |
13087 | + *val_return = DW_UNSND (attr); | |
13088 | + return dwarf2_attr_const; | |
13089 | + } | |
13090 | + if (attr->form == DW_FORM_block | |
13091 | + || attr->form == DW_FORM_block1 | |
13092 | + || attr->form == DW_FORM_block2 | |
13093 | + || attr->form == DW_FORM_block4) | |
13094 | + return dwarf2_attr_block; | |
13095 | + complaint (&symfile_complaints, _("Attribute value is not a constant (%s)"), | |
13096 | + dwarf_form_name (attr->form)); | |
13097 | + return dwarf2_attr_unknown; | |
13098 | } | |
13099 | ||
13100 | /* THIS_CU has a reference to PER_CU. If necessary, load the new compilation | |
13101 | @@ -9963,6 +10728,17 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, | |
13102 | { | |
13103 | gdb_byte *mac_ptr, *mac_end; | |
13104 | struct macro_source_file *current_file = 0; | |
13105 | + enum dwarf_macinfo_record_type macinfo_type; | |
13106 | + | |
13107 | + /* Flag is in use by the second pass and determines if GDB is still before | |
13108 | + first DW_MACINFO_start_file. If true GDB is still reading the definitions | |
13109 | + from command line. First DW_MACINFO_start_file will need to be ignored as | |
13110 | + it was already executed to create CURRENT_FILE for the main source holding | |
13111 | + also the command line definitions. On first met DW_MACINFO_start_file | |
13112 | + this flag is reset to normally execute all the remaining | |
13113 | + DW_MACINFO_start_file macinfos. */ | |
13114 | + | |
13115 | + int at_commandline; | |
13116 | ||
13117 | if (dwarf2_per_objfile->macinfo_buffer == NULL) | |
13118 | { | |
13119 | @@ -9970,19 +10746,24 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, | |
13120 | return; | |
13121 | } | |
13122 | ||
13123 | + /* Start the first pass to find ahead the main source file name. GDB has to | |
13124 | + create CURRENT_FILE where to place the macros given to the compiler | |
13125 | + from the command line. Such command line macros are present before first | |
13126 | + DW_MACINFO_start_file but still those macros are associated to the | |
13127 | + compilation unit. The compilation unit GDB identifies by its main source | |
13128 | + file name. */ | |
13129 | + | |
13130 | mac_ptr = dwarf2_per_objfile->macinfo_buffer + offset; | |
13131 | mac_end = dwarf2_per_objfile->macinfo_buffer | |
13132 | + dwarf2_per_objfile->macinfo_size; | |
13133 | ||
13134 | - for (;;) | |
13135 | + do | |
13136 | { | |
13137 | - enum dwarf_macinfo_record_type macinfo_type; | |
13138 | - | |
13139 | /* Do we at least have room for a macinfo type byte? */ | |
13140 | if (mac_ptr >= mac_end) | |
13141 | { | |
13142 | dwarf2_macros_too_long_complaint (); | |
13143 | - return; | |
13144 | + break; | |
13145 | } | |
13146 | ||
13147 | macinfo_type = read_1_byte (abfd, mac_ptr); | |
13148 | @@ -9993,7 +10774,81 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, | |
13149 | /* A zero macinfo type indicates the end of the macro | |
13150 | information. */ | |
13151 | case 0: | |
13152 | - return; | |
13153 | + break; | |
13154 | + | |
13155 | + case DW_MACINFO_define: | |
13156 | + case DW_MACINFO_undef: | |
13157 | + /* Only skip the data by MAC_PTR. */ | |
13158 | + { | |
13159 | + unsigned int bytes_read; | |
13160 | + | |
13161 | + read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); | |
13162 | + mac_ptr += bytes_read; | |
13163 | + read_string (abfd, mac_ptr, &bytes_read); | |
13164 | + mac_ptr += bytes_read; | |
13165 | + } | |
13166 | + break; | |
13167 | + | |
13168 | + case DW_MACINFO_start_file: | |
13169 | + { | |
13170 | + unsigned int bytes_read; | |
13171 | + int line, file; | |
13172 | + | |
13173 | + line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); | |
13174 | + mac_ptr += bytes_read; | |
13175 | + file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); | |
13176 | + mac_ptr += bytes_read; | |
13177 | + | |
13178 | + current_file = macro_start_file (file, line, current_file, comp_dir, | |
13179 | + lh, cu->objfile); | |
13180 | + } | |
13181 | + break; | |
13182 | + | |
13183 | + case DW_MACINFO_end_file: | |
13184 | + /* No data to skip by MAC_PTR. */ | |
13185 | + break; | |
13186 | + | |
13187 | + case DW_MACINFO_vendor_ext: | |
13188 | + /* Only skip the data by MAC_PTR. */ | |
13189 | + { | |
13190 | + unsigned int bytes_read; | |
13191 | + | |
13192 | + read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); | |
13193 | + mac_ptr += bytes_read; | |
13194 | + read_string (abfd, mac_ptr, &bytes_read); | |
13195 | + mac_ptr += bytes_read; | |
13196 | + } | |
13197 | + break; | |
13198 | + | |
13199 | + default: | |
13200 | + break; | |
13201 | + } | |
13202 | + } while (macinfo_type != 0 && current_file == NULL); | |
13203 | + | |
13204 | + /* Here is the second pass to read in the macros starting from the ones | |
13205 | + defined at the command line. */ | |
13206 | + | |
13207 | + mac_ptr = dwarf2_per_objfile->macinfo_buffer + offset; | |
13208 | + at_commandline = 1; | |
13209 | + | |
13210 | + do | |
13211 | + { | |
13212 | + /* Do we at least have room for a macinfo type byte? */ | |
13213 | + if (mac_ptr >= mac_end) | |
13214 | + { | |
13215 | + /* Complaint is in the first pass above. */ | |
13216 | + break; | |
13217 | + } | |
13218 | + | |
13219 | + macinfo_type = read_1_byte (abfd, mac_ptr); | |
13220 | + mac_ptr++; | |
13221 | + | |
13222 | + switch (macinfo_type) | |
13223 | + { | |
13224 | + /* A zero macinfo type indicates the end of the macro | |
13225 | + information. */ | |
13226 | + case 0: | |
13227 | + break; | |
13228 | ||
13229 | case DW_MACINFO_define: | |
13230 | case DW_MACINFO_undef: | |
13231 | @@ -10008,19 +10863,31 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, | |
13232 | mac_ptr += bytes_read; | |
13233 | ||
13234 | if (! current_file) | |
13235 | + { | |
13236 | + /* DWARF violation as no main source is present. */ | |
13237 | + complaint (&symfile_complaints, | |
13238 | + _("debug info with no main source gives macro %s " | |
13239 | + "on line %d: %s"), | |
13240 | + macinfo_type == | |
13241 | + DW_MACINFO_define ? _("definition") : macinfo_type == | |
13242 | + DW_MACINFO_undef ? _("undefinition") : | |
13243 | + "something-or-other", line, body); | |
13244 | + break; | |
13245 | + } | |
13246 | + if (at_commandline != (line == 0)) | |
13247 | complaint (&symfile_complaints, | |
13248 | - _("debug info gives macro %s outside of any file: %s"), | |
13249 | + _("debug info gives %s macro %s with %s line %d: %s"), | |
13250 | + at_commandline ? _("command-line") : _("in-file"), | |
13251 | macinfo_type == | |
13252 | - DW_MACINFO_define ? "definition" : macinfo_type == | |
13253 | - DW_MACINFO_undef ? "undefinition" : | |
13254 | - "something-or-other", body); | |
13255 | - else | |
13256 | - { | |
13257 | - if (macinfo_type == DW_MACINFO_define) | |
13258 | - parse_macro_definition (current_file, line, body); | |
13259 | - else if (macinfo_type == DW_MACINFO_undef) | |
13260 | - macro_undef (current_file, line, body); | |
13261 | - } | |
13262 | + DW_MACINFO_define ? _("definition") : macinfo_type == | |
13263 | + DW_MACINFO_undef ? _("undefinition") : | |
13264 | + "something-or-other", | |
13265 | + line == 0 ? _("zero") : _("non-zero"), line, body); | |
13266 | + | |
13267 | + if (macinfo_type == DW_MACINFO_define) | |
13268 | + parse_macro_definition (current_file, line, body); | |
13269 | + else if (macinfo_type == DW_MACINFO_undef) | |
13270 | + macro_undef (current_file, line, body); | |
13271 | } | |
13272 | break; | |
13273 | ||
13274 | @@ -10034,9 +10901,22 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, | |
13275 | file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); | |
13276 | mac_ptr += bytes_read; | |
13277 | ||
13278 | - current_file = macro_start_file (file, line, | |
13279 | - current_file, comp_dir, | |
13280 | - lh, cu->objfile); | |
13281 | + if (at_commandline != (line == 0)) | |
13282 | + complaint (&symfile_complaints, | |
13283 | + _("debug info gives source %d included " | |
13284 | + "from %s at %s line %d"), | |
13285 | + file, at_commandline ? _("command-line") : _("file"), | |
13286 | + line == 0 ? _("zero") : _("non-zero"), line); | |
13287 | + | |
13288 | + if (at_commandline) | |
13289 | + { | |
13290 | + /* This DW_MACINFO_start_file was executed in the pass one. */ | |
13291 | + at_commandline = 0; | |
13292 | + } | |
13293 | + else | |
13294 | + current_file = macro_start_file (file, line, | |
13295 | + current_file, comp_dir, | |
13296 | + lh, cu->objfile); | |
13297 | } | |
13298 | break; | |
13299 | ||
13300 | @@ -10090,7 +10970,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, | |
13301 | } | |
13302 | break; | |
13303 | } | |
13304 | - } | |
13305 | + } while (macinfo_type != 0); | |
13306 | } | |
13307 | ||
13308 | /* Check if the attribute's form is a DW_FORM_block* | |
13309 | @@ -10150,6 +11030,34 @@ attr_form_is_constant (struct attribute *attr) | |
13310 | } | |
13311 | } | |
13312 | ||
13313 | +/* Convert DW_BLOCK into struct dwarf2_locexpr_baton. ATTR must be a DW_BLOCK | |
13314 | + attribute type. */ | |
13315 | + | |
13316 | +static struct dwarf2_locexpr_baton * | |
13317 | +dwarf2_attr_to_locexpr_baton (struct attribute *attr, struct dwarf2_cu *cu) | |
13318 | +{ | |
13319 | + struct dwarf2_locexpr_baton *baton; | |
13320 | + | |
13321 | + gdb_assert (attr_form_is_block (attr)); | |
13322 | + | |
13323 | + baton = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (*baton)); | |
13324 | + baton->per_cu = cu->per_cu; | |
13325 | + gdb_assert (baton->per_cu); | |
13326 | + | |
13327 | + /* Note that we're just copying the block's data pointer | |
13328 | + here, not the actual data. We're still pointing into the | |
13329 | + info_buffer for SYM's objfile; right now we never release | |
13330 | + that buffer, but when we do clean up properly this may | |
13331 | + need to change. */ | |
13332 | + baton->size = DW_BLOCK (attr)->size; | |
13333 | + baton->data = DW_BLOCK (attr)->data; | |
13334 | + gdb_assert (baton->size == 0 || baton->data != NULL); | |
13335 | + | |
13336 | + return baton; | |
13337 | +} | |
13338 | + | |
13339 | +/* SYM may get its SYMBOL_CLASS overriden on invalid ATTR content. */ | |
13340 | + | |
13341 | static void | |
13342 | dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, | |
13343 | struct dwarf2_cu *cu) | |
13344 | @@ -10179,35 +11087,24 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, | |
13345 | SYMBOL_OPS (sym) = &dwarf2_loclist_funcs; | |
13346 | SYMBOL_LOCATION_BATON (sym) = baton; | |
13347 | } | |
13348 | + else if (attr_form_is_block (attr)) | |
13349 | + { | |
13350 | + SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs; | |
13351 | + SYMBOL_LOCATION_BATON (sym) = dwarf2_attr_to_locexpr_baton (attr, cu); | |
13352 | + } | |
13353 | else | |
13354 | { | |
13355 | - struct dwarf2_locexpr_baton *baton; | |
13356 | + dwarf2_invalid_attrib_class_complaint ("location description", | |
13357 | + SYMBOL_NATURAL_NAME (sym)); | |
13358 | ||
13359 | - baton = obstack_alloc (&cu->objfile->objfile_obstack, | |
13360 | - sizeof (struct dwarf2_locexpr_baton)); | |
13361 | - baton->per_cu = cu->per_cu; | |
13362 | - gdb_assert (baton->per_cu); | |
13363 | + /* Some methods are called without checking SYMBOL_OPS validity. */ | |
13364 | + SYMBOL_OPS (sym) = &dwarf2_missing_funcs; | |
13365 | + SYMBOL_LOCATION_BATON (sym) = NULL; | |
13366 | ||
13367 | - if (attr_form_is_block (attr)) | |
13368 | - { | |
13369 | - /* Note that we're just copying the block's data pointer | |
13370 | - here, not the actual data. We're still pointing into the | |
13371 | - info_buffer for SYM's objfile; right now we never release | |
13372 | - that buffer, but when we do clean up properly this may | |
13373 | - need to change. */ | |
13374 | - baton->size = DW_BLOCK (attr)->size; | |
13375 | - baton->data = DW_BLOCK (attr)->data; | |
13376 | - } | |
13377 | - else | |
13378 | - { | |
13379 | - dwarf2_invalid_attrib_class_complaint ("location description", | |
13380 | - SYMBOL_NATURAL_NAME (sym)); | |
13381 | - baton->size = 0; | |
13382 | - baton->data = NULL; | |
13383 | - } | |
13384 | - | |
13385 | - SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs; | |
13386 | - SYMBOL_LOCATION_BATON (sym) = baton; | |
13387 | + /* For functions a missing DW_AT_frame_base does not optimize out the | |
13388 | + whole function definition, only its frame base resolving. */ | |
13389 | + if (attr->name == DW_AT_location) | |
13390 | + SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; | |
13391 | } | |
13392 | } | |
13393 | ||
13394 | @@ -10482,6 +11379,31 @@ offset_and_type_eq (const void *item_lhs, const void *item_rhs) | |
13395 | return ofs_lhs->offset == ofs_rhs->offset; | |
13396 | } | |
13397 | ||
13398 | +/* Fill in generic attributes applicable for type DIEs. */ | |
13399 | + | |
13400 | +static void | |
13401 | +fetch_die_type_attrs (struct die_info *die, struct type *type, | |
13402 | + struct dwarf2_cu *cu) | |
13403 | +{ | |
13404 | + struct attribute *attr; | |
13405 | + | |
13406 | + attr = dwarf2_attr (die, DW_AT_data_location, cu); | |
13407 | + if (attr_form_is_block (attr)) | |
13408 | + TYPE_DATA_LOCATION_DWARF_BLOCK (type) = dwarf2_attr_to_locexpr_baton (attr, | |
13409 | + cu); | |
13410 | + gdb_assert (!TYPE_DATA_LOCATION_IS_ADDR (type)); | |
13411 | + | |
13412 | + attr = dwarf2_attr (die, DW_AT_allocated, cu); | |
13413 | + if (attr_form_is_block (attr)) | |
13414 | + TYPE_ALLOCATED (type) = dwarf2_attr_to_locexpr_baton (attr, cu); | |
13415 | + gdb_assert (!TYPE_NOT_ALLOCATED (type)); | |
13416 | + | |
13417 | + attr = dwarf2_attr (die, DW_AT_associated, cu); | |
13418 | + if (attr_form_is_block (attr)) | |
13419 | + TYPE_ASSOCIATED (type) = dwarf2_attr_to_locexpr_baton (attr, cu); | |
13420 | + gdb_assert (!TYPE_NOT_ASSOCIATED (type)); | |
13421 | +} | |
13422 | + | |
13423 | /* Set the type associated with DIE to TYPE. Save it in CU's hash | |
13424 | table if necessary. For convenience, return TYPE. */ | |
13425 | ||
13426 | @@ -10490,6 +11412,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) | |
13427 | { | |
13428 | struct dwarf2_offset_and_type **slot, ofs; | |
13429 | ||
13430 | + fetch_die_type_attrs (die, type, cu); | |
13431 | + | |
13432 | if (cu->type_hash == NULL) | |
13433 | { | |
13434 | gdb_assert (cu->per_cu != NULL); | |
13435 | diff --git a/gdb/elfread.c b/gdb/elfread.c | |
13436 | index ff220a2..13158f4 100644 | |
13437 | --- a/gdb/elfread.c | |
13438 | +++ b/gdb/elfread.c | |
13439 | @@ -727,10 +727,18 @@ elf_symfile_read (struct objfile *objfile, int mainline) | |
13440 | str_sect->filepos, | |
13441 | bfd_section_size (abfd, str_sect)); | |
13442 | } | |
13443 | + | |
13444 | + if (dwarf2_has_info (objfile)) | |
13445 | + dwarf2_create_quick_addrmap (objfile); | |
13446 | +} | |
13447 | + | |
13448 | +static void | |
13449 | +read_psyms (struct objfile *objfile) | |
13450 | +{ | |
13451 | if (dwarf2_has_info (objfile)) | |
13452 | { | |
13453 | /* DWARF 2 sections */ | |
13454 | - dwarf2_build_psymtabs (objfile, mainline); | |
13455 | + dwarf2_build_psymtabs (objfile, 0); | |
13456 | } | |
13457 | ||
13458 | /* FIXME: kettenis/20030504: This still needs to be integrated with | |
13459 | @@ -880,6 +888,7 @@ static struct sym_fns elf_sym_fns = | |
13460 | elf_new_init, /* sym_new_init: init anything gbl to entire symtab */ | |
13461 | elf_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
13462 | elf_symfile_read, /* sym_read: read a symbol file into symtab */ | |
13463 | + read_psyms, /* sym_read_psymbols */ | |
13464 | elf_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
13465 | default_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */ | |
13466 | elf_symfile_segments, /* sym_segments: Get segment information from | |
13467 | diff --git a/gdb/eval.c b/gdb/eval.c | |
13468 | index 1d35571..6a97e09 100644 | |
13469 | --- a/gdb/eval.c | |
13470 | +++ b/gdb/eval.c | |
13471 | @@ -39,10 +39,16 @@ | |
13472 | #include "exceptions.h" | |
13473 | #include "regcache.h" | |
13474 | #include "user-regs.h" | |
13475 | +#include "python/python.h" | |
13476 | #include "valprint.h" | |
13477 | +#include "dwarf2loc.h" | |
13478 | +#include "gdb_obstack.h" | |
13479 | +#include "objfiles.h" | |
13480 | ||
13481 | #include "gdb_assert.h" | |
13482 | ||
13483 | +#include <ctype.h> | |
13484 | + | |
13485 | /* This is defined in valops.c */ | |
13486 | extern int overload_resolution; | |
13487 | ||
13488 | @@ -651,6 +657,64 @@ ptrmath_type_p (struct type *type) | |
13489 | } | |
13490 | } | |
13491 | ||
13492 | +/* Compares the two method/function types T1 and T2 for "equality" | |
13493 | + with respect to the the methods' parameters. If the types of the | |
13494 | + two parameter lists are the same, returns 1; 0 otherwise. This | |
13495 | + comparison ignores any artificial this pointer. */ | |
13496 | +int | |
13497 | +compare_parameters (struct type *t1, struct type *t2) | |
13498 | +{ | |
13499 | + int i, has_this; | |
13500 | + /* Hacky: we don't know a priori whether or not t1 is a static | |
13501 | + method, so we skip any artificial "this" pointer and hope | |
13502 | + for the best. t2, which comes as user input, never contains a | |
13503 | + "this" pointer (a user would never enter it into expressions. */ | |
13504 | + if (TYPE_NFIELDS (t1) > 0) | |
13505 | + has_this = TYPE_FIELD_ARTIFICIAL (t1, 0) ? 1 : 0; | |
13506 | + else | |
13507 | + has_this = 0; | |
13508 | + | |
13509 | + /* Special case: a method taking void. t1 will contain either | |
13510 | + no fields or just "this". t2 will contain TYPE_CODE_VOID. */ | |
13511 | + if ((TYPE_NFIELDS (t1) - has_this) == 0 && TYPE_NFIELDS (t2) == 1 | |
13512 | + && TYPE_CODE (TYPE_FIELD_TYPE (t2, 0)) == TYPE_CODE_VOID) | |
13513 | + return 1; | |
13514 | + | |
13515 | + if ((TYPE_NFIELDS (t1) - has_this) == TYPE_NFIELDS (t2)) | |
13516 | + { | |
13517 | + for (i = has_this; i < TYPE_NFIELDS (t1); ++i) | |
13518 | + { | |
13519 | + if (rank_one_type (TYPE_FIELD_TYPE (t1, i), | |
13520 | + TYPE_FIELD_TYPE (t2, i - has_this)) | |
13521 | + != 0) | |
13522 | + return 0; | |
13523 | + } | |
13524 | + | |
13525 | + return 1; | |
13526 | + } | |
13527 | + | |
13528 | + return 0; | |
13529 | +} | |
13530 | + | |
13531 | +/* Constructs a fake method with the given parameter types. */ | |
13532 | + | |
13533 | +static struct type * | |
13534 | +make_params (int num_types, struct type **param_types) | |
13535 | +{ | |
13536 | + struct type *type = alloc_type (NULL, NULL); | |
13537 | + TYPE_LENGTH (type) = 1; | |
13538 | + TYPE_CODE (type) = TYPE_CODE_METHOD; | |
13539 | + TYPE_NFIELDS (type) = num_types; | |
13540 | + TYPE_FIELDS (type) = (struct field *) | |
13541 | + TYPE_ALLOC (type, sizeof (struct field) * num_types); | |
13542 | + memset (TYPE_FIELDS (type), 0, sizeof (struct field) * num_types); | |
13543 | + | |
13544 | + while (num_types-- > 0) | |
13545 | + TYPE_FIELD_TYPE (type, num_types) = param_types[num_types]; | |
13546 | + | |
13547 | + return type; | |
13548 | +} | |
13549 | + | |
13550 | struct value * | |
13551 | evaluate_subexp_standard (struct type *expect_type, | |
13552 | struct expression *exp, int *pos, | |
13553 | @@ -671,6 +735,7 @@ evaluate_subexp_standard (struct type *expect_type, | |
13554 | long mem_offset; | |
13555 | struct type **arg_types; | |
13556 | int save_pos1; | |
13557 | + struct cleanup *old_chain; | |
13558 | ||
13559 | pc = (*pos)++; | |
13560 | op = exp->elts[pc].opcode; | |
13561 | @@ -684,7 +749,7 @@ evaluate_subexp_standard (struct type *expect_type, | |
13562 | goto nosideret; | |
13563 | arg1 = value_aggregate_elt (exp->elts[pc + 1].type, | |
13564 | &exp->elts[pc + 3].string, | |
13565 | - 0, noside); | |
13566 | + expect_type, 0, noside); | |
13567 | if (arg1 == NULL) | |
13568 | error (_("There is no field named %s"), &exp->elts[pc + 3].string); | |
13569 | return arg1; | |
13570 | @@ -1208,9 +1273,9 @@ evaluate_subexp_standard (struct type *expect_type, | |
13571 | if (TYPE_CODE (value_type (method)) != TYPE_CODE_FUNC) | |
13572 | error (_("method address has symbol information with non-function type; skipping")); | |
13573 | if (struct_return) | |
13574 | - VALUE_ADDRESS (method) = value_as_address (msg_send_stret); | |
13575 | + set_value_address (method, value_as_address (msg_send_stret)); | |
13576 | else | |
13577 | - VALUE_ADDRESS (method) = value_as_address (msg_send); | |
13578 | + set_value_address (method, value_as_address (msg_send)); | |
13579 | called_method = method; | |
13580 | } | |
13581 | else | |
13582 | @@ -1284,7 +1349,6 @@ evaluate_subexp_standard (struct type *expect_type, | |
13583 | argvec = (struct value **) alloca (sizeof (struct value *) * (nargs + 3)); | |
13584 | if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) | |
13585 | { | |
13586 | - nargs++; | |
13587 | /* First, evaluate the structure into arg2 */ | |
13588 | pc2 = (*pos)++; | |
13589 | ||
13590 | @@ -1308,21 +1372,40 @@ evaluate_subexp_standard (struct type *expect_type, | |
13591 | ||
13592 | arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); | |
13593 | ||
13594 | - if (TYPE_CODE (check_typedef (value_type (arg1))) | |
13595 | - != TYPE_CODE_METHODPTR) | |
13596 | - error (_("Non-pointer-to-member value used in pointer-to-member " | |
13597 | - "construct")); | |
13598 | - | |
13599 | - if (noside == EVAL_AVOID_SIDE_EFFECTS) | |
13600 | + type = check_typedef (value_type (arg1)); | |
13601 | + switch (TYPE_CODE (type)) | |
13602 | { | |
13603 | - struct type *method_type = check_typedef (value_type (arg1)); | |
13604 | - arg1 = value_zero (method_type, not_lval); | |
13605 | + case TYPE_CODE_METHODPTR: | |
13606 | + if (noside == EVAL_AVOID_SIDE_EFFECTS) | |
13607 | + arg1 = value_zero (TYPE_TARGET_TYPE (type), not_lval); | |
13608 | + else | |
13609 | + arg1 = cplus_method_ptr_to_value (&arg2, arg1); | |
13610 | + | |
13611 | + /* Now, say which argument to start evaluating from */ | |
13612 | + nargs++; | |
13613 | + tem = 2; | |
13614 | + argvec[1] = arg2; | |
13615 | + break; | |
13616 | + | |
13617 | + case TYPE_CODE_MEMBERPTR: | |
13618 | + /* Now, convert these values to an address. */ | |
13619 | + arg2 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)), | |
13620 | + arg2); | |
13621 | + | |
13622 | + mem_offset = value_as_long (arg1); | |
13623 | + | |
13624 | + arg1 = value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)), | |
13625 | + value_as_long (arg2) + mem_offset); | |
13626 | + arg1 = value_ind (arg1); | |
13627 | + tem = 1; | |
13628 | + break; | |
13629 | + | |
13630 | + default: | |
13631 | + error (_("Non-pointer-to-member value used in pointer-to-member " | |
13632 | + "construct")); | |
13633 | } | |
13634 | - else | |
13635 | - arg1 = cplus_method_ptr_to_value (&arg2, arg1); | |
13636 | ||
13637 | - /* Now, say which argument to start evaluating from */ | |
13638 | - tem = 2; | |
13639 | + argvec[0] = arg1; | |
13640 | } | |
13641 | else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) | |
13642 | { | |
13643 | @@ -1434,7 +1517,7 @@ evaluate_subexp_standard (struct type *expect_type, | |
13644 | of the ``this'' pointer if necessary, so modify argvec[1] to | |
13645 | reflect any ``this'' changes. */ | |
13646 | arg2 = value_from_longest (lookup_pointer_type(value_type (temp)), | |
13647 | - VALUE_ADDRESS (temp) + value_offset (temp) | |
13648 | + value_address (temp) | |
13649 | + value_embedded_offset (temp)); | |
13650 | argvec[1] = arg2; /* the ``this'' pointer */ | |
13651 | } | |
13652 | @@ -1448,8 +1531,7 @@ evaluate_subexp_standard (struct type *expect_type, | |
13653 | } | |
13654 | else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) | |
13655 | { | |
13656 | - argvec[1] = arg2; | |
13657 | - argvec[0] = arg1; | |
13658 | + /* Pointer to member. argvec is already set up. */ | |
13659 | } | |
13660 | else if (op == OP_VAR_VALUE) | |
13661 | { | |
13662 | @@ -1512,6 +1594,9 @@ evaluate_subexp_standard (struct type *expect_type, | |
13663 | else | |
13664 | error (_("Expression of type other than \"Function returning ...\" used as function")); | |
13665 | } | |
13666 | + if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_INTERNAL_FUNCTION) | |
13667 | + return call_internal_function (argvec[0], nargs, argvec + 1); | |
13668 | + | |
13669 | return call_function_by_hand (argvec[0], nargs, argvec + 1); | |
13670 | /* pai: FIXME save value from call_function_by_hand, then adjust pc by adjust_fn_pc if +ve */ | |
13671 | ||
13672 | @@ -1529,7 +1614,10 @@ evaluate_subexp_standard (struct type *expect_type, | |
13673 | ||
13674 | /* First determine the type code we are dealing with. */ | |
13675 | arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); | |
13676 | + old_chain = make_cleanup (null_cleanup, 0); | |
13677 | + object_address_set (VALUE_ADDRESS (arg1)); | |
13678 | type = check_typedef (value_type (arg1)); | |
13679 | + do_cleanups (old_chain); | |
13680 | code = TYPE_CODE (type); | |
13681 | ||
13682 | if (code == TYPE_CODE_PTR) | |
13683 | @@ -1696,6 +1784,37 @@ evaluate_subexp_standard (struct type *expect_type, | |
13684 | error (_("non-pointer-to-member value used in pointer-to-member construct")); | |
13685 | } | |
13686 | ||
13687 | + case TYPE_INSTANCE: | |
13688 | + nargs = longest_to_int (exp->elts[pc + 1].longconst); | |
13689 | + arg_types = (struct type **) alloca (nargs * sizeof (struct type *)); | |
13690 | + for (ix = 0; ix < nargs; ++ix) | |
13691 | + arg_types[ix] = exp->elts[pc + 1 + ix + 1].type; | |
13692 | + | |
13693 | + expect_type = make_params (nargs, arg_types); | |
13694 | + *(pos) += 3 + nargs; | |
13695 | + return evaluate_subexp_standard (expect_type, exp, pos, noside); | |
13696 | + | |
13697 | + case TYPE_INSTANCE_LOOKUP: | |
13698 | + { | |
13699 | + int i; | |
13700 | + struct symbol *sym; | |
13701 | + struct type **arg_types; | |
13702 | + (*pos) += 3; | |
13703 | + printf ("TYPE_INSTANCE_LOOKUP\n"); | |
13704 | + arg_types = (struct type **) alloca (TYPE_NFIELDS (expect_type) | |
13705 | + * sizeof (struct type *)); | |
13706 | + for (i = 0; i < TYPE_NFIELDS (expect_type); ++i) | |
13707 | + arg_types[i] = TYPE_FIELD_TYPE (expect_type, i); | |
13708 | + (void) find_overload_match (arg_types, TYPE_NFIELDS (expect_type), | |
13709 | + NULL /* no need for name */, | |
13710 | + 0 /* not method */, | |
13711 | + 0 /* strict match */, | |
13712 | + NULL, exp->elts[pc + 1].symbol, NULL, | |
13713 | + &sym, NULL); | |
13714 | + i = 0; | |
13715 | + } | |
13716 | + break; | |
13717 | + | |
13718 | case BINOP_CONCAT: | |
13719 | arg1 = evaluate_subexp_with_coercion (exp, pos, noside); | |
13720 | arg2 = evaluate_subexp_with_coercion (exp, pos, noside); | |
13721 | @@ -1963,13 +2082,19 @@ evaluate_subexp_standard (struct type *expect_type, | |
13722 | { | |
13723 | int subscript_array[MAX_FORTRAN_DIMS]; | |
13724 | int array_size_array[MAX_FORTRAN_DIMS]; | |
13725 | + int byte_stride_array[MAX_FORTRAN_DIMS]; | |
13726 | int ndimensions = 1, i; | |
13727 | struct type *tmp_type; | |
13728 | int offset_item; /* The array offset where the item lives */ | |
13729 | + CORE_ADDR offset_byte; /* byte_stride based offset */ | |
13730 | + unsigned element_size; | |
13731 | ||
13732 | if (nargs > MAX_FORTRAN_DIMS) | |
13733 | error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS); | |
13734 | ||
13735 | + old_chain = make_cleanup (null_cleanup, 0); | |
13736 | + object_address_set (VALUE_ADDRESS (arg1)); | |
13737 | + | |
13738 | tmp_type = check_typedef (value_type (arg1)); | |
13739 | ndimensions = calc_f77_array_dims (type); | |
13740 | ||
13741 | @@ -1999,6 +2124,9 @@ evaluate_subexp_standard (struct type *expect_type, | |
13742 | upper = f77_get_upperbound (tmp_type); | |
13743 | lower = f77_get_lowerbound (tmp_type); | |
13744 | ||
13745 | + byte_stride_array[nargs - i - 1] = | |
13746 | + TYPE_ARRAY_BYTE_STRIDE_VALUE (tmp_type); | |
13747 | + | |
13748 | array_size_array[nargs - i - 1] = upper - lower + 1; | |
13749 | ||
13750 | /* Zero-normalize subscripts so that offsetting will work. */ | |
13751 | @@ -2017,17 +2145,25 @@ evaluate_subexp_standard (struct type *expect_type, | |
13752 | tmp_type = check_typedef (TYPE_TARGET_TYPE (tmp_type)); | |
13753 | } | |
13754 | ||
13755 | - /* Now let us calculate the offset for this item */ | |
13756 | + /* Kept for the f77_get_upperbound / f77_get_lowerbound calls above. */ | |
13757 | + do_cleanups (old_chain); | |
13758 | ||
13759 | - offset_item = subscript_array[ndimensions - 1]; | |
13760 | + /* Now let us calculate the offset for this item */ | |
13761 | ||
13762 | - for (i = ndimensions - 1; i > 0; --i) | |
13763 | - offset_item = | |
13764 | - array_size_array[i - 1] * offset_item + subscript_array[i - 1]; | |
13765 | + offset_item = 0; | |
13766 | + offset_byte = 0; | |
13767 | ||
13768 | - /* Construct a value node with the value of the offset */ | |
13769 | + for (i = ndimensions - 1; i >= 0; --i) | |
13770 | + { | |
13771 | + offset_item *= array_size_array[i]; | |
13772 | + if (byte_stride_array[i] == 0) | |
13773 | + offset_item += subscript_array[i]; | |
13774 | + else | |
13775 | + offset_byte += subscript_array[i] * byte_stride_array[i]; | |
13776 | + } | |
13777 | ||
13778 | - arg2 = value_from_longest (builtin_type_int32, offset_item); | |
13779 | + element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tmp_type)); | |
13780 | + offset_byte += offset_item * element_size; | |
13781 | ||
13782 | /* Let us now play a dirty trick: we will take arg1 | |
13783 | which is a value node pointing to the topmost level | |
13784 | @@ -2037,7 +2173,7 @@ evaluate_subexp_standard (struct type *expect_type, | |
13785 | returns the correct type value */ | |
13786 | ||
13787 | deprecated_set_value_type (arg1, tmp_type); | |
13788 | - return value_subscripted_rvalue (arg1, arg2, 0); | |
13789 | + return value_subscripted_rvalue (arg1, offset_byte); | |
13790 | } | |
13791 | ||
13792 | case BINOP_LOGICAL_AND: | |
13793 | @@ -2475,7 +2611,17 @@ evaluate_subexp_standard (struct type *expect_type, | |
13794 | if (noside == EVAL_SKIP) | |
13795 | goto nosideret; | |
13796 | else if (noside == EVAL_AVOID_SIDE_EFFECTS) | |
13797 | - return allocate_value (exp->elts[pc + 1].type); | |
13798 | + { | |
13799 | + struct type *type = exp->elts[pc + 1].type; | |
13800 | + /* If this is a typedef, then find its immediate target. We | |
13801 | + use check_typedef to resolve stubs, but we ignore its | |
13802 | + result because we do not want to dig past all | |
13803 | + typedefs. */ | |
13804 | + check_typedef (type); | |
13805 | + if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) | |
13806 | + type = TYPE_TARGET_TYPE (type); | |
13807 | + return allocate_value (type); | |
13808 | + } | |
13809 | else | |
13810 | error (_("Attempt to use a type name as an expression")); | |
13811 | ||
13812 | @@ -2568,7 +2714,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos, | |
13813 | (*pos) += 5 + BYTES_TO_EXP_ELEM (tem + 1); | |
13814 | x = value_aggregate_elt (exp->elts[pc + 1].type, | |
13815 | &exp->elts[pc + 3].string, | |
13816 | - 1, noside); | |
13817 | + NULL, 1, noside); | |
13818 | if (x == NULL) | |
13819 | error (_("There is no field named %s"), &exp->elts[pc + 3].string); | |
13820 | return x; | |
13821 | @@ -2613,7 +2759,7 @@ evaluate_subexp_with_coercion (struct expression *exp, | |
13822 | { | |
13823 | enum exp_opcode op; | |
13824 | int pc; | |
13825 | - struct value *val; | |
13826 | + struct value *val = NULL; | |
13827 | struct symbol *var; | |
13828 | struct type *type; | |
13829 | ||
13830 | @@ -2624,12 +2770,17 @@ evaluate_subexp_with_coercion (struct expression *exp, | |
13831 | { | |
13832 | case OP_VAR_VALUE: | |
13833 | var = exp->elts[pc + 2].symbol; | |
13834 | + /* address_of_variable will call object_address_set for check_typedef. | |
13835 | + Call it only if required as it can error-out on VAR in register. */ | |
13836 | + if (TYPE_DYNAMIC (SYMBOL_TYPE (var))) | |
13837 | + val = address_of_variable (var, exp->elts[pc + 1].block); | |
13838 | type = check_typedef (SYMBOL_TYPE (var)); | |
13839 | if (TYPE_CODE (type) == TYPE_CODE_ARRAY | |
13840 | && CAST_IS_CONVERSION) | |
13841 | { | |
13842 | (*pos) += 4; | |
13843 | - val = address_of_variable (var, exp->elts[pc + 1].block); | |
13844 | + if (!val) | |
13845 | + val = address_of_variable (var, exp->elts[pc + 1].block); | |
13846 | return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)), | |
13847 | val); | |
13848 | } | |
13849 | @@ -2681,9 +2832,13 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos) | |
13850 | ||
13851 | case OP_VAR_VALUE: | |
13852 | (*pos) += 4; | |
13853 | - type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol)); | |
13854 | - return | |
13855 | - value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); | |
13856 | + /* We do not need to call read_var_value but the object evaluation may | |
13857 | + need to have executed object_address_set which needs valid | |
13858 | + SYMBOL_VALUE_ADDRESS of the symbol. Still VALUE returned by | |
13859 | + read_var_value we left as lazy. */ | |
13860 | + type = value_type (read_var_value (exp->elts[pc + 2].symbol, | |
13861 | + deprecated_safe_get_selected_frame ())); | |
13862 | + return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); | |
13863 | ||
13864 | default: | |
13865 | val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); | |
13866 | diff --git a/gdb/expprint.c b/gdb/expprint.c | |
13867 | index 89bae03..f768940 100644 | |
13868 | --- a/gdb/expprint.c | |
13869 | +++ b/gdb/expprint.c | |
13870 | @@ -186,8 +186,8 @@ print_subexp_standard (struct expression *exp, int *pos, | |
13871 | If necessary, we can temporarily set it to zero, or pass it as an | |
13872 | additional parameter to LA_PRINT_STRING. -fnf */ | |
13873 | get_user_print_options (&opts); | |
13874 | - LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0, | |
13875 | - &opts); | |
13876 | + LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char, | |
13877 | + &exp->elts[pc + 2].string, nargs, 0, &opts); | |
13878 | } | |
13879 | return; | |
13880 | ||
13881 | @@ -205,8 +205,8 @@ print_subexp_standard (struct expression *exp, int *pos, | |
13882 | (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); | |
13883 | fputs_filtered ("@\"", stream); | |
13884 | get_user_print_options (&opts); | |
13885 | - LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0, | |
13886 | - &opts); | |
13887 | + LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char, | |
13888 | + &exp->elts[pc + 2].string, nargs, 0, &opts); | |
13889 | fputs_filtered ("\"", stream); | |
13890 | } | |
13891 | return; | |
13892 | @@ -291,8 +291,8 @@ print_subexp_standard (struct expression *exp, int *pos, | |
13893 | { | |
13894 | struct value_print_options opts; | |
13895 | get_user_print_options (&opts); | |
13896 | - LA_PRINT_STRING (stream, tempstr, nargs - 1, 1, 0, | |
13897 | - &opts); | |
13898 | + LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char, | |
13899 | + tempstr, nargs - 1, 0, &opts); | |
13900 | (*pos) = pc; | |
13901 | } | |
13902 | else | |
13903 | diff --git a/gdb/expression.h b/gdb/expression.h | |
13904 | index 12163e3..789cb89 100644 | |
13905 | --- a/gdb/expression.h | |
13906 | +++ b/gdb/expression.h | |
13907 | @@ -88,6 +88,16 @@ enum exp_opcode | |
13908 | when X is a pointer instead of an aggregate. */ | |
13909 | STRUCTOP_MPTR, | |
13910 | ||
13911 | + /* TYPE_INSTANCE is used when the user specifies a specific | |
13912 | + type instantiation for overloaded methods/functions. The format | |
13913 | + is: TYPE_INSTANCE num_types type0 ... typeN num_types TYPE_INSTANCE*/ | |
13914 | + TYPE_INSTANCE, | |
13915 | + | |
13916 | + /* TYPE_INSTANCE_LOOKUP is used when the user specifies a specific | |
13917 | + type instantiation of a function (not a method). In this case, | |
13918 | + we must toss the results of the parser and manually do the lookup. */ | |
13919 | + TYPE_INSTANCE_LOOKUP, | |
13920 | + | |
13921 | /* end of C++. */ | |
13922 | ||
13923 | /* For Modula-2 integer division DIV */ | |
13924 | @@ -426,6 +436,8 @@ enum noside | |
13925 | extern struct value *evaluate_subexp_standard | |
13926 | (struct type *, struct expression *, int *, enum noside); | |
13927 | ||
13928 | +extern int compare_parameters (struct type *, struct type *); | |
13929 | + | |
13930 | /* From expprint.c */ | |
13931 | ||
13932 | extern void print_expression (struct expression *, struct ui_file *); | |
13933 | @@ -435,4 +447,5 @@ extern char *op_string (enum exp_opcode); | |
13934 | extern void dump_raw_expression (struct expression *, struct ui_file *, char *); | |
13935 | extern void dump_prefix_expression (struct expression *, struct ui_file *); | |
13936 | ||
13937 | + | |
13938 | #endif /* !defined (EXPRESSION_H) */ | |
13939 | diff --git a/gdb/f-exp.y b/gdb/f-exp.y | |
13940 | index d91c413..c984e85 100644 | |
13941 | --- a/gdb/f-exp.y | |
13942 | +++ b/gdb/f-exp.y | |
13943 | @@ -198,6 +198,7 @@ static int parse_number (char *, int, int, YYSTYPE *); | |
13944 | /* Special type cases, put in to allow the parser to distinguish different | |
13945 | legal basetypes. */ | |
13946 | %token INT_KEYWORD INT_S2_KEYWORD LOGICAL_S1_KEYWORD LOGICAL_S2_KEYWORD | |
13947 | +%token LOGICAL_S8_KEYWORD | |
13948 | %token LOGICAL_KEYWORD REAL_KEYWORD REAL_S8_KEYWORD REAL_S16_KEYWORD | |
13949 | %token COMPLEX_S8_KEYWORD COMPLEX_S16_KEYWORD COMPLEX_S32_KEYWORD | |
13950 | %token BOOL_AND BOOL_OR BOOL_NOT | |
13951 | @@ -608,6 +609,8 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ | |
13952 | { $$ = parse_f_type->builtin_integer_s2; } | |
13953 | | CHARACTER | |
13954 | { $$ = parse_f_type->builtin_character; } | |
13955 | + | LOGICAL_S8_KEYWORD | |
13956 | + { $$ = parse_f_type->builtin_logical_s8;} | |
13957 | | LOGICAL_KEYWORD | |
13958 | { $$ = parse_f_type->builtin_logical; } | |
13959 | | LOGICAL_S2_KEYWORD | |
13960 | @@ -860,6 +863,7 @@ static const struct token f77_keywords[] = | |
13961 | { "integer_2", INT_S2_KEYWORD, BINOP_END }, | |
13962 | { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END }, | |
13963 | { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END }, | |
13964 | + { "logical_8", LOGICAL_S8_KEYWORD, BINOP_END }, | |
13965 | { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END }, | |
13966 | { "integer", INT_KEYWORD, BINOP_END }, | |
13967 | { "logical", LOGICAL_KEYWORD, BINOP_END }, | |
13968 | diff --git a/gdb/f-lang.c b/gdb/f-lang.c | |
13969 | index 6359841..1754c44 100644 | |
13970 | --- a/gdb/f-lang.c | |
13971 | +++ b/gdb/f-lang.c | |
13972 | @@ -55,23 +55,10 @@ typedef struct saved_bf_symnum SAVED_BF, *SAVED_BF_PTR; | |
13973 | /* Local functions */ | |
13974 | ||
13975 | extern void _initialize_f_language (void); | |
13976 | -#if 0 | |
13977 | -static void clear_function_list (void); | |
13978 | -static long get_bf_for_fcn (long); | |
13979 | -static void clear_bf_list (void); | |
13980 | -static void patch_all_commons_by_name (char *, CORE_ADDR, int); | |
13981 | -static SAVED_F77_COMMON_PTR find_first_common_named (char *); | |
13982 | -static void add_common_entry (struct symbol *); | |
13983 | -static void add_common_block (char *, CORE_ADDR, int, char *); | |
13984 | -static SAVED_FUNCTION *allocate_saved_function_node (void); | |
13985 | -static SAVED_BF_PTR allocate_saved_bf_node (void); | |
13986 | -static COMMON_ENTRY_PTR allocate_common_entry_node (void); | |
13987 | -static SAVED_F77_COMMON_PTR allocate_saved_f77_common_node (void); | |
13988 | -static void patch_common_entries (SAVED_F77_COMMON_PTR, CORE_ADDR, int); | |
13989 | -#endif | |
13990 | - | |
13991 | -static void f_printchar (int c, struct ui_file * stream); | |
13992 | -static void f_emit_char (int c, struct ui_file * stream, int quoter); | |
13993 | + | |
13994 | +static void f_printchar (int c, struct type *type, struct ui_file * stream); | |
13995 | +static void f_emit_char (int c, struct type *type, | |
13996 | + struct ui_file * stream, int quoter); | |
13997 | ||
13998 | /* Print the character C on STREAM as part of the contents of a literal | |
13999 | string whose delimiter is QUOTER. Note that that format for printing | |
14000 | @@ -80,7 +67,7 @@ static void f_emit_char (int c, struct ui_file * stream, int quoter); | |
14001 | be replaced with a true F77 version. */ | |
14002 | ||
14003 | static void | |
14004 | -f_emit_char (int c, struct ui_file *stream, int quoter) | |
14005 | +f_emit_char (int c, struct type *type, struct ui_file *stream, int quoter) | |
14006 | { | |
14007 | c &= 0xFF; /* Avoid sign bit follies */ | |
14008 | ||
14009 | @@ -126,10 +113,10 @@ f_emit_char (int c, struct ui_file *stream, int quoter) | |
14010 | be replaced with a true F77version. */ | |
14011 | ||
14012 | static void | |
14013 | -f_printchar (int c, struct ui_file *stream) | |
14014 | +f_printchar (int c, struct type *type, struct ui_file *stream) | |
14015 | { | |
14016 | fputs_filtered ("'", stream); | |
14017 | - LA_EMIT_CHAR (c, stream, '\''); | |
14018 | + LA_EMIT_CHAR (c, type, stream, '\''); | |
14019 | fputs_filtered ("'", stream); | |
14020 | } | |
14021 | ||
14022 | @@ -141,14 +128,15 @@ f_printchar (int c, struct ui_file *stream) | |
14023 | be replaced with a true F77 version. */ | |
14024 | ||
14025 | static void | |
14026 | -f_printstr (struct ui_file *stream, const gdb_byte *string, | |
14027 | - unsigned int length, int width, int force_ellipses, | |
14028 | +f_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, | |
14029 | + unsigned int length, int force_ellipses, | |
14030 | const struct value_print_options *options) | |
14031 | { | |
14032 | unsigned int i; | |
14033 | unsigned int things_printed = 0; | |
14034 | int in_quotes = 0; | |
14035 | int need_comma = 0; | |
14036 | + int width = TYPE_LENGTH (type); | |
14037 | ||
14038 | if (length == 0) | |
14039 | { | |
14040 | @@ -190,7 +178,7 @@ f_printstr (struct ui_file *stream, const gdb_byte *string, | |
14041 | fputs_filtered ("', ", stream); | |
14042 | in_quotes = 0; | |
14043 | } | |
14044 | - f_printchar (string[i], stream); | |
14045 | + f_printchar (string[i], type, stream); | |
14046 | fprintf_filtered (stream, " <repeats %u times>", reps); | |
14047 | i = rep1 - 1; | |
14048 | things_printed += options->repeat_count_threshold; | |
14049 | @@ -206,7 +194,7 @@ f_printstr (struct ui_file *stream, const gdb_byte *string, | |
14050 | fputs_filtered ("'", stream); | |
14051 | in_quotes = 1; | |
14052 | } | |
14053 | - LA_EMIT_CHAR (string[i], stream, '"'); | |
14054 | + LA_EMIT_CHAR (string[i], type, stream, '"'); | |
14055 | ++things_printed; | |
14056 | } | |
14057 | } | |
14058 | @@ -257,6 +245,7 @@ enum f_primitive_types { | |
14059 | f_primitive_type_logical, | |
14060 | f_primitive_type_logical_s1, | |
14061 | f_primitive_type_logical_s2, | |
14062 | + f_primitive_type_logical_s8, | |
14063 | f_primitive_type_integer, | |
14064 | f_primitive_type_integer_s2, | |
14065 | f_primitive_type_real, | |
14066 | @@ -287,6 +276,8 @@ f_language_arch_info (struct gdbarch *gdbarch, | |
14067 | = builtin->builtin_logical_s1; | |
14068 | lai->primitive_type_vector [f_primitive_type_logical_s2] | |
14069 | = builtin->builtin_logical_s2; | |
14070 | + lai->primitive_type_vector [f_primitive_type_logical_s8] | |
14071 | + = builtin->builtin_logical_s8; | |
14072 | lai->primitive_type_vector [f_primitive_type_real] | |
14073 | = builtin->builtin_real; | |
14074 | lai->primitive_type_vector [f_primitive_type_real_s8] | |
14075 | @@ -378,6 +369,11 @@ build_fortran_types (struct gdbarch *gdbarch) | |
14076 | gdbarch_short_bit (gdbarch) / TARGET_CHAR_BIT, | |
14077 | TYPE_FLAG_UNSIGNED, "logical*2", (struct objfile *) NULL); | |
14078 | ||
14079 | + builtin_f_type->builtin_logical_s8 = | |
14080 | + init_type (TYPE_CODE_BOOL, | |
14081 | + gdbarch_long_long_bit (gdbarch) / TARGET_CHAR_BIT, | |
14082 | + TYPE_FLAG_UNSIGNED, "logical*8", (struct objfile *) NULL); | |
14083 | + | |
14084 | builtin_f_type->builtin_integer = | |
14085 | init_type (TYPE_CODE_INT, | |
14086 | gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT, | |
14087 | @@ -451,395 +447,3 @@ _initialize_f_language (void) | |
14088 | ||
14089 | add_language (&f_language_defn); | |
14090 | } | |
14091 | - | |
14092 | -#if 0 | |
14093 | -static SAVED_BF_PTR | |
14094 | -allocate_saved_bf_node (void) | |
14095 | -{ | |
14096 | - SAVED_BF_PTR new; | |
14097 | - | |
14098 | - new = (SAVED_BF_PTR) xmalloc (sizeof (SAVED_BF)); | |
14099 | - return (new); | |
14100 | -} | |
14101 | - | |
14102 | -static SAVED_FUNCTION * | |
14103 | -allocate_saved_function_node (void) | |
14104 | -{ | |
14105 | - SAVED_FUNCTION *new; | |
14106 | - | |
14107 | - new = (SAVED_FUNCTION *) xmalloc (sizeof (SAVED_FUNCTION)); | |
14108 | - return (new); | |
14109 | -} | |
14110 | - | |
14111 | -static SAVED_F77_COMMON_PTR | |
14112 | -allocate_saved_f77_common_node (void) | |
14113 | -{ | |
14114 | - SAVED_F77_COMMON_PTR new; | |
14115 | - | |
14116 | - new = (SAVED_F77_COMMON_PTR) xmalloc (sizeof (SAVED_F77_COMMON)); | |
14117 | - return (new); | |
14118 | -} | |
14119 | - | |
14120 | -static COMMON_ENTRY_PTR | |
14121 | -allocate_common_entry_node (void) | |
14122 | -{ | |
14123 | - COMMON_ENTRY_PTR new; | |
14124 | - | |
14125 | - new = (COMMON_ENTRY_PTR) xmalloc (sizeof (COMMON_ENTRY)); | |
14126 | - return (new); | |
14127 | -} | |
14128 | -#endif | |
14129 | - | |
14130 | -SAVED_F77_COMMON_PTR head_common_list = NULL; /* Ptr to 1st saved COMMON */ | |
14131 | -SAVED_F77_COMMON_PTR tail_common_list = NULL; /* Ptr to last saved COMMON */ | |
14132 | -SAVED_F77_COMMON_PTR current_common = NULL; /* Ptr to current COMMON */ | |
14133 | - | |
14134 | -#if 0 | |
14135 | -static SAVED_BF_PTR saved_bf_list = NULL; /* Ptr to (.bf,function) | |
14136 | - list */ | |
14137 | -static SAVED_BF_PTR saved_bf_list_end = NULL; /* Ptr to above list's end */ | |
14138 | -static SAVED_BF_PTR current_head_bf_list = NULL; /* Current head of above list | |
14139 | - */ | |
14140 | - | |
14141 | -static SAVED_BF_PTR tmp_bf_ptr; /* Generic temporary for use | |
14142 | - in macros */ | |
14143 | - | |
14144 | -/* The following function simply enters a given common block onto | |
14145 | - the global common block chain */ | |
14146 | - | |
14147 | -static void | |
14148 | -add_common_block (char *name, CORE_ADDR offset, int secnum, char *func_stab) | |
14149 | -{ | |
14150 | - SAVED_F77_COMMON_PTR tmp; | |
14151 | - char *c, *local_copy_func_stab; | |
14152 | - | |
14153 | - /* If the COMMON block we are trying to add has a blank | |
14154 | - name (i.e. "#BLNK_COM") then we set it to __BLANK | |
14155 | - because the darn "#" character makes GDB's input | |
14156 | - parser have fits. */ | |
14157 | - | |
14158 | - | |
14159 | - if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0 | |
14160 | - || strcmp (name, BLANK_COMMON_NAME_MF77) == 0) | |
14161 | - { | |
14162 | - | |
14163 | - xfree (name); | |
14164 | - name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1); | |
14165 | - strcpy (name, BLANK_COMMON_NAME_LOCAL); | |
14166 | - } | |
14167 | - | |
14168 | - tmp = allocate_saved_f77_common_node (); | |
14169 | - | |
14170 | - local_copy_func_stab = xmalloc (strlen (func_stab) + 1); | |
14171 | - strcpy (local_copy_func_stab, func_stab); | |
14172 | - | |
14173 | - tmp->name = xmalloc (strlen (name) + 1); | |
14174 | - | |
14175 | - /* local_copy_func_stab is a stabstring, let us first extract the | |
14176 | - function name from the stab by NULLing out the ':' character. */ | |
14177 | - | |
14178 | - | |
14179 | - c = NULL; | |
14180 | - c = strchr (local_copy_func_stab, ':'); | |
14181 | - | |
14182 | - if (c) | |
14183 | - *c = '\0'; | |
14184 | - else | |
14185 | - error (_("Malformed function STAB found in add_common_block()")); | |
14186 | - | |
14187 | - | |
14188 | - tmp->owning_function = xmalloc (strlen (local_copy_func_stab) + 1); | |
14189 | - | |
14190 | - strcpy (tmp->owning_function, local_copy_func_stab); | |
14191 | - | |
14192 | - strcpy (tmp->name, name); | |
14193 | - tmp->offset = offset; | |
14194 | - tmp->next = NULL; | |
14195 | - tmp->entries = NULL; | |
14196 | - tmp->secnum = secnum; | |
14197 | - | |
14198 | - current_common = tmp; | |
14199 | - | |
14200 | - if (head_common_list == NULL) | |
14201 | - { | |
14202 | - head_common_list = tail_common_list = tmp; | |
14203 | - } | |
14204 | - else | |
14205 | - { | |
14206 | - tail_common_list->next = tmp; | |
14207 | - tail_common_list = tmp; | |
14208 | - } | |
14209 | -} | |
14210 | -#endif | |
14211 | - | |
14212 | -/* The following function simply enters a given common entry onto | |
14213 | - the "current_common" block that has been saved away. */ | |
14214 | - | |
14215 | -#if 0 | |
14216 | -static void | |
14217 | -add_common_entry (struct symbol *entry_sym_ptr) | |
14218 | -{ | |
14219 | - COMMON_ENTRY_PTR tmp; | |
14220 | - | |
14221 | - | |
14222 | - | |
14223 | - /* The order of this list is important, since | |
14224 | - we expect the entries to appear in decl. | |
14225 | - order when we later issue "info common" calls */ | |
14226 | - | |
14227 | - tmp = allocate_common_entry_node (); | |
14228 | - | |
14229 | - tmp->next = NULL; | |
14230 | - tmp->symbol = entry_sym_ptr; | |
14231 | - | |
14232 | - if (current_common == NULL) | |
14233 | - error (_("Attempt to add COMMON entry with no block open!")); | |
14234 | - else | |
14235 | - { | |
14236 | - if (current_common->entries == NULL) | |
14237 | - { | |
14238 | - current_common->entries = tmp; | |
14239 | - current_common->end_of_entries = tmp; | |
14240 | - } | |
14241 | - else | |
14242 | - { | |
14243 | - current_common->end_of_entries->next = tmp; | |
14244 | - current_common->end_of_entries = tmp; | |
14245 | - } | |
14246 | - } | |
14247 | -} | |
14248 | -#endif | |
14249 | - | |
14250 | -/* This routine finds the first encountred COMMON block named "name" */ | |
14251 | - | |
14252 | -#if 0 | |
14253 | -static SAVED_F77_COMMON_PTR | |
14254 | -find_first_common_named (char *name) | |
14255 | -{ | |
14256 | - | |
14257 | - SAVED_F77_COMMON_PTR tmp; | |
14258 | - | |
14259 | - tmp = head_common_list; | |
14260 | - | |
14261 | - while (tmp != NULL) | |
14262 | - { | |
14263 | - if (strcmp (tmp->name, name) == 0) | |
14264 | - return (tmp); | |
14265 | - else | |
14266 | - tmp = tmp->next; | |
14267 | - } | |
14268 | - return (NULL); | |
14269 | -} | |
14270 | -#endif | |
14271 | - | |
14272 | -/* This routine finds the first encountred COMMON block named "name" | |
14273 | - that belongs to function funcname */ | |
14274 | - | |
14275 | -SAVED_F77_COMMON_PTR | |
14276 | -find_common_for_function (char *name, char *funcname) | |
14277 | -{ | |
14278 | - | |
14279 | - SAVED_F77_COMMON_PTR tmp; | |
14280 | - | |
14281 | - tmp = head_common_list; | |
14282 | - | |
14283 | - while (tmp != NULL) | |
14284 | - { | |
14285 | - if (strcmp (tmp->name, name) == 0 | |
14286 | - && strcmp (tmp->owning_function, funcname) == 0) | |
14287 | - return (tmp); | |
14288 | - else | |
14289 | - tmp = tmp->next; | |
14290 | - } | |
14291 | - return (NULL); | |
14292 | -} | |
14293 | - | |
14294 | - | |
14295 | -#if 0 | |
14296 | - | |
14297 | -/* The following function is called to patch up the offsets | |
14298 | - for the statics contained in the COMMON block named | |
14299 | - "name." */ | |
14300 | - | |
14301 | -static void | |
14302 | -patch_common_entries (SAVED_F77_COMMON_PTR blk, CORE_ADDR offset, int secnum) | |
14303 | -{ | |
14304 | - COMMON_ENTRY_PTR entry; | |
14305 | - | |
14306 | - blk->offset = offset; /* Keep this around for future use. */ | |
14307 | - | |
14308 | - entry = blk->entries; | |
14309 | - | |
14310 | - while (entry != NULL) | |
14311 | - { | |
14312 | - SYMBOL_VALUE (entry->symbol) += offset; | |
14313 | - SYMBOL_SECTION (entry->symbol) = secnum; | |
14314 | - | |
14315 | - entry = entry->next; | |
14316 | - } | |
14317 | - blk->secnum = secnum; | |
14318 | -} | |
14319 | - | |
14320 | -/* Patch all commons named "name" that need patching.Since COMMON | |
14321 | - blocks occur with relative infrequency, we simply do a linear scan on | |
14322 | - the name. Eventually, the best way to do this will be a | |
14323 | - hashed-lookup. Secnum is the section number for the .bss section | |
14324 | - (which is where common data lives). */ | |
14325 | - | |
14326 | -static void | |
14327 | -patch_all_commons_by_name (char *name, CORE_ADDR offset, int secnum) | |
14328 | -{ | |
14329 | - | |
14330 | - SAVED_F77_COMMON_PTR tmp; | |
14331 | - | |
14332 | - /* For blank common blocks, change the canonical reprsentation | |
14333 | - of a blank name */ | |
14334 | - | |
14335 | - if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0 | |
14336 | - || strcmp (name, BLANK_COMMON_NAME_MF77) == 0) | |
14337 | - { | |
14338 | - xfree (name); | |
14339 | - name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1); | |
14340 | - strcpy (name, BLANK_COMMON_NAME_LOCAL); | |
14341 | - } | |
14342 | - | |
14343 | - tmp = head_common_list; | |
14344 | - | |
14345 | - while (tmp != NULL) | |
14346 | - { | |
14347 | - if (COMMON_NEEDS_PATCHING (tmp)) | |
14348 | - if (strcmp (tmp->name, name) == 0) | |
14349 | - patch_common_entries (tmp, offset, secnum); | |
14350 | - | |
14351 | - tmp = tmp->next; | |
14352 | - } | |
14353 | -} | |
14354 | -#endif | |
14355 | - | |
14356 | -/* This macro adds the symbol-number for the start of the function | |
14357 | - (the symbol number of the .bf) referenced by symnum_fcn to a | |
14358 | - list. This list, in reality should be a FIFO queue but since | |
14359 | - #line pragmas sometimes cause line ranges to get messed up | |
14360 | - we simply create a linear list. This list can then be searched | |
14361 | - first by a queueing algorithm and upon failure fall back to | |
14362 | - a linear scan. */ | |
14363 | - | |
14364 | -#if 0 | |
14365 | -#define ADD_BF_SYMNUM(bf_sym,fcn_sym) \ | |
14366 | - \ | |
14367 | - if (saved_bf_list == NULL) \ | |
14368 | -{ \ | |
14369 | - tmp_bf_ptr = allocate_saved_bf_node(); \ | |
14370 | - \ | |
14371 | - tmp_bf_ptr->symnum_bf = (bf_sym); \ | |
14372 | - tmp_bf_ptr->symnum_fcn = (fcn_sym); \ | |
14373 | - tmp_bf_ptr->next = NULL; \ | |
14374 | - \ | |
14375 | - current_head_bf_list = saved_bf_list = tmp_bf_ptr; \ | |
14376 | - saved_bf_list_end = tmp_bf_ptr; \ | |
14377 | - } \ | |
14378 | -else \ | |
14379 | -{ \ | |
14380 | - tmp_bf_ptr = allocate_saved_bf_node(); \ | |
14381 | - \ | |
14382 | - tmp_bf_ptr->symnum_bf = (bf_sym); \ | |
14383 | - tmp_bf_ptr->symnum_fcn = (fcn_sym); \ | |
14384 | - tmp_bf_ptr->next = NULL; \ | |
14385 | - \ | |
14386 | - saved_bf_list_end->next = tmp_bf_ptr; \ | |
14387 | - saved_bf_list_end = tmp_bf_ptr; \ | |
14388 | - } | |
14389 | -#endif | |
14390 | - | |
14391 | -/* This function frees the entire (.bf,function) list */ | |
14392 | - | |
14393 | -#if 0 | |
14394 | -static void | |
14395 | -clear_bf_list (void) | |
14396 | -{ | |
14397 | - | |
14398 | - SAVED_BF_PTR tmp = saved_bf_list; | |
14399 | - SAVED_BF_PTR next = NULL; | |
14400 | - | |
14401 | - while (tmp != NULL) | |
14402 | - { | |
14403 | - next = tmp->next; | |
14404 | - xfree (tmp); | |
14405 | - tmp = next; | |
14406 | - } | |
14407 | - saved_bf_list = NULL; | |
14408 | -} | |
14409 | -#endif | |
14410 | - | |
14411 | -int global_remote_debug; | |
14412 | - | |
14413 | -#if 0 | |
14414 | - | |
14415 | -static long | |
14416 | -get_bf_for_fcn (long the_function) | |
14417 | -{ | |
14418 | - SAVED_BF_PTR tmp; | |
14419 | - int nprobes = 0; | |
14420 | - | |
14421 | - /* First use a simple queuing algorithm (i.e. look and see if the | |
14422 | - item at the head of the queue is the one you want) */ | |
14423 | - | |
14424 | - if (saved_bf_list == NULL) | |
14425 | - internal_error (__FILE__, __LINE__, | |
14426 | - _("cannot get .bf node off empty list")); | |
14427 | - | |
14428 | - if (current_head_bf_list != NULL) | |
14429 | - if (current_head_bf_list->symnum_fcn == the_function) | |
14430 | - { | |
14431 | - if (global_remote_debug) | |
14432 | - fprintf_unfiltered (gdb_stderr, "*"); | |
14433 | - | |
14434 | - tmp = current_head_bf_list; | |
14435 | - current_head_bf_list = current_head_bf_list->next; | |
14436 | - return (tmp->symnum_bf); | |
14437 | - } | |
14438 | - | |
14439 | - /* If the above did not work (probably because #line directives were | |
14440 | - used in the sourcefile and they messed up our internal tables) we now do | |
14441 | - the ugly linear scan */ | |
14442 | - | |
14443 | - if (global_remote_debug) | |
14444 | - fprintf_unfiltered (gdb_stderr, "\ndefaulting to linear scan\n"); | |
14445 | - | |
14446 | - nprobes = 0; | |
14447 | - tmp = saved_bf_list; | |
14448 | - while (tmp != NULL) | |
14449 | - { | |
14450 | - nprobes++; | |
14451 | - if (tmp->symnum_fcn == the_function) | |
14452 | - { | |
14453 | - if (global_remote_debug) | |
14454 | - fprintf_unfiltered (gdb_stderr, "Found in %d probes\n", nprobes); | |
14455 | - current_head_bf_list = tmp->next; | |
14456 | - return (tmp->symnum_bf); | |
14457 | - } | |
14458 | - tmp = tmp->next; | |
14459 | - } | |
14460 | - | |
14461 | - return (-1); | |
14462 | -} | |
14463 | - | |
14464 | -static SAVED_FUNCTION_PTR saved_function_list = NULL; | |
14465 | -static SAVED_FUNCTION_PTR saved_function_list_end = NULL; | |
14466 | - | |
14467 | -static void | |
14468 | -clear_function_list (void) | |
14469 | -{ | |
14470 | - SAVED_FUNCTION_PTR tmp = saved_function_list; | |
14471 | - SAVED_FUNCTION_PTR next = NULL; | |
14472 | - | |
14473 | - while (tmp != NULL) | |
14474 | - { | |
14475 | - next = tmp->next; | |
14476 | - xfree (tmp); | |
14477 | - tmp = next; | |
14478 | - } | |
14479 | - | |
14480 | - saved_function_list = NULL; | |
14481 | -} | |
14482 | -#endif | |
14483 | diff --git a/gdb/f-lang.h b/gdb/f-lang.h | |
14484 | index 711bdba..cd2f804 100644 | |
14485 | --- a/gdb/f-lang.h | |
14486 | +++ b/gdb/f-lang.h | |
14487 | @@ -28,6 +28,10 @@ extern void f_error (char *); /* Defined in f-exp.y */ | |
14488 | extern void f_print_type (struct type *, char *, struct ui_file *, int, | |
14489 | int); | |
14490 | ||
14491 | +extern const char *f_object_address_data_valid_print_to_stream | |
14492 | + (struct type *type, struct ui_file *stream); | |
14493 | +extern void f_object_address_data_valid_or_error (struct type *type); | |
14494 | + | |
14495 | extern int f_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, | |
14496 | struct ui_file *, int, | |
14497 | const struct value_print_options *); | |
14498 | @@ -47,41 +51,8 @@ enum f90_range_type | |
14499 | NONE_BOUND_DEFAULT /* "(low:high)" */ | |
14500 | }; | |
14501 | ||
14502 | -struct common_entry | |
14503 | - { | |
14504 | - struct symbol *symbol; /* The symbol node corresponding | |
14505 | - to this component */ | |
14506 | - struct common_entry *next; /* The next component */ | |
14507 | - }; | |
14508 | - | |
14509 | -struct saved_f77_common | |
14510 | - { | |
14511 | - char *name; /* Name of COMMON */ | |
14512 | - char *owning_function; /* Name of parent function */ | |
14513 | - int secnum; /* Section # of .bss */ | |
14514 | - CORE_ADDR offset; /* Offset from .bss for | |
14515 | - this block */ | |
14516 | - struct common_entry *entries; /* List of block's components */ | |
14517 | - struct common_entry *end_of_entries; /* ptr. to end of components */ | |
14518 | - struct saved_f77_common *next; /* Next saved COMMON block */ | |
14519 | - }; | |
14520 | - | |
14521 | -typedef struct saved_f77_common SAVED_F77_COMMON, *SAVED_F77_COMMON_PTR; | |
14522 | - | |
14523 | -typedef struct common_entry COMMON_ENTRY, *COMMON_ENTRY_PTR; | |
14524 | - | |
14525 | -extern SAVED_F77_COMMON_PTR head_common_list; /* Ptr to 1st saved COMMON */ | |
14526 | -extern SAVED_F77_COMMON_PTR tail_common_list; /* Ptr to last saved COMMON */ | |
14527 | -extern SAVED_F77_COMMON_PTR current_common; /* Ptr to current COMMON */ | |
14528 | - | |
14529 | -extern SAVED_F77_COMMON_PTR find_common_for_function (char *, char *); | |
14530 | - | |
14531 | -#define UNINITIALIZED_SECNUM -1 | |
14532 | -#define COMMON_NEEDS_PATCHING(blk) ((blk)->secnum == UNINITIALIZED_SECNUM) | |
14533 | - | |
14534 | #define BLANK_COMMON_NAME_ORIGINAL "#BLNK_COM" /* XLF assigned */ | |
14535 | #define BLANK_COMMON_NAME_MF77 "__BLNK__" /* MF77 assigned */ | |
14536 | -#define BLANK_COMMON_NAME_LOCAL "__BLANK" /* Local GDB */ | |
14537 | ||
14538 | /* When reasonable array bounds cannot be fetched, such as when | |
14539 | you ask to 'mt print symbols' and there is no stack frame and | |
14540 | @@ -113,6 +84,7 @@ struct builtin_f_type | |
14541 | struct type *builtin_logical; | |
14542 | struct type *builtin_logical_s1; | |
14543 | struct type *builtin_logical_s2; | |
14544 | + struct type *builtin_logical_s8; | |
14545 | struct type *builtin_real; | |
14546 | struct type *builtin_real_s8; | |
14547 | struct type *builtin_real_s16; | |
14548 | diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c | |
14549 | index 6c9668f..852b9a8 100644 | |
14550 | --- a/gdb/f-typeprint.c | |
14551 | +++ b/gdb/f-typeprint.c | |
14552 | @@ -31,7 +31,7 @@ | |
14553 | #include "gdbcore.h" | |
14554 | #include "target.h" | |
14555 | #include "f-lang.h" | |
14556 | - | |
14557 | +#include "dwarf2loc.h" | |
14558 | #include "gdb_string.h" | |
14559 | #include <errno.h> | |
14560 | ||
14561 | @@ -48,6 +48,34 @@ void f_type_print_varspec_prefix (struct type *, struct ui_file *, | |
14562 | void f_type_print_base (struct type *, struct ui_file *, int, int); | |
14563 | \f | |
14564 | ||
14565 | +const char * | |
14566 | +f_object_address_data_valid_print_to_stream (struct type *type, | |
14567 | + struct ui_file *stream) | |
14568 | +{ | |
14569 | + const char *msg; | |
14570 | + | |
14571 | + msg = object_address_data_not_valid (type); | |
14572 | + if (msg != NULL) | |
14573 | + { | |
14574 | + /* Assuming the content printed to STREAM should not be localized. */ | |
14575 | + fprintf_filtered (stream, "<%s>", msg); | |
14576 | + } | |
14577 | + | |
14578 | + return msg; | |
14579 | +} | |
14580 | + | |
14581 | +void | |
14582 | +f_object_address_data_valid_or_error (struct type *type) | |
14583 | +{ | |
14584 | + const char *msg; | |
14585 | + | |
14586 | + msg = object_address_data_not_valid (type); | |
14587 | + if (msg != NULL) | |
14588 | + { | |
14589 | + error (_("Cannot access it because the %s."), _(msg)); | |
14590 | + } | |
14591 | +} | |
14592 | + | |
14593 | /* LEVEL is the depth to indent lines by. */ | |
14594 | ||
14595 | void | |
14596 | @@ -57,6 +85,9 @@ f_print_type (struct type *type, char *varstring, struct ui_file *stream, | |
14597 | enum type_code code; | |
14598 | int demangled_args; | |
14599 | ||
14600 | + if (f_object_address_data_valid_print_to_stream (type, stream) != NULL) | |
14601 | + return; | |
14602 | + | |
14603 | f_type_print_base (type, stream, show, level); | |
14604 | code = TYPE_CODE (type); | |
14605 | if ((varstring != NULL && *varstring != '\0') | |
14606 | @@ -166,6 +197,9 @@ f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, | |
14607 | ||
14608 | QUIT; | |
14609 | ||
14610 | + if (TYPE_CODE (type) != TYPE_CODE_TYPEDEF) | |
14611 | + CHECK_TYPEDEF (type); | |
14612 | + | |
14613 | switch (TYPE_CODE (type)) | |
14614 | { | |
14615 | case TYPE_CODE_ARRAY: | |
14616 | diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c | |
14617 | index 5721041..2cff7bc 100644 | |
14618 | --- a/gdb/f-valprint.c | |
14619 | +++ b/gdb/f-valprint.c | |
14620 | @@ -34,10 +34,8 @@ | |
14621 | #include "gdbcore.h" | |
14622 | #include "command.h" | |
14623 | #include "block.h" | |
14624 | - | |
14625 | -#if 0 | |
14626 | -static int there_is_a_visible_common_named (char *); | |
14627 | -#endif | |
14628 | +#include "dictionary.h" | |
14629 | +#include "gdb_assert.h" | |
14630 | ||
14631 | extern void _initialize_f_valprint (void); | |
14632 | static void info_common_command (char *, int); | |
14633 | @@ -54,15 +52,17 @@ int f77_array_offset_tbl[MAX_FORTRAN_DIMS + 1][2]; | |
14634 | /* The following macro gives us the size of the nth dimension, Where | |
14635 | n is 1 based. */ | |
14636 | ||
14637 | -#define F77_DIM_SIZE(n) (f77_array_offset_tbl[n][1]) | |
14638 | +#define F77_DIM_COUNT(n) (f77_array_offset_tbl[n][1]) | |
14639 | ||
14640 | -/* The following gives us the offset for row n where n is 1-based. */ | |
14641 | +/* The following gives us the element size for row n where n is 1-based. */ | |
14642 | ||
14643 | -#define F77_DIM_OFFSET(n) (f77_array_offset_tbl[n][0]) | |
14644 | +#define F77_DIM_BYTE_STRIDE(n) (f77_array_offset_tbl[n][0]) | |
14645 | ||
14646 | int | |
14647 | f77_get_lowerbound (struct type *type) | |
14648 | { | |
14649 | + f_object_address_data_valid_or_error (type); | |
14650 | + | |
14651 | if (TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED (type)) | |
14652 | error (_("Lower bound may not be '*' in F77")); | |
14653 | ||
14654 | @@ -72,14 +72,17 @@ f77_get_lowerbound (struct type *type) | |
14655 | int | |
14656 | f77_get_upperbound (struct type *type) | |
14657 | { | |
14658 | + f_object_address_data_valid_or_error (type); | |
14659 | + | |
14660 | if (TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)) | |
14661 | { | |
14662 | - /* We have an assumed size array on our hands. Assume that | |
14663 | - upper_bound == lower_bound so that we show at least 1 element. | |
14664 | - If the user wants to see more elements, let him manually ask for 'em | |
14665 | - and we'll subscript the array and show him. */ | |
14666 | + /* We have an assumed size array on our hands. As type_length_get | |
14667 | + already assumes a length zero of arrays with underfined bounds VALADDR | |
14668 | + passed to the Fortran functions does not contained the real inferior | |
14669 | + memory content. User should request printing of specific array | |
14670 | + elements instead. */ | |
14671 | ||
14672 | - return f77_get_lowerbound (type); | |
14673 | + return f77_get_lowerbound (type) - 1; | |
14674 | } | |
14675 | ||
14676 | return TYPE_ARRAY_UPPER_BOUND_VALUE (type); | |
14677 | @@ -135,24 +138,29 @@ f77_create_arrayprint_offset_tbl (struct type *type, struct ui_file *stream) | |
14678 | upper = f77_get_upperbound (tmp_type); | |
14679 | lower = f77_get_lowerbound (tmp_type); | |
14680 | ||
14681 | - F77_DIM_SIZE (ndimen) = upper - lower + 1; | |
14682 | + F77_DIM_COUNT (ndimen) = upper - lower + 1; | |
14683 | + | |
14684 | + F77_DIM_BYTE_STRIDE (ndimen) = | |
14685 | + TYPE_ARRAY_BYTE_STRIDE_VALUE (tmp_type); | |
14686 | ||
14687 | tmp_type = TYPE_TARGET_TYPE (tmp_type); | |
14688 | ndimen++; | |
14689 | } | |
14690 | ||
14691 | - /* Now we multiply eltlen by all the offsets, so that later we | |
14692 | + /* Now we multiply eltlen by all the BYTE_STRIDEs, so that later we | |
14693 | can print out array elements correctly. Up till now we | |
14694 | - know an offset to apply to get the item but we also | |
14695 | + know an eltlen to apply to get the item but we also | |
14696 | have to know how much to add to get to the next item */ | |
14697 | ||
14698 | ndimen--; | |
14699 | eltlen = TYPE_LENGTH (tmp_type); | |
14700 | - F77_DIM_OFFSET (ndimen) = eltlen; | |
14701 | + if (F77_DIM_BYTE_STRIDE (ndimen) == 0) | |
14702 | + F77_DIM_BYTE_STRIDE (ndimen) = eltlen; | |
14703 | while (--ndimen > 0) | |
14704 | { | |
14705 | - eltlen *= F77_DIM_SIZE (ndimen + 1); | |
14706 | - F77_DIM_OFFSET (ndimen) = eltlen; | |
14707 | + eltlen *= F77_DIM_COUNT (ndimen + 1); | |
14708 | + if (F77_DIM_BYTE_STRIDE (ndimen) == 0) | |
14709 | + F77_DIM_BYTE_STRIDE (ndimen) = eltlen; | |
14710 | } | |
14711 | } | |
14712 | ||
14713 | @@ -172,34 +180,34 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type, | |
14714 | ||
14715 | if (nss != ndimensions) | |
14716 | { | |
14717 | - for (i = 0; (i < F77_DIM_SIZE (nss) && (*elts) < options->print_max); i++) | |
14718 | + for (i = 0; (i < F77_DIM_COUNT (nss) && (*elts) < options->print_max); i++) | |
14719 | { | |
14720 | fprintf_filtered (stream, "( "); | |
14721 | f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type), | |
14722 | - valaddr + i * F77_DIM_OFFSET (nss), | |
14723 | - address + i * F77_DIM_OFFSET (nss), | |
14724 | + valaddr + i * F77_DIM_BYTE_STRIDE (nss), | |
14725 | + address + i * F77_DIM_BYTE_STRIDE (nss), | |
14726 | stream, recurse, options, elts); | |
14727 | fprintf_filtered (stream, ") "); | |
14728 | } | |
14729 | - if (*elts >= options->print_max && i < F77_DIM_SIZE (nss)) | |
14730 | + if (*elts >= options->print_max && i < F77_DIM_COUNT (nss)) | |
14731 | fprintf_filtered (stream, "..."); | |
14732 | } | |
14733 | else | |
14734 | { | |
14735 | - for (i = 0; i < F77_DIM_SIZE (nss) && (*elts) < options->print_max; | |
14736 | + for (i = 0; i < F77_DIM_COUNT (nss) && (*elts) < options->print_max; | |
14737 | i++, (*elts)++) | |
14738 | { | |
14739 | val_print (TYPE_TARGET_TYPE (type), | |
14740 | - valaddr + i * F77_DIM_OFFSET (ndimensions), | |
14741 | + valaddr + i * F77_DIM_BYTE_STRIDE (ndimensions), | |
14742 | 0, | |
14743 | - address + i * F77_DIM_OFFSET (ndimensions), | |
14744 | + address + i * F77_DIM_BYTE_STRIDE (ndimensions), | |
14745 | stream, recurse, options, current_language); | |
14746 | ||
14747 | - if (i != (F77_DIM_SIZE (nss) - 1)) | |
14748 | + if (i != (F77_DIM_COUNT (nss) - 1)) | |
14749 | fprintf_filtered (stream, ", "); | |
14750 | ||
14751 | if ((*elts == options->print_max - 1) | |
14752 | - && (i != (F77_DIM_SIZE (nss) - 1))) | |
14753 | + && (i != (F77_DIM_COUNT (nss) - 1))) | |
14754 | fprintf_filtered (stream, "..."); | |
14755 | } | |
14756 | } | |
14757 | @@ -251,12 +259,16 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
14758 | CORE_ADDR addr; | |
14759 | int index; | |
14760 | ||
14761 | + if (f_object_address_data_valid_print_to_stream (type, stream) != NULL) | |
14762 | + return 0; | |
14763 | + | |
14764 | CHECK_TYPEDEF (type); | |
14765 | switch (TYPE_CODE (type)) | |
14766 | { | |
14767 | case TYPE_CODE_STRING: | |
14768 | f77_get_dynamic_length_of_aggregate (type); | |
14769 | - LA_PRINT_STRING (stream, valaddr, TYPE_LENGTH (type), 1, 0, options); | |
14770 | + LA_PRINT_STRING (stream, builtin_type (current_gdbarch)->builtin_char, | |
14771 | + valaddr, TYPE_LENGTH (type), 0, options); | |
14772 | break; | |
14773 | ||
14774 | case TYPE_CODE_ARRAY: | |
14775 | @@ -293,7 +305,7 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
14776 | && TYPE_CODE (elttype) == TYPE_CODE_INT | |
14777 | && (options->format == 0 || options->format == 's') | |
14778 | && addr != 0) | |
14779 | - i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream, | |
14780 | + i = val_print_string (TYPE_TARGET_TYPE (type), addr, -1, stream, | |
14781 | options); | |
14782 | ||
14783 | /* Return number of characters printed, including the terminating | |
14784 | @@ -365,7 +377,7 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
14785 | { | |
14786 | fputs_filtered (" ", stream); | |
14787 | LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr), | |
14788 | - stream); | |
14789 | + type, stream); | |
14790 | } | |
14791 | } | |
14792 | break; | |
14793 | @@ -464,22 +476,54 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
14794 | return 0; | |
14795 | } | |
14796 | ||
14797 | -static void | |
14798 | -list_all_visible_commons (char *funname) | |
14799 | +static int | |
14800 | +info_common_command_for_block (struct block *block, struct frame_info *frame, | |
14801 | + const char *comname) | |
14802 | { | |
14803 | - SAVED_F77_COMMON_PTR tmp; | |
14804 | - | |
14805 | - tmp = head_common_list; | |
14806 | - | |
14807 | - printf_filtered (_("All COMMON blocks visible at this level:\n\n")); | |
14808 | - | |
14809 | - while (tmp != NULL) | |
14810 | - { | |
14811 | - if (strcmp (tmp->owning_function, funname) == 0) | |
14812 | - printf_filtered ("%s\n", tmp->name); | |
14813 | - | |
14814 | - tmp = tmp->next; | |
14815 | - } | |
14816 | + struct dict_iterator iter; | |
14817 | + struct symbol *sym; | |
14818 | + int values_printed = 0; | |
14819 | + const char *name; | |
14820 | + struct value_print_options opts; | |
14821 | + | |
14822 | + get_user_print_options (&opts); | |
14823 | + | |
14824 | + ALL_BLOCK_SYMBOLS (block, iter, sym) | |
14825 | + if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN) | |
14826 | + { | |
14827 | + struct type *type = SYMBOL_TYPE (sym); | |
14828 | + int index; | |
14829 | + | |
14830 | + gdb_assert (SYMBOL_CLASS (sym) == LOC_STATIC); | |
14831 | + gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT); | |
14832 | + | |
14833 | + if (comname && (!SYMBOL_LINKAGE_NAME (sym) | |
14834 | + || strcmp (comname, SYMBOL_LINKAGE_NAME (sym)) != 0)) | |
14835 | + continue; | |
14836 | + | |
14837 | + values_printed = 1; | |
14838 | + if (SYMBOL_PRINT_NAME (sym)) | |
14839 | + printf_filtered (_("Contents of F77 COMMON block '%s':\n"), | |
14840 | + SYMBOL_PRINT_NAME (sym)); | |
14841 | + else | |
14842 | + printf_filtered (_("Contents of blank COMMON block:\n")); | |
14843 | + | |
14844 | + for (index = 0; index < TYPE_NFIELDS (type); index++) | |
14845 | + { | |
14846 | + struct value *val; | |
14847 | + | |
14848 | + gdb_assert (field_is_static (&TYPE_FIELD (type, index))); | |
14849 | + val = value_static_field (type, index); | |
14850 | + | |
14851 | + printf_filtered ("%s = ", TYPE_FIELD_NAME (type, index)); | |
14852 | + value_print (val, gdb_stdout, &opts); | |
14853 | + putchar_filtered ('\n'); | |
14854 | + } | |
14855 | + | |
14856 | + putchar_filtered ('\n'); | |
14857 | + } | |
14858 | + | |
14859 | + return values_printed; | |
14860 | } | |
14861 | ||
14862 | /* This function is used to print out the values in a given COMMON | |
14863 | @@ -489,11 +533,9 @@ list_all_visible_commons (char *funname) | |
14864 | static void | |
14865 | info_common_command (char *comname, int from_tty) | |
14866 | { | |
14867 | - SAVED_F77_COMMON_PTR the_common; | |
14868 | - COMMON_ENTRY_PTR entry; | |
14869 | struct frame_info *fi; | |
14870 | - char *funname = 0; | |
14871 | - struct symbol *func; | |
14872 | + struct block *block; | |
14873 | + int values_printed = 0; | |
14874 | ||
14875 | /* We have been told to display the contents of F77 COMMON | |
14876 | block supposedly visible in this function. Let us | |
14877 | @@ -505,136 +547,32 @@ info_common_command (char *comname, int from_tty) | |
14878 | /* The following is generally ripped off from stack.c's routine | |
14879 | print_frame_info() */ | |
14880 | ||
14881 | - func = find_pc_function (get_frame_pc (fi)); | |
14882 | - if (func) | |
14883 | - { | |
14884 | - /* In certain pathological cases, the symtabs give the wrong | |
14885 | - function (when we are in the first function in a file which | |
14886 | - is compiled without debugging symbols, the previous function | |
14887 | - is compiled with debugging symbols, and the "foo.o" symbol | |
14888 | - that is supposed to tell us where the file with debugging symbols | |
14889 | - ends has been truncated by ar because it is longer than 15 | |
14890 | - characters). | |
14891 | - | |
14892 | - So look in the minimal symbol tables as well, and if it comes | |
14893 | - up with a larger address for the function use that instead. | |
14894 | - I don't think this can ever cause any problems; there shouldn't | |
14895 | - be any minimal symbols in the middle of a function. | |
14896 | - FIXME: (Not necessarily true. What about text labels) */ | |
14897 | - | |
14898 | - struct minimal_symbol *msymbol = | |
14899 | - lookup_minimal_symbol_by_pc (get_frame_pc (fi)); | |
14900 | - | |
14901 | - if (msymbol != NULL | |
14902 | - && (SYMBOL_VALUE_ADDRESS (msymbol) | |
14903 | - > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) | |
14904 | - funname = SYMBOL_LINKAGE_NAME (msymbol); | |
14905 | - else | |
14906 | - funname = SYMBOL_LINKAGE_NAME (func); | |
14907 | - } | |
14908 | - else | |
14909 | - { | |
14910 | - struct minimal_symbol *msymbol = | |
14911 | - lookup_minimal_symbol_by_pc (get_frame_pc (fi)); | |
14912 | - | |
14913 | - if (msymbol != NULL) | |
14914 | - funname = SYMBOL_LINKAGE_NAME (msymbol); | |
14915 | - else /* Got no 'funname', code below will fail. */ | |
14916 | - error (_("No function found for frame.")); | |
14917 | - } | |
14918 | - | |
14919 | - /* If comname is NULL, we assume the user wishes to see the | |
14920 | - which COMMON blocks are visible here and then return */ | |
14921 | - | |
14922 | - if (comname == 0) | |
14923 | + block = get_frame_block (fi, 0); | |
14924 | + if (block == NULL) | |
14925 | { | |
14926 | - list_all_visible_commons (funname); | |
14927 | + printf_filtered (_("No symbol table info available.\n")); | |
14928 | return; | |
14929 | } | |
14930 | ||
14931 | - the_common = find_common_for_function (comname, funname); | |
14932 | - | |
14933 | - if (the_common) | |
14934 | + while (block) | |
14935 | { | |
14936 | - if (strcmp (comname, BLANK_COMMON_NAME_LOCAL) == 0) | |
14937 | - printf_filtered (_("Contents of blank COMMON block:\n")); | |
14938 | - else | |
14939 | - printf_filtered (_("Contents of F77 COMMON block '%s':\n"), comname); | |
14940 | - | |
14941 | - printf_filtered ("\n"); | |
14942 | - entry = the_common->entries; | |
14943 | - | |
14944 | - while (entry != NULL) | |
14945 | - { | |
14946 | - print_variable_and_value (NULL, entry->symbol, fi, gdb_stdout, 0); | |
14947 | - entry = entry->next; | |
14948 | - } | |
14949 | + if (info_common_command_for_block (block, fi, comname)) | |
14950 | + values_printed = 1; | |
14951 | + /* After handling the function's top-level block, stop. Don't | |
14952 | + continue to its superblock, the block of per-file symbols. */ | |
14953 | + if (BLOCK_FUNCTION (block)) | |
14954 | + break; | |
14955 | + block = BLOCK_SUPERBLOCK (block); | |
14956 | } | |
14957 | - else | |
14958 | - printf_filtered (_("Cannot locate the common block %s in function '%s'\n"), | |
14959 | - comname, funname); | |
14960 | -} | |
14961 | - | |
14962 | -/* This function is used to determine whether there is a | |
14963 | - F77 common block visible at the current scope called 'comname'. */ | |
14964 | - | |
14965 | -#if 0 | |
14966 | -static int | |
14967 | -there_is_a_visible_common_named (char *comname) | |
14968 | -{ | |
14969 | - SAVED_F77_COMMON_PTR the_common; | |
14970 | - struct frame_info *fi; | |
14971 | - char *funname = 0; | |
14972 | - struct symbol *func; | |
14973 | - | |
14974 | - if (comname == NULL) | |
14975 | - error (_("Cannot deal with NULL common name!")); | |
14976 | ||
14977 | - fi = get_selected_frame (_("No frame selected")); | |
14978 | - | |
14979 | - /* The following is generally ripped off from stack.c's routine | |
14980 | - print_frame_info() */ | |
14981 | - | |
14982 | - func = find_pc_function (fi->pc); | |
14983 | - if (func) | |
14984 | + if (!values_printed) | |
14985 | { | |
14986 | - /* In certain pathological cases, the symtabs give the wrong | |
14987 | - function (when we are in the first function in a file which | |
14988 | - is compiled without debugging symbols, the previous function | |
14989 | - is compiled with debugging symbols, and the "foo.o" symbol | |
14990 | - that is supposed to tell us where the file with debugging symbols | |
14991 | - ends has been truncated by ar because it is longer than 15 | |
14992 | - characters). | |
14993 | - | |
14994 | - So look in the minimal symbol tables as well, and if it comes | |
14995 | - up with a larger address for the function use that instead. | |
14996 | - I don't think this can ever cause any problems; there shouldn't | |
14997 | - be any minimal symbols in the middle of a function. | |
14998 | - FIXME: (Not necessarily true. What about text labels) */ | |
14999 | - | |
15000 | - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); | |
15001 | - | |
15002 | - if (msymbol != NULL | |
15003 | - && (SYMBOL_VALUE_ADDRESS (msymbol) | |
15004 | - > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) | |
15005 | - funname = SYMBOL_LINKAGE_NAME (msymbol); | |
15006 | + if (comname) | |
15007 | + printf_filtered (_("No common block '%s'.\n"), comname); | |
15008 | else | |
15009 | - funname = SYMBOL_LINKAGE_NAME (func); | |
15010 | + printf_filtered (_("No common blocks.\n")); | |
15011 | } | |
15012 | - else | |
15013 | - { | |
15014 | - struct minimal_symbol *msymbol = | |
15015 | - lookup_minimal_symbol_by_pc (fi->pc); | |
15016 | - | |
15017 | - if (msymbol != NULL) | |
15018 | - funname = SYMBOL_LINKAGE_NAME (msymbol); | |
15019 | - } | |
15020 | - | |
15021 | - the_common = find_common_for_function (comname, funname); | |
15022 | - | |
15023 | - return (the_common ? 1 : 0); | |
15024 | } | |
15025 | -#endif | |
15026 | ||
15027 | void | |
15028 | _initialize_f_valprint (void) | |
15029 | diff --git a/gdb/findcmd.c b/gdb/findcmd.c | |
15030 | index 7ae43e5..2894948 100644 | |
15031 | --- a/gdb/findcmd.c | |
15032 | +++ b/gdb/findcmd.c | |
15033 | @@ -26,7 +26,7 @@ | |
15034 | ||
15035 | /* Copied from bfd_put_bits. */ | |
15036 | ||
15037 | -static void | |
15038 | +void | |
15039 | put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p) | |
15040 | { | |
15041 | int i; | |
15042 | @@ -44,6 +44,41 @@ put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p) | |
15043 | } | |
15044 | } | |
15045 | ||
15046 | +/* Allocates a buffer in *PATTERN_BUF, with a hard-coded initial size which | |
15047 | + will be returned in *PATTERN_BUF_SIZE. *PATTERN_BUF_END points to the same | |
15048 | + place as *PATTERN_BUF, indicating that the buffer is initially empty. */ | |
15049 | + | |
15050 | +void | |
15051 | +allocate_pattern_buffer (char **pattern_buf, char **pattern_buf_end, | |
15052 | + ULONGEST *pattern_buf_size) | |
15053 | +{ | |
15054 | +#define INITIAL_PATTERN_BUF_SIZE 100 | |
15055 | + *pattern_buf_size = INITIAL_PATTERN_BUF_SIZE; | |
15056 | + *pattern_buf = xmalloc (*pattern_buf_size); | |
15057 | + *pattern_buf_end = *pattern_buf; | |
15058 | +} | |
15059 | + | |
15060 | +/* Grows *PATTERN_BUF by a factor of two if it's not large enough to hold | |
15061 | + VAL_BYTES more bytes or a 64-bit value, whichever is larger. | |
15062 | + *PATTERN_BUF_END is updated as necessary. */ | |
15063 | + | |
15064 | +void | |
15065 | +increase_pattern_buffer (char **pattern_buf, char **pattern_buf_end, | |
15066 | + ULONGEST *pattern_buf_size, int val_bytes) | |
15067 | +{ | |
15068 | + /* Keep it simple and assume size == 'g' when watching for when we | |
15069 | + need to grow the pattern buf. */ | |
15070 | + if ((*pattern_buf_end - *pattern_buf + max (val_bytes, sizeof (int64_t))) | |
15071 | + > *pattern_buf_size) | |
15072 | + { | |
15073 | + size_t current_offset = *pattern_buf_end - *pattern_buf; | |
15074 | + | |
15075 | + *pattern_buf_size *= 2; | |
15076 | + *pattern_buf = xrealloc (*pattern_buf, *pattern_buf_size); | |
15077 | + *pattern_buf_end = *pattern_buf + current_offset; | |
15078 | + } | |
15079 | +} | |
15080 | + | |
15081 | /* Subroutine of find_command to simplify it. | |
15082 | Parse the arguments of the "find" command. */ | |
15083 | ||
15084 | @@ -59,8 +94,7 @@ parse_find_args (char *args, ULONGEST *max_countp, | |
15085 | char *pattern_buf; | |
15086 | /* Current size of search pattern buffer. | |
15087 | We realloc space as needed. */ | |
15088 | -#define INITIAL_PATTERN_BUF_SIZE 100 | |
15089 | - ULONGEST pattern_buf_size = INITIAL_PATTERN_BUF_SIZE; | |
15090 | + ULONGEST pattern_buf_size; | |
15091 | /* Pointer to one past the last in-use part of pattern_buf. */ | |
15092 | char *pattern_buf_end; | |
15093 | ULONGEST pattern_len; | |
15094 | @@ -74,8 +108,7 @@ parse_find_args (char *args, ULONGEST *max_countp, | |
15095 | if (args == NULL) | |
15096 | error (_("Missing search parameters.")); | |
15097 | ||
15098 | - pattern_buf = xmalloc (pattern_buf_size); | |
15099 | - pattern_buf_end = pattern_buf; | |
15100 | + allocate_pattern_buffer (&pattern_buf, &pattern_buf_end, &pattern_buf_size); | |
15101 | old_cleanups = make_cleanup (free_current_contents, &pattern_buf); | |
15102 | ||
15103 | /* Get search granularity and/or max count if specified. | |
15104 | @@ -172,16 +205,8 @@ parse_find_args (char *args, ULONGEST *max_countp, | |
15105 | v = parse_to_comma_and_eval (&s); | |
15106 | val_bytes = TYPE_LENGTH (value_type (v)); | |
15107 | ||
15108 | - /* Keep it simple and assume size == 'g' when watching for when we | |
15109 | - need to grow the pattern buf. */ | |
15110 | - if ((pattern_buf_end - pattern_buf + max (val_bytes, sizeof (int64_t))) | |
15111 | - > pattern_buf_size) | |
15112 | - { | |
15113 | - size_t current_offset = pattern_buf_end - pattern_buf; | |
15114 | - pattern_buf_size *= 2; | |
15115 | - pattern_buf = xrealloc (pattern_buf, pattern_buf_size); | |
15116 | - pattern_buf_end = pattern_buf + current_offset; | |
15117 | - } | |
15118 | + increase_pattern_buffer (&pattern_buf, &pattern_buf_end, | |
15119 | + &pattern_buf_size, val_bytes); | |
15120 | ||
15121 | if (size != '\0') | |
15122 | { | |
15123 | @@ -236,6 +261,45 @@ parse_find_args (char *args, ULONGEST *max_countp, | |
15124 | discard_cleanups (old_cleanups); | |
15125 | } | |
15126 | ||
15127 | +/* Drives target_search_memory to sweep through the specified search space, | |
15128 | + possibly in several iterations (with one call to this function for each | |
15129 | + iteration). *START_ADDR is the address where the search starts, and is | |
15130 | + updated to the next starting address to continue the search. | |
15131 | + *SEARCH_SPACE_LEN is the amount of bytes which will be searched, and is | |
15132 | + updated for the next iteration. PATTERN_BUF holds the pattern to be searched | |
15133 | + for, PATTERN_LEN is the size of the pattern in bytes. If a match is found, | |
15134 | + it's address is put in *FOUND_ADDR. | |
15135 | + | |
15136 | + Returns 1 if found, 0 if not found, and -1 if there was an error requiring | |
15137 | + halting of the search (e.g. memory read error). */ | |
15138 | + | |
15139 | +int | |
15140 | +search_memory (CORE_ADDR *start_addr, ULONGEST *search_space_len, | |
15141 | + const char *pattern_buf, ULONGEST pattern_len, | |
15142 | + CORE_ADDR *found_addr) | |
15143 | +{ | |
15144 | + /* Offset from start of this iteration to the next iteration. */ | |
15145 | + ULONGEST next_iter_incr; | |
15146 | + int found; | |
15147 | + | |
15148 | + found = target_search_memory (*start_addr, *search_space_len, | |
15149 | + pattern_buf, pattern_len, found_addr); | |
15150 | + if (found <= 0) | |
15151 | + return found; | |
15152 | + | |
15153 | + /* Begin next iteration at one byte past this match. */ | |
15154 | + next_iter_incr = (*found_addr - *start_addr) + 1; | |
15155 | + | |
15156 | + /* For robustness, we don't let search_space_len go -ve here. */ | |
15157 | + if (*search_space_len >= next_iter_incr) | |
15158 | + *search_space_len -= next_iter_incr; | |
15159 | + else | |
15160 | + *search_space_len = 0; | |
15161 | + *start_addr += next_iter_incr; | |
15162 | + | |
15163 | + return found; | |
15164 | +} | |
15165 | + | |
15166 | static void | |
15167 | find_command (char *args, int from_tty) | |
15168 | { | |
15169 | @@ -264,12 +328,11 @@ find_command (char *args, int from_tty) | |
15170 | while (search_space_len >= pattern_len | |
15171 | && found_count < max_count) | |
15172 | { | |
15173 | - /* Offset from start of this iteration to the next iteration. */ | |
15174 | - ULONGEST next_iter_incr; | |
15175 | CORE_ADDR found_addr; | |
15176 | - int found = target_search_memory (start_addr, search_space_len, | |
15177 | - pattern_buf, pattern_len, &found_addr); | |
15178 | + int found; | |
15179 | ||
15180 | + found = search_memory (&start_addr, &search_space_len, pattern_buf, | |
15181 | + pattern_len, &found_addr); | |
15182 | if (found <= 0) | |
15183 | break; | |
15184 | ||
15185 | @@ -277,16 +340,6 @@ find_command (char *args, int from_tty) | |
15186 | printf_filtered ("\n"); | |
15187 | ++found_count; | |
15188 | last_found_addr = found_addr; | |
15189 | - | |
15190 | - /* Begin next iteration at one byte past this match. */ | |
15191 | - next_iter_incr = (found_addr - start_addr) + 1; | |
15192 | - | |
15193 | - /* For robustness, we don't let search_space_len go -ve here. */ | |
15194 | - if (search_space_len >= next_iter_incr) | |
15195 | - search_space_len -= next_iter_incr; | |
15196 | - else | |
15197 | - search_space_len = 0; | |
15198 | - start_addr += next_iter_incr; | |
15199 | } | |
15200 | ||
15201 | /* Record and print the results. */ | |
15202 | diff --git a/gdb/findvar.c b/gdb/findvar.c | |
15203 | index 1048887..b958ec6 100644 | |
15204 | --- a/gdb/findvar.c | |
15205 | +++ b/gdb/findvar.c | |
15206 | @@ -35,6 +35,7 @@ | |
15207 | #include "user-regs.h" | |
15208 | #include "block.h" | |
15209 | #include "objfiles.h" | |
15210 | +#include "dwarf2loc.h" | |
15211 | ||
15212 | /* Basic byte-swapping routines. GDB has needed these for a long time... | |
15213 | All extract a target-format integer at ADDR which is LEN bytes long. */ | |
15214 | @@ -275,7 +276,7 @@ value_of_register (int regnum, struct frame_info *frame) | |
15215 | memcpy (value_contents_raw (reg_val), raw_buffer, | |
15216 | register_size (gdbarch, regnum)); | |
15217 | VALUE_LVAL (reg_val) = lval; | |
15218 | - VALUE_ADDRESS (reg_val) = addr; | |
15219 | + set_value_address (reg_val, addr); | |
15220 | VALUE_REGNUM (reg_val) = regnum; | |
15221 | set_value_optimized_out (reg_val, optim); | |
15222 | VALUE_FRAME_ID (reg_val) = get_frame_id (frame); | |
15223 | @@ -382,27 +383,16 @@ symbol_read_needs_frame (struct symbol *sym) | |
15224 | /* Given a struct symbol for a variable, | |
15225 | and a stack frame id, read the value of the variable | |
15226 | and return a (pointer to a) struct value containing the value. | |
15227 | - If the variable cannot be found, return a zero pointer. */ | |
15228 | + If the variable cannot be found, return a zero pointer. | |
15229 | + We have to first find the address of the variable before allocating struct | |
15230 | + value to return as its size may depend on DW_OP_PUSH_OBJECT_ADDRESS possibly | |
15231 | + used by its type. */ | |
15232 | ||
15233 | struct value * | |
15234 | read_var_value (struct symbol *var, struct frame_info *frame) | |
15235 | { | |
15236 | - struct value *v; | |
15237 | struct type *type = SYMBOL_TYPE (var); | |
15238 | CORE_ADDR addr; | |
15239 | - int len; | |
15240 | - | |
15241 | - if (SYMBOL_CLASS (var) == LOC_COMPUTED | |
15242 | - || SYMBOL_CLASS (var) == LOC_REGISTER) | |
15243 | - /* These cases do not use V. */ | |
15244 | - v = NULL; | |
15245 | - else | |
15246 | - { | |
15247 | - v = allocate_value (type); | |
15248 | - VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */ | |
15249 | - } | |
15250 | - | |
15251 | - len = TYPE_LENGTH (type); | |
15252 | ||
15253 | if (symbol_read_needs_frame (var)) | |
15254 | gdb_assert (frame); | |
15255 | @@ -410,31 +400,39 @@ read_var_value (struct symbol *var, struct frame_info *frame) | |
15256 | switch (SYMBOL_CLASS (var)) | |
15257 | { | |
15258 | case LOC_CONST: | |
15259 | - /* Put the constant back in target format. */ | |
15260 | - store_signed_integer (value_contents_raw (v), len, | |
15261 | - (LONGEST) SYMBOL_VALUE (var)); | |
15262 | - VALUE_LVAL (v) = not_lval; | |
15263 | - return v; | |
15264 | + { | |
15265 | + /* Put the constant back in target format. */ | |
15266 | + struct value *v = allocate_value (type); | |
15267 | + VALUE_LVAL (v) = not_lval; | |
15268 | + store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type), | |
15269 | + (LONGEST) SYMBOL_VALUE (var)); | |
15270 | + return v; | |
15271 | + } | |
15272 | ||
15273 | case LOC_LABEL: | |
15274 | - /* Put the constant back in target format. */ | |
15275 | - if (overlay_debugging) | |
15276 | - { | |
15277 | - CORE_ADDR addr | |
15278 | - = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), | |
15279 | - SYMBOL_OBJ_SECTION (var)); | |
15280 | - store_typed_address (value_contents_raw (v), type, addr); | |
15281 | - } | |
15282 | - else | |
15283 | - store_typed_address (value_contents_raw (v), type, | |
15284 | - SYMBOL_VALUE_ADDRESS (var)); | |
15285 | - VALUE_LVAL (v) = not_lval; | |
15286 | - return v; | |
15287 | + { | |
15288 | + /* Put the constant back in target format. */ | |
15289 | + struct value *v = allocate_value (type); | |
15290 | + VALUE_LVAL (v) = not_lval; | |
15291 | + if (overlay_debugging) | |
15292 | + { | |
15293 | + CORE_ADDR addr | |
15294 | + = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), | |
15295 | + SYMBOL_OBJ_SECTION (var)); | |
15296 | + store_typed_address (value_contents_raw (v), type, addr); | |
15297 | + } | |
15298 | + else | |
15299 | + store_typed_address (value_contents_raw (v), type, | |
15300 | + SYMBOL_VALUE_ADDRESS (var)); | |
15301 | + return v; | |
15302 | + } | |
15303 | ||
15304 | case LOC_CONST_BYTES: | |
15305 | { | |
15306 | - memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), len); | |
15307 | + struct value *v = allocate_value (type); | |
15308 | VALUE_LVAL (v) = not_lval; | |
15309 | + memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), | |
15310 | + TYPE_LENGTH (type)); | |
15311 | return v; | |
15312 | } | |
15313 | ||
15314 | @@ -476,12 +474,23 @@ read_var_value (struct symbol *var, struct frame_info *frame) | |
15315 | break; | |
15316 | ||
15317 | case LOC_BLOCK: | |
15318 | - if (overlay_debugging) | |
15319 | - VALUE_ADDRESS (v) = symbol_overlayed_address | |
15320 | - (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var)); | |
15321 | - else | |
15322 | - VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var)); | |
15323 | - return v; | |
15324 | + { | |
15325 | + CORE_ADDR addr; | |
15326 | + struct value *v; | |
15327 | + | |
15328 | + if (overlay_debugging) | |
15329 | + addr = symbol_overlayed_address | |
15330 | + (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var)); | |
15331 | + else | |
15332 | + addr = BLOCK_START (SYMBOL_BLOCK_VALUE (var)); | |
15333 | + /* ADDR is set here for ALLOCATE_VALUE's CHECK_TYPEDEF for | |
15334 | + DW_OP_push_object_address. */ | |
15335 | + object_address_set (addr); | |
15336 | + v = allocate_value (type); | |
15337 | + VALUE_ADDRESS (v) = addr; | |
15338 | + VALUE_LVAL (v) = lval_memory; | |
15339 | + return v; | |
15340 | + } | |
15341 | ||
15342 | case LOC_REGISTER: | |
15343 | case LOC_REGPARM_ADDR: | |
15344 | @@ -499,7 +508,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) | |
15345 | error (_("Value of register variable not available.")); | |
15346 | ||
15347 | addr = value_as_address (regval); | |
15348 | - VALUE_LVAL (v) = lval_memory; | |
15349 | } | |
15350 | else | |
15351 | { | |
15352 | @@ -542,18 +550,33 @@ read_var_value (struct symbol *var, struct frame_info *frame) | |
15353 | break; | |
15354 | ||
15355 | case LOC_OPTIMIZED_OUT: | |
15356 | - VALUE_LVAL (v) = not_lval; | |
15357 | - set_value_optimized_out (v, 1); | |
15358 | - return v; | |
15359 | + { | |
15360 | + struct value *v = allocate_value (type); | |
15361 | + | |
15362 | + VALUE_LVAL (v) = not_lval; | |
15363 | + set_value_optimized_out (v, 1); | |
15364 | + return v; | |
15365 | + } | |
15366 | ||
15367 | default: | |
15368 | error (_("Cannot look up value of a botched symbol.")); | |
15369 | break; | |
15370 | } | |
15371 | ||
15372 | - VALUE_ADDRESS (v) = addr; | |
15373 | - set_value_lazy (v, 1); | |
15374 | - return v; | |
15375 | + { | |
15376 | + struct value *v; | |
15377 | + | |
15378 | + /* ADDR is set here for ALLOCATE_VALUE's CHECK_TYPEDEF for | |
15379 | + DW_OP_PUSH_OBJECT_ADDRESS. */ | |
15380 | + object_address_set (addr); | |
15381 | + v = allocate_value (type); | |
15382 | + VALUE_ADDRESS (v) = addr; | |
15383 | + VALUE_LVAL (v) = lval_memory; | |
15384 | + | |
15385 | + set_value_lazy (v, 1); | |
15386 | + | |
15387 | + return v; | |
15388 | + } | |
15389 | } | |
15390 | ||
15391 | /* Install default attributes for register values. */ | |
15392 | @@ -590,10 +613,11 @@ struct value * | |
15393 | value_from_register (struct type *type, int regnum, struct frame_info *frame) | |
15394 | { | |
15395 | struct gdbarch *gdbarch = get_frame_arch (frame); | |
15396 | - struct type *type1 = check_typedef (type); | |
15397 | struct value *v; | |
15398 | ||
15399 | - if (gdbarch_convert_register_p (gdbarch, regnum, type1)) | |
15400 | + type = check_typedef (type); | |
15401 | + | |
15402 | + if (gdbarch_convert_register_p (gdbarch, regnum, type)) | |
15403 | { | |
15404 | /* The ISA/ABI need to something weird when obtaining the | |
15405 | specified value from this register. It might need to | |
15406 | @@ -607,7 +631,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) | |
15407 | VALUE_FRAME_ID (v) = get_frame_id (frame); | |
15408 | VALUE_REGNUM (v) = regnum; | |
15409 | gdbarch_register_to_value (gdbarch, | |
15410 | - frame, regnum, type1, value_contents_raw (v)); | |
15411 | + frame, regnum, type, value_contents_raw (v)); | |
15412 | } | |
15413 | else | |
15414 | { | |
15415 | diff --git a/gdb/frame.c b/gdb/frame.c | |
15416 | index dfd6b3d..2ea37c3 100644 | |
15417 | --- a/gdb/frame.c | |
15418 | +++ b/gdb/frame.c | |
15419 | @@ -596,7 +596,7 @@ frame_register_unwind (struct frame_info *frame, int regnum, | |
15420 | ||
15421 | *optimizedp = value_optimized_out (value); | |
15422 | *lvalp = VALUE_LVAL (value); | |
15423 | - *addrp = VALUE_ADDRESS (value); | |
15424 | + *addrp = value_address (value); | |
15425 | *realnump = VALUE_REGNUM (value); | |
15426 | ||
15427 | if (bufferp) | |
15428 | @@ -682,7 +682,7 @@ frame_unwind_register_value (struct frame_info *frame, int regnum) | |
15429 | VALUE_REGNUM (value)); | |
15430 | else if (VALUE_LVAL (value) == lval_memory) | |
15431 | fprintf_unfiltered (gdb_stdlog, " address=0x%s", | |
15432 | - paddr_nz (VALUE_ADDRESS (value))); | |
15433 | + paddr_nz (value_address (value))); | |
15434 | else | |
15435 | fprintf_unfiltered (gdb_stdlog, " computed"); | |
15436 | ||
15437 | diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c | |
15438 | index ff387db..452f70c 100644 | |
15439 | --- a/gdb/frv-tdep.c | |
15440 | +++ b/gdb/frv-tdep.c | |
15441 | @@ -1230,7 +1230,7 @@ frv_push_dummy_call (struct gdbarch *gdbarch, struct value *function, | |
15442 | ||
15443 | if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION) | |
15444 | { | |
15445 | - store_unsigned_integer (valbuf, 4, VALUE_ADDRESS (arg)); | |
15446 | + store_unsigned_integer (valbuf, 4, value_address (arg)); | |
15447 | typecode = TYPE_CODE_PTR; | |
15448 | len = 4; | |
15449 | val = valbuf; | |
15450 | diff --git a/gdb/gdb_locale.h b/gdb/gdb_locale.h | |
15451 | index e8ba0ea..4fa4d3d 100644 | |
15452 | --- a/gdb/gdb_locale.h | |
15453 | +++ b/gdb/gdb_locale.h | |
15454 | @@ -41,4 +41,8 @@ | |
15455 | # define N_(String) (String) | |
15456 | #endif | |
15457 | ||
15458 | +#ifdef HAVE_LANGINFO_CODESET | |
15459 | +#include <langinfo.h> | |
15460 | +#endif | |
15461 | + | |
15462 | #endif /* GDB_LOCALE_H */ | |
15463 | diff --git a/gdb/gdb_obstack.h b/gdb/gdb_obstack.h | |
15464 | index 48f49cd..cd1a1d7 100644 | |
15465 | --- a/gdb/gdb_obstack.h | |
15466 | +++ b/gdb/gdb_obstack.h | |
15467 | @@ -45,4 +45,7 @@ | |
15468 | #define obstack_grow_str0(OBSTACK,STRING) \ | |
15469 | obstack_grow0 (OBSTACK, STRING, strlen (STRING)) | |
15470 | ||
15471 | +#define obstack_grow_wstr(OBSTACK, WSTRING) \ | |
15472 | + obstack_grow (OBSTACK, WSTRING, sizeof (wchar_t) * wcslen (WSTRING)) | |
15473 | + | |
15474 | #endif | |
15475 | diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c | |
15476 | index 3273b34..d6c737b 100644 | |
15477 | --- a/gdb/gdbarch.c | |
15478 | +++ b/gdb/gdbarch.c | |
15479 | @@ -243,6 +243,11 @@ struct gdbarch | |
15480 | gdbarch_target_signal_to_host_ftype *target_signal_to_host; | |
15481 | gdbarch_get_siginfo_type_ftype *get_siginfo_type; | |
15482 | gdbarch_record_special_symbol_ftype *record_special_symbol; | |
15483 | + gdbarch_get_syscall_number_ftype *get_syscall_number; | |
15484 | + gdbarch_get_syscall_by_number_ftype *get_syscall_by_number; | |
15485 | + gdbarch_get_syscall_by_name_ftype *get_syscall_by_name; | |
15486 | + gdbarch_get_syscall_names_ftype *get_syscall_names; | |
15487 | + const char * xml_syscall_filename; | |
15488 | int has_global_solist; | |
15489 | }; | |
15490 | ||
15491 | @@ -378,6 +383,11 @@ struct gdbarch startup_gdbarch = | |
15492 | default_target_signal_to_host, /* target_signal_to_host */ | |
15493 | 0, /* get_siginfo_type */ | |
15494 | 0, /* record_special_symbol */ | |
15495 | + 0, /* get_syscall_number */ | |
15496 | + 0, /* get_syscall_by_number */ | |
15497 | + 0, /* get_syscall_by_name */ | |
15498 | + 0, /* get_syscall_names */ | |
15499 | + 0, /* xml_syscall_filename */ | |
15500 | 0, /* has_global_solist */ | |
15501 | /* startup_gdbarch() */ | |
15502 | }; | |
15503 | @@ -634,6 +644,11 @@ verify_gdbarch (struct gdbarch *gdbarch) | |
15504 | /* Skip verify of target_signal_to_host, invalid_p == 0 */ | |
15505 | /* Skip verify of get_siginfo_type, has predicate */ | |
15506 | /* Skip verify of record_special_symbol, has predicate */ | |
15507 | + /* Skip verify of get_syscall_number, has predicate */ | |
15508 | + /* Skip verify of get_syscall_by_number, has predicate */ | |
15509 | + /* Skip verify of get_syscall_by_name, has predicate */ | |
15510 | + /* Skip verify of get_syscall_names, has predicate */ | |
15511 | + /* Skip verify of xml_syscall_filename, invalid_p == 0 */ | |
15512 | /* Skip verify of has_global_solist, invalid_p == 0 */ | |
15513 | buf = ui_file_xstrdup (log, &dummy); | |
15514 | make_cleanup (xfree, buf); | |
15515 | @@ -859,6 +874,30 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) | |
15516 | "gdbarch_dump: get_siginfo_type = <%s>\n", | |
15517 | host_address_to_string (gdbarch->get_siginfo_type)); | |
15518 | fprintf_unfiltered (file, | |
15519 | + "gdbarch_dump: gdbarch_get_syscall_by_name_p() = %d\n", | |
15520 | + gdbarch_get_syscall_by_name_p (gdbarch)); | |
15521 | + fprintf_unfiltered (file, | |
15522 | + "gdbarch_dump: get_syscall_by_name = <%s>\n", | |
15523 | + host_address_to_string (gdbarch->get_syscall_by_name)); | |
15524 | + fprintf_unfiltered (file, | |
15525 | + "gdbarch_dump: gdbarch_get_syscall_by_number_p() = %d\n", | |
15526 | + gdbarch_get_syscall_by_number_p (gdbarch)); | |
15527 | + fprintf_unfiltered (file, | |
15528 | + "gdbarch_dump: get_syscall_by_number = <%s>\n", | |
15529 | + host_address_to_string (gdbarch->get_syscall_by_number)); | |
15530 | + fprintf_unfiltered (file, | |
15531 | + "gdbarch_dump: gdbarch_get_syscall_names_p() = %d\n", | |
15532 | + gdbarch_get_syscall_names_p (gdbarch)); | |
15533 | + fprintf_unfiltered (file, | |
15534 | + "gdbarch_dump: get_syscall_names = <%s>\n", | |
15535 | + host_address_to_string (gdbarch->get_syscall_names)); | |
15536 | + fprintf_unfiltered (file, | |
15537 | + "gdbarch_dump: gdbarch_get_syscall_number_p() = %d\n", | |
15538 | + gdbarch_get_syscall_number_p (gdbarch)); | |
15539 | + fprintf_unfiltered (file, | |
15540 | + "gdbarch_dump: get_syscall_number = <%s>\n", | |
15541 | + host_address_to_string (gdbarch->get_syscall_number)); | |
15542 | + fprintf_unfiltered (file, | |
15543 | "gdbarch_dump: has_global_solist = %s\n", | |
15544 | plongest (gdbarch->has_global_solist)); | |
15545 | fprintf_unfiltered (file, | |
15546 | @@ -1122,6 +1161,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) | |
15547 | fprintf_unfiltered (file, | |
15548 | "gdbarch_dump: write_pc = <%s>\n", | |
15549 | host_address_to_string (gdbarch->write_pc)); | |
15550 | + fprintf_unfiltered (file, | |
15551 | + "gdbarch_dump: xml_syscall_filename = %s\n", | |
15552 | + gdbarch->xml_syscall_filename); | |
15553 | if (gdbarch->dump_tdep != NULL) | |
15554 | gdbarch->dump_tdep (gdbarch, file); | |
15555 | } | |
15556 | @@ -3333,6 +3375,119 @@ set_gdbarch_record_special_symbol (struct gdbarch *gdbarch, | |
15557 | } | |
15558 | ||
15559 | int | |
15560 | +gdbarch_get_syscall_number_p (struct gdbarch *gdbarch) | |
15561 | +{ | |
15562 | + gdb_assert (gdbarch != NULL); | |
15563 | + return gdbarch->get_syscall_number != NULL; | |
15564 | +} | |
15565 | + | |
15566 | +LONGEST | |
15567 | +gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid) | |
15568 | +{ | |
15569 | + gdb_assert (gdbarch != NULL); | |
15570 | + gdb_assert (gdbarch->get_syscall_number != NULL); | |
15571 | + if (gdbarch_debug >= 2) | |
15572 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_get_syscall_number called\n"); | |
15573 | + return gdbarch->get_syscall_number (gdbarch, ptid); | |
15574 | +} | |
15575 | + | |
15576 | +void | |
15577 | +set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, | |
15578 | + gdbarch_get_syscall_number_ftype get_syscall_number) | |
15579 | +{ | |
15580 | + gdbarch->get_syscall_number = get_syscall_number; | |
15581 | +} | |
15582 | + | |
15583 | +int | |
15584 | +gdbarch_get_syscall_by_number_p (struct gdbarch *gdbarch) | |
15585 | +{ | |
15586 | + gdb_assert (gdbarch != NULL); | |
15587 | + return gdbarch->get_syscall_by_number != NULL; | |
15588 | +} | |
15589 | + | |
15590 | +void | |
15591 | +gdbarch_get_syscall_by_number (struct gdbarch *gdbarch, int syscall_number, struct syscall *s) | |
15592 | +{ | |
15593 | + gdb_assert (gdbarch != NULL); | |
15594 | + gdb_assert (gdbarch->get_syscall_by_number != NULL); | |
15595 | + if (gdbarch_debug >= 2) | |
15596 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_get_syscall_by_number called\n"); | |
15597 | + gdbarch->get_syscall_by_number (gdbarch, syscall_number, s); | |
15598 | +} | |
15599 | + | |
15600 | +void | |
15601 | +set_gdbarch_get_syscall_by_number (struct gdbarch *gdbarch, | |
15602 | + gdbarch_get_syscall_by_number_ftype get_syscall_by_number) | |
15603 | +{ | |
15604 | + gdbarch->get_syscall_by_number = get_syscall_by_number; | |
15605 | +} | |
15606 | + | |
15607 | +int | |
15608 | +gdbarch_get_syscall_by_name_p (struct gdbarch *gdbarch) | |
15609 | +{ | |
15610 | + gdb_assert (gdbarch != NULL); | |
15611 | + return gdbarch->get_syscall_by_name != NULL; | |
15612 | +} | |
15613 | + | |
15614 | +void | |
15615 | +gdbarch_get_syscall_by_name (struct gdbarch *gdbarch, const char *syscall_name, struct syscall *s) | |
15616 | +{ | |
15617 | + gdb_assert (gdbarch != NULL); | |
15618 | + gdb_assert (gdbarch->get_syscall_by_name != NULL); | |
15619 | + if (gdbarch_debug >= 2) | |
15620 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_get_syscall_by_name called\n"); | |
15621 | + gdbarch->get_syscall_by_name (gdbarch, syscall_name, s); | |
15622 | +} | |
15623 | + | |
15624 | +void | |
15625 | +set_gdbarch_get_syscall_by_name (struct gdbarch *gdbarch, | |
15626 | + gdbarch_get_syscall_by_name_ftype get_syscall_by_name) | |
15627 | +{ | |
15628 | + gdbarch->get_syscall_by_name = get_syscall_by_name; | |
15629 | +} | |
15630 | + | |
15631 | +int | |
15632 | +gdbarch_get_syscall_names_p (struct gdbarch *gdbarch) | |
15633 | +{ | |
15634 | + gdb_assert (gdbarch != NULL); | |
15635 | + return gdbarch->get_syscall_names != NULL; | |
15636 | +} | |
15637 | + | |
15638 | +const char ** | |
15639 | +gdbarch_get_syscall_names (struct gdbarch *gdbarch) | |
15640 | +{ | |
15641 | + gdb_assert (gdbarch != NULL); | |
15642 | + gdb_assert (gdbarch->get_syscall_names != NULL); | |
15643 | + if (gdbarch_debug >= 2) | |
15644 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_get_syscall_names called\n"); | |
15645 | + return gdbarch->get_syscall_names (gdbarch); | |
15646 | +} | |
15647 | + | |
15648 | +void | |
15649 | +set_gdbarch_get_syscall_names (struct gdbarch *gdbarch, | |
15650 | + gdbarch_get_syscall_names_ftype get_syscall_names) | |
15651 | +{ | |
15652 | + gdbarch->get_syscall_names = get_syscall_names; | |
15653 | +} | |
15654 | + | |
15655 | +const char * | |
15656 | +gdbarch_xml_syscall_filename (struct gdbarch *gdbarch) | |
15657 | +{ | |
15658 | + gdb_assert (gdbarch != NULL); | |
15659 | + /* Skip verify of xml_syscall_filename, invalid_p == 0 */ | |
15660 | + if (gdbarch_debug >= 2) | |
15661 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_xml_syscall_filename called\n"); | |
15662 | + return gdbarch->xml_syscall_filename; | |
15663 | +} | |
15664 | + | |
15665 | +void | |
15666 | +set_gdbarch_xml_syscall_filename (struct gdbarch *gdbarch, | |
15667 | + const char * xml_syscall_filename) | |
15668 | +{ | |
15669 | + gdbarch->xml_syscall_filename = xml_syscall_filename; | |
15670 | +} | |
15671 | + | |
15672 | +int | |
15673 | gdbarch_has_global_solist (struct gdbarch *gdbarch) | |
15674 | { | |
15675 | gdb_assert (gdbarch != NULL); | |
15676 | diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h | |
15677 | index 04c8920..017b9df 100644 | |
15678 | --- a/gdb/gdbarch.h | |
15679 | +++ b/gdb/gdbarch.h | |
15680 | @@ -52,6 +52,7 @@ struct bp_target_info; | |
15681 | struct target_desc; | |
15682 | struct displaced_step_closure; | |
15683 | struct core_regset_section; | |
15684 | +struct syscall; | |
15685 | ||
15686 | extern struct gdbarch *current_gdbarch; | |
15687 | extern struct gdbarch *target_gdbarch; | |
15688 | @@ -839,6 +840,47 @@ typedef void (gdbarch_record_special_symbol_ftype) (struct gdbarch *gdbarch, str | |
15689 | extern void gdbarch_record_special_symbol (struct gdbarch *gdbarch, struct objfile *objfile, asymbol *sym); | |
15690 | extern void set_gdbarch_record_special_symbol (struct gdbarch *gdbarch, gdbarch_record_special_symbol_ftype *record_special_symbol); | |
15691 | ||
15692 | +/* Functions for the 'catch syscall' feature. | |
15693 | + Get architecture-specific system calls information from registers. */ | |
15694 | + | |
15695 | +extern int gdbarch_get_syscall_number_p (struct gdbarch *gdbarch); | |
15696 | + | |
15697 | +typedef LONGEST (gdbarch_get_syscall_number_ftype) (struct gdbarch *gdbarch, ptid_t ptid); | |
15698 | +extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid); | |
15699 | +extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number); | |
15700 | + | |
15701 | +/* Fills the struct syscall (passed as argument) with the corresponding | |
15702 | + system call represented by syscall_number. */ | |
15703 | + | |
15704 | +extern int gdbarch_get_syscall_by_number_p (struct gdbarch *gdbarch); | |
15705 | + | |
15706 | +typedef void (gdbarch_get_syscall_by_number_ftype) (struct gdbarch *gdbarch, int syscall_number, struct syscall *s); | |
15707 | +extern void gdbarch_get_syscall_by_number (struct gdbarch *gdbarch, int syscall_number, struct syscall *s); | |
15708 | +extern void set_gdbarch_get_syscall_by_number (struct gdbarch *gdbarch, gdbarch_get_syscall_by_number_ftype *get_syscall_by_number); | |
15709 | + | |
15710 | +/* Fills the struct syscall (passed as argument) with the corresponding | |
15711 | + system call represented by syscall_name. */ | |
15712 | + | |
15713 | +extern int gdbarch_get_syscall_by_name_p (struct gdbarch *gdbarch); | |
15714 | + | |
15715 | +typedef void (gdbarch_get_syscall_by_name_ftype) (struct gdbarch *gdbarch, const char *syscall_name, struct syscall *s); | |
15716 | +extern void gdbarch_get_syscall_by_name (struct gdbarch *gdbarch, const char *syscall_name, struct syscall *s); | |
15717 | +extern void set_gdbarch_get_syscall_by_name (struct gdbarch *gdbarch, gdbarch_get_syscall_by_name_ftype *get_syscall_by_name); | |
15718 | + | |
15719 | +/* Returns the array containing the syscall names for the architecture. */ | |
15720 | + | |
15721 | +extern int gdbarch_get_syscall_names_p (struct gdbarch *gdbarch); | |
15722 | + | |
15723 | +typedef const char ** (gdbarch_get_syscall_names_ftype) (struct gdbarch *gdbarch); | |
15724 | +extern const char ** gdbarch_get_syscall_names (struct gdbarch *gdbarch); | |
15725 | +extern void set_gdbarch_get_syscall_names (struct gdbarch *gdbarch, gdbarch_get_syscall_names_ftype *get_syscall_names); | |
15726 | + | |
15727 | +/* Stores the name of syscall's XML file. Contains NULL if the file | |
15728 | + was not set. */ | |
15729 | + | |
15730 | +extern const char * gdbarch_xml_syscall_filename (struct gdbarch *gdbarch); | |
15731 | +extern void set_gdbarch_xml_syscall_filename (struct gdbarch *gdbarch, const char * xml_syscall_filename); | |
15732 | + | |
15733 | /* True if the list of shared libraries is one and only for all | |
15734 | processes, as opposed to a list of shared libraries per inferior. | |
15735 | When this property is true, GDB assumes that since shared libraries | |
15736 | @@ -848,6 +890,9 @@ extern void set_gdbarch_record_special_symbol (struct gdbarch *gdbarch, gdbarch_ | |
15737 | extern int gdbarch_has_global_solist (struct gdbarch *gdbarch); | |
15738 | extern void set_gdbarch_has_global_solist (struct gdbarch *gdbarch, int has_global_solist); | |
15739 | ||
15740 | +/* Definition for an unknown syscall, used basically in error-cases. */ | |
15741 | +#define UNKNOWN_SYSCALL (-1) | |
15742 | + | |
15743 | extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); | |
15744 | ||
15745 | ||
15746 | diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh | |
15747 | index f93bfc1..66cbcd0 100755 | |
15748 | --- a/gdb/gdbarch.sh | |
15749 | +++ b/gdb/gdbarch.sh | |
15750 | @@ -724,6 +724,26 @@ M:struct type *:get_siginfo_type:void: | |
15751 | # Record architecture-specific information from the symbol table. | |
15752 | M:void:record_special_symbol:struct objfile *objfile, asymbol *sym:objfile, sym | |
15753 | ||
15754 | +# Functions for the 'catch syscall' feature. | |
15755 | + | |
15756 | +# Get architecture-specific system calls information from registers. | |
15757 | +M:LONGEST:get_syscall_number:ptid_t ptid:ptid | |
15758 | + | |
15759 | +# Fills the struct syscall (passed as argument) with the corresponding | |
15760 | +# system call represented by syscall_number. | |
15761 | +M:void:get_syscall_by_number:int syscall_number, struct syscall *s:syscall_number, s | |
15762 | + | |
15763 | +# Fills the struct syscall (passed as argument) with the corresponding | |
15764 | +# system call represented by syscall_name. | |
15765 | +M:void:get_syscall_by_name:const char *syscall_name, struct syscall *s:syscall_name, s | |
15766 | + | |
15767 | +# Returns the array containing the syscall names for the architecture. | |
15768 | +M:const char **:get_syscall_names:void: | |
15769 | + | |
15770 | +# Stores the name of syscall's XML file. Contains NULL if the file | |
15771 | +# was not set. | |
15772 | +v:const char *:xml_syscall_filename:::0:0::0:gdbarch->xml_syscall_filename | |
15773 | + | |
15774 | # True if the list of shared libraries is one and only for all | |
15775 | # processes, as opposed to a list of shared libraries per inferior. | |
15776 | # When this property is true, GDB assumes that since shared libraries | |
15777 | @@ -842,6 +862,7 @@ struct bp_target_info; | |
15778 | struct target_desc; | |
15779 | struct displaced_step_closure; | |
15780 | struct core_regset_section; | |
15781 | +struct syscall; | |
15782 | ||
15783 | extern struct gdbarch *current_gdbarch; | |
15784 | extern struct gdbarch *target_gdbarch; | |
15785 | @@ -911,6 +932,9 @@ done | |
15786 | # close it off | |
15787 | cat <<EOF | |
15788 | ||
15789 | +/* Definition for an unknown syscall, used basically in error-cases. */ | |
15790 | +#define UNKNOWN_SYSCALL (-1) | |
15791 | + | |
15792 | extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); | |
15793 | ||
15794 | ||
15795 | diff --git a/gdb/gdbinit.in b/gdb/gdbinit.in | |
15796 | index ffb7f53..a2e7e94 100644 | |
15797 | --- a/gdb/gdbinit.in | |
15798 | +++ b/gdb/gdbinit.in | |
15799 | @@ -1,5 +1,15 @@ | |
15800 | echo Setting up the environment for debugging gdb.\n | |
15801 | ||
15802 | +# Set up the Python library and "require" command. | |
15803 | +python | |
15804 | +from os.path import abspath | |
15805 | +gdb.datadir = abspath ('@srcdir@/python/lib') | |
15806 | +gdb.pythonlibdir = gdb.datadir | |
15807 | +gdb.__path__ = [gdb.datadir + '/gdb'] | |
15808 | +sys.path.insert(0, gdb.datadir) | |
15809 | +end | |
15810 | +source @srcdir@/python/lib/gdb/__init__.py | |
15811 | + | |
15812 | set complaints 1 | |
15813 | ||
15814 | b internal_error | |
15815 | diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h | |
15816 | index 3a405a8..a2e2636 100644 | |
15817 | --- a/gdb/gdbthread.h | |
15818 | +++ b/gdb/gdbthread.h | |
15819 | @@ -228,6 +228,9 @@ struct thread_info *find_thread_id (int num); | |
15820 | /* Change the ptid of thread OLD_PTID to NEW_PTID. */ | |
15821 | void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid); | |
15822 | ||
15823 | +/* Prune dead threads from the list of threads. */ | |
15824 | +extern void prune_threads (void); | |
15825 | + | |
15826 | /* Iterator function to call a user-provided callback function | |
15827 | once for each known thread. */ | |
15828 | typedef int (*thread_callback_func) (struct thread_info *, void *); | |
15829 | diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c | |
15830 | index 8102321..012485c 100644 | |
15831 | --- a/gdb/gdbtypes.c | |
15832 | +++ b/gdb/gdbtypes.c | |
15833 | @@ -38,6 +38,8 @@ | |
15834 | #include "cp-abi.h" | |
15835 | #include "gdb_assert.h" | |
15836 | #include "hashtab.h" | |
15837 | +#include "dwarf2expr.h" | |
15838 | +#include "dwarf2loc.h" | |
15839 | ||
15840 | /* These variables point to the objects | |
15841 | representing the predefined C data types. */ | |
15842 | @@ -146,6 +148,23 @@ static void print_bit_vector (B_TYPE *, int); | |
15843 | static void print_arg_types (struct field *, int, int); | |
15844 | static void dump_fn_fieldlists (struct type *, int); | |
15845 | static void print_cplus_stuff (struct type *, int); | |
15846 | +static void type_init_refc (struct type *new_type, struct type *parent_type); | |
15847 | + | |
15848 | +/* A reference count structure for the type reference count map. Each | |
15849 | + type in a hierarchy of types is mapped to the same reference | |
15850 | + count. */ | |
15851 | +struct type_refc_entry | |
15852 | +{ | |
15853 | + /* One type in the hierarchy. Each type in the hierarchy gets its | |
15854 | + own slot. */ | |
15855 | + struct type *type; | |
15856 | + | |
15857 | + /* A pointer to the shared reference count. */ | |
15858 | + int *refc; | |
15859 | +}; | |
15860 | + | |
15861 | +/* The hash table holding all reference counts. */ | |
15862 | +static htab_t type_refc_table; | |
15863 | ||
15864 | ||
15865 | /* Alloc a new type structure and fill it with some defaults. If | |
15866 | @@ -154,23 +173,25 @@ static void print_cplus_stuff (struct type *, int); | |
15867 | structure by xmalloc () (for permanent types). */ | |
15868 | ||
15869 | struct type * | |
15870 | -alloc_type (struct objfile *objfile) | |
15871 | +alloc_type (struct objfile *objfile, struct type *parent) | |
15872 | { | |
15873 | struct type *type; | |
15874 | ||
15875 | /* Alloc the structure and start off with all fields zeroed. */ | |
15876 | ||
15877 | - if (objfile == NULL) | |
15878 | + switch ((long) objfile) | |
15879 | { | |
15880 | + case (long) OBJFILE_INTERNAL: | |
15881 | + case (long) OBJFILE_MALLOC: | |
15882 | type = XZALLOC (struct type); | |
15883 | TYPE_MAIN_TYPE (type) = XZALLOC (struct main_type); | |
15884 | - } | |
15885 | - else | |
15886 | - { | |
15887 | + break; | |
15888 | + default: | |
15889 | type = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct type); | |
15890 | TYPE_MAIN_TYPE (type) = OBSTACK_ZALLOC (&objfile->objfile_obstack, | |
15891 | struct main_type); | |
15892 | OBJSTAT (objfile, n_types++); | |
15893 | + break; | |
15894 | } | |
15895 | ||
15896 | /* Initialize the fields that might not be zero. */ | |
15897 | @@ -180,6 +201,9 @@ alloc_type (struct objfile *objfile) | |
15898 | TYPE_VPTR_FIELDNO (type) = -1; | |
15899 | TYPE_CHAIN (type) = type; /* Chain back to itself. */ | |
15900 | ||
15901 | + if (objfile == NULL) | |
15902 | + type_init_refc (type, parent); | |
15903 | + | |
15904 | return (type); | |
15905 | } | |
15906 | ||
15907 | @@ -194,16 +218,24 @@ alloc_type_instance (struct type *oldtype) | |
15908 | ||
15909 | /* Allocate the structure. */ | |
15910 | ||
15911 | - if (TYPE_OBJFILE (oldtype) == NULL) | |
15912 | - type = XZALLOC (struct type); | |
15913 | - else | |
15914 | - type = OBSTACK_ZALLOC (&TYPE_OBJFILE (oldtype)->objfile_obstack, | |
15915 | - struct type); | |
15916 | - | |
15917 | + switch ((long) TYPE_OBJFILE (oldtype)) | |
15918 | + { | |
15919 | + case (long) OBJFILE_INTERNAL: | |
15920 | + case (long) OBJFILE_MALLOC: | |
15921 | + type = XZALLOC (struct type); | |
15922 | + break; | |
15923 | + default: | |
15924 | + type = OBSTACK_ZALLOC (&TYPE_OBJFILE (oldtype)->objfile_obstack, | |
15925 | + struct type); | |
15926 | + break; | |
15927 | + } | |
15928 | TYPE_MAIN_TYPE (type) = TYPE_MAIN_TYPE (oldtype); | |
15929 | ||
15930 | TYPE_CHAIN (type) = type; /* Chain back to itself for now. */ | |
15931 | ||
15932 | + if (TYPE_OBJFILE (oldtype) == NULL) | |
15933 | + type_init_refc (type, oldtype); | |
15934 | + | |
15935 | return (type); | |
15936 | } | |
15937 | ||
15938 | @@ -248,7 +280,7 @@ make_pointer_type (struct type *type, struct type **typeptr) | |
15939 | ||
15940 | if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ | |
15941 | { | |
15942 | - ntype = alloc_type (TYPE_OBJFILE (type)); | |
15943 | + ntype = alloc_type (TYPE_OBJFILE (type), type); | |
15944 | if (typeptr) | |
15945 | *typeptr = ntype; | |
15946 | } | |
15947 | @@ -260,6 +292,9 @@ make_pointer_type (struct type *type, struct type **typeptr) | |
15948 | smash_type (ntype); | |
15949 | TYPE_CHAIN (ntype) = chain; | |
15950 | TYPE_OBJFILE (ntype) = objfile; | |
15951 | + | |
15952 | + /* Callers may only supply storage if there is an objfile. */ | |
15953 | + gdb_assert (objfile); | |
15954 | } | |
15955 | ||
15956 | TYPE_TARGET_TYPE (ntype) = type; | |
15957 | @@ -328,7 +363,7 @@ make_reference_type (struct type *type, struct type **typeptr) | |
15958 | ||
15959 | if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ | |
15960 | { | |
15961 | - ntype = alloc_type (TYPE_OBJFILE (type)); | |
15962 | + ntype = alloc_type (TYPE_OBJFILE (type), type); | |
15963 | if (typeptr) | |
15964 | *typeptr = ntype; | |
15965 | } | |
15966 | @@ -340,6 +375,9 @@ make_reference_type (struct type *type, struct type **typeptr) | |
15967 | smash_type (ntype); | |
15968 | TYPE_CHAIN (ntype) = chain; | |
15969 | TYPE_OBJFILE (ntype) = objfile; | |
15970 | + | |
15971 | + /* Callers may only supply storage if there is an objfile. */ | |
15972 | + gdb_assert (objfile); | |
15973 | } | |
15974 | ||
15975 | TYPE_TARGET_TYPE (ntype) = type; | |
15976 | @@ -388,7 +426,7 @@ make_function_type (struct type *type, struct type **typeptr) | |
15977 | ||
15978 | if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */ | |
15979 | { | |
15980 | - ntype = alloc_type (TYPE_OBJFILE (type)); | |
15981 | + ntype = alloc_type (TYPE_OBJFILE (type), type); | |
15982 | if (typeptr) | |
15983 | *typeptr = ntype; | |
15984 | } | |
15985 | @@ -398,6 +436,9 @@ make_function_type (struct type *type, struct type **typeptr) | |
15986 | objfile = TYPE_OBJFILE (ntype); | |
15987 | smash_type (ntype); | |
15988 | TYPE_OBJFILE (ntype) = objfile; | |
15989 | + | |
15990 | + /* Callers may only supply storage if there is an objfile. */ | |
15991 | + gdb_assert (objfile); | |
15992 | } | |
15993 | ||
15994 | TYPE_TARGET_TYPE (ntype) = type; | |
15995 | @@ -643,7 +684,7 @@ lookup_memberptr_type (struct type *type, struct type *domain) | |
15996 | { | |
15997 | struct type *mtype; | |
15998 | ||
15999 | - mtype = alloc_type (TYPE_OBJFILE (type)); | |
16000 | + mtype = alloc_type (TYPE_OBJFILE (type), NULL); | |
16001 | smash_to_memberptr_type (mtype, domain, type); | |
16002 | return (mtype); | |
16003 | } | |
16004 | @@ -655,7 +696,7 @@ lookup_methodptr_type (struct type *to_type) | |
16005 | { | |
16006 | struct type *mtype; | |
16007 | ||
16008 | - mtype = alloc_type (TYPE_OBJFILE (to_type)); | |
16009 | + mtype = alloc_type (TYPE_OBJFILE (to_type), NULL); | |
16010 | TYPE_TARGET_TYPE (mtype) = to_type; | |
16011 | TYPE_DOMAIN_TYPE (mtype) = TYPE_DOMAIN_TYPE (to_type); | |
16012 | TYPE_LENGTH (mtype) = cplus_method_ptr_size (to_type); | |
16013 | @@ -696,19 +737,20 @@ create_range_type (struct type *result_type, struct type *index_type, | |
16014 | int low_bound, int high_bound) | |
16015 | { | |
16016 | if (result_type == NULL) | |
16017 | - result_type = alloc_type (TYPE_OBJFILE (index_type)); | |
16018 | + result_type = alloc_type (TYPE_OBJFILE (index_type), index_type); | |
16019 | TYPE_CODE (result_type) = TYPE_CODE_RANGE; | |
16020 | TYPE_TARGET_TYPE (result_type) = index_type; | |
16021 | if (TYPE_STUB (index_type)) | |
16022 | TYPE_TARGET_STUB (result_type) = 1; | |
16023 | else | |
16024 | TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type)); | |
16025 | - TYPE_NFIELDS (result_type) = 2; | |
16026 | + TYPE_NFIELDS (result_type) = 3; | |
16027 | TYPE_FIELDS (result_type) = TYPE_ZALLOC (result_type, | |
16028 | TYPE_NFIELDS (result_type) | |
16029 | * sizeof (struct field)); | |
16030 | TYPE_LOW_BOUND (result_type) = low_bound; | |
16031 | TYPE_HIGH_BOUND (result_type) = high_bound; | |
16032 | + TYPE_BYTE_STRIDE (result_type) = 0; | |
16033 | ||
16034 | if (low_bound >= 0) | |
16035 | TYPE_UNSIGNED (result_type) = 1; | |
16036 | @@ -727,6 +769,9 @@ get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp) | |
16037 | switch (TYPE_CODE (type)) | |
16038 | { | |
16039 | case TYPE_CODE_RANGE: | |
16040 | + if (TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (type) | |
16041 | + || TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED (type)) | |
16042 | + return -1; | |
16043 | *lowp = TYPE_LOW_BOUND (type); | |
16044 | *highp = TYPE_HIGH_BOUND (type); | |
16045 | return 1; | |
16046 | @@ -805,30 +850,56 @@ create_array_type (struct type *result_type, | |
16047 | ||
16048 | if (result_type == NULL) | |
16049 | { | |
16050 | - result_type = alloc_type (TYPE_OBJFILE (range_type)); | |
16051 | + result_type = alloc_type (TYPE_OBJFILE (range_type), range_type); | |
16052 | } | |
16053 | + else | |
16054 | + { | |
16055 | + /* Callers may only supply storage if there is an objfile. */ | |
16056 | + gdb_assert (TYPE_OBJFILE (result_type)); | |
16057 | + } | |
16058 | + | |
16059 | TYPE_CODE (result_type) = TYPE_CODE_ARRAY; | |
16060 | TYPE_TARGET_TYPE (result_type) = element_type; | |
16061 | - if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) | |
16062 | - low_bound = high_bound = 0; | |
16063 | - CHECK_TYPEDEF (element_type); | |
16064 | - /* Be careful when setting the array length. Ada arrays can be | |
16065 | - empty arrays with the high_bound being smaller than the low_bound. | |
16066 | - In such cases, the array length should be zero. */ | |
16067 | - if (high_bound < low_bound) | |
16068 | - TYPE_LENGTH (result_type) = 0; | |
16069 | - else | |
16070 | - TYPE_LENGTH (result_type) = | |
16071 | - TYPE_LENGTH (element_type) * (high_bound - low_bound + 1); | |
16072 | TYPE_NFIELDS (result_type) = 1; | |
16073 | TYPE_FIELDS (result_type) = | |
16074 | (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field)); | |
16075 | + /* FIXME: type alloc. */ | |
16076 | TYPE_INDEX_TYPE (result_type) = range_type; | |
16077 | TYPE_VPTR_FIELDNO (result_type) = -1; | |
16078 | ||
16079 | - /* TYPE_FLAG_TARGET_STUB will take care of zero length arrays */ | |
16080 | + /* DWARF blocks may depend on runtime information like | |
16081 | + DW_OP_PUSH_OBJECT_ADDRESS not being available during the | |
16082 | + CREATE_ARRAY_TYPE time. */ | |
16083 | + if (TYPE_RANGE_BOUND_IS_DWARF_BLOCK (range_type, 0) | |
16084 | + || TYPE_RANGE_BOUND_IS_DWARF_BLOCK (range_type, 1) | |
16085 | + || TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (range_type) | |
16086 | + || TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED (range_type) | |
16087 | + || get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) | |
16088 | + { | |
16089 | + low_bound = 0; | |
16090 | + high_bound = -1; | |
16091 | + } | |
16092 | + | |
16093 | + /* Be careful when setting the array length. Ada arrays can be | |
16094 | + empty arrays with the high_bound being smaller than the low_bound. | |
16095 | + In such cases, the array length should be zero. TYPE_TARGET_STUB needs to | |
16096 | + be checked as it may have dependencies on DWARF blocks depending on | |
16097 | + runtime information not available during the CREATE_ARRAY_TYPE time. */ | |
16098 | + if (high_bound < low_bound || TYPE_TARGET_STUB (element_type)) | |
16099 | + TYPE_LENGTH (result_type) = 0; | |
16100 | + else | |
16101 | + { | |
16102 | + CHECK_TYPEDEF (element_type); | |
16103 | + TYPE_LENGTH (result_type) = | |
16104 | + TYPE_LENGTH (element_type) * (high_bound - low_bound + 1); | |
16105 | + } | |
16106 | + | |
16107 | if (TYPE_LENGTH (result_type) == 0) | |
16108 | - TYPE_TARGET_STUB (result_type) = 1; | |
16109 | + { | |
16110 | + /* The real size will be computed for specific instances by | |
16111 | + CHECK_TYPEDEF. */ | |
16112 | + TYPE_TARGET_STUB (result_type) = 1; | |
16113 | + } | |
16114 | ||
16115 | return (result_type); | |
16116 | } | |
16117 | @@ -865,7 +936,12 @@ create_set_type (struct type *result_type, struct type *domain_type) | |
16118 | { | |
16119 | if (result_type == NULL) | |
16120 | { | |
16121 | - result_type = alloc_type (TYPE_OBJFILE (domain_type)); | |
16122 | + result_type = alloc_type (TYPE_OBJFILE (domain_type), domain_type); | |
16123 | + } | |
16124 | + else | |
16125 | + { | |
16126 | + /* Callers may only supply storage if there is an objfile. */ | |
16127 | + gdb_assert (TYPE_OBJFILE (result_type)); | |
16128 | } | |
16129 | TYPE_CODE (result_type) = TYPE_CODE_SET; | |
16130 | TYPE_NFIELDS (result_type) = 1; | |
16131 | @@ -1368,6 +1444,84 @@ stub_noname_complaint (void) | |
16132 | complaint (&symfile_complaints, _("stub type has NULL name")); | |
16133 | } | |
16134 | ||
16135 | +/* Calculate the memory length of array TYPE. | |
16136 | + | |
16137 | + TARGET_TYPE should be set to `check_typedef (TYPE_TARGET_TYPE (type))' as | |
16138 | + a performance hint. Feel free to pass NULL. Set FULL_SPAN to return the | |
16139 | + size incl. the possible padding of the last element - it may differ from the | |
16140 | + cleared FULL_SPAN return value (the expected SIZEOF) for non-zero | |
16141 | + TYPE_BYTE_STRIDE values. */ | |
16142 | + | |
16143 | +static CORE_ADDR | |
16144 | +type_length_get (struct type *type, struct type *target_type, int full_span) | |
16145 | +{ | |
16146 | + struct type *range_type; | |
16147 | + int count; | |
16148 | + CORE_ADDR byte_stride = 0; /* `= 0' for a false GCC warning. */ | |
16149 | + CORE_ADDR element_size; | |
16150 | + | |
16151 | + if (TYPE_CODE (type) != TYPE_CODE_ARRAY | |
16152 | + && TYPE_CODE (type) != TYPE_CODE_STRING) | |
16153 | + return TYPE_LENGTH (type); | |
16154 | + | |
16155 | + /* Avoid executing TYPE_HIGH_BOUND for invalid (unallocated/unassociated) | |
16156 | + Fortran arrays. The allocated data will never be used so they can be | |
16157 | + zero-length. */ | |
16158 | + if (object_address_data_not_valid (type)) | |
16159 | + return 0; | |
16160 | + | |
16161 | + range_type = TYPE_INDEX_TYPE (type); | |
16162 | + if (TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED (range_type) | |
16163 | + || TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (range_type)) | |
16164 | + return 0; | |
16165 | + count = TYPE_HIGH_BOUND (range_type) - TYPE_LOW_BOUND (range_type) + 1; | |
16166 | + /* It may happen for wrong DWARF annotations returning garbage data. */ | |
16167 | + if (count < 0) | |
16168 | + warning (_("Range for type %s has invalid bounds %d..%d"), | |
16169 | + TYPE_NAME (type), TYPE_LOW_BOUND (range_type), | |
16170 | + TYPE_HIGH_BOUND (range_type)); | |
16171 | + /* The code below does not handle count == 0 right. */ | |
16172 | + if (count <= 0) | |
16173 | + return 0; | |
16174 | + if (full_span || count > 1) | |
16175 | + { | |
16176 | + /* We do not use TYPE_ARRAY_BYTE_STRIDE_VALUE (type) here as we want to | |
16177 | + force FULL_SPAN to 1. */ | |
16178 | + byte_stride = TYPE_BYTE_STRIDE (range_type); | |
16179 | + if (byte_stride == 0) | |
16180 | + { | |
16181 | + if (target_type == NULL) | |
16182 | + target_type = check_typedef (TYPE_TARGET_TYPE (type)); | |
16183 | + byte_stride = type_length_get (target_type, NULL, 1); | |
16184 | + } | |
16185 | + } | |
16186 | + if (full_span) | |
16187 | + return count * byte_stride; | |
16188 | + if (target_type == NULL) | |
16189 | + target_type = check_typedef (TYPE_TARGET_TYPE (type)); | |
16190 | + element_size = type_length_get (target_type, NULL, 1); | |
16191 | + return (count - 1) * byte_stride + element_size; | |
16192 | +} | |
16193 | + | |
16194 | +/* Prepare TYPE after being read in by the backend. Currently this function | |
16195 | + only propagates the TYPE_DYNAMIC flag. */ | |
16196 | + | |
16197 | +void | |
16198 | +finalize_type (struct type *type) | |
16199 | +{ | |
16200 | + int i; | |
16201 | + | |
16202 | + for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
16203 | + if (TYPE_FIELD_TYPE (type, i) && TYPE_DYNAMIC (TYPE_FIELD_TYPE (type, i))) | |
16204 | + break; | |
16205 | + | |
16206 | + /* FIXME: cplus_stuff is ignored here. */ | |
16207 | + if (i < TYPE_NFIELDS (type) | |
16208 | + || (TYPE_VPTR_BASETYPE (type) && TYPE_DYNAMIC (TYPE_VPTR_BASETYPE (type))) | |
16209 | + || (TYPE_TARGET_TYPE (type) && TYPE_DYNAMIC (TYPE_TARGET_TYPE (type)))) | |
16210 | + TYPE_DYNAMIC (type) = 1; | |
16211 | +} | |
16212 | + | |
16213 | /* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989. | |
16214 | ||
16215 | If this is a stubbed struct (i.e. declared as struct foo *), see if | |
16216 | @@ -1384,7 +1538,8 @@ stub_noname_complaint (void) | |
16217 | /* Find the real type of TYPE. This function returns the real type, | |
16218 | after removing all layers of typedefs and completing opaque or stub | |
16219 | types. Completion changes the TYPE argument, but stripping of | |
16220 | - typedefs does not. */ | |
16221 | + typedefs does not. Still original passed TYPE will have TYPE_LENGTH | |
16222 | + updated. FIXME: Remove this dependency (only ada_to_fixed_type?). */ | |
16223 | ||
16224 | struct type * | |
16225 | check_typedef (struct type *type) | |
16226 | @@ -1420,7 +1575,7 @@ check_typedef (struct type *type) | |
16227 | if (sym) | |
16228 | TYPE_TARGET_TYPE (type) = SYMBOL_TYPE (sym); | |
16229 | else /* TYPE_CODE_UNDEF */ | |
16230 | - TYPE_TARGET_TYPE (type) = alloc_type (NULL); | |
16231 | + TYPE_TARGET_TYPE (type) = alloc_type (NULL, NULL); | |
16232 | } | |
16233 | type = TYPE_TARGET_TYPE (type); | |
16234 | } | |
16235 | @@ -1494,34 +1649,37 @@ check_typedef (struct type *type) | |
16236 | } | |
16237 | } | |
16238 | ||
16239 | - if (TYPE_TARGET_STUB (type)) | |
16240 | + /* copy_type_recursive automatically makes the resulting type containing only | |
16241 | + constant values expected by the callers of this function. */ | |
16242 | + if (TYPE_DYNAMIC (type)) | |
16243 | + { | |
16244 | + htab_t copied_types; | |
16245 | + struct type *type_old = type; | |
16246 | + | |
16247 | + copied_types = create_copied_types_hash (NULL); | |
16248 | + type = copy_type_recursive (type, copied_types); | |
16249 | + htab_delete (copied_types); | |
16250 | + | |
16251 | + gdb_assert (TYPE_DYNAMIC (type) == 0); | |
16252 | + } | |
16253 | + | |
16254 | + if (!currently_reading_symtab | |
16255 | + && (TYPE_TARGET_STUB (type) || TYPE_DYNAMIC (type))) | |
16256 | { | |
16257 | - struct type *range_type; | |
16258 | struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type)); | |
16259 | ||
16260 | + if (TYPE_DYNAMIC (type)) | |
16261 | + TYPE_TARGET_TYPE (type) = target_type; | |
16262 | if (TYPE_STUB (target_type) || TYPE_TARGET_STUB (target_type)) | |
16263 | { | |
16264 | /* Empty. */ | |
16265 | } | |
16266 | else if (TYPE_CODE (type) == TYPE_CODE_ARRAY | |
16267 | - && TYPE_NFIELDS (type) == 1 | |
16268 | - && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type)) | |
16269 | - == TYPE_CODE_RANGE)) | |
16270 | + || TYPE_CODE (type) == TYPE_CODE_STRING) | |
16271 | { | |
16272 | /* Now recompute the length of the array type, based on its | |
16273 | - number of elements and the target type's length. | |
16274 | - Watch out for Ada null Ada arrays where the high bound | |
16275 | - is smaller than the low bound. */ | |
16276 | - const int low_bound = TYPE_LOW_BOUND (range_type); | |
16277 | - const int high_bound = TYPE_HIGH_BOUND (range_type); | |
16278 | - int nb_elements; | |
16279 | - | |
16280 | - if (high_bound < low_bound) | |
16281 | - nb_elements = 0; | |
16282 | - else | |
16283 | - nb_elements = high_bound - low_bound + 1; | |
16284 | - | |
16285 | - TYPE_LENGTH (type) = nb_elements * TYPE_LENGTH (target_type); | |
16286 | + number of elements and the target type's length. */ | |
16287 | + TYPE_LENGTH (type) = type_length_get (type, target_type, 0); | |
16288 | TYPE_TARGET_STUB (type) = 0; | |
16289 | } | |
16290 | else if (TYPE_CODE (type) == TYPE_CODE_RANGE) | |
16291 | @@ -1529,9 +1687,12 @@ check_typedef (struct type *type) | |
16292 | TYPE_LENGTH (type) = TYPE_LENGTH (target_type); | |
16293 | TYPE_TARGET_STUB (type) = 0; | |
16294 | } | |
16295 | + TYPE_DYNAMIC (type) = 0; | |
16296 | } | |
16297 | + | |
16298 | /* Cache TYPE_LENGTH for future use. */ | |
16299 | TYPE_LENGTH (orig_type) = TYPE_LENGTH (type); | |
16300 | + | |
16301 | return type; | |
16302 | } | |
16303 | ||
16304 | @@ -1753,7 +1914,7 @@ init_type (enum type_code code, int length, int flags, | |
16305 | { | |
16306 | struct type *type; | |
16307 | ||
16308 | - type = alloc_type (objfile); | |
16309 | + type = alloc_type (objfile, NULL); | |
16310 | TYPE_CODE (type) = code; | |
16311 | TYPE_LENGTH (type) = length; | |
16312 | ||
16313 | @@ -1783,15 +1944,24 @@ init_type (enum type_code code, int length, int flags, | |
16314 | if (flags & TYPE_FLAG_FIXED_INSTANCE) | |
16315 | TYPE_FIXED_INSTANCE (type) = 1; | |
16316 | ||
16317 | - if ((name != NULL) && (objfile != NULL)) | |
16318 | - { | |
16319 | - TYPE_NAME (type) = obsavestring (name, strlen (name), | |
16320 | - &objfile->objfile_obstack); | |
16321 | - } | |
16322 | - else | |
16323 | - { | |
16324 | - TYPE_NAME (type) = name; | |
16325 | - } | |
16326 | + if (name) | |
16327 | + switch ((long) objfile) | |
16328 | + { | |
16329 | + case (long) OBJFILE_INTERNAL: | |
16330 | + TYPE_NAME (type) = name; | |
16331 | + break; | |
16332 | + case (long) OBJFILE_MALLOC: | |
16333 | + TYPE_NAME (type) = xstrdup (name); | |
16334 | + break; | |
16335 | +#if 0 /* OBJFILE_MALLOC duplication now. */ | |
16336 | + case (long) NULL: | |
16337 | + internal_error (__FILE__, __LINE__, | |
16338 | + _("OBJFILE pointer NULL should be OBJFILE_* instead")); | |
16339 | +#endif | |
16340 | + default: | |
16341 | + TYPE_NAME (type) = obsavestring (name, strlen (name), | |
16342 | + &objfile->objfile_obstack); | |
16343 | + } | |
16344 | ||
16345 | /* C++ fancies. */ | |
16346 | ||
16347 | @@ -1803,6 +1973,10 @@ init_type (enum type_code code, int length, int flags, | |
16348 | { | |
16349 | INIT_CPLUS_SPECIFIC (type); | |
16350 | } | |
16351 | + | |
16352 | + if (!objfile) | |
16353 | + type_incref (type); | |
16354 | + | |
16355 | return (type); | |
16356 | } | |
16357 | ||
16358 | @@ -2916,33 +3090,47 @@ type_pair_eq (const void *item_lhs, const void *item_rhs) | |
16359 | } | |
16360 | ||
16361 | /* Allocate the hash table used by copy_type_recursive to walk | |
16362 | - types without duplicates. We use OBJFILE's obstack, because | |
16363 | - OBJFILE is about to be deleted. */ | |
16364 | + types without duplicates. */ | |
16365 | ||
16366 | htab_t | |
16367 | create_copied_types_hash (struct objfile *objfile) | |
16368 | { | |
16369 | - return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq, | |
16370 | - NULL, &objfile->objfile_obstack, | |
16371 | - hashtab_obstack_allocate, | |
16372 | - dummy_obstack_deallocate); | |
16373 | + if (objfile == NULL) | |
16374 | + { | |
16375 | + /* NULL OBJFILE is for TYPE_DYNAMIC types already contained in | |
16376 | + OBJFILE_MALLOC memory, such as those from VALUE_HISTORY_CHAIN. Table | |
16377 | + element entries get allocated by xmalloc - so use xfree. */ | |
16378 | + return htab_create (1, type_pair_hash, type_pair_eq, xfree); | |
16379 | + } | |
16380 | + else | |
16381 | + { | |
16382 | + /* Use OBJFILE's obstack, because OBJFILE is about to be deleted. Table | |
16383 | + element entries get allocated by xmalloc - so use xfree. */ | |
16384 | + return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq, | |
16385 | + xfree, &objfile->objfile_obstack, | |
16386 | + hashtab_obstack_allocate, | |
16387 | + dummy_obstack_deallocate); | |
16388 | + } | |
16389 | } | |
16390 | ||
16391 | -/* Recursively copy (deep copy) TYPE, if it is associated with | |
16392 | - OBJFILE. Return a new type allocated using malloc, a saved type if | |
16393 | - we have already visited TYPE (using COPIED_TYPES), or TYPE if it is | |
16394 | - not associated with OBJFILE. */ | |
16395 | +/* A helper for copy_type_recursive. This does all the work. | |
16396 | + REPRESENTATIVE is a pointer to a type. This is used to register | |
16397 | + newly-created types in the type_refc_table. Initially it pointer | |
16398 | + to a NULL pointer, but it is filled in the first time a type is | |
16399 | + copied. OBJFILE is used only for an assertion checking. */ | |
16400 | ||
16401 | -struct type * | |
16402 | -copy_type_recursive (struct objfile *objfile, | |
16403 | - struct type *type, | |
16404 | - htab_t copied_types) | |
16405 | +static struct type * | |
16406 | +copy_type_recursive_1 (struct objfile *objfile, | |
16407 | + struct type *type, | |
16408 | + htab_t copied_types, | |
16409 | + struct type **representative) | |
16410 | { | |
16411 | struct type_pair *stored, pair; | |
16412 | void **slot; | |
16413 | struct type *new_type; | |
16414 | ||
16415 | - if (TYPE_OBJFILE (type) == NULL) | |
16416 | + if (TYPE_OBJFILE (type) == OBJFILE_INTERNAL | |
16417 | + || (objfile == OBJFILE_MALLOC && !TYPE_DYNAMIC (type))) | |
16418 | return type; | |
16419 | ||
16420 | /* This type shouldn't be pointing to any types in other objfiles; | |
16421 | @@ -2954,11 +3142,15 @@ copy_type_recursive (struct objfile *objfile, | |
16422 | if (*slot != NULL) | |
16423 | return ((struct type_pair *) *slot)->new; | |
16424 | ||
16425 | - new_type = alloc_type (NULL); | |
16426 | + new_type = alloc_type (OBJFILE_MALLOC, *representative); | |
16427 | + if (!*representative) | |
16428 | + *representative = new_type; | |
16429 | ||
16430 | /* We must add the new type to the hash table immediately, in case | |
16431 | - we encounter this type again during a recursive call below. */ | |
16432 | - stored = obstack_alloc (&objfile->objfile_obstack, sizeof (struct type_pair)); | |
16433 | + we encounter this type again during a recursive call below. Memory could | |
16434 | + be allocated from OBJFILE in the case we will be removing OBJFILE, this | |
16435 | + optimization is missed and xfree is called for it from COPIED_TYPES. */ | |
16436 | + stored = xmalloc (sizeof (*stored)); | |
16437 | stored->old = type; | |
16438 | stored->new = new_type; | |
16439 | *slot = stored; | |
16440 | @@ -2968,6 +3160,13 @@ copy_type_recursive (struct objfile *objfile, | |
16441 | *TYPE_MAIN_TYPE (new_type) = *TYPE_MAIN_TYPE (type); | |
16442 | TYPE_OBJFILE (new_type) = NULL; | |
16443 | ||
16444 | + /* Pre-clear the fields processed by delete_main_type. If DWARF block | |
16445 | + evaluations below call error we would leave an unfreeable TYPE. */ | |
16446 | + TYPE_TARGET_TYPE (new_type) = NULL; | |
16447 | + TYPE_VPTR_BASETYPE (new_type) = NULL; | |
16448 | + TYPE_NFIELDS (new_type) = 0; | |
16449 | + TYPE_FIELDS (new_type) = NULL; | |
16450 | + | |
16451 | if (TYPE_NAME (type)) | |
16452 | TYPE_NAME (new_type) = xstrdup (TYPE_NAME (type)); | |
16453 | if (TYPE_TAG_NAME (type)) | |
16454 | @@ -2976,12 +3175,45 @@ copy_type_recursive (struct objfile *objfile, | |
16455 | TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type); | |
16456 | TYPE_LENGTH (new_type) = TYPE_LENGTH (type); | |
16457 | ||
16458 | + if (TYPE_ALLOCATED (new_type)) | |
16459 | + { | |
16460 | + gdb_assert (!TYPE_NOT_ALLOCATED (new_type)); | |
16461 | + | |
16462 | + if (!dwarf_locexpr_baton_eval (TYPE_ALLOCATED (new_type))) | |
16463 | + TYPE_NOT_ALLOCATED (new_type) = 1; | |
16464 | + TYPE_ALLOCATED (new_type) = NULL; | |
16465 | + } | |
16466 | + | |
16467 | + if (TYPE_ASSOCIATED (new_type)) | |
16468 | + { | |
16469 | + gdb_assert (!TYPE_NOT_ASSOCIATED (new_type)); | |
16470 | + | |
16471 | + if (!dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (new_type))) | |
16472 | + TYPE_NOT_ASSOCIATED (new_type) = 1; | |
16473 | + TYPE_ASSOCIATED (new_type) = NULL; | |
16474 | + } | |
16475 | + | |
16476 | + if (!TYPE_DATA_LOCATION_IS_ADDR (new_type) | |
16477 | + && TYPE_DATA_LOCATION_DWARF_BLOCK (new_type)) | |
16478 | + { | |
16479 | + if (TYPE_NOT_ALLOCATED (new_type) | |
16480 | + || TYPE_NOT_ASSOCIATED (new_type)) | |
16481 | + TYPE_DATA_LOCATION_DWARF_BLOCK (new_type) = NULL; | |
16482 | + else | |
16483 | + { | |
16484 | + TYPE_DATA_LOCATION_IS_ADDR (new_type) = 1; | |
16485 | + TYPE_DATA_LOCATION_ADDR (new_type) = dwarf_locexpr_baton_eval | |
16486 | + (TYPE_DATA_LOCATION_DWARF_BLOCK (new_type)); | |
16487 | + } | |
16488 | + } | |
16489 | + | |
16490 | /* Copy the fields. */ | |
16491 | if (TYPE_NFIELDS (type)) | |
16492 | { | |
16493 | int i, nfields; | |
16494 | ||
16495 | nfields = TYPE_NFIELDS (type); | |
16496 | + TYPE_NFIELDS (new_type) = nfields; | |
16497 | TYPE_FIELDS (new_type) = XCALLOC (nfields, struct field); | |
16498 | for (i = 0; i < nfields; i++) | |
16499 | { | |
16500 | @@ -2990,8 +3222,8 @@ copy_type_recursive (struct objfile *objfile, | |
16501 | TYPE_FIELD_BITSIZE (new_type, i) = TYPE_FIELD_BITSIZE (type, i); | |
16502 | if (TYPE_FIELD_TYPE (type, i)) | |
16503 | TYPE_FIELD_TYPE (new_type, i) | |
16504 | - = copy_type_recursive (objfile, TYPE_FIELD_TYPE (type, i), | |
16505 | - copied_types); | |
16506 | + = copy_type_recursive_1 (objfile, TYPE_FIELD_TYPE (type, i), | |
16507 | + copied_types, representative); | |
16508 | if (TYPE_FIELD_NAME (type, i)) | |
16509 | TYPE_FIELD_NAME (new_type, i) = | |
16510 | xstrdup (TYPE_FIELD_NAME (type, i)); | |
16511 | @@ -3010,6 +3242,16 @@ copy_type_recursive (struct objfile *objfile, | |
16512 | xstrdup (TYPE_FIELD_STATIC_PHYSNAME (type, | |
16513 | i))); | |
16514 | break; | |
16515 | + case FIELD_LOC_KIND_DWARF_BLOCK: | |
16516 | + /* `struct dwarf2_locexpr_baton' is too bound to its objfile so | |
16517 | + it is expected to be made constant by CHECK_TYPEDEF. */ | |
16518 | + if (TYPE_NOT_ALLOCATED (new_type) | |
16519 | + || TYPE_NOT_ASSOCIATED (new_type)) | |
16520 | + SET_FIELD_DWARF_BLOCK (TYPE_FIELD (new_type, i), NULL); | |
16521 | + else | |
16522 | + SET_FIELD_BITPOS (TYPE_FIELD (new_type, i), | |
16523 | + dwarf_locexpr_baton_eval (TYPE_FIELD_DWARF_BLOCK (type, i))); | |
16524 | + break; | |
16525 | default: | |
16526 | internal_error (__FILE__, __LINE__, | |
16527 | _("Unexpected type field location kind: %d"), | |
16528 | @@ -3018,17 +3260,32 @@ copy_type_recursive (struct objfile *objfile, | |
16529 | } | |
16530 | } | |
16531 | ||
16532 | + /* Convert TYPE_RANGE_HIGH_BOUND_IS_COUNT into a regular bound. */ | |
16533 | + if (TYPE_CODE (type) == TYPE_CODE_RANGE | |
16534 | + && TYPE_RANGE_HIGH_BOUND_IS_COUNT (type)) | |
16535 | + { | |
16536 | + TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type) = 0; | |
16537 | + TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (type) | |
16538 | + + TYPE_HIGH_BOUND (type) - 1; | |
16539 | + } | |
16540 | + | |
16541 | + /* Both FIELD_LOC_KIND_DWARF_BLOCK and TYPE_RANGE_HIGH_BOUND_IS_COUNT were | |
16542 | + possibly converted. */ | |
16543 | + TYPE_DYNAMIC (new_type) = 0; | |
16544 | + | |
16545 | /* Copy pointers to other types. */ | |
16546 | if (TYPE_TARGET_TYPE (type)) | |
16547 | TYPE_TARGET_TYPE (new_type) = | |
16548 | - copy_type_recursive (objfile, | |
16549 | - TYPE_TARGET_TYPE (type), | |
16550 | - copied_types); | |
16551 | + copy_type_recursive_1 (objfile, | |
16552 | + TYPE_TARGET_TYPE (type), | |
16553 | + copied_types, | |
16554 | + representative); | |
16555 | if (TYPE_VPTR_BASETYPE (type)) | |
16556 | TYPE_VPTR_BASETYPE (new_type) = | |
16557 | - copy_type_recursive (objfile, | |
16558 | - TYPE_VPTR_BASETYPE (type), | |
16559 | - copied_types); | |
16560 | + copy_type_recursive_1 (objfile, | |
16561 | + TYPE_VPTR_BASETYPE (type), | |
16562 | + copied_types, | |
16563 | + representative); | |
16564 | /* Maybe copy the type_specific bits. | |
16565 | ||
16566 | NOTE drow/2005-12-09: We do not copy the C++-specific bits like | |
16567 | @@ -3046,6 +3303,20 @@ copy_type_recursive (struct objfile *objfile, | |
16568 | return new_type; | |
16569 | } | |
16570 | ||
16571 | +/* Recursively copy (deep copy) TYPE. Return a new type allocated using | |
16572 | + malloc, a saved type if we have already visited TYPE (using COPIED_TYPES), | |
16573 | + or TYPE if it is not associated with OBJFILE. */ | |
16574 | + | |
16575 | +struct type * | |
16576 | +copy_type_recursive (struct type *type, | |
16577 | + htab_t copied_types) | |
16578 | +{ | |
16579 | + struct type *representative = NULL; | |
16580 | + | |
16581 | + return copy_type_recursive_1 (TYPE_OBJFILE (type), type, copied_types, | |
16582 | + &representative); | |
16583 | +} | |
16584 | + | |
16585 | /* Make a copy of the given TYPE, except that the pointer & reference | |
16586 | types are not preserved. | |
16587 | ||
16588 | @@ -3059,7 +3330,7 @@ copy_type (const struct type *type) | |
16589 | ||
16590 | gdb_assert (TYPE_OBJFILE (type) != NULL); | |
16591 | ||
16592 | - new_type = alloc_type (TYPE_OBJFILE (type)); | |
16593 | + new_type = alloc_type (TYPE_OBJFILE (type), NULL); | |
16594 | TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type); | |
16595 | TYPE_LENGTH (new_type) = TYPE_LENGTH (type); | |
16596 | memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type), | |
16597 | @@ -3068,6 +3339,232 @@ copy_type (const struct type *type) | |
16598 | return new_type; | |
16599 | } | |
16600 | ||
16601 | +static void delete_type (struct type *type); | |
16602 | + | |
16603 | +/* A helper for delete_type which deletes a main_type and the things to which | |
16604 | + it refers. TYPE is a type whose main_type we wish to destroy. */ | |
16605 | + | |
16606 | +static void | |
16607 | +delete_main_type (struct main_type *main_type) | |
16608 | +{ | |
16609 | + int i; | |
16610 | + void **slot; | |
16611 | + struct | |
16612 | + { | |
16613 | + struct main_type *main_type; | |
16614 | + } type_local = { main_type }, *type = &type_local; | |
16615 | + | |
16616 | + gdb_assert (TYPE_OBJFILE (type) == OBJFILE_MALLOC); | |
16617 | + | |
16618 | + xfree (TYPE_NAME (type)); | |
16619 | + xfree (TYPE_TAG_NAME (type)); | |
16620 | + | |
16621 | + for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
16622 | + { | |
16623 | + xfree (TYPE_FIELD_NAME (type, i)); | |
16624 | + | |
16625 | + if (TYPE_FIELD_LOC_KIND (type, i) == FIELD_LOC_KIND_PHYSNAME) | |
16626 | + xfree (TYPE_FIELD_STATIC_PHYSNAME (type, i)); | |
16627 | + } | |
16628 | + xfree (TYPE_FIELDS (type)); | |
16629 | + | |
16630 | + /* Strangely, HAVE_CPLUS_STRUCT will return true when there isn't | |
16631 | + one at all. */ | |
16632 | + gdb_assert (!HAVE_CPLUS_STRUCT (type) || !TYPE_CPLUS_SPECIFIC (type)); | |
16633 | + | |
16634 | + xfree (TYPE_MAIN_TYPE (type)); | |
16635 | +} | |
16636 | + | |
16637 | +/* Store `struct main_type *' entries which got `struct type *' deleted. */ | |
16638 | + | |
16639 | +static htab_t deleted_main_types_hash; | |
16640 | + | |
16641 | +/* To be called before any call of delete_type. */ | |
16642 | + | |
16643 | +static void | |
16644 | +delete_type_begin (void) | |
16645 | +{ | |
16646 | + gdb_assert (deleted_main_types_hash == NULL); | |
16647 | + | |
16648 | + deleted_main_types_hash = htab_create_alloc (10, htab_hash_pointer, | |
16649 | + htab_eq_pointer, NULL, xcalloc, xfree); | |
16650 | +} | |
16651 | + | |
16652 | +/* Helper for delete_type_finish. */ | |
16653 | + | |
16654 | +static int | |
16655 | +delete_type_finish_traverse (void **slot, void *unused) | |
16656 | +{ | |
16657 | + struct main_type *main_type = *slot; | |
16658 | + | |
16659 | + delete_main_type (main_type); | |
16660 | + | |
16661 | + return 1; | |
16662 | +} | |
16663 | + | |
16664 | +/* To be called after all the calls of delete_type. Each MAIN_TYPE must have | |
16665 | + either none or all of its TYPE entries deleted. */ | |
16666 | + | |
16667 | +static void | |
16668 | +delete_type_finish (void) | |
16669 | +{ | |
16670 | + htab_traverse (deleted_main_types_hash, delete_type_finish_traverse, NULL); | |
16671 | + | |
16672 | + htab_delete (deleted_main_types_hash); | |
16673 | + deleted_main_types_hash = NULL; | |
16674 | +} | |
16675 | + | |
16676 | +/* Delete TYPE and remember MAIN_TYPE it references. TYPE must have been | |
16677 | + allocated using xmalloc -- not using an objfile. You must wrap calls of | |
16678 | + this function by delete_type_begin and delete_type_finish. */ | |
16679 | + | |
16680 | +static void | |
16681 | +delete_type (struct type *type) | |
16682 | +{ | |
16683 | + void **slot; | |
16684 | + | |
16685 | + if (!type) | |
16686 | + return; | |
16687 | + | |
16688 | + if (TYPE_OBJFILE (type) == OBJFILE_INTERNAL) | |
16689 | + return; | |
16690 | + gdb_assert (TYPE_OBJFILE (type) == OBJFILE_MALLOC); | |
16691 | + | |
16692 | + slot = htab_find_slot (deleted_main_types_hash, TYPE_MAIN_TYPE (type), | |
16693 | + INSERT); | |
16694 | + gdb_assert (!*slot); | |
16695 | + *slot = TYPE_MAIN_TYPE (type); | |
16696 | + | |
16697 | + xfree (type); | |
16698 | +} | |
16699 | + | |
16700 | +/* Hash function for type_refc_table. */ | |
16701 | + | |
16702 | +static hashval_t | |
16703 | +type_refc_hash (const void *p) | |
16704 | +{ | |
16705 | + const struct type_refc_entry *entry = p; | |
16706 | + return htab_hash_pointer (entry->type); | |
16707 | +} | |
16708 | + | |
16709 | +/* Equality function for type_refc_table. */ | |
16710 | + | |
16711 | +static int | |
16712 | +type_refc_equal (const void *a, const void *b) | |
16713 | +{ | |
16714 | + const struct type_refc_entry *left = a; | |
16715 | + const struct type_refc_entry *right = b; | |
16716 | + return left->type == right->type; | |
16717 | +} | |
16718 | + | |
16719 | +/* Insert the new type NEW_TYPE into the table. Does nothing if | |
16720 | + NEW_TYPE has an objfile. If PARENT_TYPE is not NULL, then NEW_TYPE | |
16721 | + will be inserted into the same hierarchy as PARENT_TYPE. In this | |
16722 | + case, PARENT_TYPE must already exist in the reference count map. | |
16723 | + If PARENT_TYPE is NULL, a new reference count is allocated and set | |
16724 | + to one. */ | |
16725 | + | |
16726 | +static void | |
16727 | +type_init_refc (struct type *new_type, struct type *parent_type) | |
16728 | +{ | |
16729 | + int *refc; | |
16730 | + void **slot; | |
16731 | + struct type_refc_entry *new_entry; | |
16732 | + | |
16733 | + if (TYPE_OBJFILE (new_type)) | |
16734 | + return; | |
16735 | + | |
16736 | + if (parent_type) | |
16737 | + { | |
16738 | + struct type_refc_entry entry, *found; | |
16739 | + entry.type = parent_type; | |
16740 | + found = htab_find (type_refc_table, &entry); | |
16741 | + gdb_assert (found); | |
16742 | + refc = found->refc; | |
16743 | + } | |
16744 | + else | |
16745 | + { | |
16746 | + refc = xmalloc (sizeof (int)); | |
16747 | + *refc = 0; | |
16748 | + } | |
16749 | + | |
16750 | + new_entry = XNEW (struct type_refc_entry); | |
16751 | + new_entry->type = new_type; | |
16752 | + new_entry->refc = refc; | |
16753 | + | |
16754 | + slot = htab_find_slot (type_refc_table, new_entry, INSERT); | |
16755 | + gdb_assert (!*slot); | |
16756 | + *slot = new_entry; | |
16757 | +} | |
16758 | + | |
16759 | +/* Increment the reference count for TYPE. */ | |
16760 | + | |
16761 | +void | |
16762 | +type_incref (struct type *type) | |
16763 | +{ | |
16764 | + struct type_refc_entry entry, *found; | |
16765 | + | |
16766 | + if (TYPE_OBJFILE (type)) | |
16767 | + return; | |
16768 | + | |
16769 | + entry.type = type; | |
16770 | + found = htab_find (type_refc_table, &entry); | |
16771 | + gdb_assert (found); | |
16772 | + ++*(found->refc); | |
16773 | +} | |
16774 | + | |
16775 | +/* A traverse callback for type_refc_table which removes any entry | |
16776 | + whose reference count is zero (unused entry). */ | |
16777 | + | |
16778 | +static int | |
16779 | +type_refc_remove (void **slot, void *unused) | |
16780 | +{ | |
16781 | + struct type_refc_entry *entry = *slot; | |
16782 | + | |
16783 | + if (*entry->refc == 0) | |
16784 | + { | |
16785 | + delete_type (entry->type); | |
16786 | + | |
16787 | + xfree (entry); | |
16788 | + htab_clear_slot (type_refc_table, slot); | |
16789 | + } | |
16790 | + | |
16791 | + return 1; | |
16792 | +} | |
16793 | + | |
16794 | +/* Decrement the reference count for TYPE. Even if TYPE has no more | |
16795 | + references still do not delete it as callers may hold pointers to types | |
16796 | + dynamically generated by check_typedef where type_incref is never called. | |
16797 | + Always rely on the free_all_types garbage collector. */ | |
16798 | + | |
16799 | +void | |
16800 | +type_decref (struct type *type) | |
16801 | +{ | |
16802 | + struct type_refc_entry entry, *found; | |
16803 | + | |
16804 | + if (TYPE_OBJFILE (type)) | |
16805 | + return; | |
16806 | + | |
16807 | + entry.type = type; | |
16808 | + found = htab_find (type_refc_table, &entry); | |
16809 | + gdb_assert (found); | |
16810 | + gdb_assert (found->refc > 0); | |
16811 | + --*(found->refc); | |
16812 | +} | |
16813 | + | |
16814 | +/* Free all the types that have been allocated and that are not used according | |
16815 | + to type_refc_entry->refc. Called after each command, successful or not. | |
16816 | + Use this cleanup only in the GDB idle state as GDB code does not necessarily | |
16817 | + use type_incref / type_decref during temporary use of types. */ | |
16818 | + | |
16819 | +void | |
16820 | +free_all_types (void) | |
16821 | +{ | |
16822 | + delete_type_begin (); | |
16823 | + htab_traverse (type_refc_table, type_refc_remove, NULL); | |
16824 | + delete_type_finish (); | |
16825 | +} | |
16826 | + | |
16827 | static struct type * | |
16828 | build_flt (int bit, char *name, const struct floatformat **floatformats) | |
16829 | { | |
16830 | @@ -3105,7 +3602,7 @@ build_complex (int bit, char *name, struct type *target_type) | |
16831 | return builtin_type_error; | |
16832 | } | |
16833 | t = init_type (TYPE_CODE_COMPLEX, 2 * bit / TARGET_CHAR_BIT, | |
16834 | - 0, name, (struct objfile *) NULL); | |
16835 | + 0, name, OBJFILE_INTERNAL); | |
16836 | TYPE_TARGET_TYPE (t) = target_type; | |
16837 | return t; | |
16838 | } | |
16839 | @@ -3119,56 +3616,56 @@ gdbtypes_post_init (struct gdbarch *gdbarch) | |
16840 | builtin_type->builtin_void = | |
16841 | init_type (TYPE_CODE_VOID, 1, | |
16842 | 0, | |
16843 | - "void", (struct objfile *) NULL); | |
16844 | + "void", OBJFILE_INTERNAL); | |
16845 | builtin_type->builtin_char = | |
16846 | init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, | |
16847 | (TYPE_FLAG_NOSIGN | |
16848 | | (gdbarch_char_signed (gdbarch) ? 0 : TYPE_FLAG_UNSIGNED)), | |
16849 | - "char", (struct objfile *) NULL); | |
16850 | + "char", OBJFILE_INTERNAL); | |
16851 | builtin_type->builtin_signed_char = | |
16852 | init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, | |
16853 | 0, | |
16854 | - "signed char", (struct objfile *) NULL); | |
16855 | + "signed char", OBJFILE_INTERNAL); | |
16856 | builtin_type->builtin_unsigned_char = | |
16857 | init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, | |
16858 | TYPE_FLAG_UNSIGNED, | |
16859 | - "unsigned char", (struct objfile *) NULL); | |
16860 | + "unsigned char", OBJFILE_INTERNAL); | |
16861 | builtin_type->builtin_short = | |
16862 | init_type (TYPE_CODE_INT, | |
16863 | gdbarch_short_bit (gdbarch) / TARGET_CHAR_BIT, | |
16864 | - 0, "short", (struct objfile *) NULL); | |
16865 | + 0, "short", OBJFILE_INTERNAL); | |
16866 | builtin_type->builtin_unsigned_short = | |
16867 | init_type (TYPE_CODE_INT, | |
16868 | gdbarch_short_bit (gdbarch) / TARGET_CHAR_BIT, | |
16869 | TYPE_FLAG_UNSIGNED, "unsigned short", | |
16870 | - (struct objfile *) NULL); | |
16871 | + OBJFILE_INTERNAL); | |
16872 | builtin_type->builtin_int = | |
16873 | init_type (TYPE_CODE_INT, | |
16874 | gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT, | |
16875 | - 0, "int", (struct objfile *) NULL); | |
16876 | + 0, "int", OBJFILE_INTERNAL); | |
16877 | builtin_type->builtin_unsigned_int = | |
16878 | init_type (TYPE_CODE_INT, | |
16879 | gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT, | |
16880 | TYPE_FLAG_UNSIGNED, "unsigned int", | |
16881 | - (struct objfile *) NULL); | |
16882 | + OBJFILE_INTERNAL); | |
16883 | builtin_type->builtin_long = | |
16884 | init_type (TYPE_CODE_INT, | |
16885 | gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT, | |
16886 | - 0, "long", (struct objfile *) NULL); | |
16887 | + 0, "long", OBJFILE_INTERNAL); | |
16888 | builtin_type->builtin_unsigned_long = | |
16889 | init_type (TYPE_CODE_INT, | |
16890 | gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT, | |
16891 | TYPE_FLAG_UNSIGNED, "unsigned long", | |
16892 | - (struct objfile *) NULL); | |
16893 | + OBJFILE_INTERNAL); | |
16894 | builtin_type->builtin_long_long = | |
16895 | init_type (TYPE_CODE_INT, | |
16896 | gdbarch_long_long_bit (gdbarch) / TARGET_CHAR_BIT, | |
16897 | - 0, "long long", (struct objfile *) NULL); | |
16898 | + 0, "long long", OBJFILE_INTERNAL); | |
16899 | builtin_type->builtin_unsigned_long_long = | |
16900 | init_type (TYPE_CODE_INT, | |
16901 | gdbarch_long_long_bit (gdbarch) / TARGET_CHAR_BIT, | |
16902 | TYPE_FLAG_UNSIGNED, "unsigned long long", | |
16903 | - (struct objfile *) NULL); | |
16904 | + OBJFILE_INTERNAL); | |
16905 | builtin_type->builtin_float | |
16906 | = build_flt (gdbarch_float_bit (gdbarch), "float", | |
16907 | gdbarch_float_format (gdbarch)); | |
16908 | @@ -3187,26 +3684,26 @@ gdbtypes_post_init (struct gdbarch *gdbarch) | |
16909 | builtin_type->builtin_string = | |
16910 | init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT, | |
16911 | 0, | |
16912 | - "string", (struct objfile *) NULL); | |
16913 | + "string", OBJFILE_INTERNAL); | |
16914 | builtin_type->builtin_bool = | |
16915 | init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT, | |
16916 | 0, | |
16917 | - "bool", (struct objfile *) NULL); | |
16918 | + "bool", OBJFILE_INTERNAL); | |
16919 | ||
16920 | /* The following three are about decimal floating point types, which | |
16921 | are 32-bits, 64-bits and 128-bits respectively. */ | |
16922 | builtin_type->builtin_decfloat | |
16923 | = init_type (TYPE_CODE_DECFLOAT, 32 / 8, | |
16924 | 0, | |
16925 | - "_Decimal32", (struct objfile *) NULL); | |
16926 | + "_Decimal32", OBJFILE_INTERNAL); | |
16927 | builtin_type->builtin_decdouble | |
16928 | = init_type (TYPE_CODE_DECFLOAT, 64 / 8, | |
16929 | 0, | |
16930 | - "_Decimal64", (struct objfile *) NULL); | |
16931 | + "_Decimal64", OBJFILE_INTERNAL); | |
16932 | builtin_type->builtin_declong | |
16933 | = init_type (TYPE_CODE_DECFLOAT, 128 / 8, | |
16934 | 0, | |
16935 | - "_Decimal128", (struct objfile *) NULL); | |
16936 | + "_Decimal128", OBJFILE_INTERNAL); | |
16937 | ||
16938 | /* Pointer/Address types. */ | |
16939 | ||
16940 | @@ -3245,27 +3742,28 @@ gdbtypes_post_init (struct gdbarch *gdbarch) | |
16941 | init_type (TYPE_CODE_INT, | |
16942 | gdbarch_addr_bit (gdbarch) / 8, | |
16943 | TYPE_FLAG_UNSIGNED, | |
16944 | - "__CORE_ADDR", (struct objfile *) NULL); | |
16945 | + "__CORE_ADDR", OBJFILE_INTERNAL); | |
16946 | ||
16947 | ||
16948 | /* The following set of types is used for symbols with no | |
16949 | debug information. */ | |
16950 | builtin_type->nodebug_text_symbol = | |
16951 | init_type (TYPE_CODE_FUNC, 1, 0, | |
16952 | - "<text variable, no debug info>", NULL); | |
16953 | + "<text variable, no debug info>", OBJFILE_INTERNAL); | |
16954 | TYPE_TARGET_TYPE (builtin_type->nodebug_text_symbol) = | |
16955 | builtin_type->builtin_int; | |
16956 | builtin_type->nodebug_data_symbol = | |
16957 | init_type (TYPE_CODE_INT, | |
16958 | gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT, 0, | |
16959 | - "<data variable, no debug info>", NULL); | |
16960 | + "<data variable, no debug info>", OBJFILE_INTERNAL); | |
16961 | builtin_type->nodebug_unknown_symbol = | |
16962 | init_type (TYPE_CODE_INT, 1, 0, | |
16963 | - "<variable (not text or data), no debug info>", NULL); | |
16964 | + "<variable (not text or data), no debug info>", | |
16965 | + OBJFILE_INTERNAL); | |
16966 | builtin_type->nodebug_tls_symbol = | |
16967 | init_type (TYPE_CODE_INT, | |
16968 | gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT, 0, | |
16969 | - "<thread local variable, no debug info>", NULL); | |
16970 | + "<thread local variable, no debug info>", OBJFILE_INTERNAL); | |
16971 | ||
16972 | return builtin_type; | |
16973 | } | |
16974 | @@ -3276,6 +3774,9 @@ _initialize_gdbtypes (void) | |
16975 | { | |
16976 | gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init); | |
16977 | ||
16978 | + type_refc_table = htab_create_alloc (20, type_refc_hash, type_refc_equal, | |
16979 | + NULL, xcalloc, xfree); | |
16980 | + | |
16981 | /* FIXME: The following types are architecture-neutral. However, | |
16982 | they contain pointer_type and reference_type fields potentially | |
16983 | caching pointer or reference types that *are* architecture | |
16984 | @@ -3284,47 +3785,47 @@ _initialize_gdbtypes (void) | |
16985 | builtin_type_int0 = | |
16986 | init_type (TYPE_CODE_INT, 0 / 8, | |
16987 | 0, | |
16988 | - "int0_t", (struct objfile *) NULL); | |
16989 | + "int0_t", OBJFILE_INTERNAL); | |
16990 | builtin_type_int8 = | |
16991 | init_type (TYPE_CODE_INT, 8 / 8, | |
16992 | TYPE_FLAG_NOTTEXT, | |
16993 | - "int8_t", (struct objfile *) NULL); | |
16994 | + "int8_t", OBJFILE_INTERNAL); | |
16995 | builtin_type_uint8 = | |
16996 | init_type (TYPE_CODE_INT, 8 / 8, | |
16997 | TYPE_FLAG_UNSIGNED | TYPE_FLAG_NOTTEXT, | |
16998 | - "uint8_t", (struct objfile *) NULL); | |
16999 | + "uint8_t", OBJFILE_INTERNAL); | |
17000 | builtin_type_int16 = | |
17001 | init_type (TYPE_CODE_INT, 16 / 8, | |
17002 | 0, | |
17003 | - "int16_t", (struct objfile *) NULL); | |
17004 | + "int16_t", OBJFILE_INTERNAL); | |
17005 | builtin_type_uint16 = | |
17006 | init_type (TYPE_CODE_INT, 16 / 8, | |
17007 | TYPE_FLAG_UNSIGNED, | |
17008 | - "uint16_t", (struct objfile *) NULL); | |
17009 | + "uint16_t", OBJFILE_INTERNAL); | |
17010 | builtin_type_int32 = | |
17011 | init_type (TYPE_CODE_INT, 32 / 8, | |
17012 | 0, | |
17013 | - "int32_t", (struct objfile *) NULL); | |
17014 | + "int32_t", OBJFILE_INTERNAL); | |
17015 | builtin_type_uint32 = | |
17016 | init_type (TYPE_CODE_INT, 32 / 8, | |
17017 | TYPE_FLAG_UNSIGNED, | |
17018 | - "uint32_t", (struct objfile *) NULL); | |
17019 | + "uint32_t", OBJFILE_INTERNAL); | |
17020 | builtin_type_int64 = | |
17021 | init_type (TYPE_CODE_INT, 64 / 8, | |
17022 | 0, | |
17023 | - "int64_t", (struct objfile *) NULL); | |
17024 | + "int64_t", OBJFILE_INTERNAL); | |
17025 | builtin_type_uint64 = | |
17026 | init_type (TYPE_CODE_INT, 64 / 8, | |
17027 | TYPE_FLAG_UNSIGNED, | |
17028 | - "uint64_t", (struct objfile *) NULL); | |
17029 | + "uint64_t", OBJFILE_INTERNAL); | |
17030 | builtin_type_int128 = | |
17031 | init_type (TYPE_CODE_INT, 128 / 8, | |
17032 | 0, | |
17033 | - "int128_t", (struct objfile *) NULL); | |
17034 | + "int128_t", OBJFILE_INTERNAL); | |
17035 | builtin_type_uint128 = | |
17036 | init_type (TYPE_CODE_INT, 128 / 8, | |
17037 | TYPE_FLAG_UNSIGNED, | |
17038 | - "uint128_t", (struct objfile *) NULL); | |
17039 | + "uint128_t", OBJFILE_INTERNAL); | |
17040 | ||
17041 | builtin_type_ieee_single = | |
17042 | build_flt (-1, "builtin_type_ieee_single", floatformats_ieee_single); | |
17043 | @@ -3344,15 +3845,15 @@ _initialize_gdbtypes (void) | |
17044 | builtin_type_void = | |
17045 | init_type (TYPE_CODE_VOID, 1, | |
17046 | 0, | |
17047 | - "void", (struct objfile *) NULL); | |
17048 | + "void", OBJFILE_INTERNAL); | |
17049 | builtin_type_true_char = | |
17050 | init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT, | |
17051 | 0, | |
17052 | - "true character", (struct objfile *) NULL); | |
17053 | + "true character", OBJFILE_INTERNAL); | |
17054 | builtin_type_true_unsigned_char = | |
17055 | init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT, | |
17056 | TYPE_FLAG_UNSIGNED, | |
17057 | - "true character", (struct objfile *) NULL); | |
17058 | + "true character", OBJFILE_INTERNAL); | |
17059 | ||
17060 | add_setshow_zinteger_cmd ("overload", no_class, &overload_debug, _("\ | |
17061 | Set debugging of C++ overloading."), _("\ | |
17062 | diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h | |
17063 | index c90b6d7..077b89c 100644 | |
17064 | --- a/gdb/gdbtypes.h | |
17065 | +++ b/gdb/gdbtypes.h | |
17066 | @@ -134,7 +134,10 @@ enum type_code | |
17067 | ||
17068 | TYPE_CODE_NAMESPACE, /* C++ namespace. */ | |
17069 | ||
17070 | - TYPE_CODE_DECFLOAT /* Decimal floating point. */ | |
17071 | + TYPE_CODE_DECFLOAT, /* Decimal floating point. */ | |
17072 | + | |
17073 | + /* Internal function type. */ | |
17074 | + TYPE_CODE_INTERNAL_FUNCTION | |
17075 | }; | |
17076 | ||
17077 | /* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an | |
17078 | @@ -209,6 +212,11 @@ enum type_instance_flag_value | |
17079 | ||
17080 | #define TYPE_TARGET_STUB(t) (TYPE_MAIN_TYPE (t)->flag_target_stub) | |
17081 | ||
17082 | +/* Type needs to be evaluated on each CHECK_TYPEDEF and its results must not be | |
17083 | + sticky. */ | |
17084 | + | |
17085 | +#define TYPE_DYNAMIC(t) (TYPE_MAIN_TYPE (t)->flag_dynamic) | |
17086 | + | |
17087 | /* Static type. If this is set, the corresponding type had | |
17088 | * a static modifier. | |
17089 | * Note: This may be unnecessary, since static data members | |
17090 | @@ -266,6 +274,36 @@ enum type_instance_flag_value | |
17091 | ||
17092 | #define TYPE_NOTTEXT(t) (TYPE_MAIN_TYPE (t)->flag_nottext) | |
17093 | ||
17094 | +/* Is HIGH_BOUND a low-bound relative count (1) or the high bound itself (0)? */ | |
17095 | + | |
17096 | +#define TYPE_RANGE_HIGH_BOUND_IS_COUNT(range_type) \ | |
17097 | + (TYPE_MAIN_TYPE (range_type)->flag_range_high_bound_is_count) | |
17098 | + | |
17099 | +/* Not allocated. TYPE_ALLOCATED(t) must be NULL in such case. If this flag | |
17100 | + is unset and TYPE_ALLOCATED(t) is NULL then the type is allocated. If this | |
17101 | + flag is unset and TYPE_ALLOCATED(t) is not NULL then its DWARF block | |
17102 | + determines the actual allocation state. */ | |
17103 | + | |
17104 | +#define TYPE_NOT_ALLOCATED(t) (TYPE_MAIN_TYPE (t)->flag_not_allocated) | |
17105 | + | |
17106 | +/* Not associated. TYPE_ASSOCIATED(t) must be NULL in such case. If this flag | |
17107 | + is unset and TYPE_ASSOCIATED(t) is NULL then the type is associated. If | |
17108 | + this flag is unset and TYPE_ASSOCIATED(t) is not NULL then its DWARF block | |
17109 | + determines the actual association state. */ | |
17110 | + | |
17111 | +#define TYPE_NOT_ASSOCIATED(t) (TYPE_MAIN_TYPE (t)->flag_not_associated) | |
17112 | + | |
17113 | +/* Address of the actual data as for DW_AT_data_location. Its dwarf block must | |
17114 | + not be evaluated unless both TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are | |
17115 | + false. If TYPE_DATA_LOCATION_IS_ADDR set then TYPE_DATA_LOCATION_ADDR value | |
17116 | + is the actual data address value. If unset and | |
17117 | + TYPE_DATA_LOCATION_DWARF_BLOCK is NULL then the value is the normal | |
17118 | + VALUE_ADDRESS copy. If unset and TYPE_DATA_LOCATION_DWARF_BLOCK is not NULL | |
17119 | + then its DWARF block determines the actual data address. */ | |
17120 | + | |
17121 | +#define TYPE_DATA_LOCATION_IS_ADDR(t) \ | |
17122 | + (TYPE_MAIN_TYPE (t)->flag_data_location_is_addr) | |
17123 | + | |
17124 | /* Constant type. If this is set, the corresponding type has a | |
17125 | * const modifier. | |
17126 | */ | |
17127 | @@ -352,6 +390,11 @@ struct main_type | |
17128 | unsigned int flag_stub_supported : 1; | |
17129 | unsigned int flag_nottext : 1; | |
17130 | unsigned int flag_fixed_instance : 1; | |
17131 | + unsigned int flag_dynamic : 1; | |
17132 | + unsigned int flag_range_high_bound_is_count : 1; | |
17133 | + unsigned int flag_not_allocated : 1; | |
17134 | + unsigned int flag_not_associated : 1; | |
17135 | + unsigned int flag_data_location_is_addr : 1; | |
17136 | ||
17137 | /* Number of fields described for this type. This field appears at | |
17138 | this location because it packs nicely here. */ | |
17139 | @@ -414,6 +457,20 @@ struct main_type | |
17140 | ||
17141 | struct type *target_type; | |
17142 | ||
17143 | + /* For DW_AT_data_location. */ | |
17144 | + union | |
17145 | + { | |
17146 | + struct dwarf2_locexpr_baton *dwarf_block; | |
17147 | + CORE_ADDR addr; | |
17148 | + } | |
17149 | + data_location; | |
17150 | + | |
17151 | + /* For DW_AT_allocated. */ | |
17152 | + struct dwarf2_locexpr_baton *allocated; | |
17153 | + | |
17154 | + /* For DW_AT_associated. */ | |
17155 | + struct dwarf2_locexpr_baton *associated; | |
17156 | + | |
17157 | /* For structure and union types, a description of each field. | |
17158 | For set and pascal array types, there is one "field", | |
17159 | whose type is the domain type of the set or array. | |
17160 | @@ -795,9 +852,9 @@ extern void allocate_cplus_struct_type (struct type *); | |
17161 | #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type | |
17162 | #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type | |
17163 | #define TYPE_CHAIN(thistype) (thistype)->chain | |
17164 | -/* Note that if thistype is a TYPEDEF type, you have to call check_typedef. | |
17165 | - But check_typedef does set the TYPE_LENGTH of the TYPEDEF type, | |
17166 | - so you only have to call check_typedef once. Since allocate_value | |
17167 | +/* Note that if thistype is a TYPEDEF, ARRAY or STRING type, you have to call | |
17168 | + check_typedef. But check_typedef does set the TYPE_LENGTH of the TYPEDEF | |
17169 | + type, so you only have to call check_typedef once. Since allocate_value | |
17170 | calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe. */ | |
17171 | #define TYPE_LENGTH(thistype) (thistype)->length | |
17172 | #define TYPE_OBJFILE(thistype) TYPE_MAIN_TYPE(thistype)->objfile | |
17173 | @@ -807,23 +864,44 @@ extern void allocate_cplus_struct_type (struct type *); | |
17174 | #define TYPE_NFIELDS(thistype) TYPE_MAIN_TYPE(thistype)->nfields | |
17175 | #define TYPE_FIELDS(thistype) TYPE_MAIN_TYPE(thistype)->fields | |
17176 | #define TYPE_TEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->template_args | |
17177 | +#define TYPE_DATA_LOCATION_DWARF_BLOCK(thistype) TYPE_MAIN_TYPE (thistype)->data_location.dwarf_block | |
17178 | +#define TYPE_DATA_LOCATION_ADDR(thistype) TYPE_MAIN_TYPE (thistype)->data_location.addr | |
17179 | +#define TYPE_ALLOCATED(thistype) TYPE_MAIN_TYPE (thistype)->allocated | |
17180 | +#define TYPE_ASSOCIATED(thistype) TYPE_MAIN_TYPE (thistype)->associated | |
17181 | ||
17182 | #define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0) | |
17183 | #define TYPE_LOW_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 0) | |
17184 | #define TYPE_HIGH_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 1) | |
17185 | - | |
17186 | -/* Moto-specific stuff for FORTRAN arrays */ | |
17187 | - | |
17188 | -#define TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED(arraytype) \ | |
17189 | - (TYPE_FIELD_ARTIFICIAL(TYPE_INDEX_TYPE((arraytype)),1)) | |
17190 | +#define TYPE_BYTE_STRIDE(range_type) TYPE_FIELD_BITPOS (range_type, 2) | |
17191 | + | |
17192 | +/* Whether we should use TYPE_FIELD_DWARF_BLOCK (and not TYPE_FIELD_BITPOS). */ | |
17193 | +#define TYPE_RANGE_BOUND_IS_DWARF_BLOCK(range_type, fieldno) \ | |
17194 | + (TYPE_FIELD_LOC_KIND (range_type, fieldno) == FIELD_LOC_KIND_DWARF_BLOCK) | |
17195 | +#define TYPE_RANGE_BOUND_SET_DWARF_BLOCK(range_type, fieldno) \ | |
17196 | + (TYPE_FIELD_LOC_KIND (range_type, fieldno) = FIELD_LOC_KIND_DWARF_BLOCK) | |
17197 | +#define TYPE_ARRAY_BOUND_IS_DWARF_BLOCK(array_type, fieldno) \ | |
17198 | + TYPE_RANGE_BOUND_IS_DWARF_BLOCK (TYPE_INDEX_TYPE (array_type), fieldno) | |
17199 | + | |
17200 | +/* Unbound arrays, such as GCC array[]; at end of struct. */ | |
17201 | +#define TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED(rangetype) \ | |
17202 | + TYPE_FIELD_ARTIFICIAL((rangetype),0) | |
17203 | +#define TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED(rangetype) \ | |
17204 | + TYPE_FIELD_ARTIFICIAL((rangetype),1) | |
17205 | #define TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED(arraytype) \ | |
17206 | - (TYPE_FIELD_ARTIFICIAL(TYPE_INDEX_TYPE((arraytype)),0)) | |
17207 | - | |
17208 | -#define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \ | |
17209 | - (TYPE_HIGH_BOUND(TYPE_INDEX_TYPE((arraytype)))) | |
17210 | + TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED (TYPE_INDEX_TYPE (arraytype)) | |
17211 | +#define TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED(arraytype) \ | |
17212 | + TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (TYPE_INDEX_TYPE (arraytype)) | |
17213 | ||
17214 | #define TYPE_ARRAY_LOWER_BOUND_VALUE(arraytype) \ | |
17215 | - (TYPE_LOW_BOUND(TYPE_INDEX_TYPE((arraytype)))) | |
17216 | + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (arraytype)) | |
17217 | +#define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \ | |
17218 | + TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (arraytype)) | |
17219 | +/* TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)) with a fallback to the | |
17220 | + element size if no specific stride value is known. */ | |
17221 | +#define TYPE_ARRAY_BYTE_STRIDE_VALUE(arraytype) \ | |
17222 | + (TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)) == 0 \ | |
17223 | + ? TYPE_LENGTH (TYPE_TARGET_TYPE (arraytype)) \ | |
17224 | + : TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype))) | |
17225 | ||
17226 | /* C++ */ | |
17227 | ||
17228 | @@ -1078,6 +1156,16 @@ extern struct type *builtin_type_error; | |
17229 | (TYPE_UNSIGNED(t) ? UMIN_OF_SIZE(TYPE_LENGTH(t)) \ | |
17230 | : MIN_OF_SIZE(TYPE_LENGTH(t))) | |
17231 | ||
17232 | +/* Virtual OBJFILE used for builtin types. */ | |
17233 | +#define OBJFILE_INTERNAL ((struct objfile *) 1L) | |
17234 | + | |
17235 | +/* Virtual OBJFILE used for types allocated by malloc. FIXME: Currently | |
17236 | + backward compatible with the old NULL value; fix then also init_type. */ | |
17237 | +#define OBJFILE_MALLOC ((struct objfile *) 0L) | |
17238 | + | |
17239 | +#define OBJFILE_IS_VIRTUAL(objfile) ((objfile) == OBJFILE_INTERNAL \ | |
17240 | + || (objfile) == OBJFILE_MALLOC) | |
17241 | + | |
17242 | /* Allocate space for storing data associated with a particular type. | |
17243 | We ensure that the space is allocated using the same mechanism that | |
17244 | was used to allocate the space for the type structure itself. I.E. | |
17245 | @@ -1087,18 +1175,18 @@ extern struct type *builtin_type_error; | |
17246 | builtin types), then the data space will be allocated with xmalloc, | |
17247 | the same as for the type structure. */ | |
17248 | ||
17249 | -#define TYPE_ALLOC(t,size) \ | |
17250 | - (TYPE_OBJFILE (t) != NULL \ | |
17251 | - ? obstack_alloc (&TYPE_OBJFILE (t) -> objfile_obstack, size) \ | |
17252 | - : xmalloc (size)) | |
17253 | +#define TYPE_ALLOC(t,size) \ | |
17254 | + (OBJFILE_IS_VIRTUAL (TYPE_OBJFILE (t)) \ | |
17255 | + ? xmalloc (size) \ | |
17256 | + : obstack_alloc (&TYPE_OBJFILE (t) -> objfile_obstack, size)) | |
17257 | ||
17258 | -#define TYPE_ZALLOC(t,size) \ | |
17259 | - (TYPE_OBJFILE (t) != NULL \ | |
17260 | - ? memset (obstack_alloc (&TYPE_OBJFILE (t)->objfile_obstack, size), \ | |
17261 | - 0, size) \ | |
17262 | - : xzalloc (size)) | |
17263 | +#define TYPE_ZALLOC(t,size) \ | |
17264 | + (OBJFILE_IS_VIRTUAL (TYPE_OBJFILE (t)) \ | |
17265 | + ? xzalloc (size) \ | |
17266 | + : memset (obstack_alloc (&TYPE_OBJFILE (t)->objfile_obstack, size), \ | |
17267 | + 0, size)) | |
17268 | ||
17269 | -extern struct type *alloc_type (struct objfile *); | |
17270 | +extern struct type *alloc_type (struct objfile *, struct type *); | |
17271 | ||
17272 | extern struct type *init_type (enum type_code, int, int, char *, | |
17273 | struct objfile *); | |
17274 | @@ -1172,6 +1260,18 @@ extern struct type *create_range_type (struct type *, struct type *, int, | |
17275 | extern struct type *create_array_type (struct type *, struct type *, | |
17276 | struct type *); | |
17277 | ||
17278 | +extern CORE_ADDR type_range_any_field_internal (struct type *range_type, | |
17279 | + int fieldno); | |
17280 | + | |
17281 | +extern int type_range_high_bound_internal (struct type *range_type); | |
17282 | + | |
17283 | +extern int type_range_count_bound_internal (struct type *range_type); | |
17284 | + | |
17285 | +extern CORE_ADDR type_range_byte_stride_internal (struct type *range_type, | |
17286 | + struct type *element_type); | |
17287 | + | |
17288 | +extern void finalize_type (struct type *type); | |
17289 | + | |
17290 | extern struct type *create_string_type (struct type *, struct type *); | |
17291 | ||
17292 | extern struct type *create_set_type (struct type *, struct type *); | |
17293 | @@ -1263,10 +1363,15 @@ extern void maintenance_print_type (char *, int); | |
17294 | ||
17295 | extern htab_t create_copied_types_hash (struct objfile *objfile); | |
17296 | ||
17297 | -extern struct type *copy_type_recursive (struct objfile *objfile, | |
17298 | - struct type *type, | |
17299 | +extern struct type *copy_type_recursive (struct type *type, | |
17300 | htab_t copied_types); | |
17301 | ||
17302 | extern struct type *copy_type (const struct type *type); | |
17303 | ||
17304 | +extern void type_incref (struct type *type); | |
17305 | + | |
17306 | +extern void type_decref (struct type *type); | |
17307 | + | |
17308 | +extern void free_all_types (void); | |
17309 | + | |
17310 | #endif /* GDBTYPES_H */ | |
17311 | diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c | |
17312 | index 7cacac1..a456228 100644 | |
17313 | --- a/gdb/gnu-v2-abi.c | |
17314 | +++ b/gdb/gnu-v2-abi.c | |
17315 | @@ -242,7 +242,7 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) | |
17316 | we'd waste a bunch of time figuring out we already know the type. | |
17317 | Besides, we don't care about the type, just the actual pointer | |
17318 | */ | |
17319 | - if (VALUE_ADDRESS (value_field (v, known_type_vptr_fieldno)) == 0) | |
17320 | + if (value_address (value_field (v, known_type_vptr_fieldno)) == 0) | |
17321 | return NULL; | |
17322 | ||
17323 | vtbl = value_as_address (value_field (v, known_type_vptr_fieldno)); | |
17324 | diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c | |
17325 | index 3a52df3..6cdf716 100644 | |
17326 | --- a/gdb/gnu-v3-abi.c | |
17327 | +++ b/gdb/gnu-v3-abi.c | |
17328 | @@ -269,8 +269,7 @@ gnuv3_rtti_type (struct value *value, | |
17329 | ||
17330 | /* Find the linker symbol for this vtable. */ | |
17331 | vtable_symbol | |
17332 | - = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtable) | |
17333 | - + value_offset (vtable) | |
17334 | + = lookup_minimal_symbol_by_pc (value_address (vtable) | |
17335 | + value_embedded_offset (vtable)); | |
17336 | if (! vtable_symbol) | |
17337 | return NULL; | |
17338 | @@ -487,10 +486,8 @@ gnuv3_find_method_in (struct type *domain, CORE_ADDR voffset, | |
17339 | LONGEST adjustment) | |
17340 | { | |
17341 | int i; | |
17342 | - const char *physname; | |
17343 | ||
17344 | /* Search this class first. */ | |
17345 | - physname = NULL; | |
17346 | if (adjustment == 0) | |
17347 | { | |
17348 | int len; | |
17349 | @@ -615,13 +612,15 @@ gnuv3_print_method_ptr (const gdb_byte *contents, | |
17350 | { | |
17351 | char *demangled_name = cplus_demangle (physname, | |
17352 | DMGL_ANSI | DMGL_PARAMS); | |
17353 | - if (demangled_name != NULL) | |
17354 | + fprintf_filtered (stream, "&virtual "); | |
17355 | + if (demangled_name == NULL) | |
17356 | + fputs_filtered (physname, stream); | |
17357 | + else | |
17358 | { | |
17359 | - fprintf_filtered (stream, "&virtual "); | |
17360 | fputs_filtered (demangled_name, stream); | |
17361 | xfree (demangled_name); | |
17362 | - return; | |
17363 | } | |
17364 | + return; | |
17365 | } | |
17366 | } | |
17367 | ||
17368 | diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c | |
17369 | index 2366474..f83de32 100644 | |
17370 | --- a/gdb/i386-linux-nat.c | |
17371 | +++ b/gdb/i386-linux-nat.c | |
17372 | @@ -751,7 +751,13 @@ i386_linux_resume (struct target_ops *ops, | |
17373 | { | |
17374 | int pid = PIDGET (ptid); | |
17375 | ||
17376 | - int request = PTRACE_CONT; | |
17377 | + int request; | |
17378 | + | |
17379 | + if (target_passed_by_entrypoint () > 0 | |
17380 | + && catch_syscall_enabled () > 0) | |
17381 | + request = PTRACE_SYSCALL; | |
17382 | + else | |
17383 | + request = PTRACE_CONT; | |
17384 | ||
17385 | if (step) | |
17386 | { | |
17387 | diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c | |
17388 | index 1a2e4f0..973eced 100644 | |
17389 | --- a/gdb/i386-linux-tdep.c | |
17390 | +++ b/gdb/i386-linux-tdep.c | |
17391 | @@ -37,6 +37,10 @@ | |
17392 | #include "symtab.h" | |
17393 | #include "arch-utils.h" | |
17394 | #include "regset.h" | |
17395 | +#include "linux-tdep.h" | |
17396 | + | |
17397 | +/* The syscall's XML filename for i386. */ | |
17398 | +#define XML_SYSCALL_FILENAME_I386 "syscalls/i386-linux.xml" | |
17399 | ||
17400 | /* Supported register note sections. */ | |
17401 | static struct core_regset_section i386_linux_regset_sections[] = | |
17402 | @@ -349,6 +353,26 @@ i386_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) | |
17403 | } | |
17404 | \f | |
17405 | ||
17406 | +static LONGEST | |
17407 | +i386_linux_get_syscall_number (struct gdbarch *gdbarch, | |
17408 | + ptid_t ptid) | |
17409 | +{ | |
17410 | + struct regcache *regcache = get_thread_regcache (ptid); | |
17411 | + /* The content of a register. */ | |
17412 | + gdb_byte buf[4]; | |
17413 | + /* The result. */ | |
17414 | + LONGEST ret; | |
17415 | + | |
17416 | + /* Getting the system call number from the register. | |
17417 | + When dealing with x86 architecture, this information | |
17418 | + is stored at %eax register. */ | |
17419 | + regcache_cooked_read (regcache, I386_LINUX_ORIG_EAX_REGNUM, buf); | |
17420 | + | |
17421 | + ret = extract_signed_integer (buf, 4); | |
17422 | + | |
17423 | + return ret; | |
17424 | +} | |
17425 | + | |
17426 | /* The register sets used in GNU/Linux ELF core-dumps are identical to | |
17427 | the register sets in `struct user' that are used for a.out | |
17428 | core-dumps. These are also used by ptrace(2). The corresponding | |
17429 | @@ -419,6 +443,9 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) | |
17430 | { | |
17431 | struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | |
17432 | ||
17433 | + /* Initializing common functions. */ | |
17434 | + linux_tdep_init (gdbarch); | |
17435 | + | |
17436 | /* GNU/Linux uses ELF. */ | |
17437 | i386_elf_init_abi (info, gdbarch); | |
17438 | ||
17439 | @@ -472,6 +499,11 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) | |
17440 | displaced_step_at_entry_point); | |
17441 | ||
17442 | set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type); | |
17443 | + | |
17444 | + /* Functions for 'catch syscall'. */ | |
17445 | + set_gdbarch_xml_syscall_filename (gdbarch, XML_SYSCALL_FILENAME_I386); | |
17446 | + set_gdbarch_get_syscall_number (gdbarch, | |
17447 | + i386_linux_get_syscall_number); | |
17448 | } | |
17449 | ||
17450 | /* Provide a prototype to silence -Wmissing-prototypes. */ | |
17451 | diff --git a/gdb/inf-child.c b/gdb/inf-child.c | |
17452 | index 38311f1..fc968cf 100644 | |
17453 | --- a/gdb/inf-child.c | |
17454 | +++ b/gdb/inf-child.c | |
17455 | @@ -148,6 +148,15 @@ inf_child_remove_exec_catchpoint (int pid) | |
17456 | } | |
17457 | ||
17458 | static int | |
17459 | +inf_child_set_syscall_catchpoint (int pid, int needed, int any_count, | |
17460 | + int table_size, int *table) | |
17461 | +{ | |
17462 | + /* This version of Unix doesn't support notification of syscall | |
17463 | + events. */ | |
17464 | + return 0; | |
17465 | +} | |
17466 | + | |
17467 | +static int | |
17468 | inf_child_can_run (void) | |
17469 | { | |
17470 | return 1; | |
17471 | @@ -190,6 +199,7 @@ inf_child_target (void) | |
17472 | t->to_follow_fork = inf_child_follow_fork; | |
17473 | t->to_insert_exec_catchpoint = inf_child_insert_exec_catchpoint; | |
17474 | t->to_remove_exec_catchpoint = inf_child_remove_exec_catchpoint; | |
17475 | + t->to_set_syscall_catchpoint = inf_child_set_syscall_catchpoint; | |
17476 | t->to_can_run = inf_child_can_run; | |
17477 | t->to_pid_to_exec_file = inf_child_pid_to_exec_file; | |
17478 | t->to_stratum = process_stratum; | |
17479 | diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c | |
17480 | index f40b6b7..ff429c4 100644 | |
17481 | --- a/gdb/inf-ptrace.c | |
17482 | +++ b/gdb/inf-ptrace.c | |
17483 | @@ -356,13 +356,19 @@ inf_ptrace_resume (struct target_ops *ops, | |
17484 | ptid_t ptid, int step, enum target_signal signal) | |
17485 | { | |
17486 | pid_t pid = ptid_get_pid (ptid); | |
17487 | - int request = PT_CONTINUE; | |
17488 | + int request; | |
17489 | ||
17490 | if (pid == -1) | |
17491 | /* Resume all threads. Traditionally ptrace() only supports | |
17492 | single-threaded processes, so simply resume the inferior. */ | |
17493 | pid = ptid_get_pid (inferior_ptid); | |
17494 | ||
17495 | + if (target_passed_by_entrypoint () > 0 | |
17496 | + && catch_syscall_enabled () > 0) | |
17497 | + request = PT_SYSCALL; | |
17498 | + else | |
17499 | + request = PT_CONTINUE; | |
17500 | + | |
17501 | if (step) | |
17502 | { | |
17503 | /* If this system does not support PT_STEP, a higher level | |
17504 | diff --git a/gdb/infcall.c b/gdb/infcall.c | |
17505 | index d6da8b2..80168b3 100644 | |
17506 | --- a/gdb/infcall.c | |
17507 | +++ b/gdb/infcall.c | |
17508 | @@ -98,6 +98,28 @@ Unwinding of stack if a signal is received while in a call dummy is %s.\n"), | |
17509 | value); | |
17510 | } | |
17511 | ||
17512 | +/* This boolean tells what gdb should do if a std::terminate call is | |
17513 | + made while in a function called from gdb (call dummy). | |
17514 | + As the confines of a single dummy stack prohibit out-of-frame | |
17515 | + handlers from handling a raised exception, and as out-of-frame | |
17516 | + handlers are common in C++, this can lead to no handler being found | |
17517 | + by the unwinder, and a std::terminate call. This is a false positive. | |
17518 | + If set, gdb unwinds the stack and restores the context to what it | |
17519 | + was before the call. | |
17520 | + | |
17521 | + The default is to unwind the frame if a std::terminate call is made.. */ | |
17522 | + | |
17523 | +static int unwind_on_terminating_exception_p = 1; | |
17524 | +static void | |
17525 | +show_unwind_on_terminating_exception_p (struct ui_file *file, int from_tty, | |
17526 | + struct cmd_list_element *c, | |
17527 | + const char *value) | |
17528 | + | |
17529 | +{ | |
17530 | + fprintf_filtered (file, _("\ | |
17531 | +Unwind stack if a C++ exception is unhandled while in a call dummy is %s.\n"), | |
17532 | + value); | |
17533 | +} | |
17534 | ||
17535 | /* Perform the standard coercions that are specified | |
17536 | for arguments to be passed to C or Ada functions. | |
17537 | @@ -217,7 +239,7 @@ find_function_addr (struct value *function, struct type **retval_type) | |
17538 | /* Determine address to call. */ | |
17539 | if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD) | |
17540 | { | |
17541 | - funaddr = VALUE_ADDRESS (function); | |
17542 | + funaddr = value_address (function); | |
17543 | value_type = TYPE_TARGET_TYPE (ftype); | |
17544 | } | |
17545 | else if (code == TYPE_CODE_PTR) | |
17546 | @@ -419,6 +441,8 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) | |
17547 | struct cleanup *args_cleanup; | |
17548 | struct frame_info *frame; | |
17549 | struct gdbarch *gdbarch; | |
17550 | + struct breakpoint *terminate_bp = 0; | |
17551 | + struct minimal_symbol *tm; | |
17552 | ptid_t call_thread_ptid; | |
17553 | struct gdb_exception e; | |
17554 | const char *name; | |
17555 | @@ -718,6 +742,29 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) | |
17556 | bpt = set_momentary_breakpoint (sal, dummy_id, bp_call_dummy); | |
17557 | bpt->disposition = disp_del; | |
17558 | } | |
17559 | + | |
17560 | + /* Create a breakpoint in std::terminate. | |
17561 | + If a C++ exception is raised in the dummy-frame, and the | |
17562 | + exception handler is (normally, and expected to be) out-of-frame, | |
17563 | + the default C++ handler will (wrongly) be called in an inferior | |
17564 | + function call. This is wrong, as an exception can be normally | |
17565 | + and legally handled out-of-frame. The confines of the dummy frame | |
17566 | + prevent the unwinder from finding the correct handler (or any | |
17567 | + handler, unless it is in-frame). The default handler calls | |
17568 | + std::terminate. This will kill the inferior. Assert that | |
17569 | + terminate should never be called in an inferior function | |
17570 | + call. Place a momentary breakpoint in the std::terminate function | |
17571 | + and if triggered in the call, rewind */ | |
17572 | + if (unwind_on_terminating_exception_p) | |
17573 | + { | |
17574 | + tm = lookup_minimal_symbol ("std::terminate()", NULL, NULL); | |
17575 | + if (tm != NULL) | |
17576 | + { | |
17577 | + terminate_bp = set_momentary_breakpoint_at_pc | |
17578 | + (SYMBOL_VALUE_ADDRESS (tm), bp_breakpoint); | |
17579 | + make_cleanup_delete_breakpoint (terminate_bp); | |
17580 | + } | |
17581 | + } | |
17582 | ||
17583 | /* Everything's ready, push all the info needed to restore the | |
17584 | caller (and identify the dummy-frame) onto the dummy-frame | |
17585 | @@ -828,6 +875,16 @@ When the function is done executing, GDB will silently stop."), | |
17586 | name); | |
17587 | } | |
17588 | ||
17589 | + if (! target_has_execution) | |
17590 | + { | |
17591 | + /* If we try to restore the inferior status (via the cleanup), | |
17592 | + we'll crash as the inferior is no longer running. */ | |
17593 | + discard_cleanups (inf_status_cleanup); | |
17594 | + discard_inferior_status (inf_status); | |
17595 | + error (_("\ | |
17596 | +The program being debugged exited while in a function called from GDB.")); | |
17597 | + } | |
17598 | + | |
17599 | if (stopped_by_random_signal || !stop_stack_dummy) | |
17600 | { | |
17601 | const char *name = get_function_name (funaddr, | |
17602 | @@ -884,6 +941,38 @@ When the function is done executing, GDB will silently stop."), | |
17603 | ||
17604 | if (!stop_stack_dummy) | |
17605 | { | |
17606 | + | |
17607 | + /* Check if unwind on terminating exception behaviour is on */ | |
17608 | + if (unwind_on_terminating_exception_p) | |
17609 | + { | |
17610 | + /* Check that the breakpoint is our special std::terminate | |
17611 | + breakpoint. If it is, we do not want to kill the inferior | |
17612 | + in an inferior function call. Rewind, and warn the user */ | |
17613 | + | |
17614 | + if ((terminate_bp != NULL) && | |
17615 | + (inferior_thread()->stop_bpstat->breakpoint_at->address | |
17616 | + == terminate_bp->loc->address)) | |
17617 | + | |
17618 | + | |
17619 | + { | |
17620 | + | |
17621 | + /* We must get back to the frame we were before the | |
17622 | + dummy call. */ | |
17623 | + dummy_frame_pop (dummy_id); | |
17624 | + | |
17625 | + /* We also need to restore inferior status to that before the | |
17626 | + dummy call. */ | |
17627 | + restore_inferior_status (inf_status); | |
17628 | + | |
17629 | + error (_("\ | |
17630 | +The program being debugged entered a std::terminate call which would\n\ | |
17631 | +have terminated the program being debugged. GDB has restored the\n\ | |
17632 | +context to what it was before the call\n\ | |
17633 | +To change this behaviour use \"set unwind-on-terminating-exception off\"\n\ | |
17634 | +Evaluation of the expression containing the function (%s) will be abandoned."), | |
17635 | + name); | |
17636 | + } | |
17637 | + } | |
17638 | /* We hit a breakpoint inside the FUNCTION. | |
17639 | Keep the dummy frame, the user may want to examine its state. | |
17640 | Discard inferior status, we're not at the same point | |
17641 | @@ -992,4 +1081,19 @@ The default is to stop in the frame where the signal was received."), | |
17642 | NULL, | |
17643 | show_unwind_on_signal_p, | |
17644 | &setlist, &showlist); | |
17645 | + | |
17646 | + add_setshow_boolean_cmd ("unwind-on-terminating-exception", no_class, | |
17647 | + &unwind_on_terminating_exception_p, _("\ | |
17648 | +Set unwinding of stack if a std::terminate() call originates from\n\ | |
17649 | +the default C++ exception handler."), _("\ | |
17650 | +Show unwinding of stack if a std::terminate() call originates from\n\ | |
17651 | +the default C++ exception handler."), _("\ | |
17652 | +The unwind on terminating exception flag lets the user determine\n\ | |
17653 | +what gdb should do if a std::terminate() call is made from the\n\ | |
17654 | +default exception handler.\n\ | |
17655 | +The default is to unwind the frame."), | |
17656 | + NULL, | |
17657 | + show_unwind_on_terminating_exception_p, | |
17658 | + &setlist, &showlist); | |
17659 | + | |
17660 | } | |
17661 | diff --git a/gdb/infcmd.c b/gdb/infcmd.c | |
17662 | index 0a17dab..d48f4b1 100644 | |
17663 | --- a/gdb/infcmd.c | |
17664 | +++ b/gdb/infcmd.c | |
17665 | @@ -466,6 +466,11 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) | |
17666 | init_wait_for_inferior (); | |
17667 | clear_breakpoint_hit_counts (); | |
17668 | ||
17669 | + /* If we already caught a syscall catchpoint, then reset its | |
17670 | + syscall_number information because we are starting all over | |
17671 | + again. */ | |
17672 | + clear_syscall_catchpoints_info (); | |
17673 | + | |
17674 | /* Clean up any leftovers from other runs. Some other things from | |
17675 | this function should probably be moved into target_pre_inferior. */ | |
17676 | target_pre_inferior (from_tty); | |
17677 | diff --git a/gdb/infrun.c b/gdb/infrun.c | |
17678 | index ee5f987..2f627ea 100644 | |
17679 | --- a/gdb/infrun.c | |
17680 | +++ b/gdb/infrun.c | |
17681 | @@ -1046,7 +1046,7 @@ a command like `return' or `jump' to continue execution.")); | |
17682 | } | |
17683 | } | |
17684 | ||
17685 | - /* If there were any forks/vforks/execs that were caught and are | |
17686 | + /* If there were any forks/vforks/execs/syscalls that were caught and are | |
17687 | now to be followed, then do so. */ | |
17688 | switch (pending_follow.kind) | |
17689 | { | |
17690 | @@ -1069,6 +1069,11 @@ a command like `return' or `jump' to continue execution.")); | |
17691 | pending_follow.kind = TARGET_WAITKIND_SPURIOUS; | |
17692 | break; | |
17693 | ||
17694 | + case TARGET_WAITKIND_SYSCALL_ENTRY: | |
17695 | + case TARGET_WAITKIND_SYSCALL_RETURN: | |
17696 | + pending_follow.kind = TARGET_WAITKIND_SPURIOUS; | |
17697 | + break; | |
17698 | + | |
17699 | default: | |
17700 | break; | |
17701 | } | |
17702 | @@ -1509,7 +1514,7 @@ init_wait_for_inferior (void) | |
17703 | ||
17704 | breakpoint_init_inferior (inf_starting); | |
17705 | ||
17706 | - /* The first resume is not following a fork/vfork/exec. */ | |
17707 | + /* The first resume is not following a fork/vfork/exec/syscall. */ | |
17708 | pending_follow.kind = TARGET_WAITKIND_SPURIOUS; /* I.e., none. */ | |
17709 | ||
17710 | clear_proceed_status (); | |
17711 | @@ -2155,6 +2160,50 @@ ensure_not_running (void) | |
17712 | error_is_running (); | |
17713 | } | |
17714 | ||
17715 | +/* Auxiliary function that handles syscall entry/return events. | |
17716 | + It returns 1 if the inferior should keep going (and GDB | |
17717 | + should ignore the event), or 0 if the event deserves to be | |
17718 | + processed. */ | |
17719 | +static int | |
17720 | +deal_with_syscall_event (struct execution_control_state *ecs) | |
17721 | +{ | |
17722 | + int syscall_number = gdbarch_get_syscall_number (current_gdbarch, | |
17723 | + ecs->ptid); | |
17724 | + if (catch_syscall_enabled () > 0 | |
17725 | + && catching_syscall_number (syscall_number) > 0) | |
17726 | + { | |
17727 | + ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP; | |
17728 | + pending_follow.kind = ecs->ws.kind; | |
17729 | + | |
17730 | + if (!ptid_equal (ecs->ptid, inferior_ptid)) | |
17731 | + { | |
17732 | + context_switch (ecs->ptid); | |
17733 | + reinit_frame_cache (); | |
17734 | + } | |
17735 | + | |
17736 | + stop_pc = read_pc (); | |
17737 | + | |
17738 | + ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid); | |
17739 | + | |
17740 | + ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat); | |
17741 | + | |
17742 | + /* If no catchpoint triggered for this, then keep going. */ | |
17743 | + if (ecs->random_signal) | |
17744 | + { | |
17745 | + ecs->event_thread->stop_signal = TARGET_SIGNAL_0; | |
17746 | + keep_going (ecs); | |
17747 | + return 1; | |
17748 | + } | |
17749 | + return 0; | |
17750 | + } | |
17751 | + else | |
17752 | + { | |
17753 | + resume (0, TARGET_SIGNAL_0); | |
17754 | + prepare_to_wait (ecs); | |
17755 | + return 1; | |
17756 | + } | |
17757 | +} | |
17758 | + | |
17759 | /* Given an execution control state that has been freshly filled in | |
17760 | by an event from the inferior, figure out what it means and take | |
17761 | appropriate action. */ | |
17762 | @@ -2449,9 +2498,11 @@ handle_inferior_event (struct execution_control_state *ecs) | |
17763 | case TARGET_WAITKIND_SYSCALL_ENTRY: | |
17764 | if (debug_infrun) | |
17765 | fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SYSCALL_ENTRY\n"); | |
17766 | - resume (0, TARGET_SIGNAL_0); | |
17767 | - prepare_to_wait (ecs); | |
17768 | - return; | |
17769 | + /* Getting the current syscall number */ | |
17770 | + if (deal_with_syscall_event (ecs) != 0) | |
17771 | + return; | |
17772 | + goto process_event_stop_test; | |
17773 | + break; | |
17774 | ||
17775 | /* Before examining the threads further, step this thread to | |
17776 | get it entirely out of the syscall. (We get notice of the | |
17777 | @@ -2461,9 +2512,10 @@ handle_inferior_event (struct execution_control_state *ecs) | |
17778 | case TARGET_WAITKIND_SYSCALL_RETURN: | |
17779 | if (debug_infrun) | |
17780 | fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SYSCALL_RETURN\n"); | |
17781 | - target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); | |
17782 | - prepare_to_wait (ecs); | |
17783 | - return; | |
17784 | + if (deal_with_syscall_event (ecs) != 0) | |
17785 | + return; | |
17786 | + goto process_event_stop_test; | |
17787 | + break; | |
17788 | ||
17789 | case TARGET_WAITKIND_STOPPED: | |
17790 | if (debug_infrun) | |
17791 | @@ -5166,6 +5218,25 @@ inferior_has_execd (ptid_t pid, char **execd_pathname) | |
17792 | return 1; | |
17793 | } | |
17794 | ||
17795 | +int | |
17796 | +inferior_has_called_syscall (ptid_t pid, int *syscall_number) | |
17797 | +{ | |
17798 | + struct target_waitstatus last; | |
17799 | + ptid_t last_ptid; | |
17800 | + | |
17801 | + get_last_target_status (&last_ptid, &last); | |
17802 | + | |
17803 | + if (last.kind != TARGET_WAITKIND_SYSCALL_ENTRY && | |
17804 | + last.kind != TARGET_WAITKIND_SYSCALL_RETURN) | |
17805 | + return 0; | |
17806 | + | |
17807 | + if (!ptid_equal (last_ptid, pid)) | |
17808 | + return 0; | |
17809 | + | |
17810 | + *syscall_number = last.value.syscall_number; | |
17811 | + return 1; | |
17812 | +} | |
17813 | + | |
17814 | /* Oft used ptids */ | |
17815 | ptid_t null_ptid; | |
17816 | ptid_t minus_one_ptid; | |
17817 | diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c | |
17818 | index b702ebf..a211adf 100644 | |
17819 | --- a/gdb/jv-lang.c | |
17820 | +++ b/gdb/jv-lang.c | |
17821 | @@ -61,7 +61,8 @@ static char *get_java_utf8_name (struct obstack *obstack, struct value *name); | |
17822 | static int java_class_is_primitive (struct value *clas); | |
17823 | static struct value *java_value_string (char *ptr, int len); | |
17824 | ||
17825 | -static void java_emit_char (int c, struct ui_file * stream, int quoter); | |
17826 | +static void java_emit_char (int c, struct type *type, | |
17827 | + struct ui_file * stream, int quoter); | |
17828 | ||
17829 | static char *java_class_name_from_physname (const char *physname); | |
17830 | ||
17831 | @@ -210,8 +211,7 @@ get_java_utf8_name (struct obstack *obstack, struct value *name) | |
17832 | CORE_ADDR data_addr; | |
17833 | temp = value_struct_elt (&temp, NULL, "length", NULL, "structure"); | |
17834 | name_length = (int) value_as_long (temp); | |
17835 | - data_addr = VALUE_ADDRESS (temp) + value_offset (temp) | |
17836 | - + TYPE_LENGTH (value_type (temp)); | |
17837 | + data_addr = value_address (temp) + TYPE_LENGTH (value_type (temp)); | |
17838 | chrs = obstack_alloc (obstack, name_length + 1); | |
17839 | chrs[name_length] = '\0'; | |
17840 | read_memory (data_addr, (gdb_byte *) chrs, name_length); | |
17841 | @@ -266,7 +266,7 @@ type_from_class (struct value *clas) | |
17842 | return NULL; | |
17843 | clas = value_ind (clas); | |
17844 | } | |
17845 | - addr = VALUE_ADDRESS (clas) + value_offset (clas); | |
17846 | + addr = value_address (clas); | |
17847 | ||
17848 | #if 0 | |
17849 | get_java_class_symtab (); | |
17850 | @@ -302,7 +302,7 @@ type_from_class (struct value *clas) | |
17851 | if (type != NULL) | |
17852 | return type; | |
17853 | ||
17854 | - type = alloc_type (objfile); | |
17855 | + type = alloc_type (objfile, NULL); | |
17856 | TYPE_CODE (type) = TYPE_CODE_STRUCT; | |
17857 | INIT_CPLUS_SPECIFIC (type); | |
17858 | ||
17859 | @@ -422,7 +422,7 @@ java_link_class_type (struct type *type, struct value *clas) | |
17860 | fields = NULL; | |
17861 | nfields--; /* First set up dummy "class" field. */ | |
17862 | SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields), | |
17863 | - VALUE_ADDRESS (clas) + value_offset (clas)); | |
17864 | + value_address (clas)); | |
17865 | TYPE_FIELD_NAME (type, nfields) = "class"; | |
17866 | TYPE_FIELD_TYPE (type, nfields) = value_type (clas); | |
17867 | SET_TYPE_FIELD_PRIVATE (type, nfields); | |
17868 | @@ -439,7 +439,9 @@ java_link_class_type (struct type *type, struct value *clas) | |
17869 | } | |
17870 | else | |
17871 | { /* Re-use field value for next field. */ | |
17872 | - VALUE_ADDRESS (field) += TYPE_LENGTH (value_type (field)); | |
17873 | + CORE_ADDR addr | |
17874 | + = value_address (field) + TYPE_LENGTH (value_type (field)); | |
17875 | + set_value_address (field, addr); | |
17876 | set_value_lazy (field, 1); | |
17877 | } | |
17878 | temp = field; | |
17879 | @@ -509,7 +511,9 @@ java_link_class_type (struct type *type, struct value *clas) | |
17880 | } | |
17881 | else | |
17882 | { /* Re-use method value for next method. */ | |
17883 | - VALUE_ADDRESS (method) += TYPE_LENGTH (value_type (method)); | |
17884 | + CORE_ADDR addr | |
17885 | + = value_address (method) + TYPE_LENGTH (value_type (method)); | |
17886 | + set_value_address (method, addr); | |
17887 | set_value_lazy (method, 1); | |
17888 | } | |
17889 | ||
17890 | @@ -796,7 +800,7 @@ java_value_string (char *ptr, int len) | |
17891 | characters and strings is language specific. */ | |
17892 | ||
17893 | static void | |
17894 | -java_emit_char (int c, struct ui_file *stream, int quoter) | |
17895 | +java_emit_char (int c, struct type *type, struct ui_file *stream, int quoter) | |
17896 | { | |
17897 | switch (c) | |
17898 | { | |
17899 | diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c | |
17900 | index d3606fd..cdcb440 100644 | |
17901 | --- a/gdb/jv-valprint.c | |
17902 | +++ b/gdb/jv-valprint.c | |
17903 | @@ -45,7 +45,7 @@ java_value_print (struct value *val, struct ui_file *stream, | |
17904 | struct value_print_options opts; | |
17905 | ||
17906 | type = value_type (val); | |
17907 | - address = VALUE_ADDRESS (val) + value_offset (val); | |
17908 | + address = value_address (val); | |
17909 | ||
17910 | if (is_object_type (type)) | |
17911 | { | |
17912 | @@ -143,8 +143,8 @@ java_value_print (struct value *val, struct ui_file *stream, | |
17913 | struct value *v = allocate_value (el_type); | |
17914 | struct value *next_v = allocate_value (el_type); | |
17915 | ||
17916 | - VALUE_ADDRESS (v) = address + JAVA_OBJECT_SIZE + 4; | |
17917 | - VALUE_ADDRESS (next_v) = VALUE_ADDRESS (v); | |
17918 | + set_value_address (v, address + JAVA_OBJECT_SIZE + 4); | |
17919 | + set_value_address (next_v, value_raw_address (v)); | |
17920 | ||
17921 | while (i < length && things_printed < options->print_max) | |
17922 | { | |
17923 | @@ -230,7 +230,7 @@ java_value_print (struct value *val, struct ui_file *stream, | |
17924 | ||
17925 | value_free_to_mark (mark); /* Release unnecessary values */ | |
17926 | ||
17927 | - val_print_string (data + boffset, count, 2, stream, options); | |
17928 | + val_print_string (java_char_type, data + boffset, count, stream, options); | |
17929 | ||
17930 | return 0; | |
17931 | } | |
17932 | @@ -520,7 +520,7 @@ java_val_print (struct type *type, const gdb_byte *valaddr, | |
17933 | || (TYPE_CODE (type) == TYPE_CODE_INT | |
17934 | && TYPE_LENGTH (type) == 2 | |
17935 | && strcmp (TYPE_NAME (type), "char") == 0)) | |
17936 | - LA_PRINT_CHAR ((int) unpack_long (type, valaddr), stream); | |
17937 | + LA_PRINT_CHAR ((int) unpack_long (type, valaddr), type, stream); | |
17938 | else | |
17939 | val_print_type_code_int (type, valaddr, stream); | |
17940 | break; | |
17941 | diff --git a/gdb/language.c b/gdb/language.c | |
17942 | index 3c37a64..6209d7f 100644 | |
17943 | --- a/gdb/language.c | |
17944 | +++ b/gdb/language.c | |
17945 | @@ -65,9 +65,11 @@ static void set_check (char *, int); | |
17946 | ||
17947 | static void set_type_range_case (void); | |
17948 | ||
17949 | -static void unk_lang_emit_char (int c, struct ui_file *stream, int quoter); | |
17950 | +static void unk_lang_emit_char (int c, struct type *type, | |
17951 | + struct ui_file *stream, int quoter); | |
17952 | ||
17953 | -static void unk_lang_printchar (int c, struct ui_file *stream); | |
17954 | +static void unk_lang_printchar (int c, struct type *type, | |
17955 | + struct ui_file *stream); | |
17956 | ||
17957 | static void unk_lang_print_type (struct type *, char *, struct ui_file *, | |
17958 | int, int); | |
17959 | @@ -1065,20 +1067,22 @@ unk_lang_error (char *msg) | |
17960 | } | |
17961 | ||
17962 | static void | |
17963 | -unk_lang_emit_char (int c, struct ui_file *stream, int quoter) | |
17964 | +unk_lang_emit_char (int c, struct type *type, struct ui_file *stream, | |
17965 | + int quoter) | |
17966 | { | |
17967 | error (_("internal error - unimplemented function unk_lang_emit_char called.")); | |
17968 | } | |
17969 | ||
17970 | static void | |
17971 | -unk_lang_printchar (int c, struct ui_file *stream) | |
17972 | +unk_lang_printchar (int c, struct type *type, struct ui_file *stream) | |
17973 | { | |
17974 | error (_("internal error - unimplemented function unk_lang_printchar called.")); | |
17975 | } | |
17976 | ||
17977 | static void | |
17978 | -unk_lang_printstr (struct ui_file *stream, const gdb_byte *string, | |
17979 | - unsigned int length, int width, int force_ellipses, | |
17980 | +unk_lang_printstr (struct ui_file *stream, struct type *type, | |
17981 | + const gdb_byte *string, unsigned int length, | |
17982 | + int force_ellipses, | |
17983 | const struct value_print_options *options) | |
17984 | { | |
17985 | error (_("internal error - unimplemented function unk_lang_printstr called.")); | |
17986 | diff --git a/gdb/language.h b/gdb/language.h | |
17987 | index 85826fd..e5f80ab 100644 | |
17988 | --- a/gdb/language.h | |
17989 | +++ b/gdb/language.h | |
17990 | @@ -186,14 +186,15 @@ struct language_defn | |
17991 | ||
17992 | void (*la_post_parser) (struct expression ** expp, int void_context_p); | |
17993 | ||
17994 | - void (*la_printchar) (int ch, struct ui_file * stream); | |
17995 | + void (*la_printchar) (int ch, struct type *chtype, struct ui_file * stream); | |
17996 | ||
17997 | - void (*la_printstr) (struct ui_file * stream, const gdb_byte *string, | |
17998 | - unsigned int length, int width, | |
17999 | + void (*la_printstr) (struct ui_file * stream, struct type *elttype, | |
18000 | + const gdb_byte *string, unsigned int length, | |
18001 | int force_ellipses, | |
18002 | const struct value_print_options *); | |
18003 | ||
18004 | - void (*la_emitchar) (int ch, struct ui_file * stream, int quoter); | |
18005 | + void (*la_emitchar) (int ch, struct type *chtype, | |
18006 | + struct ui_file * stream, int quoter); | |
18007 | ||
18008 | /* Print a type using syntax appropriate for this language. */ | |
18009 | ||
18010 | @@ -381,13 +382,13 @@ extern enum language set_language (enum language); | |
18011 | #define LA_VALUE_PRINT(val,stream,options) \ | |
18012 | (current_language->la_value_print(val,stream,options)) | |
18013 | ||
18014 | -#define LA_PRINT_CHAR(ch, stream) \ | |
18015 | - (current_language->la_printchar(ch, stream)) | |
18016 | -#define LA_PRINT_STRING(stream, string, length, width, force_ellipses,options) \ | |
18017 | - (current_language->la_printstr(stream, string, length, width, \ | |
18018 | +#define LA_PRINT_CHAR(ch, type, stream) \ | |
18019 | + (current_language->la_printchar(ch, type, stream)) | |
18020 | +#define LA_PRINT_STRING(stream, elttype, string, length, force_ellipses,options) \ | |
18021 | + (current_language->la_printstr(stream, elttype, string, length, \ | |
18022 | force_ellipses,options)) | |
18023 | -#define LA_EMIT_CHAR(ch, stream, quoter) \ | |
18024 | - (current_language->la_emitchar(ch, stream, quoter)) | |
18025 | +#define LA_EMIT_CHAR(ch, type, stream, quoter) \ | |
18026 | + (current_language->la_emitchar(ch, type, stream, quoter)) | |
18027 | #define LA_GET_STRING(value, buffer, length, encoding) \ | |
18028 | (current_language->la_get_string(value, buffer, length, encoding)) | |
18029 | ||
18030 | diff --git a/gdb/linespec.c b/gdb/linespec.c | |
18031 | index 6579d42..b3ae6c0 100644 | |
18032 | --- a/gdb/linespec.c | |
18033 | +++ b/gdb/linespec.c | |
18034 | @@ -842,13 +842,33 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, | |
18035 | } | |
18036 | else if (paren_pointer != NULL) | |
18037 | { | |
18038 | - p = paren_pointer + 1; | |
18039 | + /* We need to deal with method and function overloads | |
18040 | + with no parameters. Gdb and gcc (and who knows about other | |
18041 | + compilers) are very inconsistent with the keyword "void". | |
18042 | + Canonicalizing C++ types is insufficient in this case, since | |
18043 | + we still need to enforce the presence (or lack thereof) of | |
18044 | + "void". For simplicity, omit the keyword "void" if present. */ | |
18045 | + if (strncmp (paren_pointer - 5, "(void)", 6) == 0) | |
18046 | + { | |
18047 | + char *a, *b; | |
18048 | + a = paren_pointer - 4; | |
18049 | + b = paren_pointer; | |
18050 | + while ((*(a++) = *(b++)) != '\0') ; | |
18051 | + *a = '\0'; | |
18052 | + p = paren_pointer - 3; | |
18053 | + } | |
18054 | + else | |
18055 | + p = paren_pointer + 1; | |
18056 | } | |
18057 | else | |
18058 | { | |
18059 | p = skip_quoted (*argptr); | |
18060 | } | |
18061 | ||
18062 | + /* Make sure we keep important kewords like "const" */ | |
18063 | + if (strncmp (p, " const", 6) == 0) | |
18064 | + p += 6; | |
18065 | + | |
18066 | copy = (char *) alloca (p - *argptr + 1); | |
18067 | memcpy (copy, *argptr, p - *argptr); | |
18068 | copy[p - *argptr] = '\0'; | |
18069 | diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c | |
18070 | index 12b786e..e30bf9a 100644 | |
18071 | --- a/gdb/linux-nat.c | |
18072 | +++ b/gdb/linux-nat.c | |
18073 | @@ -61,6 +61,10 @@ | |
18074 | # endif | |
18075 | #endif /* HAVE_PERSONALITY */ | |
18076 | ||
18077 | +/* To be used when one needs to know wether a | |
18078 | + WSTOPSIG (status) is a syscall */ | |
18079 | +#define TRAP_IS_SYSCALL (SIGTRAP | 0x80) | |
18080 | + | |
18081 | /* This comment documents high-level logic of this file. | |
18082 | ||
18083 | Waiting for events in sync mode | |
18084 | @@ -281,17 +285,29 @@ struct simple_pid_list *stopped_pids; | |
18085 | ||
18086 | static int linux_supports_tracefork_flag = -1; | |
18087 | ||
18088 | +/* This variable is a tri-state flag: -1 for unknown, 0 if PTRACE_O_TRACESYSGOOD | |
18089 | + can not be used, 1 if it can. */ | |
18090 | + | |
18091 | +static int linux_supports_tracesysgood_flag = -1; | |
18092 | + | |
18093 | /* If we have PTRACE_O_TRACEFORK, this flag indicates whether we also have | |
18094 | PTRACE_O_TRACEVFORKDONE. */ | |
18095 | ||
18096 | static int linux_supports_tracevforkdone_flag = -1; | |
18097 | ||
18098 | +/* If the inferior have passed through its entrypoint (AT_ENTRY), | |
18099 | + then this flag is set to 1. Otherwise, its value is 0. */ | |
18100 | +static int linux_passed_by_entrypoint_flag = 0; | |
18101 | + | |
18102 | /* Async mode support */ | |
18103 | ||
18104 | /* Zero if the async mode, although enabled, is masked, which means | |
18105 | linux_nat_wait should behave as if async mode was off. */ | |
18106 | static int linux_nat_async_mask_value = 1; | |
18107 | ||
18108 | +/* Stores the current used ptrace() options. */ | |
18109 | +static int current_ptrace_options = 0; | |
18110 | + | |
18111 | /* The read/write ends of the pipe registered as waitable file in the | |
18112 | event loop. */ | |
18113 | static int linux_nat_event_pipe[2] = { -1, -1 }; | |
18114 | @@ -636,6 +652,41 @@ linux_test_for_tracefork (int original_pid) | |
18115 | linux_nat_async_events (async_events_original_state); | |
18116 | } | |
18117 | ||
18118 | +/* Determine if PTRACE_O_TRACESYSGOOD can be used to follow syscalls. | |
18119 | + | |
18120 | + We try to enable syscall tracing on ORIGINAL_PID. If this fails, | |
18121 | + we know that the feature is not available. This may change the tracing | |
18122 | + options for ORIGINAL_PID, but we'll be setting them shortly anyway. */ | |
18123 | + | |
18124 | +static void | |
18125 | +linux_test_for_tracesysgood (int original_pid) | |
18126 | +{ | |
18127 | + int ret; | |
18128 | + enum sigchld_state async_events_original_state; | |
18129 | + | |
18130 | + async_events_original_state = linux_nat_async_events (sigchld_sync); | |
18131 | + | |
18132 | + linux_supports_tracesysgood_flag = 0; | |
18133 | + | |
18134 | + ret = ptrace (PTRACE_SETOPTIONS, original_pid, 0, PTRACE_O_TRACESYSGOOD); | |
18135 | + if (ret != 0) | |
18136 | + return; | |
18137 | + | |
18138 | + linux_supports_tracesysgood_flag = 1; | |
18139 | + linux_nat_async_events (async_events_original_state); | |
18140 | +} | |
18141 | + | |
18142 | +/* Determine wether we support PTRACE_O_TRACESYSGOOD option available. | |
18143 | + This function also sets linux_supports_tracesysgood_flag. */ | |
18144 | + | |
18145 | +static int | |
18146 | +linux_supports_tracesysgood (int pid) | |
18147 | +{ | |
18148 | + if (linux_supports_tracesysgood_flag == -1) | |
18149 | + linux_test_for_tracesysgood (pid); | |
18150 | + return linux_supports_tracesysgood_flag; | |
18151 | +} | |
18152 | + | |
18153 | /* Return non-zero iff we have tracefork functionality available. | |
18154 | This function also sets linux_supports_tracefork_flag. */ | |
18155 | ||
18156 | @@ -655,12 +706,34 @@ linux_supports_tracevforkdone (int pid) | |
18157 | return linux_supports_tracevforkdone_flag; | |
18158 | } | |
18159 | ||
18160 | +static void | |
18161 | +linux_enable_tracesysgood (ptid_t ptid) | |
18162 | +{ | |
18163 | + int pid = ptid_get_lwp (ptid); | |
18164 | + | |
18165 | + if (pid == 0) | |
18166 | + pid = ptid_get_pid (ptid); | |
18167 | + | |
18168 | + if (linux_supports_tracesysgood (pid) == 0) | |
18169 | + return; | |
18170 | + | |
18171 | + current_ptrace_options |= PTRACE_O_TRACESYSGOOD; | |
18172 | + linux_passed_by_entrypoint_flag = 1; | |
18173 | + | |
18174 | + ptrace (PTRACE_SETOPTIONS, pid, 0, current_ptrace_options); | |
18175 | +} | |
18176 | + | |
18177 | +static int | |
18178 | +linux_passed_by_entrypoint (void) | |
18179 | +{ | |
18180 | + return linux_passed_by_entrypoint_flag; | |
18181 | +} | |
18182 | + | |
18183 | \f | |
18184 | void | |
18185 | linux_enable_event_reporting (ptid_t ptid) | |
18186 | { | |
18187 | int pid = ptid_get_lwp (ptid); | |
18188 | - int options; | |
18189 | ||
18190 | if (pid == 0) | |
18191 | pid = ptid_get_pid (ptid); | |
18192 | @@ -668,15 +741,16 @@ linux_enable_event_reporting (ptid_t ptid) | |
18193 | if (! linux_supports_tracefork (pid)) | |
18194 | return; | |
18195 | ||
18196 | - options = PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXEC | |
18197 | - | PTRACE_O_TRACECLONE; | |
18198 | + current_ptrace_options |= PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | |
18199 | + | PTRACE_O_TRACEEXEC | PTRACE_O_TRACECLONE; | |
18200 | + | |
18201 | if (linux_supports_tracevforkdone (pid)) | |
18202 | - options |= PTRACE_O_TRACEVFORKDONE; | |
18203 | + current_ptrace_options |= PTRACE_O_TRACEVFORKDONE; | |
18204 | ||
18205 | /* Do not enable PTRACE_O_TRACEEXIT until GDB is more prepared to support | |
18206 | read-only process state. */ | |
18207 | ||
18208 | - ptrace (PTRACE_SETOPTIONS, pid, 0, options); | |
18209 | + ptrace (PTRACE_SETOPTIONS, pid, 0, current_ptrace_options); | |
18210 | } | |
18211 | ||
18212 | static void | |
18213 | @@ -684,6 +758,7 @@ linux_child_post_attach (int pid) | |
18214 | { | |
18215 | linux_enable_event_reporting (pid_to_ptid (pid)); | |
18216 | check_for_thread_db (); | |
18217 | + linux_enable_tracesysgood (pid_to_ptid (pid)); | |
18218 | } | |
18219 | ||
18220 | static void | |
18221 | @@ -691,6 +766,7 @@ linux_child_post_startup_inferior (ptid_t ptid) | |
18222 | { | |
18223 | linux_enable_event_reporting (ptid); | |
18224 | check_for_thread_db (); | |
18225 | + linux_enable_tracesysgood (ptid); | |
18226 | } | |
18227 | ||
18228 | static int | |
18229 | @@ -931,6 +1007,16 @@ linux_child_insert_exec_catchpoint (int pid) | |
18230 | error (_("Your system does not support exec catchpoints.")); | |
18231 | } | |
18232 | ||
18233 | +static int | |
18234 | +linux_child_set_syscall_catchpoint (int pid, int needed, int any_count, | |
18235 | + int table_size, int *table) | |
18236 | +{ | |
18237 | + if (! linux_supports_tracesysgood (pid)) | |
18238 | + error (_("Your system does not support syscall catchpoints.")); | |
18239 | + /* We ignore the arguments. */ | |
18240 | + return 0; | |
18241 | +} | |
18242 | + | |
18243 | /* On GNU/Linux there are no real LWP's. The closest thing to LWP's | |
18244 | are processes sharing the same VM space. A multi-threaded process | |
18245 | is basically a group of such processes. However, such a grouping | |
18246 | @@ -1352,6 +1438,9 @@ linux_nat_create_inferior (struct target_ops *ops, | |
18247 | int personality_orig = 0, personality_set = 0; | |
18248 | #endif /* HAVE_PERSONALITY */ | |
18249 | ||
18250 | + /* We are sarting, so we still have not passed through our entrypoint. */ | |
18251 | + linux_passed_by_entrypoint_flag = 0; | |
18252 | + | |
18253 | /* The fork_child mechanism is synchronous and calls target_wait, so | |
18254 | we have to mask the async mode. */ | |
18255 | ||
18256 | @@ -1996,6 +2085,26 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, | |
18257 | return 0; | |
18258 | } | |
18259 | ||
18260 | + /* Used for 'catch syscall' feature. */ | |
18261 | + if (WSTOPSIG (status) == TRAP_IS_SYSCALL) | |
18262 | + { | |
18263 | + if (catch_syscall_enabled () == 0) | |
18264 | + ourstatus->kind = TARGET_WAITKIND_IGNORE; | |
18265 | + else | |
18266 | + { | |
18267 | + struct regcache *regcache = get_thread_regcache (lp->ptid); | |
18268 | + struct gdbarch *gdbarch = get_regcache_arch (regcache); | |
18269 | + | |
18270 | + ourstatus->kind = | |
18271 | + (lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY) ? | |
18272 | + TARGET_WAITKIND_SYSCALL_RETURN : TARGET_WAITKIND_SYSCALL_ENTRY; | |
18273 | + lp->syscall_state = ourstatus->kind; | |
18274 | + ourstatus->value.syscall_number = | |
18275 | + (int) gdbarch_get_syscall_number (gdbarch, lp->ptid); | |
18276 | + } | |
18277 | + return 0; | |
18278 | + } | |
18279 | + | |
18280 | internal_error (__FILE__, __LINE__, | |
18281 | _("unknown ptrace event %d"), event); | |
18282 | } | |
18283 | @@ -2606,11 +2715,16 @@ linux_nat_filter_event (int lwpid, int status, int options) | |
18284 | } | |
18285 | ||
18286 | /* Save the trap's siginfo in case we need it later. */ | |
18287 | - if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP) | |
18288 | + if (WIFSTOPPED (status) | |
18289 | + && (WSTOPSIG (status) == SIGTRAP || WSTOPSIG (status) == TRAP_IS_SYSCALL)) | |
18290 | save_siginfo (lp); | |
18291 | ||
18292 | - /* Handle GNU/Linux's extended waitstatus for trace events. */ | |
18293 | - if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0) | |
18294 | + /* Handle GNU/Linux's extended waitstatus for trace events. | |
18295 | + It is necessary to check if WSTOPSIG is signaling a that | |
18296 | + the inferior is entering/exiting a system call. */ | |
18297 | + if (WIFSTOPPED (status) | |
18298 | + && ((WSTOPSIG (status) == TRAP_IS_SYSCALL) | |
18299 | + || (WSTOPSIG (status) == SIGTRAP && status >> 16 != 0))) | |
18300 | { | |
18301 | if (debug_linux_nat) | |
18302 | fprintf_unfiltered (gdb_stdlog, | |
18303 | @@ -4262,12 +4376,14 @@ linux_target_install_ops (struct target_ops *t) | |
18304 | t->to_insert_fork_catchpoint = linux_child_insert_fork_catchpoint; | |
18305 | t->to_insert_vfork_catchpoint = linux_child_insert_vfork_catchpoint; | |
18306 | t->to_insert_exec_catchpoint = linux_child_insert_exec_catchpoint; | |
18307 | + t->to_set_syscall_catchpoint = linux_child_set_syscall_catchpoint; | |
18308 | t->to_pid_to_exec_file = linux_child_pid_to_exec_file; | |
18309 | t->to_post_startup_inferior = linux_child_post_startup_inferior; | |
18310 | t->to_post_attach = linux_child_post_attach; | |
18311 | t->to_follow_fork = linux_child_follow_fork; | |
18312 | t->to_find_memory_regions = linux_nat_find_memory_regions; | |
18313 | t->to_make_corefile_notes = linux_nat_make_corefile_notes; | |
18314 | + t->to_passed_by_entrypoint = linux_passed_by_entrypoint; | |
18315 | ||
18316 | super_xfer_partial = t->to_xfer_partial; | |
18317 | t->to_xfer_partial = linux_xfer_partial; | |
18318 | diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h | |
18319 | index fec5139..36d2439 100644 | |
18320 | --- a/gdb/linux-nat.h | |
18321 | +++ b/gdb/linux-nat.h | |
18322 | @@ -70,6 +70,13 @@ struct lwp_info | |
18323 | or to a local variable in lin_lwp_wait. */ | |
18324 | struct target_waitstatus waitstatus; | |
18325 | ||
18326 | + /* Signal wether we are in a SYSCALL_ENTRY or | |
18327 | + in a SYSCALL_RETURN event. | |
18328 | + Values: | |
18329 | + - TARGET_WAITKIND_SYSCALL_ENTRY | |
18330 | + - TARGET_WAITKIND_SYSCALL_RETURN */ | |
18331 | + int syscall_state; | |
18332 | + | |
18333 | /* Next LWP in list. */ | |
18334 | struct lwp_info *next; | |
18335 | }; | |
18336 | diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c | |
18337 | index e18e134..d44b505 100644 | |
18338 | --- a/gdb/linux-tdep.c | |
18339 | +++ b/gdb/linux-tdep.c | |
18340 | @@ -20,6 +20,8 @@ | |
18341 | #include "defs.h" | |
18342 | #include "gdbtypes.h" | |
18343 | #include "linux-tdep.h" | |
18344 | +#include "xml-syscall.h" | |
18345 | +#include "target.h" | |
18346 | ||
18347 | /* This function is suitable for architectures that don't | |
18348 | extend/override the standard siginfo structure. */ | |
18349 | @@ -137,3 +139,81 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) | |
18350 | ||
18351 | return siginfo_type; | |
18352 | } | |
18353 | + | |
18354 | +/* Structure used to store information about the available syscalls in | |
18355 | + the system. */ | |
18356 | +static const struct syscalls_info *sysinfo = NULL; | |
18357 | + | |
18358 | +/* A flag to tell if we already initialized the structure above. */ | |
18359 | +static int have_initialized_sysinfo = 0; | |
18360 | + | |
18361 | +/* The filename of the syscall's XML. */ | |
18362 | +static const char *xml_syscall_file = NULL; | |
18363 | + | |
18364 | +/* Initializes the syscalls_info structure according to the | |
18365 | + architecture. */ | |
18366 | +static void | |
18367 | +init_sysinfo (struct gdbarch *gdbarch) | |
18368 | +{ | |
18369 | + /* Did we already try to initialize the structure? */ | |
18370 | + if (have_initialized_sysinfo) | |
18371 | + return; | |
18372 | + | |
18373 | + if (xml_syscall_file == NULL) | |
18374 | + xml_syscall_file = gdbarch_xml_syscall_filename (gdbarch); | |
18375 | + | |
18376 | + sysinfo = xml_init_syscalls_info (xml_syscall_file); | |
18377 | + | |
18378 | + have_initialized_sysinfo = 1; | |
18379 | + | |
18380 | + if (sysinfo == NULL) | |
18381 | + { | |
18382 | + if (xml_syscall_file) | |
18383 | + /* The initialization failed. Let's show a warning | |
18384 | + message to the user (just this time) and leave. */ | |
18385 | + warning (_("Could not load the syscall XML file '%s'.\n\ | |
18386 | +GDB will not be able to display syscall names."), xml_syscall_file); | |
18387 | + else | |
18388 | + /* There's no file to open. Let's warn the user. */ | |
18389 | + warning (_("There is no XML file to open.\n\ | |
18390 | +GDB will not be able to display syscall names.")); | |
18391 | + } | |
18392 | +} | |
18393 | + | |
18394 | +static void | |
18395 | +linux_get_syscall_by_number (struct gdbarch *gdbarch, | |
18396 | + int syscall_number, | |
18397 | + struct syscall *s) | |
18398 | +{ | |
18399 | + init_sysinfo (gdbarch); | |
18400 | + | |
18401 | + s->number = syscall_number; | |
18402 | + s->name = xml_get_syscall_name (sysinfo, syscall_number); | |
18403 | +} | |
18404 | + | |
18405 | +static void | |
18406 | +linux_get_syscall_by_name (struct gdbarch *gdbarch, | |
18407 | + const char *syscall_name, | |
18408 | + struct syscall *s) | |
18409 | +{ | |
18410 | + init_sysinfo (gdbarch); | |
18411 | + | |
18412 | + s->number = xml_get_syscall_number (sysinfo, syscall_name); | |
18413 | + s->name = syscall_name; | |
18414 | +} | |
18415 | + | |
18416 | +static const char ** | |
18417 | +linux_get_syscall_names (struct gdbarch *gdbarch) | |
18418 | +{ | |
18419 | + init_sysinfo (gdbarch); | |
18420 | + | |
18421 | + return xml_list_of_syscalls (sysinfo); | |
18422 | +} | |
18423 | + | |
18424 | +void | |
18425 | +linux_tdep_init (struct gdbarch *gdbarch) | |
18426 | +{ | |
18427 | + set_gdbarch_get_syscall_by_number (gdbarch, linux_get_syscall_by_number); | |
18428 | + set_gdbarch_get_syscall_by_name (gdbarch, linux_get_syscall_by_name); | |
18429 | + set_gdbarch_get_syscall_names (gdbarch, linux_get_syscall_names); | |
18430 | +} | |
18431 | diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h | |
18432 | index 50af511..1e1e541 100644 | |
18433 | --- a/gdb/linux-tdep.h | |
18434 | +++ b/gdb/linux-tdep.h | |
18435 | @@ -22,4 +22,6 @@ | |
18436 | ||
18437 | struct type *linux_get_siginfo_type (struct gdbarch *); | |
18438 | ||
18439 | +extern void linux_tdep_init (struct gdbarch *gdbarch); | |
18440 | + | |
18441 | #endif /* linux-tdep.h */ | |
18442 | diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c | |
18443 | index 9e4bb1b..9ca3ae1 100644 | |
18444 | --- a/gdb/m2-lang.c | |
18445 | +++ b/gdb/m2-lang.c | |
18446 | @@ -29,8 +29,8 @@ | |
18447 | #include "valprint.h" | |
18448 | ||
18449 | extern void _initialize_m2_language (void); | |
18450 | -static void m2_printchar (int, struct ui_file *); | |
18451 | -static void m2_emit_char (int, struct ui_file *, int); | |
18452 | +static void m2_printchar (int, struct type *, struct ui_file *); | |
18453 | +static void m2_emit_char (int, struct type *, struct ui_file *, int); | |
18454 | ||
18455 | /* Print the character C on STREAM as part of the contents of a literal | |
18456 | string whose delimiter is QUOTER. Note that that format for printing | |
18457 | @@ -39,7 +39,7 @@ static void m2_emit_char (int, struct ui_file *, int); | |
18458 | be replaced with a true Modula version. */ | |
18459 | ||
18460 | static void | |
18461 | -m2_emit_char (int c, struct ui_file *stream, int quoter) | |
18462 | +m2_emit_char (int c, struct type *type, struct ui_file *stream, int quoter) | |
18463 | { | |
18464 | ||
18465 | c &= 0xFF; /* Avoid sign bit follies */ | |
18466 | @@ -88,10 +88,10 @@ m2_emit_char (int c, struct ui_file *stream, int quoter) | |
18467 | be replaced with a true Modula version. */ | |
18468 | ||
18469 | static void | |
18470 | -m2_printchar (int c, struct ui_file *stream) | |
18471 | +m2_printchar (int c, struct type *type, struct ui_file *stream) | |
18472 | { | |
18473 | fputs_filtered ("'", stream); | |
18474 | - LA_EMIT_CHAR (c, stream, '\''); | |
18475 | + LA_EMIT_CHAR (c, type, stream, '\''); | |
18476 | fputs_filtered ("'", stream); | |
18477 | } | |
18478 | ||
18479 | @@ -103,14 +103,15 @@ m2_printchar (int c, struct ui_file *stream) | |
18480 | be replaced with a true Modula version. */ | |
18481 | ||
18482 | static void | |
18483 | -m2_printstr (struct ui_file *stream, const gdb_byte *string, | |
18484 | - unsigned int length, int width, int force_ellipses, | |
18485 | +m2_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, | |
18486 | + unsigned int length, int force_ellipses, | |
18487 | const struct value_print_options *options) | |
18488 | { | |
18489 | unsigned int i; | |
18490 | unsigned int things_printed = 0; | |
18491 | int in_quotes = 0; | |
18492 | int need_comma = 0; | |
18493 | + int width = TYPE_LENGTH (type); | |
18494 | ||
18495 | if (length == 0) | |
18496 | { | |
18497 | @@ -152,7 +153,7 @@ m2_printstr (struct ui_file *stream, const gdb_byte *string, | |
18498 | fputs_filtered ("\", ", stream); | |
18499 | in_quotes = 0; | |
18500 | } | |
18501 | - m2_printchar (string[i], stream); | |
18502 | + m2_printchar (string[i], type, stream); | |
18503 | fprintf_filtered (stream, " <repeats %u times>", reps); | |
18504 | i = rep1 - 1; | |
18505 | things_printed += options->repeat_count_threshold; | |
18506 | @@ -168,7 +169,7 @@ m2_printstr (struct ui_file *stream, const gdb_byte *string, | |
18507 | fputs_filtered ("\"", stream); | |
18508 | in_quotes = 1; | |
18509 | } | |
18510 | - LA_EMIT_CHAR (string[i], stream, '"'); | |
18511 | + LA_EMIT_CHAR (string[i], type, stream, '"'); | |
18512 | ++things_printed; | |
18513 | } | |
18514 | } | |
18515 | diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c | |
18516 | index 71c410c..41fb8fe 100644 | |
18517 | --- a/gdb/m2-valprint.c | |
18518 | +++ b/gdb/m2-valprint.c | |
18519 | @@ -237,7 +237,8 @@ print_unpacked_pointer (struct type *type, | |
18520 | && TYPE_CODE (elttype) == TYPE_CODE_INT | |
18521 | && (options->format == 0 || options->format == 's') | |
18522 | && addr != 0) | |
18523 | - return val_print_string (addr, -1, TYPE_LENGTH (elttype), stream, options); | |
18524 | + return val_print_string (TYPE_TARGET_TYPE (type), addr, -1, | |
18525 | + stream, options); | |
18526 | ||
18527 | return 0; | |
18528 | } | |
18529 | @@ -294,7 +295,7 @@ m2_print_array_contents (struct type *type, const gdb_byte *valaddr, | |
18530 | || ((current_language->la_language == language_m2) | |
18531 | && (TYPE_CODE (type) == TYPE_CODE_CHAR))) | |
18532 | && (options->format == 0 || options->format == 's')) | |
18533 | - val_print_string (address, len+1, eltlen, stream, options); | |
18534 | + val_print_string (type, address, len+1, stream, options); | |
18535 | else | |
18536 | { | |
18537 | fprintf_filtered (stream, "{"); | |
18538 | @@ -359,7 +360,8 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
18539 | len = temp_len; | |
18540 | } | |
18541 | ||
18542 | - LA_PRINT_STRING (stream, valaddr + embedded_offset, len, 1, 0, | |
18543 | + LA_PRINT_STRING (stream, TYPE_TARGET_TYPE (type), | |
18544 | + valaddr + embedded_offset, len, 0, | |
18545 | options); | |
18546 | i = len; | |
18547 | } | |
18548 | @@ -547,7 +549,7 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
18549 | else | |
18550 | fprintf_filtered (stream, "%d", (int) val); | |
18551 | fputs_filtered (" ", stream); | |
18552 | - LA_PRINT_CHAR ((unsigned char) val, stream); | |
18553 | + LA_PRINT_CHAR ((unsigned char) val, type, stream); | |
18554 | } | |
18555 | break; | |
18556 | ||
18557 | diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c | |
18558 | index 5f4b9a6..eccfe31 100644 | |
18559 | --- a/gdb/m32r-tdep.c | |
18560 | +++ b/gdb/m32r-tdep.c | |
18561 | @@ -713,7 +713,7 @@ m32r_push_dummy_call (struct gdbarch *gdbarch, struct value *function, | |
18562 | if (len > 8 | |
18563 | && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) | |
18564 | { | |
18565 | - store_unsigned_integer (valbuf, 4, VALUE_ADDRESS (args[argnum])); | |
18566 | + store_unsigned_integer (valbuf, 4, value_address (args[argnum])); | |
18567 | typecode = TYPE_CODE_PTR; | |
18568 | len = 4; | |
18569 | val = valbuf; | |
18570 | diff --git a/gdb/macroexp.c b/gdb/macroexp.c | |
18571 | index f0a8c1f..752a939 100644 | |
18572 | --- a/gdb/macroexp.c | |
18573 | +++ b/gdb/macroexp.c | |
18574 | @@ -23,6 +23,7 @@ | |
18575 | #include "macrotab.h" | |
18576 | #include "macroexp.h" | |
18577 | #include "gdb_assert.h" | |
18578 | +#include "c-lang.h" | |
18579 | ||
18580 | ||
18581 | \f | |
18582 | @@ -320,14 +321,17 @@ get_character_constant (struct macro_buffer *tok, char *p, char *end) | |
18583 | way GDB's C/C++ lexer does. So we call parse_escape in utils.c | |
18584 | to handle escape sequences. */ | |
18585 | if ((p + 1 <= end && *p == '\'') | |
18586 | - || (p + 2 <= end && p[0] == 'L' && p[1] == '\'')) | |
18587 | + || (p + 2 <= end | |
18588 | + && (p[0] == 'L' || p[0] == 'u' || p[0] == 'U') | |
18589 | + && p[1] == '\'')) | |
18590 | { | |
18591 | char *tok_start = p; | |
18592 | char *body_start; | |
18593 | + int char_count = 0; | |
18594 | ||
18595 | if (*p == '\'') | |
18596 | p++; | |
18597 | - else if (*p == 'L') | |
18598 | + else if (*p == 'L' || *p == 'u' || *p == 'U') | |
18599 | p += 2; | |
18600 | else | |
18601 | gdb_assert (0); | |
18602 | @@ -339,7 +343,7 @@ get_character_constant (struct macro_buffer *tok, char *p, char *end) | |
18603 | error (_("Unmatched single quote.")); | |
18604 | else if (*p == '\'') | |
18605 | { | |
18606 | - if (p == body_start) | |
18607 | + if (!char_count) | |
18608 | error (_("A character constant must contain at least one " | |
18609 | "character.")); | |
18610 | p++; | |
18611 | @@ -348,10 +352,13 @@ get_character_constant (struct macro_buffer *tok, char *p, char *end) | |
18612 | else if (*p == '\\') | |
18613 | { | |
18614 | p++; | |
18615 | - parse_escape (&p); | |
18616 | + char_count += c_parse_escape (&p, NULL); | |
18617 | } | |
18618 | else | |
18619 | - p++; | |
18620 | + { | |
18621 | + p++; | |
18622 | + char_count++; | |
18623 | + } | |
18624 | } | |
18625 | ||
18626 | set_token (tok, tok_start, p); | |
18627 | @@ -370,16 +377,16 @@ static int | |
18628 | get_string_literal (struct macro_buffer *tok, char *p, char *end) | |
18629 | { | |
18630 | if ((p + 1 <= end | |
18631 | - && *p == '\"') | |
18632 | + && *p == '"') | |
18633 | || (p + 2 <= end | |
18634 | - && p[0] == 'L' | |
18635 | - && p[1] == '\"')) | |
18636 | + && (p[0] == 'L' || p[0] == 'u' || p[0] == 'U') | |
18637 | + && p[1] == '"')) | |
18638 | { | |
18639 | char *tok_start = p; | |
18640 | ||
18641 | - if (*p == '\"') | |
18642 | + if (*p == '"') | |
18643 | p++; | |
18644 | - else if (*p == 'L') | |
18645 | + else if (*p == 'L' || *p == 'u' || *p == 'U') | |
18646 | p += 2; | |
18647 | else | |
18648 | gdb_assert (0); | |
18649 | @@ -388,7 +395,7 @@ get_string_literal (struct macro_buffer *tok, char *p, char *end) | |
18650 | { | |
18651 | if (p >= end) | |
18652 | error (_("Unterminated string in expression.")); | |
18653 | - else if (*p == '\"') | |
18654 | + else if (*p == '"') | |
18655 | { | |
18656 | p++; | |
18657 | break; | |
18658 | @@ -399,7 +406,7 @@ get_string_literal (struct macro_buffer *tok, char *p, char *end) | |
18659 | else if (*p == '\\') | |
18660 | { | |
18661 | p++; | |
18662 | - parse_escape (&p); | |
18663 | + c_parse_escape (&p, NULL); | |
18664 | } | |
18665 | else | |
18666 | p++; | |
18667 | diff --git a/gdb/main.c b/gdb/main.c | |
18668 | index 5d4640b..6f9e61b 100644 | |
18669 | --- a/gdb/main.c | |
18670 | +++ b/gdb/main.c | |
18671 | @@ -40,6 +40,8 @@ | |
18672 | #include "interps.h" | |
18673 | #include "main.h" | |
18674 | ||
18675 | +#include "python/python.h" | |
18676 | + | |
18677 | /* If nonzero, display time usage both at startup and for each command. */ | |
18678 | ||
18679 | int display_time; | |
18680 | @@ -62,6 +64,9 @@ int dbx_commands = 0; | |
18681 | /* System root path, used to find libraries etc. */ | |
18682 | char *gdb_sysroot = 0; | |
18683 | ||
18684 | +/* GDB datadir, used to store data files. */ | |
18685 | +char *gdb_datadir = 0; | |
18686 | + | |
18687 | struct ui_file *gdb_stdout; | |
18688 | struct ui_file *gdb_stderr; | |
18689 | struct ui_file *gdb_stdlog; | |
18690 | @@ -211,6 +216,8 @@ captured_main (void *data) | |
18691 | char *cdarg = NULL; | |
18692 | char *ttyarg = NULL; | |
18693 | ||
18694 | + int python_script = 0; | |
18695 | + | |
18696 | /* These are static so that we can take their address in an initializer. */ | |
18697 | static int print_help; | |
18698 | static int print_version; | |
18699 | @@ -357,6 +364,40 @@ captured_main (void *data) | |
18700 | } | |
18701 | } | |
18702 | ||
18703 | +#ifdef GDB_DATADIR_RELOCATABLE | |
18704 | + gdb_datadir = make_relative_prefix (argv[0], BINDIR, GDB_DATADIR); | |
18705 | + if (gdb_datadir) | |
18706 | + { | |
18707 | + struct stat s; | |
18708 | + int res = 0; | |
18709 | + | |
18710 | + if (stat (gdb_datadir, &s) == 0) | |
18711 | + if (S_ISDIR (s.st_mode)) | |
18712 | + res = 1; | |
18713 | + | |
18714 | + if (res == 0) | |
18715 | + { | |
18716 | + xfree (gdb_datadir); | |
18717 | + gdb_datadir = xstrdup (GDB_DATADIR); | |
18718 | + } | |
18719 | + } | |
18720 | + else | |
18721 | + gdb_datadir = xstrdup (GDB_DATADIR); | |
18722 | +#else | |
18723 | + gdb_datadir = xstrdup (GDB_DATADIR); | |
18724 | +#endif /* GDB_DATADIR_RELOCATABLE */ | |
18725 | + | |
18726 | + /* Canonicalize the GDB's datadir path. */ | |
18727 | + if (*gdb_datadir) | |
18728 | + { | |
18729 | + char *canon_debug = lrealpath (gdb_datadir); | |
18730 | + if (canon_debug) | |
18731 | + { | |
18732 | + xfree (gdb_datadir); | |
18733 | + gdb_datadir = canon_debug; | |
18734 | + } | |
18735 | + } | |
18736 | + | |
18737 | get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit); | |
18738 | ||
18739 | /* There will always be an interpreter. Either the one passed into | |
18740 | @@ -441,10 +482,14 @@ captured_main (void *data) | |
18741 | {"args", no_argument, &set_args, 1}, | |
18742 | {"l", required_argument, 0, 'l'}, | |
18743 | {"return-child-result", no_argument, &return_child_result, 1}, | |
18744 | +#if HAVE_PYTHON | |
18745 | + {"python", no_argument, 0, 'P'}, | |
18746 | + {"P", no_argument, 0, 'P'}, | |
18747 | +#endif | |
18748 | {0, no_argument, 0, 0} | |
18749 | }; | |
18750 | ||
18751 | - while (1) | |
18752 | + while (!python_script) | |
18753 | { | |
18754 | int option_index; | |
18755 | ||
18756 | @@ -462,6 +507,9 @@ captured_main (void *data) | |
18757 | case 0: | |
18758 | /* Long option that just sets a flag. */ | |
18759 | break; | |
18760 | + case 'P': | |
18761 | + python_script = 1; | |
18762 | + break; | |
18763 | case OPT_SE: | |
18764 | symarg = optarg; | |
18765 | execarg = optarg; | |
18766 | @@ -638,7 +686,31 @@ extern int gdbtk_test (char *); | |
18767 | use_windows = 0; | |
18768 | } | |
18769 | ||
18770 | - if (set_args) | |
18771 | + if (python_script) | |
18772 | + { | |
18773 | + /* The first argument is a python script to evaluate, and | |
18774 | + subsequent arguments are passed to the script for | |
18775 | + processing there. */ | |
18776 | + if (optind >= argc) | |
18777 | + { | |
18778 | + fprintf_unfiltered (gdb_stderr, | |
18779 | + _("%s: Python script file name required\n"), | |
18780 | + argv[0]); | |
18781 | + exit (1); | |
18782 | + } | |
18783 | + | |
18784 | + /* FIXME: should handle inferior I/O intelligently here. | |
18785 | + E.g., should be possible to run gdb in pipeline and have | |
18786 | + Python (and gdb) output go to stderr or file; and if a | |
18787 | + prompt is needed, open the tty. */ | |
18788 | + quiet = 1; | |
18789 | + /* FIXME: should read .gdbinit if, and only if, a prompt is | |
18790 | + requested by the script. Though... maybe this is not | |
18791 | + ideal? */ | |
18792 | + /* FIXME: likewise, reading in history. */ | |
18793 | + inhibit_gdbinit = 1; | |
18794 | + } | |
18795 | + else if (set_args) | |
18796 | { | |
18797 | /* The remaining options are the command-line options for the | |
18798 | inferior. The first one is the sym/exec file, and the rest | |
18799 | @@ -866,7 +938,8 @@ Can't attach to process and specify a core file at the same time.")); | |
18800 | xfree (cmdarg); | |
18801 | ||
18802 | /* Read in the old history after all the command files have been read. */ | |
18803 | - init_history (); | |
18804 | + if (!python_script) | |
18805 | + init_history (); | |
18806 | ||
18807 | if (batch) | |
18808 | { | |
18809 | @@ -895,13 +968,25 @@ Can't attach to process and specify a core file at the same time.")); | |
18810 | #endif | |
18811 | } | |
18812 | ||
18813 | - /* NOTE: cagney/1999-11-07: There is probably no reason for not | |
18814 | - moving this loop and the code found in captured_command_loop() | |
18815 | - into the command_loop() proper. The main thing holding back that | |
18816 | - change - SET_TOP_LEVEL() - has been eliminated. */ | |
18817 | - while (1) | |
18818 | +#if HAVE_PYTHON | |
18819 | + if (python_script) | |
18820 | { | |
18821 | - catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); | |
18822 | + extern int pagination_enabled; | |
18823 | + pagination_enabled = 0; | |
18824 | + run_python_script (argc - optind, &argv[optind]); | |
18825 | + return 1; | |
18826 | + } | |
18827 | + else | |
18828 | +#endif | |
18829 | + { | |
18830 | + /* NOTE: cagney/1999-11-07: There is probably no reason for not | |
18831 | + moving this loop and the code found in captured_command_loop() | |
18832 | + into the command_loop() proper. The main thing holding back that | |
18833 | + change - SET_TOP_LEVEL() - has been eliminated. */ | |
18834 | + while (1) | |
18835 | + { | |
18836 | + catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); | |
18837 | + } | |
18838 | } | |
18839 | /* No exit -- exit is through quit_command. */ | |
18840 | } | |
18841 | @@ -933,7 +1018,12 @@ print_gdb_help (struct ui_file *stream) | |
18842 | fputs_unfiltered (_("\ | |
18843 | This is the GNU debugger. Usage:\n\n\ | |
18844 | gdb [options] [executable-file [core-file or process-id]]\n\ | |
18845 | - gdb [options] --args executable-file [inferior-arguments ...]\n\n\ | |
18846 | + gdb [options] --args executable-file [inferior-arguments ...]\n"), stream); | |
18847 | +#if HAVE_PYTHON | |
18848 | + fputs_unfiltered (_("\ | |
18849 | + gdb [options] [--python|-P] script-file [script-arguments ...]\n"), stream); | |
18850 | +#endif | |
18851 | + fputs_unfiltered (_("\n\ | |
18852 | Options:\n\n\ | |
18853 | "), stream); | |
18854 | fputs_unfiltered (_("\ | |
18855 | @@ -971,7 +1061,13 @@ Options:\n\n\ | |
18856 | --nw Do not use a window interface.\n\ | |
18857 | --nx Do not read "), stream); | |
18858 | fputs_unfiltered (gdbinit, stream); | |
18859 | - fputs_unfiltered (_(" file.\n\ | |
18860 | + fputs_unfiltered (_(" file.\n"), stream); | |
18861 | +#if HAVE_PYTHON | |
18862 | + fputs_unfiltered (_("\ | |
18863 | + --python, -P Following argument is Python script file; remaining\n\ | |
18864 | + arguments are passed to script.\n"), stream); | |
18865 | +#endif | |
18866 | + fputs_unfiltered (_("\ | |
18867 | --quiet Do not print version number on startup.\n\ | |
18868 | --readnow Fully read symbol files on first access.\n\ | |
18869 | "), stream); | |
18870 | diff --git a/gdb/maint.c b/gdb/maint.c | |
18871 | index 56cafe9..1b57ff5 100644 | |
18872 | --- a/gdb/maint.c | |
18873 | +++ b/gdb/maint.c | |
18874 | @@ -906,4 +906,12 @@ When enabled GDB is profiled."), | |
18875 | show_maintenance_profile_p, | |
18876 | &maintenance_set_cmdlist, | |
18877 | &maintenance_show_cmdlist); | |
18878 | + add_setshow_filename_cmd ("gdb_datadir", class_maintenance, | |
18879 | + &gdb_datadir, _("Set GDB's datadir path."), | |
18880 | + _("Show GDB's datadir path."), | |
18881 | + _("\ | |
18882 | +When set, GDB uses the specified path to search for data files."), | |
18883 | + NULL, NULL, | |
18884 | + &maintenance_set_cmdlist, | |
18885 | + &maintenance_show_cmdlist); | |
18886 | } | |
18887 | diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c | |
18888 | index 7cbcc59..e507c3b 100644 | |
18889 | --- a/gdb/mdebugread.c | |
18890 | +++ b/gdb/mdebugread.c | |
18891 | @@ -4696,7 +4696,7 @@ new_type (char *name) | |
18892 | { | |
18893 | struct type *t; | |
18894 | ||
18895 | - t = alloc_type (current_objfile); | |
18896 | + t = alloc_type (current_objfile, NULL); | |
18897 | TYPE_NAME (t) = name; | |
18898 | TYPE_CPLUS_SPECIFIC (t) = (struct cplus_struct_type *) &cplus_struct_default; | |
18899 | return t; | |
18900 | diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c | |
18901 | index 143074b..0f4efba 100644 | |
18902 | --- a/gdb/mi/mi-cmd-var.c | |
18903 | +++ b/gdb/mi/mi-cmd-var.c | |
18904 | @@ -249,6 +249,41 @@ mi_cmd_var_set_format (char *command, char **argv, int argc) | |
18905 | } | |
18906 | ||
18907 | void | |
18908 | +mi_cmd_var_set_visualizer (char *command, char **argv, int argc) | |
18909 | +{ | |
18910 | + struct varobj *var; | |
18911 | + | |
18912 | + if (argc != 2) | |
18913 | + error ("Usage: NAME VISUALIZER_FUNCTION."); | |
18914 | + | |
18915 | + var = varobj_get_handle (argv[0]); | |
18916 | + | |
18917 | + if (var == NULL) | |
18918 | + error ("Variable object not found"); | |
18919 | + | |
18920 | + varobj_set_visualizer (var, argv[1]); | |
18921 | +} | |
18922 | + | |
18923 | +void | |
18924 | +mi_cmd_var_set_child_range (char *command, char **argv, int argc) | |
18925 | +{ | |
18926 | + struct varobj *var; | |
18927 | + int from, to; | |
18928 | + | |
18929 | + if (argc != 3) | |
18930 | + error (_("-var-set-child-range: NAME FROM TO")); | |
18931 | + | |
18932 | + var = varobj_get_handle (argv[0]); | |
18933 | + if (var == NULL) | |
18934 | + error (_("Variable object not found")); | |
18935 | + | |
18936 | + from = atoi (argv[1]); | |
18937 | + to = atoi (argv[2]); | |
18938 | + | |
18939 | + varobj_set_child_range (var, from, to); | |
18940 | +} | |
18941 | + | |
18942 | +void | |
18943 | mi_cmd_var_set_frozen (char *command, char **argv, int argc) | |
18944 | { | |
18945 | struct varobj *var; | |
18946 | @@ -369,6 +404,8 @@ mi_cmd_var_list_children (char *command, char **argv, int argc) | |
18947 | int numchild; | |
18948 | enum print_values print_values; | |
18949 | int ix; | |
18950 | + int from, to; | |
18951 | + char *display_hint; | |
18952 | ||
18953 | if (argc != 1 && argc != 2) | |
18954 | error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME")); | |
18955 | @@ -388,14 +425,22 @@ mi_cmd_var_list_children (char *command, char **argv, int argc) | |
18956 | else | |
18957 | print_values = PRINT_NO_VALUES; | |
18958 | ||
18959 | - if (VEC_length (varobj_p, children) == 0) | |
18960 | + varobj_get_child_range (var, children, &from, &to); | |
18961 | + if (from >= to) | |
18962 | return; | |
18963 | ||
18964 | + display_hint = varobj_get_display_hint (var); | |
18965 | + if (display_hint) | |
18966 | + { | |
18967 | + ui_out_field_string (uiout, "displayhint", display_hint); | |
18968 | + xfree (display_hint); | |
18969 | + } | |
18970 | + | |
18971 | if (mi_version (uiout) == 1) | |
18972 | cleanup_children = make_cleanup_ui_out_tuple_begin_end (uiout, "children"); | |
18973 | else | |
18974 | cleanup_children = make_cleanup_ui_out_list_begin_end (uiout, "children"); | |
18975 | - for (ix = 0; VEC_iterate (varobj_p, children, ix, child); ++ix) | |
18976 | + for (ix = from; ix < to && VEC_iterate (varobj_p, children, ix, child); ++ix) | |
18977 | { | |
18978 | struct cleanup *cleanup_child; | |
18979 | cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, "child"); | |
18980 | @@ -662,6 +707,8 @@ varobj_update_one (struct varobj *var, enum print_values print_values, | |
18981 | ||
18982 | for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i) | |
18983 | { | |
18984 | + char *display_hint; | |
18985 | + | |
18986 | if (mi_version (uiout) > 1) | |
18987 | cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); | |
18988 | ui_out_field_string (uiout, "name", varobj_get_objname (r->varobj)); | |
18989 | @@ -695,6 +742,36 @@ varobj_update_one (struct varobj *var, enum print_values print_values, | |
18990 | ui_out_field_int (uiout, "new_num_children", | |
18991 | varobj_get_num_children (r->varobj)); | |
18992 | } | |
18993 | + | |
18994 | + display_hint = varobj_get_display_hint (var); | |
18995 | + if (display_hint) | |
18996 | + { | |
18997 | + ui_out_field_string (uiout, "displayhint", display_hint); | |
18998 | + xfree (display_hint); | |
18999 | + } | |
19000 | + | |
19001 | + if (r->children_changed) | |
19002 | + { | |
19003 | + int ix, from, to; | |
19004 | + struct varobj *child; | |
19005 | + struct cleanup *cleanup = | |
19006 | + make_cleanup_ui_out_list_begin_end (uiout, "children"); | |
19007 | + | |
19008 | + VEC (varobj_p)* children = varobj_list_children (r->varobj); | |
19009 | + varobj_get_child_range (r->varobj, children, &from, &to); | |
19010 | + | |
19011 | + for (ix = from; | |
19012 | + ix < to && VEC_iterate (varobj_p, children, ix, child); | |
19013 | + ++ix) | |
19014 | + { | |
19015 | + struct cleanup *cleanup_child; | |
19016 | + cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); | |
19017 | + print_varobj (child, print_values, 1 /* print expression */); | |
19018 | + do_cleanups (cleanup_child); | |
19019 | + } | |
19020 | + | |
19021 | + do_cleanups (cleanup); | |
19022 | + } | |
19023 | ||
19024 | if (mi_version (uiout) > 1) | |
19025 | do_cleanups (cleanup); | |
19026 | diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c | |
19027 | index 2610b6a..f31233b 100644 | |
19028 | --- a/gdb/mi/mi-cmds.c | |
19029 | +++ b/gdb/mi/mi-cmds.c | |
19030 | @@ -160,7 +160,9 @@ struct mi_cmd mi_cmds[] = | |
19031 | { "var-info-num-children", { NULL, 0 }, mi_cmd_var_info_num_children}, | |
19032 | { "var-info-type", { NULL, 0 }, mi_cmd_var_info_type}, | |
19033 | { "var-list-children", { NULL, 0 }, mi_cmd_var_list_children}, | |
19034 | + { "var-set-child-range", { NULL, 0 }, mi_cmd_var_set_child_range }, | |
19035 | { "var-set-format", { NULL, 0 }, mi_cmd_var_set_format}, | |
19036 | + { "var-set-visualizer", { NULL, 0 }, mi_cmd_var_set_visualizer}, | |
19037 | { "var-set-frozen", { NULL, 0 }, mi_cmd_var_set_frozen}, | |
19038 | { "var-show-attributes", { NULL, 0 }, mi_cmd_var_show_attributes}, | |
19039 | { "var-show-format", { NULL, 0 }, mi_cmd_var_show_format}, | |
19040 | diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h | |
19041 | index 39f16fb..291a07f 100644 | |
19042 | --- a/gdb/mi/mi-cmds.h | |
19043 | +++ b/gdb/mi/mi-cmds.h | |
19044 | @@ -92,7 +92,9 @@ extern mi_cmd_argv_ftype mi_cmd_var_info_num_children; | |
19045 | extern mi_cmd_argv_ftype mi_cmd_var_info_type; | |
19046 | extern mi_cmd_argv_ftype mi_cmd_var_list_children; | |
19047 | extern mi_cmd_argv_ftype mi_cmd_var_set_format; | |
19048 | +extern mi_cmd_argv_ftype mi_cmd_var_set_child_range; | |
19049 | extern mi_cmd_argv_ftype mi_cmd_var_set_frozen; | |
19050 | +extern mi_cmd_argv_ftype mi_cmd_var_set_visualizer; | |
19051 | extern mi_cmd_argv_ftype mi_cmd_var_show_attributes; | |
19052 | extern mi_cmd_argv_ftype mi_cmd_var_show_format; | |
19053 | extern mi_cmd_argv_ftype mi_cmd_var_update; | |
19054 | diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c | |
19055 | index b905a9e..eaa5f12 100644 | |
19056 | --- a/gdb/mi/mi-main.c | |
19057 | +++ b/gdb/mi/mi-main.c | |
19058 | @@ -777,7 +777,7 @@ mi_cmd_data_evaluate_expression (char *command, char **argv, int argc) | |
19059 | get_user_print_options (&opts); | |
19060 | opts.deref_ref = 0; | |
19061 | val_print (value_type (val), value_contents (val), | |
19062 | - value_embedded_offset (val), VALUE_ADDRESS (val), | |
19063 | + value_embedded_offset (val), value_address (val), | |
19064 | stb->stream, 0, &opts, current_language); | |
19065 | ||
19066 | ui_out_field_stream (uiout, "value", stb); | |
19067 | @@ -1101,6 +1101,10 @@ mi_cmd_list_features (char *command, char **argv, int argc) | |
19068 | ui_out_field_string (uiout, NULL, "frozen-varobjs"); | |
19069 | ui_out_field_string (uiout, NULL, "pending-breakpoints"); | |
19070 | ui_out_field_string (uiout, NULL, "thread-info"); | |
19071 | + | |
19072 | +#if HAVE_PYTHON | |
19073 | + ui_out_field_string (uiout, NULL, "python"); | |
19074 | +#endif | |
19075 | ||
19076 | do_cleanups (cleanup); | |
19077 | return; | |
19078 | @@ -1317,6 +1321,7 @@ mi_cmd_execute (struct mi_parse *parse) | |
19079 | struct cleanup *cleanup; | |
19080 | int i; | |
19081 | free_all_values (); | |
19082 | + free_all_types (); | |
19083 | ||
19084 | current_token = xstrdup (parse->token); | |
19085 | cleanup = make_cleanup (free_current_contents, ¤t_token); | |
19086 | diff --git a/gdb/minsyms.c b/gdb/minsyms.c | |
19087 | index bf776b3..e4b0f31 100644 | |
19088 | --- a/gdb/minsyms.c | |
19089 | +++ b/gdb/minsyms.c | |
19090 | @@ -48,6 +48,8 @@ | |
19091 | #include "value.h" | |
19092 | #include "cp-abi.h" | |
19093 | #include "target.h" | |
19094 | +#include "cp-support.h" | |
19095 | +#include "language.h" | |
19096 | ||
19097 | /* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE. | |
19098 | At the end, copy them all into one newly allocated location on an objfile's | |
19099 | @@ -187,6 +189,9 @@ lookup_minimal_symbol (const char *name, const char *sfile, | |
19100 | unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; | |
19101 | unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE; | |
19102 | ||
19103 | + int needtofreename = 0; | |
19104 | + const char *modified_name; | |
19105 | + | |
19106 | if (sfile != NULL) | |
19107 | { | |
19108 | char *p = strrchr (sfile, '/'); | |
19109 | @@ -194,6 +199,18 @@ lookup_minimal_symbol (const char *name, const char *sfile, | |
19110 | sfile = p + 1; | |
19111 | } | |
19112 | ||
19113 | + /* For C++, canonicalize the input name. */ | |
19114 | + modified_name = name; | |
19115 | + if (current_language->la_language == language_cplus) | |
19116 | + { | |
19117 | + char *cname = cp_canonicalize_string (name); | |
19118 | + if (cname) | |
19119 | + { | |
19120 | + modified_name = cname; | |
19121 | + needtofreename = 1; | |
19122 | + } | |
19123 | + } | |
19124 | + | |
19125 | for (objfile = object_files; | |
19126 | objfile != NULL && found_symbol == NULL; | |
19127 | objfile = objfile->next) | |
19128 | @@ -218,9 +235,16 @@ lookup_minimal_symbol (const char *name, const char *sfile, | |
19129 | int match; | |
19130 | ||
19131 | if (pass == 1) | |
19132 | - match = strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0; | |
19133 | + { | |
19134 | + match = strcmp (SYMBOL_LINKAGE_NAME (msymbol), | |
19135 | + modified_name) == 0; | |
19136 | + } | |
19137 | else | |
19138 | - match = SYMBOL_MATCHES_SEARCH_NAME (msymbol, name); | |
19139 | + { | |
19140 | + match = SYMBOL_MATCHES_SEARCH_NAME (msymbol, | |
19141 | + modified_name); | |
19142 | + } | |
19143 | + | |
19144 | if (match) | |
19145 | { | |
19146 | switch (MSYMBOL_TYPE (msymbol)) | |
19147 | @@ -259,6 +283,10 @@ lookup_minimal_symbol (const char *name, const char *sfile, | |
19148 | } | |
19149 | } | |
19150 | } | |
19151 | + | |
19152 | + if (needtofreename) | |
19153 | + xfree ((void *) modified_name); | |
19154 | + | |
19155 | /* External symbols are best. */ | |
19156 | if (found_symbol) | |
19157 | return found_symbol; | |
19158 | diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c | |
19159 | index 6c8c4c0..7d283a4 100644 | |
19160 | --- a/gdb/mips-tdep.c | |
19161 | +++ b/gdb/mips-tdep.c | |
19162 | @@ -2757,7 +2757,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, | |
19163 | if (len > regsize | |
19164 | && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) | |
19165 | { | |
19166 | - store_unsigned_integer (valbuf, regsize, VALUE_ADDRESS (arg)); | |
19167 | + store_unsigned_integer (valbuf, regsize, value_address (arg)); | |
19168 | typecode = TYPE_CODE_PTR; | |
19169 | len = regsize; | |
19170 | val = valbuf; | |
19171 | diff --git a/gdb/mipsread.c b/gdb/mipsread.c | |
19172 | index a84003f..924c1c5 100644 | |
19173 | --- a/gdb/mipsread.c | |
19174 | +++ b/gdb/mipsread.c | |
19175 | @@ -394,6 +394,7 @@ static struct sym_fns ecoff_sym_fns = | |
19176 | mipscoff_new_init, /* sym_new_init: init anything gbl to entire symtab */ | |
19177 | mipscoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
19178 | mipscoff_symfile_read, /* sym_read: read a symbol file into symtab */ | |
19179 | + NULL, /* sym_read_psymbols */ | |
19180 | mipscoff_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
19181 | default_symfile_offsets, /* sym_offsets: dummy FIXME til implem sym reloc */ | |
19182 | default_symfile_segments, /* sym_segments: Get segment information from | |
19183 | diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c | |
19184 | index f0cea27..02be43a 100644 | |
19185 | --- a/gdb/mn10300-tdep.c | |
19186 | +++ b/gdb/mn10300-tdep.c | |
19187 | @@ -1027,7 +1027,7 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch, | |
19188 | /* Change to pointer-to-type. */ | |
19189 | arg_len = push_size; | |
19190 | store_unsigned_integer (valbuf, push_size, | |
19191 | - VALUE_ADDRESS (*args)); | |
19192 | + value_address (*args)); | |
19193 | val = &valbuf[0]; | |
19194 | } | |
19195 | else | |
19196 | diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c | |
19197 | index a6c74a3..9b8d801 100644 | |
19198 | --- a/gdb/objc-lang.c | |
19199 | +++ b/gdb/objc-lang.c | |
19200 | @@ -280,7 +280,7 @@ objc_demangle (const char *mangled, int options) | |
19201 | for printing characters and strings is language specific. */ | |
19202 | ||
19203 | static void | |
19204 | -objc_emit_char (int c, struct ui_file *stream, int quoter) | |
19205 | +objc_emit_char (int c, struct type *type, struct ui_file *stream, int quoter) | |
19206 | { | |
19207 | ||
19208 | c &= 0xFF; /* Avoid sign bit follies. */ | |
19209 | @@ -326,10 +326,10 @@ objc_emit_char (int c, struct ui_file *stream, int quoter) | |
19210 | } | |
19211 | ||
19212 | static void | |
19213 | -objc_printchar (int c, struct ui_file *stream) | |
19214 | +objc_printchar (int c, struct type *type, struct ui_file *stream) | |
19215 | { | |
19216 | fputs_filtered ("'", stream); | |
19217 | - objc_emit_char (c, stream, '\''); | |
19218 | + objc_emit_char (c, type, stream, '\''); | |
19219 | fputs_filtered ("'", stream); | |
19220 | } | |
19221 | ||
19222 | @@ -340,14 +340,16 @@ objc_printchar (int c, struct ui_file *stream) | |
19223 | FORCE_ELLIPSES. */ | |
19224 | ||
19225 | static void | |
19226 | -objc_printstr (struct ui_file *stream, const gdb_byte *string, | |
19227 | - unsigned int length, int width, int force_ellipses, | |
19228 | +objc_printstr (struct ui_file *stream, struct type *type, | |
19229 | + const gdb_byte *string, unsigned int length, | |
19230 | + int force_ellipses, | |
19231 | const struct value_print_options *options) | |
19232 | { | |
19233 | unsigned int i; | |
19234 | unsigned int things_printed = 0; | |
19235 | int in_quotes = 0; | |
19236 | int need_comma = 0; | |
19237 | + int width = TYPE_LENGTH (type); | |
19238 | ||
19239 | /* If the string was not truncated due to `set print elements', and | |
19240 | the last byte of it is a null, we don't print that, in | |
19241 | @@ -395,7 +397,7 @@ objc_printstr (struct ui_file *stream, const gdb_byte *string, | |
19242 | fputs_filtered ("\", ", stream); | |
19243 | in_quotes = 0; | |
19244 | } | |
19245 | - objc_printchar (string[i], stream); | |
19246 | + objc_printchar (string[i], type, stream); | |
19247 | fprintf_filtered (stream, " <repeats %u times>", reps); | |
19248 | i = rep1 - 1; | |
19249 | things_printed += options->repeat_count_threshold; | |
19250 | @@ -411,7 +413,7 @@ objc_printstr (struct ui_file *stream, const gdb_byte *string, | |
19251 | fputs_filtered ("\"", stream); | |
19252 | in_quotes = 1; | |
19253 | } | |
19254 | - objc_emit_char (string[i], stream, '"'); | |
19255 | + objc_emit_char (string[i], type, stream, '"'); | |
19256 | ++things_printed; | |
19257 | } | |
19258 | } | |
19259 | diff --git a/gdb/objfiles.c b/gdb/objfiles.c | |
19260 | index bc77de8..079ebcf 100644 | |
19261 | --- a/gdb/objfiles.c | |
19262 | +++ b/gdb/objfiles.c | |
19263 | @@ -691,6 +691,20 @@ have_partial_symbols (void) | |
19264 | return 1; | |
19265 | } | |
19266 | } | |
19267 | + | |
19268 | + /* Try again, after reading partial symbols. We do this in two | |
19269 | + passes because objfiles are always added to the head of the list, | |
19270 | + and there might be a later objfile for which we've already read | |
19271 | + partial symbols. */ | |
19272 | + ALL_OBJFILES (ofp) | |
19273 | + { | |
19274 | + require_partial_symbols (ofp); | |
19275 | + if (ofp->psymtabs != NULL) | |
19276 | + { | |
19277 | + return 1; | |
19278 | + } | |
19279 | + } | |
19280 | + | |
19281 | return 0; | |
19282 | } | |
19283 | ||
19284 | diff --git a/gdb/objfiles.h b/gdb/objfiles.h | |
19285 | index 60d3143..b6fdd92 100644 | |
19286 | --- a/gdb/objfiles.h | |
19287 | +++ b/gdb/objfiles.h | |
19288 | @@ -212,6 +212,11 @@ struct objfile | |
19289 | ||
19290 | struct partial_symtab *psymtabs; | |
19291 | ||
19292 | + /* An address map that can be used to quickly determine if an | |
19293 | + address comes from this objfile. This can be NULL. */ | |
19294 | + | |
19295 | + struct addrmap *quick_addrmap; | |
19296 | + | |
19297 | /* Map addresses to the entries of PSYMTABS. It would be more efficient to | |
19298 | have a map per the whole process but ADDRMAP cannot selectively remove | |
19299 | its items during FREE_OBJFILE. This mapping is already present even for | |
19300 | @@ -420,6 +425,15 @@ struct objfile | |
19301 | #define OBJF_KEEPBFD (1 << 4) /* Do not delete bfd */ | |
19302 | ||
19303 | ||
19304 | +/* Set if we have tried to read partial symtabs for this objfile. | |
19305 | + This is used to allow lazy reading of partial symtabs. */ | |
19306 | + | |
19307 | +#define OBJF_SYMTABS_READ (1 << 6) | |
19308 | + | |
19309 | +/* This flag is set for the main objfile. */ | |
19310 | + | |
19311 | +#define OBJF_MAIN (1 << 7) | |
19312 | + | |
19313 | /* The object file that the main symbol table was loaded from (e.g. the | |
19314 | argument to the "symbol-file" or "file" command). */ | |
19315 | ||
19316 | @@ -556,6 +570,13 @@ extern void *objfile_data (struct objfile *objfile, | |
19317 | ALL_OBJFILES (objfile) \ | |
19318 | ALL_OBJFILE_PSYMTABS (objfile, p) | |
19319 | ||
19320 | +/* Like ALL_PSYMTABS, but ensure that partial symbols have been read | |
19321 | + before examining the objfile. */ | |
19322 | + | |
19323 | +#define ALL_PSYMTABS_REQUIRED(objfile, p) \ | |
19324 | + ALL_OBJFILES (objfile) \ | |
19325 | + ALL_OBJFILE_PSYMTABS (require_partial_symbols (objfile), p) | |
19326 | + | |
19327 | /* Traverse all minimal symbols in all objfiles. */ | |
19328 | ||
19329 | #define ALL_MSYMBOLS(objfile, m) \ | |
19330 | diff --git a/gdb/p-lang.c b/gdb/p-lang.c | |
19331 | index 41da3e0..e743a6f 100644 | |
19332 | --- a/gdb/p-lang.c | |
19333 | +++ b/gdb/p-lang.c | |
19334 | @@ -97,7 +97,8 @@ pascal_main_name (void) | |
19335 | but this does not happen for Free Pascal nor for GPC. */ | |
19336 | int | |
19337 | is_pascal_string_type (struct type *type,int *length_pos, | |
19338 | - int *length_size, int *string_pos, int *char_size, | |
19339 | + int *length_size, int *string_pos, | |
19340 | + struct type **char_type, | |
19341 | char **arrayname) | |
19342 | { | |
19343 | if (TYPE_CODE (type) == TYPE_CODE_STRUCT) | |
19344 | @@ -114,8 +115,8 @@ is_pascal_string_type (struct type *type,int *length_pos, | |
19345 | *length_size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)); | |
19346 | if (string_pos) | |
19347 | *string_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT; | |
19348 | - if (char_size) | |
19349 | - *char_size = 1; | |
19350 | + if (char_type) | |
19351 | + *char_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1)); | |
19352 | if (arrayname) | |
19353 | *arrayname = TYPE_FIELDS (type)[1].name; | |
19354 | return 2; | |
19355 | @@ -126,7 +127,6 @@ is_pascal_string_type (struct type *type,int *length_pos, | |
19356 | && strcmp (TYPE_FIELDS (type)[0].name, "Capacity") == 0 | |
19357 | && strcmp (TYPE_FIELDS (type)[1].name, "length") == 0) | |
19358 | { | |
19359 | - struct type *char_type; | |
19360 | if (length_pos) | |
19361 | *length_pos = TYPE_FIELD_BITPOS (type, 1) / TARGET_CHAR_BIT; | |
19362 | if (length_size) | |
19363 | @@ -134,13 +134,12 @@ is_pascal_string_type (struct type *type,int *length_pos, | |
19364 | if (string_pos) | |
19365 | *string_pos = TYPE_FIELD_BITPOS (type, 2) / TARGET_CHAR_BIT; | |
19366 | /* FIXME: how can I detect wide chars in GPC ?? */ | |
19367 | - char_type = TYPE_FIELD_TYPE (type,2); | |
19368 | - if (char_size && TYPE_CODE (char_type) == TYPE_CODE_ARRAY) | |
19369 | + if (char_type) | |
19370 | { | |
19371 | - *char_size = TYPE_LENGTH (TYPE_TARGET_TYPE (char_type)); | |
19372 | + *char_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 2)); | |
19373 | + if (TYPE_CODE (*char_type) == TYPE_CODE_ARRAY) | |
19374 | + *char_type = TYPE_TARGET_TYPE (*char_type); | |
19375 | } | |
19376 | - else if (char_size) | |
19377 | - *char_size = 1; | |
19378 | if (arrayname) | |
19379 | *arrayname = TYPE_FIELDS (type)[2].name; | |
19380 | return 3; | |
19381 | @@ -182,14 +181,15 @@ pascal_one_char (int c, struct ui_file *stream, int *in_quotes) | |
19382 | } | |
19383 | } | |
19384 | ||
19385 | -static void pascal_emit_char (int c, struct ui_file *stream, int quoter); | |
19386 | +static void pascal_emit_char (int c, struct type *type, | |
19387 | + struct ui_file *stream, int quoter); | |
19388 | ||
19389 | /* Print the character C on STREAM as part of the contents of a literal | |
19390 | string whose delimiter is QUOTER. Note that that format for printing | |
19391 | characters and strings is language specific. */ | |
19392 | ||
19393 | static void | |
19394 | -pascal_emit_char (int c, struct ui_file *stream, int quoter) | |
19395 | +pascal_emit_char (int c, struct type *type, struct ui_file *stream, int quoter) | |
19396 | { | |
19397 | int in_quotes = 0; | |
19398 | pascal_one_char (c, stream, &in_quotes); | |
19399 | @@ -198,7 +198,7 @@ pascal_emit_char (int c, struct ui_file *stream, int quoter) | |
19400 | } | |
19401 | ||
19402 | void | |
19403 | -pascal_printchar (int c, struct ui_file *stream) | |
19404 | +pascal_printchar (int c, struct type *type, struct ui_file *stream) | |
19405 | { | |
19406 | int in_quotes = 0; | |
19407 | pascal_one_char (c, stream, &in_quotes); | |
19408 | @@ -212,14 +212,16 @@ pascal_printchar (int c, struct ui_file *stream) | |
19409 | had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. */ | |
19410 | ||
19411 | void | |
19412 | -pascal_printstr (struct ui_file *stream, const gdb_byte *string, | |
19413 | - unsigned int length, int width, int force_ellipses, | |
19414 | +pascal_printstr (struct ui_file *stream, struct type *type, | |
19415 | + const gdb_byte *string, unsigned int length, | |
19416 | + int force_ellipses, | |
19417 | const struct value_print_options *options) | |
19418 | { | |
19419 | unsigned int i; | |
19420 | unsigned int things_printed = 0; | |
19421 | int in_quotes = 0; | |
19422 | int need_comma = 0; | |
19423 | + int width = TYPE_LENGTH (type); | |
19424 | ||
19425 | /* If the string was not truncated due to `set print elements', and | |
19426 | the last byte of it is a null, we don't print that, in traditional C | |
19427 | @@ -273,7 +275,7 @@ pascal_printstr (struct ui_file *stream, const gdb_byte *string, | |
19428 | fputs_filtered ("', ", stream); | |
19429 | in_quotes = 0; | |
19430 | } | |
19431 | - pascal_printchar (current_char, stream); | |
19432 | + pascal_printchar (current_char, type, stream); | |
19433 | fprintf_filtered (stream, " <repeats %u times>", reps); | |
19434 | i = rep1 - 1; | |
19435 | things_printed += options->repeat_count_threshold; | |
19436 | diff --git a/gdb/p-lang.h b/gdb/p-lang.h | |
19437 | index 09a4569..2b2eb2d 100644 | |
19438 | --- a/gdb/p-lang.h | |
19439 | +++ b/gdb/p-lang.h | |
19440 | @@ -48,12 +48,13 @@ extern void pascal_type_print_method_args (char *, char *, | |
19441 | /* These are in p-lang.c: */ | |
19442 | ||
19443 | extern int | |
19444 | - is_pascal_string_type (struct type *, int *, int *, int *, int *, char **); | |
19445 | + is_pascal_string_type (struct type *, int *, int *, int *, | |
19446 | + struct type **, char **); | |
19447 | ||
19448 | -extern void pascal_printchar (int, struct ui_file *); | |
19449 | +extern void pascal_printchar (int, struct type *, struct ui_file *); | |
19450 | ||
19451 | -extern void pascal_printstr (struct ui_file *, const gdb_byte *, | |
19452 | - unsigned int, int, int, | |
19453 | +extern void pascal_printstr (struct ui_file *, struct type *, const gdb_byte *, | |
19454 | + unsigned int, int, | |
19455 | const struct value_print_options *); | |
19456 | ||
19457 | extern struct type **const (pascal_builtin_types[]); | |
19458 | diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c | |
19459 | index 27ae619..29f0e6d 100644 | |
19460 | --- a/gdb/p-valprint.c | |
19461 | +++ b/gdb/p-valprint.c | |
19462 | @@ -61,7 +61,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, | |
19463 | struct type *elttype; | |
19464 | unsigned eltlen; | |
19465 | int length_pos, length_size, string_pos; | |
19466 | - int char_size; | |
19467 | + struct type *char_type; | |
19468 | LONGEST val; | |
19469 | CORE_ADDR addr; | |
19470 | ||
19471 | @@ -100,8 +100,9 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, | |
19472 | len = temp_len; | |
19473 | } | |
19474 | ||
19475 | - LA_PRINT_STRING (stream, valaddr + embedded_offset, len, | |
19476 | - eltlen, 0, options); | |
19477 | + LA_PRINT_STRING (stream, TYPE_TARGET_TYPE (type), | |
19478 | + valaddr + embedded_offset, len, 0, | |
19479 | + options); | |
19480 | i = len; | |
19481 | } | |
19482 | else | |
19483 | @@ -175,8 +176,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, | |
19484 | && addr != 0) | |
19485 | { | |
19486 | /* no wide string yet */ | |
19487 | - i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream, | |
19488 | - options); | |
19489 | + i = val_print_string (elttype, addr, -1, stream, options); | |
19490 | } | |
19491 | /* also for pointers to pascal strings */ | |
19492 | /* Note: this is Free Pascal specific: | |
19493 | @@ -184,7 +184,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, | |
19494 | Pascal strings are mapped to records | |
19495 | with lowercase names PM */ | |
19496 | if (is_pascal_string_type (elttype, &length_pos, &length_size, | |
19497 | - &string_pos, &char_size, NULL) | |
19498 | + &string_pos, &char_type, NULL) | |
19499 | && addr != 0) | |
19500 | { | |
19501 | ULONGEST string_length; | |
19502 | @@ -193,7 +193,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, | |
19503 | read_memory (addr + length_pos, buffer, length_size); | |
19504 | string_length = extract_unsigned_integer (buffer, length_size); | |
19505 | xfree (buffer); | |
19506 | - i = val_print_string (addr + string_pos, string_length, char_size, stream, options); | |
19507 | + i = val_print_string (char_type ,addr + string_pos, string_length, stream, options); | |
19508 | } | |
19509 | else if (pascal_object_is_vtbl_member (type)) | |
19510 | { | |
19511 | @@ -298,10 +298,10 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, | |
19512 | else | |
19513 | { | |
19514 | if (is_pascal_string_type (type, &length_pos, &length_size, | |
19515 | - &string_pos, &char_size, NULL)) | |
19516 | + &string_pos, &char_type, NULL)) | |
19517 | { | |
19518 | len = extract_unsigned_integer (valaddr + embedded_offset + length_pos, length_size); | |
19519 | - LA_PRINT_STRING (stream, valaddr + embedded_offset + string_pos, len, char_size, 0, options); | |
19520 | + LA_PRINT_STRING (stream, char_type, valaddr + embedded_offset + string_pos, len, 0, options); | |
19521 | } | |
19522 | else | |
19523 | pascal_object_print_value_fields (type, valaddr + embedded_offset, address, stream, | |
19524 | @@ -426,7 +426,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, | |
19525 | else | |
19526 | fprintf_filtered (stream, "%d", (int) val); | |
19527 | fputs_filtered (" ", stream); | |
19528 | - LA_PRINT_CHAR ((unsigned char) val, stream); | |
19529 | + LA_PRINT_CHAR ((unsigned char) val, type, stream); | |
19530 | } | |
19531 | break; | |
19532 | ||
19533 | @@ -931,7 +931,7 @@ pascal_object_print_static_field (struct value *val, | |
19534 | ||
19535 | if (TYPE_CODE (type) == TYPE_CODE_STRUCT) | |
19536 | { | |
19537 | - CORE_ADDR *first_dont_print; | |
19538 | + CORE_ADDR *first_dont_print, addr; | |
19539 | int i; | |
19540 | ||
19541 | first_dont_print | |
19542 | @@ -941,7 +941,7 @@ pascal_object_print_static_field (struct value *val, | |
19543 | ||
19544 | while (--i >= 0) | |
19545 | { | |
19546 | - if (VALUE_ADDRESS (val) == first_dont_print[i]) | |
19547 | + if (value_address (val) == first_dont_print[i]) | |
19548 | { | |
19549 | fputs_filtered ("<same as static member of an already seen type>", | |
19550 | stream); | |
19551 | @@ -949,11 +949,12 @@ pascal_object_print_static_field (struct value *val, | |
19552 | } | |
19553 | } | |
19554 | ||
19555 | - obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val), | |
19556 | + addr = value_address (val); | |
19557 | + obstack_grow (&dont_print_statmem_obstack, (char *) &addr, | |
19558 | sizeof (CORE_ADDR)); | |
19559 | ||
19560 | CHECK_TYPEDEF (type); | |
19561 | - pascal_object_print_value_fields (type, value_contents (val), VALUE_ADDRESS (val), | |
19562 | + pascal_object_print_value_fields (type, value_contents (val), value_address (val), | |
19563 | stream, recurse, options, NULL, 1); | |
19564 | return; | |
19565 | } | |
19566 | diff --git a/gdb/parse.c b/gdb/parse.c | |
19567 | index eee1f8e..66aaf6a 100644 | |
19568 | --- a/gdb/parse.c | |
19569 | +++ b/gdb/parse.c | |
19570 | @@ -306,7 +306,7 @@ write_exp_elt_intern (struct internalvar *expelt) | |
19571 | strings with embedded null bytes, as is required for some languages. | |
19572 | ||
19573 | Don't be fooled by the fact that the string is null byte terminated, | |
19574 | - this is strictly for the convenience of debugging gdb itself. Gdb | |
19575 | + this is strictly for the convenience of debugging gdb itself. | |
19576 | Gdb does not depend up the string being null terminated, since the | |
19577 | actual length is recorded in expression elements at each end of the | |
19578 | string. The null byte is taken into consideration when computing how | |
19579 | @@ -352,6 +352,65 @@ write_exp_string (struct stoken str) | |
19580 | write_exp_elt_longcst ((LONGEST) len); | |
19581 | } | |
19582 | ||
19583 | +/* Add a vector of string constants to the end of the expression. | |
19584 | + | |
19585 | + This adds an OP_STRING operation, but encodes the contents | |
19586 | + differently from write_exp_string. The language is expected to | |
19587 | + handle evaluation of this expression itself. | |
19588 | + | |
19589 | + After the usual OP_STRING header, TYPE is written into the | |
19590 | + expression as a long constant. The interpretation of this field is | |
19591 | + up to the language evaluator. | |
19592 | + | |
19593 | + Next, each string in VEC is written. The length is written as a | |
19594 | + long constant, followed by the contents of the string. */ | |
19595 | + | |
19596 | +void | |
19597 | +write_exp_string_vector (int type, struct stoken_vector *vec) | |
19598 | +{ | |
19599 | + int i, n_slots, len; | |
19600 | + | |
19601 | + /* Compute the size. We compute the size in number of slots to | |
19602 | + avoid issues with string padding. */ | |
19603 | + n_slots = 0; | |
19604 | + for (i = 0; i < vec->len; ++i) | |
19605 | + { | |
19606 | + /* One slot for the length of this element, plus the number of | |
19607 | + slots needed for this string. */ | |
19608 | + n_slots += 1 + BYTES_TO_EXP_ELEM (vec->tokens[i].length); | |
19609 | + } | |
19610 | + | |
19611 | + /* One more slot for the type of the string. */ | |
19612 | + ++n_slots; | |
19613 | + | |
19614 | + /* Now compute a phony string length. */ | |
19615 | + len = EXP_ELEM_TO_BYTES (n_slots) - 1; | |
19616 | + | |
19617 | + n_slots += 4; | |
19618 | + if ((expout_ptr + n_slots) >= expout_size) | |
19619 | + { | |
19620 | + expout_size = max (expout_size * 2, expout_ptr + n_slots + 10); | |
19621 | + expout = (struct expression *) | |
19622 | + xrealloc ((char *) expout, (sizeof (struct expression) | |
19623 | + + EXP_ELEM_TO_BYTES (expout_size))); | |
19624 | + } | |
19625 | + | |
19626 | + write_exp_elt_opcode (OP_STRING); | |
19627 | + write_exp_elt_longcst (len); | |
19628 | + write_exp_elt_longcst (type); | |
19629 | + | |
19630 | + for (i = 0; i < vec->len; ++i) | |
19631 | + { | |
19632 | + write_exp_elt_longcst (vec->tokens[i].length); | |
19633 | + memcpy (&expout->elts[expout_ptr], vec->tokens[i].ptr, | |
19634 | + vec->tokens[i].length); | |
19635 | + expout_ptr += BYTES_TO_EXP_ELEM (vec->tokens[i].length); | |
19636 | + } | |
19637 | + | |
19638 | + write_exp_elt_longcst (len); | |
19639 | + write_exp_elt_opcode (OP_STRING); | |
19640 | +} | |
19641 | + | |
19642 | /* Add a bitstring constant to the end of the expression. | |
19643 | ||
19644 | Bitstring constants are stored by first writing an expression element | |
19645 | @@ -777,6 +836,15 @@ operator_length_standard (struct expression *expr, int endpos, | |
19646 | args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); | |
19647 | break; | |
19648 | ||
19649 | + case TYPE_INSTANCE: | |
19650 | + oplen = 4 + longest_to_int (expr->elts[endpos - 2].longconst); | |
19651 | + args = 1; | |
19652 | + break; | |
19653 | + | |
19654 | + case TYPE_INSTANCE_LOOKUP: | |
19655 | + oplen = 3; | |
19656 | + break; | |
19657 | + | |
19658 | case OP_OBJC_MSGCALL: /* Objective C message (method) call */ | |
19659 | oplen = 4; | |
19660 | args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); | |
19661 | diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h | |
19662 | index 2c4b755..cbda9c3 100644 | |
19663 | --- a/gdb/parser-defs.h | |
19664 | +++ b/gdb/parser-defs.h | |
19665 | @@ -69,6 +69,22 @@ struct stoken | |
19666 | int length; | |
19667 | }; | |
19668 | ||
19669 | +struct typed_stoken | |
19670 | + { | |
19671 | + /* A language-specific type field. */ | |
19672 | + int type; | |
19673 | + /* Pointer to first byte of char-string or first bit of bit-string */ | |
19674 | + char *ptr; | |
19675 | + /* Length of string in bytes for char-string or bits for bit-string */ | |
19676 | + int length; | |
19677 | + }; | |
19678 | + | |
19679 | +struct stoken_vector | |
19680 | + { | |
19681 | + int len; | |
19682 | + struct typed_stoken *tokens; | |
19683 | + }; | |
19684 | + | |
19685 | struct ttype | |
19686 | { | |
19687 | struct stoken stoken; | |
19688 | @@ -130,6 +146,8 @@ extern void write_exp_elt_intern (struct internalvar *); | |
19689 | ||
19690 | extern void write_exp_string (struct stoken); | |
19691 | ||
19692 | +void write_exp_string_vector (int type, struct stoken_vector *vec); | |
19693 | + | |
19694 | extern void write_exp_bitstring (struct stoken); | |
19695 | ||
19696 | extern void write_exp_elt_block (struct block *); | |
19697 | diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c | |
19698 | index d08d4fc..c2bbdf9 100644 | |
19699 | --- a/gdb/ppc-linux-tdep.c | |
19700 | +++ b/gdb/ppc-linux-tdep.c | |
19701 | @@ -38,6 +38,7 @@ | |
19702 | #include "trad-frame.h" | |
19703 | #include "frame-unwind.h" | |
19704 | #include "tramp-frame.h" | |
19705 | +#include "linux-tdep.h" | |
19706 | ||
19707 | #include "features/rs6000/powerpc-32l.c" | |
19708 | #include "features/rs6000/powerpc-altivec32l.c" | |
19709 | @@ -53,6 +54,9 @@ | |
19710 | #include "features/rs6000/powerpc-isa205-vsx64l.c" | |
19711 | #include "features/rs6000/powerpc-e500l.c" | |
19712 | ||
19713 | +/* The syscall's XML filename for PPC and PPC64. */ | |
19714 | +#define XML_SYSCALL_FILENAME_PPC "syscalls/ppc-linux.xml" | |
19715 | +#define XML_SYSCALL_FILENAME_PPC64 "syscalls/ppc64-linux.xml" | |
19716 | ||
19717 | /* ppc_linux_memory_remove_breakpoints attempts to remove a breakpoint | |
19718 | in much the same fashion as memory_remove_breakpoint in mem-break.c, | |
19719 | @@ -1009,6 +1013,38 @@ ppc_linux_trap_reg_p (struct gdbarch *gdbarch) | |
19720 | && register_size (gdbarch, PPC_TRAP_REGNUM) > 0; | |
19721 | } | |
19722 | ||
19723 | +/* Return the current system call's number present in the | |
19724 | + r0 register. When the function fails, it returns -1. */ | |
19725 | +static LONGEST | |
19726 | +ppc_linux_get_syscall_number (struct gdbarch *gdbarch, | |
19727 | + ptid_t ptid) | |
19728 | +{ | |
19729 | + struct regcache *regcache = get_thread_regcache (ptid); | |
19730 | + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | |
19731 | + struct cleanup *cleanbuf; | |
19732 | + /* The content of a register */ | |
19733 | + gdb_byte *buf; | |
19734 | + /* The result */ | |
19735 | + LONGEST ret; | |
19736 | + | |
19737 | + /* Make sure we're in a 32- or 64-bit machine */ | |
19738 | + gdb_assert (tdep->wordsize == 4 || tdep->wordsize == 8); | |
19739 | + | |
19740 | + buf = (gdb_byte *) xmalloc (tdep->wordsize * sizeof (gdb_byte)); | |
19741 | + | |
19742 | + cleanbuf = make_cleanup (xfree, buf); | |
19743 | + | |
19744 | + /* Getting the system call number from the register. | |
19745 | + When dealing with PowerPC architecture, this information | |
19746 | + is stored at 0th register. */ | |
19747 | + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum, buf); | |
19748 | + | |
19749 | + ret = extract_signed_integer (buf, tdep->wordsize); | |
19750 | + do_cleanups (cleanbuf); | |
19751 | + | |
19752 | + return ret; | |
19753 | +} | |
19754 | + | |
19755 | static void | |
19756 | ppc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) | |
19757 | { | |
19758 | @@ -1069,6 +1105,9 @@ ppc_linux_init_abi (struct gdbarch_info info, | |
19759 | struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | |
19760 | struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info; | |
19761 | ||
19762 | + /* Initializing common methods. */ | |
19763 | + linux_tdep_init (gdbarch); | |
19764 | + | |
19765 | /* PPC GNU/Linux uses either 64-bit or 128-bit long doubles; where | |
19766 | 128-bit, they are IBM long double, not IEEE quad long double as | |
19767 | in the System V ABI PowerPC Processor Supplement. We can safely | |
19768 | @@ -1080,6 +1119,9 @@ ppc_linux_init_abi (struct gdbarch_info info, | |
19769 | /* Handle inferior calls during interrupted system calls. */ | |
19770 | set_gdbarch_write_pc (gdbarch, ppc_linux_write_pc); | |
19771 | ||
19772 | + /* Get the syscall number from the arch's register. */ | |
19773 | + set_gdbarch_get_syscall_number (gdbarch, ppc_linux_get_syscall_number); | |
19774 | + | |
19775 | if (tdep->wordsize == 4) | |
19776 | { | |
19777 | /* Until November 2001, gcc did not comply with the 32 bit SysV | |
19778 | @@ -1099,6 +1141,9 @@ ppc_linux_init_abi (struct gdbarch_info info, | |
19779 | set_solib_svr4_fetch_link_map_offsets | |
19780 | (gdbarch, svr4_ilp32_fetch_link_map_offsets); | |
19781 | ||
19782 | + /* Setting the correct XML syscall filename. */ | |
19783 | + set_gdbarch_xml_syscall_filename (gdbarch, XML_SYSCALL_FILENAME_PPC); | |
19784 | + | |
19785 | /* Trampolines. */ | |
19786 | tramp_frame_prepend_unwinder (gdbarch, &ppc32_linux_sigaction_tramp_frame); | |
19787 | tramp_frame_prepend_unwinder (gdbarch, &ppc32_linux_sighandler_tramp_frame); | |
19788 | @@ -1116,6 +1161,9 @@ ppc_linux_init_abi (struct gdbarch_info info, | |
19789 | set_solib_svr4_fetch_link_map_offsets | |
19790 | (gdbarch, svr4_lp64_fetch_link_map_offsets); | |
19791 | ||
19792 | + /* Setting the correct XML syscall filename. */ | |
19793 | + set_gdbarch_xml_syscall_filename (gdbarch, XML_SYSCALL_FILENAME_PPC64); | |
19794 | + | |
19795 | /* Trampolines. */ | |
19796 | tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sigaction_tramp_frame); | |
19797 | tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sighandler_tramp_frame); | |
19798 | diff --git a/gdb/printcmd.c b/gdb/printcmd.c | |
19799 | index 375f82e..8c3f476 100644 | |
19800 | --- a/gdb/printcmd.c | |
19801 | +++ b/gdb/printcmd.c | |
19802 | @@ -43,6 +43,7 @@ | |
19803 | #include "disasm.h" | |
19804 | #include "dfp.h" | |
19805 | #include "valprint.h" | |
19806 | +#include "charset.h" | |
19807 | ||
19808 | #ifdef TUI | |
19809 | #include "tui/tui.h" /* For tui_active et.al. */ | |
19810 | @@ -62,11 +63,15 @@ struct format_data | |
19811 | int count; | |
19812 | char format; | |
19813 | char size; | |
19814 | + | |
19815 | + /* True if the value should be printed raw -- that is, bypassing | |
19816 | + python-based formatters. */ | |
19817 | + unsigned char raw; | |
19818 | }; | |
19819 | ||
19820 | /* Last specified output format. */ | |
19821 | ||
19822 | -static char last_format = 'x'; | |
19823 | +static char last_format = 0; | |
19824 | ||
19825 | /* Last specified examination size. 'b', 'h', 'w' or `q'. */ | |
19826 | ||
19827 | @@ -175,6 +180,7 @@ decode_format (char **string_ptr, int oformat, int osize) | |
19828 | val.format = '?'; | |
19829 | val.size = '?'; | |
19830 | val.count = 1; | |
19831 | + val.raw = 0; | |
19832 | ||
19833 | if (*p >= '0' && *p <= '9') | |
19834 | val.count = atoi (p); | |
19835 | @@ -187,6 +193,11 @@ decode_format (char **string_ptr, int oformat, int osize) | |
19836 | { | |
19837 | if (*p == 'b' || *p == 'h' || *p == 'w' || *p == 'g') | |
19838 | val.size = *p++; | |
19839 | + else if (*p == 'r') | |
19840 | + { | |
19841 | + val.raw = 1; | |
19842 | + p++; | |
19843 | + } | |
19844 | else if (*p >= 'a' && *p <= 'z') | |
19845 | val.format = *p++; | |
19846 | else | |
19847 | @@ -264,24 +275,27 @@ print_formatted (struct value *val, int size, | |
19848 | int len = TYPE_LENGTH (type); | |
19849 | ||
19850 | if (VALUE_LVAL (val) == lval_memory) | |
19851 | - next_address = VALUE_ADDRESS (val) + len; | |
19852 | + next_address = value_address (val) + len; | |
19853 | ||
19854 | if (size) | |
19855 | { | |
19856 | switch (options->format) | |
19857 | { | |
19858 | case 's': | |
19859 | - /* FIXME: Need to handle wchar_t's here... */ | |
19860 | - next_address = VALUE_ADDRESS (val) | |
19861 | - + val_print_string (VALUE_ADDRESS (val), -1, 1, stream, | |
19862 | - options); | |
19863 | + { | |
19864 | + struct type *elttype = value_type (val); | |
19865 | + next_address = (value_address (val) | |
19866 | + + val_print_string (elttype, | |
19867 | + value_address (val), -1, | |
19868 | + stream, options)); | |
19869 | + } | |
19870 | return; | |
19871 | ||
19872 | case 'i': | |
19873 | /* We often wrap here if there are long symbolic names. */ | |
19874 | wrap_here (" "); | |
19875 | - next_address = (VALUE_ADDRESS (val) | |
19876 | - + gdb_print_insn (VALUE_ADDRESS (val), stream, | |
19877 | + next_address = (value_address (val) | |
19878 | + + gdb_print_insn (value_address (val), stream, | |
19879 | &branch_delay_insns)); | |
19880 | return; | |
19881 | } | |
19882 | @@ -369,7 +383,7 @@ print_scalar_formatted (const void *valaddr, struct type *type, | |
19883 | print_hex_chars (stream, valaddr, len, byte_order); | |
19884 | return; | |
19885 | case 'c': | |
19886 | - print_char_chars (stream, valaddr, len, byte_order); | |
19887 | + print_char_chars (stream, type, valaddr, len, byte_order); | |
19888 | return; | |
19889 | default: | |
19890 | break; | |
19891 | @@ -865,6 +879,7 @@ print_command_1 (char *exp, int inspect, int voidprint) | |
19892 | fmt.count = 1; | |
19893 | fmt.format = 0; | |
19894 | fmt.size = 0; | |
19895 | + fmt.raw = 0; | |
19896 | } | |
19897 | ||
19898 | if (exp && *exp) | |
19899 | @@ -878,6 +893,11 @@ print_command_1 (char *exp, int inspect, int voidprint) | |
19900 | else | |
19901 | val = access_value_history (0); | |
19902 | ||
19903 | + /* Do not try to OBJECT_ADDRESS_SET here anything. We are interested in the | |
19904 | + source variable base addresses as found by READ_VAR_VALUE. The value here | |
19905 | + can be already a calculated expression address inappropriate for | |
19906 | + DW_OP_push_object_address. */ | |
19907 | + | |
19908 | if (voidprint || (val && value_type (val) && | |
19909 | TYPE_CODE (value_type (val)) != TYPE_CODE_VOID)) | |
19910 | { | |
19911 | @@ -900,6 +920,7 @@ print_command_1 (char *exp, int inspect, int voidprint) | |
19912 | ||
19913 | get_formatted_print_options (&opts, format); | |
19914 | opts.inspect_it = inspect; | |
19915 | + opts.raw = fmt.raw; | |
19916 | ||
19917 | print_formatted (val, fmt.size, &opts, gdb_stdout); | |
19918 | printf_filtered ("\n"); | |
19919 | @@ -950,6 +971,7 @@ output_command (char *exp, int from_tty) | |
19920 | struct value_print_options opts; | |
19921 | ||
19922 | fmt.size = 0; | |
19923 | + fmt.raw = 0; | |
19924 | ||
19925 | if (exp && *exp == '/') | |
19926 | { | |
19927 | @@ -967,6 +989,7 @@ output_command (char *exp, int from_tty) | |
19928 | annotate_value_begin (value_type (val)); | |
19929 | ||
19930 | get_formatted_print_options (&opts, format); | |
19931 | + opts.raw = fmt.raw; | |
19932 | print_formatted (val, fmt.size, &opts, gdb_stdout); | |
19933 | ||
19934 | annotate_value_end (); | |
19935 | @@ -1287,9 +1310,10 @@ x_command (char *exp, int from_tty) | |
19936 | struct cleanup *old_chain; | |
19937 | struct value *val; | |
19938 | ||
19939 | - fmt.format = last_format; | |
19940 | + fmt.format = last_format ? last_format : 'x'; | |
19941 | fmt.size = last_size; | |
19942 | fmt.count = 1; | |
19943 | + fmt.raw = 0; | |
19944 | ||
19945 | if (exp && *exp == '/') | |
19946 | { | |
19947 | @@ -1316,7 +1340,7 @@ x_command (char *exp, int from_tty) | |
19948 | if (/* last_format == 'i' && */ | |
19949 | TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC | |
19950 | && VALUE_LVAL (val) == lval_memory) | |
19951 | - next_address = VALUE_ADDRESS (val); | |
19952 | + next_address = value_address (val); | |
19953 | else | |
19954 | next_address = value_as_address (val); | |
19955 | do_cleanups (old_chain); | |
19956 | @@ -1393,6 +1417,7 @@ display_command (char *exp, int from_tty) | |
19957 | fmt.format = 0; | |
19958 | fmt.size = 0; | |
19959 | fmt.count = 0; | |
19960 | + fmt.raw = 0; | |
19961 | } | |
19962 | ||
19963 | innermost_block = 0; | |
19964 | @@ -1585,6 +1610,7 @@ do_one_display (struct display *d) | |
19965 | annotate_display_expression (); | |
19966 | ||
19967 | get_formatted_print_options (&opts, d->format.format); | |
19968 | + opts.raw = d->format.raw; | |
19969 | print_formatted (evaluate_expression (d->exp), | |
19970 | d->format.size, &opts, gdb_stdout); | |
19971 | printf_filtered ("\n"); | |
19972 | @@ -1865,7 +1891,8 @@ printf_command (char *arg, int from_tty) | |
19973 | ||
19974 | enum argclass | |
19975 | { | |
19976 | - int_arg, long_arg, long_long_arg, ptr_arg, string_arg, | |
19977 | + int_arg, long_arg, long_long_arg, ptr_arg, | |
19978 | + string_arg, wide_string_arg, wide_char_arg, | |
19979 | double_arg, long_double_arg, decfloat_arg | |
19980 | }; | |
19981 | enum argclass *argclass; | |
19982 | @@ -1997,8 +2024,8 @@ printf_command (char *arg, int from_tty) | |
19983 | break; | |
19984 | ||
19985 | case 'c': | |
19986 | - this_argclass = int_arg; | |
19987 | - if (lcount || seen_h || seen_big_l) | |
19988 | + this_argclass = lcount == 0 ? int_arg : wide_char_arg; | |
19989 | + if (lcount > 1 || seen_h || seen_big_l) | |
19990 | bad = 1; | |
19991 | if (seen_prec || seen_zero || seen_space || seen_plus) | |
19992 | bad = 1; | |
19993 | @@ -2013,8 +2040,8 @@ printf_command (char *arg, int from_tty) | |
19994 | break; | |
19995 | ||
19996 | case 's': | |
19997 | - this_argclass = string_arg; | |
19998 | - if (lcount || seen_h || seen_big_l) | |
19999 | + this_argclass = lcount == 0 ? string_arg : wide_string_arg; | |
20000 | + if (lcount > 1 || seen_h || seen_big_l) | |
20001 | bad = 1; | |
20002 | if (seen_zero || seen_space || seen_plus) | |
20003 | bad = 1; | |
20004 | @@ -2066,6 +2093,15 @@ printf_command (char *arg, int from_tty) | |
20005 | last_arg[length_before_ll + lcount]; | |
20006 | current_substring += length_before_ll + 4; | |
20007 | } | |
20008 | + else if (this_argclass == wide_string_arg | |
20009 | + || this_argclass == wide_char_arg) | |
20010 | + { | |
20011 | + /* Convert %ls or %lc to %s. */ | |
20012 | + int length_before_ls = f - last_arg - 2; | |
20013 | + strncpy (current_substring, last_arg, length_before_ls); | |
20014 | + strcpy (current_substring + length_before_ls, "s"); | |
20015 | + current_substring += length_before_ls + 2; | |
20016 | + } | |
20017 | else | |
20018 | { | |
20019 | strncpy (current_substring, last_arg, f - last_arg); | |
20020 | @@ -2130,6 +2166,76 @@ printf_command (char *arg, int from_tty) | |
20021 | printf_filtered (current_substring, (char *) str); | |
20022 | } | |
20023 | break; | |
20024 | + case wide_string_arg: | |
20025 | + { | |
20026 | + gdb_byte *str; | |
20027 | + CORE_ADDR tem; | |
20028 | + int j; | |
20029 | + struct type *wctype = lookup_typename ("wchar_t", NULL, 0); | |
20030 | + int wcwidth = TYPE_LENGTH (wctype); | |
20031 | + gdb_byte *buf = alloca (wcwidth); | |
20032 | + struct obstack output; | |
20033 | + struct cleanup *inner_cleanup; | |
20034 | + | |
20035 | + tem = value_as_address (val_args[i]); | |
20036 | + | |
20037 | + /* This is a %s argument. Find the length of the string. */ | |
20038 | + for (j = 0;; j += wcwidth) | |
20039 | + { | |
20040 | + QUIT; | |
20041 | + read_memory (tem + j, buf, wcwidth); | |
20042 | + if (extract_unsigned_integer (buf, wcwidth) == 0) | |
20043 | + break; | |
20044 | + } | |
20045 | + | |
20046 | + /* Copy the string contents into a string inside GDB. */ | |
20047 | + str = (gdb_byte *) alloca (j + wcwidth); | |
20048 | + if (j != 0) | |
20049 | + read_memory (tem, str, j); | |
20050 | + memset (&str[j], 0, wcwidth); | |
20051 | + | |
20052 | + obstack_init (&output); | |
20053 | + inner_cleanup = make_cleanup_obstack_free (&output); | |
20054 | + | |
20055 | + convert_between_encodings (target_wide_charset (), | |
20056 | + host_charset (), | |
20057 | + str, j, wcwidth, | |
20058 | + &output, translit_char); | |
20059 | + obstack_grow_str0 (&output, ""); | |
20060 | + | |
20061 | + printf_filtered (current_substring, obstack_base (&output)); | |
20062 | + do_cleanups (inner_cleanup); | |
20063 | + } | |
20064 | + break; | |
20065 | + case wide_char_arg: | |
20066 | + { | |
20067 | + struct type *wctype = lookup_typename ("wchar_t", NULL, 0); | |
20068 | + struct type *valtype; | |
20069 | + struct obstack output; | |
20070 | + struct cleanup *inner_cleanup; | |
20071 | + const gdb_byte *bytes; | |
20072 | + | |
20073 | + valtype = value_type (val_args[i]); | |
20074 | + if (TYPE_LENGTH (valtype) != TYPE_LENGTH (wctype) | |
20075 | + || TYPE_CODE (valtype) != TYPE_CODE_INT) | |
20076 | + error (_("expected wchar_t argument for %%lc")); | |
20077 | + | |
20078 | + bytes = value_contents (val_args[i]); | |
20079 | + | |
20080 | + obstack_init (&output); | |
20081 | + inner_cleanup = make_cleanup_obstack_free (&output); | |
20082 | + | |
20083 | + convert_between_encodings (target_wide_charset (), | |
20084 | + host_charset (), | |
20085 | + bytes, TYPE_LENGTH (valtype), | |
20086 | + TYPE_LENGTH (valtype), | |
20087 | + &output, translit_char); | |
20088 | + obstack_grow_str0 (&output, ""); | |
20089 | + | |
20090 | + printf_filtered (current_substring, obstack_base (&output)); | |
20091 | + do_cleanups (inner_cleanup); | |
20092 | + } | |
20093 | + break; | |
20094 | case double_arg: | |
20095 | { | |
20096 | struct type *type = value_type (val_args[i]); | |
20097 | diff --git a/gdb/python/lib/gdb/FrameIterator.py b/gdb/python/lib/gdb/FrameIterator.py | |
20098 | new file mode 100644 | |
20099 | index 0000000..87fb074 | |
20100 | --- /dev/null | |
20101 | +++ b/gdb/python/lib/gdb/FrameIterator.py | |
20102 | @@ -0,0 +1,33 @@ | |
20103 | +# Iterator over frames. | |
20104 | + | |
20105 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
20106 | + | |
20107 | +# This program is free software; you can redistribute it and/or modify | |
20108 | +# it under the terms of the GNU General Public License as published by | |
20109 | +# the Free Software Foundation; either version 3 of the License, or | |
20110 | +# (at your option) any later version. | |
20111 | +# | |
20112 | +# This program is distributed in the hope that it will be useful, | |
20113 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20114 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20115 | +# GNU General Public License for more details. | |
20116 | +# | |
20117 | +# You should have received a copy of the GNU General Public License | |
20118 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20119 | + | |
20120 | +class FrameIterator: | |
20121 | + """An iterator that iterates over frames.""" | |
20122 | + | |
20123 | + def __init__ (self, frame): | |
20124 | + "Initialize a FrameIterator. FRAME is the starting frame." | |
20125 | + self.frame = frame | |
20126 | + | |
20127 | + def __iter__ (self): | |
20128 | + return self | |
20129 | + | |
20130 | + def next (self): | |
20131 | + result = self.frame | |
20132 | + if result == None: | |
20133 | + raise StopIteration | |
20134 | + self.frame = result.older () | |
20135 | + return result | |
20136 | diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py | |
20137 | new file mode 100644 | |
20138 | index 0000000..b375c68 | |
20139 | --- /dev/null | |
20140 | +++ b/gdb/python/lib/gdb/__init__.py | |
20141 | @@ -0,0 +1,19 @@ | |
20142 | +# Startup code. | |
20143 | + | |
20144 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
20145 | + | |
20146 | +# This program is free software; you can redistribute it and/or modify | |
20147 | +# it under the terms of the GNU General Public License as published by | |
20148 | +# the Free Software Foundation; either version 3 of the License, or | |
20149 | +# (at your option) any later version. | |
20150 | +# | |
20151 | +# This program is distributed in the hope that it will be useful, | |
20152 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20153 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20154 | +# GNU General Public License for more details. | |
20155 | +# | |
20156 | +# You should have received a copy of the GNU General Public License | |
20157 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20158 | + | |
20159 | +# Load the require command by default. | |
20160 | +import gdb.command.require | |
20161 | diff --git a/gdb/python/lib/gdb/backtrace.py b/gdb/python/lib/gdb/backtrace.py | |
20162 | new file mode 100644 | |
20163 | index 0000000..2baab5f | |
20164 | --- /dev/null | |
20165 | +++ b/gdb/python/lib/gdb/backtrace.py | |
20166 | @@ -0,0 +1,42 @@ | |
20167 | +# Filtering backtrace. | |
20168 | + | |
20169 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
20170 | + | |
20171 | +# This program is free software; you can redistribute it and/or modify | |
20172 | +# it under the terms of the GNU General Public License as published by | |
20173 | +# the Free Software Foundation; either version 3 of the License, or | |
20174 | +# (at your option) any later version. | |
20175 | +# | |
20176 | +# This program is distributed in the hope that it will be useful, | |
20177 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20178 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20179 | +# GNU General Public License for more details. | |
20180 | +# | |
20181 | +# You should have received a copy of the GNU General Public License | |
20182 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20183 | + | |
20184 | +import gdb | |
20185 | +import itertools | |
20186 | + | |
20187 | +# Our only exports. | |
20188 | +__all__ = ['push_frame_filter', 'create_frame_filter'] | |
20189 | + | |
20190 | +frame_filter = None | |
20191 | + | |
20192 | +def push_frame_filter (constructor): | |
20193 | + """Register a new backtrace filter class with the 'backtrace' command. | |
20194 | +The filter will be passed an iterator as an argument. The iterator | |
20195 | +will return gdb.Frame-like objects. The filter should in turn act as | |
20196 | +an iterator returning such objects.""" | |
20197 | + global frame_filter | |
20198 | + if frame_filter == None: | |
20199 | + frame_filter = constructor | |
20200 | + else: | |
20201 | + frame_filter = lambda iterator: constructor (frame_filter (iterator)) | |
20202 | + | |
20203 | +def create_frame_filter (iter): | |
20204 | + global frame_filter | |
20205 | + if frame_filter is None: | |
20206 | + return iter | |
20207 | + return frame_filter (iter) | |
20208 | + | |
20209 | diff --git a/gdb/python/lib/gdb/command/__init__.py b/gdb/python/lib/gdb/command/__init__.py | |
20210 | new file mode 100644 | |
20211 | index 0000000..8b13789 | |
20212 | --- /dev/null | |
20213 | +++ b/gdb/python/lib/gdb/command/__init__.py | |
20214 | @@ -0,0 +1 @@ | |
20215 | + | |
20216 | diff --git a/gdb/python/lib/gdb/command/alias.py b/gdb/python/lib/gdb/command/alias.py | |
20217 | new file mode 100644 | |
20218 | index 0000000..96b6618 | |
20219 | --- /dev/null | |
20220 | +++ b/gdb/python/lib/gdb/command/alias.py | |
20221 | @@ -0,0 +1,59 @@ | |
20222 | +# Alias command. | |
20223 | + | |
20224 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
20225 | + | |
20226 | +# This program is free software; you can redistribute it and/or modify | |
20227 | +# it under the terms of the GNU General Public License as published by | |
20228 | +# the Free Software Foundation; either version 3 of the License, or | |
20229 | +# (at your option) any later version. | |
20230 | +# | |
20231 | +# This program is distributed in the hope that it will be useful, | |
20232 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20233 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20234 | +# GNU General Public License for more details. | |
20235 | +# | |
20236 | +# You should have received a copy of the GNU General Public License | |
20237 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20238 | + | |
20239 | +import gdb | |
20240 | + | |
20241 | +class AliasImplementation (gdb.Command): | |
20242 | + def __init__ (self, name, real, doc): | |
20243 | + # Have to set __doc__ before the super init call. | |
20244 | + # It would be nice if gdb's help looked up __doc__ dynamically. | |
20245 | + self.__doc__ = doc | |
20246 | + # Note: no good way to complete :( | |
20247 | + super (AliasImplementation, self).__init__ (name, gdb.COMMAND_NONE) | |
20248 | + self.real = real | |
20249 | + | |
20250 | + def invoke(self, arg, from_tty): | |
20251 | + gdb.execute (self.real + ' ' + arg, from_tty) | |
20252 | + | |
20253 | +class AliasCommand (gdb.Command): | |
20254 | + """Alias one command to another. | |
20255 | +In the simplest form, the first word is the name of the alias, and | |
20256 | +the remaining words are the the expansion. | |
20257 | +An '=' by itself can be used to define a multi-word alias; words | |
20258 | +before the '=' are the name of the new command.""" | |
20259 | + | |
20260 | + def __init__ (self): | |
20261 | + # Completion is not quite right here. | |
20262 | + super (AliasCommand, self).__init__ ("alias", gdb.COMMAND_NONE, | |
20263 | + gdb.COMPLETE_COMMAND) | |
20264 | + | |
20265 | + def invoke (self, arg, from_tty): | |
20266 | + self.dont_repeat () | |
20267 | + # Without some form of quoting we can't alias a multi-word | |
20268 | + # command to another command. | |
20269 | + args = arg.split() | |
20270 | + try: | |
20271 | + start = args.index ('=') | |
20272 | + end = start + 1 | |
20273 | + except ValueError: | |
20274 | + start = 1 | |
20275 | + end = 1 | |
20276 | + target = " ".join(args[end:]) | |
20277 | + AliasImplementation (" ".join (args[0:start]), target, | |
20278 | + "This command is an alias for '%s'." % target) | |
20279 | + | |
20280 | +AliasCommand() | |
20281 | diff --git a/gdb/python/lib/gdb/command/backtrace.py b/gdb/python/lib/gdb/command/backtrace.py | |
20282 | new file mode 100644 | |
20283 | index 0000000..f07696e | |
20284 | --- /dev/null | |
20285 | +++ b/gdb/python/lib/gdb/command/backtrace.py | |
20286 | @@ -0,0 +1,197 @@ | |
20287 | +# New backtrace command. | |
20288 | + | |
20289 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
20290 | + | |
20291 | +# This program is free software; you can redistribute it and/or modify | |
20292 | +# it under the terms of the GNU General Public License as published by | |
20293 | +# the Free Software Foundation; either version 3 of the License, or | |
20294 | +# (at your option) any later version. | |
20295 | +# | |
20296 | +# This program is distributed in the hope that it will be useful, | |
20297 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20298 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20299 | +# GNU General Public License for more details. | |
20300 | +# | |
20301 | +# You should have received a copy of the GNU General Public License | |
20302 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20303 | + | |
20304 | +import gdb | |
20305 | +import gdb.backtrace | |
20306 | +import itertools | |
20307 | +from gdb.FrameIterator import FrameIterator | |
20308 | +import sys | |
20309 | + | |
20310 | +class FrameWrapper: | |
20311 | + def __init__ (self, frame): | |
20312 | + self.frame = frame; | |
20313 | + | |
20314 | + def write_symbol (self, stream, sym, block): | |
20315 | + if len (sym.linkage_name): | |
20316 | + nsym, is_field_of_this = gdb.lookup_symbol (sym.linkage_name, block) | |
20317 | + if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER: | |
20318 | + sym = nsym | |
20319 | + | |
20320 | + stream.write (sym.print_name + "=") | |
20321 | + try: | |
20322 | + val = self.frame.read_var (sym) | |
20323 | + if val != None: | |
20324 | + val = str (val) | |
20325 | + # FIXME: would be nice to have a more precise exception here. | |
20326 | + except RuntimeError, text: | |
20327 | + val = text | |
20328 | + if val == None: | |
20329 | + stream.write ("???") | |
20330 | + else: | |
20331 | + stream.write (str (val)) | |
20332 | + | |
20333 | + def print_frame_locals (self, stream, func): | |
20334 | + if not func: | |
20335 | + return | |
20336 | + | |
20337 | + first = True | |
20338 | + block = func.value | |
20339 | + | |
20340 | + for sym in block: | |
20341 | + if sym.is_argument: | |
20342 | + continue; | |
20343 | + | |
20344 | + self.write_symbol (stream, sym, block) | |
20345 | + stream.write ('\n') | |
20346 | + | |
20347 | + def print_frame_args (self, stream, func): | |
20348 | + if not func: | |
20349 | + return | |
20350 | + | |
20351 | + first = True | |
20352 | + block = func.value | |
20353 | + | |
20354 | + for sym in block: | |
20355 | + if not sym.is_argument: | |
20356 | + continue; | |
20357 | + | |
20358 | + if not first: | |
20359 | + stream.write (", ") | |
20360 | + | |
20361 | + self.write_symbol (stream, sym, block) | |
20362 | + first = False | |
20363 | + | |
20364 | + # FIXME: this should probably just be a method on gdb.Frame. | |
20365 | + # But then we need stream wrappers. | |
20366 | + def describe (self, stream, full): | |
20367 | + if self.frame.type () == gdb.DUMMY_FRAME: | |
20368 | + stream.write (" <function called from gdb>\n") | |
20369 | + elif self.frame.type () == gdb.SIGTRAMP_FRAME: | |
20370 | + stream.write (" <signal handler called>\n") | |
20371 | + else: | |
20372 | + sal = self.frame.find_sal () | |
20373 | + pc = self.frame.pc () | |
20374 | + name = self.frame.name () | |
20375 | + if not name: | |
20376 | + name = "??" | |
20377 | + if pc != sal.pc or not sal.symtab: | |
20378 | + stream.write (" 0x%08x in" % pc) | |
20379 | + stream.write (" " + name + " (") | |
20380 | + | |
20381 | + func = gdb.find_pc_function (self.frame.addr_in_block ()) | |
20382 | + self.print_frame_args (stream, func) | |
20383 | + | |
20384 | + stream.write (")") | |
20385 | + | |
20386 | + if sal.symtab and sal.symtab.filename: | |
20387 | + stream.write (" at " + sal.symtab.filename) | |
20388 | + stream.write (":" + str (sal.line)) | |
20389 | + | |
20390 | + if not self.frame.name () or (not sal.symtab or not sal.symtab.filename): | |
20391 | + lib = gdb.solib_address (pc) | |
20392 | + if lib: | |
20393 | + stream.write (" from " + lib) | |
20394 | + | |
20395 | + stream.write ("\n") | |
20396 | + | |
20397 | + if full: | |
20398 | + self.print_frame_locals (stream, func) | |
20399 | + | |
20400 | + def __getattr__ (self, name): | |
20401 | + return getattr (self.frame, name) | |
20402 | + | |
20403 | +class ReverseBacktraceParameter (gdb.Parameter): | |
20404 | + """The new-backtrace command can show backtraces in 'reverse' order. | |
20405 | +This means that the innermost frame will be printed last. | |
20406 | +Note that reverse backtraces are more expensive to compute.""" | |
20407 | + | |
20408 | + set_doc = "Enable or disable reverse backtraces." | |
20409 | + show_doc = "Show whether backtraces will be printed in reverse order." | |
20410 | + | |
20411 | + def __init__(self): | |
20412 | + gdb.Parameter.__init__ (self, "reverse-backtrace", | |
20413 | + gdb.COMMAND_STACK, gdb.PARAM_BOOLEAN) | |
20414 | + # Default to compatibility with gdb. | |
20415 | + self.value = False | |
20416 | + | |
20417 | +class FilteringBacktrace (gdb.Command): | |
20418 | + """Print backtrace of all stack frames, or innermost COUNT frames. | |
20419 | +With a negative argument, print outermost -COUNT frames. | |
20420 | +Use of the 'full' qualifier also prints the values of the local variables. | |
20421 | +Use of the 'raw' qualifier avoids any filtering by loadable modules. | |
20422 | +""" | |
20423 | + | |
20424 | + def __init__ (self): | |
20425 | + # FIXME: this is not working quite well enough to replace | |
20426 | + # "backtrace" yet. | |
20427 | + gdb.Command.__init__ (self, "new-backtrace", gdb.COMMAND_STACK) | |
20428 | + self.reverse = ReverseBacktraceParameter() | |
20429 | + | |
20430 | + def reverse_iter (self, iter): | |
20431 | + result = [] | |
20432 | + for item in iter: | |
20433 | + result.append (item) | |
20434 | + result.reverse() | |
20435 | + return result | |
20436 | + | |
20437 | + def final_n (self, iter, x): | |
20438 | + result = [] | |
20439 | + for item in iter: | |
20440 | + result.append (item) | |
20441 | + return result[x:] | |
20442 | + | |
20443 | + def invoke (self, arg, from_tty): | |
20444 | + i = 0 | |
20445 | + count = 0 | |
20446 | + filter = True | |
20447 | + full = False | |
20448 | + | |
20449 | + for word in arg.split (" "): | |
20450 | + if word == '': | |
20451 | + continue | |
20452 | + elif word == 'raw': | |
20453 | + filter = False | |
20454 | + elif word == 'full': | |
20455 | + full = True | |
20456 | + else: | |
20457 | + count = int (word) | |
20458 | + | |
20459 | + # FIXME: provide option to start at selected frame | |
20460 | + # However, should still number as if starting from newest | |
20461 | + iter = itertools.imap (FrameWrapper, | |
20462 | + FrameIterator (gdb.newest_frame ())) | |
20463 | + if filter: | |
20464 | + iter = gdb.backtrace.create_frame_filter (iter) | |
20465 | + | |
20466 | + # Now wrap in an iterator that numbers the frames. | |
20467 | + iter = itertools.izip (itertools.count (0), iter) | |
20468 | + | |
20469 | + # Reverse if the user wanted that. | |
20470 | + if self.reverse.value: | |
20471 | + iter = self.reverse_iter (iter) | |
20472 | + | |
20473 | + # Extract sub-range user wants. | |
20474 | + if count < 0: | |
20475 | + iter = self.final_n (iter, count) | |
20476 | + elif count > 0: | |
20477 | + iter = itertools.islice (iter, 0, count) | |
20478 | + | |
20479 | + for pair in iter: | |
20480 | + sys.stdout.write ("#%-2d" % pair[0]) | |
20481 | + pair[1].describe (sys.stdout, full) | |
20482 | + | |
20483 | +FilteringBacktrace() | |
20484 | diff --git a/gdb/python/lib/gdb/command/ignore_errors.py b/gdb/python/lib/gdb/command/ignore_errors.py | |
20485 | new file mode 100644 | |
20486 | index 0000000..6fa48ff | |
20487 | --- /dev/null | |
20488 | +++ b/gdb/python/lib/gdb/command/ignore_errors.py | |
20489 | @@ -0,0 +1,37 @@ | |
20490 | +# Ignore errors in user commands. | |
20491 | + | |
20492 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
20493 | + | |
20494 | +# This program is free software; you can redistribute it and/or modify | |
20495 | +# it under the terms of the GNU General Public License as published by | |
20496 | +# the Free Software Foundation; either version 3 of the License, or | |
20497 | +# (at your option) any later version. | |
20498 | +# | |
20499 | +# This program is distributed in the hope that it will be useful, | |
20500 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20501 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20502 | +# GNU General Public License for more details. | |
20503 | +# | |
20504 | +# You should have received a copy of the GNU General Public License | |
20505 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20506 | + | |
20507 | +import gdb | |
20508 | + | |
20509 | +class IgnoreErrorsCommand (gdb.Command): | |
20510 | + """Execute a single command, ignoring all errors. | |
20511 | +Only one-line commands are supported. | |
20512 | +This is primarily useful in scripts.""" | |
20513 | + | |
20514 | + def __init__ (self): | |
20515 | + super (IgnoreErrorsCommand, self).__init__ ("ignore-errors", | |
20516 | + gdb.COMMAND_OBSCURE, | |
20517 | + # FIXME... | |
20518 | + gdb.COMPLETE_COMMAND) | |
20519 | + | |
20520 | + def invoke (self, arg, from_tty): | |
20521 | + try: | |
20522 | + gdb.execute (arg, from_tty) | |
20523 | + except: | |
20524 | + pass | |
20525 | + | |
20526 | +IgnoreErrorsCommand () | |
20527 | diff --git a/gdb/python/lib/gdb/command/pahole.py b/gdb/python/lib/gdb/command/pahole.py | |
20528 | new file mode 100644 | |
20529 | index 0000000..569b816 | |
20530 | --- /dev/null | |
20531 | +++ b/gdb/python/lib/gdb/command/pahole.py | |
20532 | @@ -0,0 +1,81 @@ | |
20533 | +# pahole command for gdb | |
20534 | + | |
20535 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
20536 | + | |
20537 | +# This program is free software; you can redistribute it and/or modify | |
20538 | +# it under the terms of the GNU General Public License as published by | |
20539 | +# the Free Software Foundation; either version 3 of the License, or | |
20540 | +# (at your option) any later version. | |
20541 | +# | |
20542 | +# This program is distributed in the hope that it will be useful, | |
20543 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20544 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20545 | +# GNU General Public License for more details. | |
20546 | +# | |
20547 | +# You should have received a copy of the GNU General Public License | |
20548 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20549 | + | |
20550 | +import gdb | |
20551 | + | |
20552 | +class Pahole (gdb.Command): | |
20553 | + """Show the holes in a structure. | |
20554 | +This command takes a single argument, a type name. | |
20555 | +It prints the type and displays comments showing where holes are.""" | |
20556 | + | |
20557 | + def __init__ (self): | |
20558 | + super (Pahole, self).__init__ ("pahole", gdb.COMMAND_NONE, | |
20559 | + gdb.COMPLETE_SYMBOL) | |
20560 | + | |
20561 | + @staticmethod | |
20562 | + def strip (type): | |
20563 | + while type.code () == gdb.TYPE_CODE_TYPEDEF: | |
20564 | + type = type.target () | |
20565 | + return type | |
20566 | + | |
20567 | + def pahole (self, type, level, name): | |
20568 | + if name is None: | |
20569 | + name = '' | |
20570 | + tag = type.tag () | |
20571 | + if tag is None: | |
20572 | + tag = '' | |
20573 | + print '%sstruct %s {' % (' ' * (2 * level), tag) | |
20574 | + bitpos = 0 | |
20575 | + for field in type.fields (): | |
20576 | + # Skip static fields. | |
20577 | + if not hasattr (field, ('bitpos')): | |
20578 | + continue | |
20579 | + | |
20580 | + ftype = self.strip (field.type) | |
20581 | + | |
20582 | + if bitpos != field.bitpos: | |
20583 | + hole = field.bitpos - bitpos | |
20584 | + print ' /* XXX %d bit hole, try to pack */' % hole | |
20585 | + bitpos = field.bitpos | |
20586 | + if field.bitsize > 0: | |
20587 | + fieldsize = field.bitsize | |
20588 | + else: | |
20589 | + # TARGET_CHAR_BIT here... | |
20590 | + fieldsize = 8 * ftype.sizeof () | |
20591 | + | |
20592 | + # TARGET_CHAR_BIT | |
20593 | + print ' /* %3d %3d */' % (int (bitpos / 8), int (fieldsize / 8)), | |
20594 | + bitpos = bitpos + fieldsize | |
20595 | + | |
20596 | + if ftype.code () == gdb.TYPE_CODE_STRUCT: | |
20597 | + self.pahole (ftype, level + 1, field.name) | |
20598 | + else: | |
20599 | + print ' ' * (2 + 2 * level), | |
20600 | + print '%s %s' % (str (ftype), field.name) | |
20601 | + | |
20602 | + print ' ' * (14 + 2 * level), | |
20603 | + print '} %s' % name | |
20604 | + | |
20605 | + def invoke (self, arg, from_tty): | |
20606 | + type = gdb.Type (arg) | |
20607 | + type = self.strip (type) | |
20608 | + if type.code () != gdb.TYPE_CODE_STRUCT: | |
20609 | + raise TypeError, '%s is not a struct type' % arg | |
20610 | + print ' ' * 14, | |
20611 | + self.pahole (type, 0, '') | |
20612 | + | |
20613 | +Pahole() | |
20614 | diff --git a/gdb/python/lib/gdb/command/require.py b/gdb/python/lib/gdb/command/require.py | |
20615 | new file mode 100644 | |
20616 | index 0000000..1fbc1e8 | |
20617 | --- /dev/null | |
20618 | +++ b/gdb/python/lib/gdb/command/require.py | |
20619 | @@ -0,0 +1,57 @@ | |
20620 | +# Demand-loading commands. | |
20621 | + | |
20622 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
20623 | + | |
20624 | +# This program is free software; you can redistribute it and/or modify | |
20625 | +# it under the terms of the GNU General Public License as published by | |
20626 | +# the Free Software Foundation; either version 3 of the License, or | |
20627 | +# (at your option) any later version. | |
20628 | +# | |
20629 | +# This program is distributed in the hope that it will be useful, | |
20630 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20631 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20632 | +# GNU General Public License for more details. | |
20633 | +# | |
20634 | +# You should have received a copy of the GNU General Public License | |
20635 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20636 | + | |
20637 | +import gdb | |
20638 | +import os | |
20639 | + | |
20640 | +class RequireCommand (gdb.Command): | |
20641 | + """Prefix command for requiring features.""" | |
20642 | + | |
20643 | + def __init__ (self): | |
20644 | + super (RequireCommand, self).__init__ ("require", | |
20645 | + gdb.COMMAND_SUPPORT, | |
20646 | + gdb.COMPLETE_NONE, | |
20647 | + True) | |
20648 | + | |
20649 | +class RequireSubcommand (gdb.Command): | |
20650 | + """Demand-load a command by name.""" | |
20651 | + | |
20652 | + def __init__ (self, name): | |
20653 | + self.__doc__ = "Demand-load a %s by name." % name | |
20654 | + super (RequireSubcommand, self).__init__ ("require %s" % name, | |
20655 | + gdb.COMMAND_SUPPORT) | |
20656 | + self.name = name | |
20657 | + | |
20658 | + def invoke (self, arg, from_tty): | |
20659 | + for cmd in arg.split(): | |
20660 | + exec ('import gdb.' + self.name + '.' + cmd, globals ()) | |
20661 | + | |
20662 | + def complete (self, text, word): | |
20663 | + dir = gdb.pythondir + '/gdb/' + self.name | |
20664 | + result = [] | |
20665 | + for file in os.listdir(dir): | |
20666 | + if not file.startswith (word) or not file.endswith ('.py'): | |
20667 | + continue | |
20668 | + feature = file[0:-3] | |
20669 | + if feature == 'require' or feature == '__init__': | |
20670 | + continue | |
20671 | + result.append (feature) | |
20672 | + return result | |
20673 | + | |
20674 | +RequireCommand() | |
20675 | +RequireSubcommand("command") | |
20676 | +RequireSubcommand("function") | |
20677 | diff --git a/gdb/python/lib/gdb/command/save_breakpoints.py b/gdb/python/lib/gdb/command/save_breakpoints.py | |
20678 | new file mode 100644 | |
20679 | index 0000000..90e07db | |
20680 | --- /dev/null | |
20681 | +++ b/gdb/python/lib/gdb/command/save_breakpoints.py | |
20682 | @@ -0,0 +1,65 @@ | |
20683 | +# Save breakpoints. | |
20684 | + | |
20685 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
20686 | + | |
20687 | +# This program is free software; you can redistribute it and/or modify | |
20688 | +# it under the terms of the GNU General Public License as published by | |
20689 | +# the Free Software Foundation; either version 3 of the License, or | |
20690 | +# (at your option) any later version. | |
20691 | +# | |
20692 | +# This program is distributed in the hope that it will be useful, | |
20693 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20694 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20695 | +# GNU General Public License for more details. | |
20696 | +# | |
20697 | +# You should have received a copy of the GNU General Public License | |
20698 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20699 | + | |
20700 | +from __future__ import with_statement | |
20701 | +import gdb | |
20702 | + | |
20703 | +class SavePrefixCommand (gdb.Command): | |
20704 | + "Prefix command for saving things." | |
20705 | + | |
20706 | + def __init__ (self): | |
20707 | + super (SavePrefixCommand, self).__init__ ("save", | |
20708 | + gdb.COMMAND_SUPPORT, | |
20709 | + gdb.COMPLETE_NONE, True) | |
20710 | + | |
20711 | +class SaveBreakpointsCommand (gdb.Command): | |
20712 | + """Save the current breakpoints to a file. | |
20713 | +This command takes a single argument, a file name. | |
20714 | +The breakpoints can be restored using the 'source' command.""" | |
20715 | + | |
20716 | + def __init__ (self): | |
20717 | + super (SaveBreakpointsCommand, self).__init__ ("save breakpoints", | |
20718 | + gdb.COMMAND_SUPPORT, | |
20719 | + gdb.COMPLETE_FILENAME) | |
20720 | + | |
20721 | + def invoke (self, arg, from_tty): | |
20722 | + self.dont_repeat () | |
20723 | + bps = gdb.breakpoints () | |
20724 | + if bps is None: | |
20725 | + raise RuntimeError, 'No breakpoints to save' | |
20726 | + with open (arg.strip (), 'w') as f: | |
20727 | + for bp in bps: | |
20728 | + print >> f, "break", bp.location, | |
20729 | + if bp.thread is not None: | |
20730 | + print >> f, " thread", bp.thread, | |
20731 | + if bp.condition is not None: | |
20732 | + print >> f, " if", bp.condition, | |
20733 | + print >> f | |
20734 | + if not bp.enabled: | |
20735 | + print >> f, "disable %d" % bp.number | |
20736 | + # Note: we don't save the ignore count; there doesn't | |
20737 | + # seem to be much point. | |
20738 | + commands = bp.commands | |
20739 | + if commands is not None: | |
20740 | + print >> f, "commands" | |
20741 | + # Note that COMMANDS has a trailing newline. | |
20742 | + print >> f, commands, | |
20743 | + print >> f, "end" | |
20744 | + print >> f | |
20745 | + | |
20746 | +SavePrefixCommand () | |
20747 | +SaveBreakpointsCommand () | |
20748 | diff --git a/gdb/python/lib/gdb/function/__init__.py b/gdb/python/lib/gdb/function/__init__.py | |
20749 | new file mode 100644 | |
20750 | index 0000000..8b13789 | |
20751 | --- /dev/null | |
20752 | +++ b/gdb/python/lib/gdb/function/__init__.py | |
20753 | @@ -0,0 +1 @@ | |
20754 | + | |
20755 | diff --git a/gdb/python/lib/gdb/function/caller_is.py b/gdb/python/lib/gdb/function/caller_is.py | |
20756 | new file mode 100644 | |
20757 | index 0000000..2b9c5c7 | |
20758 | --- /dev/null | |
20759 | +++ b/gdb/python/lib/gdb/function/caller_is.py | |
20760 | @@ -0,0 +1,58 @@ | |
20761 | +# Caller-is functions. | |
20762 | + | |
20763 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
20764 | + | |
20765 | +# This program is free software; you can redistribute it and/or modify | |
20766 | +# it under the terms of the GNU General Public License as published by | |
20767 | +# the Free Software Foundation; either version 3 of the License, or | |
20768 | +# (at your option) any later version. | |
20769 | +# | |
20770 | +# This program is distributed in the hope that it will be useful, | |
20771 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20772 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20773 | +# GNU General Public License for more details. | |
20774 | +# | |
20775 | +# You should have received a copy of the GNU General Public License | |
20776 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20777 | + | |
20778 | +import gdb | |
20779 | +import re | |
20780 | + | |
20781 | +class CallerIs (gdb.Function): | |
20782 | + """Return True if the calling function's name is equal to a string. | |
20783 | +This function takes one or two arguments. | |
20784 | +The first argument is the name of a function; if the calling function's | |
20785 | +name is equal to this argument, this function returns True. | |
20786 | +The optional second argument tells this function how many stack frames | |
20787 | +to traverse to find the calling function. The default is 1.""" | |
20788 | + | |
20789 | + def __init__ (self): | |
20790 | + super (CallerIs, self).__init__ ("caller_is") | |
20791 | + | |
20792 | + def invoke (self, name, nframes = 1): | |
20793 | + frame = gdb.selected_frame () | |
20794 | + while nframes > 0: | |
20795 | + frame = frame.older () | |
20796 | + nframes = nframes - 1 | |
20797 | + return frame.name () == name.string () | |
20798 | + | |
20799 | +class CallerMatches (gdb.Function): | |
20800 | + """Return True if the calling function's name matches a string. | |
20801 | +This function takes one or two arguments. | |
20802 | +The first argument is a regular expression; if the calling function's | |
20803 | +name is matched by this argument, this function returns True. | |
20804 | +The optional second argument tells this function how many stack frames | |
20805 | +to traverse to find the calling function. The default is 1.""" | |
20806 | + | |
20807 | + def __init__ (self): | |
20808 | + super (CallerMatches, self).__init__ ("caller_matches") | |
20809 | + | |
20810 | + def invoke (self, name, nframes = 1): | |
20811 | + frame = gdb.selected_frame () | |
20812 | + while nframes > 0: | |
20813 | + frame = frame.older () | |
20814 | + nframes = nframes - 1 | |
20815 | + return re.match (name.string (), frame.name ()) is not None | |
20816 | + | |
20817 | +CallerIs() | |
20818 | +CallerMatches() | |
20819 | diff --git a/gdb/python/lib/gdb/function/in_scope.py b/gdb/python/lib/gdb/function/in_scope.py | |
20820 | new file mode 100644 | |
20821 | index 0000000..debb3bb | |
20822 | --- /dev/null | |
20823 | +++ b/gdb/python/lib/gdb/function/in_scope.py | |
20824 | @@ -0,0 +1,47 @@ | |
20825 | +# In-scope function. | |
20826 | + | |
20827 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
20828 | + | |
20829 | +# This program is free software; you can redistribute it and/or modify | |
20830 | +# it under the terms of the GNU General Public License as published by | |
20831 | +# the Free Software Foundation; either version 3 of the License, or | |
20832 | +# (at your option) any later version. | |
20833 | +# | |
20834 | +# This program is distributed in the hope that it will be useful, | |
20835 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20836 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20837 | +# GNU General Public License for more details. | |
20838 | +# | |
20839 | +# You should have received a copy of the GNU General Public License | |
20840 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20841 | + | |
20842 | +import gdb | |
20843 | + | |
20844 | +class InScope (gdb.Function): | |
20845 | + """Return True if all the given variables or macros are in scope. | |
20846 | +Takes one argument for each variable name to be checked.""" | |
20847 | + | |
20848 | + def __init__ (self): | |
20849 | + super (InScope, self).__init__ ("in_scope") | |
20850 | + | |
20851 | + def invoke (self, *vars): | |
20852 | + if len (vars) == 0: | |
20853 | + raise TypeError, "in_scope takes at least one argument" | |
20854 | + | |
20855 | + # gdb.Value isn't hashable so it can't be put in a map. | |
20856 | + # Convert to string first. | |
20857 | + wanted = set (map (lambda x: x.string (), vars)) | |
20858 | + found = set () | |
20859 | + block = gdb.selected_frame ().block () | |
20860 | + while block: | |
20861 | + for sym in block: | |
20862 | + if (sym.is_argument or sym.is_constant | |
20863 | + or sym.is_function or sym.is_variable): | |
20864 | + if sym.name in wanted: | |
20865 | + found.add (sym.name) | |
20866 | + | |
20867 | + block = block.superblock | |
20868 | + | |
20869 | + return wanted == found | |
20870 | + | |
20871 | +InScope () | |
20872 | diff --git a/gdb/python/lib/gdb/libstdcxx/__init__.py b/gdb/python/lib/gdb/libstdcxx/__init__.py | |
20873 | new file mode 100644 | |
20874 | index 0000000..8b13789 | |
20875 | --- /dev/null | |
20876 | +++ b/gdb/python/lib/gdb/libstdcxx/__init__.py | |
20877 | @@ -0,0 +1 @@ | |
20878 | + | |
20879 | diff --git a/gdb/python/lib/gdb/libstdcxx/v6/__init__.py b/gdb/python/lib/gdb/libstdcxx/v6/__init__.py | |
20880 | new file mode 100644 | |
20881 | index 0000000..8b13789 | |
20882 | --- /dev/null | |
20883 | +++ b/gdb/python/lib/gdb/libstdcxx/v6/__init__.py | |
20884 | @@ -0,0 +1 @@ | |
20885 | + | |
20886 | diff --git a/gdb/python/lib/gdb/libstdcxx/v6/hook.in b/gdb/python/lib/gdb/libstdcxx/v6/hook.in | |
20887 | new file mode 100644 | |
20888 | index 0000000..fe7c072 | |
20889 | --- /dev/null | |
20890 | +++ b/gdb/python/lib/gdb/libstdcxx/v6/hook.in | |
20891 | @@ -0,0 +1,27 @@ | |
20892 | +# -*- python -*- | |
20893 | +# Copyright (C) 2009 Free Software Foundation, Inc. | |
20894 | + | |
20895 | +# This program is free software; you can redistribute it and/or modify | |
20896 | +# it under the terms of the GNU General Public License as published by | |
20897 | +# the Free Software Foundation; either version 3 of the License, or | |
20898 | +# (at your option) any later version. | |
20899 | +# | |
20900 | +# This program is distributed in the hope that it will be useful, | |
20901 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20902 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20903 | +# GNU General Public License for more details. | |
20904 | +# | |
20905 | +# You should have received a copy of the GNU General Public License | |
20906 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20907 | + | |
20908 | +import sys | |
20909 | +import gdb | |
20910 | + | |
20911 | +# Update module path. | |
20912 | +dir = '@dir@' | |
20913 | +if not dir in sys.path: | |
20914 | + sys.path.insert(0, dir) | |
20915 | + | |
20916 | +# Load the pretty-printers. | |
20917 | +from libstdcxx.v6.printers import register_libstdcxx_printers | |
20918 | +register_libstdcxx_printers (gdb.current_objfile ()) | |
20919 | diff --git a/gdb/python/lib/gdb/libstdcxx/v6/printers.py b/gdb/python/lib/gdb/libstdcxx/v6/printers.py | |
20920 | new file mode 100644 | |
20921 | index 0000000..c0dc987 | |
20922 | --- /dev/null | |
20923 | +++ b/gdb/python/lib/gdb/libstdcxx/v6/printers.py | |
20924 | @@ -0,0 +1,647 @@ | |
20925 | +# Pretty-printers for libstc++. | |
20926 | + | |
20927 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
20928 | + | |
20929 | +# This program is free software; you can redistribute it and/or modify | |
20930 | +# it under the terms of the GNU General Public License as published by | |
20931 | +# the Free Software Foundation; either version 3 of the License, or | |
20932 | +# (at your option) any later version. | |
20933 | +# | |
20934 | +# This program is distributed in the hope that it will be useful, | |
20935 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20936 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20937 | +# GNU General Public License for more details. | |
20938 | +# | |
20939 | +# You should have received a copy of the GNU General Public License | |
20940 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20941 | + | |
20942 | +import gdb | |
20943 | +import itertools | |
20944 | +import re | |
20945 | + | |
20946 | +class StdPointerPrinter: | |
20947 | + "Print a smart pointer of some kind" | |
20948 | + | |
20949 | + def __init__ (self, typename, val): | |
20950 | + self.typename = typename | |
20951 | + self.val = val | |
20952 | + | |
20953 | + def to_string (self): | |
20954 | + return '%s (count %d) %s' % (self.typename, | |
20955 | + self.val['_M_refcount']['_M_pi']['_M_use_count'], | |
20956 | + self.val['_M_ptr']) | |
20957 | + | |
20958 | +class UniquePointerPrinter: | |
20959 | + "Print a unique_ptr" | |
20960 | + | |
20961 | + def __init__ (self, val): | |
20962 | + self.val = val | |
20963 | + | |
20964 | + def to_string (self): | |
20965 | + return self.val['_M_t'] | |
20966 | + | |
20967 | +class StdListPrinter: | |
20968 | + "Print a std::list" | |
20969 | + | |
20970 | + class _iterator: | |
20971 | + def __init__(self, nodetype, head): | |
20972 | + self.nodetype = nodetype | |
20973 | + self.base = head['_M_next'] | |
20974 | + self.head = head.address() | |
20975 | + self.count = 0 | |
20976 | + | |
20977 | + def __iter__(self): | |
20978 | + return self | |
20979 | + | |
20980 | + def next(self): | |
20981 | + if self.base == self.head: | |
20982 | + raise StopIteration | |
20983 | + elt = self.base.cast(self.nodetype).dereference() | |
20984 | + self.base = elt['_M_next'] | |
20985 | + count = self.count | |
20986 | + self.count = self.count + 1 | |
20987 | + return ('[%d]' % count, elt['_M_data']) | |
20988 | + | |
20989 | + def __init__(self, val): | |
20990 | + self.val = val | |
20991 | + | |
20992 | + def children(self): | |
20993 | + itype = self.val.type().template_argument(0) | |
20994 | + nodetype = gdb.Type('std::_List_node<%s>' % itype).pointer() | |
20995 | + return self._iterator(nodetype, self.val['_M_impl']['_M_node']) | |
20996 | + | |
20997 | + def to_string(self): | |
20998 | + if self.val['_M_impl']['_M_node'].address() == self.val['_M_impl']['_M_node']['_M_next']: | |
20999 | + return 'empty std::list' | |
21000 | + return 'std::list' | |
21001 | + | |
21002 | +class StdListIteratorPrinter: | |
21003 | + "Print std::list::iterator" | |
21004 | + | |
21005 | + def __init__(self, val): | |
21006 | + self.val = val | |
21007 | + | |
21008 | + def to_string(self): | |
21009 | + itype = self.val.type().template_argument(0) | |
21010 | + nodetype = gdb.Type('std::_List_node<%s>' % itype).pointer() | |
21011 | + return self.val['_M_node'].cast(nodetype).dereference()['_M_data'] | |
21012 | + | |
21013 | +class StdSlistPrinter: | |
21014 | + "Print a __gnu_cxx::slist" | |
21015 | + | |
21016 | + class _iterator: | |
21017 | + def __init__(self, nodetype, head): | |
21018 | + self.nodetype = nodetype | |
21019 | + self.base = head['_M_head']['_M_next'] | |
21020 | + self.count = 0 | |
21021 | + | |
21022 | + def __iter__(self): | |
21023 | + return self | |
21024 | + | |
21025 | + def next(self): | |
21026 | + if self.base == 0: | |
21027 | + raise StopIteration | |
21028 | + elt = self.base.cast(self.nodetype).dereference() | |
21029 | + self.base = elt['_M_next'] | |
21030 | + count = self.count | |
21031 | + self.count = self.count + 1 | |
21032 | + return ('[%d]' % count, elt['_M_data']) | |
21033 | + | |
21034 | + def __init__(self, val): | |
21035 | + self.val = val | |
21036 | + | |
21037 | + def children(self): | |
21038 | + itype = self.val.type().template_argument(0) | |
21039 | + nodetype = gdb.Type('__gnu_cxx::_Slist_node<%s>' % itype).pointer() | |
21040 | + return self._iterator(nodetype, self.val) | |
21041 | + | |
21042 | + def to_string(self): | |
21043 | + if self.val['_M_head']['_M_next'] == 0: | |
21044 | + return 'empty __gnu_cxx::slist' | |
21045 | + return '__gnu_cxx::slist' | |
21046 | + | |
21047 | +class StdSlistIteratorPrinter: | |
21048 | + "Print __gnu_cxx::slist::iterator" | |
21049 | + | |
21050 | + def __init__(self, val): | |
21051 | + self.val = val | |
21052 | + | |
21053 | + def to_string(self): | |
21054 | + itype = self.val.type().template_argument(0) | |
21055 | + nodetype = gdb.Type('__gnu_cxx::_Slist_node<%s>' % itype).pointer() | |
21056 | + return self.val['_M_node'].cast(nodetype).dereference()['_M_data'] | |
21057 | + | |
21058 | +class StdVectorPrinter: | |
21059 | + "Print a std::vector" | |
21060 | + | |
21061 | + class _iterator: | |
21062 | + def __init__ (self, start, finish): | |
21063 | + self.item = start | |
21064 | + self.finish = finish | |
21065 | + self.count = 0 | |
21066 | + | |
21067 | + def __iter__(self): | |
21068 | + return self | |
21069 | + | |
21070 | + def next(self): | |
21071 | + if self.item == self.finish: | |
21072 | + raise StopIteration | |
21073 | + count = self.count | |
21074 | + self.count = self.count + 1 | |
21075 | + elt = self.item.dereference() | |
21076 | + self.item = self.item + 1 | |
21077 | + return ('[%d]' % count, elt) | |
21078 | + | |
21079 | + def __init__(self, val): | |
21080 | + self.val = val | |
21081 | + | |
21082 | + def children(self): | |
21083 | + return self._iterator(self.val['_M_impl']['_M_start'], | |
21084 | + self.val['_M_impl']['_M_finish']) | |
21085 | + | |
21086 | + def to_string(self): | |
21087 | + start = self.val['_M_impl']['_M_start'] | |
21088 | + finish = self.val['_M_impl']['_M_finish'] | |
21089 | + end = self.val['_M_impl']['_M_end_of_storage'] | |
21090 | + return ('std::vector of length %d, capacity %d' | |
21091 | + % (int (finish - start), int (end - start))) | |
21092 | + | |
21093 | + def display_hint(self): | |
21094 | + return 'array' | |
21095 | + | |
21096 | +class StdVectorIteratorPrinter: | |
21097 | + "Print std::vector::iterator" | |
21098 | + | |
21099 | + def __init__(self, val): | |
21100 | + self.val = val | |
21101 | + | |
21102 | + def to_string(self): | |
21103 | + return self.val['_M_current'].dereference() | |
21104 | + | |
21105 | +class StdStackOrQueuePrinter: | |
21106 | + "Print a std::stack or std::queue" | |
21107 | + | |
21108 | + def __init__ (self, typename, val): | |
21109 | + self.typename = typename | |
21110 | + self.visualizer = gdb.default_visualizer(val['c']) | |
21111 | + | |
21112 | + def children (self): | |
21113 | + return self.visualizer.children() | |
21114 | + | |
21115 | + def to_string (self): | |
21116 | + return '%s wrapping: %s' % (self.typename, | |
21117 | + self.visualizer.to_string()) | |
21118 | + | |
21119 | + def display_hint (self): | |
21120 | + if hasattr (self.visualizer, 'display_hint'): | |
21121 | + return self.visualizer.display_hint () | |
21122 | + return None | |
21123 | + | |
21124 | +class RbtreeIterator: | |
21125 | + def __init__(self, rbtree): | |
21126 | + self.size = rbtree['_M_t']['_M_impl']['_M_node_count'] | |
21127 | + self.node = rbtree['_M_t']['_M_impl']['_M_header']['_M_left'] | |
21128 | + self.count = 0 | |
21129 | + | |
21130 | + def __iter__(self): | |
21131 | + return self | |
21132 | + | |
21133 | + def __len__(self): | |
21134 | + return int (self.size) | |
21135 | + | |
21136 | + def next(self): | |
21137 | + if self.count == self.size: | |
21138 | + raise StopIteration | |
21139 | + result = self.node | |
21140 | + self.count = self.count + 1 | |
21141 | + if self.count < self.size: | |
21142 | + # Compute the next node. | |
21143 | + node = self.node | |
21144 | + if node.dereference()['_M_right']: | |
21145 | + node = node.dereference()['_M_right'] | |
21146 | + while node.dereference()['_M_left']: | |
21147 | + node = node.dereference()['_M_left'] | |
21148 | + else: | |
21149 | + parent = node.dereference()['_M_parent'] | |
21150 | + while node == parent.dereference()['_M_right']: | |
21151 | + node = parent | |
21152 | + parent = parent.dereference()['_M_parent'] | |
21153 | + if node.dereference()['_M_right'] != parent: | |
21154 | + node = parent | |
21155 | + self.node = node | |
21156 | + return result | |
21157 | + | |
21158 | +# This is a pretty printer for std::_Rb_tree_iterator (which is | |
21159 | +# std::map::iterator), and has nothing to do with the RbtreeIterator | |
21160 | +# class above. | |
21161 | +class StdRbtreeIteratorPrinter: | |
21162 | + "Print std::map::iterator" | |
21163 | + | |
21164 | + def __init__ (self, val): | |
21165 | + self.val = val | |
21166 | + | |
21167 | + def to_string (self): | |
21168 | + valuetype = self.val.type().template_argument(0) | |
21169 | + nodetype = gdb.Type('std::_Rb_tree_node < %s >' % valuetype) | |
21170 | + nodetype = nodetype.pointer() | |
21171 | + return self.val.cast(nodetype).dereference()['_M_value_field'] | |
21172 | + | |
21173 | + | |
21174 | +class StdMapPrinter: | |
21175 | + "Print a std::map or std::multimap" | |
21176 | + | |
21177 | + # Turn an RbtreeIterator into a pretty-print iterator. | |
21178 | + class _iter: | |
21179 | + def __init__(self, rbiter, type): | |
21180 | + self.rbiter = rbiter | |
21181 | + self.count = 0 | |
21182 | + self.type = type | |
21183 | + | |
21184 | + def __iter__(self): | |
21185 | + return self | |
21186 | + | |
21187 | + def next(self): | |
21188 | + if self.count % 2 == 0: | |
21189 | + n = self.rbiter.next() | |
21190 | + n = n.cast(self.type).dereference()['_M_value_field'] | |
21191 | + self.pair = n | |
21192 | + item = n['first'] | |
21193 | + else: | |
21194 | + item = self.pair['second'] | |
21195 | + result = ('[%d]' % self.count, item) | |
21196 | + self.count = self.count + 1 | |
21197 | + return result | |
21198 | + | |
21199 | + def __init__ (self, typename, val): | |
21200 | + self.typename = typename | |
21201 | + self.val = val | |
21202 | + self.iter = RbtreeIterator (val) | |
21203 | + | |
21204 | + def to_string (self): | |
21205 | + return '%s with %d elements' % (self.typename, len (self.iter)) | |
21206 | + | |
21207 | + def children (self): | |
21208 | + keytype = self.val.type().template_argument(0).const() | |
21209 | + valuetype = self.val.type().template_argument(1) | |
21210 | + nodetype = gdb.Type('std::_Rb_tree_node< std::pair< %s, %s > >' % (keytype, valuetype)) | |
21211 | + nodetype = nodetype.pointer() | |
21212 | + return self._iter (self.iter, nodetype) | |
21213 | + | |
21214 | + def display_hint (self): | |
21215 | + return 'map' | |
21216 | + | |
21217 | +class StdSetPrinter: | |
21218 | + "Print a std::set or std::multiset" | |
21219 | + | |
21220 | + # Turn an RbtreeIterator into a pretty-print iterator. | |
21221 | + class _iter: | |
21222 | + def __init__(self, rbiter, type): | |
21223 | + self.rbiter = rbiter | |
21224 | + self.count = 0 | |
21225 | + self.type = type | |
21226 | + | |
21227 | + def __iter__(self): | |
21228 | + return self | |
21229 | + | |
21230 | + def next(self): | |
21231 | + item = self.rbiter.next() | |
21232 | + item = item.cast(self.type).dereference()['_M_value_field'] | |
21233 | + # FIXME: this is weird ... what to do? | |
21234 | + # Maybe a 'set' display hint? | |
21235 | + result = ('[%d]' % self.count, item) | |
21236 | + self.count = self.count + 1 | |
21237 | + return result | |
21238 | + | |
21239 | + def __init__ (self, typename, val): | |
21240 | + self.typename = typename | |
21241 | + self.val = val | |
21242 | + self.iter = RbtreeIterator (val) | |
21243 | + | |
21244 | + def to_string (self): | |
21245 | + return '%s with %d elements' % (self.typename, len (self.iter)) | |
21246 | + | |
21247 | + def children (self): | |
21248 | + keytype = self.val.type().template_argument(0) | |
21249 | + nodetype = gdb.Type('std::_Rb_tree_node< %s >' % keytype).pointer() | |
21250 | + return self._iter (self.iter, nodetype) | |
21251 | + | |
21252 | +class StdBitsetPrinter: | |
21253 | + "Print a std::bitset" | |
21254 | + | |
21255 | + def __init__(self, val): | |
21256 | + self.val = val | |
21257 | + | |
21258 | + def to_string (self): | |
21259 | + # If template_argument handled values, we could print the | |
21260 | + # size. Or we could use a regexp on the type. | |
21261 | + return 'std::bitset' | |
21262 | + | |
21263 | + def children (self): | |
21264 | + words = self.val['_M_w'] | |
21265 | + wtype = words.type() | |
21266 | + | |
21267 | + # The _M_w member can be either an unsigned long, or an | |
21268 | + # array. This depends on the template specialization used. | |
21269 | + # If it is a single long, convert to a single element list. | |
21270 | + if wtype.code () == gdb.TYPE_CODE_ARRAY: | |
21271 | + tsize = wtype.target ().sizeof () | |
21272 | + else: | |
21273 | + words = [words] | |
21274 | + tsize = wtype.sizeof () | |
21275 | + | |
21276 | + nwords = wtype.sizeof() / tsize | |
21277 | + result = [] | |
21278 | + byte = 0 | |
21279 | + while byte < nwords: | |
21280 | + w = words[byte] | |
21281 | + bit = 0 | |
21282 | + while w != 0: | |
21283 | + if (w & 1) != 0: | |
21284 | + # Another spot where we could use 'set'? | |
21285 | + result.append(('[%d]' % (byte * tsize * 8 + bit), 1)) | |
21286 | + bit = bit + 1 | |
21287 | + w = w >> 1 | |
21288 | + byte = byte + 1 | |
21289 | + return result | |
21290 | + | |
21291 | +class StdDequePrinter: | |
21292 | + "Print a std::deque" | |
21293 | + | |
21294 | + class _iter: | |
21295 | + def __init__(self, node, start, end, last, buffer_size): | |
21296 | + self.node = node | |
21297 | + self.p = start | |
21298 | + self.end = end | |
21299 | + self.last = last | |
21300 | + self.buffer_size = buffer_size | |
21301 | + self.count = 0 | |
21302 | + | |
21303 | + def __iter__(self): | |
21304 | + return self | |
21305 | + | |
21306 | + def next(self): | |
21307 | + if self.p == self.last: | |
21308 | + raise StopIteration | |
21309 | + | |
21310 | + result = ('[%d]' % self.count, self.p.dereference()) | |
21311 | + self.count = self.count + 1 | |
21312 | + | |
21313 | + # Advance the 'cur' pointer. | |
21314 | + self.p = self.p + 1 | |
21315 | + if self.p == self.end: | |
21316 | + # If we got to the end of this bucket, move to the | |
21317 | + # next bucket. | |
21318 | + self.node = self.node + 1 | |
21319 | + self.p = self.node[0] | |
21320 | + self.end = self.p + self.buffer_size | |
21321 | + | |
21322 | + return result | |
21323 | + | |
21324 | + def __init__(self, val): | |
21325 | + self.val = val | |
21326 | + self.elttype = val.type().template_argument(0) | |
21327 | + size = self.elttype.sizeof () | |
21328 | + if size < 512: | |
21329 | + self.buffer_size = int (512 / size) | |
21330 | + else: | |
21331 | + self.buffer_size = 1 | |
21332 | + | |
21333 | + def to_string(self): | |
21334 | + start = self.val['_M_impl']['_M_start'] | |
21335 | + end = self.val['_M_impl']['_M_finish'] | |
21336 | + | |
21337 | + delta_n = end['_M_node'] - start['_M_node'] - 1 | |
21338 | + delta_s = start['_M_last'] - start['_M_cur'] | |
21339 | + delta_e = end['_M_cur'] - end['_M_first'] | |
21340 | + | |
21341 | + size = self.buffer_size * delta_n + delta_s + delta_e | |
21342 | + | |
21343 | + return 'std::deque with %d elements' % long (size) | |
21344 | + | |
21345 | + def children(self): | |
21346 | + start = self.val['_M_impl']['_M_start'] | |
21347 | + end = self.val['_M_impl']['_M_finish'] | |
21348 | + return self._iter(start['_M_node'], start['_M_cur'], start['_M_last'], | |
21349 | + end['_M_cur'], self.buffer_size) | |
21350 | + | |
21351 | + def display_hint (self): | |
21352 | + return 'array' | |
21353 | + | |
21354 | +class StdDequeIteratorPrinter: | |
21355 | + "Print std::deque::iterator" | |
21356 | + | |
21357 | + def __init__(self, val): | |
21358 | + self.val = val | |
21359 | + | |
21360 | + def to_string(self): | |
21361 | + return self.val['_M_cur'].dereference() | |
21362 | + | |
21363 | +class WideEncoding (gdb.Parameter): | |
21364 | + """The target wide character set is the encoding used for wchar_t.""" | |
21365 | + | |
21366 | + set_doc = "Set the target wide character set." | |
21367 | + show_doc = "Show the target wide character set." | |
21368 | + | |
21369 | + # FIXME: needs a complete method -- but does Parameter support it? | |
21370 | + def __init__ (self): | |
21371 | + super (WideEncoding, self).__init__ ("target-wide-charset", | |
21372 | + gdb.COMMAND_SUPPORT, | |
21373 | + gdb.PARAM_STRING) | |
21374 | + # I think this is ok for most glibc locales. | |
21375 | + self.value = 'UTF-32' | |
21376 | + | |
21377 | +target_wide_charset = WideEncoding() | |
21378 | + | |
21379 | +class StdStringPrinter: | |
21380 | + "Print a std::basic_string of some kind" | |
21381 | + | |
21382 | + def __init__(self, encoding, val): | |
21383 | + self.encoding = encoding | |
21384 | + self.val = val | |
21385 | + | |
21386 | + def to_string(self): | |
21387 | + # Look up the target encoding as late as possible. | |
21388 | + encoding = self.encoding | |
21389 | + if encoding is None: | |
21390 | + encoding = gdb.parameter('target-charset') | |
21391 | + elif isinstance(encoding, WideEncoding): | |
21392 | + encoding = encoding.value | |
21393 | + return self.val['_M_dataplus']['_M_p'].string(encoding) | |
21394 | + | |
21395 | + def display_hint (self): | |
21396 | + return 'string' | |
21397 | + | |
21398 | +class Tr1HashtableIterator: | |
21399 | + def __init__ (self, hash): | |
21400 | + self.count = 0 | |
21401 | + self.n_buckets = hash['_M_element_count'] | |
21402 | + if self.n_buckets == 0: | |
21403 | + self.node = False | |
21404 | + else: | |
21405 | + self.bucket = hash['_M_buckets'] | |
21406 | + self.node = self.bucket[0] | |
21407 | + self.update () | |
21408 | + | |
21409 | + def __iter__ (self): | |
21410 | + return self | |
21411 | + | |
21412 | + def update (self): | |
21413 | + # If we advanced off the end of the chain, move to the next | |
21414 | + # bucket. | |
21415 | + while self.node == 0: | |
21416 | + self.bucket = self.bucket + 1 | |
21417 | + self.node = self.bucket[0] | |
21418 | + | |
21419 | + # If we advanced off the end of the bucket array, then | |
21420 | + # we're done. | |
21421 | + if self.count == self.n_buckets: | |
21422 | + self.node = False | |
21423 | + else: | |
21424 | + self.count = self.count + 1 | |
21425 | + | |
21426 | + def next (self): | |
21427 | + if not self.node: | |
21428 | + raise StopIteration | |
21429 | + result = self.node.dereference()['_M_v'] | |
21430 | + self.node = self.node.dereference()['_M_next'] | |
21431 | + self.update () | |
21432 | + return result | |
21433 | + | |
21434 | +class Tr1UnorderedSetPrinter: | |
21435 | + "Print a tr1::unordered_set" | |
21436 | + | |
21437 | + def __init__ (self, typename, val): | |
21438 | + self.typename = typename | |
21439 | + self.val = val | |
21440 | + | |
21441 | + def to_string (self): | |
21442 | + return '%s with %d elements' % (self.typename, self.val['_M_element_count']) | |
21443 | + | |
21444 | + @staticmethod | |
21445 | + def format_count (i): | |
21446 | + return '[%d]' % i | |
21447 | + | |
21448 | + def children (self): | |
21449 | + counter = itertools.imap (self.format_count, itertools.count()) | |
21450 | + return itertools.izip (counter, Tr1HashtableIterator (self.val)) | |
21451 | + | |
21452 | +class Tr1UnorderedMapPrinter: | |
21453 | + "Print a tr1::unordered_map" | |
21454 | + | |
21455 | + def __init__ (self, typename, val): | |
21456 | + self.typename = typename | |
21457 | + self.val = val | |
21458 | + | |
21459 | + def to_string (self): | |
21460 | + return '%s with %d elements' % (self.typename, self.val['_M_element_count']) | |
21461 | + | |
21462 | + @staticmethod | |
21463 | + def flatten (list): | |
21464 | + for elt in list: | |
21465 | + for i in elt: | |
21466 | + yield i | |
21467 | + | |
21468 | + @staticmethod | |
21469 | + def format_one (elt): | |
21470 | + return (elt['first'], elt['second']) | |
21471 | + | |
21472 | + @staticmethod | |
21473 | + def format_count (i): | |
21474 | + return '[%d]' % i | |
21475 | + | |
21476 | + def children (self): | |
21477 | + counter = itertools.imap (self.format_count, itertools.count()) | |
21478 | + # Map over the hash table and flatten the result. | |
21479 | + data = self.flatten (itertools.imap (self.format_one, Tr1HashtableIterator (self.val))) | |
21480 | + # Zip the two iterators together. | |
21481 | + return itertools.izip (counter, data) | |
21482 | + | |
21483 | + def display_hint (self): | |
21484 | + return 'map' | |
21485 | + | |
21486 | +def register_libstdcxx_printers (obj): | |
21487 | + "Register libstdc++ pretty-printers with objfile Obj." | |
21488 | + | |
21489 | + if obj == None: | |
21490 | + obj = gdb | |
21491 | + | |
21492 | + obj.pretty_printers.append (lookup_function) | |
21493 | + | |
21494 | +def lookup_function (val): | |
21495 | + "Look-up and return a pretty-printer that can print val." | |
21496 | + | |
21497 | + # Get the type. | |
21498 | + type = val.type (); | |
21499 | + | |
21500 | + # If it points to a reference, get the reference. | |
21501 | + if type.code () == gdb.TYPE_CODE_REF: | |
21502 | + type = type.target () | |
21503 | + | |
21504 | + # Get the unqualified type, stripped of typedefs. | |
21505 | + type = type.unqualified ().strip_typedefs () | |
21506 | + | |
21507 | + # Get the type name. | |
21508 | + typename = type.tag () | |
21509 | + if typename == None: | |
21510 | + return None | |
21511 | + | |
21512 | + # Iterate over local dictionary of types to determine | |
21513 | + # if a printer is registered for that type. Return an | |
21514 | + # instantiation of the printer if found. | |
21515 | + for function in pretty_printers_dict: | |
21516 | + if function.search (typename): | |
21517 | + return pretty_printers_dict[function] (val) | |
21518 | + | |
21519 | + # Cannot find a pretty printer. Return None. | |
21520 | + return None | |
21521 | + | |
21522 | +def build_libstdcxx_dictionary (): | |
21523 | + # libstdc++ objects requiring pretty-printing. | |
21524 | + # In order from: | |
21525 | + # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html | |
21526 | + pretty_printers_dict[re.compile('^std::basic_string<char,.*>$')] = lambda val: StdStringPrinter(None, val) | |
21527 | + pretty_printers_dict[re.compile('^std::basic_string<wchar_t,.*>$')] = lambda val: StdStringPrinter(target_wide_charset, val) | |
21528 | + pretty_printers_dict[re.compile('^std::basic_string<char16_t,.*>$')] = lambda val: StdStringPrinter('UTF-16', val) | |
21529 | + pretty_printers_dict[re.compile('^std::basic_string<char32_t,.*>$')] = lambda val: StdStringPrinter('UTF-32', val) | |
21530 | + pretty_printers_dict[re.compile('^std::bitset<.*>$')] = StdBitsetPrinter | |
21531 | + pretty_printers_dict[re.compile('^std::deque<.*>$')] = StdDequePrinter | |
21532 | + pretty_printers_dict[re.compile('^std::list<.*>$')] = StdListPrinter | |
21533 | + pretty_printers_dict[re.compile('^std::map<.*>$')] = lambda val: StdMapPrinter("std::map", val) | |
21534 | + pretty_printers_dict[re.compile('^std::multimap<.*>$')] = lambda val: StdMapPrinter("std::multimap", val) | |
21535 | + pretty_printers_dict[re.compile('^std::multiset<.*>$')] = lambda val: StdSetPrinter("std::multiset", val) | |
21536 | + pretty_printers_dict[re.compile('^std::priority_queue<.*>$')] = lambda val: StdStackOrQueuePrinter("std::priority_queue", val) | |
21537 | + pretty_printers_dict[re.compile('^std::queue<.*>$')] = lambda val: StdStackOrQueuePrinter("std::queue", val) | |
21538 | + pretty_printers_dict[re.compile('^std::set<.*>$')] = lambda val: StdSetPrinter("std::set", val) | |
21539 | + pretty_printers_dict[re.compile('^std::stack<.*>$')] = lambda val: StdStackOrQueuePrinter("std::stack", val) | |
21540 | + pretty_printers_dict[re.compile('^std::unique_ptr<.*>$')] = UniquePointerPrinter | |
21541 | + pretty_printers_dict[re.compile('^std::vector<.*>$')] = StdVectorPrinter | |
21542 | + # vector<bool> | |
21543 | + | |
21544 | + # These are the C++0x printers. They also exist in the standard namespace. | |
21545 | + # For array - the default GDB pretty-printer seems reasonable. | |
21546 | + pretty_printers_dict[re.compile('^std::(tr1::)?shared_ptr<.*>$')] = lambda val: StdPointerPrinter ('std::shared_ptr', val) | |
21547 | + pretty_printers_dict[re.compile('^std::(tr1::)?weak_ptr<.*>$')] = lambda val: StdPointerPrinter ('std::weak_ptr', val) | |
21548 | + pretty_printers_dict[re.compile('^std::(tr1::)?unordered_map<.*>$')] = lambda val: Tr1UnorderedMapPrinter ('std::tr1::unordered_map', val) | |
21549 | + pretty_printers_dict[re.compile('^std::(tr1::)?unordered_set<.*>$')] = lambda val: Tr1UnorderedSetPrinter ('std::tr1::unordered_set', val) | |
21550 | + pretty_printers_dict[re.compile('^std::(tr1::)?unordered_multimap<.*>$')] = lambda val: Tr1UnorderedMapPrinter ('std::tr1::unordered_multimap', val) | |
21551 | + pretty_printers_dict[re.compile('^std::(tr1::)?unordered_multiset<.*>$')] = lambda val: Tr1UnorderedSetPrinter ('std::tr1::unordered_multiset', val) | |
21552 | + | |
21553 | + | |
21554 | + # Extensions. | |
21555 | + pretty_printers_dict[re.compile('^__gnu_cxx::slist<.*>$')] = StdSlistPrinter | |
21556 | + | |
21557 | + if True: | |
21558 | + # These shouldn't be necessary, if GDB "print *i" worked. | |
21559 | + # But it often doesn't, so here they are. | |
21560 | + pretty_printers_dict[re.compile('^std::_List_iterator<.*>$')] = lambda val: StdListIteratorPrinter(val) | |
21561 | + pretty_printers_dict[re.compile('^std::_List_const_iterator<.*>$')] = lambda val: StdListIteratorPrinter(val) | |
21562 | + pretty_printers_dict[re.compile('^std::_Rb_tree_iterator<.*>$')] = lambda val: StdRbtreeIteratorPrinter(val) | |
21563 | + pretty_printers_dict[re.compile('^std::_Rb_tree_const_iterator<.*>$')] = lambda val: StdRbtreeIteratorPrinter(val) | |
21564 | + pretty_printers_dict[re.compile('^std::_Deque_iterator<.*>$')] = lambda val: StdDequeIteratorPrinter(val) | |
21565 | + pretty_printers_dict[re.compile('^std::_Deque_const_iterator<.*>$')] = lambda val: StdDequeIteratorPrinter(val) | |
21566 | + pretty_printers_dict[re.compile('^__gnu_cxx::__normal_iterator<.*>$')] = lambda val: StdVectorIteratorPrinter(val) | |
21567 | + pretty_printers_dict[re.compile('^__gnu_cxx::_Slist_iterator<.*>$')] = lambda val: StdSlistIteratorPrinter(val) | |
21568 | + | |
21569 | +pretty_printers_dict = {} | |
21570 | + | |
21571 | +build_libstdcxx_dictionary () | |
21572 | diff --git a/gdb/python/python-block.c b/gdb/python/python-block.c | |
21573 | new file mode 100644 | |
21574 | index 0000000..8019e9d | |
21575 | --- /dev/null | |
21576 | +++ b/gdb/python/python-block.c | |
21577 | @@ -0,0 +1,265 @@ | |
21578 | +/* Python interface to blocks. | |
21579 | + | |
21580 | + Copyright (C) 2008 Free Software Foundation, Inc. | |
21581 | + | |
21582 | + This file is part of GDB. | |
21583 | + | |
21584 | + This program is free software; you can redistribute it and/or modify | |
21585 | + it under the terms of the GNU General Public License as published by | |
21586 | + the Free Software Foundation; either version 3 of the License, or | |
21587 | + (at your option) any later version. | |
21588 | + | |
21589 | + This program is distributed in the hope that it will be useful, | |
21590 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21591 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21592 | + GNU General Public License for more details. | |
21593 | + | |
21594 | + You should have received a copy of the GNU General Public License | |
21595 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
21596 | + | |
21597 | +#include "defs.h" | |
21598 | +#include "block.h" | |
21599 | +#include "dictionary.h" | |
21600 | +#include "symtab.h" | |
21601 | +#include "python-internal.h" | |
21602 | + | |
21603 | +typedef struct { | |
21604 | + PyObject_HEAD | |
21605 | + struct block *block; | |
21606 | +} block_object; | |
21607 | + | |
21608 | +typedef struct { | |
21609 | + PyObject_HEAD | |
21610 | + struct dictionary *dict; | |
21611 | + struct dict_iterator iter; | |
21612 | + int initialized_p; | |
21613 | +} block_syms_iterator_object; | |
21614 | + | |
21615 | +static PyTypeObject block_syms_iterator_object_type; | |
21616 | + | |
21617 | +static PyObject * | |
21618 | +blpy_iter (PyObject *self) | |
21619 | +{ | |
21620 | + block_syms_iterator_object *block_iter_obj; | |
21621 | + | |
21622 | + block_iter_obj = PyObject_New (block_syms_iterator_object, | |
21623 | + &block_syms_iterator_object_type); | |
21624 | + if (block_iter_obj == NULL) | |
21625 | + { | |
21626 | + PyErr_SetString (PyExc_MemoryError, | |
21627 | + "Could not allocate iterator object."); | |
21628 | + return NULL; | |
21629 | + } | |
21630 | + | |
21631 | + block_iter_obj->dict = BLOCK_DICT (((block_object *) self)->block); | |
21632 | + block_iter_obj->initialized_p = 0; | |
21633 | + | |
21634 | + return (PyObject *) block_iter_obj; | |
21635 | +} | |
21636 | + | |
21637 | +static PyObject * | |
21638 | +blpy_get_start (PyObject *self, void *closure) | |
21639 | +{ | |
21640 | + block_object *self_block = (block_object *) self; | |
21641 | + | |
21642 | + return PyLong_FromUnsignedLongLong (BLOCK_START (self_block->block)); | |
21643 | +} | |
21644 | + | |
21645 | +static PyObject * | |
21646 | +blpy_get_end (PyObject *self, void *closure) | |
21647 | +{ | |
21648 | + block_object *self_block = (block_object *) self; | |
21649 | + | |
21650 | + return PyLong_FromUnsignedLongLong (BLOCK_END (self_block->block)); | |
21651 | +} | |
21652 | + | |
21653 | +static PyObject * | |
21654 | +blpy_get_function (PyObject *self, void *closure) | |
21655 | +{ | |
21656 | + block_object *self_block = (block_object *) self; | |
21657 | + struct symbol *sym; | |
21658 | + | |
21659 | + sym = BLOCK_FUNCTION (self_block->block); | |
21660 | + if (sym) | |
21661 | + return symbol_to_symbol_object (sym); | |
21662 | + | |
21663 | + Py_RETURN_NONE; | |
21664 | +} | |
21665 | + | |
21666 | +static PyObject * | |
21667 | +blpy_get_superblock (PyObject *self, void *closure) | |
21668 | +{ | |
21669 | + block_object *self_block = (block_object *) self; | |
21670 | + struct block *block; | |
21671 | + | |
21672 | + block = BLOCK_SUPERBLOCK (self_block->block); | |
21673 | + if (block) | |
21674 | + return block_to_block_object (block); | |
21675 | + | |
21676 | + Py_RETURN_NONE; | |
21677 | +} | |
21678 | + | |
21679 | +PyObject * | |
21680 | +block_to_block_object (struct block *block) | |
21681 | +{ | |
21682 | + block_object *block_obj; | |
21683 | + | |
21684 | + block_obj = PyObject_New (block_object, &block_object_type); | |
21685 | + if (block_obj == NULL) | |
21686 | + { | |
21687 | + PyErr_SetString (PyExc_MemoryError, "Could not allocate block object."); | |
21688 | + return NULL; | |
21689 | + } | |
21690 | + | |
21691 | + block_obj->block = block; | |
21692 | + | |
21693 | + return (PyObject *) block_obj; | |
21694 | +} | |
21695 | + | |
21696 | +struct block * | |
21697 | +block_object_to_block (PyObject *obj) | |
21698 | +{ | |
21699 | + if (! PyObject_TypeCheck (obj, &block_object_type)) | |
21700 | + return NULL; | |
21701 | + return ((block_object *) obj)->block; | |
21702 | +} | |
21703 | + | |
21704 | +static PyObject * | |
21705 | +blpy_block_syms_iter (PyObject *self) | |
21706 | +{ | |
21707 | + return self; | |
21708 | +} | |
21709 | + | |
21710 | +static PyObject * | |
21711 | +blpy_block_syms_iternext (PyObject *self) | |
21712 | +{ | |
21713 | + block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self; | |
21714 | + struct symbol *sym; | |
21715 | + | |
21716 | + if (!iter_obj->initialized_p) | |
21717 | + { | |
21718 | + sym = dict_iterator_first (iter_obj->dict, &(iter_obj->iter)); | |
21719 | + iter_obj->initialized_p = 1; | |
21720 | + } | |
21721 | + else | |
21722 | + sym = dict_iterator_next (&(iter_obj->iter)); | |
21723 | + | |
21724 | + return (sym == NULL)? NULL : symbol_to_symbol_object (sym); | |
21725 | +} | |
21726 | + | |
21727 | +/* Return the innermost lexical block containing the specified pc value, | |
21728 | + or 0 if there is none. */ | |
21729 | + | |
21730 | +PyObject * | |
21731 | +gdbpy_block_for_pc (PyObject *self, PyObject *args) | |
21732 | +{ | |
21733 | + unsigned PY_LONG_LONG pc; | |
21734 | + struct block *block; | |
21735 | + PyObject *sym_obj; | |
21736 | + | |
21737 | + if (!PyArg_ParseTuple (args, "K", &pc)) | |
21738 | + return NULL; | |
21739 | + | |
21740 | + block = block_for_pc (pc); | |
21741 | + if (block) | |
21742 | + return block_to_block_object (block); | |
21743 | + | |
21744 | + Py_RETURN_NONE; | |
21745 | +} | |
21746 | + | |
21747 | +void | |
21748 | +gdbpy_initialize_blocks (void) | |
21749 | +{ | |
21750 | + block_object_type.tp_new = PyType_GenericNew; | |
21751 | + if (PyType_Ready (&block_object_type) < 0) | |
21752 | + return; | |
21753 | + | |
21754 | + block_syms_iterator_object_type.tp_new = PyType_GenericNew; | |
21755 | + if (PyType_Ready (&block_syms_iterator_object_type) < 0) | |
21756 | + return; | |
21757 | + | |
21758 | + Py_INCREF (&block_object_type); | |
21759 | + PyModule_AddObject (gdb_module, "Block", (PyObject *) &block_object_type); | |
21760 | + | |
21761 | + Py_INCREF (&block_syms_iterator_object_type); | |
21762 | + PyModule_AddObject (gdb_module, "BlockIterator", | |
21763 | + (PyObject *) &block_syms_iterator_object_type); | |
21764 | +} | |
21765 | + | |
21766 | +\f | |
21767 | + | |
21768 | +static PyGetSetDef block_object_getset[] = { | |
21769 | + { "start", blpy_get_start, NULL, "Start address of the block.", NULL }, | |
21770 | + { "end", blpy_get_end, NULL, "End address of the block.", NULL }, | |
21771 | + { "function", blpy_get_function, NULL, | |
21772 | + "Symbol that names the block, or None.", NULL }, | |
21773 | + { "superblock", blpy_get_superblock, NULL, | |
21774 | + "Block containing the block, or None.", NULL }, | |
21775 | + { NULL } /* Sentinel */ | |
21776 | +}; | |
21777 | + | |
21778 | +PyTypeObject block_object_type = { | |
21779 | + PyObject_HEAD_INIT (NULL) | |
21780 | + 0, /*ob_size*/ | |
21781 | + "gdb.Block", /*tp_name*/ | |
21782 | + sizeof (block_object), /*tp_basicsize*/ | |
21783 | + 0, /*tp_itemsize*/ | |
21784 | + 0, /*tp_dealloc*/ | |
21785 | + 0, /*tp_print*/ | |
21786 | + 0, /*tp_getattr*/ | |
21787 | + 0, /*tp_setattr*/ | |
21788 | + 0, /*tp_compare*/ | |
21789 | + 0, /*tp_repr*/ | |
21790 | + 0, /*tp_as_number*/ | |
21791 | + 0, /*tp_as_sequence*/ | |
21792 | + 0, /*tp_as_mapping*/ | |
21793 | + 0, /*tp_hash */ | |
21794 | + 0, /*tp_call*/ | |
21795 | + 0, /*tp_str*/ | |
21796 | + 0, /*tp_getattro*/ | |
21797 | + 0, /*tp_setattro*/ | |
21798 | + 0, /*tp_as_buffer*/ | |
21799 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ | |
21800 | + "GDB block object", /* tp_doc */ | |
21801 | + 0, /* tp_traverse */ | |
21802 | + 0, /* tp_clear */ | |
21803 | + 0, /* tp_richcompare */ | |
21804 | + 0, /* tp_weaklistoffset */ | |
21805 | + blpy_iter, /* tp_iter */ | |
21806 | + 0, /* tp_iternext */ | |
21807 | + 0, /* tp_methods */ | |
21808 | + 0, /* tp_members */ | |
21809 | + block_object_getset /* tp_getset */ | |
21810 | +}; | |
21811 | + | |
21812 | +static PyTypeObject block_syms_iterator_object_type = { | |
21813 | + PyObject_HEAD_INIT (NULL) | |
21814 | + 0, /*ob_size*/ | |
21815 | + "gdb.BlockIterator", /*tp_name*/ | |
21816 | + sizeof (block_syms_iterator_object), /*tp_basicsize*/ | |
21817 | + 0, /*tp_itemsize*/ | |
21818 | + 0, /*tp_dealloc*/ | |
21819 | + 0, /*tp_print*/ | |
21820 | + 0, /*tp_getattr*/ | |
21821 | + 0, /*tp_setattr*/ | |
21822 | + 0, /*tp_compare*/ | |
21823 | + 0, /*tp_repr*/ | |
21824 | + 0, /*tp_as_number*/ | |
21825 | + 0, /*tp_as_sequence*/ | |
21826 | + 0, /*tp_as_mapping*/ | |
21827 | + 0, /*tp_hash */ | |
21828 | + 0, /*tp_call*/ | |
21829 | + 0, /*tp_str*/ | |
21830 | + 0, /*tp_getattro*/ | |
21831 | + 0, /*tp_setattro*/ | |
21832 | + 0, /*tp_as_buffer*/ | |
21833 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ | |
21834 | + "GDB block syms iterator object", /* tp_doc */ | |
21835 | + 0, /* tp_traverse */ | |
21836 | + 0, /* tp_clear */ | |
21837 | + 0, /* tp_richcompare */ | |
21838 | + 0, /* tp_weaklistoffset */ | |
21839 | + blpy_block_syms_iter, /* tp_iter */ | |
21840 | + blpy_block_syms_iternext, /* tp_iternext */ | |
21841 | + 0 /* tp_methods */ | |
21842 | +}; | |
21843 | diff --git a/gdb/python/python-breakpoint.c b/gdb/python/python-breakpoint.c | |
21844 | new file mode 100644 | |
21845 | index 0000000..ec80419 | |
21846 | --- /dev/null | |
21847 | +++ b/gdb/python/python-breakpoint.c | |
21848 | @@ -0,0 +1,665 @@ | |
21849 | +/* Python interface to breakpoints | |
21850 | + | |
21851 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
21852 | + | |
21853 | + This file is part of GDB. | |
21854 | + | |
21855 | + This program is free software; you can redistribute it and/or modify | |
21856 | + it under the terms of the GNU General Public License as published by | |
21857 | + the Free Software Foundation; either version 3 of the License, or | |
21858 | + (at your option) any later version. | |
21859 | + | |
21860 | + This program is distributed in the hope that it will be useful, | |
21861 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21862 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21863 | + GNU General Public License for more details. | |
21864 | + | |
21865 | + You should have received a copy of the GNU General Public License | |
21866 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
21867 | + | |
21868 | +#include "defs.h" | |
21869 | +#include "value.h" | |
21870 | +#include "exceptions.h" | |
21871 | +#include "python-internal.h" | |
21872 | +#include "charset.h" | |
21873 | +#include "breakpoint.h" | |
21874 | +#include "gdbcmd.h" | |
21875 | +#include "gdbthread.h" | |
21876 | +#include "observer.h" | |
21877 | + | |
21878 | + | |
21879 | +/* From breakpoint.c. */ | |
21880 | +extern struct breakpoint *breakpoint_chain; | |
21881 | + | |
21882 | + | |
21883 | +typedef struct breakpoint_object breakpoint_object; | |
21884 | + | |
21885 | +static PyTypeObject breakpoint_object_type; | |
21886 | + | |
21887 | +/* A dynamically allocated vector of breakpoint objects. Each | |
21888 | + breakpoint has a number. A breakpoint is valid if its slot in this | |
21889 | + vector is non-null. When a breakpoint is deleted, we drop our | |
21890 | + reference to it and zero its slot; this is how we let the Python | |
21891 | + object have a lifetime which is independent from that of the gdb | |
21892 | + breakpoint. */ | |
21893 | +static breakpoint_object **bppy_breakpoints; | |
21894 | + | |
21895 | +/* Number of slots in bppy_breakpoints. */ | |
21896 | +static int bppy_slots; | |
21897 | + | |
21898 | +/* Number of live breakpoints. */ | |
21899 | +static int bppy_live; | |
21900 | + | |
21901 | +/* Variables used to pass information between the Breakpoint | |
21902 | + constructor and the breakpoint-created hook function. */ | |
21903 | +static breakpoint_object *bppy_pending_object; | |
21904 | + | |
21905 | +struct breakpoint_object | |
21906 | +{ | |
21907 | + PyObject_HEAD | |
21908 | + | |
21909 | + /* The breakpoint number according to gdb. */ | |
21910 | + int number; | |
21911 | + | |
21912 | + /* The gdb breakpoint object, or NULL if the breakpoint has been | |
21913 | + deleted. */ | |
21914 | + struct breakpoint *bp; | |
21915 | +}; | |
21916 | + | |
21917 | +/* Evaluate to true if the breakpoint NUM is valid, false otherwise. */ | |
21918 | +#define BPPY_VALID_P(Num) \ | |
21919 | + ((Num) >= 0 \ | |
21920 | + && (Num) < bppy_slots \ | |
21921 | + && bppy_breakpoints[Num] != NULL) | |
21922 | + | |
21923 | +/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python | |
21924 | + exception if it is invalid. */ | |
21925 | +#define BPPY_REQUIRE_VALID(Breakpoint) \ | |
21926 | + do { \ | |
21927 | + if (! BPPY_VALID_P ((Breakpoint)->number)) \ | |
21928 | + return PyErr_Format (PyExc_RuntimeError, "breakpoint %d is invalid", \ | |
21929 | + (Breakpoint)->number); \ | |
21930 | + } while (0) | |
21931 | + | |
21932 | +/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python | |
21933 | + exception if it is invalid. This macro is for use in setter functions. */ | |
21934 | +#define BPPY_SET_REQUIRE_VALID(Breakpoint) \ | |
21935 | + do { \ | |
21936 | + if (! BPPY_VALID_P ((Breakpoint)->number)) \ | |
21937 | + { \ | |
21938 | + PyErr_Format (PyExc_RuntimeError, "breakpoint %d is invalid", \ | |
21939 | + (Breakpoint)->number); \ | |
21940 | + return -1; \ | |
21941 | + } \ | |
21942 | + } while (0) | |
21943 | + | |
21944 | +/* Python function which checks the validity of a breakpoint object. */ | |
21945 | +static PyObject * | |
21946 | +bppy_is_valid (PyObject *self, PyObject *args) | |
21947 | +{ | |
21948 | + if (((breakpoint_object *) self)->bp) | |
21949 | + Py_RETURN_TRUE; | |
21950 | + Py_RETURN_FALSE; | |
21951 | +} | |
21952 | + | |
21953 | +/* Python function to test whether or not the breakpoint is enabled. */ | |
21954 | +static PyObject * | |
21955 | +bppy_get_enabled (PyObject *self, void *closure) | |
21956 | +{ | |
21957 | + if (! ((breakpoint_object *) self)->bp) | |
21958 | + Py_RETURN_FALSE; | |
21959 | + /* Not clear what we really want here. */ | |
21960 | + if (((breakpoint_object *) self)->bp->enable_state == bp_enabled) | |
21961 | + Py_RETURN_TRUE; | |
21962 | + Py_RETURN_FALSE; | |
21963 | +} | |
21964 | + | |
21965 | +/* Python function to test whether or not the breakpoint is silent. */ | |
21966 | +static PyObject * | |
21967 | +bppy_get_silent (PyObject *self, void *closure) | |
21968 | +{ | |
21969 | + BPPY_REQUIRE_VALID ((breakpoint_object *) self); | |
21970 | + if (((breakpoint_object *) self)->bp->silent) | |
21971 | + Py_RETURN_TRUE; | |
21972 | + Py_RETURN_FALSE; | |
21973 | +} | |
21974 | + | |
21975 | +/* Python function to set the enabled state of a breakpoint. */ | |
21976 | +static int | |
21977 | +bppy_set_enabled (PyObject *self, PyObject *newvalue, void *closure) | |
21978 | +{ | |
21979 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
21980 | + int cmp; | |
21981 | + | |
21982 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
21983 | + | |
21984 | + if (newvalue == NULL) | |
21985 | + { | |
21986 | + PyErr_SetString (PyExc_TypeError, "cannot delete `enabled' attribute"); | |
21987 | + return -1; | |
21988 | + } | |
21989 | + else if (! PyBool_Check (newvalue)) | |
21990 | + { | |
21991 | + PyErr_SetString (PyExc_TypeError, | |
21992 | + "the value of `enabled' must be a boolean"); | |
21993 | + return -1; | |
21994 | + } | |
21995 | + | |
21996 | + cmp = PyObject_IsTrue (newvalue); | |
21997 | + if (cmp < 0) | |
21998 | + return -1; | |
21999 | + else if (cmp == 1) | |
22000 | + enable_breakpoint (self_bp->bp); | |
22001 | + else | |
22002 | + disable_breakpoint (self_bp->bp); | |
22003 | + return 0; | |
22004 | +} | |
22005 | + | |
22006 | +/* Python function to set the 'silent' state of a breakpoint. */ | |
22007 | +static int | |
22008 | +bppy_set_silent (PyObject *self, PyObject *newvalue, void *closure) | |
22009 | +{ | |
22010 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
22011 | + int cmp; | |
22012 | + | |
22013 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
22014 | + | |
22015 | + if (newvalue == NULL) | |
22016 | + { | |
22017 | + PyErr_SetString (PyExc_TypeError, "cannot delete `silent' attribute"); | |
22018 | + return -1; | |
22019 | + } | |
22020 | + else if (! PyBool_Check (newvalue)) | |
22021 | + { | |
22022 | + PyErr_SetString (PyExc_TypeError, | |
22023 | + "the value of `silent' must be a boolean"); | |
22024 | + return -1; | |
22025 | + } | |
22026 | + | |
22027 | + cmp = PyObject_IsTrue (newvalue); | |
22028 | + if (cmp < 0) | |
22029 | + return -1; | |
22030 | + else | |
22031 | + self_bp->bp->silent = cmp; | |
22032 | + | |
22033 | + return 0; | |
22034 | +} | |
22035 | + | |
22036 | +/* Python function to set the thread of a breakpoint. */ | |
22037 | +static int | |
22038 | +bppy_set_thread (PyObject *self, PyObject *newvalue, void *closure) | |
22039 | +{ | |
22040 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
22041 | + int id; | |
22042 | + | |
22043 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
22044 | + | |
22045 | + if (newvalue == NULL) | |
22046 | + { | |
22047 | + PyErr_SetString (PyExc_TypeError, "cannot delete `thread' attribute"); | |
22048 | + return -1; | |
22049 | + } | |
22050 | + else if (PyInt_Check (newvalue)) | |
22051 | + { | |
22052 | + id = (int) PyInt_AsLong (newvalue); | |
22053 | + if (! valid_thread_id (id)) | |
22054 | + { | |
22055 | + PyErr_SetString (PyExc_RuntimeError, "invalid thread id"); | |
22056 | + return -1; | |
22057 | + } | |
22058 | + } | |
22059 | + else if (newvalue == Py_None) | |
22060 | + id = -1; | |
22061 | + else | |
22062 | + { | |
22063 | + PyErr_SetString (PyExc_TypeError, | |
22064 | + "the value of `thread' must be an integer or None"); | |
22065 | + return -1; | |
22066 | + } | |
22067 | + | |
22068 | + self_bp->bp->thread = id; | |
22069 | + | |
22070 | + return 0; | |
22071 | +} | |
22072 | + | |
22073 | +/* Python function to set the ignore count of a breakpoint. */ | |
22074 | +static int | |
22075 | +bppy_set_ignore_count (PyObject *self, PyObject *newvalue, void *closure) | |
22076 | +{ | |
22077 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
22078 | + long value; | |
22079 | + | |
22080 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
22081 | + | |
22082 | + if (newvalue == NULL) | |
22083 | + { | |
22084 | + PyErr_SetString (PyExc_TypeError, | |
22085 | + "cannot delete `ignore_count' attribute"); | |
22086 | + return -1; | |
22087 | + } | |
22088 | + else if (! PyInt_Check (newvalue)) | |
22089 | + { | |
22090 | + PyErr_SetString (PyExc_TypeError, | |
22091 | + "the value of `ignore_count' must be an integer"); | |
22092 | + return -1; | |
22093 | + } | |
22094 | + | |
22095 | + value = PyInt_AsLong (newvalue); | |
22096 | + if (value < 0) | |
22097 | + value = 0; | |
22098 | + set_ignore_count (self_bp->number, (int) value, 0); | |
22099 | + | |
22100 | + return 0; | |
22101 | +} | |
22102 | + | |
22103 | +/* Python function to set the hit count of a breakpoint. */ | |
22104 | +static int | |
22105 | +bppy_set_hit_count (PyObject *self, PyObject *newvalue, void *closure) | |
22106 | +{ | |
22107 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
22108 | + | |
22109 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
22110 | + | |
22111 | + if (newvalue == NULL) | |
22112 | + { | |
22113 | + PyErr_SetString (PyExc_TypeError, "cannot delete `hit_count' attribute"); | |
22114 | + return -1; | |
22115 | + } | |
22116 | + else if (! PyInt_Check (newvalue) || PyInt_AsLong (newvalue) != 0) | |
22117 | + { | |
22118 | + PyErr_SetString (PyExc_AttributeError, | |
22119 | + "the value of `hit_count' must be zero"); | |
22120 | + return -1; | |
22121 | + } | |
22122 | + | |
22123 | + self_bp->bp->hit_count = 0; | |
22124 | + | |
22125 | + return 0; | |
22126 | +} | |
22127 | + | |
22128 | +/* Python function to get the location of a breakpoint. */ | |
22129 | +static PyObject * | |
22130 | +bppy_get_location (PyObject *self, void *closure) | |
22131 | +{ | |
22132 | + char *str; | |
22133 | + | |
22134 | + BPPY_REQUIRE_VALID ((breakpoint_object *) self); | |
22135 | + str = ((breakpoint_object *) self)->bp->addr_string; | |
22136 | + /* FIXME: watchpoints? tracepoints? */ | |
22137 | + if (! str) | |
22138 | + str = ""; | |
22139 | + return PyString_Decode (str, strlen (str), host_charset (), NULL); | |
22140 | +} | |
22141 | + | |
22142 | +/* Python function to get the condition expression of a breakpoint. */ | |
22143 | +static PyObject * | |
22144 | +bppy_get_condition (PyObject *self, void *closure) | |
22145 | +{ | |
22146 | + char *str; | |
22147 | + BPPY_REQUIRE_VALID ((breakpoint_object *) self); | |
22148 | + | |
22149 | + str = ((breakpoint_object *) self)->bp->cond_string; | |
22150 | + if (! str) | |
22151 | + Py_RETURN_NONE; | |
22152 | + return PyString_Decode (str, strlen (str), host_charset (), NULL); | |
22153 | +} | |
22154 | + | |
22155 | +static int | |
22156 | +bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure) | |
22157 | +{ | |
22158 | + char *exp; | |
22159 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
22160 | + volatile struct gdb_exception except; | |
22161 | + | |
22162 | + BPPY_SET_REQUIRE_VALID (self_bp); | |
22163 | + | |
22164 | + if (newvalue == NULL) | |
22165 | + { | |
22166 | + PyErr_SetString (PyExc_TypeError, "cannot delete `condition' attribute"); | |
22167 | + return -1; | |
22168 | + } | |
22169 | + else if (newvalue == Py_None) | |
22170 | + exp = ""; | |
22171 | + else | |
22172 | + { | |
22173 | + exp = python_string_to_host_string (newvalue); | |
22174 | + if (exp == NULL) | |
22175 | + return -1; | |
22176 | + } | |
22177 | + | |
22178 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22179 | + { | |
22180 | + set_breakpoint_condition (self_bp->bp, exp, 0); | |
22181 | + } | |
22182 | + GDB_PY_SET_HANDLE_EXCEPTION (except); | |
22183 | + | |
22184 | + return 0; | |
22185 | +} | |
22186 | + | |
22187 | +/* Python function to get the commands attached to a breakpoint. */ | |
22188 | +static PyObject * | |
22189 | +bppy_get_commands (PyObject *self, void *closure) | |
22190 | +{ | |
22191 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
22192 | + long length; | |
22193 | + volatile struct gdb_exception except; | |
22194 | + struct ui_file *string_file; | |
22195 | + struct cleanup *chain; | |
22196 | + PyObject *result; | |
22197 | + char *cmdstr; | |
22198 | + | |
22199 | + BPPY_REQUIRE_VALID (self_bp); | |
22200 | + | |
22201 | + if (! self_bp->bp->commands) | |
22202 | + Py_RETURN_NONE; | |
22203 | + | |
22204 | + string_file = mem_fileopen (); | |
22205 | + chain = make_cleanup_ui_file_delete (string_file); | |
22206 | + | |
22207 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22208 | + { | |
22209 | + /* FIXME: this can fail. Maybe we need to be making a new | |
22210 | + ui_out object here? */ | |
22211 | + ui_out_redirect (uiout, string_file); | |
22212 | + print_command_lines (uiout, self_bp->bp->commands, 0); | |
22213 | + ui_out_redirect (uiout, NULL); | |
22214 | + } | |
22215 | + cmdstr = ui_file_xstrdup (string_file, &length); | |
22216 | + GDB_PY_HANDLE_EXCEPTION (except); | |
22217 | + | |
22218 | + result = PyString_Decode (cmdstr, strlen (cmdstr), host_charset (), NULL); | |
22219 | + do_cleanups (chain); | |
22220 | + xfree (cmdstr); | |
22221 | + return result; | |
22222 | +} | |
22223 | + | |
22224 | +/* Python function to get the breakpoint's number. */ | |
22225 | +static PyObject * | |
22226 | +bppy_get_number (PyObject *self, void *closure) | |
22227 | +{ | |
22228 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
22229 | + | |
22230 | + BPPY_REQUIRE_VALID (self_bp); | |
22231 | + | |
22232 | + return PyInt_FromLong (self_bp->number); | |
22233 | +} | |
22234 | + | |
22235 | +/* Python function to get the breakpoint's thread ID. */ | |
22236 | +static PyObject * | |
22237 | +bppy_get_thread (PyObject *self, void *closure) | |
22238 | +{ | |
22239 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
22240 | + | |
22241 | + BPPY_REQUIRE_VALID (self_bp); | |
22242 | + | |
22243 | + if (self_bp->bp->thread == -1) | |
22244 | + Py_RETURN_NONE; | |
22245 | + | |
22246 | + return PyInt_FromLong (self_bp->bp->thread); | |
22247 | +} | |
22248 | + | |
22249 | +/* Python function to get the breakpoint's hit count. */ | |
22250 | +static PyObject * | |
22251 | +bppy_get_hit_count (PyObject *self, void *closure) | |
22252 | +{ | |
22253 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
22254 | + | |
22255 | + BPPY_REQUIRE_VALID (self_bp); | |
22256 | + | |
22257 | + return PyInt_FromLong (self_bp->bp->hit_count); | |
22258 | +} | |
22259 | + | |
22260 | +/* Python function to get the breakpoint's ignore count. */ | |
22261 | +static PyObject * | |
22262 | +bppy_get_ignore_count (PyObject *self, void *closure) | |
22263 | +{ | |
22264 | + breakpoint_object *self_bp = (breakpoint_object *) self; | |
22265 | + | |
22266 | + BPPY_REQUIRE_VALID (self_bp); | |
22267 | + | |
22268 | + return PyInt_FromLong (self_bp->bp->ignore_count); | |
22269 | +} | |
22270 | + | |
22271 | +/* Python function to create a new breakpoint. */ | |
22272 | +static PyObject * | |
22273 | +bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs) | |
22274 | +{ | |
22275 | + PyObject *result; | |
22276 | + char *spec; | |
22277 | + volatile struct gdb_exception except; | |
22278 | + | |
22279 | + /* FIXME: allow condition, thread, temporary, ... ? */ | |
22280 | + if (! PyArg_ParseTuple (args, "s", &spec)) | |
22281 | + return NULL; | |
22282 | + result = subtype->tp_alloc (subtype, 0); | |
22283 | + if (! result) | |
22284 | + return NULL; | |
22285 | + bppy_pending_object = (breakpoint_object *) result; | |
22286 | + bppy_pending_object->number = -1; | |
22287 | + bppy_pending_object->bp = NULL; | |
22288 | + | |
22289 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22290 | + { | |
22291 | + set_breakpoint (spec, NULL, 0, 0, -1, 0, AUTO_BOOLEAN_TRUE, | |
22292 | + 1 /*enabled*/); | |
22293 | + } | |
22294 | + if (except.reason < 0) | |
22295 | + { | |
22296 | + subtype->tp_free (result); | |
22297 | + return PyErr_Format (except.reason == RETURN_QUIT | |
22298 | + ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, | |
22299 | + "%s", except.message); | |
22300 | + } | |
22301 | + | |
22302 | + BPPY_REQUIRE_VALID ((breakpoint_object *) result); | |
22303 | + return result; | |
22304 | +} | |
22305 | + | |
22306 | +\f | |
22307 | + | |
22308 | +/* Static function to return a tuple holding all breakpoints. */ | |
22309 | + | |
22310 | +PyObject * | |
22311 | +gdbpy_breakpoints (PyObject *self, PyObject *args) | |
22312 | +{ | |
22313 | + PyObject *result; | |
22314 | + | |
22315 | + if (bppy_live == 0) | |
22316 | + Py_RETURN_NONE; | |
22317 | + | |
22318 | + result = PyTuple_New (bppy_live); | |
22319 | + if (result) | |
22320 | + { | |
22321 | + int i, out = 0; | |
22322 | + for (i = 0; out < bppy_live; ++i) | |
22323 | + { | |
22324 | + if (! bppy_breakpoints[i]) | |
22325 | + continue; | |
22326 | + Py_INCREF (bppy_breakpoints[i]); | |
22327 | + PyTuple_SetItem (result, out, (PyObject *) bppy_breakpoints[i]); | |
22328 | + ++out; | |
22329 | + } | |
22330 | + } | |
22331 | + return result; | |
22332 | +} | |
22333 | + | |
22334 | +\f | |
22335 | + | |
22336 | +/* Event callback functions. */ | |
22337 | + | |
22338 | +/* Callback that is used when a breakpoint is created. This function | |
22339 | + will create a new Python breakpoint object. */ | |
22340 | +static void | |
22341 | +gdbpy_breakpoint_created (int num) | |
22342 | +{ | |
22343 | + breakpoint_object *newbp; | |
22344 | + struct breakpoint *bp; | |
22345 | + PyGILState_STATE state; | |
22346 | + | |
22347 | + if (num < 0) | |
22348 | + return; | |
22349 | + | |
22350 | + for (bp = breakpoint_chain; bp; bp = bp->next) | |
22351 | + if (bp->number == num) | |
22352 | + break; | |
22353 | + if (! bp) | |
22354 | + return; | |
22355 | + | |
22356 | + if (num >= bppy_slots) | |
22357 | + { | |
22358 | + int old = bppy_slots; | |
22359 | + bppy_slots = bppy_slots * 2 + 10; | |
22360 | + bppy_breakpoints | |
22361 | + = (breakpoint_object **) xrealloc (bppy_breakpoints, | |
22362 | + (bppy_slots | |
22363 | + * sizeof (breakpoint_object *))); | |
22364 | + memset (&bppy_breakpoints[old], 0, | |
22365 | + (bppy_slots - old) * sizeof (PyObject *)); | |
22366 | + } | |
22367 | + | |
22368 | + ++bppy_live; | |
22369 | + | |
22370 | + state = PyGILState_Ensure (); | |
22371 | + | |
22372 | + if (bppy_pending_object) | |
22373 | + { | |
22374 | + newbp = bppy_pending_object; | |
22375 | + bppy_pending_object = NULL; | |
22376 | + } | |
22377 | + else | |
22378 | + newbp = PyObject_New (breakpoint_object, &breakpoint_object_type); | |
22379 | + if (newbp) | |
22380 | + { | |
22381 | + PyObject *hookfn; | |
22382 | + | |
22383 | + newbp->number = num; | |
22384 | + newbp->bp = bp; | |
22385 | + bppy_breakpoints[num] = newbp; | |
22386 | + | |
22387 | + hookfn = gdbpy_get_hook_function ("new_breakpoint"); | |
22388 | + if (hookfn) | |
22389 | + { | |
22390 | + PyObject *result; | |
22391 | + result = PyObject_CallFunctionObjArgs (hookfn, newbp, NULL); | |
22392 | + if (result) | |
22393 | + { | |
22394 | + Py_DECREF (result); | |
22395 | + } | |
22396 | + Py_DECREF (hookfn); | |
22397 | + } | |
22398 | + } | |
22399 | + | |
22400 | + /* Just ignore errors here. */ | |
22401 | + PyErr_Clear (); | |
22402 | + | |
22403 | + PyGILState_Release (state); | |
22404 | +} | |
22405 | + | |
22406 | +/* Callback that is used when a breakpoint is deleted. This will | |
22407 | + invalidate the corresponding Python object. */ | |
22408 | +static void | |
22409 | +gdbpy_breakpoint_deleted (int num) | |
22410 | +{ | |
22411 | + PyGILState_STATE state; | |
22412 | + | |
22413 | + state = PyGILState_Ensure (); | |
22414 | + if (BPPY_VALID_P (num)) | |
22415 | + { | |
22416 | + bppy_breakpoints[num]->bp = NULL; | |
22417 | + Py_DECREF (bppy_breakpoints[num]); | |
22418 | + bppy_breakpoints[num] = NULL; | |
22419 | + --bppy_live; | |
22420 | + } | |
22421 | + PyGILState_Release (state); | |
22422 | +} | |
22423 | + | |
22424 | +\f | |
22425 | + | |
22426 | +/* Initialize the Python breakpoint code. */ | |
22427 | +void | |
22428 | +gdbpy_initialize_breakpoints (void) | |
22429 | +{ | |
22430 | + breakpoint_object_type.tp_new = bppy_new; | |
22431 | + if (PyType_Ready (&breakpoint_object_type) < 0) | |
22432 | + return; | |
22433 | + | |
22434 | + Py_INCREF (&breakpoint_object_type); | |
22435 | + PyModule_AddObject (gdb_module, "Breakpoint", | |
22436 | + (PyObject *) &breakpoint_object_type); | |
22437 | + | |
22438 | + observer_attach_breakpoint_created (gdbpy_breakpoint_created); | |
22439 | + observer_attach_breakpoint_deleted (gdbpy_breakpoint_deleted); | |
22440 | +} | |
22441 | + | |
22442 | +\f | |
22443 | + | |
22444 | +static PyGetSetDef breakpoint_object_getset[] = { | |
22445 | + { "enabled", bppy_get_enabled, bppy_set_enabled, | |
22446 | + "Boolean telling whether the breakpoint is enabled.", NULL }, | |
22447 | + { "silent", bppy_get_silent, bppy_set_silent, | |
22448 | + "Boolean telling whether the breakpoint is silent.", NULL }, | |
22449 | + { "thread", bppy_get_thread, bppy_set_thread, | |
22450 | + "Thread ID for the breakpoint.\n\ | |
22451 | +If the value is a thread ID (integer), then this is a thread-specific breakpoint.\n\ | |
22452 | +If the value is None, then this breakpoint not thread-specific.\n\ | |
22453 | +No other type of value can be used.", NULL }, | |
22454 | + { "ignore_count", bppy_get_ignore_count, bppy_set_ignore_count, | |
22455 | + "Number of times this breakpoint should be automatically continued.", | |
22456 | + NULL }, | |
22457 | + { "number", bppy_get_number, NULL, | |
22458 | + "Breakpoint's number assigned by GDB.", NULL }, | |
22459 | + { "hit_count", bppy_get_hit_count, bppy_set_hit_count, | |
22460 | + "Number of times the breakpoint has been hit.\n\ | |
22461 | +Can be set to zero to clear the count. No other value is valid\n\ | |
22462 | +when setting this property.", NULL }, | |
22463 | + { "location", bppy_get_location, NULL, | |
22464 | + "Location of the breakpoint, as specified by the user.", NULL}, | |
22465 | + { "condition", bppy_get_condition, bppy_set_condition, | |
22466 | + "Condition of the breakpoint, as specified by the user,\ | |
22467 | +or None if no condition set."}, | |
22468 | + { "commands", bppy_get_commands, NULL, | |
22469 | + "Commands of the breakpoint, as specified by the user."}, | |
22470 | + { NULL } /* Sentinel. */ | |
22471 | +}; | |
22472 | + | |
22473 | +static PyMethodDef breakpoint_object_methods[] = | |
22474 | +{ | |
22475 | + { "is_valid", bppy_is_valid, METH_NOARGS, | |
22476 | + "Return true if this breakpoint is valid, false if not." }, | |
22477 | + { NULL } /* Sentinel. */ | |
22478 | +}; | |
22479 | + | |
22480 | +static PyTypeObject breakpoint_object_type = | |
22481 | +{ | |
22482 | + PyObject_HEAD_INIT (NULL) | |
22483 | + 0, /*ob_size*/ | |
22484 | + "gdb.Breakpoint", /*tp_name*/ | |
22485 | + sizeof (breakpoint_object), /*tp_basicsize*/ | |
22486 | + 0, /*tp_itemsize*/ | |
22487 | + 0, /*tp_dealloc*/ | |
22488 | + 0, /*tp_print*/ | |
22489 | + 0, /*tp_getattr*/ | |
22490 | + 0, /*tp_setattr*/ | |
22491 | + 0, /*tp_compare*/ | |
22492 | + 0, /*tp_repr*/ | |
22493 | + 0, /*tp_as_number*/ | |
22494 | + 0, /*tp_as_sequence*/ | |
22495 | + 0, /*tp_as_mapping*/ | |
22496 | + 0, /*tp_hash */ | |
22497 | + 0, /*tp_call*/ | |
22498 | + 0, /*tp_str*/ | |
22499 | + 0, /*tp_getattro*/ | |
22500 | + 0, /*tp_setattro*/ | |
22501 | + 0, /*tp_as_buffer*/ | |
22502 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
22503 | + "GDB breakpoint object", /* tp_doc */ | |
22504 | + 0, /* tp_traverse */ | |
22505 | + 0, /* tp_clear */ | |
22506 | + 0, /* tp_richcompare */ | |
22507 | + 0, /* tp_weaklistoffset */ | |
22508 | + 0, /* tp_iter */ | |
22509 | + 0, /* tp_iternext */ | |
22510 | + breakpoint_object_methods, /* tp_methods */ | |
22511 | + 0, /* tp_members */ | |
22512 | + breakpoint_object_getset /* tp_getset */ | |
22513 | +}; | |
22514 | diff --git a/gdb/python/python-cmd.c b/gdb/python/python-cmd.c | |
22515 | index 36cde34..e6e3ac0 100644 | |
22516 | --- a/gdb/python/python-cmd.c | |
22517 | +++ b/gdb/python/python-cmd.c | |
22518 | @@ -47,8 +47,7 @@ static struct cmdpy_completer completers[] = | |
22519 | ||
22520 | #define N_COMPLETERS (sizeof (completers) / sizeof (completers[0])) | |
22521 | ||
22522 | -/* A gdb command. For the time being only ordinary commands (not | |
22523 | - set/show commands) are allowed. */ | |
22524 | +/* A gdb command. */ | |
22525 | struct cmdpy_object | |
22526 | { | |
22527 | PyObject_HEAD | |
22528 | @@ -68,7 +67,6 @@ typedef struct cmdpy_object cmdpy_object; | |
22529 | ||
22530 | static PyTypeObject cmdpy_object_type; | |
22531 | ||
22532 | - | |
22533 | /* Constants used by this module. */ | |
22534 | static PyObject *invoke_cst; | |
22535 | static PyObject *complete_cst; | |
22536 | @@ -265,10 +263,13 @@ cmdpy_completer (struct cmd_list_element *command, char *text, char *word) | |
22537 | *BASE_LIST is set to the final prefix command's list of | |
22538 | *sub-commands. | |
22539 | ||
22540 | + START_LIST is the list in which the search starts. | |
22541 | + | |
22542 | This function returns the xmalloc()d name of the new command. On | |
22543 | error sets the Python error and returns NULL. */ | |
22544 | -static char * | |
22545 | -parse_command_name (char *text, struct cmd_list_element ***base_list) | |
22546 | +char * | |
22547 | +gdbpy_parse_command_name (char *text, struct cmd_list_element ***base_list, | |
22548 | + struct cmd_list_element **start_list) | |
22549 | { | |
22550 | struct cmd_list_element *elt; | |
22551 | int len = strlen (text); | |
22552 | @@ -301,7 +302,7 @@ parse_command_name (char *text, struct cmd_list_element ***base_list) | |
22553 | ; | |
22554 | if (i < 0) | |
22555 | { | |
22556 | - *base_list = &cmdlist; | |
22557 | + *base_list = start_list; | |
22558 | return result; | |
22559 | } | |
22560 | ||
22561 | @@ -310,7 +311,7 @@ parse_command_name (char *text, struct cmd_list_element ***base_list) | |
22562 | prefix_text[i + 1] = '\0'; | |
22563 | ||
22564 | text = prefix_text; | |
22565 | - elt = lookup_cmd_1 (&text, cmdlist, NULL, 1); | |
22566 | + elt = lookup_cmd_1 (&text, *start_list, NULL, 1); | |
22567 | if (!elt || elt == (struct cmd_list_element *) -1) | |
22568 | { | |
22569 | PyErr_Format (PyExc_RuntimeError, _("could not find command prefix %s"), | |
22570 | @@ -336,16 +337,16 @@ parse_command_name (char *text, struct cmd_list_element ***base_list) | |
22571 | ||
22572 | /* Object initializer; sets up gdb-side structures for command. | |
22573 | ||
22574 | - Use: __init__(NAME, CMDCLASS, [COMPLETERCLASS, [PREFIX]]). | |
22575 | + Use: __init__(NAME, COMMAND_CLASS, [COMPLETER_CLASS, [PREFIX]]). | |
22576 | ||
22577 | NAME is the name of the command. It may consist of multiple words, | |
22578 | in which case the final word is the name of the new command, and | |
22579 | earlier words must be prefix commands. | |
22580 | ||
22581 | - CMDCLASS is the kind of command. It should be one of the COMMAND_* | |
22582 | + COMMAND_CLASS is the kind of command. It should be one of the COMMAND_* | |
22583 | constants defined in the gdb module. | |
22584 | ||
22585 | - COMPLETERCLASS is the kind of completer. If not given, the | |
22586 | + COMPLETER_CLASS is the kind of completer. If not given, the | |
22587 | "complete" method will be used. Otherwise, it should be one of the | |
22588 | COMPLETE_* constants defined in the gdb module. | |
22589 | ||
22590 | @@ -356,7 +357,7 @@ parse_command_name (char *text, struct cmd_list_element ***base_list) | |
22591 | ||
22592 | */ | |
22593 | static int | |
22594 | -cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds) | |
22595 | +cmdpy_init (PyObject *self, PyObject *args, PyObject *kw) | |
22596 | { | |
22597 | cmdpy_object *obj = (cmdpy_object *) self; | |
22598 | char *name; | |
22599 | @@ -366,6 +367,8 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds) | |
22600 | volatile struct gdb_exception except; | |
22601 | struct cmd_list_element **cmd_list; | |
22602 | char *cmd_name, *pfx_name; | |
22603 | + static char *keywords[] = { "name", "command_class", "completer_class", | |
22604 | + "prefix", NULL }; | |
22605 | PyObject *is_prefix = NULL; | |
22606 | int cmp; | |
22607 | ||
22608 | @@ -378,7 +381,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds) | |
22609 | return -1; | |
22610 | } | |
22611 | ||
22612 | - if (! PyArg_ParseTuple (args, "si|iO", &name, &cmdtype, | |
22613 | + if (! PyArg_ParseTupleAndKeywords (args, kw, "si|iO", keywords, &name, &cmdtype, | |
22614 | &completetype, &is_prefix)) | |
22615 | return -1; | |
22616 | ||
22617 | @@ -399,7 +402,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds) | |
22618 | return -1; | |
22619 | } | |
22620 | ||
22621 | - cmd_name = parse_command_name (name, &cmd_list); | |
22622 | + cmd_name = gdbpy_parse_command_name (name, &cmd_list, &cmdlist); | |
22623 | if (! cmd_name) | |
22624 | return -1; | |
22625 | ||
22626 | diff --git a/gdb/python/python-frame.c b/gdb/python/python-frame.c | |
22627 | new file mode 100644 | |
22628 | index 0000000..c257ac3 | |
22629 | --- /dev/null | |
22630 | +++ b/gdb/python/python-frame.c | |
22631 | @@ -0,0 +1,686 @@ | |
22632 | +/* Python interface to stack frames | |
22633 | + | |
22634 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
22635 | + | |
22636 | + This file is part of GDB. | |
22637 | + | |
22638 | + This program is free software; you can redistribute it and/or modify | |
22639 | + it under the terms of the GNU General Public License as published by | |
22640 | + the Free Software Foundation; either version 3 of the License, or | |
22641 | + (at your option) any later version. | |
22642 | + | |
22643 | + This program is distributed in the hope that it will be useful, | |
22644 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22645 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22646 | + GNU General Public License for more details. | |
22647 | + | |
22648 | + You should have received a copy of the GNU General Public License | |
22649 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
22650 | + | |
22651 | +#include "defs.h" | |
22652 | +#include "charset.h" | |
22653 | +#include "block.h" | |
22654 | +#include "frame.h" | |
22655 | +#include "exceptions.h" | |
22656 | +#include "symtab.h" | |
22657 | +#include "stack.h" | |
22658 | +#include "value.h" | |
22659 | +#include "python-internal.h" | |
22660 | + | |
22661 | +typedef struct { | |
22662 | + PyObject_HEAD | |
22663 | + struct frame_id frame_id; | |
22664 | + struct gdbarch *gdbarch; | |
22665 | + | |
22666 | + /* Marks that the FRAME_ID member actually holds the ID of the frame next | |
22667 | + to this, and not this frames' ID itself. This is a hack to permit Python | |
22668 | + frame objects which represent invalid frames (i.e., the last frame_info | |
22669 | + in a corrupt stack). The problem arises from the fact that this code | |
22670 | + relies on FRAME_ID to uniquely identify a frame, which is not always true | |
22671 | + for the last "frame" in a corrupt stack (it can have a null ID, or the same | |
22672 | + ID as the previous frame). Whenever get_prev_frame returns NULL, we | |
22673 | + record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */ | |
22674 | + int frame_id_is_next; | |
22675 | +} frame_object; | |
22676 | + | |
22677 | +/* Require a valid frame. This must be called inside a TRY_CATCH, or | |
22678 | + another context in which a gdb exception is allowed. */ | |
22679 | +#define FRAPY_REQUIRE_VALID(frame_obj, frame) \ | |
22680 | + do { \ | |
22681 | + frame = frame_object_to_frame_info (frame_obj); \ | |
22682 | + if (frame == NULL) \ | |
22683 | + error ("Frame is invalid."); \ | |
22684 | + } while (0) | |
22685 | + | |
22686 | +static PyTypeObject frame_object_type; | |
22687 | + | |
22688 | +/* Returns the frame_info object corresponding to the given Python Frame | |
22689 | + object. If the frame doesn't exist anymore (the frame id doesn't | |
22690 | + correspond to any frame in the inferior), returns NULL. */ | |
22691 | + | |
22692 | +static struct frame_info * | |
22693 | +frame_object_to_frame_info (frame_object *frame_obj) | |
22694 | +{ | |
22695 | + struct frame_info *frame; | |
22696 | + | |
22697 | + frame = frame_find_by_id (frame_obj->frame_id); | |
22698 | + if (frame == NULL) | |
22699 | + return NULL; | |
22700 | + | |
22701 | + if (frame_obj->frame_id_is_next) | |
22702 | + frame = get_prev_frame (frame); | |
22703 | + | |
22704 | + return frame; | |
22705 | +} | |
22706 | + | |
22707 | +/* Called by the Python interpreter to obtain string representation | |
22708 | + of the object. */ | |
22709 | + | |
22710 | +static PyObject * | |
22711 | +frapy_str (PyObject *self) | |
22712 | +{ | |
22713 | + char *s; | |
22714 | + long len; | |
22715 | + PyObject *result; | |
22716 | + struct ui_file *strfile; | |
22717 | + | |
22718 | + strfile = mem_fileopen (); | |
22719 | + fprint_frame_id (strfile, ((frame_object *) self)->frame_id); | |
22720 | + s = ui_file_xstrdup (strfile, &len); | |
22721 | + result = PyString_FromString (s); | |
22722 | + xfree (s); | |
22723 | + | |
22724 | + return result; | |
22725 | +} | |
22726 | + | |
22727 | +/* Implementation of gdb.Frame.is_valid (self) -> Boolean. | |
22728 | + Returns True if the frame corresponding to the frame_id of this | |
22729 | + object still exists in the inferior. */ | |
22730 | + | |
22731 | +static PyObject * | |
22732 | +frapy_is_valid (PyObject *self, PyObject *args) | |
22733 | +{ | |
22734 | + struct frame_info *frame; | |
22735 | + | |
22736 | + frame = frame_object_to_frame_info ((frame_object *) self); | |
22737 | + if (frame == NULL) | |
22738 | + Py_RETURN_FALSE; | |
22739 | + | |
22740 | + Py_RETURN_TRUE; | |
22741 | +} | |
22742 | + | |
22743 | +/* Implementation of gdb.Frame.equals (self, other) -> Boolean. */ | |
22744 | + | |
22745 | +static PyObject * | |
22746 | +frapy_equal_p (PyObject *self, PyObject *args) | |
22747 | +{ | |
22748 | + int equalp = 0; /* Initialize to appease gcc warning. */ | |
22749 | + frame_object *self_frame = (frame_object *) self; | |
22750 | + frame_object *other; | |
22751 | + volatile struct gdb_exception except; | |
22752 | + | |
22753 | + if (!PyArg_ParseTuple (args, "O!", &frame_object_type, &other)) | |
22754 | + return NULL; | |
22755 | + | |
22756 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22757 | + { | |
22758 | + equalp = frame_id_eq (self_frame->frame_id, other->frame_id); | |
22759 | + } | |
22760 | + GDB_PY_HANDLE_EXCEPTION (except); | |
22761 | + | |
22762 | + if (equalp) | |
22763 | + Py_RETURN_TRUE; | |
22764 | + | |
22765 | + Py_RETURN_FALSE; | |
22766 | +} | |
22767 | + | |
22768 | +/* Implementation of gdb.Frame.name (self) -> String. | |
22769 | + Returns the name of the function corresponding to this frame. */ | |
22770 | + | |
22771 | +static PyObject * | |
22772 | +frapy_name (PyObject *self, PyObject *args) | |
22773 | +{ | |
22774 | + struct frame_info *frame; | |
22775 | + char *name; | |
22776 | + enum language lang; | |
22777 | + PyObject *result; | |
22778 | + volatile struct gdb_exception except; | |
22779 | + | |
22780 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22781 | + { | |
22782 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
22783 | + | |
22784 | + find_frame_funname (frame, &name, &lang); | |
22785 | + } | |
22786 | + GDB_PY_HANDLE_EXCEPTION (except); | |
22787 | + | |
22788 | + if (name) | |
22789 | + result = target_string_to_unicode (name, strlen (name)); | |
22790 | + else | |
22791 | + { | |
22792 | + result = Py_None; | |
22793 | + Py_INCREF (Py_None); | |
22794 | + } | |
22795 | + | |
22796 | + return result; | |
22797 | +} | |
22798 | + | |
22799 | +/* Implementation of gdb.Frame.type (self) -> Integer. | |
22800 | + Returns the frame type, namely one of the gdb.*_FRAME constants. */ | |
22801 | + | |
22802 | +static PyObject * | |
22803 | +frapy_type (PyObject *self, PyObject *args) | |
22804 | +{ | |
22805 | + struct frame_info *frame; | |
22806 | + enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning. */ | |
22807 | + volatile struct gdb_exception except; | |
22808 | + | |
22809 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22810 | + { | |
22811 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
22812 | + | |
22813 | + type = get_frame_type (frame); | |
22814 | + } | |
22815 | + GDB_PY_HANDLE_EXCEPTION (except); | |
22816 | + | |
22817 | + return PyInt_FromLong (type); | |
22818 | +} | |
22819 | + | |
22820 | +/* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer. | |
22821 | + Returns one of the gdb.FRAME_UNWIND_* constants. */ | |
22822 | + | |
22823 | +static PyObject * | |
22824 | +frapy_unwind_stop_reason (PyObject *self, PyObject *args) | |
22825 | +{ | |
22826 | + struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */ | |
22827 | + volatile struct gdb_exception except; | |
22828 | + enum unwind_stop_reason stop_reason; | |
22829 | + | |
22830 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22831 | + { | |
22832 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
22833 | + } | |
22834 | + GDB_PY_HANDLE_EXCEPTION (except); | |
22835 | + | |
22836 | + stop_reason = get_frame_unwind_stop_reason (frame); | |
22837 | + | |
22838 | + return PyInt_FromLong (stop_reason); | |
22839 | +} | |
22840 | + | |
22841 | +/* Implementation of gdb.Frame.pc (self) -> Long. | |
22842 | + Returns the frame's resume address. */ | |
22843 | + | |
22844 | +static PyObject * | |
22845 | +frapy_pc (PyObject *self, PyObject *args) | |
22846 | +{ | |
22847 | + CORE_ADDR pc = 0; /* Initialize to appease gcc warning. */ | |
22848 | + struct frame_info *frame; | |
22849 | + volatile struct gdb_exception except; | |
22850 | + | |
22851 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22852 | + { | |
22853 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
22854 | + | |
22855 | + pc = get_frame_pc (frame); | |
22856 | + } | |
22857 | + GDB_PY_HANDLE_EXCEPTION (except); | |
22858 | + | |
22859 | + return PyLong_FromUnsignedLongLong (pc); | |
22860 | +} | |
22861 | + | |
22862 | +/* Implementation of gdb.Frame.block (self) -> gdb.Block. | |
22863 | + Returns the frame's code block. */ | |
22864 | + | |
22865 | +static PyObject * | |
22866 | +frapy_block (PyObject *self, PyObject *args) | |
22867 | +{ | |
22868 | + struct frame_info *frame; | |
22869 | + struct block *block = NULL; | |
22870 | + volatile struct gdb_exception except; | |
22871 | + | |
22872 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22873 | + { | |
22874 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
22875 | + | |
22876 | + block = block_for_pc (get_frame_address_in_block (frame)); | |
22877 | + } | |
22878 | + GDB_PY_HANDLE_EXCEPTION (except); | |
22879 | + | |
22880 | + if (block) | |
22881 | + return block_to_block_object (block); | |
22882 | + | |
22883 | + Py_RETURN_NONE; | |
22884 | +} | |
22885 | + | |
22886 | + | |
22887 | +/* Implementation of gdb.Frame.addr_in_block (self) -> Long. | |
22888 | + Returns an address which falls within the frame's code block. */ | |
22889 | + | |
22890 | +static PyObject * | |
22891 | +frapy_addr_in_block (PyObject *self, PyObject *args) | |
22892 | +{ | |
22893 | + CORE_ADDR pc = 0; /* Initialize to appease gcc warning. */ | |
22894 | + struct frame_info *frame; | |
22895 | + volatile struct gdb_exception except; | |
22896 | + | |
22897 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22898 | + { | |
22899 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
22900 | + | |
22901 | + pc = get_frame_address_in_block (frame); | |
22902 | + } | |
22903 | + GDB_PY_HANDLE_EXCEPTION (except); | |
22904 | + | |
22905 | + return PyLong_FromUnsignedLongLong (pc); | |
22906 | +} | |
22907 | + | |
22908 | +/* Convert a frame_info struct to a Python Frame object. | |
22909 | + Sets a Python exception and returns NULL on error. */ | |
22910 | + | |
22911 | +static frame_object * | |
22912 | +frame_info_to_frame_object (struct frame_info *frame) | |
22913 | +{ | |
22914 | + frame_object *frame_obj; | |
22915 | + | |
22916 | + frame_obj = PyObject_New (frame_object, &frame_object_type); | |
22917 | + if (frame_obj == NULL) | |
22918 | + { | |
22919 | + PyErr_SetString (PyExc_MemoryError, "Could not allocate frame object."); | |
22920 | + return NULL; | |
22921 | + } | |
22922 | + | |
22923 | + /* Try to get the previous frame, to determine if this is the last frame | |
22924 | + in a corrupt stack. If so, we need to store the frame_id of the next | |
22925 | + frame and not of this one (which is possibly invalid). */ | |
22926 | + if (get_prev_frame (frame) == NULL | |
22927 | + && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON | |
22928 | + && get_next_frame (frame) != NULL) | |
22929 | + { | |
22930 | + frame_obj->frame_id = get_frame_id (get_next_frame (frame)); | |
22931 | + frame_obj->frame_id_is_next = 1; | |
22932 | + } | |
22933 | + else | |
22934 | + { | |
22935 | + frame_obj->frame_id = get_frame_id (frame); | |
22936 | + frame_obj->frame_id_is_next = 0; | |
22937 | + } | |
22938 | + | |
22939 | + frame_obj->gdbarch = get_frame_arch (frame); | |
22940 | + | |
22941 | + return frame_obj; | |
22942 | +} | |
22943 | + | |
22944 | +/* Implementation of gdb.Frame.older (self) -> gdb.Frame. | |
22945 | + Returns the frame immediately older (outer) to this frame, or None if | |
22946 | + there isn't one. */ | |
22947 | + | |
22948 | +static PyObject * | |
22949 | +frapy_older (PyObject *self, PyObject *args) | |
22950 | +{ | |
22951 | + struct frame_info *frame, *prev; | |
22952 | + volatile struct gdb_exception except; | |
22953 | + PyObject *prev_obj = NULL; /* Initialize to appease gcc warning. */ | |
22954 | + | |
22955 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22956 | + { | |
22957 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
22958 | + | |
22959 | + prev = get_prev_frame (frame); | |
22960 | + if (prev) | |
22961 | + prev_obj = (PyObject *) frame_info_to_frame_object (prev); | |
22962 | + else | |
22963 | + { | |
22964 | + Py_INCREF (Py_None); | |
22965 | + prev_obj = Py_None; | |
22966 | + } | |
22967 | + } | |
22968 | + GDB_PY_HANDLE_EXCEPTION (except); | |
22969 | + | |
22970 | + return prev_obj; | |
22971 | +} | |
22972 | + | |
22973 | +/* Implementation of gdb.Frame.newer (self) -> gdb.Frame. | |
22974 | + Returns the frame immediately newer (inner) to this frame, or None if | |
22975 | + there isn't one. */ | |
22976 | + | |
22977 | +static PyObject * | |
22978 | +frapy_newer (PyObject *self, PyObject *args) | |
22979 | +{ | |
22980 | + struct frame_info *frame, *next; | |
22981 | + volatile struct gdb_exception except; | |
22982 | + PyObject *next_obj = NULL; /* Initialize to appease gcc warning. */ | |
22983 | + | |
22984 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
22985 | + { | |
22986 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
22987 | + | |
22988 | + next = get_next_frame (frame); | |
22989 | + if (next) | |
22990 | + next_obj = (PyObject *) frame_info_to_frame_object (next); | |
22991 | + else | |
22992 | + { | |
22993 | + Py_INCREF (Py_None); | |
22994 | + next_obj = Py_None; | |
22995 | + } | |
22996 | + } | |
22997 | + GDB_PY_HANDLE_EXCEPTION (except); | |
22998 | + | |
22999 | + return next_obj; | |
23000 | +} | |
23001 | + | |
23002 | +/* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line. | |
23003 | + Returns the frame's symtab and line. */ | |
23004 | + | |
23005 | +static PyObject * | |
23006 | +frapy_find_sal (PyObject *self, PyObject *args) | |
23007 | +{ | |
23008 | + struct frame_info *frame; | |
23009 | + struct symtab_and_line sal; | |
23010 | + volatile struct gdb_exception except; | |
23011 | + PyObject *sal_obj = NULL; /* Initialize to appease gcc warning. */ | |
23012 | + | |
23013 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
23014 | + { | |
23015 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
23016 | + | |
23017 | + find_frame_sal (frame, &sal); | |
23018 | + sal_obj = symtab_and_line_to_sal_object (sal); | |
23019 | + } | |
23020 | + GDB_PY_HANDLE_EXCEPTION (except); | |
23021 | + | |
23022 | + return sal_obj; | |
23023 | +} | |
23024 | + | |
23025 | +/* Implementation of gdb.Frame.read_var (self, variable) -> gdb.Value. | |
23026 | + Returns the value of the given variable in this frame. The argument can be | |
23027 | + either a gdb.Symbol or a string. Returns None if GDB can't find the | |
23028 | + specified variable. */ | |
23029 | + | |
23030 | +static PyObject * | |
23031 | +frapy_read_var (PyObject *self, PyObject *args) | |
23032 | +{ | |
23033 | + struct frame_info *frame; | |
23034 | + PyObject *sym_obj; | |
23035 | + struct symbol *var = NULL; /* gcc-4.3.2 false warning. */ | |
23036 | + struct value *val = NULL; | |
23037 | + volatile struct gdb_exception except; | |
23038 | + | |
23039 | + if (!PyArg_ParseTuple (args, "O", &sym_obj)) | |
23040 | + return NULL; | |
23041 | + | |
23042 | + if (PyObject_TypeCheck (sym_obj, &symbol_object_type)) | |
23043 | + var = symbol_object_to_symbol (sym_obj); | |
23044 | + else if (gdbpy_is_string (sym_obj)) | |
23045 | + { | |
23046 | + char *var_name; | |
23047 | + struct block *block = NULL; | |
23048 | + struct cleanup *cleanup; | |
23049 | + volatile struct gdb_exception except; | |
23050 | + | |
23051 | + var_name = python_string_to_target_string (sym_obj); | |
23052 | + if (!var_name) | |
23053 | + return NULL; | |
23054 | + cleanup = make_cleanup (xfree, var_name); | |
23055 | + | |
23056 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
23057 | + { | |
23058 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
23059 | + | |
23060 | + block = block_for_pc (get_frame_address_in_block (frame)); | |
23061 | + var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL); | |
23062 | + } | |
23063 | + GDB_PY_HANDLE_EXCEPTION (except); | |
23064 | + | |
23065 | + if (!var) | |
23066 | + { | |
23067 | + PyErr_Format (PyExc_ValueError, | |
23068 | + _("variable '%s' not found"), var_name); | |
23069 | + do_cleanups (cleanup); | |
23070 | + | |
23071 | + return NULL; | |
23072 | + } | |
23073 | + | |
23074 | + do_cleanups (cleanup); | |
23075 | + } | |
23076 | + else | |
23077 | + { | |
23078 | + PyErr_SetString (PyExc_TypeError, | |
23079 | + _("argument must be a symbol or string")); | |
23080 | + return NULL; | |
23081 | + } | |
23082 | + | |
23083 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
23084 | + { | |
23085 | + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); | |
23086 | + | |
23087 | + val = read_var_value (var, frame); | |
23088 | + } | |
23089 | + GDB_PY_HANDLE_EXCEPTION (except); | |
23090 | + | |
23091 | + if (val) | |
23092 | + return value_to_value_object (val); | |
23093 | + | |
23094 | + Py_RETURN_NONE; | |
23095 | +} | |
23096 | + | |
23097 | +/* Implementation of gdb.frames () -> (gdb.Frame, ...). | |
23098 | + Returns a tuple of all frame objects. */ | |
23099 | + | |
23100 | +PyObject * | |
23101 | +gdbpy_frames (PyObject *self, PyObject *args) | |
23102 | +{ | |
23103 | + int result = 0; | |
23104 | + struct frame_info *frame; | |
23105 | + frame_object *frame_obj; | |
23106 | + PyObject *list, *tuple; | |
23107 | + volatile struct gdb_exception except; | |
23108 | + | |
23109 | + list = PyList_New (0); | |
23110 | + if (list == NULL) | |
23111 | + { | |
23112 | + PyErr_SetString (PyExc_MemoryError, "Could not allocate frames list."); | |
23113 | + return NULL; | |
23114 | + } | |
23115 | + | |
23116 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
23117 | + { | |
23118 | + for (frame = get_current_frame (); frame; frame = get_prev_frame (frame)) | |
23119 | + { | |
23120 | + frame_obj = frame_info_to_frame_object (frame); | |
23121 | + if (frame_obj == NULL) | |
23122 | + { | |
23123 | + Py_DECREF (list); | |
23124 | + list = NULL; | |
23125 | + break; | |
23126 | + } | |
23127 | + | |
23128 | + PyList_Append (list, (PyObject *) frame_obj); | |
23129 | + } | |
23130 | + } | |
23131 | + if (except.reason < 0) | |
23132 | + { | |
23133 | + Py_DECREF (list); | |
23134 | + return PyErr_Format (except.reason == RETURN_QUIT | |
23135 | + ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, | |
23136 | + "%s", except.message); | |
23137 | + } | |
23138 | + | |
23139 | + if (list) | |
23140 | + { | |
23141 | + tuple = PyList_AsTuple (list); | |
23142 | + Py_DECREF (list); | |
23143 | + } | |
23144 | + else | |
23145 | + tuple = NULL; | |
23146 | + | |
23147 | + return tuple; | |
23148 | +} | |
23149 | + | |
23150 | +/* Implementation of gdb.newest_frame () -> gdb.Frame. | |
23151 | + Returns the newest frame object. */ | |
23152 | + | |
23153 | +PyObject * | |
23154 | +gdbpy_newest_frame (PyObject *self, PyObject *args) | |
23155 | +{ | |
23156 | + struct frame_info *frame; | |
23157 | + frame_object *frame_obj = NULL; /* Initialize to appease gcc warning. */ | |
23158 | + volatile struct gdb_exception except; | |
23159 | + | |
23160 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
23161 | + { | |
23162 | + frame = get_current_frame (); | |
23163 | + frame_obj = frame_info_to_frame_object (frame); | |
23164 | + } | |
23165 | + GDB_PY_HANDLE_EXCEPTION (except); | |
23166 | + | |
23167 | + return (PyObject *) frame_obj; | |
23168 | +} | |
23169 | + | |
23170 | +/* Implementation of gdb.selected_frame () -> gdb.Frame. | |
23171 | + Returns the selected frame object. */ | |
23172 | + | |
23173 | +PyObject * | |
23174 | +gdbpy_selected_frame (PyObject *self, PyObject *args) | |
23175 | +{ | |
23176 | + struct frame_info *frame; | |
23177 | + frame_object *frame_obj = NULL; /* Initialize to appease gcc warning. */ | |
23178 | + volatile struct gdb_exception except; | |
23179 | + | |
23180 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
23181 | + { | |
23182 | + frame = get_selected_frame ("No frame is currently selected."); | |
23183 | + frame_obj = frame_info_to_frame_object (frame); | |
23184 | + } | |
23185 | + GDB_PY_HANDLE_EXCEPTION (except); | |
23186 | + | |
23187 | + return (PyObject *) frame_obj; | |
23188 | +} | |
23189 | + | |
23190 | +/* Implementation of gdb.stop_reason_string (Integer) -> String. | |
23191 | + Return a string explaining the unwind stop reason. */ | |
23192 | + | |
23193 | +PyObject * | |
23194 | +gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args) | |
23195 | +{ | |
23196 | + int reason; | |
23197 | + const char *str; | |
23198 | + | |
23199 | + if (!PyArg_ParseTuple (args, "i", &reason)) | |
23200 | + return NULL; | |
23201 | + | |
23202 | + if (reason < 0 || reason > UNWIND_NO_SAVED_PC) | |
23203 | + { | |
23204 | + PyErr_SetString (PyExc_ValueError, "Invalid frame stop reason."); | |
23205 | + return NULL; | |
23206 | + } | |
23207 | + | |
23208 | + str = frame_stop_reason_string (reason); | |
23209 | + return PyUnicode_Decode (str, strlen (str), host_charset (), NULL); | |
23210 | +} | |
23211 | + | |
23212 | +/* Sets up the Frame API in the gdb module. */ | |
23213 | + | |
23214 | +void | |
23215 | +gdbpy_initialize_frames (void) | |
23216 | +{ | |
23217 | + frame_object_type.tp_new = PyType_GenericNew; | |
23218 | + if (PyType_Ready (&frame_object_type) < 0) | |
23219 | + return; | |
23220 | + | |
23221 | + /* Note: These would probably be best exposed as class attributes of Frame, | |
23222 | + but I don't know how to do it except by messing with the type's dictionary. | |
23223 | + That seems too messy. */ | |
23224 | + PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME); | |
23225 | + PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME); | |
23226 | + PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME); | |
23227 | + PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME); | |
23228 | + PyModule_AddIntConstant (gdb_module, | |
23229 | + "FRAME_UNWIND_NO_REASON", UNWIND_NO_REASON); | |
23230 | + PyModule_AddIntConstant (gdb_module, | |
23231 | + "FRAME_UNWIND_NULL_ID", UNWIND_NULL_ID); | |
23232 | + PyModule_AddIntConstant (gdb_module, | |
23233 | + "FRAME_UNWIND_FIRST_ERROR", UNWIND_FIRST_ERROR); | |
23234 | + PyModule_AddIntConstant (gdb_module, | |
23235 | + "FRAME_UNWIND_INNER_ID", UNWIND_INNER_ID); | |
23236 | + PyModule_AddIntConstant (gdb_module, | |
23237 | + "FRAME_UNWIND_SAME_ID", UNWIND_SAME_ID); | |
23238 | + PyModule_AddIntConstant (gdb_module, | |
23239 | + "FRAME_UNWIND_NO_SAVED_PC", UNWIND_NO_SAVED_PC); | |
23240 | + | |
23241 | + Py_INCREF (&frame_object_type); | |
23242 | + PyModule_AddObject (gdb_module, "Frame", (PyObject *) &frame_object_type); | |
23243 | +} | |
23244 | + | |
23245 | +\f | |
23246 | + | |
23247 | +static PyMethodDef frame_object_methods[] = { | |
23248 | + { "equals", frapy_equal_p, METH_VARARGS, | |
23249 | + "equals (frame) -> Boolean.\n\ | |
23250 | +Compare this frame to the given frame." }, | |
23251 | + { "is_valid", frapy_is_valid, METH_NOARGS, | |
23252 | + "is_valid () -> Boolean.\n\ | |
23253 | +Return true if this frame is valid, false if not." }, | |
23254 | + { "name", frapy_name, METH_NOARGS, | |
23255 | + "name () -> String.\n\ | |
23256 | +Return the function name of the frame, or None if it can't be determined." }, | |
23257 | + { "type", frapy_type, METH_NOARGS, | |
23258 | + "type () -> Integer.\n\ | |
23259 | +Return the type of the frame." }, | |
23260 | + { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS, | |
23261 | + "unwind_stop_reason () -> Integer.\n\ | |
23262 | +Return the reason why it's not possible to find frames older than this." }, | |
23263 | + { "pc", frapy_pc, METH_NOARGS, | |
23264 | + "pc () -> Long.\n\ | |
23265 | +Return the frame's resume address." }, | |
23266 | + { "block", frapy_block, METH_NOARGS, | |
23267 | + "block () -> gdb.Block.\n\ | |
23268 | +Return the frame's code block." }, | |
23269 | + { "addr_in_block", frapy_addr_in_block, METH_NOARGS, | |
23270 | + "addr_in_block () -> Long.\n\ | |
23271 | +Return an address which falls within the frame's code block." }, | |
23272 | + { "older", frapy_older, METH_NOARGS, | |
23273 | + "older () -> gdb.Frame.\n\ | |
23274 | +Return the frame immediately older (outer) to this frame." }, | |
23275 | + { "newer", frapy_newer, METH_NOARGS, | |
23276 | + "newer () -> gdb.Frame.\n\ | |
23277 | +Return the frame immetidaely newer (inner) to this frame." }, | |
23278 | + { "find_sal", frapy_find_sal, METH_NOARGS, | |
23279 | + "find_sal () -> gdb.Symtab_and_line.\n\ | |
23280 | +Return the frame's symtab and line." }, | |
23281 | + { "read_var", frapy_read_var, METH_VARARGS, | |
23282 | + "read_var (variable) -> gdb.Value.\n\ | |
23283 | +Return the value of the variable in this frame." }, | |
23284 | + {NULL} /* Sentinel */ | |
23285 | +}; | |
23286 | + | |
23287 | +static PyTypeObject frame_object_type = { | |
23288 | + PyObject_HEAD_INIT (NULL) | |
23289 | + 0, /* ob_size */ | |
23290 | + "gdb.Frame", /* tp_name */ | |
23291 | + sizeof (frame_object), /* tp_basicsize */ | |
23292 | + 0, /* tp_itemsize */ | |
23293 | + 0, /* tp_dealloc */ | |
23294 | + 0, /* tp_print */ | |
23295 | + 0, /* tp_getattr */ | |
23296 | + 0, /* tp_setattr */ | |
23297 | + 0, /* tp_compare */ | |
23298 | + 0, /* tp_repr */ | |
23299 | + 0, /* tp_as_number */ | |
23300 | + 0, /* tp_as_sequence */ | |
23301 | + 0, /* tp_as_mapping */ | |
23302 | + 0, /* tp_hash */ | |
23303 | + 0, /* tp_call */ | |
23304 | + frapy_str, /* tp_str */ | |
23305 | + 0, /* tp_getattro */ | |
23306 | + 0, /* tp_setattro */ | |
23307 | + 0, /* tp_as_buffer */ | |
23308 | + Py_TPFLAGS_DEFAULT, /* tp_flags */ | |
23309 | + "GDB frame object", /* tp_doc */ | |
23310 | + 0, /* tp_traverse */ | |
23311 | + 0, /* tp_clear */ | |
23312 | + 0, /* tp_richcompare */ | |
23313 | + 0, /* tp_weaklistoffset */ | |
23314 | + 0, /* tp_iter */ | |
23315 | + 0, /* tp_iternext */ | |
23316 | + frame_object_methods /* tp_methods */ | |
23317 | +}; | |
23318 | diff --git a/gdb/python/python-function.c b/gdb/python/python-function.c | |
23319 | new file mode 100644 | |
23320 | index 0000000..4a85a33 | |
23321 | --- /dev/null | |
23322 | +++ b/gdb/python/python-function.c | |
23323 | @@ -0,0 +1,180 @@ | |
23324 | +/* Convenience functions implemented in Python. | |
23325 | + | |
23326 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
23327 | + | |
23328 | + This file is part of GDB. | |
23329 | + | |
23330 | + This program is free software; you can redistribute it and/or modify | |
23331 | + it under the terms of the GNU General Public License as published by | |
23332 | + the Free Software Foundation; either version 3 of the License, or | |
23333 | + (at your option) any later version. | |
23334 | + | |
23335 | + This program is distributed in the hope that it will be useful, | |
23336 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23337 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23338 | + GNU General Public License for more details. | |
23339 | + | |
23340 | + You should have received a copy of the GNU General Public License | |
23341 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
23342 | + | |
23343 | + | |
23344 | +#include "defs.h" | |
23345 | +#include "value.h" | |
23346 | +#include "exceptions.h" | |
23347 | +#include "python-internal.h" | |
23348 | +#include "charset.h" | |
23349 | +#include "gdbcmd.h" | |
23350 | +#include "cli/cli-decode.h" | |
23351 | +#include "completer.h" | |
23352 | +#include "expression.h" | |
23353 | + | |
23354 | +static PyTypeObject fnpy_object_type; | |
23355 | + | |
23356 | +\f | |
23357 | + | |
23358 | +static PyObject * | |
23359 | +convert_values_to_python (int argc, struct value **argv) | |
23360 | +{ | |
23361 | + int i; | |
23362 | + PyObject *result = PyTuple_New (argc); | |
23363 | + for (i = 0; i < argc; ++i) | |
23364 | + { | |
23365 | + PyObject *elt = value_to_value_object (argv[i]); | |
23366 | + if (! elt) | |
23367 | + { | |
23368 | + Py_DECREF (result); | |
23369 | + error (_("Could not convert value to Python object.")); | |
23370 | + } | |
23371 | + PyTuple_SetItem (result, i, elt); | |
23372 | + } | |
23373 | + return result; | |
23374 | +} | |
23375 | + | |
23376 | +/* Call a Python function object's invoke method. */ | |
23377 | + | |
23378 | +static struct value * | |
23379 | +fnpy_call (void *cookie, int argc, struct value **argv) | |
23380 | +{ | |
23381 | + int i; | |
23382 | + struct value *value = NULL; | |
23383 | + PyObject *result, *callable, *args; | |
23384 | + struct cleanup *cleanup; | |
23385 | + PyGILState_STATE state; | |
23386 | + | |
23387 | + state = PyGILState_Ensure (); | |
23388 | + cleanup = make_cleanup_py_restore_gil (&state); | |
23389 | + | |
23390 | + args = convert_values_to_python (argc, argv); | |
23391 | + | |
23392 | + callable = PyObject_GetAttrString ((PyObject *) cookie, "invoke"); | |
23393 | + if (! callable) | |
23394 | + { | |
23395 | + Py_DECREF (args); | |
23396 | + error (_("No method named 'invoke' in object.")); | |
23397 | + } | |
23398 | + | |
23399 | + result = PyObject_Call (callable, args, NULL); | |
23400 | + Py_DECREF (callable); | |
23401 | + Py_DECREF (args); | |
23402 | + | |
23403 | + if (!result) | |
23404 | + { | |
23405 | + gdbpy_print_stack (); | |
23406 | + error (_("Error while executing Python code.")); | |
23407 | + } | |
23408 | + | |
23409 | + value = convert_value_from_python (result); | |
23410 | + if (value == NULL) | |
23411 | + { | |
23412 | + Py_DECREF (result); | |
23413 | + gdbpy_print_stack (); | |
23414 | + error (_("Error while executing Python code.")); | |
23415 | + } | |
23416 | + | |
23417 | + Py_DECREF (result); | |
23418 | + do_cleanups (cleanup); | |
23419 | + | |
23420 | + return value; | |
23421 | +} | |
23422 | + | |
23423 | +/* Initializer for a Function object. It takes one argument, the name | |
23424 | + of the function. */ | |
23425 | + | |
23426 | +static int | |
23427 | +fnpy_init (PyObject *self, PyObject *args, PyObject *kwds) | |
23428 | +{ | |
23429 | + char *name, *docstring = NULL; | |
23430 | + if (! PyArg_ParseTuple (args, "s", &name)) | |
23431 | + return -1; | |
23432 | + Py_INCREF (self); | |
23433 | + | |
23434 | + if (PyObject_HasAttrString (self, "__doc__")) | |
23435 | + { | |
23436 | + PyObject *ds_obj = PyObject_GetAttrString (self, "__doc__"); | |
23437 | + if (ds_obj && gdbpy_is_string (ds_obj)) | |
23438 | + /* Nothing ever frees this. */ | |
23439 | + docstring = python_string_to_host_string (ds_obj); | |
23440 | + } | |
23441 | + if (! docstring) | |
23442 | + docstring = _("This function is not documented."); | |
23443 | + | |
23444 | + add_internal_function (name, docstring, fnpy_call, self); | |
23445 | + return 0; | |
23446 | +} | |
23447 | + | |
23448 | +/* Initialize internal function support. */ | |
23449 | + | |
23450 | +void | |
23451 | +gdbpy_initialize_functions (void) | |
23452 | +{ | |
23453 | + if (PyType_Ready (&fnpy_object_type) < 0) | |
23454 | + return; | |
23455 | + | |
23456 | + Py_INCREF (&fnpy_object_type); | |
23457 | + PyModule_AddObject (gdb_module, "Function", (PyObject *) &fnpy_object_type); | |
23458 | +} | |
23459 | + | |
23460 | +\f | |
23461 | + | |
23462 | +static PyTypeObject fnpy_object_type = | |
23463 | +{ | |
23464 | + PyObject_HEAD_INIT (NULL) | |
23465 | + 0, /*ob_size*/ | |
23466 | + "gdb.Function", /*tp_name*/ | |
23467 | + sizeof (PyObject), /*tp_basicsize*/ | |
23468 | + 0, /*tp_itemsize*/ | |
23469 | + 0, /*tp_dealloc*/ | |
23470 | + 0, /*tp_print*/ | |
23471 | + 0, /*tp_getattr*/ | |
23472 | + 0, /*tp_setattr*/ | |
23473 | + 0, /*tp_compare*/ | |
23474 | + 0, /*tp_repr*/ | |
23475 | + 0, /*tp_as_number*/ | |
23476 | + 0, /*tp_as_sequence*/ | |
23477 | + 0, /*tp_as_mapping*/ | |
23478 | + 0, /*tp_hash */ | |
23479 | + 0, /*tp_call*/ | |
23480 | + 0, /*tp_str*/ | |
23481 | + 0, /*tp_getattro*/ | |
23482 | + 0, /*tp_setattro*/ | |
23483 | + 0, /*tp_as_buffer*/ | |
23484 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | |
23485 | + "GDB function object", /* tp_doc */ | |
23486 | + 0, /* tp_traverse */ | |
23487 | + 0, /* tp_clear */ | |
23488 | + 0, /* tp_richcompare */ | |
23489 | + 0, /* tp_weaklistoffset */ | |
23490 | + 0, /* tp_iter */ | |
23491 | + 0, /* tp_iternext */ | |
23492 | + 0, /* tp_methods */ | |
23493 | + 0, /* tp_members */ | |
23494 | + 0, /* tp_getset */ | |
23495 | + 0, /* tp_base */ | |
23496 | + 0, /* tp_dict */ | |
23497 | + 0, /* tp_descr_get */ | |
23498 | + 0, /* tp_descr_set */ | |
23499 | + 0, /* tp_dictoffset */ | |
23500 | + fnpy_init, /* tp_init */ | |
23501 | + 0, /* tp_alloc */ | |
23502 | + PyType_GenericNew /* tp_new */ | |
23503 | +}; | |
23504 | diff --git a/gdb/python/python-hooks.c b/gdb/python/python-hooks.c | |
23505 | new file mode 100644 | |
23506 | index 0000000..a3140bc | |
23507 | --- /dev/null | |
23508 | +++ b/gdb/python/python-hooks.c | |
23509 | @@ -0,0 +1,50 @@ | |
23510 | +/* Notifications from gdb to Python | |
23511 | + | |
23512 | + Copyright (C) 2008 Free Software Foundation, Inc. | |
23513 | + | |
23514 | + This file is part of GDB. | |
23515 | + | |
23516 | + This program is free software; you can redistribute it and/or modify | |
23517 | + it under the terms of the GNU General Public License as published by | |
23518 | + the Free Software Foundation; either version 3 of the License, or | |
23519 | + (at your option) any later version. | |
23520 | + | |
23521 | + This program is distributed in the hope that it will be useful, | |
23522 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23523 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23524 | + GNU General Public License for more details. | |
23525 | + | |
23526 | + You should have received a copy of the GNU General Public License | |
23527 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
23528 | + | |
23529 | +#include "defs.h" | |
23530 | +#include "cli/cli-decode.h" | |
23531 | +#include "charset.h" | |
23532 | +#include "python.h" | |
23533 | +#include "python-internal.h" | |
23534 | +#include "observer.h" | |
23535 | + | |
23536 | +PyObject * | |
23537 | +gdbpy_get_hook_function (const char *name) | |
23538 | +{ | |
23539 | + PyObject *hooks; | |
23540 | + PyObject *result; | |
23541 | + | |
23542 | + if (! PyObject_HasAttrString (gdb_module, "hooks")) | |
23543 | + return NULL; | |
23544 | + hooks = PyObject_GetAttrString (gdb_module, "hooks"); | |
23545 | + if (! hooks) | |
23546 | + return NULL; | |
23547 | + /* The cast is because the Python function doesn't declare const argument. | |
23548 | + This is a problem in Python version 2.4, but not in 2.5. */ | |
23549 | + if (! PyObject_HasAttrString (hooks, (char *) name)) | |
23550 | + { | |
23551 | + Py_DECREF (hooks); | |
23552 | + return NULL; | |
23553 | + } | |
23554 | + /* The cast is because the Python function doesn't declare const argument. | |
23555 | + This is a problem in Python version 2.4, but not in 2.5. */ | |
23556 | + result = PyObject_GetAttrString (hooks, (char *) name); | |
23557 | + Py_DECREF (hooks); | |
23558 | + return result; | |
23559 | +} | |
23560 | diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h | |
23561 | index 02dbfc4..4aae0aa 100644 | |
23562 | --- a/gdb/python/python-internal.h | |
23563 | +++ b/gdb/python/python-internal.h | |
23564 | @@ -33,6 +33,7 @@ | |
23565 | ||
23566 | #if HAVE_LIBPYTHON2_4 | |
23567 | #include "python2.4/Python.h" | |
23568 | +#include "python2.4/frameobject.h" | |
23569 | /* Py_ssize_t is not defined until 2.5. | |
23570 | Logical type for Py_ssize_t is Py_intptr_t, but that fails in 64-bit | |
23571 | compilation due to several apparent mistakes in python2.4 API, so we | |
23572 | @@ -40,8 +41,10 @@ | |
23573 | typedef int Py_ssize_t; | |
23574 | #elif HAVE_LIBPYTHON2_5 | |
23575 | #include "python2.5/Python.h" | |
23576 | +#include "python2.5/frameobject.h" | |
23577 | #elif HAVE_LIBPYTHON2_6 | |
23578 | #include "python2.6/Python.h" | |
23579 | +#include "python2.6/frameobject.h" | |
23580 | #else | |
23581 | #error "Unable to find usable Python.h" | |
23582 | #endif | |
23583 | @@ -58,23 +61,69 @@ typedef int Py_ssize_t; | |
23584 | #define PyEval_ReleaseLock() 0 | |
23585 | #endif | |
23586 | ||
23587 | +#include "command.h" | |
23588 | + | |
23589 | +struct block; | |
23590 | +struct symbol; | |
23591 | +struct symtab_and_line; | |
23592 | struct value; | |
23593 | ||
23594 | extern PyObject *gdb_module; | |
23595 | +extern PyTypeObject block_object_type; | |
23596 | extern PyTypeObject value_object_type; | |
23597 | +extern PyTypeObject symbol_object_type; | |
23598 | ||
23599 | PyObject *gdbpy_history (PyObject *self, PyObject *args); | |
23600 | - | |
23601 | +PyObject *gdbpy_breakpoints (PyObject *, PyObject *); | |
23602 | +PyObject *gdbpy_frames (PyObject *, PyObject *); | |
23603 | +PyObject *gdbpy_newest_frame (PyObject *, PyObject *); | |
23604 | +PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *); | |
23605 | +PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw); | |
23606 | +PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args); | |
23607 | +PyObject *gdbpy_block_for_pc (PyObject *self, PyObject *args); | |
23608 | +PyObject *gdbpy_read_memory (PyObject *self, PyObject *args); | |
23609 | +PyObject *gdbpy_write_memory (PyObject *self, PyObject *args); | |
23610 | + | |
23611 | +PyObject *symtab_and_line_to_sal_object (struct symtab_and_line sal); | |
23612 | +PyObject *symtab_to_symtab_object (struct symtab *symtab); | |
23613 | +PyObject *symbol_to_symbol_object (struct symbol *sym); | |
23614 | +PyObject *block_to_block_object (struct block *block); | |
23615 | PyObject *value_to_value_object (struct value *v); | |
23616 | +PyObject *type_to_type_object (struct type *); | |
23617 | +PyObject *objfile_to_objfile_object (struct objfile *); | |
23618 | ||
23619 | +PyObject *objfpy_get_printers (PyObject *, void *); | |
23620 | + | |
23621 | +struct block *block_object_to_block (PyObject *obj); | |
23622 | +struct symbol *symbol_object_to_symbol (PyObject *obj); | |
23623 | +struct value *value_object_to_value (PyObject *self); | |
23624 | struct value *convert_value_from_python (PyObject *obj); | |
23625 | +struct type *type_object_to_type (PyObject *obj); | |
23626 | + | |
23627 | +PyObject *gdbpy_get_hook_function (const char *); | |
23628 | ||
23629 | void gdbpy_initialize_values (void); | |
23630 | +void gdbpy_initialize_breakpoints (void); | |
23631 | +void gdbpy_initialize_frames (void); | |
23632 | +void gdbpy_initialize_symtabs (void); | |
23633 | void gdbpy_initialize_commands (void); | |
23634 | +void gdbpy_initialize_symbols (void); | |
23635 | +void gdbpy_initialize_types (void); | |
23636 | +void gdbpy_initialize_blocks (void); | |
23637 | +void gdbpy_initialize_functions (void); | |
23638 | +void gdbpy_initialize_objfile (void); | |
23639 | +void gdbpy_initialize_parameters (void); | |
23640 | +void gdbpy_initialize_membuf (void); | |
23641 | ||
23642 | struct cleanup *make_cleanup_py_decref (PyObject *py); | |
23643 | struct cleanup *make_cleanup_py_restore_gil (PyGILState_STATE *state); | |
23644 | ||
23645 | +char *gdbpy_parse_command_name (char *text, | |
23646 | + struct cmd_list_element ***base_list, | |
23647 | + struct cmd_list_element **start_list); | |
23648 | + | |
23649 | +PyObject *gdbpy_parameter_value (enum var_types, void *); | |
23650 | + | |
23651 | /* Use this after a TRY_EXCEPT to throw the appropriate Python | |
23652 | exception. */ | |
23653 | #define GDB_PY_HANDLE_EXCEPTION(Exception) \ | |
23654 | @@ -85,6 +134,19 @@ struct cleanup *make_cleanup_py_restore_gil (PyGILState_STATE *state); | |
23655 | "%s", Exception.message); \ | |
23656 | } while (0) | |
23657 | ||
23658 | +/* Use this after a TRY_EXCEPT to throw the appropriate Python | |
23659 | + exception. This macro is for use inside setter functions. */ | |
23660 | +#define GDB_PY_SET_HANDLE_EXCEPTION(Exception) \ | |
23661 | + do { \ | |
23662 | + if (Exception.reason < 0) \ | |
23663 | + { \ | |
23664 | + PyErr_Format (Exception.reason == RETURN_QUIT \ | |
23665 | + ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \ | |
23666 | + "%s", Exception.message); \ | |
23667 | + return -1; \ | |
23668 | + } \ | |
23669 | + } while (0) | |
23670 | + | |
23671 | ||
23672 | void gdbpy_print_stack (void); | |
23673 | ||
23674 | @@ -95,6 +157,21 @@ char *python_string_to_host_string (PyObject *obj); | |
23675 | PyObject *target_string_to_unicode (const gdb_byte *str, int length); | |
23676 | int gdbpy_is_string (PyObject *obj); | |
23677 | ||
23678 | +int gdbpy_is_value_object (PyObject *obj); | |
23679 | + | |
23680 | +/* Note that these are declared here, and not in python.h with the | |
23681 | + other pretty-printer functions, because they refer to PyObject. */ | |
23682 | +char *apply_varobj_pretty_printer (PyObject *print_obj, | |
23683 | + struct value **replacement); | |
23684 | +PyObject *gdbpy_get_varobj_pretty_printer (struct value *value); | |
23685 | +PyObject *gdbpy_instantiate_printer (PyObject *cons, PyObject *value); | |
23686 | +char *gdbpy_get_display_hint (PyObject *printer); | |
23687 | + | |
23688 | +extern PyObject *gdbpy_children_cst; | |
23689 | +extern PyObject *gdbpy_to_string_cst; | |
23690 | +extern PyObject *gdbpy_display_hint_cst; | |
23691 | extern PyObject *gdbpy_doc_cst; | |
23692 | ||
23693 | +int get_addr_from_python (PyObject *obj, CORE_ADDR *addr); | |
23694 | + | |
23695 | #endif /* GDB_PYTHON_INTERNAL_H */ | |
23696 | diff --git a/gdb/python/python-membuf.c b/gdb/python/python-membuf.c | |
23697 | new file mode 100644 | |
23698 | index 0000000..a4c7d74 | |
23699 | --- /dev/null | |
23700 | +++ b/gdb/python/python-membuf.c | |
23701 | @@ -0,0 +1,243 @@ | |
23702 | +/* Python interface to the inferior memory. | |
23703 | + | |
23704 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
23705 | + | |
23706 | + This file is part of GDB. | |
23707 | + | |
23708 | + This program is free software; you can redistribute it and/or modify | |
23709 | + it under the terms of the GNU General Public License as published by | |
23710 | + the Free Software Foundation; either version 3 of the License, or | |
23711 | + (at your option) any later version. | |
23712 | + | |
23713 | + This program is distributed in the hope that it will be useful, | |
23714 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23715 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23716 | + GNU General Public License for more details. | |
23717 | + | |
23718 | + You should have received a copy of the GNU General Public License | |
23719 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
23720 | + | |
23721 | +#include "defs.h" | |
23722 | +#include "exceptions.h" | |
23723 | +#include "gdbcore.h" | |
23724 | +#include "python-internal.h" | |
23725 | + | |
23726 | +typedef struct { | |
23727 | + PyObject_HEAD | |
23728 | + void *buffer; | |
23729 | + | |
23730 | + /* These are kept just for mbpy_str. */ | |
23731 | + CORE_ADDR addr; | |
23732 | + CORE_ADDR length; | |
23733 | +} membuf_object; | |
23734 | + | |
23735 | +static PyTypeObject membuf_object_type; | |
23736 | + | |
23737 | +/* Implementation of gdb.read_memory (address, length). | |
23738 | + Returns a Python buffer object with LENGTH bytes of the inferior's memory | |
23739 | + at ADDRESS. Both arguments are integers. */ | |
23740 | + | |
23741 | +PyObject * | |
23742 | +gdbpy_read_memory (PyObject *self, PyObject *args) | |
23743 | +{ | |
23744 | + CORE_ADDR addr, length; | |
23745 | + void *buffer; | |
23746 | + membuf_object *membuf_obj; | |
23747 | + struct cleanup *cleanups; | |
23748 | + volatile struct gdb_exception except; | |
23749 | + | |
23750 | + /* Assume CORE_ADDR corresponds to unsigned long. */ | |
23751 | + if (! PyArg_ParseTuple (args, "kk", &addr, &length)) | |
23752 | + return NULL; | |
23753 | + | |
23754 | + buffer = xmalloc (length); | |
23755 | + cleanups = make_cleanup (xfree, buffer); | |
23756 | + | |
23757 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
23758 | + { | |
23759 | + read_memory (addr, buffer, length); | |
23760 | + } | |
23761 | + GDB_PY_HANDLE_EXCEPTION (except); | |
23762 | + | |
23763 | + discard_cleanups (cleanups); | |
23764 | + | |
23765 | + membuf_obj = PyObject_New (membuf_object, &membuf_object_type); | |
23766 | + if (membuf_obj == NULL) | |
23767 | + { | |
23768 | + xfree (buffer); | |
23769 | + PyErr_SetString (PyExc_MemoryError, | |
23770 | + "Could not allocate memory buffer object."); | |
23771 | + return NULL; | |
23772 | + } | |
23773 | + | |
23774 | + membuf_obj->buffer = buffer; | |
23775 | + | |
23776 | + membuf_obj->addr = addr; | |
23777 | + membuf_obj->length = length; | |
23778 | + | |
23779 | + return PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0, Py_END_OF_BUFFER); | |
23780 | +} | |
23781 | + | |
23782 | +/* Implementation of gdb.write_memory (address, buffer [, length]). | |
23783 | + Writes the contents of BUFFER (a Python object supporting the read buffer | |
23784 | + protocol) at ADDRESS in the inferior's memory. Write LENGTH bytes from | |
23785 | + BUFFER, or its entire contents if the argument is not provided. The | |
23786 | + function returns nothing. */ | |
23787 | + | |
23788 | +PyObject * | |
23789 | +gdbpy_write_memory (PyObject *self, PyObject *args) | |
23790 | +{ | |
23791 | + int buf_len; | |
23792 | + const char *buffer; | |
23793 | + long length = -1; | |
23794 | + CORE_ADDR addr; | |
23795 | + volatile struct gdb_exception except; | |
23796 | + | |
23797 | + /* Assume CORE_ADDR corresponds to unsigned long. */ | |
23798 | + if (! PyArg_ParseTuple (args, "ks#|l", &addr, &buffer, &buf_len, &length)) | |
23799 | + return NULL; | |
23800 | + | |
23801 | + if (length == -1) | |
23802 | + length = buf_len; | |
23803 | + | |
23804 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
23805 | + { | |
23806 | + write_memory (addr, buffer, length); | |
23807 | + } | |
23808 | + GDB_PY_HANDLE_EXCEPTION (except); | |
23809 | + | |
23810 | + Py_RETURN_NONE; | |
23811 | +} | |
23812 | + | |
23813 | +/* Destructor of Membuf objects. */ | |
23814 | + | |
23815 | +static void | |
23816 | +mbpy_dealloc (PyObject *self) | |
23817 | +{ | |
23818 | + xfree (((membuf_object *) self)->buffer); | |
23819 | + self->ob_type->tp_free (self); | |
23820 | +} | |
23821 | + | |
23822 | +/* Return a description of the Membuf object. */ | |
23823 | + | |
23824 | +static PyObject * | |
23825 | +mbpy_str (PyObject *self) | |
23826 | +{ | |
23827 | + membuf_object *membuf_obj = (membuf_object *) self; | |
23828 | + | |
23829 | + return PyString_FromFormat ("memory buffer for address %s, %s bytes long", | |
23830 | + paddress (membuf_obj->addr), | |
23831 | + pulongest (membuf_obj->length)); | |
23832 | +} | |
23833 | + | |
23834 | +static Py_ssize_t | |
23835 | +get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr) | |
23836 | +{ | |
23837 | + membuf_object *membuf_obj = (membuf_object *) self; | |
23838 | + | |
23839 | + if (segment) | |
23840 | + { | |
23841 | + PyErr_SetString (PyExc_SystemError, | |
23842 | + "The memory buffer supports only one segment."); | |
23843 | + return -1; | |
23844 | + } | |
23845 | + | |
23846 | + *ptrptr = membuf_obj->buffer; | |
23847 | + | |
23848 | + return membuf_obj->length; | |
23849 | +} | |
23850 | + | |
23851 | +static Py_ssize_t | |
23852 | +get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr) | |
23853 | +{ | |
23854 | + return get_read_buffer (self, segment, ptrptr); | |
23855 | +} | |
23856 | + | |
23857 | +static Py_ssize_t | |
23858 | +get_seg_count (PyObject *self, Py_ssize_t *lenp) | |
23859 | +{ | |
23860 | + if (lenp) | |
23861 | + *lenp = ((membuf_object *) self)->length; | |
23862 | + | |
23863 | + return 1; | |
23864 | +} | |
23865 | + | |
23866 | +static Py_ssize_t | |
23867 | +get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr) | |
23868 | +{ | |
23869 | + void *ptr = NULL; | |
23870 | + Py_ssize_t ret; | |
23871 | + | |
23872 | + ret = get_read_buffer (self, segment, &ptr); | |
23873 | + *ptrptr = (char *) ptr; | |
23874 | + | |
23875 | + return ret; | |
23876 | +} | |
23877 | + | |
23878 | +/* Python doesn't provide a decent way to get compatibility here. */ | |
23879 | +#if HAVE_LIBPYTHON2_4 | |
23880 | +#define CHARBUFFERPROC_NAME getcharbufferproc | |
23881 | +#else | |
23882 | +#define CHARBUFFERPROC_NAME charbufferproc | |
23883 | +#endif | |
23884 | + | |
23885 | +static PyBufferProcs buffer_procs = { | |
23886 | + get_read_buffer, | |
23887 | + get_write_buffer, | |
23888 | + get_seg_count, | |
23889 | + /* The cast here works around a difference between Python 2.4 and | |
23890 | + Python 2.5. */ | |
23891 | + (CHARBUFFERPROC_NAME) get_char_buffer | |
23892 | +}; | |
23893 | + | |
23894 | +static PyTypeObject membuf_object_type = { | |
23895 | + PyObject_HEAD_INIT (NULL) | |
23896 | + 0, /*ob_size*/ | |
23897 | + "gdb.Membuf", /*tp_name*/ | |
23898 | + sizeof (membuf_object), /*tp_basicsize*/ | |
23899 | + 0, /*tp_itemsize*/ | |
23900 | + mbpy_dealloc, /*tp_dealloc*/ | |
23901 | + 0, /*tp_print*/ | |
23902 | + 0, /*tp_getattr*/ | |
23903 | + 0, /*tp_setattr*/ | |
23904 | + 0, /*tp_compare*/ | |
23905 | + 0, /*tp_repr*/ | |
23906 | + 0, /*tp_as_number*/ | |
23907 | + 0, /*tp_as_sequence*/ | |
23908 | + 0, /*tp_as_mapping*/ | |
23909 | + 0, /*tp_hash */ | |
23910 | + 0, /*tp_call*/ | |
23911 | + mbpy_str, /*tp_str*/ | |
23912 | + 0, /*tp_getattro*/ | |
23913 | + 0, /*tp_setattro*/ | |
23914 | + &buffer_procs, /*tp_as_buffer*/ | |
23915 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
23916 | + "GDB memory buffer object", /*tp_doc*/ | |
23917 | + 0, /* tp_traverse */ | |
23918 | + 0, /* tp_clear */ | |
23919 | + 0, /* tp_richcompare */ | |
23920 | + 0, /* tp_weaklistoffset */ | |
23921 | + 0, /* tp_iter */ | |
23922 | + 0, /* tp_iternext */ | |
23923 | + 0, /* tp_methods */ | |
23924 | + 0, /* tp_members */ | |
23925 | + 0, /* tp_getset */ | |
23926 | + 0, /* tp_base */ | |
23927 | + 0, /* tp_dict */ | |
23928 | + 0, /* tp_descr_get */ | |
23929 | + 0, /* tp_descr_set */ | |
23930 | + 0, /* tp_dictoffset */ | |
23931 | + 0, /* tp_init */ | |
23932 | + 0, /* tp_alloc */ | |
23933 | + PyType_GenericNew /* tp_new */ | |
23934 | +}; | |
23935 | + | |
23936 | +void | |
23937 | +gdbpy_initialize_membuf (void) | |
23938 | +{ | |
23939 | + if (PyType_Ready (&membuf_object_type) < 0) | |
23940 | + return; | |
23941 | + | |
23942 | + Py_INCREF (&membuf_object_type); | |
23943 | + PyModule_AddObject (gdb_module, "Membuf", (PyObject *) &membuf_object_type); | |
23944 | +} | |
23945 | diff --git a/gdb/python/python-objfile.c b/gdb/python/python-objfile.c | |
23946 | new file mode 100644 | |
23947 | index 0000000..e97d3a2 | |
23948 | --- /dev/null | |
23949 | +++ b/gdb/python/python-objfile.c | |
23950 | @@ -0,0 +1,221 @@ | |
23951 | +/* Python interface to objfiles. | |
23952 | + | |
23953 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
23954 | + | |
23955 | + This file is part of GDB. | |
23956 | + | |
23957 | + This program is free software; you can redistribute it and/or modify | |
23958 | + it under the terms of the GNU General Public License as published by | |
23959 | + the Free Software Foundation; either version 3 of the License, or | |
23960 | + (at your option) any later version. | |
23961 | + | |
23962 | + This program is distributed in the hope that it will be useful, | |
23963 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23964 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23965 | + GNU General Public License for more details. | |
23966 | + | |
23967 | + You should have received a copy of the GNU General Public License | |
23968 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
23969 | + | |
23970 | +#include "defs.h" | |
23971 | +#include "python-internal.h" | |
23972 | +#include "charset.h" | |
23973 | +#include "objfiles.h" | |
23974 | + | |
23975 | +typedef struct | |
23976 | +{ | |
23977 | + PyObject_HEAD | |
23978 | + | |
23979 | + /* The corresponding objfile. */ | |
23980 | + struct objfile *objfile; | |
23981 | + | |
23982 | + /* The pretty-printer list of functions. */ | |
23983 | + PyObject *printers; | |
23984 | +} objfile_object; | |
23985 | + | |
23986 | +static PyTypeObject objfile_object_type; | |
23987 | + | |
23988 | +static const struct objfile_data *objfpy_objfile_data_key; | |
23989 | + | |
23990 | +\f | |
23991 | + | |
23992 | +/* An Objfile method which returns the objfile's file name, or None. */ | |
23993 | +static PyObject * | |
23994 | +objfpy_get_filename (PyObject *self, void *closure) | |
23995 | +{ | |
23996 | + objfile_object *obj = (objfile_object *) self; | |
23997 | + if (obj->objfile && obj->objfile->name) | |
23998 | + return PyString_Decode (obj->objfile->name, strlen (obj->objfile->name), | |
23999 | + host_charset (), NULL); | |
24000 | + Py_RETURN_NONE; | |
24001 | +} | |
24002 | + | |
24003 | +static void | |
24004 | +objfpy_dealloc (PyObject *o) | |
24005 | +{ | |
24006 | + objfile_object *self = (objfile_object *) o; | |
24007 | + Py_XDECREF (self->printers); | |
24008 | + self->ob_type->tp_free ((PyObject *) self); | |
24009 | +} | |
24010 | + | |
24011 | +static PyObject * | |
24012 | +objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords) | |
24013 | +{ | |
24014 | + objfile_object *self = (objfile_object *) type->tp_alloc (type, 0); | |
24015 | + if (self) | |
24016 | + { | |
24017 | + self->objfile = NULL; | |
24018 | + | |
24019 | + self->printers = PyList_New (0); | |
24020 | + if (!self->printers) | |
24021 | + { | |
24022 | + Py_DECREF (self); | |
24023 | + return NULL; | |
24024 | + } | |
24025 | + } | |
24026 | + return (PyObject *) self; | |
24027 | +} | |
24028 | + | |
24029 | +PyObject * | |
24030 | +objfpy_get_printers (PyObject *o, void *ignore) | |
24031 | +{ | |
24032 | + objfile_object *self = (objfile_object *) o; | |
24033 | + Py_INCREF (self->printers); | |
24034 | + return self->printers; | |
24035 | +} | |
24036 | + | |
24037 | +static int | |
24038 | +objfpy_set_printers (PyObject *o, PyObject *value, void *ignore) | |
24039 | +{ | |
24040 | + objfile_object *self = (objfile_object *) o; | |
24041 | + if (! value) | |
24042 | + { | |
24043 | + PyErr_SetString (PyExc_TypeError, | |
24044 | + "cannot delete the pretty_printers attribute"); | |
24045 | + return -1; | |
24046 | + } | |
24047 | + | |
24048 | + if (! PyList_Check (value)) | |
24049 | + { | |
24050 | + PyErr_SetString (PyExc_TypeError, | |
24051 | + "the pretty_printers attribute must be a list"); | |
24052 | + return -1; | |
24053 | + } | |
24054 | + | |
24055 | + Py_XDECREF (self->printers); | |
24056 | + Py_INCREF (value); | |
24057 | + self->printers = value; | |
24058 | + | |
24059 | + return 0; | |
24060 | +} | |
24061 | + | |
24062 | +\f | |
24063 | + | |
24064 | +/* Clear the OBJFILE pointer in an Objfile object and remove the | |
24065 | + reference. */ | |
24066 | +static void | |
24067 | +clean_up_objfile (struct objfile *objfile, void *datum) | |
24068 | +{ | |
24069 | + objfile_object *object = datum; | |
24070 | + object->objfile = NULL; | |
24071 | + Py_DECREF ((PyObject *) object); | |
24072 | +} | |
24073 | + | |
24074 | +/* Return the Python object of type Objfile representing OBJFILE. If | |
24075 | + the object has already been created, return it. Otherwise, create | |
24076 | + it. Return NULL and set the Python error on failure. */ | |
24077 | +PyObject * | |
24078 | +objfile_to_objfile_object (struct objfile *objfile) | |
24079 | +{ | |
24080 | + objfile_object *object; | |
24081 | + | |
24082 | + object = objfile_data (objfile, objfpy_objfile_data_key); | |
24083 | + if (!object) | |
24084 | + { | |
24085 | + object = PyObject_New (objfile_object, &objfile_object_type); | |
24086 | + if (object) | |
24087 | + { | |
24088 | + PyObject *dict; | |
24089 | + | |
24090 | + object->objfile = objfile; | |
24091 | + | |
24092 | + object->printers = PyList_New (0); | |
24093 | + if (!object->printers) | |
24094 | + { | |
24095 | + Py_DECREF (object); | |
24096 | + return NULL; | |
24097 | + } | |
24098 | + | |
24099 | + set_objfile_data (objfile, objfpy_objfile_data_key, object); | |
24100 | + } | |
24101 | + } | |
24102 | + | |
24103 | + return (PyObject *) object; | |
24104 | +} | |
24105 | + | |
24106 | +void | |
24107 | +gdbpy_initialize_objfile (void) | |
24108 | +{ | |
24109 | + objfpy_objfile_data_key | |
24110 | + = register_objfile_data_with_cleanup (clean_up_objfile); | |
24111 | + | |
24112 | + if (PyType_Ready (&objfile_object_type) < 0) | |
24113 | + return; | |
24114 | + | |
24115 | + Py_INCREF (&objfile_object_type); | |
24116 | + PyModule_AddObject (gdb_module, "Objfile", (PyObject *) &objfile_object_type); | |
24117 | +} | |
24118 | + | |
24119 | +\f | |
24120 | + | |
24121 | +static PyGetSetDef objfile_getset[] = | |
24122 | +{ | |
24123 | + { "filename", objfpy_get_filename, NULL, | |
24124 | + "The objfile's filename, or None.", NULL }, | |
24125 | + { "pretty_printers", objfpy_get_printers, objfpy_set_printers, | |
24126 | + "Pretty printers.", NULL }, | |
24127 | + { NULL } | |
24128 | +}; | |
24129 | + | |
24130 | +static PyTypeObject objfile_object_type = | |
24131 | +{ | |
24132 | + PyObject_HEAD_INIT (NULL) | |
24133 | + 0, /*ob_size*/ | |
24134 | + "gdb.Objfile", /*tp_name*/ | |
24135 | + sizeof (objfile_object), /*tp_basicsize*/ | |
24136 | + 0, /*tp_itemsize*/ | |
24137 | + objfpy_dealloc, /*tp_dealloc*/ | |
24138 | + 0, /*tp_print*/ | |
24139 | + 0, /*tp_getattr*/ | |
24140 | + 0, /*tp_setattr*/ | |
24141 | + 0, /*tp_compare*/ | |
24142 | + 0, /*tp_repr*/ | |
24143 | + 0, /*tp_as_number*/ | |
24144 | + 0, /*tp_as_sequence*/ | |
24145 | + 0, /*tp_as_mapping*/ | |
24146 | + 0, /*tp_hash */ | |
24147 | + 0, /*tp_call*/ | |
24148 | + 0, /*tp_str*/ | |
24149 | + 0, /*tp_getattro*/ | |
24150 | + 0, /*tp_setattro*/ | |
24151 | + 0, /*tp_as_buffer*/ | |
24152 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
24153 | + "GDB objfile object", /* tp_doc */ | |
24154 | + 0, /* tp_traverse */ | |
24155 | + 0, /* tp_clear */ | |
24156 | + 0, /* tp_richcompare */ | |
24157 | + 0, /* tp_weaklistoffset */ | |
24158 | + 0, /* tp_iter */ | |
24159 | + 0, /* tp_iternext */ | |
24160 | + 0, /* tp_methods */ | |
24161 | + 0, /* tp_members */ | |
24162 | + objfile_getset, /* tp_getset */ | |
24163 | + 0, /* tp_base */ | |
24164 | + 0, /* tp_dict */ | |
24165 | + 0, /* tp_descr_get */ | |
24166 | + 0, /* tp_descr_set */ | |
24167 | + 0, /* tp_dictoffset */ | |
24168 | + 0, /* tp_init */ | |
24169 | + 0, /* tp_alloc */ | |
24170 | + objfpy_new, /* tp_new */ | |
24171 | +}; | |
24172 | diff --git a/gdb/python/python-param.c b/gdb/python/python-param.c | |
24173 | new file mode 100644 | |
24174 | index 0000000..1f591a8 | |
24175 | --- /dev/null | |
24176 | +++ b/gdb/python/python-param.c | |
24177 | @@ -0,0 +1,606 @@ | |
24178 | +/* gdb parameters implemented in Python | |
24179 | + | |
24180 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
24181 | + | |
24182 | + This file is part of GDB. | |
24183 | + | |
24184 | + This program is free software; you can redistribute it and/or modify | |
24185 | + it under the terms of the GNU General Public License as published by | |
24186 | + the Free Software Foundation; either version 3 of the License, or | |
24187 | + (at your option) any later version. | |
24188 | + | |
24189 | + This program is distributed in the hope that it will be useful, | |
24190 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24191 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24192 | + GNU General Public License for more details. | |
24193 | + | |
24194 | + You should have received a copy of the GNU General Public License | |
24195 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
24196 | + | |
24197 | + | |
24198 | +#include "defs.h" | |
24199 | +#include "value.h" | |
24200 | +#include "exceptions.h" | |
24201 | +#include "python-internal.h" | |
24202 | +#include "charset.h" | |
24203 | +#include "gdbcmd.h" | |
24204 | +#include "cli/cli-decode.h" | |
24205 | +#include "completer.h" | |
24206 | + | |
24207 | +/* Parameter constants and their values. */ | |
24208 | +struct parm_constant | |
24209 | +{ | |
24210 | + char *name; | |
24211 | + int value; | |
24212 | +}; | |
24213 | + | |
24214 | +struct parm_constant parm_constants[] = | |
24215 | +{ | |
24216 | + { "PARAM_BOOLEAN", var_boolean }, | |
24217 | + { "PARAM_AUTO_BOOLEAN", var_auto_boolean }, | |
24218 | + { "PARAM_UINTEGER", var_uinteger }, | |
24219 | + { "PARAM_INTEGER", var_integer }, | |
24220 | + { "PARAM_STRING", var_string }, | |
24221 | + { "PARAM_STRING_NOESCAPE", var_string_noescape }, | |
24222 | + { "PARAM_OPTIONAL_FILENAME", var_optional_filename }, | |
24223 | + { "PARAM_FILENAME", var_filename }, | |
24224 | + { "PARAM_ZINTEGER", var_zinteger }, | |
24225 | + { "PARAM_ENUM", var_enum }, | |
24226 | + { NULL, 0 } | |
24227 | +}; | |
24228 | + | |
24229 | +/* A union that can hold anything described by enum var_types. */ | |
24230 | +union parmpy_variable | |
24231 | +{ | |
24232 | + /* Hold an integer value, for boolean and integer types. */ | |
24233 | + int intval; | |
24234 | + | |
24235 | + /* Hold an auto_boolean. */ | |
24236 | + enum auto_boolean autoboolval; | |
24237 | + | |
24238 | + /* Hold an unsigned integer value, for uinteger. */ | |
24239 | + unsigned int uintval; | |
24240 | + | |
24241 | + /* Hold a string, for the various string types. */ | |
24242 | + char *stringval; | |
24243 | + | |
24244 | + /* Hold a string, for enums. */ | |
24245 | + const char *cstringval; | |
24246 | +}; | |
24247 | + | |
24248 | +/* A gdb parameter. */ | |
24249 | +struct parmpy_object | |
24250 | +{ | |
24251 | + PyObject_HEAD | |
24252 | + | |
24253 | + /* The type of the parameter. */ | |
24254 | + enum var_types type; | |
24255 | + | |
24256 | + /* The value of the parameter. */ | |
24257 | + union parmpy_variable value; | |
24258 | + | |
24259 | + /* For an enum command, the possible values. The vector is | |
24260 | + allocated with xmalloc, as is each element. It is | |
24261 | + NULL-terminated. */ | |
24262 | + const char **enumeration; | |
24263 | +}; | |
24264 | + | |
24265 | +typedef struct parmpy_object parmpy_object; | |
24266 | + | |
24267 | +static PyTypeObject parmpy_object_type; | |
24268 | + | |
24269 | +/* Some handy string constants. */ | |
24270 | +static PyObject *set_doc_cst; | |
24271 | +static PyObject *show_doc_cst; | |
24272 | + | |
24273 | +\f | |
24274 | + | |
24275 | +/* Get an attribute. */ | |
24276 | +static PyObject * | |
24277 | +get_attr (PyObject *obj, PyObject *attr_name) | |
24278 | +{ | |
24279 | + if (PyString_Check (attr_name) | |
24280 | + && ! strcmp (PyString_AsString (attr_name), "value")) | |
24281 | + { | |
24282 | + parmpy_object *self = (parmpy_object *) obj; | |
24283 | + return gdbpy_parameter_value (self->type, &self->value); | |
24284 | + } | |
24285 | + | |
24286 | + return PyObject_GenericGetAttr (obj, attr_name); | |
24287 | +} | |
24288 | + | |
24289 | +/* Set a parameter value from a Python value. Return 0 on success, -1 | |
24290 | + on failure. */ | |
24291 | +static int | |
24292 | +set_parameter_value (parmpy_object *self, PyObject *value) | |
24293 | +{ | |
24294 | + int cmp; | |
24295 | + | |
24296 | + switch (self->type) | |
24297 | + { | |
24298 | + case var_string: | |
24299 | + case var_string_noescape: | |
24300 | + case var_optional_filename: | |
24301 | + case var_filename: | |
24302 | + if (! gdbpy_is_string (value) | |
24303 | + && (self->type == var_filename | |
24304 | + || value != Py_None)) | |
24305 | + { | |
24306 | + PyErr_SetString (PyExc_RuntimeError, "string required"); | |
24307 | + return -1; | |
24308 | + } | |
24309 | + if (self->value.stringval) | |
24310 | + xfree (self->value.stringval); | |
24311 | + if (value == Py_None) | |
24312 | + { | |
24313 | + if (self->type == var_optional_filename) | |
24314 | + self->value.stringval = xstrdup (""); | |
24315 | + else | |
24316 | + self->value.stringval = NULL; | |
24317 | + } | |
24318 | + else | |
24319 | + self->value.stringval = python_string_to_host_string (value); | |
24320 | + break; | |
24321 | + | |
24322 | + case var_enum: | |
24323 | + { | |
24324 | + int i; | |
24325 | + char *str; | |
24326 | + | |
24327 | + if (! gdbpy_is_string (value)) | |
24328 | + { | |
24329 | + PyErr_SetString (PyExc_RuntimeError, "string required"); | |
24330 | + return -1; | |
24331 | + } | |
24332 | + | |
24333 | + str = python_string_to_host_string (value); | |
24334 | + for (i = 0; self->enumeration[i]; ++i) | |
24335 | + if (! strcmp (self->enumeration[i], str)) | |
24336 | + break; | |
24337 | + xfree (str); | |
24338 | + if (! self->enumeration[i]) | |
24339 | + { | |
24340 | + PyErr_SetString (PyExc_RuntimeError, | |
24341 | + "value must be member of enumeration"); | |
24342 | + return -1; | |
24343 | + } | |
24344 | + self->value.cstringval = self->enumeration[i]; | |
24345 | + break; | |
24346 | + } | |
24347 | + | |
24348 | + case var_boolean: | |
24349 | + if (! PyBool_Check (value)) | |
24350 | + { | |
24351 | + PyErr_SetString (PyExc_RuntimeError, "boolean required"); | |
24352 | + return -1; | |
24353 | + } | |
24354 | + cmp = PyObject_IsTrue (value); | |
24355 | + if (cmp < 0) | |
24356 | + return -1; | |
24357 | + self->value.intval = cmp; | |
24358 | + break; | |
24359 | + | |
24360 | + case var_auto_boolean: | |
24361 | + if (! PyBool_Check (value) && value != Py_None) | |
24362 | + { | |
24363 | + PyErr_SetString (PyExc_RuntimeError, | |
24364 | + "boolean or None required"); | |
24365 | + return -1; | |
24366 | + } | |
24367 | + | |
24368 | + if (value == Py_None) | |
24369 | + self->value.autoboolval = AUTO_BOOLEAN_AUTO; | |
24370 | + else | |
24371 | + { | |
24372 | + cmp = PyObject_IsTrue (value); | |
24373 | + if (cmp < 0 ) | |
24374 | + return -1; | |
24375 | + if (cmp == 1) | |
24376 | + self->value.autoboolval = AUTO_BOOLEAN_TRUE; | |
24377 | + else | |
24378 | + self->value.autoboolval = AUTO_BOOLEAN_FALSE; | |
24379 | + | |
24380 | + break; | |
24381 | + } | |
24382 | + | |
24383 | + case var_integer: | |
24384 | + case var_zinteger: | |
24385 | + case var_uinteger: | |
24386 | + { | |
24387 | + long l; | |
24388 | + int ok; | |
24389 | + | |
24390 | + if (! PyInt_Check (value)) | |
24391 | + { | |
24392 | + PyErr_SetString (PyExc_RuntimeError, "value must be integer"); | |
24393 | + return -1; | |
24394 | + } | |
24395 | + | |
24396 | + l = PyInt_AsLong (value); | |
24397 | + if (self->type == var_uinteger) | |
24398 | + { | |
24399 | + ok = (l >= 0 && l <= UINT_MAX); | |
24400 | + if (l == 0) | |
24401 | + l = UINT_MAX; | |
24402 | + } | |
24403 | + else if (self->type == var_integer) | |
24404 | + { | |
24405 | + ok = (l >= INT_MIN && l <= INT_MAX); | |
24406 | + if (l == 0) | |
24407 | + l = INT_MAX; | |
24408 | + } | |
24409 | + else | |
24410 | + ok = (l >= INT_MIN && l <= INT_MAX); | |
24411 | + | |
24412 | + if (! ok) | |
24413 | + { | |
24414 | + PyErr_SetString (PyExc_RuntimeError, "range exceeded"); | |
24415 | + return -1; | |
24416 | + } | |
24417 | + | |
24418 | + self->value.intval = (int) l; | |
24419 | + break; | |
24420 | + } | |
24421 | + | |
24422 | + default: | |
24423 | + PyErr_SetString (PyExc_RuntimeError, "programmer error: unhandled type"); | |
24424 | + return -1; | |
24425 | + } | |
24426 | + | |
24427 | + return 0; | |
24428 | +} | |
24429 | + | |
24430 | +/* Set an attribute. */ | |
24431 | +static int | |
24432 | +set_attr (PyObject *obj, PyObject *attr_name, PyObject *val) | |
24433 | +{ | |
24434 | + if (PyString_Check (attr_name) | |
24435 | + && ! strcmp (PyString_AsString (attr_name), "value")) | |
24436 | + { | |
24437 | + if (!val) | |
24438 | + { | |
24439 | + PyErr_SetString (PyExc_RuntimeError, | |
24440 | + "cannot delete a parameter's value"); | |
24441 | + return -1; | |
24442 | + } | |
24443 | + return set_parameter_value ((parmpy_object *) obj, val); | |
24444 | + } | |
24445 | + | |
24446 | + return PyObject_GenericSetAttr (obj, attr_name, val); | |
24447 | +} | |
24448 | + | |
24449 | +\f | |
24450 | + | |
24451 | +/* A helper function that dispatches to the appropriate add_setshow | |
24452 | + function. */ | |
24453 | +static void | |
24454 | +add_setshow_generic (int parmclass, enum command_class cmdclass, | |
24455 | + char *cmd_name, parmpy_object *self, | |
24456 | + char *set_doc, char *show_doc, char *help_doc, | |
24457 | + struct cmd_list_element **set_list, | |
24458 | + struct cmd_list_element **show_list) | |
24459 | +{ | |
24460 | + switch (parmclass) | |
24461 | + { | |
24462 | + case var_boolean: | |
24463 | + add_setshow_boolean_cmd (cmd_name, cmdclass, &self->value.intval, | |
24464 | + set_doc, show_doc, help_doc, | |
24465 | + NULL, NULL, set_list, show_list); | |
24466 | + break; | |
24467 | + | |
24468 | + case var_auto_boolean: | |
24469 | + add_setshow_auto_boolean_cmd (cmd_name, cmdclass, | |
24470 | + &self->value.autoboolval, | |
24471 | + set_doc, show_doc, help_doc, | |
24472 | + NULL, NULL, set_list, show_list); | |
24473 | + break; | |
24474 | + | |
24475 | + case var_uinteger: | |
24476 | + add_setshow_uinteger_cmd (cmd_name, cmdclass, &self->value.uintval, | |
24477 | + set_doc, show_doc, help_doc, | |
24478 | + NULL, NULL, set_list, show_list); | |
24479 | + break; | |
24480 | + | |
24481 | + case var_integer: | |
24482 | + add_setshow_integer_cmd (cmd_name, cmdclass, &self->value.intval, | |
24483 | + set_doc, show_doc, help_doc, | |
24484 | + NULL, NULL, set_list, show_list); | |
24485 | + break; | |
24486 | + | |
24487 | + case var_string: | |
24488 | + add_setshow_string_cmd (cmd_name, cmdclass, &self->value.stringval, | |
24489 | + set_doc, show_doc, help_doc, | |
24490 | + NULL, NULL, set_list, show_list); | |
24491 | + break; | |
24492 | + | |
24493 | + case var_string_noescape: | |
24494 | + add_setshow_string_noescape_cmd (cmd_name, cmdclass, | |
24495 | + &self->value.stringval, | |
24496 | + set_doc, show_doc, help_doc, | |
24497 | + NULL, NULL, set_list, show_list); | |
24498 | + break; | |
24499 | + | |
24500 | + case var_optional_filename: | |
24501 | + add_setshow_optional_filename_cmd (cmd_name, cmdclass, | |
24502 | + &self->value.stringval, | |
24503 | + set_doc, show_doc, help_doc, | |
24504 | + NULL, NULL, set_list, show_list); | |
24505 | + break; | |
24506 | + | |
24507 | + case var_filename: | |
24508 | + add_setshow_filename_cmd (cmd_name, cmdclass, &self->value.stringval, | |
24509 | + set_doc, show_doc, help_doc, | |
24510 | + NULL, NULL, set_list, show_list); | |
24511 | + break; | |
24512 | + | |
24513 | + case var_zinteger: | |
24514 | + add_setshow_zinteger_cmd (cmd_name, cmdclass, &self->value.intval, | |
24515 | + set_doc, show_doc, help_doc, | |
24516 | + NULL, NULL, set_list, show_list); | |
24517 | + break; | |
24518 | + | |
24519 | + case var_enum: | |
24520 | + add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration, | |
24521 | + &self->value.cstringval, | |
24522 | + set_doc, show_doc, help_doc, | |
24523 | + NULL, NULL, set_list, show_list); | |
24524 | + /* Initialize the value, just in case. */ | |
24525 | + self->value.cstringval = self->enumeration[0]; | |
24526 | + break; | |
24527 | + } | |
24528 | +} | |
24529 | + | |
24530 | +/* A helper which computes enum values. Returns 1 on success, 0 on | |
24531 | + error. */ | |
24532 | +static int | |
24533 | +compute_enum_values (parmpy_object *self, PyObject *enum_values) | |
24534 | +{ | |
24535 | + Py_ssize_t size, i; | |
24536 | + | |
24537 | + if (! enum_values) | |
24538 | + { | |
24539 | + PyErr_SetString (PyExc_RuntimeError, | |
24540 | + "enumeration required for PARAM_ENUM"); | |
24541 | + return 0; | |
24542 | + } | |
24543 | + | |
24544 | + if (! PySequence_Check (enum_values)) | |
24545 | + { | |
24546 | + PyErr_SetString (PyExc_RuntimeError, "enumeration is not a sequence"); | |
24547 | + return 0; | |
24548 | + } | |
24549 | + | |
24550 | + size = PySequence_Size (enum_values); | |
24551 | + if (size < 0) | |
24552 | + return 0; | |
24553 | + if (size == 0) | |
24554 | + { | |
24555 | + PyErr_SetString (PyExc_RuntimeError, "empty enumeration"); | |
24556 | + return 0; | |
24557 | + } | |
24558 | + | |
24559 | + self->enumeration = xmalloc ((size + 1) * sizeof (char *)); | |
24560 | + memset (self->enumeration, 0, (size + 1) * sizeof (char *)); | |
24561 | + | |
24562 | + for (i = 0; i < size; ++i) | |
24563 | + { | |
24564 | + PyObject *item = PySequence_GetItem (enum_values, i); | |
24565 | + if (! item) | |
24566 | + return 0; | |
24567 | + if (! gdbpy_is_string (item)) | |
24568 | + { | |
24569 | + PyErr_SetString (PyExc_RuntimeError, "enumeration item not a string"); | |
24570 | + return 0; | |
24571 | + } | |
24572 | + self->enumeration[i] = python_string_to_host_string (item); | |
24573 | + } | |
24574 | + | |
24575 | + return 1; | |
24576 | +} | |
24577 | + | |
24578 | +/* A helper function which returns a documentation string for an | |
24579 | + object. */ | |
24580 | +static char * | |
24581 | +get_doc_string (PyObject *object, PyObject *attr) | |
24582 | +{ | |
24583 | + char *result = NULL; | |
24584 | + if (PyObject_HasAttr (object, attr)) | |
24585 | + { | |
24586 | + PyObject *ds_obj = PyObject_GetAttr (object, attr); | |
24587 | + if (ds_obj && gdbpy_is_string (ds_obj)) | |
24588 | + result = python_string_to_host_string (ds_obj); | |
24589 | + } | |
24590 | + if (! result) | |
24591 | + result = xstrdup ("This command is not documented."); | |
24592 | + return result; | |
24593 | +} | |
24594 | + | |
24595 | +/* Object initializer; sets up gdb-side structures for command. | |
24596 | + | |
24597 | + Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM]) | |
24598 | + | |
24599 | + NAME is the name of the parameter. It may consist of multiple | |
24600 | + words, in which case the final word is the name of the new command, | |
24601 | + and earlier words must be prefix commands. | |
24602 | + | |
24603 | + CMDCLASS is the kind of command. It should be one of the COMMAND_* | |
24604 | + constants defined in the gdb module. | |
24605 | + | |
24606 | + PARMCLASS is the type of the parameter. It should be one of the | |
24607 | + PARAM_* constants defined in the gdb module. | |
24608 | + | |
24609 | + If PARMCLASS is PARAM_ENUM, then the final argument should be a | |
24610 | + collection of strings. These strings are the valid values for this | |
24611 | + parameter. | |
24612 | + | |
24613 | + The documentation for the parameter is taken from the doc string | |
24614 | + for the python class. | |
24615 | + | |
24616 | +*/ | |
24617 | +static int | |
24618 | +parmpy_init (PyObject *self, PyObject *args, PyObject *kwds) | |
24619 | +{ | |
24620 | + parmpy_object *obj = (parmpy_object *) self; | |
24621 | + char *name; | |
24622 | + char *set_doc, *show_doc, *doc; | |
24623 | + char *cmd_name; | |
24624 | + int parmclass, cmdtype; | |
24625 | + PyObject *enum_values = NULL; | |
24626 | + struct cmd_list_element *cmd_list; | |
24627 | + struct cmd_list_element **set_list, **show_list; | |
24628 | + volatile struct gdb_exception except; | |
24629 | + | |
24630 | + if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass, | |
24631 | + &enum_values)) | |
24632 | + return -1; | |
24633 | + | |
24634 | + if (cmdtype != no_class && cmdtype != class_run | |
24635 | + && cmdtype != class_vars && cmdtype != class_stack | |
24636 | + && cmdtype != class_files && cmdtype != class_support | |
24637 | + && cmdtype != class_info && cmdtype != class_breakpoint | |
24638 | + && cmdtype != class_trace && cmdtype != class_obscure | |
24639 | + && cmdtype != class_maintenance) | |
24640 | + { | |
24641 | + PyErr_Format (PyExc_RuntimeError, "invalid command class argument"); | |
24642 | + return -1; | |
24643 | + } | |
24644 | + | |
24645 | + if (parmclass != var_boolean && parmclass != var_auto_boolean | |
24646 | + && parmclass != var_uinteger && parmclass != var_integer | |
24647 | + && parmclass != var_string && parmclass != var_string_noescape | |
24648 | + && parmclass != var_optional_filename && parmclass != var_filename | |
24649 | + && parmclass != var_zinteger && parmclass != var_enum) | |
24650 | + { | |
24651 | + PyErr_SetString (PyExc_RuntimeError, "invalid parameter class argument"); | |
24652 | + return -1; | |
24653 | + } | |
24654 | + | |
24655 | + if (enum_values && parmclass != var_enum) | |
24656 | + { | |
24657 | + PyErr_SetString (PyExc_RuntimeError, | |
24658 | + "only PARAM_ENUM accepts a fourth argument"); | |
24659 | + return -1; | |
24660 | + } | |
24661 | + if (parmclass == var_enum) | |
24662 | + { | |
24663 | + if (! compute_enum_values (obj, enum_values)) | |
24664 | + return -1; | |
24665 | + } | |
24666 | + | |
24667 | + obj->type = (enum var_types) parmclass; | |
24668 | + memset (&obj->value, 0, sizeof (obj->value)); | |
24669 | + obj->enumeration = NULL; | |
24670 | + | |
24671 | + cmd_name = gdbpy_parse_command_name (name, &set_list, &setlist); | |
24672 | + if (! cmd_name) | |
24673 | + return -1; | |
24674 | + xfree (cmd_name); | |
24675 | + cmd_name = gdbpy_parse_command_name (name, &show_list, &showlist); | |
24676 | + if (! cmd_name) | |
24677 | + return -1; | |
24678 | + | |
24679 | + /* FIXME: there is no way to register a destructor function for | |
24680 | + set/show commands. So, these are leaked. */ | |
24681 | + set_doc = get_doc_string (self, set_doc_cst); | |
24682 | + show_doc = get_doc_string (self, show_doc_cst); | |
24683 | + doc = get_doc_string (self, gdbpy_doc_cst); | |
24684 | + | |
24685 | + Py_INCREF (self); | |
24686 | + | |
24687 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
24688 | + { | |
24689 | + add_setshow_generic (parmclass, (enum command_class) cmdtype, | |
24690 | + cmd_name, obj, | |
24691 | + set_doc, show_doc, | |
24692 | + doc, set_list, show_list); | |
24693 | + } | |
24694 | + if (except.reason < 0) | |
24695 | + { | |
24696 | + xfree (cmd_name); | |
24697 | + xfree (set_doc); | |
24698 | + xfree (show_doc); | |
24699 | + xfree (doc); | |
24700 | + Py_DECREF (self); | |
24701 | + PyErr_Format (except.reason == RETURN_QUIT | |
24702 | + ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, | |
24703 | + "%s", except.message); | |
24704 | + return -1; | |
24705 | + } | |
24706 | + return 0; | |
24707 | +} | |
24708 | + | |
24709 | +\f | |
24710 | + | |
24711 | +/* Initialize the 'parameters' module. */ | |
24712 | +void | |
24713 | +gdbpy_initialize_parameters (void) | |
24714 | +{ | |
24715 | + int i; | |
24716 | + | |
24717 | + if (PyType_Ready (&parmpy_object_type) < 0) | |
24718 | + return; | |
24719 | + | |
24720 | + set_doc_cst = PyString_FromString ("set_doc"); | |
24721 | + if (! set_doc_cst) | |
24722 | + return; | |
24723 | + show_doc_cst = PyString_FromString ("show_doc"); | |
24724 | + if (! show_doc_cst) | |
24725 | + return; | |
24726 | + | |
24727 | + for (i = 0; parm_constants[i].name; ++i) | |
24728 | + { | |
24729 | + if (PyModule_AddIntConstant (gdb_module, | |
24730 | + parm_constants[i].name, | |
24731 | + parm_constants[i].value) < 0) | |
24732 | + return; | |
24733 | + } | |
24734 | + | |
24735 | + Py_INCREF (&parmpy_object_type); | |
24736 | + PyModule_AddObject (gdb_module, "Parameter", | |
24737 | + (PyObject *) &parmpy_object_type); | |
24738 | +} | |
24739 | + | |
24740 | +\f | |
24741 | + | |
24742 | +static PyTypeObject parmpy_object_type = | |
24743 | +{ | |
24744 | + PyObject_HEAD_INIT (NULL) | |
24745 | + 0, /*ob_size*/ | |
24746 | + "gdb.Parameter", /*tp_name*/ | |
24747 | + sizeof (parmpy_object), /*tp_basicsize*/ | |
24748 | + 0, /*tp_itemsize*/ | |
24749 | + 0, /*tp_dealloc*/ | |
24750 | + 0, /*tp_print*/ | |
24751 | + 0, /*tp_getattr*/ | |
24752 | + 0, /*tp_setattr*/ | |
24753 | + 0, /*tp_compare*/ | |
24754 | + 0, /*tp_repr*/ | |
24755 | + 0, /*tp_as_number*/ | |
24756 | + 0, /*tp_as_sequence*/ | |
24757 | + 0, /*tp_as_mapping*/ | |
24758 | + 0, /*tp_hash */ | |
24759 | + 0, /*tp_call*/ | |
24760 | + 0, /*tp_str*/ | |
24761 | + get_attr, /*tp_getattro*/ | |
24762 | + set_attr, /*tp_setattro*/ | |
24763 | + 0, /*tp_as_buffer*/ | |
24764 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | |
24765 | + "GDB parameter object", /* tp_doc */ | |
24766 | + 0, /* tp_traverse */ | |
24767 | + 0, /* tp_clear */ | |
24768 | + 0, /* tp_richcompare */ | |
24769 | + 0, /* tp_weaklistoffset */ | |
24770 | + 0, /* tp_iter */ | |
24771 | + 0, /* tp_iternext */ | |
24772 | + 0, /* tp_methods */ | |
24773 | + 0, /* tp_members */ | |
24774 | + 0, /* tp_getset */ | |
24775 | + 0, /* tp_base */ | |
24776 | + 0, /* tp_dict */ | |
24777 | + 0, /* tp_descr_get */ | |
24778 | + 0, /* tp_descr_set */ | |
24779 | + 0, /* tp_dictoffset */ | |
24780 | + parmpy_init, /* tp_init */ | |
24781 | + 0, /* tp_alloc */ | |
24782 | + PyType_GenericNew /* tp_new */ | |
24783 | +}; | |
24784 | diff --git a/gdb/python/python-symbol.c b/gdb/python/python-symbol.c | |
24785 | new file mode 100644 | |
24786 | index 0000000..c7fda5c | |
24787 | --- /dev/null | |
24788 | +++ b/gdb/python/python-symbol.c | |
24789 | @@ -0,0 +1,337 @@ | |
24790 | +/* Python interface to symbols. | |
24791 | + | |
24792 | + Copyright (C) 2008 Free Software Foundation, Inc. | |
24793 | + | |
24794 | + This file is part of GDB. | |
24795 | + | |
24796 | + This program is free software; you can redistribute it and/or modify | |
24797 | + it under the terms of the GNU General Public License as published by | |
24798 | + the Free Software Foundation; either version 3 of the License, or | |
24799 | + (at your option) any later version. | |
24800 | + | |
24801 | + This program is distributed in the hope that it will be useful, | |
24802 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24803 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24804 | + GNU General Public License for more details. | |
24805 | + | |
24806 | + You should have received a copy of the GNU General Public License | |
24807 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
24808 | + | |
24809 | +#include "defs.h" | |
24810 | +#include "block.h" | |
24811 | +#include "exceptions.h" | |
24812 | +#include "frame.h" | |
24813 | +#include "symtab.h" | |
24814 | +#include "python-internal.h" | |
24815 | + | |
24816 | +typedef struct { | |
24817 | + PyObject_HEAD | |
24818 | + struct symbol *symbol; | |
24819 | +} symbol_object; | |
24820 | + | |
24821 | + | |
24822 | +static PyObject * | |
24823 | +sympy_str (PyObject *self) | |
24824 | +{ | |
24825 | + int ret; | |
24826 | + char *s; | |
24827 | + PyObject *result; | |
24828 | + | |
24829 | + ret = asprintf (&s, "symbol for %s", | |
24830 | + SYMBOL_PRINT_NAME (((symbol_object *) self)->symbol)); | |
24831 | + if (ret < 0) | |
24832 | + Py_RETURN_NONE; | |
24833 | + | |
24834 | + result = PyString_FromString (s); | |
24835 | + xfree (s); | |
24836 | + | |
24837 | + return result; | |
24838 | +} | |
24839 | + | |
24840 | +static PyObject * | |
24841 | +sympy_get_value (PyObject *self, void *closure) | |
24842 | +{ | |
24843 | + symbol_object *self_sym = (symbol_object *) self; | |
24844 | + | |
24845 | + switch (SYMBOL_CLASS (self_sym->symbol)) | |
24846 | + { | |
24847 | + case LOC_BLOCK: | |
24848 | + return block_to_block_object (SYMBOL_BLOCK_VALUE (self_sym->symbol)); | |
24849 | + } | |
24850 | + | |
24851 | + PyErr_SetString (PyExc_NotImplementedError, | |
24852 | + "Symbol type not yet supported in Python scripts."); | |
24853 | + return NULL; | |
24854 | +} | |
24855 | + | |
24856 | +static PyObject * | |
24857 | +sympy_get_symtab (PyObject *self, void *closure) | |
24858 | +{ | |
24859 | + symbol_object *self_sym = (symbol_object *) self; | |
24860 | + | |
24861 | + return symtab_to_symtab_object (SYMBOL_SYMTAB (self_sym->symbol)); | |
24862 | +} | |
24863 | + | |
24864 | +static PyObject * | |
24865 | +sympy_get_name (PyObject *self, void *closure) | |
24866 | +{ | |
24867 | + symbol_object *self_sym = (symbol_object *) self; | |
24868 | + | |
24869 | + return PyString_FromString (SYMBOL_NATURAL_NAME (self_sym->symbol)); | |
24870 | +} | |
24871 | + | |
24872 | +static PyObject * | |
24873 | +sympy_get_linkage_name (PyObject *self, void *closure) | |
24874 | +{ | |
24875 | + symbol_object *self_sym = (symbol_object *) self; | |
24876 | + | |
24877 | + return PyString_FromString (SYMBOL_LINKAGE_NAME (self_sym->symbol)); | |
24878 | +} | |
24879 | + | |
24880 | +static PyObject * | |
24881 | +sympy_get_print_name (PyObject *self, void *closure) | |
24882 | +{ | |
24883 | + symbol_object *self_sym = (symbol_object *) self; | |
24884 | + | |
24885 | + return PyString_FromString (SYMBOL_PRINT_NAME (self_sym->symbol)); | |
24886 | +} | |
24887 | + | |
24888 | +static PyObject * | |
24889 | +sympy_get_addr_class (PyObject *self, void *closure) | |
24890 | +{ | |
24891 | + symbol_object *self_sym = (symbol_object *) self; | |
24892 | + | |
24893 | + return PyInt_FromLong (SYMBOL_CLASS (self_sym->symbol)); | |
24894 | +} | |
24895 | + | |
24896 | +static PyObject * | |
24897 | +sympy_is_argument (PyObject *self, void *closure) | |
24898 | +{ | |
24899 | + symbol_object *self_sym = (symbol_object *) self; | |
24900 | + | |
24901 | + return PyBool_FromLong (SYMBOL_IS_ARGUMENT (self_sym->symbol)); | |
24902 | +} | |
24903 | + | |
24904 | +static PyObject * | |
24905 | +sympy_is_constant (PyObject *self, void *closure) | |
24906 | +{ | |
24907 | + symbol_object *self_sym = (symbol_object *) self; | |
24908 | + enum address_class class = SYMBOL_CLASS (self_sym->symbol); | |
24909 | + | |
24910 | + return PyBool_FromLong (class == LOC_CONST || class == LOC_CONST_BYTES); | |
24911 | +} | |
24912 | + | |
24913 | +static PyObject * | |
24914 | +sympy_is_function (PyObject *self, void *closure) | |
24915 | +{ | |
24916 | + symbol_object *self_sym = (symbol_object *) self; | |
24917 | + enum address_class class = SYMBOL_CLASS (self_sym->symbol); | |
24918 | + | |
24919 | + return PyBool_FromLong (class == LOC_BLOCK); | |
24920 | +} | |
24921 | + | |
24922 | +static PyObject * | |
24923 | +sympy_is_variable (PyObject *self, void *closure) | |
24924 | +{ | |
24925 | + symbol_object *self_sym = (symbol_object *) self; | |
24926 | + enum address_class class = SYMBOL_CLASS (self_sym->symbol); | |
24927 | + | |
24928 | + return PyBool_FromLong (!SYMBOL_IS_ARGUMENT (self_sym->symbol) | |
24929 | + && (class == LOC_LOCAL || class == LOC_REGISTER || class == LOC_STATIC | |
24930 | + || class == LOC_COMPUTED || class == LOC_OPTIMIZED_OUT)); | |
24931 | +} | |
24932 | + | |
24933 | +PyObject * | |
24934 | +symbol_to_symbol_object (struct symbol *sym) | |
24935 | +{ | |
24936 | + symbol_object *sym_obj; | |
24937 | + | |
24938 | + sym_obj = PyObject_New (symbol_object, &symbol_object_type); | |
24939 | + if (sym_obj == NULL) | |
24940 | + { | |
24941 | + PyErr_SetString (PyExc_MemoryError, "Could not allocate symbol object."); | |
24942 | + return NULL; | |
24943 | + } | |
24944 | + | |
24945 | + sym_obj->symbol = sym; | |
24946 | + | |
24947 | + return (PyObject *) sym_obj; | |
24948 | +} | |
24949 | + | |
24950 | +struct symbol * | |
24951 | +symbol_object_to_symbol (PyObject *obj) | |
24952 | +{ | |
24953 | + if (! PyObject_TypeCheck (obj, &symbol_object_type)) | |
24954 | + return NULL; | |
24955 | + return ((symbol_object *) obj)->symbol; | |
24956 | +} | |
24957 | + | |
24958 | +/* Implementation of | |
24959 | + gdb.lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this) | |
24960 | + A tuple with 2 elements is always returned. The first is the symbol | |
24961 | + object or None, the second is a boolean with the value of | |
24962 | + is_a_field_of_this (see comment in lookup_symbol_in_language). */ | |
24963 | + | |
24964 | +PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw) | |
24965 | +{ | |
24966 | + int domain = VAR_DOMAIN, is_a_field_of_this = 0; | |
24967 | + const char *name; | |
24968 | + static char *keywords[] = { "name", "block", "domain", NULL }; | |
24969 | + struct symbol *symbol; | |
24970 | + PyObject *block_obj = NULL, *ret_tuple, *sym_obj, *bool_obj; | |
24971 | + struct block *block = NULL; | |
24972 | + | |
24973 | + if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!i", keywords, &name, | |
24974 | + &block_object_type, &block_obj, &domain)) | |
24975 | + return NULL; | |
24976 | + | |
24977 | + if (block_obj) | |
24978 | + block = block_object_to_block (block_obj); | |
24979 | + else | |
24980 | + { | |
24981 | + struct frame_info *selected_frame; | |
24982 | + volatile struct gdb_exception except; | |
24983 | + | |
24984 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
24985 | + { | |
24986 | + selected_frame = get_selected_frame (_("No frame selected.")); | |
24987 | + block = block_for_pc (get_frame_address_in_block (selected_frame)); | |
24988 | + } | |
24989 | + GDB_PY_HANDLE_EXCEPTION (except); | |
24990 | + } | |
24991 | + | |
24992 | + symbol = lookup_symbol (name, block, domain, &is_a_field_of_this); | |
24993 | + | |
24994 | + ret_tuple = PyTuple_New (2); | |
24995 | + if (!ret_tuple) | |
24996 | + { | |
24997 | + PyErr_SetString (PyExc_MemoryError, "Could not allocate tuple object."); | |
24998 | + return NULL; | |
24999 | + } | |
25000 | + | |
25001 | + if (symbol) | |
25002 | + { | |
25003 | + sym_obj = symbol_to_symbol_object (symbol); | |
25004 | + if (!sym_obj) | |
25005 | + { | |
25006 | + Py_DECREF (ret_tuple); | |
25007 | + return NULL; | |
25008 | + } | |
25009 | + } | |
25010 | + else | |
25011 | + { | |
25012 | + sym_obj = Py_None; | |
25013 | + Py_INCREF (Py_None); | |
25014 | + } | |
25015 | + PyTuple_SET_ITEM (ret_tuple, 0, sym_obj); | |
25016 | + | |
25017 | + bool_obj = is_a_field_of_this? Py_True : Py_False; | |
25018 | + Py_INCREF (bool_obj); | |
25019 | + PyTuple_SET_ITEM (ret_tuple, 1, bool_obj); | |
25020 | + | |
25021 | + return ret_tuple; | |
25022 | +} | |
25023 | + | |
25024 | +void | |
25025 | +gdbpy_initialize_symbols (void) | |
25026 | +{ | |
25027 | + symbol_object_type.tp_new = PyType_GenericNew; | |
25028 | + if (PyType_Ready (&symbol_object_type) < 0) | |
25029 | + return; | |
25030 | + | |
25031 | + /* FIXME: These would probably be best exposed as class attributes of Symbol, | |
25032 | + but I don't know how to do it except by messing with the type's dictionary. | |
25033 | + That seems too messy. */ | |
25034 | + /* FIXME 2: Some of these were removed from GDB since I first wrote this code, | |
25035 | + so it's probably a good idea not to expose them to Python. */ | |
25036 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_UNDEF", LOC_UNDEF); | |
25037 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_CONST", LOC_CONST); | |
25038 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_STATIC", LOC_STATIC); | |
25039 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGISTER", LOC_REGISTER); | |
25040 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_ARG", LOC_ARG); | |
25041 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REF_ARG", LOC_REF_ARG); | |
25042 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_LOCAL", LOC_LOCAL); | |
25043 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_TYPEDEF", LOC_TYPEDEF); | |
25044 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_LABEL", LOC_LABEL); | |
25045 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_BLOCK", LOC_BLOCK); | |
25046 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_CONST_BYTES", | |
25047 | + LOC_CONST_BYTES); | |
25048 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_UNRESOLVED", LOC_UNRESOLVED); | |
25049 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_OPTIMIZED_OUT", | |
25050 | + LOC_OPTIMIZED_OUT); | |
25051 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_COMPUTED", LOC_COMPUTED); | |
25052 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGPARM_ADDR", | |
25053 | + LOC_REGPARM_ADDR); | |
25054 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_UNDEF_DOMAIN", UNDEF_DOMAIN); | |
25055 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_VAR_DOMAIN", VAR_DOMAIN); | |
25056 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_STRUCT_DOMAIN", STRUCT_DOMAIN); | |
25057 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_LABEL_DOMAIN", LABEL_DOMAIN); | |
25058 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_VARIABLES_DOMAIN", | |
25059 | + VARIABLES_DOMAIN); | |
25060 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_FUNCTIONS_DOMAIN", | |
25061 | + FUNCTIONS_DOMAIN); | |
25062 | + PyModule_AddIntConstant (gdb_module, "SYMBOL_TYPES_DOMAIN", TYPES_DOMAIN); | |
25063 | + | |
25064 | + Py_INCREF (&symbol_object_type); | |
25065 | + PyModule_AddObject (gdb_module, "Symbol", (PyObject *) &symbol_object_type); | |
25066 | +} | |
25067 | + | |
25068 | +\f | |
25069 | + | |
25070 | +static PyGetSetDef symbol_object_getset[] = { | |
25071 | + { "value", sympy_get_value, NULL, "Value of the symbol.", NULL }, | |
25072 | + { "symtab", sympy_get_symtab, NULL, | |
25073 | + "Symbol table in which the symbol appears.", NULL }, | |
25074 | + { "name", sympy_get_name, NULL, | |
25075 | + "Name of the symbol, as it appears in the source code.", NULL }, | |
25076 | + { "linkage_name", sympy_get_linkage_name, NULL, | |
25077 | + "Name of the symbol, as used by the linker (i.e., may be mangled).", NULL }, | |
25078 | + { "print_name", sympy_get_print_name, NULL, | |
25079 | + "Name of the symbol in a form suitable for output.\n\ | |
25080 | +This is either name or linkage_name, depending on whether the user asked GDB\n\ | |
25081 | +to display demangled or mangled names.", NULL }, | |
25082 | + { "addr_class", sympy_get_addr_class, NULL, "Address class of the symbol." }, | |
25083 | + { "is_argument", sympy_is_argument, NULL, | |
25084 | + "True if the symbol is an argument of a function." }, | |
25085 | + { "is_constant", sympy_is_constant, NULL, | |
25086 | + "True if the symbol is a constant." }, | |
25087 | + { "is_function", sympy_is_function, NULL, | |
25088 | + "True if the symbol is a function or method." }, | |
25089 | + { "is_variable", sympy_is_variable, NULL, | |
25090 | + "True if the symbol is a variable." }, | |
25091 | + { NULL } /* Sentinel */ | |
25092 | +}; | |
25093 | + | |
25094 | +PyTypeObject symbol_object_type = { | |
25095 | + PyObject_HEAD_INIT (NULL) | |
25096 | + 0, /*ob_size*/ | |
25097 | + "gdb.Symbol", /*tp_name*/ | |
25098 | + sizeof (symbol_object), /*tp_basicsize*/ | |
25099 | + 0, /*tp_itemsize*/ | |
25100 | + 0, /*tp_dealloc*/ | |
25101 | + 0, /*tp_print*/ | |
25102 | + 0, /*tp_getattr*/ | |
25103 | + 0, /*tp_setattr*/ | |
25104 | + 0, /*tp_compare*/ | |
25105 | + 0, /*tp_repr*/ | |
25106 | + 0, /*tp_as_number*/ | |
25107 | + 0, /*tp_as_sequence*/ | |
25108 | + 0, /*tp_as_mapping*/ | |
25109 | + 0, /*tp_hash */ | |
25110 | + 0, /*tp_call*/ | |
25111 | + sympy_str, /*tp_str*/ | |
25112 | + 0, /*tp_getattro*/ | |
25113 | + 0, /*tp_setattro*/ | |
25114 | + 0, /*tp_as_buffer*/ | |
25115 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
25116 | + "GDB symbol object", /* tp_doc */ | |
25117 | + 0, /* tp_traverse */ | |
25118 | + 0, /* tp_clear */ | |
25119 | + 0, /* tp_richcompare */ | |
25120 | + 0, /* tp_weaklistoffset */ | |
25121 | + 0, /* tp_iter */ | |
25122 | + 0, /* tp_iternext */ | |
25123 | + 0, /* tp_methods */ | |
25124 | + 0, /* tp_members */ | |
25125 | + symbol_object_getset /* tp_getset */ | |
25126 | +}; | |
25127 | diff --git a/gdb/python/python-symtab.c b/gdb/python/python-symtab.c | |
25128 | new file mode 100644 | |
25129 | index 0000000..a48c38c | |
25130 | --- /dev/null | |
25131 | +++ b/gdb/python/python-symtab.c | |
25132 | @@ -0,0 +1,311 @@ | |
25133 | +/* Python interface to symbol tables. | |
25134 | + | |
25135 | + Copyright (C) 2008 Free Software Foundation, Inc. | |
25136 | + | |
25137 | + This file is part of GDB. | |
25138 | + | |
25139 | + This program is free software; you can redistribute it and/or modify | |
25140 | + it under the terms of the GNU General Public License as published by | |
25141 | + the Free Software Foundation; either version 3 of the License, or | |
25142 | + (at your option) any later version. | |
25143 | + | |
25144 | + This program is distributed in the hope that it will be useful, | |
25145 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25146 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25147 | + GNU General Public License for more details. | |
25148 | + | |
25149 | + You should have received a copy of the GNU General Public License | |
25150 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
25151 | + | |
25152 | +#include "defs.h" | |
25153 | +#include "charset.h" | |
25154 | +#include "symtab.h" | |
25155 | +#include "source.h" | |
25156 | +#include "python-internal.h" | |
25157 | + | |
25158 | +typedef struct { | |
25159 | + PyObject_HEAD | |
25160 | + struct symtab *symtab; | |
25161 | +} symtab_object; | |
25162 | + | |
25163 | +static PyTypeObject symtab_object_type; | |
25164 | + | |
25165 | +typedef struct { | |
25166 | + PyObject_HEAD | |
25167 | + symtab_object *symtab; | |
25168 | + struct symtab_and_line *sal; | |
25169 | +} sal_object; | |
25170 | + | |
25171 | +static PyTypeObject sal_object_type; | |
25172 | + | |
25173 | + | |
25174 | +static PyObject * | |
25175 | +stpy_str (PyObject *self) | |
25176 | +{ | |
25177 | + int ret; | |
25178 | + char *s; | |
25179 | + PyObject *result; | |
25180 | + | |
25181 | + ret = asprintf (&s, "symbol table for %s", | |
25182 | + ((symtab_object *) self)->symtab->filename); | |
25183 | + if (ret < 0) | |
25184 | + Py_RETURN_NONE; | |
25185 | + | |
25186 | + result = PyString_FromString (s); | |
25187 | + xfree (s); | |
25188 | + | |
25189 | + return result; | |
25190 | +} | |
25191 | + | |
25192 | +static PyObject * | |
25193 | +stpy_get_filename (PyObject *self, void *closure) | |
25194 | +{ | |
25195 | + symtab_object *self_symtab = (symtab_object *) self; | |
25196 | + PyObject *str_obj; | |
25197 | + | |
25198 | + /* FIXME: Can symtab->filename really be NULL? */ | |
25199 | + if (self_symtab->symtab->filename) | |
25200 | + str_obj = PyString_Decode (self_symtab->symtab->filename, | |
25201 | + strlen (self_symtab->symtab->filename), | |
25202 | + host_charset (), NULL); | |
25203 | + else | |
25204 | + { | |
25205 | + str_obj = Py_None; | |
25206 | + Py_INCREF (Py_None); | |
25207 | + } | |
25208 | + | |
25209 | + return str_obj; | |
25210 | +} | |
25211 | + | |
25212 | +static PyObject * | |
25213 | +stpy_fullname (PyObject *self, PyObject *args) | |
25214 | +{ | |
25215 | + char *fullname; | |
25216 | + | |
25217 | + fullname = symtab_to_fullname (((symtab_object *) self)->symtab); | |
25218 | + if (fullname) | |
25219 | + return PyString_Decode (fullname, strlen (fullname), host_charset (), NULL); | |
25220 | + | |
25221 | + Py_RETURN_NONE; | |
25222 | +} | |
25223 | + | |
25224 | +static PyObject * | |
25225 | +salpy_str (PyObject *self) | |
25226 | +{ | |
25227 | + int ret; | |
25228 | + char *s, *filename; | |
25229 | + sal_object *sal_obj; | |
25230 | + PyObject *result; | |
25231 | + | |
25232 | + sal_obj = (sal_object *) self; | |
25233 | + filename = (sal_obj->symtab == (symtab_object *) Py_None)? "<unknown>" : | |
25234 | + sal_obj->symtab->symtab->filename; | |
25235 | + ret = asprintf (&s, "symbol and line for %s, line %d", filename, | |
25236 | + sal_obj->sal->line); | |
25237 | + if (ret < 0) | |
25238 | + Py_RETURN_NONE; | |
25239 | + | |
25240 | + result = PyString_FromString (s); | |
25241 | + xfree (s); | |
25242 | + | |
25243 | + return result; | |
25244 | +} | |
25245 | + | |
25246 | +static PyObject * | |
25247 | +salpy_get_pc (PyObject *self, void *closure) | |
25248 | +{ | |
25249 | + return PyLong_FromUnsignedLongLong (((sal_object *) self)->sal->pc); | |
25250 | +} | |
25251 | + | |
25252 | +static PyObject * | |
25253 | +salpy_get_line (PyObject *self, void *closure) | |
25254 | +{ | |
25255 | + return PyLong_FromUnsignedLongLong (((sal_object *) self)->sal->line); | |
25256 | +} | |
25257 | + | |
25258 | +static PyObject * | |
25259 | +salpy_get_symtab (PyObject *self, void *closure) | |
25260 | +{ | |
25261 | + sal_object *self_sal = (sal_object *) self; | |
25262 | + | |
25263 | + Py_INCREF (self_sal->symtab); | |
25264 | + | |
25265 | + return (PyObject *) self_sal->symtab; | |
25266 | +} | |
25267 | + | |
25268 | +static void | |
25269 | +salpy_dealloc (PyObject *self) | |
25270 | +{ | |
25271 | + sal_object *self_sal = (sal_object *) self; | |
25272 | + | |
25273 | + Py_DECREF (self_sal->symtab); | |
25274 | + xfree (self_sal->sal); | |
25275 | + self_sal->ob_type->tp_free (self); | |
25276 | +} | |
25277 | + | |
25278 | +PyObject * | |
25279 | +symtab_and_line_to_sal_object (struct symtab_and_line sal) | |
25280 | +{ | |
25281 | + sal_object *sal_obj; | |
25282 | + symtab_object *symtab_obj; | |
25283 | + | |
25284 | + sal_obj = PyObject_New (sal_object, &sal_object_type); | |
25285 | + if (sal_obj == NULL) | |
25286 | + { | |
25287 | + PyErr_SetString (PyExc_MemoryError, | |
25288 | + "Could not allocate Symtab_and_line object."); | |
25289 | + return NULL; | |
25290 | + } | |
25291 | + | |
25292 | + if (sal.symtab) | |
25293 | + { | |
25294 | + symtab_obj = (symtab_object *) symtab_to_symtab_object (sal.symtab); | |
25295 | + if (symtab_obj == NULL) | |
25296 | + { | |
25297 | + Py_DECREF (sal_obj); | |
25298 | + return NULL; | |
25299 | + } | |
25300 | + | |
25301 | + symtab_obj->symtab = sal.symtab; | |
25302 | + } | |
25303 | + else | |
25304 | + { | |
25305 | + symtab_obj = (symtab_object *) Py_None; | |
25306 | + Py_INCREF (Py_None); | |
25307 | + } | |
25308 | + | |
25309 | + sal_obj->sal = (struct symtab_and_line *) | |
25310 | + xmalloc (sizeof (struct symtab_and_line)); | |
25311 | + *(sal_obj->sal) = sal; | |
25312 | + sal_obj->symtab = symtab_obj; | |
25313 | + | |
25314 | + return (PyObject *) sal_obj; | |
25315 | +} | |
25316 | + | |
25317 | +PyObject * | |
25318 | +symtab_to_symtab_object (struct symtab *symtab) | |
25319 | +{ | |
25320 | + symtab_object *symtab_obj; | |
25321 | + | |
25322 | + symtab_obj = PyObject_New (symtab_object, &symtab_object_type); | |
25323 | + if (symtab_obj == NULL) | |
25324 | + { | |
25325 | + PyErr_SetString (PyExc_MemoryError, | |
25326 | + "Could not allocate Symtab object."); | |
25327 | + | |
25328 | + return NULL; | |
25329 | + } | |
25330 | + | |
25331 | + symtab_obj->symtab = symtab; | |
25332 | + | |
25333 | + return (PyObject *) symtab_obj; | |
25334 | +} | |
25335 | + | |
25336 | +void | |
25337 | +gdbpy_initialize_symtabs (void) | |
25338 | +{ | |
25339 | + symtab_object_type.tp_new = PyType_GenericNew; | |
25340 | + if (PyType_Ready (&symtab_object_type) < 0) | |
25341 | + return; | |
25342 | + | |
25343 | + sal_object_type.tp_new = PyType_GenericNew; | |
25344 | + if (PyType_Ready (&sal_object_type) < 0) | |
25345 | + return; | |
25346 | + | |
25347 | + Py_INCREF (&symtab_object_type); | |
25348 | + PyModule_AddObject (gdb_module, "Symtab", (PyObject *) &symtab_object_type); | |
25349 | + | |
25350 | + Py_INCREF (&sal_object_type); | |
25351 | + PyModule_AddObject (gdb_module, "Symtab_and_line", | |
25352 | + (PyObject *) &sal_object_type); | |
25353 | +} | |
25354 | + | |
25355 | +\f | |
25356 | + | |
25357 | +static PyGetSetDef symtab_object_getset[] = { | |
25358 | + { "filename", stpy_get_filename, NULL, | |
25359 | + "The symbol table's source filename.", NULL }, | |
25360 | + {NULL} /* Sentinel */ | |
25361 | +}; | |
25362 | + | |
25363 | +static PyMethodDef symtab_object_methods[] = { | |
25364 | + { "fullname", stpy_fullname, METH_NOARGS, | |
25365 | + "Return the symtab's full source filename." }, | |
25366 | + {NULL} /* Sentinel */ | |
25367 | +}; | |
25368 | + | |
25369 | +static PyTypeObject symtab_object_type = { | |
25370 | + PyObject_HEAD_INIT (NULL) | |
25371 | + 0, /*ob_size*/ | |
25372 | + "gdb.Symtab", /*tp_name*/ | |
25373 | + sizeof (symtab_object), /*tp_basicsize*/ | |
25374 | + 0, /*tp_itemsize*/ | |
25375 | + 0, /*tp_dealloc*/ | |
25376 | + 0, /*tp_print*/ | |
25377 | + 0, /*tp_getattr*/ | |
25378 | + 0, /*tp_setattr*/ | |
25379 | + 0, /*tp_compare*/ | |
25380 | + 0, /*tp_repr*/ | |
25381 | + 0, /*tp_as_number*/ | |
25382 | + 0, /*tp_as_sequence*/ | |
25383 | + 0, /*tp_as_mapping*/ | |
25384 | + 0, /*tp_hash */ | |
25385 | + 0, /*tp_call*/ | |
25386 | + stpy_str, /*tp_str*/ | |
25387 | + 0, /*tp_getattro*/ | |
25388 | + 0, /*tp_setattro*/ | |
25389 | + 0, /*tp_as_buffer*/ | |
25390 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
25391 | + "GDB symtab object", /* tp_doc */ | |
25392 | + 0, /* tp_traverse */ | |
25393 | + 0, /* tp_clear */ | |
25394 | + 0, /* tp_richcompare */ | |
25395 | + 0, /* tp_weaklistoffset */ | |
25396 | + 0, /* tp_iter */ | |
25397 | + 0, /* tp_iternext */ | |
25398 | + symtab_object_methods, /* tp_methods */ | |
25399 | + 0, /* tp_members */ | |
25400 | + symtab_object_getset /* tp_getset */ | |
25401 | +}; | |
25402 | + | |
25403 | +static PyGetSetDef sal_object_getset[] = { | |
25404 | + { "symtab", salpy_get_symtab, NULL, "Symtab object.", NULL }, | |
25405 | + { "pc", salpy_get_pc, NULL, "Return the symtab_and_line's pc.", NULL }, | |
25406 | + { "line", salpy_get_line, NULL, | |
25407 | + "Return the symtab_and_line's line.", NULL }, | |
25408 | + {NULL} /* Sentinel */ | |
25409 | +}; | |
25410 | + | |
25411 | +static PyTypeObject sal_object_type = { | |
25412 | + PyObject_HEAD_INIT (NULL) | |
25413 | + 0, /*ob_size*/ | |
25414 | + "gdb.Symtab_and_line", /*tp_name*/ | |
25415 | + sizeof (sal_object), /*tp_basicsize*/ | |
25416 | + 0, /*tp_itemsize*/ | |
25417 | + salpy_dealloc, /*tp_dealloc*/ | |
25418 | + 0, /*tp_print*/ | |
25419 | + 0, /*tp_getattr*/ | |
25420 | + 0, /*tp_setattr*/ | |
25421 | + 0, /*tp_compare*/ | |
25422 | + 0, /*tp_repr*/ | |
25423 | + 0, /*tp_as_number*/ | |
25424 | + 0, /*tp_as_sequence*/ | |
25425 | + 0, /*tp_as_mapping*/ | |
25426 | + 0, /*tp_hash */ | |
25427 | + 0, /*tp_call*/ | |
25428 | + salpy_str, /*tp_str*/ | |
25429 | + 0, /*tp_getattro*/ | |
25430 | + 0, /*tp_setattro*/ | |
25431 | + 0, /*tp_as_buffer*/ | |
25432 | + Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
25433 | + "GDB symtab_and_line object", /* tp_doc */ | |
25434 | + 0, /* tp_traverse */ | |
25435 | + 0, /* tp_clear */ | |
25436 | + 0, /* tp_richcompare */ | |
25437 | + 0, /* tp_weaklistoffset */ | |
25438 | + 0, /* tp_iter */ | |
25439 | + 0, /* tp_iternext */ | |
25440 | + 0, /* tp_methods */ | |
25441 | + 0, /* tp_members */ | |
25442 | + sal_object_getset /* tp_getset */ | |
25443 | +}; | |
25444 | diff --git a/gdb/python/python-type.c b/gdb/python/python-type.c | |
25445 | new file mode 100644 | |
25446 | index 0000000..772a011 | |
25447 | --- /dev/null | |
25448 | +++ b/gdb/python/python-type.c | |
25449 | @@ -0,0 +1,821 @@ | |
25450 | +/* Python interface to types. | |
25451 | + | |
25452 | + Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
25453 | + | |
25454 | + This file is part of GDB. | |
25455 | + | |
25456 | + This program is free software; you can redistribute it and/or modify | |
25457 | + it under the terms of the GNU General Public License as published by | |
25458 | + the Free Software Foundation; either version 3 of the License, or | |
25459 | + (at your option) any later version. | |
25460 | + | |
25461 | + This program is distributed in the hope that it will be useful, | |
25462 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25463 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25464 | + GNU General Public License for more details. | |
25465 | + | |
25466 | + You should have received a copy of the GNU General Public License | |
25467 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
25468 | + | |
25469 | +#include "defs.h" | |
25470 | +#include "value.h" | |
25471 | +#include "exceptions.h" | |
25472 | +#include "python-internal.h" | |
25473 | +#include "charset.h" | |
25474 | +#include "gdbtypes.h" | |
25475 | +#include "cp-support.h" | |
25476 | +#include "demangle.h" | |
25477 | +#include "objfiles.h" | |
25478 | +#include "gdb_assert.h" | |
25479 | + | |
25480 | +typedef struct pyty_type_object | |
25481 | +{ | |
25482 | + PyObject_HEAD | |
25483 | + struct type *type; | |
25484 | + | |
25485 | + /* If a Type object is associated with an objfile, it is kept on a | |
25486 | + doubly-linked list, rooted in the objfile. This lets us copy the | |
25487 | + underlying struct type when the objfile is deleted. */ | |
25488 | + struct pyty_type_object *prev; | |
25489 | + struct pyty_type_object *next; | |
25490 | +} type_object; | |
25491 | + | |
25492 | +static PyTypeObject type_object_type; | |
25493 | + | |
25494 | +/* A Field object. */ | |
25495 | +typedef struct pyty_field_object | |
25496 | +{ | |
25497 | + PyObject_HEAD | |
25498 | + | |
25499 | + /* Dictionary holding our attributes. */ | |
25500 | + PyObject *dict; | |
25501 | +} field_object; | |
25502 | + | |
25503 | +static PyTypeObject field_object_type; | |
25504 | + | |
25505 | +/* This is used to initialize various gdb.TYPE_ constants. */ | |
25506 | +struct pyty_code | |
25507 | +{ | |
25508 | + /* The code. */ | |
25509 | + enum type_code code; | |
25510 | + /* The name. */ | |
25511 | + const char *name; | |
25512 | +}; | |
25513 | + | |
25514 | +#define ENTRY(X) { X, #X } | |
25515 | + | |
25516 | +static struct pyty_code pyty_codes[] = | |
25517 | +{ | |
25518 | + ENTRY (TYPE_CODE_PTR), | |
25519 | + ENTRY (TYPE_CODE_ARRAY), | |
25520 | + ENTRY (TYPE_CODE_STRUCT), | |
25521 | + ENTRY (TYPE_CODE_UNION), | |
25522 | + ENTRY (TYPE_CODE_ENUM), | |
25523 | + ENTRY (TYPE_CODE_FLAGS), | |
25524 | + ENTRY (TYPE_CODE_FUNC), | |
25525 | + ENTRY (TYPE_CODE_INT), | |
25526 | + ENTRY (TYPE_CODE_FLT), | |
25527 | + ENTRY (TYPE_CODE_VOID), | |
25528 | + ENTRY (TYPE_CODE_SET), | |
25529 | + ENTRY (TYPE_CODE_RANGE), | |
25530 | + ENTRY (TYPE_CODE_STRING), | |
25531 | + ENTRY (TYPE_CODE_BITSTRING), | |
25532 | + ENTRY (TYPE_CODE_ERROR), | |
25533 | + ENTRY (TYPE_CODE_METHOD), | |
25534 | + ENTRY (TYPE_CODE_METHODPTR), | |
25535 | + ENTRY (TYPE_CODE_MEMBERPTR), | |
25536 | + ENTRY (TYPE_CODE_REF), | |
25537 | + ENTRY (TYPE_CODE_CHAR), | |
25538 | + ENTRY (TYPE_CODE_BOOL), | |
25539 | + ENTRY (TYPE_CODE_COMPLEX), | |
25540 | + ENTRY (TYPE_CODE_TYPEDEF), | |
25541 | + ENTRY (TYPE_CODE_TEMPLATE), | |
25542 | + ENTRY (TYPE_CODE_TEMPLATE_ARG), | |
25543 | + ENTRY (TYPE_CODE_NAMESPACE), | |
25544 | + ENTRY (TYPE_CODE_DECFLOAT), | |
25545 | + ENTRY (TYPE_CODE_INTERNAL_FUNCTION), | |
25546 | + { TYPE_CODE_UNDEF, NULL } | |
25547 | +}; | |
25548 | + | |
25549 | +\f | |
25550 | + | |
25551 | +static void | |
25552 | +field_dealloc (PyObject *obj) | |
25553 | +{ | |
25554 | + field_object *f = (field_object *) obj; | |
25555 | + Py_XDECREF (f->dict); | |
25556 | +} | |
25557 | + | |
25558 | +static PyObject * | |
25559 | +field_new (void) | |
25560 | +{ | |
25561 | + field_object *result = PyObject_New (field_object, &field_object_type); | |
25562 | + if (result) | |
25563 | + { | |
25564 | + result->dict = PyDict_New (); | |
25565 | + if (!result->dict) | |
25566 | + { | |
25567 | + Py_DECREF (result); | |
25568 | + result = NULL; | |
25569 | + } | |
25570 | + } | |
25571 | + return (PyObject *) result; | |
25572 | +} | |
25573 | + | |
25574 | +\f | |
25575 | + | |
25576 | +/* Return the code for this type. */ | |
25577 | +static PyObject * | |
25578 | +typy_code (PyObject *self, PyObject *args) | |
25579 | +{ | |
25580 | + struct type *type = ((type_object *) self)->type; | |
25581 | + return PyInt_FromLong (TYPE_CODE (type)); | |
25582 | +} | |
25583 | + | |
25584 | +/* Helper function for typy_fields which converts a single field to a | |
25585 | + dictionary. Returns NULL on error. */ | |
25586 | +static PyObject * | |
25587 | +convert_field (struct type *type, int field) | |
25588 | +{ | |
25589 | + PyObject *result = field_new (); | |
25590 | + PyObject *arg; | |
25591 | + | |
25592 | + if (!result) | |
25593 | + return NULL; | |
25594 | + | |
25595 | + if (!field_is_static (&TYPE_FIELD (type, field))) | |
25596 | + { | |
25597 | + arg = PyLong_FromLong (TYPE_FIELD_BITPOS (type, field)); | |
25598 | + if (!arg) | |
25599 | + goto fail; | |
25600 | + | |
25601 | + if (PyObject_SetAttrString (result, "bitpos", arg) < 0) | |
25602 | + goto failarg; | |
25603 | + } | |
25604 | + | |
25605 | + if (TYPE_FIELD_NAME (type, field)) | |
25606 | + arg = PyString_FromString (TYPE_FIELD_NAME (type, field)); | |
25607 | + else | |
25608 | + { | |
25609 | + arg = Py_None; | |
25610 | + Py_INCREF (arg); | |
25611 | + } | |
25612 | + if (!arg) | |
25613 | + goto fail; | |
25614 | + if (PyObject_SetAttrString (result, "name", arg) < 0) | |
25615 | + goto failarg; | |
25616 | + | |
25617 | + arg = TYPE_FIELD_ARTIFICIAL (type, field) ? Py_True : Py_False; | |
25618 | + Py_INCREF (arg); | |
25619 | + if (PyObject_SetAttrString (result, "artificial", arg) < 0) | |
25620 | + goto failarg; | |
25621 | + | |
25622 | + arg = PyLong_FromLong (TYPE_FIELD_BITSIZE (type, field)); | |
25623 | + if (!arg) | |
25624 | + goto fail; | |
25625 | + if (PyObject_SetAttrString (result, "bitsize", arg) < 0) | |
25626 | + goto failarg; | |
25627 | + | |
25628 | + arg = type_to_type_object (TYPE_FIELD_TYPE (type, field)); | |
25629 | + if (!arg) | |
25630 | + goto fail; | |
25631 | + if (PyObject_SetAttrString (result, "type", arg) < 0) | |
25632 | + goto failarg; | |
25633 | + | |
25634 | + return result; | |
25635 | + | |
25636 | + failarg: | |
25637 | + Py_DECREF (arg); | |
25638 | + fail: | |
25639 | + Py_DECREF (result); | |
25640 | + return NULL; | |
25641 | +} | |
25642 | + | |
25643 | +/* Return a sequence of all fields. Each field is a dictionary with | |
25644 | + some pre-defined keys. */ | |
25645 | +static PyObject * | |
25646 | +typy_fields (PyObject *self, PyObject *args) | |
25647 | +{ | |
25648 | + PyObject *result; | |
25649 | + int i; | |
25650 | + struct type *type = ((type_object *) self)->type; | |
25651 | + | |
25652 | + /* We would like to make a tuple here, make fields immutable, and | |
25653 | + then memoize the result (and perhaps make Field.type() lazy). | |
25654 | + However, that can lead to cycles. */ | |
25655 | + result = PyList_New (0); | |
25656 | + | |
25657 | + for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
25658 | + { | |
25659 | + PyObject *dict = convert_field (type, i); | |
25660 | + if (!dict) | |
25661 | + { | |
25662 | + Py_DECREF (result); | |
25663 | + return NULL; | |
25664 | + } | |
25665 | + if (PyList_Append (result, dict)) | |
25666 | + { | |
25667 | + Py_DECREF (dict); | |
25668 | + Py_DECREF (result); | |
25669 | + return NULL; | |
25670 | + } | |
25671 | + } | |
25672 | + | |
25673 | + return result; | |
25674 | +} | |
25675 | + | |
25676 | +/* Return the type's tag, or None. */ | |
25677 | +static PyObject * | |
25678 | +typy_tag (PyObject *self, PyObject *args) | |
25679 | +{ | |
25680 | + struct type *type = ((type_object *) self)->type; | |
25681 | + if (!TYPE_TAG_NAME (type)) | |
25682 | + Py_RETURN_NONE; | |
25683 | + return PyString_FromString (TYPE_TAG_NAME (type)); | |
25684 | +} | |
25685 | + | |
25686 | +/* Return the type, stripped of typedefs. */ | |
25687 | +static PyObject * | |
25688 | +typy_strip_typedefs (PyObject *self, PyObject *args) | |
25689 | +{ | |
25690 | + struct type *type = ((type_object *) self)->type; | |
25691 | + | |
25692 | + return type_to_type_object (check_typedef (type)); | |
25693 | +} | |
25694 | + | |
25695 | +/* Return a Type object which represents a pointer to SELF. */ | |
25696 | +static PyObject * | |
25697 | +typy_pointer (PyObject *self, PyObject *args) | |
25698 | +{ | |
25699 | + struct type *type = ((type_object *) self)->type; | |
25700 | + volatile struct gdb_exception except; | |
25701 | + | |
25702 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
25703 | + { | |
25704 | + type = lookup_pointer_type (type); | |
25705 | + } | |
25706 | + GDB_PY_HANDLE_EXCEPTION (except); | |
25707 | + | |
25708 | + return type_to_type_object (type); | |
25709 | +} | |
25710 | + | |
25711 | +/* Return a Type object which represents a reference to SELF. */ | |
25712 | +static PyObject * | |
25713 | +typy_reference (PyObject *self, PyObject *args) | |
25714 | +{ | |
25715 | + struct type *type = ((type_object *) self)->type; | |
25716 | + volatile struct gdb_exception except; | |
25717 | + | |
25718 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
25719 | + { | |
25720 | + type = lookup_reference_type (type); | |
25721 | + } | |
25722 | + GDB_PY_HANDLE_EXCEPTION (except); | |
25723 | + | |
25724 | + return type_to_type_object (type); | |
25725 | +} | |
25726 | + | |
25727 | +/* Return a Type object which represents the target type of SELF. */ | |
25728 | +static PyObject * | |
25729 | +typy_target (PyObject *self, PyObject *args) | |
25730 | +{ | |
25731 | + struct type *type = ((type_object *) self)->type; | |
25732 | + | |
25733 | + if (!TYPE_TARGET_TYPE (type)) | |
25734 | + { | |
25735 | + PyErr_SetString (PyExc_RuntimeError, "type does not have a target"); | |
25736 | + return NULL; | |
25737 | + } | |
25738 | + | |
25739 | + return type_to_type_object (TYPE_TARGET_TYPE (type)); | |
25740 | +} | |
25741 | + | |
25742 | +/* Return a const-qualified type variant. */ | |
25743 | +static PyObject * | |
25744 | +typy_const (PyObject *self, PyObject *args) | |
25745 | +{ | |
25746 | + struct type *type = ((type_object *) self)->type; | |
25747 | + volatile struct gdb_exception except; | |
25748 | + | |
25749 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
25750 | + { | |
25751 | + type = make_cv_type (1, 0, type, NULL); | |
25752 | + } | |
25753 | + GDB_PY_HANDLE_EXCEPTION (except); | |
25754 | + | |
25755 | + return type_to_type_object (type); | |
25756 | +} | |
25757 | + | |
25758 | +/* Return a volatile-qualified type variant. */ | |
25759 | +static PyObject * | |
25760 | +typy_volatile (PyObject *self, PyObject *args) | |
25761 | +{ | |
25762 | + struct type *type = ((type_object *) self)->type; | |
25763 | + volatile struct gdb_exception except; | |
25764 | + | |
25765 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
25766 | + { | |
25767 | + type = make_cv_type (0, 1, type, NULL); | |
25768 | + } | |
25769 | + GDB_PY_HANDLE_EXCEPTION (except); | |
25770 | + | |
25771 | + return type_to_type_object (type); | |
25772 | +} | |
25773 | + | |
25774 | +/* Return an unqualified type variant. */ | |
25775 | +static PyObject * | |
25776 | +typy_unqualified (PyObject *self, PyObject *args) | |
25777 | +{ | |
25778 | + struct type *type = ((type_object *) self)->type; | |
25779 | + volatile struct gdb_exception except; | |
25780 | + | |
25781 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
25782 | + { | |
25783 | + type = make_cv_type (0, 0, type, NULL); | |
25784 | + } | |
25785 | + GDB_PY_HANDLE_EXCEPTION (except); | |
25786 | + | |
25787 | + return type_to_type_object (type); | |
25788 | +} | |
25789 | + | |
25790 | +/* Return the size of the type represented by SELF, in bytes. */ | |
25791 | +static PyObject * | |
25792 | +typy_sizeof (PyObject *self, PyObject *args) | |
25793 | +{ | |
25794 | + struct type *type = ((type_object *) self)->type; | |
25795 | + volatile struct gdb_exception except; | |
25796 | + | |
25797 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
25798 | + { | |
25799 | + CHECK_TYPEDEF (type); | |
25800 | + } | |
25801 | + GDB_PY_HANDLE_EXCEPTION (except); | |
25802 | + | |
25803 | + return PyLong_FromLong (TYPE_LENGTH (type)); | |
25804 | +} | |
25805 | + | |
25806 | +static struct type * | |
25807 | +typy_lookup_typename (char *type_name, struct block *block) | |
25808 | +{ | |
25809 | + struct type *type = NULL; | |
25810 | + volatile struct gdb_exception except; | |
25811 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
25812 | + { | |
25813 | + if (!strncmp (type_name, "struct ", 7)) | |
25814 | + type = lookup_struct (type_name + 7, block); | |
25815 | + else if (!strncmp (type_name, "union ", 6)) | |
25816 | + type = lookup_union (type_name + 6, block); | |
25817 | + else if (!strncmp (type_name, "enum ", 5)) | |
25818 | + type = lookup_enum (type_name + 5, block); | |
25819 | + else | |
25820 | + type = lookup_typename (type_name, block, 0); | |
25821 | + } | |
25822 | + if (except.reason < 0) | |
25823 | + { | |
25824 | + PyErr_Format (except.reason == RETURN_QUIT | |
25825 | + ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, | |
25826 | + "%s", except.message); | |
25827 | + return NULL; | |
25828 | + } | |
25829 | + | |
25830 | + return type; | |
25831 | +} | |
25832 | + | |
25833 | +static struct type * | |
25834 | +typy_lookup_type (struct demangle_component *demangled, | |
25835 | + struct block *block) | |
25836 | +{ | |
25837 | + struct type *type; | |
25838 | + char *type_name; | |
25839 | + enum demangle_component_type demangled_type; | |
25840 | + | |
25841 | + /* Save the type: typy_lookup_type() may (indirectly) overwrite | |
25842 | + memory pointed by demangled. */ | |
25843 | + demangled_type = demangled->type; | |
25844 | + | |
25845 | + if (demangled_type == DEMANGLE_COMPONENT_POINTER | |
25846 | + || demangled_type == DEMANGLE_COMPONENT_REFERENCE | |
25847 | + || demangled_type == DEMANGLE_COMPONENT_CONST | |
25848 | + || demangled_type == DEMANGLE_COMPONENT_VOLATILE) | |
25849 | + { | |
25850 | + type = typy_lookup_type (demangled->u.s_binary.left, block); | |
25851 | + if (! type) | |
25852 | + return NULL; | |
25853 | + | |
25854 | + switch (demangled_type) | |
25855 | + { | |
25856 | + case DEMANGLE_COMPONENT_REFERENCE: | |
25857 | + return lookup_reference_type (type); | |
25858 | + case DEMANGLE_COMPONENT_POINTER: | |
25859 | + return lookup_pointer_type (type); | |
25860 | + case DEMANGLE_COMPONENT_CONST: | |
25861 | + return make_cv_type (1, 0, type, NULL); | |
25862 | + case DEMANGLE_COMPONENT_VOLATILE: | |
25863 | + return make_cv_type (0, 1, type, NULL); | |
25864 | + } | |
25865 | + } | |
25866 | + | |
25867 | + type_name = cp_comp_to_string (demangled, 10); | |
25868 | + type = typy_lookup_typename (type_name, block); | |
25869 | + xfree (type_name); | |
25870 | + | |
25871 | + return type; | |
25872 | +} | |
25873 | + | |
25874 | +static PyObject * | |
25875 | +typy_template_argument (PyObject *self, PyObject *args) | |
25876 | +{ | |
25877 | + int i, argno, n_pointers; | |
25878 | + struct type *type = ((type_object *) self)->type; | |
25879 | + struct demangle_component *demangled; | |
25880 | + const char *err; | |
25881 | + struct type *argtype; | |
25882 | + struct block *block = NULL; | |
25883 | + PyObject *block_obj = NULL; | |
25884 | + | |
25885 | + if (! PyArg_ParseTuple (args, "i|O", &argno, &block_obj)) | |
25886 | + return NULL; | |
25887 | + | |
25888 | + if (block_obj) | |
25889 | + { | |
25890 | + block = block_object_to_block (block_obj); | |
25891 | + if (! block) | |
25892 | + { | |
25893 | + PyErr_SetString (PyExc_RuntimeError, | |
25894 | + "second argument must be block"); | |
25895 | + return NULL; | |
25896 | + } | |
25897 | + } | |
25898 | + | |
25899 | + type = check_typedef (type); | |
25900 | + if (TYPE_CODE (type) == TYPE_CODE_REF) | |
25901 | + type = check_typedef (TYPE_TARGET_TYPE (type)); | |
25902 | + | |
25903 | + if (TYPE_NAME (type) == NULL) | |
25904 | + { | |
25905 | + PyErr_SetString (PyExc_RuntimeError, "null type name"); | |
25906 | + return NULL; | |
25907 | + } | |
25908 | + | |
25909 | + /* Note -- this is not thread-safe. */ | |
25910 | + demangled = cp_demangled_name_to_comp (TYPE_NAME (type), &err); | |
25911 | + if (! demangled) | |
25912 | + { | |
25913 | + PyErr_SetString (PyExc_RuntimeError, err); | |
25914 | + return NULL; | |
25915 | + } | |
25916 | + | |
25917 | + /* Strip off component names. */ | |
25918 | + while (demangled->type == DEMANGLE_COMPONENT_QUAL_NAME | |
25919 | + || demangled->type == DEMANGLE_COMPONENT_LOCAL_NAME) | |
25920 | + demangled = demangled->u.s_binary.right; | |
25921 | + | |
25922 | + if (demangled->type != DEMANGLE_COMPONENT_TEMPLATE) | |
25923 | + { | |
25924 | + PyErr_SetString (PyExc_RuntimeError, "type is not a template"); | |
25925 | + return NULL; | |
25926 | + } | |
25927 | + | |
25928 | + /* Skip from the template to the arguments. */ | |
25929 | + demangled = demangled->u.s_binary.right; | |
25930 | + | |
25931 | + for (i = 0; demangled && i < argno; ++i) | |
25932 | + demangled = demangled->u.s_binary.right; | |
25933 | + | |
25934 | + if (! demangled) | |
25935 | + { | |
25936 | + PyErr_Format (PyExc_RuntimeError, "no argument %d in template", | |
25937 | + argno); | |
25938 | + return NULL; | |
25939 | + } | |
25940 | + | |
25941 | + argtype = typy_lookup_type (demangled->u.s_binary.left, block); | |
25942 | + if (! argtype) | |
25943 | + return NULL; | |
25944 | + | |
25945 | + return type_to_type_object (argtype); | |
25946 | +} | |
25947 | + | |
25948 | +static PyObject * | |
25949 | +typy_str (PyObject *self) | |
25950 | +{ | |
25951 | + volatile struct gdb_exception except; | |
25952 | + char *thetype = NULL; | |
25953 | + PyObject *result; | |
25954 | + | |
25955 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
25956 | + { | |
25957 | + struct cleanup *old_chain; | |
25958 | + struct ui_file *stb; | |
25959 | + long length; | |
25960 | + | |
25961 | + stb = mem_fileopen (); | |
25962 | + old_chain = make_cleanup_ui_file_delete (stb); | |
25963 | + | |
25964 | + type_print (type_object_to_type (self), "", stb, -1); | |
25965 | + | |
25966 | + thetype = ui_file_xstrdup (stb, &length); | |
25967 | + do_cleanups (old_chain); | |
25968 | + } | |
25969 | + if (except.reason < 0) | |
25970 | + { | |
25971 | + xfree (thetype); | |
25972 | + GDB_PY_HANDLE_EXCEPTION (except); | |
25973 | + } | |
25974 | + | |
25975 | + result = PyUnicode_Decode (thetype, strlen (thetype), host_charset (), NULL); | |
25976 | + xfree (thetype); | |
25977 | + | |
25978 | + return result; | |
25979 | +} | |
25980 | + | |
25981 | +\f | |
25982 | + | |
25983 | +static const struct objfile_data *typy_objfile_data_key; | |
25984 | + | |
25985 | +static void | |
25986 | +clean_up_objfile_types (struct objfile *objfile, void *datum) | |
25987 | +{ | |
25988 | + type_object *obj = datum; | |
25989 | + htab_t copied_types; | |
25990 | + struct cleanup *cleanup; | |
25991 | + PyGILState_STATE state; | |
25992 | + | |
25993 | + /* This prevents another thread from freeing the objects we're | |
25994 | + operating on. */ | |
25995 | + state = PyGILState_Ensure (); | |
25996 | + cleanup = make_cleanup_py_restore_gil (&state); | |
25997 | + | |
25998 | + copied_types = create_copied_types_hash (objfile); | |
25999 | + | |
26000 | + while (obj) | |
26001 | + { | |
26002 | + type_object *next = obj->next; | |
26003 | + | |
26004 | + htab_empty (copied_types); | |
26005 | + | |
26006 | + /* No need to decref the old type here, since we know it has no | |
26007 | + reference count. */ | |
26008 | + gdb_assert (objfile == TYPE_OBJFILE (obj->type)); | |
26009 | + obj->type = copy_type_recursive (obj->type, copied_types); | |
26010 | + type_incref (obj->type); | |
26011 | + | |
26012 | + obj->next = NULL; | |
26013 | + obj->prev = NULL; | |
26014 | + | |
26015 | + obj = next; | |
26016 | + } | |
26017 | + | |
26018 | + htab_delete (copied_types); | |
26019 | + | |
26020 | + do_cleanups (cleanup); | |
26021 | +} | |
26022 | + | |
26023 | +static void | |
26024 | +set_type (type_object *obj, struct type *type) | |
26025 | +{ | |
26026 | + obj->type = type; | |
26027 | + type_incref (type); | |
26028 | + obj->prev = NULL; | |
26029 | + if (type && !OBJFILE_IS_VIRTUAL (TYPE_OBJFILE (type))) | |
26030 | + { | |
26031 | + struct objfile *objfile = TYPE_OBJFILE (type); | |
26032 | + | |
26033 | + obj->next = objfile_data (objfile, typy_objfile_data_key); | |
26034 | + if (obj->next) | |
26035 | + obj->next->prev = obj; | |
26036 | + set_objfile_data (objfile, typy_objfile_data_key, obj); | |
26037 | + } | |
26038 | + else | |
26039 | + obj->next = NULL; | |
26040 | +} | |
26041 | + | |
26042 | +static PyObject * | |
26043 | +typy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs) | |
26044 | +{ | |
26045 | + char *type_name = NULL; | |
26046 | + struct type *type = NULL; | |
26047 | + type_object *result; | |
26048 | + PyObject *block_obj = NULL; | |
26049 | + struct block *block = NULL; | |
26050 | + | |
26051 | + /* FIXME: it is strange to allow a Type with no name, but we need | |
26052 | + this for type_to_type_object. */ | |
26053 | + if (! PyArg_ParseTuple (args, "|sO", &type_name, &block_obj)) | |
26054 | + return NULL; | |
26055 | + | |
26056 | + if (block_obj) | |
26057 | + { | |
26058 | + block = block_object_to_block (block_obj); | |
26059 | + if (! block) | |
26060 | + { | |
26061 | + PyErr_SetString (PyExc_RuntimeError, | |
26062 | + "second argument must be block"); | |
26063 | + return NULL; | |
26064 | + } | |
26065 | + } | |
26066 | + | |
26067 | + if (type_name) | |
26068 | + { | |
26069 | + type = typy_lookup_typename (type_name, block); | |
26070 | + if (! type) | |
26071 | + return NULL; | |
26072 | + } | |
26073 | + | |
26074 | + result = (type_object *) subtype->tp_alloc (subtype, 1); | |
26075 | + if (! result) | |
26076 | + return NULL; | |
26077 | + | |
26078 | + set_type (result, type); | |
26079 | + | |
26080 | + return (PyObject *) result; | |
26081 | +} | |
26082 | + | |
26083 | +static void | |
26084 | +typy_dealloc (PyObject *obj) | |
26085 | +{ | |
26086 | + type_object *type = (type_object *) obj; | |
26087 | + | |
26088 | + if (type->type) | |
26089 | + type_decref (type->type); | |
26090 | + | |
26091 | + if (type->prev) | |
26092 | + type->prev->next = type->next; | |
26093 | + else if (type->type && !OBJFILE_IS_VIRTUAL (TYPE_OBJFILE (type->type))) | |
26094 | + { | |
26095 | + /* Must reset head of list. */ | |
26096 | + struct objfile *objfile = TYPE_OBJFILE (type->type); | |
26097 | + if (objfile) | |
26098 | + set_objfile_data (objfile, typy_objfile_data_key, type->next); | |
26099 | + } | |
26100 | + if (type->next) | |
26101 | + type->next->prev = type->prev; | |
26102 | + | |
26103 | + type->ob_type->tp_free (type); | |
26104 | +} | |
26105 | + | |
26106 | +/* Create a new Type referring to TYPE. */ | |
26107 | +PyObject * | |
26108 | +type_to_type_object (struct type *type) | |
26109 | +{ | |
26110 | + type_object *type_obj; | |
26111 | + | |
26112 | + type_obj = PyObject_New (type_object, &type_object_type); | |
26113 | + if (type_obj) | |
26114 | + set_type (type_obj, type); | |
26115 | + | |
26116 | + return (PyObject *) type_obj; | |
26117 | +} | |
26118 | + | |
26119 | +struct type * | |
26120 | +type_object_to_type (PyObject *obj) | |
26121 | +{ | |
26122 | + if (! PyObject_TypeCheck (obj, &type_object_type)) | |
26123 | + return NULL; | |
26124 | + return ((type_object *) obj)->type; | |
26125 | +} | |
26126 | + | |
26127 | +\f | |
26128 | + | |
26129 | +void | |
26130 | +gdbpy_initialize_types (void) | |
26131 | +{ | |
26132 | + int i; | |
26133 | + | |
26134 | + typy_objfile_data_key | |
26135 | + = register_objfile_data_with_cleanup (clean_up_objfile_types); | |
26136 | + | |
26137 | + if (PyType_Ready (&type_object_type) < 0) | |
26138 | + return; | |
26139 | + if (PyType_Ready (&field_object_type) < 0) | |
26140 | + return; | |
26141 | + | |
26142 | + for (i = 0; pyty_codes[i].name; ++i) | |
26143 | + { | |
26144 | + if (PyModule_AddIntConstant (gdb_module, | |
26145 | + /* Cast needed for Python 2.4. */ | |
26146 | + (char *) pyty_codes[i].name, | |
26147 | + pyty_codes[i].code) < 0) | |
26148 | + return; | |
26149 | + } | |
26150 | + | |
26151 | + Py_INCREF (&type_object_type); | |
26152 | + PyModule_AddObject (gdb_module, "Type", (PyObject *) &type_object_type); | |
26153 | + | |
26154 | + Py_INCREF (&field_object_type); | |
26155 | + PyModule_AddObject (gdb_module, "Field", (PyObject *) &field_object_type); | |
26156 | +} | |
26157 | + | |
26158 | +\f | |
26159 | + | |
26160 | +static PyMethodDef type_object_methods[] = | |
26161 | +{ | |
26162 | + { "code", typy_code, METH_NOARGS, "Return the code for this type" }, | |
26163 | + { "const", typy_const, METH_NOARGS, "Return a const variant of this type" }, | |
26164 | + { "fields", typy_fields, METH_NOARGS, | |
26165 | + "Return a sequence holding all the fields of this type.\n\ | |
26166 | +Each field is a dictionary." }, | |
26167 | + { "pointer", typy_pointer, METH_NOARGS, "Return pointer to this type" }, | |
26168 | + { "reference", typy_reference, METH_NOARGS, "Return reference to this type" }, | |
26169 | + { "sizeof", typy_sizeof, METH_NOARGS, | |
26170 | + "Return the size of this type, in bytes" }, | |
26171 | + { "tag", typy_tag, METH_NOARGS, | |
26172 | + "Return the tag name for this type, or None." }, | |
26173 | + { "strip_typedefs", typy_strip_typedefs, METH_NOARGS, | |
26174 | + "Return a type stripped of typedefs"}, | |
26175 | + { "target", typy_target, METH_NOARGS, | |
26176 | + "Return the target type of this type" }, | |
26177 | + { "template_argument", typy_template_argument, METH_VARARGS, | |
26178 | + "Return a single template argument type" }, | |
26179 | + { "unqualified", typy_unqualified, METH_NOARGS, | |
26180 | + "Return a variant of this type without const or volatile attributes" }, | |
26181 | + { "volatile", typy_volatile, METH_NOARGS, | |
26182 | + "Return a volatile variant of this type" }, | |
26183 | + { NULL } | |
26184 | +}; | |
26185 | + | |
26186 | +static PyTypeObject type_object_type = | |
26187 | +{ | |
26188 | + PyObject_HEAD_INIT (NULL) | |
26189 | + 0, /*ob_size*/ | |
26190 | + "gdb.Type", /*tp_name*/ | |
26191 | + sizeof (type_object), /*tp_basicsize*/ | |
26192 | + 0, /*tp_itemsize*/ | |
26193 | + typy_dealloc, /*tp_dealloc*/ | |
26194 | + 0, /*tp_print*/ | |
26195 | + 0, /*tp_getattr*/ | |
26196 | + 0, /*tp_setattr*/ | |
26197 | + 0, /*tp_compare*/ | |
26198 | + 0, /*tp_repr*/ | |
26199 | + 0, /*tp_as_number*/ | |
26200 | + 0, /*tp_as_sequence*/ | |
26201 | + 0, /*tp_as_mapping*/ | |
26202 | + 0, /*tp_hash */ | |
26203 | + 0, /*tp_call*/ | |
26204 | + typy_str, /*tp_str*/ | |
26205 | + 0, /*tp_getattro*/ | |
26206 | + 0, /*tp_setattro*/ | |
26207 | + 0, /*tp_as_buffer*/ | |
26208 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ | |
26209 | + "GDB type object", /* tp_doc */ | |
26210 | + 0, /* tp_traverse */ | |
26211 | + 0, /* tp_clear */ | |
26212 | + 0, /* tp_richcompare */ | |
26213 | + 0, /* tp_weaklistoffset */ | |
26214 | + 0, /* tp_iter */ | |
26215 | + 0, /* tp_iternext */ | |
26216 | + type_object_methods, /* tp_methods */ | |
26217 | + 0, /* tp_members */ | |
26218 | + 0, /* tp_getset */ | |
26219 | + 0, /* tp_base */ | |
26220 | + 0, /* tp_dict */ | |
26221 | + 0, /* tp_descr_get */ | |
26222 | + 0, /* tp_descr_set */ | |
26223 | + 0, /* tp_dictoffset */ | |
26224 | + 0, /* tp_init */ | |
26225 | + 0, /* tp_alloc */ | |
26226 | + typy_new, /* tp_new */ | |
26227 | +}; | |
26228 | + | |
26229 | +static PyTypeObject field_object_type = | |
26230 | +{ | |
26231 | + PyObject_HEAD_INIT (NULL) | |
26232 | + 0, /*ob_size*/ | |
26233 | + "gdb.Field", /*tp_name*/ | |
26234 | + sizeof (field_object), /*tp_basicsize*/ | |
26235 | + 0, /*tp_itemsize*/ | |
26236 | + field_dealloc, /*tp_dealloc*/ | |
26237 | + 0, /*tp_print*/ | |
26238 | + 0, /*tp_getattr*/ | |
26239 | + 0, /*tp_setattr*/ | |
26240 | + 0, /*tp_compare*/ | |
26241 | + 0, /*tp_repr*/ | |
26242 | + 0, /*tp_as_number*/ | |
26243 | + 0, /*tp_as_sequence*/ | |
26244 | + 0, /*tp_as_mapping*/ | |
26245 | + 0, /*tp_hash */ | |
26246 | + 0, /*tp_call*/ | |
26247 | + 0, /*tp_str*/ | |
26248 | + 0, /*tp_getattro*/ | |
26249 | + 0, /*tp_setattro*/ | |
26250 | + 0, /*tp_as_buffer*/ | |
26251 | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ | |
26252 | + "GDB field object", /* tp_doc */ | |
26253 | + 0, /* tp_traverse */ | |
26254 | + 0, /* tp_clear */ | |
26255 | + 0, /* tp_richcompare */ | |
26256 | + 0, /* tp_weaklistoffset */ | |
26257 | + 0, /* tp_iter */ | |
26258 | + 0, /* tp_iternext */ | |
26259 | + 0, /* tp_methods */ | |
26260 | + 0, /* tp_members */ | |
26261 | + 0, /* tp_getset */ | |
26262 | + 0, /* tp_base */ | |
26263 | + 0, /* tp_dict */ | |
26264 | + 0, /* tp_descr_get */ | |
26265 | + 0, /* tp_descr_set */ | |
26266 | + offsetof (field_object, dict), /* tp_dictoffset */ | |
26267 | + 0, /* tp_init */ | |
26268 | + 0, /* tp_alloc */ | |
26269 | + 0, /* tp_new */ | |
26270 | +}; | |
26271 | diff --git a/gdb/python/python-utils.c b/gdb/python/python-utils.c | |
26272 | index ddac2f5..f9c9486 100644 | |
26273 | --- a/gdb/python/python-utils.c | |
26274 | +++ b/gdb/python/python-utils.c | |
26275 | @@ -19,6 +19,7 @@ | |
26276 | ||
26277 | #include "defs.h" | |
26278 | #include "charset.h" | |
26279 | +#include "value.h" | |
26280 | #include "python-internal.h" | |
26281 | ||
26282 | ||
26283 | @@ -99,8 +100,8 @@ python_string_to_unicode (PyObject *obj) | |
26284 | } | |
26285 | ||
26286 | /* Returns a newly allocated string with the contents of the given unicode | |
26287 | - string object converted to CHARSET. If an error occurs during the | |
26288 | - conversion, NULL will be returned and a python exception will be set. | |
26289 | + string object converted to a named charset. If an error occurs during | |
26290 | + the conversion, NULL will be returned and a python exception will be set. | |
26291 | ||
26292 | The caller is responsible for xfree'ing the string. */ | |
26293 | static char * | |
26294 | @@ -191,3 +192,48 @@ gdbpy_is_string (PyObject *obj) | |
26295 | { | |
26296 | return PyString_Check (obj) || PyUnicode_Check (obj); | |
26297 | } | |
26298 | + | |
26299 | +/* Converts OBJ to a CORE_ADDR value. | |
26300 | + | |
26301 | + Returns 1 on success or 0 on failure, with a Python exception set. This | |
26302 | + function can also throw GDB exceptions. */ | |
26303 | + | |
26304 | +int | |
26305 | +get_addr_from_python (PyObject *obj, CORE_ADDR *addr) | |
26306 | +{ | |
26307 | + if (gdbpy_is_value_object (obj)) | |
26308 | + *addr = value_as_address (value_object_to_value (obj)); | |
26309 | + else if (PyLong_Check (obj)) | |
26310 | + { | |
26311 | + /* Assume CORE_ADDR corresponds to unsigned long. */ | |
26312 | + *addr = PyLong_AsUnsignedLong (obj); | |
26313 | + if (PyErr_Occurred () != NULL) | |
26314 | + return 0; | |
26315 | + } | |
26316 | + else if (PyInt_Check (obj)) | |
26317 | + { | |
26318 | + long val; | |
26319 | + | |
26320 | + /* Assume CORE_ADDR corresponds to unsigned long. */ | |
26321 | + val = PyInt_AsLong (obj); | |
26322 | + | |
26323 | + if (val >= 0) | |
26324 | + *addr = val; | |
26325 | + else | |
26326 | + { | |
26327 | + /* If no error ocurred, VAL is indeed negative. */ | |
26328 | + if (PyErr_Occurred () != NULL) | |
26329 | + return 0; | |
26330 | + | |
26331 | + PyErr_SetString (PyExc_ValueError, "negative address"); | |
26332 | + return 0; | |
26333 | + } | |
26334 | + } | |
26335 | + else | |
26336 | + { | |
26337 | + PyErr_SetString (PyExc_TypeError, "invalid type for address"); | |
26338 | + return 0; | |
26339 | + } | |
26340 | + | |
26341 | + return 1; | |
26342 | +} | |
26343 | diff --git a/gdb/python/python-value.c b/gdb/python/python-value.c | |
26344 | index bc077b6..2507fcd 100644 | |
26345 | --- a/gdb/python/python-value.c | |
26346 | +++ b/gdb/python/python-value.c | |
26347 | @@ -52,6 +52,10 @@ struct value *values_in_python = NULL; | |
26348 | /* Python's long type corresponds to C's long long type. */ | |
26349 | #define builtin_type_pylong builtin_type (current_gdbarch)->builtin_long_long | |
26350 | ||
26351 | +/* Python's long type corresponds to C's long long type. Unsigned version. */ | |
26352 | +#define builtin_type_upylong builtin_type \ | |
26353 | + (current_gdbarch)->builtin_unsigned_long_long | |
26354 | + | |
26355 | #define builtin_type_pybool \ | |
26356 | language_bool_type (current_language, current_gdbarch) | |
26357 | ||
26358 | @@ -143,10 +147,19 @@ valpy_address (PyObject *self, PyObject *args) | |
26359 | return value_to_value_object (res_val); | |
26360 | } | |
26361 | ||
26362 | -/* Return Unicode string with value contents (assumed to be encoded in the | |
26363 | - target's charset). */ | |
26364 | +/* Return type of the value. */ | |
26365 | +static PyObject * | |
26366 | +valpy_type (PyObject *self, PyObject *args) | |
26367 | +{ | |
26368 | + struct value *value = ((value_object *) self)->value; | |
26369 | + return type_to_type_object (value_type (value)); | |
26370 | +} | |
26371 | + | |
26372 | +/* Implementation of gdb.Value.string ([encoding] [, errors]) -> string | |
26373 | + Return Unicode string with value contents. If ENCODING is not given, | |
26374 | + the string is assumed to be encoded in the target's charset. */ | |
26375 | static PyObject * | |
26376 | -valpy_string (PyObject *self, PyObject *args) | |
26377 | +valpy_string (PyObject *self, PyObject *args, PyObject *kw) | |
26378 | { | |
26379 | int length, ret = 0; | |
26380 | gdb_byte *buffer; | |
26381 | @@ -157,8 +170,10 @@ valpy_string (PyObject *self, PyObject *args) | |
26382 | const char *errors = NULL; | |
26383 | const char *user_encoding = NULL; | |
26384 | const char *la_encoding = NULL; | |
26385 | + static char *keywords[] = { "encoding", "errors" }; | |
26386 | ||
26387 | - if (!PyArg_ParseTuple (args, "|ss", &user_encoding, &errors)) | |
26388 | + if (!PyArg_ParseTupleAndKeywords (args, kw, "|ss", keywords, | |
26389 | + &user_encoding, &errors)) | |
26390 | return NULL; | |
26391 | ||
26392 | TRY_CATCH (except, RETURN_MASK_ALL) | |
26393 | @@ -174,6 +189,34 @@ valpy_string (PyObject *self, PyObject *args) | |
26394 | return unicode; | |
26395 | } | |
26396 | ||
26397 | +/* Cast a value to a given type. */ | |
26398 | +static PyObject * | |
26399 | +valpy_cast (PyObject *self, PyObject *args) | |
26400 | +{ | |
26401 | + PyObject *type_obj; | |
26402 | + struct type *type; | |
26403 | + struct value *res_val = NULL; /* Initialize to appease gcc warning. */ | |
26404 | + volatile struct gdb_exception except; | |
26405 | + | |
26406 | + if (! PyArg_ParseTuple (args, "O", &type_obj)) | |
26407 | + return NULL; | |
26408 | + | |
26409 | + type = type_object_to_type (type_obj); | |
26410 | + if (! type) | |
26411 | + { | |
26412 | + PyErr_SetString (PyExc_RuntimeError, "argument must be a Type"); | |
26413 | + return NULL; | |
26414 | + } | |
26415 | + | |
26416 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
26417 | + { | |
26418 | + res_val = value_cast (type, ((value_object *) self)->value); | |
26419 | + } | |
26420 | + GDB_PY_HANDLE_EXCEPTION (except); | |
26421 | + | |
26422 | + return value_to_value_object (res_val); | |
26423 | +} | |
26424 | + | |
26425 | static Py_ssize_t | |
26426 | valpy_length (PyObject *self) | |
26427 | { | |
26428 | @@ -306,11 +349,11 @@ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other) | |
26429 | a gdb.Value object and need to convert it from python as well. */ | |
26430 | arg1 = convert_value_from_python (self); | |
26431 | if (arg1 == NULL) | |
26432 | - return NULL; | |
26433 | + break; | |
26434 | ||
26435 | arg2 = convert_value_from_python (other); | |
26436 | if (arg2 == NULL) | |
26437 | - return NULL; | |
26438 | + break; | |
26439 | ||
26440 | switch (opcode) | |
26441 | { | |
26442 | @@ -387,7 +430,7 @@ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other) | |
26443 | } | |
26444 | GDB_PY_HANDLE_EXCEPTION (except); | |
26445 | ||
26446 | - return value_to_value_object (res_val); | |
26447 | + return res_val ? value_to_value_object (res_val) : NULL; | |
26448 | } | |
26449 | ||
26450 | static PyObject * | |
26451 | @@ -718,6 +761,17 @@ value_to_value_object (struct value *val) | |
26452 | return (PyObject *) val_obj; | |
26453 | } | |
26454 | ||
26455 | +/* Returns value structure corresponding to the given value object. */ | |
26456 | +struct value * | |
26457 | +value_object_to_value (PyObject *self) | |
26458 | +{ | |
26459 | + value_object *real; | |
26460 | + if (! PyObject_TypeCheck (self, &value_object_type)) | |
26461 | + return NULL; | |
26462 | + real = (value_object *) self; | |
26463 | + return real->value; | |
26464 | +} | |
26465 | + | |
26466 | /* Try to convert a Python value to a gdb value. If the value cannot | |
26467 | be converted, set a Python exception and return NULL. */ | |
26468 | ||
26469 | @@ -751,7 +805,34 @@ convert_value_from_python (PyObject *obj) | |
26470 | { | |
26471 | LONGEST l = PyLong_AsLongLong (obj); | |
26472 | ||
26473 | - if (! PyErr_Occurred ()) | |
26474 | + if (PyErr_Occurred ()) | |
26475 | + { | |
26476 | + /* If the error was an overflow, we can try converting to | |
26477 | + ULONGEST instead. */ | |
26478 | + if (PyErr_ExceptionMatches (PyExc_OverflowError)) | |
26479 | + { | |
26480 | + PyObject *etype, *evalue, *etraceback, *zero; | |
26481 | + | |
26482 | + PyErr_Fetch (&etype, &evalue, &etraceback); | |
26483 | + zero = PyInt_FromLong (0); | |
26484 | + | |
26485 | + /* Check whether obj is positive. */ | |
26486 | + if (PyObject_RichCompareBool (obj, zero, Py_GT) > 0) | |
26487 | + { | |
26488 | + ULONGEST ul; | |
26489 | + | |
26490 | + ul = PyLong_AsUnsignedLongLong (obj); | |
26491 | + if (! PyErr_Occurred ()) | |
26492 | + value = value_from_ulongest (builtin_type_upylong, ul); | |
26493 | + } | |
26494 | + else | |
26495 | + /* There's nothing we can do. */ | |
26496 | + PyErr_Restore (etype, evalue, etraceback); | |
26497 | + | |
26498 | + Py_DECREF (zero); | |
26499 | + } | |
26500 | + } | |
26501 | + else | |
26502 | value = value_from_longest (builtin_type_pylong, l); | |
26503 | } | |
26504 | else if (PyFloat_Check (obj)) | |
26505 | @@ -774,7 +855,7 @@ convert_value_from_python (PyObject *obj) | |
26506 | } | |
26507 | } | |
26508 | else if (PyObject_TypeCheck (obj, &value_object_type)) | |
26509 | - value = ((value_object *) obj)->value; | |
26510 | + value = value_copy (((value_object *) obj)->value); | |
26511 | else | |
26512 | PyErr_Format (PyExc_TypeError, _("Could not convert Python object: %s"), | |
26513 | PyString_AsString (PyObject_Str (obj))); | |
26514 | @@ -810,6 +891,14 @@ gdbpy_history (PyObject *self, PyObject *args) | |
26515 | return value_to_value_object (res_val); | |
26516 | } | |
26517 | ||
26518 | +/* Returns 1 in OBJ is a gdb.Value object, 0 otherwise. */ | |
26519 | + | |
26520 | +int | |
26521 | +gdbpy_is_value_object (PyObject *obj) | |
26522 | +{ | |
26523 | + return PyObject_TypeCheck (obj, &value_object_type); | |
26524 | +} | |
26525 | + | |
26526 | void | |
26527 | gdbpy_initialize_values (void) | |
26528 | { | |
26529 | @@ -822,11 +911,16 @@ gdbpy_initialize_values (void) | |
26530 | values_in_python = NULL; | |
26531 | } | |
26532 | ||
26533 | +\f | |
26534 | + | |
26535 | static PyMethodDef value_object_methods[] = { | |
26536 | { "address", valpy_address, METH_NOARGS, "Return the address of the value." }, | |
26537 | + { "cast", valpy_cast, METH_VARARGS, "Cast the value to the supplied type." }, | |
26538 | { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." }, | |
26539 | - { "string", valpy_string, METH_VARARGS, | |
26540 | - "Return Unicode string representation of the value." }, | |
26541 | + { "type", valpy_type, METH_NOARGS, "Return type of the value." }, | |
26542 | + { "string", (PyCFunction) valpy_string, METH_VARARGS | METH_KEYWORDS, | |
26543 | + "string ([encoding] [, errors]) -> string\n\ | |
26544 | +Return Unicode string representation of the value." }, | |
26545 | {NULL} /* Sentinel */ | |
26546 | }; | |
26547 | ||
26548 | diff --git a/gdb/python/python.c b/gdb/python/python.c | |
26549 | index b3a27d6..2b06748 100644 | |
26550 | --- a/gdb/python/python.c | |
26551 | +++ b/gdb/python/python.c | |
26552 | @@ -22,6 +22,12 @@ | |
26553 | #include "ui-out.h" | |
26554 | #include "cli/cli-script.h" | |
26555 | #include "gdbcmd.h" | |
26556 | +#include "objfiles.h" | |
26557 | +#include "observer.h" | |
26558 | +#include "gdb_regex.h" | |
26559 | +#include "language.h" | |
26560 | +#include "valprint.h" | |
26561 | +#include "event-loop.h" | |
26562 | ||
26563 | #include <ctype.h> | |
26564 | ||
26565 | @@ -29,6 +35,10 @@ | |
26566 | false otherwise. */ | |
26567 | static int gdbpy_should_print_stack = 1; | |
26568 | ||
26569 | +/* This is true if we should auto-load python code when an objfile is | |
26570 | + opened, false otherwise. */ | |
26571 | +static int gdbpy_auto_load = 1; | |
26572 | + | |
26573 | #ifdef HAVE_PYTHON | |
26574 | ||
26575 | #include "python.h" | |
26576 | @@ -36,16 +46,29 @@ static int gdbpy_should_print_stack = 1; | |
26577 | #include "cli/cli-decode.h" | |
26578 | #include "charset.h" | |
26579 | #include "top.h" | |
26580 | +#include "solib.h" | |
26581 | #include "exceptions.h" | |
26582 | #include "python-internal.h" | |
26583 | +#include "linespec.h" | |
26584 | +#include "symtab.h" | |
26585 | +#include "source.h" | |
26586 | #include "version.h" | |
26587 | +#include "inferior.h" | |
26588 | +#include "gdbthread.h" | |
26589 | #include "target.h" | |
26590 | #include "gdbthread.h" | |
26591 | +#include "event-top.h" | |
26592 | + | |
26593 | +static PyMethodDef GdbMethods[]; | |
26594 | ||
26595 | static PyMethodDef GdbMethods[]; | |
26596 | ||
26597 | PyObject *gdb_module; | |
26598 | ||
26599 | +/* Some string constants we may wish to use. */ | |
26600 | +PyObject *gdbpy_to_string_cst; | |
26601 | +PyObject *gdbpy_children_cst; | |
26602 | +PyObject *gdbpy_display_hint_cst; | |
26603 | PyObject *gdbpy_doc_cst; | |
26604 | ||
26605 | /* Given a command_line, return a command string suitable for passing | |
26606 | @@ -143,10 +166,10 @@ python_command (char *arg, int from_tty) | |
26607 | NULL (and set a Python exception) on error. Helper function for | |
26608 | get_parameter. */ | |
26609 | ||
26610 | -static PyObject * | |
26611 | -parameter_to_python (struct cmd_list_element *cmd) | |
26612 | +PyObject * | |
26613 | +gdbpy_parameter_value (enum var_types type, void *var) | |
26614 | { | |
26615 | - switch (cmd->var_type) | |
26616 | + switch (type) | |
26617 | { | |
26618 | case var_string: | |
26619 | case var_string_noescape: | |
26620 | @@ -154,7 +177,7 @@ parameter_to_python (struct cmd_list_element *cmd) | |
26621 | case var_filename: | |
26622 | case var_enum: | |
26623 | { | |
26624 | - char *str = * (char **) cmd->var; | |
26625 | + char *str = * (char **) var; | |
26626 | if (! str) | |
26627 | str = ""; | |
26628 | return PyString_Decode (str, strlen (str), host_charset (), NULL); | |
26629 | @@ -162,7 +185,7 @@ parameter_to_python (struct cmd_list_element *cmd) | |
26630 | ||
26631 | case var_boolean: | |
26632 | { | |
26633 | - if (* (int *) cmd->var) | |
26634 | + if (* (int *) var) | |
26635 | Py_RETURN_TRUE; | |
26636 | else | |
26637 | Py_RETURN_FALSE; | |
26638 | @@ -170,7 +193,7 @@ parameter_to_python (struct cmd_list_element *cmd) | |
26639 | ||
26640 | case var_auto_boolean: | |
26641 | { | |
26642 | - enum auto_boolean ab = * (enum auto_boolean *) cmd->var; | |
26643 | + enum auto_boolean ab = * (enum auto_boolean *) var; | |
26644 | if (ab == AUTO_BOOLEAN_TRUE) | |
26645 | Py_RETURN_TRUE; | |
26646 | else if (ab == AUTO_BOOLEAN_FALSE) | |
26647 | @@ -180,15 +203,15 @@ parameter_to_python (struct cmd_list_element *cmd) | |
26648 | } | |
26649 | ||
26650 | case var_integer: | |
26651 | - if ((* (int *) cmd->var) == INT_MAX) | |
26652 | + if ((* (int *) var) == INT_MAX) | |
26653 | Py_RETURN_NONE; | |
26654 | /* Fall through. */ | |
26655 | case var_zinteger: | |
26656 | - return PyLong_FromLong (* (int *) cmd->var); | |
26657 | + return PyLong_FromLong (* (int *) var); | |
26658 | ||
26659 | case var_uinteger: | |
26660 | { | |
26661 | - unsigned int val = * (unsigned int *) cmd->var; | |
26662 | + unsigned int val = * (unsigned int *) var; | |
26663 | if (val == UINT_MAX) | |
26664 | Py_RETURN_NONE; | |
26665 | return PyLong_FromUnsignedLong (val); | |
26666 | @@ -202,10 +225,11 @@ parameter_to_python (struct cmd_list_element *cmd) | |
26667 | value. */ | |
26668 | ||
26669 | static PyObject * | |
26670 | -get_parameter (PyObject *self, PyObject *args) | |
26671 | +gdbpy_parameter (PyObject *self, PyObject *args) | |
26672 | { | |
26673 | struct cmd_list_element *alias, *prefix, *cmd; | |
26674 | char *arg, *newarg; | |
26675 | + int found = -1; | |
26676 | volatile struct gdb_exception except; | |
26677 | ||
26678 | if (! PyArg_ParseTuple (args, "s", &arg)) | |
26679 | @@ -215,19 +239,17 @@ get_parameter (PyObject *self, PyObject *args) | |
26680 | ||
26681 | TRY_CATCH (except, RETURN_MASK_ALL) | |
26682 | { | |
26683 | - if (! lookup_cmd_composition (newarg, &alias, &prefix, &cmd)) | |
26684 | - { | |
26685 | - xfree (newarg); | |
26686 | - return PyErr_Format (PyExc_RuntimeError, | |
26687 | - "could not find variable `%s'", arg); | |
26688 | - } | |
26689 | + found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd); | |
26690 | } | |
26691 | xfree (newarg); | |
26692 | GDB_PY_HANDLE_EXCEPTION (except); | |
26693 | + if (!found) | |
26694 | + return PyErr_Format (PyExc_RuntimeError, | |
26695 | + "could not find parameter `%s'", arg); | |
26696 | ||
26697 | if (! cmd->var) | |
26698 | - return PyErr_Format (PyExc_RuntimeError, "`%s' is not a variable", arg); | |
26699 | - return parameter_to_python (cmd); | |
26700 | + return PyErr_Format (PyExc_RuntimeError, "`%s' is not a parameter", arg); | |
26701 | + return gdbpy_parameter_value (cmd->var_type, cmd->var); | |
26702 | } | |
26703 | ||
26704 | /* A Python function which evaluates a string using the gdb CLI. */ | |
26705 | @@ -266,6 +288,570 @@ execute_gdb_command (PyObject *self, PyObject *args) | |
26706 | Py_RETURN_NONE; | |
26707 | } | |
26708 | ||
26709 | +/* Implementation of gdb.solib_address (Long) -> String. | |
26710 | + Returns the name of the shared library holding a given address, or None. */ | |
26711 | + | |
26712 | +static PyObject * | |
26713 | +gdbpy_solib_address (PyObject *self, PyObject *args) | |
26714 | +{ | |
26715 | + unsigned long long pc; | |
26716 | + char *soname; | |
26717 | + PyObject *str_obj; | |
26718 | + | |
26719 | + if (!PyArg_ParseTuple (args, "K", &pc)) | |
26720 | + return NULL; | |
26721 | + | |
26722 | + soname = solib_address (pc); | |
26723 | + if (soname) | |
26724 | + str_obj = PyString_Decode (soname, strlen (soname), host_charset (), NULL); | |
26725 | + else | |
26726 | + { | |
26727 | + str_obj = Py_None; | |
26728 | + Py_INCREF (Py_None); | |
26729 | + } | |
26730 | + | |
26731 | + return str_obj; | |
26732 | +} | |
26733 | + | |
26734 | +static PyObject * | |
26735 | +gdbpy_find_pc_function (PyObject *self, PyObject *args) | |
26736 | +{ | |
26737 | + unsigned long long pc; | |
26738 | + struct symbol *sym; | |
26739 | + PyObject *sym_obj; | |
26740 | + | |
26741 | + if (!PyArg_ParseTuple (args, "K", &pc)) | |
26742 | + return NULL; | |
26743 | + | |
26744 | + sym = find_pc_function (pc); | |
26745 | + if (sym) | |
26746 | + return symbol_to_symbol_object (sym); | |
26747 | + | |
26748 | + Py_RETURN_NONE; | |
26749 | +} | |
26750 | + | |
26751 | +/* Adds GDB value V to the pattern buffer in *PATTERN_BUF. If SIZE is not zero, | |
26752 | + it specifies the number of bytes from V to copy to *PATTERN_BUF. The | |
26753 | + function increases the size of *PATTERN_BUF as necessary, adjusting | |
26754 | + *PATTERN_BUF_END and *PATTERN_BUF_SIZE in the process. */ | |
26755 | + | |
26756 | +static void | |
26757 | +add_value_pattern (struct value *v, int size, char **pattern_buf, | |
26758 | + char **pattern_buf_end, ULONGEST *pattern_buf_size) | |
26759 | +{ | |
26760 | + int val_bytes; | |
26761 | + | |
26762 | + if (size) | |
26763 | + { | |
26764 | + LONGEST x = value_as_long (v); | |
26765 | + | |
26766 | + if (size == 1) | |
26767 | + *(*pattern_buf_end)++ = x; | |
26768 | + else | |
26769 | + { | |
26770 | + put_bits (x, *pattern_buf_end, size * 8, | |
26771 | + gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG); | |
26772 | + *pattern_buf_end += size; | |
26773 | + } | |
26774 | + } | |
26775 | + else | |
26776 | + { | |
26777 | + val_bytes = TYPE_LENGTH (value_type (v)); | |
26778 | + | |
26779 | + increase_pattern_buffer (pattern_buf, pattern_buf_end, | |
26780 | + pattern_buf_size, val_bytes); | |
26781 | + | |
26782 | + memcpy (*pattern_buf_end, value_contents_raw (v), val_bytes); | |
26783 | + *pattern_buf_end += val_bytes; | |
26784 | + } | |
26785 | +} | |
26786 | + | |
26787 | +/* This function does the actual work of constructing the pattern buffer from | |
26788 | + OBJ. If OBJ is an object which implements the read buffer protocol (such | |
26789 | + as a string, a byte array or gdb.Membuf), then its contents are directly | |
26790 | + copied to *PATTERN_BUF. If it is a list, then this function is recursively | |
26791 | + called for each of its elements. If OBJ is an object which can be converted | |
26792 | + to a GDB value, then the contents of the value are copied to PATTERN_BUF. | |
26793 | + If SIZE is different than zero, then it limits the number of bytes which | |
26794 | + are copied to the buffer in case OBJ is converted to a GDB value. That | |
26795 | + means that SIZE influences only Python scalars and gdb.Value objects. | |
26796 | + The function increases the size of *PATTERN_BUF as necessary, adjusting | |
26797 | + *PATTERN_BUF_END and *PATTERN_BUF_SIZE in the process. | |
26798 | + | |
26799 | + Returns 1 on success or 0 on failure, with a Python exception set. This | |
26800 | + function can also throw GDB exceptions. */ | |
26801 | + | |
26802 | +static int | |
26803 | +add_pattern_element (PyObject *obj, int size, char **pattern_buf, | |
26804 | + char **pattern_buf_end, ULONGEST *pattern_buf_size) | |
26805 | +{ | |
26806 | + if (PyObject_CheckReadBuffer (obj)) | |
26807 | + { | |
26808 | + /* Handle string, Unicode string, byte array, gdb.Membuf and any other | |
26809 | + object implementing the buffer protocol. The SIZE parameter is | |
26810 | + ignored in this case. */ | |
26811 | + | |
26812 | + Py_ssize_t val_bytes; | |
26813 | + const void *buffer; | |
26814 | + | |
26815 | + if (PyObject_AsReadBuffer (obj, &buffer, &val_bytes) == -1) | |
26816 | + return 0; | |
26817 | + | |
26818 | + increase_pattern_buffer (pattern_buf, pattern_buf_end, | |
26819 | + pattern_buf_size, val_bytes); | |
26820 | + | |
26821 | + memcpy (*pattern_buf_end, buffer, val_bytes); | |
26822 | + *pattern_buf_end += val_bytes; | |
26823 | + } | |
26824 | + else if (gdbpy_is_value_object (obj)) | |
26825 | + add_value_pattern (value_object_to_value (obj), size, pattern_buf, | |
26826 | + pattern_buf_end, pattern_buf_size); | |
26827 | + else if (PySequence_Check (obj)) | |
26828 | + { | |
26829 | + /* Handle lists and tuples. */ | |
26830 | + | |
26831 | + Py_ssize_t i, num_objs; | |
26832 | + | |
26833 | + num_objs = PySequence_Size (obj); | |
26834 | + for (i = 0; i < num_objs; i++) | |
26835 | + if (!add_pattern_element (PySequence_GetItem (obj, i), size, | |
26836 | + pattern_buf, pattern_buf_end, | |
26837 | + pattern_buf_size)) | |
26838 | + return 0; | |
26839 | + } | |
26840 | + else | |
26841 | + { | |
26842 | + /* See if we can convert from a Python object to a GDB value. */ | |
26843 | + | |
26844 | + struct value *v = convert_value_from_python (obj); | |
26845 | + | |
26846 | + if (v) | |
26847 | + add_value_pattern (v, size, pattern_buf, pattern_buf_end, | |
26848 | + pattern_buf_size); | |
26849 | + else | |
26850 | + return 0; | |
26851 | + } | |
26852 | + | |
26853 | + return 1; | |
26854 | +} | |
26855 | + | |
26856 | +/* Constructs the search pattern from OBJ, putting it in *PATTERN_BUFP, and its | |
26857 | + size in *PATTERN_LENP. See the function add_pattern_element to learn how | |
26858 | + the search pattern is obtained from OBJ. | |
26859 | + | |
26860 | + Returns 1 on success or 0 on failure, with a Python exception set. This | |
26861 | + function can also throw GDB exceptions. */ | |
26862 | + | |
26863 | +static int | |
26864 | +get_search_pattern (PyObject *obj, int size, char **pattern_bufp, | |
26865 | + ULONGEST *pattern_lenp) | |
26866 | +{ | |
26867 | + /* Buffer to hold the search pattern. */ | |
26868 | + char *pattern_buf; | |
26869 | + /* Current size of search pattern buffer. | |
26870 | + We realloc space as needed. */ | |
26871 | + ULONGEST pattern_buf_size; | |
26872 | + /* Pointer to one past the last in-use part of pattern_buf. */ | |
26873 | + char *pattern_buf_end; | |
26874 | + struct cleanup *old_cleanups; | |
26875 | + | |
26876 | + allocate_pattern_buffer (&pattern_buf, &pattern_buf_end, &pattern_buf_size); | |
26877 | + old_cleanups = make_cleanup (free_current_contents, &pattern_buf); | |
26878 | + | |
26879 | + if (!add_pattern_element (obj, size, &pattern_buf, &pattern_buf_end, | |
26880 | + &pattern_buf_size)) | |
26881 | + { | |
26882 | + do_cleanups (old_cleanups); | |
26883 | + | |
26884 | + return 0; | |
26885 | + } | |
26886 | + | |
26887 | + *pattern_bufp = pattern_buf; | |
26888 | + *pattern_lenp = pattern_buf_end - pattern_buf; | |
26889 | + | |
26890 | + discard_cleanups (old_cleanups); | |
26891 | + | |
26892 | + return 1; | |
26893 | +} | |
26894 | + | |
26895 | +/* Implementation of | |
26896 | + gdb.search_memory (address, length, pattern [, size] [, max_count]). | |
26897 | + The third argument may be either a pattern, or a list or tupple of patterns | |
26898 | + to be searched. Size is the size in bytes of each search query value, either | |
26899 | + 1, 2, 4 or 8. Returns a list of the addresses where matches were found. */ | |
26900 | + | |
26901 | +PyObject * | |
26902 | +gdbpy_search_memory (PyObject *self, PyObject *args, PyObject *kw) | |
26903 | +{ | |
26904 | + int size = 0; | |
26905 | + long length; | |
26906 | + unsigned int found_count = 0; | |
26907 | + long max_count = 0; | |
26908 | + CORE_ADDR start_addr; | |
26909 | + char *pattern_buf; | |
26910 | + static char *keywords[] = { "address", "length", "pattern", "size", | |
26911 | + "max_count", NULL }; | |
26912 | + ULONGEST pattern_len, search_space_len; | |
26913 | + PyObject *pattern, *list = NULL, *start_addr_obj; | |
26914 | + volatile struct gdb_exception except; | |
26915 | + | |
26916 | + /* Assume CORE_ADDR corresponds to unsigned long. */ | |
26917 | + if (! PyArg_ParseTupleAndKeywords (args, kw, "OlO|il", keywords, | |
26918 | + &start_addr_obj, &length, &pattern, | |
26919 | + &size, &max_count)) | |
26920 | + return NULL; | |
26921 | + | |
26922 | + if (!max_count) | |
26923 | + max_count = LONG_MAX; | |
26924 | + | |
26925 | + if (!length) | |
26926 | + { | |
26927 | + PyErr_SetString (PyExc_ValueError, "empty search range"); | |
26928 | + return NULL; | |
26929 | + } | |
26930 | + else if (length < 0) | |
26931 | + { | |
26932 | + PyErr_SetString (PyExc_ValueError, "invalid search range"); | |
26933 | + return NULL; | |
26934 | + } | |
26935 | + else | |
26936 | + { | |
26937 | + /* Watch for overflows. */ | |
26938 | + if (length > CORE_ADDR_MAX | |
26939 | + || (start_addr + length - 1) < start_addr) | |
26940 | + { | |
26941 | + PyErr_SetString (PyExc_ValueError, "search range too large"); | |
26942 | + return NULL; | |
26943 | + } | |
26944 | + | |
26945 | + search_space_len = length; | |
26946 | + } | |
26947 | + | |
26948 | + if (size != 0 && size != 1 && size != 2 && size != 4 && size != 8) | |
26949 | + { | |
26950 | + PyErr_SetString (PyExc_ValueError, "invalid pattern size"); | |
26951 | + return NULL; | |
26952 | + } | |
26953 | + | |
26954 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
26955 | + { | |
26956 | + if (get_addr_from_python (start_addr_obj, &start_addr)) | |
26957 | + { | |
26958 | + if (get_search_pattern (pattern, size, &pattern_buf, &pattern_len)) | |
26959 | + { | |
26960 | + /* Any cleanups get automatically executed on an exception. */ | |
26961 | + struct cleanup *cleanups = make_cleanup (xfree, pattern_buf); | |
26962 | + | |
26963 | + list = PyList_New (0); | |
26964 | + | |
26965 | + while (search_space_len >= pattern_len && found_count < max_count) | |
26966 | + { | |
26967 | + CORE_ADDR found_addr; | |
26968 | + int found; | |
26969 | + | |
26970 | + found = search_memory (&start_addr, &search_space_len, | |
26971 | + pattern_buf, pattern_len, &found_addr); | |
26972 | + if (found <= 0) | |
26973 | + break; | |
26974 | + | |
26975 | + PyList_Append (list, PyLong_FromUnsignedLong (found_addr)); | |
26976 | + ++found_count; | |
26977 | + } | |
26978 | + | |
26979 | + do_cleanups (cleanups); | |
26980 | + } | |
26981 | + } | |
26982 | + } | |
26983 | + GDB_PY_HANDLE_EXCEPTION (except); | |
26984 | + | |
26985 | + return list; | |
26986 | +} | |
26987 | + | |
26988 | +/* A Python function which is a wrapper for decode_line_1. */ | |
26989 | + | |
26990 | +static PyObject * | |
26991 | +gdbpy_decode_line (PyObject *self, PyObject *args) | |
26992 | +{ | |
26993 | + struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to appease gcc. */ | |
26994 | + struct symtab_and_line sal; | |
26995 | + char *arg = NULL; | |
26996 | + int free_sals = 0, i; | |
26997 | + PyObject *result = NULL; | |
26998 | + volatile struct gdb_exception except; | |
26999 | + | |
27000 | + if (! PyArg_ParseTuple (args, "|s", &arg)) | |
27001 | + return NULL; | |
27002 | + | |
27003 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
27004 | + { | |
27005 | + if (arg) | |
27006 | + { | |
27007 | + char *copy; | |
27008 | + | |
27009 | + arg = strdup (arg); | |
27010 | + copy = arg; | |
27011 | + | |
27012 | + sals = decode_line_1 (©, 0, 0, 0, 0, 0); | |
27013 | + free_sals = 1; | |
27014 | + } | |
27015 | + else | |
27016 | + { | |
27017 | + set_default_source_symtab_and_line (); | |
27018 | + sal = get_current_source_symtab_and_line (); | |
27019 | + sals.sals = &sal; | |
27020 | + sals.nelts = 1; | |
27021 | + } | |
27022 | + } | |
27023 | + if (arg) | |
27024 | + xfree (arg); | |
27025 | + | |
27026 | + if (except.reason < 0) | |
27027 | + { | |
27028 | + if (free_sals) | |
27029 | + xfree (sals.sals); | |
27030 | + /* We know this will always throw. */ | |
27031 | + GDB_PY_HANDLE_EXCEPTION (except); | |
27032 | + } | |
27033 | + | |
27034 | + if (sals.nelts) | |
27035 | + { | |
27036 | + result = PyTuple_New (sals.nelts); | |
27037 | + for (i = 0; i < sals.nelts; ++i) | |
27038 | + { | |
27039 | + PyObject *obj; | |
27040 | + char *str; | |
27041 | + | |
27042 | + obj = symtab_and_line_to_sal_object (sals.sals[i]); | |
27043 | + if (! obj) | |
27044 | + { | |
27045 | + Py_DECREF (result); | |
27046 | + result = NULL; | |
27047 | + break; | |
27048 | + } | |
27049 | + | |
27050 | + PyTuple_SetItem (result, i, obj); | |
27051 | + } | |
27052 | + } | |
27053 | + | |
27054 | + if (free_sals) | |
27055 | + xfree (sals.sals); | |
27056 | + | |
27057 | + if (result) | |
27058 | + return result; | |
27059 | + Py_RETURN_NONE; | |
27060 | +} | |
27061 | + | |
27062 | +/* Parse a string and evaluate it as an expression. */ | |
27063 | +static PyObject * | |
27064 | +gdbpy_parse_and_eval (PyObject *self, PyObject *args) | |
27065 | +{ | |
27066 | + char *expr_str; | |
27067 | + struct value *result = NULL; | |
27068 | + volatile struct gdb_exception except; | |
27069 | + | |
27070 | + if (!PyArg_ParseTuple (args, "s", &expr_str)) | |
27071 | + return NULL; | |
27072 | + | |
27073 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
27074 | + { | |
27075 | + result = parse_and_eval (expr_str); | |
27076 | + } | |
27077 | + GDB_PY_HANDLE_EXCEPTION (except); | |
27078 | + | |
27079 | + return value_to_value_object (result); | |
27080 | +} | |
27081 | + | |
27082 | +\f | |
27083 | + | |
27084 | +/* Posting and handling events. */ | |
27085 | + | |
27086 | +/* A single event. */ | |
27087 | +struct gdbpy_event | |
27088 | +{ | |
27089 | + /* The Python event. This is just a callable object. */ | |
27090 | + PyObject *event; | |
27091 | + /* The next event. */ | |
27092 | + struct gdbpy_event *next; | |
27093 | +}; | |
27094 | + | |
27095 | +/* All pending events. */ | |
27096 | +static struct gdbpy_event *gdbpy_event_list; | |
27097 | +/* The final link of the event list. */ | |
27098 | +static struct gdbpy_event **gdbpy_event_list_end; | |
27099 | + | |
27100 | +/* We use a file handler, and not an async handler, so that we can | |
27101 | + wake up the main thread even when it is blocked in poll(). */ | |
27102 | +static int gdbpy_event_fds[2]; | |
27103 | + | |
27104 | +/* The file handler callback. This reads from the internal pipe, and | |
27105 | + then processes the Python event queue. This will always be run in | |
27106 | + the main gdb thread. */ | |
27107 | +static void | |
27108 | +gdbpy_run_events (int err, gdb_client_data ignore) | |
27109 | +{ | |
27110 | + PyGILState_STATE state; | |
27111 | + char buffer[100]; | |
27112 | + int r; | |
27113 | + | |
27114 | + state = PyGILState_Ensure (); | |
27115 | + | |
27116 | + /* Just read whatever is available on the fd. It is relatively | |
27117 | + harmless if there are any bytes left over. */ | |
27118 | + r = read (gdbpy_event_fds[0], buffer, sizeof (buffer)); | |
27119 | + | |
27120 | + while (gdbpy_event_list) | |
27121 | + { | |
27122 | + /* Dispatching the event might push a new element onto the event | |
27123 | + loop, so we update here "atomically enough". */ | |
27124 | + struct gdbpy_event *item = gdbpy_event_list; | |
27125 | + gdbpy_event_list = gdbpy_event_list->next; | |
27126 | + if (gdbpy_event_list == NULL) | |
27127 | + gdbpy_event_list_end = &gdbpy_event_list; | |
27128 | + | |
27129 | + /* Ignore errors. */ | |
27130 | + PyObject_CallObject (item->event, NULL); | |
27131 | + | |
27132 | + Py_DECREF (item->event); | |
27133 | + xfree (item); | |
27134 | + } | |
27135 | + | |
27136 | + PyGILState_Release (state); | |
27137 | +} | |
27138 | + | |
27139 | +/* Submit an event to the gdb thread. */ | |
27140 | +static PyObject * | |
27141 | +gdbpy_post_event (PyObject *self, PyObject *args) | |
27142 | +{ | |
27143 | + struct gdbpy_event *event; | |
27144 | + PyObject *func; | |
27145 | + int wakeup; | |
27146 | + | |
27147 | + if (!PyArg_ParseTuple (args, "O", &func)) | |
27148 | + return NULL; | |
27149 | + | |
27150 | + if (!PyCallable_Check (func)) | |
27151 | + { | |
27152 | + PyErr_SetString (PyExc_RuntimeError, "Posted event is not callable"); | |
27153 | + return NULL; | |
27154 | + } | |
27155 | + | |
27156 | + Py_INCREF (func); | |
27157 | + | |
27158 | + /* From here until the end of the function, we have the GIL, so we | |
27159 | + can operate on our global data structures without worrying. */ | |
27160 | + wakeup = gdbpy_event_list == NULL; | |
27161 | + | |
27162 | + event = XNEW (struct gdbpy_event); | |
27163 | + event->event = func; | |
27164 | + event->next = NULL; | |
27165 | + *gdbpy_event_list_end = event; | |
27166 | + gdbpy_event_list_end = &event->next; | |
27167 | + | |
27168 | + /* Wake up gdb when needed. */ | |
27169 | + if (wakeup) | |
27170 | + { | |
27171 | + char c = 'q'; /* Anything. */ | |
27172 | + if (write (gdbpy_event_fds[1], &c, 1) != 1) | |
27173 | + return PyErr_SetFromErrno (PyExc_IOError); | |
27174 | + } | |
27175 | + | |
27176 | + Py_RETURN_NONE; | |
27177 | +} | |
27178 | + | |
27179 | +/* Initialize the Python event handler. */ | |
27180 | +static void | |
27181 | +gdbpy_initialize_events (void) | |
27182 | +{ | |
27183 | + if (!pipe (gdbpy_event_fds)) | |
27184 | + { | |
27185 | + gdbpy_event_list_end = &gdbpy_event_list; | |
27186 | + add_file_handler (gdbpy_event_fds[0], gdbpy_run_events, NULL); | |
27187 | + } | |
27188 | +} | |
27189 | + | |
27190 | +\f | |
27191 | + | |
27192 | +/* Threads. */ | |
27193 | + | |
27194 | +/* Callback function for use with iterate_over_threads. This function | |
27195 | + just counts the number of threads. */ | |
27196 | + | |
27197 | +static int | |
27198 | +count_callback (struct thread_info *info, void *user_data) | |
27199 | +{ | |
27200 | + int *count = (int *) user_data; | |
27201 | + ++*count; | |
27202 | + return 0; | |
27203 | +} | |
27204 | + | |
27205 | +/* Structure for storing some state when iterating over threads. */ | |
27206 | + | |
27207 | +struct set_thread_info | |
27208 | +{ | |
27209 | + PyObject *tuple; | |
27210 | + int index; | |
27211 | +}; | |
27212 | + | |
27213 | +/* Callback function for use with iterate_over_threads. This function | |
27214 | + stores the thread ID into a Python tuple. */ | |
27215 | + | |
27216 | +static int | |
27217 | +update_tuple_callback (struct thread_info *info, void *user_data) | |
27218 | +{ | |
27219 | + struct set_thread_info *tinfo = (struct set_thread_info *) user_data; | |
27220 | + PyTuple_SetItem (tinfo->tuple, tinfo->index, PyInt_FromLong (info->num)); | |
27221 | + ++tinfo->index; | |
27222 | + return 0; | |
27223 | +} | |
27224 | + | |
27225 | +/* Python function which yields a tuple holding all valid thread IDs. */ | |
27226 | + | |
27227 | +static PyObject * | |
27228 | +gdbpy_threads (PyObject *unused1, PyObject *unused2) | |
27229 | +{ | |
27230 | + int thread_count = 0; | |
27231 | + struct set_thread_info info; | |
27232 | + PyObject *result; | |
27233 | + | |
27234 | + prune_threads (); | |
27235 | + target_find_new_threads (); | |
27236 | + | |
27237 | + iterate_over_threads (count_callback, &thread_count); | |
27238 | + | |
27239 | + if (!thread_count) | |
27240 | + Py_RETURN_NONE; | |
27241 | + | |
27242 | + result = PyTuple_New (thread_count); | |
27243 | + info.tuple = result; | |
27244 | + info.index = 0; | |
27245 | + iterate_over_threads (update_tuple_callback, &info); | |
27246 | + return result; | |
27247 | +} | |
27248 | + | |
27249 | +/* Python function that returns the current thread's ID. */ | |
27250 | + | |
27251 | +static PyObject * | |
27252 | +gdbpy_current_thread (PyObject *unused1, PyObject *unused2) | |
27253 | +{ | |
27254 | + if (PIDGET (inferior_ptid) == 0) | |
27255 | + Py_RETURN_NONE; | |
27256 | + return PyInt_FromLong (pid_to_thread_id (inferior_ptid)); | |
27257 | +} | |
27258 | + | |
27259 | +/* Python function for switching to a given thread. */ | |
27260 | + | |
27261 | +static PyObject * | |
27262 | +gdbpy_switch_to_thread (PyObject *self, PyObject *args) | |
27263 | +{ | |
27264 | + int id; | |
27265 | + if (! PyArg_ParseTuple (args, "i", &id)) | |
27266 | + return NULL; | |
27267 | + if (! valid_thread_id (id)) | |
27268 | + return PyErr_Format (PyExc_RuntimeError, "invalid thread id"); | |
27269 | + switch_to_thread (thread_id_to_pid (id)); | |
27270 | + Py_RETURN_NONE; | |
27271 | +} | |
27272 | + | |
27273 | \f | |
27274 | ||
27275 | /* Printing. */ | |
27276 | @@ -302,6 +888,769 @@ gdbpy_print_stack (void) | |
27277 | PyErr_Clear (); | |
27278 | } | |
27279 | ||
27280 | +\f | |
27281 | + | |
27282 | +/* Script interface. */ | |
27283 | + | |
27284 | +/* True if 'gdb -P' was used, false otherwise. */ | |
27285 | +static int running_python_script; | |
27286 | + | |
27287 | +/* True if we are currently in a call to 'gdb.cli', false otherwise. */ | |
27288 | +static int in_cli; | |
27289 | + | |
27290 | +/* Enter the command loop. */ | |
27291 | + | |
27292 | +static PyObject * | |
27293 | +gdbpy_cli (PyObject *unused1, PyObject *unused2) | |
27294 | +{ | |
27295 | + if (! running_python_script || in_cli) | |
27296 | + return PyErr_Format (PyExc_RuntimeError, "cannot invoke CLI recursively"); | |
27297 | + | |
27298 | + in_cli = 1; | |
27299 | + cli_command_loop (); | |
27300 | + in_cli = 0; | |
27301 | + | |
27302 | + Py_RETURN_NONE; | |
27303 | +} | |
27304 | + | |
27305 | +/* Set up the Python argument vector and evaluate a script. This is | |
27306 | + used to implement 'gdb -P'. */ | |
27307 | + | |
27308 | +void | |
27309 | +run_python_script (int argc, char **argv) | |
27310 | +{ | |
27311 | + FILE *input; | |
27312 | + PyGILState_STATE state; | |
27313 | + | |
27314 | + /* We never free this, since we plan to exit at the end. */ | |
27315 | + state = PyGILState_Ensure (); | |
27316 | + | |
27317 | + running_python_script = 1; | |
27318 | + PySys_SetArgv (argc - 1, argv + 1); | |
27319 | + input = fopen (argv[0], "r"); | |
27320 | + if (! input) | |
27321 | + { | |
27322 | + fprintf (stderr, "could not open %s: %s\n", argv[0], strerror (errno)); | |
27323 | + exit (1); | |
27324 | + } | |
27325 | + PyRun_SimpleFile (input, argv[0]); | |
27326 | + fclose (input); | |
27327 | + exit (0); | |
27328 | +} | |
27329 | + | |
27330 | +void | |
27331 | +source_python_script (FILE *stream, char *file) | |
27332 | +{ | |
27333 | + PyGILState_STATE state; | |
27334 | + | |
27335 | + state = PyGILState_Ensure (); | |
27336 | + | |
27337 | + PyRun_SimpleFile (stream, file); | |
27338 | + | |
27339 | + fclose (stream); | |
27340 | + PyGILState_Release (state); | |
27341 | +} | |
27342 | + | |
27343 | +\f | |
27344 | + | |
27345 | +/* The "current" objfile. This is set when gdb detects that a new | |
27346 | + objfile has been loaded. It is only set for the duration of a call | |
27347 | + to gdbpy_new_objfile; it is NULL at other times. */ | |
27348 | +static struct objfile *gdbpy_current_objfile; | |
27349 | + | |
27350 | +/* The file name we attempt to read. */ | |
27351 | +#define GDBPY_AUTO_FILENAME "-gdb.py" | |
27352 | + | |
27353 | +/* This is a new_objfile observer callback which loads python code | |
27354 | + based on the path to the objfile. */ | |
27355 | +static void | |
27356 | +gdbpy_new_objfile (struct objfile *objfile) | |
27357 | +{ | |
27358 | + char *realname; | |
27359 | + char *filename, *debugfile; | |
27360 | + int len; | |
27361 | + FILE *input; | |
27362 | + PyGILState_STATE state; | |
27363 | + struct cleanup *cleanups; | |
27364 | + | |
27365 | + if (!gdbpy_auto_load || !objfile || !objfile->name) | |
27366 | + return; | |
27367 | + | |
27368 | + state = PyGILState_Ensure (); | |
27369 | + | |
27370 | + gdbpy_current_objfile = objfile; | |
27371 | + | |
27372 | + realname = gdb_realpath (objfile->name); | |
27373 | + len = strlen (realname); | |
27374 | + filename = xmalloc (len + sizeof (GDBPY_AUTO_FILENAME)); | |
27375 | + memcpy (filename, realname, len); | |
27376 | + strcpy (filename + len, GDBPY_AUTO_FILENAME); | |
27377 | + | |
27378 | + input = fopen (filename, "r"); | |
27379 | + debugfile = filename; | |
27380 | + | |
27381 | + cleanups = make_cleanup (xfree, filename); | |
27382 | + make_cleanup (xfree, realname); | |
27383 | + | |
27384 | + if (!input && debug_file_directory) | |
27385 | + { | |
27386 | + /* Also try the same file in the separate debug info directory. */ | |
27387 | + debugfile = xmalloc (strlen (filename) | |
27388 | + + strlen (debug_file_directory) + 1); | |
27389 | + strcpy (debugfile, debug_file_directory); | |
27390 | + /* FILENAME is absolute, so we don't need a "/" here. */ | |
27391 | + strcat (debugfile, filename); | |
27392 | + | |
27393 | + make_cleanup (xfree, debugfile); | |
27394 | + input = fopen (debugfile, "r"); | |
27395 | + } | |
27396 | + | |
27397 | + if (!input && gdb_datadir) | |
27398 | + { | |
27399 | + /* Also try the same file in a subdirectory of gdb's data | |
27400 | + directory. */ | |
27401 | + debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename) | |
27402 | + + strlen ("/auto-load") + 1); | |
27403 | + strcpy (debugfile, gdb_datadir); | |
27404 | + strcat (debugfile, "/auto-load"); | |
27405 | + /* FILENAME is absolute, so we don't need a "/" here. */ | |
27406 | + strcat (debugfile, filename); | |
27407 | + | |
27408 | + make_cleanup (xfree, debugfile); | |
27409 | + input = fopen (debugfile, "r"); | |
27410 | + } | |
27411 | + | |
27412 | + if (input) | |
27413 | + { | |
27414 | + /* We don't want to throw an exception here -- but the user | |
27415 | + would like to know that something went wrong. */ | |
27416 | + if (PyRun_SimpleFile (input, debugfile)) | |
27417 | + gdbpy_print_stack (); | |
27418 | + fclose (input); | |
27419 | + } | |
27420 | + | |
27421 | + do_cleanups (cleanups); | |
27422 | + gdbpy_current_objfile = NULL; | |
27423 | + | |
27424 | + PyGILState_Release (state); | |
27425 | +} | |
27426 | + | |
27427 | +/* Return the current Objfile, or None if there isn't one. */ | |
27428 | +static PyObject * | |
27429 | +gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2) | |
27430 | +{ | |
27431 | + PyObject *result; | |
27432 | + | |
27433 | + if (! gdbpy_current_objfile) | |
27434 | + Py_RETURN_NONE; | |
27435 | + | |
27436 | + result = objfile_to_objfile_object (gdbpy_current_objfile); | |
27437 | + if (result) | |
27438 | + Py_INCREF (result); | |
27439 | + return result; | |
27440 | +} | |
27441 | + | |
27442 | +/* Return a sequence holding all the Objfiles. */ | |
27443 | +static PyObject * | |
27444 | +gdbpy_objfiles (PyObject *unused1, PyObject *unused2) | |
27445 | +{ | |
27446 | + struct objfile *objf; | |
27447 | + PyObject *list; | |
27448 | + | |
27449 | + list = PyList_New (0); | |
27450 | + if (!list) | |
27451 | + return NULL; | |
27452 | + | |
27453 | + ALL_OBJFILES (objf) | |
27454 | + { | |
27455 | + PyObject *item = objfile_to_objfile_object (objf); | |
27456 | + if (!item || PyList_Append (list, item) == -1) | |
27457 | + { | |
27458 | + Py_DECREF (list); | |
27459 | + return NULL; | |
27460 | + } | |
27461 | + } | |
27462 | + | |
27463 | + return list; | |
27464 | +} | |
27465 | + | |
27466 | +\f | |
27467 | + | |
27468 | +/* Helper function for find_pretty_printer which iterates over a | |
27469 | + list, calls each function and inspects output. */ | |
27470 | +static PyObject * | |
27471 | +search_pp_list (PyObject *list, PyObject *value) | |
27472 | +{ | |
27473 | + Py_ssize_t pp_list_size, list_index; | |
27474 | + PyObject *function, *printer = NULL; | |
27475 | + | |
27476 | + pp_list_size = PyList_Size (list); | |
27477 | + for (list_index = 0; list_index < pp_list_size; list_index++) | |
27478 | + { | |
27479 | + function = PyList_GetItem (list, list_index); | |
27480 | + if (! function) | |
27481 | + return NULL; | |
27482 | + | |
27483 | + /* gdbpy_instantiate_printer can return three possible return | |
27484 | + values: NULL on error; Py_None if the pretty-printer | |
27485 | + in the list cannot print the value; or a printer instance if | |
27486 | + the printer can print the value. */ | |
27487 | + printer = gdbpy_instantiate_printer (function, value); | |
27488 | + if (! printer) | |
27489 | + return NULL; | |
27490 | + else if (printer != Py_None) | |
27491 | + return printer; | |
27492 | + | |
27493 | + Py_DECREF (printer); | |
27494 | + } | |
27495 | + | |
27496 | + Py_RETURN_NONE; | |
27497 | +} | |
27498 | + | |
27499 | +/* Find the pretty-printing constructor function for TYPE. If no | |
27500 | + pretty-printer exists, return NULL. If one exists, return a new | |
27501 | + reference. */ | |
27502 | +static PyObject * | |
27503 | +find_pretty_printer (PyObject *value) | |
27504 | +{ | |
27505 | + PyObject *pp_list = NULL; | |
27506 | + PyObject *function = NULL; | |
27507 | + struct objfile *obj; | |
27508 | + volatile struct gdb_exception except; | |
27509 | + | |
27510 | + /* Look at the pretty-printer dictionary for each objfile. */ | |
27511 | + ALL_OBJFILES (obj) | |
27512 | + { | |
27513 | + PyObject *objf = objfile_to_objfile_object (obj); | |
27514 | + if (!objf) | |
27515 | + continue; | |
27516 | + | |
27517 | + pp_list = objfpy_get_printers (objf, NULL); | |
27518 | + function = search_pp_list (pp_list, value); | |
27519 | + | |
27520 | + /* If there is an error in any objfile list, abort the search and | |
27521 | + exit. */ | |
27522 | + if (! function) | |
27523 | + { | |
27524 | + Py_XDECREF (pp_list); | |
27525 | + return NULL; | |
27526 | + } | |
27527 | + | |
27528 | + if (function != Py_None) | |
27529 | + goto done; | |
27530 | + | |
27531 | + /* In this loop, if function is not an instantiation of a | |
27532 | + pretty-printer, and it is not null, then it is a return of | |
27533 | + Py_RETURN_NONE, which must be decremented. */ | |
27534 | + Py_DECREF (function); | |
27535 | + Py_XDECREF (pp_list); | |
27536 | + } | |
27537 | + | |
27538 | + pp_list = NULL; | |
27539 | + /* Fetch the global pretty printer dictionary. */ | |
27540 | + if (! PyObject_HasAttrString (gdb_module, "pretty_printers")) | |
27541 | + goto done; | |
27542 | + pp_list = PyObject_GetAttrString (gdb_module, "pretty_printers"); | |
27543 | + if (! pp_list) | |
27544 | + goto done; | |
27545 | + if (! PyList_Check (pp_list)) | |
27546 | + goto done; | |
27547 | + | |
27548 | + function = search_pp_list (pp_list, value); | |
27549 | + | |
27550 | + done: | |
27551 | + Py_XDECREF (pp_list); | |
27552 | + | |
27553 | + return function; | |
27554 | +} | |
27555 | + | |
27556 | +/* Pretty-print a single value, via the printer object PRINTER. If | |
27557 | + the function returns a string, an xmalloc()d copy is returned. | |
27558 | + Otherwise, if the function returns a value, a *OUT_VALUE is set to | |
27559 | + the value, and NULL is returned. On error, *OUT_VALUE is set to | |
27560 | + NULL and NULL is returned. */ | |
27561 | +static char * | |
27562 | +pretty_print_one_value (PyObject *printer, struct value **out_value) | |
27563 | +{ | |
27564 | + char *output = NULL; | |
27565 | + volatile struct gdb_exception except; | |
27566 | + | |
27567 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
27568 | + { | |
27569 | + PyObject *result; | |
27570 | + | |
27571 | + result = PyObject_CallMethodObjArgs (printer, gdbpy_to_string_cst, NULL); | |
27572 | + if (result) | |
27573 | + { | |
27574 | + if (gdbpy_is_string (result)) | |
27575 | + output = python_string_to_host_string (result); | |
27576 | + else if (PyObject_TypeCheck (result, &value_object_type)) | |
27577 | + { | |
27578 | + /* If we just call convert_value_from_python for this | |
27579 | + type, we won't know who owns the result. For this | |
27580 | + one case we need to copy the resulting value. */ | |
27581 | + struct value *v = value_object_to_value (result); | |
27582 | + *out_value = value_copy (v); | |
27583 | + } | |
27584 | + else | |
27585 | + *out_value = convert_value_from_python (result); | |
27586 | + Py_DECREF (result); | |
27587 | + } | |
27588 | + } | |
27589 | + | |
27590 | + return output; | |
27591 | +} | |
27592 | + | |
27593 | +/* Instantiate a pretty-printer given a constructor, CONS, and a | |
27594 | + value, VAL. Return NULL on error. Ownership of the object | |
27595 | + instance is transferred to the reciever */ | |
27596 | +PyObject * | |
27597 | +gdbpy_instantiate_printer (PyObject *cons, PyObject *value) | |
27598 | +{ | |
27599 | + PyObject *result; | |
27600 | + result = PyObject_CallFunctionObjArgs (cons, value, NULL); | |
27601 | + return result; | |
27602 | +} | |
27603 | + | |
27604 | +/* Return the display hint for the object printer, PRINTER. Return | |
27605 | + NULL if there is no display_hint method, or if the method did not | |
27606 | + return a string. On error, print stack trace and return NULL. On | |
27607 | + success, return an xmalloc()d string. */ | |
27608 | +char * | |
27609 | +gdbpy_get_display_hint (PyObject *printer) | |
27610 | +{ | |
27611 | + PyObject *hint; | |
27612 | + char *result = NULL; | |
27613 | + | |
27614 | + if (! PyObject_HasAttr (printer, gdbpy_display_hint_cst)) | |
27615 | + return NULL; | |
27616 | + | |
27617 | + hint = PyObject_CallMethodObjArgs (printer, gdbpy_display_hint_cst, NULL); | |
27618 | + if (gdbpy_is_string (hint)) | |
27619 | + result = python_string_to_host_string (hint); | |
27620 | + if (hint) | |
27621 | + Py_DECREF (hint); | |
27622 | + else | |
27623 | + gdbpy_print_stack (); | |
27624 | + | |
27625 | + return result; | |
27626 | +} | |
27627 | + | |
27628 | +/* Helper for apply_val_pretty_printer which calls to_string and | |
27629 | + formats the result. */ | |
27630 | +static void | |
27631 | +print_string_repr (PyObject *printer, const char *hint, | |
27632 | + struct ui_file *stream, int recurse, | |
27633 | + const struct value_print_options *options, | |
27634 | + const struct language_defn *language) | |
27635 | +{ | |
27636 | + char *output; | |
27637 | + struct value *replacement = NULL; | |
27638 | + | |
27639 | + output = pretty_print_one_value (printer, &replacement); | |
27640 | + if (output) | |
27641 | + { | |
27642 | + if (hint && !strcmp (hint, "string")) | |
27643 | + { | |
27644 | + struct type *string_char_type; | |
27645 | + | |
27646 | + /* OUTPUT is already in the hosts's charset. */ | |
27647 | + string_char_type = language_string_char_type (language, | |
27648 | + current_gdbarch); | |
27649 | + LA_PRINT_STRING (stream, string_char_type, (gdb_byte *) output, | |
27650 | + strlen (output), 0, options); | |
27651 | + } | |
27652 | + else | |
27653 | + fputs_filtered (output, stream); | |
27654 | + xfree (output); | |
27655 | + } | |
27656 | + else if (replacement) | |
27657 | + common_val_print (replacement, stream, recurse, options, language); | |
27658 | + else | |
27659 | + gdbpy_print_stack (); | |
27660 | +} | |
27661 | + | |
27662 | +static void | |
27663 | +py_restore_tstate (void *p) | |
27664 | +{ | |
27665 | + PyFrameObject *frame = p; | |
27666 | + PyThreadState *tstate = PyThreadState_GET (); | |
27667 | + tstate->frame = frame; | |
27668 | +} | |
27669 | + | |
27670 | +/* Create a dummy PyFrameObject, needed to work around | |
27671 | + a Python-2.4 bug with generators. */ | |
27672 | +static PyObject * | |
27673 | +push_dummy_python_frame () | |
27674 | +{ | |
27675 | + PyObject *empty_string, *null_tuple, *globals; | |
27676 | + PyCodeObject *code; | |
27677 | + PyFrameObject *frame; | |
27678 | + PyThreadState *tstate; | |
27679 | + | |
27680 | + empty_string = PyString_FromString (""); | |
27681 | + if (!empty_string) | |
27682 | + return NULL; | |
27683 | + | |
27684 | + null_tuple = PyTuple_New (0); | |
27685 | + if (!null_tuple) | |
27686 | + { | |
27687 | + Py_DECREF (empty_string); | |
27688 | + return NULL; | |
27689 | + } | |
27690 | + | |
27691 | + code = PyCode_New (0, /* argcount */ | |
27692 | + 0, /* nlocals */ | |
27693 | + 0, /* stacksize */ | |
27694 | + 0, /* flags */ | |
27695 | + empty_string, /* code */ | |
27696 | + null_tuple, /* consts */ | |
27697 | + null_tuple, /* names */ | |
27698 | + null_tuple, /* varnames */ | |
27699 | +#if PYTHON_API_VERSION >= 1010 | |
27700 | + null_tuple, /* freevars */ | |
27701 | + null_tuple, /* cellvars */ | |
27702 | +#endif | |
27703 | + empty_string, /* filename */ | |
27704 | + empty_string, /* name */ | |
27705 | + 1, /* firstlineno */ | |
27706 | + empty_string /* lnotab */ | |
27707 | + ); | |
27708 | + | |
27709 | + Py_DECREF (empty_string); | |
27710 | + Py_DECREF (null_tuple); | |
27711 | + | |
27712 | + if (!code) | |
27713 | + return NULL; | |
27714 | + | |
27715 | + globals = PyDict_New (); | |
27716 | + if (!globals) | |
27717 | + { | |
27718 | + Py_DECREF (code); | |
27719 | + return NULL; | |
27720 | + } | |
27721 | + | |
27722 | + tstate = PyThreadState_GET (); | |
27723 | + | |
27724 | + frame = PyFrame_New (tstate, code, globals, NULL); | |
27725 | + | |
27726 | + Py_DECREF (globals); | |
27727 | + Py_DECREF (code); | |
27728 | + | |
27729 | + if (!frame) | |
27730 | + return NULL; | |
27731 | + | |
27732 | + tstate->frame = frame; | |
27733 | + make_cleanup (py_restore_tstate, frame->f_back); | |
27734 | + return (PyObject *) frame; | |
27735 | +} | |
27736 | + | |
27737 | +/* Helper for apply_val_pretty_printer that formats children of the | |
27738 | + printer, if any exist. */ | |
27739 | +static void | |
27740 | +print_children (PyObject *printer, const char *hint, | |
27741 | + struct ui_file *stream, int recurse, | |
27742 | + const struct value_print_options *options, | |
27743 | + const struct language_defn *language) | |
27744 | +{ | |
27745 | + int is_map, is_array, done_flag, pretty; | |
27746 | + unsigned int i; | |
27747 | + PyObject *children, *iter, *frame; | |
27748 | + struct cleanup *cleanups; | |
27749 | + | |
27750 | + if (! PyObject_HasAttr (printer, gdbpy_children_cst)) | |
27751 | + return; | |
27752 | + | |
27753 | + /* If we are printing a map or an array, we want some special | |
27754 | + formatting. */ | |
27755 | + is_map = hint && ! strcmp (hint, "map"); | |
27756 | + is_array = hint && ! strcmp (hint, "array"); | |
27757 | + | |
27758 | + children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst, | |
27759 | + NULL); | |
27760 | + if (! children) | |
27761 | + { | |
27762 | + gdbpy_print_stack (); | |
27763 | + return; | |
27764 | + } | |
27765 | + | |
27766 | + cleanups = make_cleanup_py_decref (children); | |
27767 | + | |
27768 | + iter = PyObject_GetIter (children); | |
27769 | + if (!iter) | |
27770 | + { | |
27771 | + gdbpy_print_stack (); | |
27772 | + goto done; | |
27773 | + } | |
27774 | + make_cleanup_py_decref (iter); | |
27775 | + | |
27776 | + /* Use the prettyprint_arrays option if we are printing an array, | |
27777 | + and the pretty option otherwise. */ | |
27778 | + pretty = is_array ? options->prettyprint_arrays : options->pretty; | |
27779 | + | |
27780 | + /* Manufacture a dummy Python frame to work around Python 2.4 bug, | |
27781 | + where it insists on having a non-NULL tstate->frame when | |
27782 | + a generator is called. */ | |
27783 | + frame = push_dummy_python_frame (); | |
27784 | + if (!frame) | |
27785 | + { | |
27786 | + gdbpy_print_stack (); | |
27787 | + goto done; | |
27788 | + } | |
27789 | + make_cleanup_py_decref (frame); | |
27790 | + | |
27791 | + done_flag = 0; | |
27792 | + for (i = 0; i < options->print_max; ++i) | |
27793 | + { | |
27794 | + PyObject *py_v, *item = PyIter_Next (iter); | |
27795 | + char *name; | |
27796 | + struct cleanup *inner_cleanup; | |
27797 | + | |
27798 | + if (! item) | |
27799 | + { | |
27800 | + if (PyErr_Occurred ()) | |
27801 | + gdbpy_print_stack (); | |
27802 | + /* Set a flag so we can know whether we printed all the | |
27803 | + available elements. */ | |
27804 | + else | |
27805 | + done_flag = 1; | |
27806 | + break; | |
27807 | + } | |
27808 | + | |
27809 | + if (! PyArg_ParseTuple (item, "sO", &name, &py_v)) | |
27810 | + { | |
27811 | + gdbpy_print_stack (); | |
27812 | + Py_DECREF (item); | |
27813 | + continue; | |
27814 | + } | |
27815 | + inner_cleanup = make_cleanup_py_decref (item); | |
27816 | + | |
27817 | + /* Print initial "{". For other elements, there are three | |
27818 | + cases: | |
27819 | + 1. Maps. Print a "," after each value element. | |
27820 | + 2. Arrays. Always print a ",". | |
27821 | + 3. Other. Always print a ",". */ | |
27822 | + if (i == 0) | |
27823 | + fputs_filtered (" = {", stream); | |
27824 | + else if (! is_map || i % 2 == 0) | |
27825 | + fputs_filtered (pretty ? "," : ", ", stream); | |
27826 | + | |
27827 | + /* In summary mode, we just want to print "= {...}" if there is | |
27828 | + a value. */ | |
27829 | + if (options->summary) | |
27830 | + { | |
27831 | + /* This increment tricks the post-loop logic to print what | |
27832 | + we want. */ | |
27833 | + ++i; | |
27834 | + /* Likewise. */ | |
27835 | + pretty = 0; | |
27836 | + break; | |
27837 | + } | |
27838 | + | |
27839 | + if (! is_map || i % 2 == 0) | |
27840 | + { | |
27841 | + if (pretty) | |
27842 | + { | |
27843 | + fputs_filtered ("\n", stream); | |
27844 | + print_spaces_filtered (2 + 2 * recurse, stream); | |
27845 | + } | |
27846 | + else | |
27847 | + wrap_here (n_spaces (2 + 2 *recurse)); | |
27848 | + } | |
27849 | + | |
27850 | + if (is_map && i % 2 == 0) | |
27851 | + fputs_filtered ("[", stream); | |
27852 | + else if (is_array) | |
27853 | + { | |
27854 | + /* We print the index, not whatever the child method | |
27855 | + returned as the name. */ | |
27856 | + if (options->print_array_indexes) | |
27857 | + fprintf_filtered (stream, "[%d] = ", i); | |
27858 | + } | |
27859 | + else if (! is_map) | |
27860 | + { | |
27861 | + fputs_filtered (name, stream); | |
27862 | + fputs_filtered (" = ", stream); | |
27863 | + } | |
27864 | + | |
27865 | + if (gdbpy_is_string (py_v)) | |
27866 | + { | |
27867 | + char *text = python_string_to_host_string (py_v); | |
27868 | + if (! text) | |
27869 | + gdbpy_print_stack (); | |
27870 | + else | |
27871 | + { | |
27872 | + fputs_filtered (text, stream); | |
27873 | + xfree (text); | |
27874 | + } | |
27875 | + } | |
27876 | + else | |
27877 | + { | |
27878 | + struct value *value = convert_value_from_python (py_v); | |
27879 | + | |
27880 | + if (value == NULL) | |
27881 | + { | |
27882 | + gdbpy_print_stack (); | |
27883 | + error (_("Error while executing Python code.")); | |
27884 | + } | |
27885 | + else | |
27886 | + common_val_print (value, stream, recurse + 1, options, language); | |
27887 | + } | |
27888 | + | |
27889 | + if (is_map && i % 2 == 0) | |
27890 | + fputs_filtered ("] = ", stream); | |
27891 | + | |
27892 | + do_cleanups (inner_cleanup); | |
27893 | + } | |
27894 | + | |
27895 | + if (i) | |
27896 | + { | |
27897 | + if (!done_flag) | |
27898 | + { | |
27899 | + if (pretty) | |
27900 | + { | |
27901 | + fputs_filtered ("\n", stream); | |
27902 | + print_spaces_filtered (2 + 2 * recurse, stream); | |
27903 | + } | |
27904 | + fputs_filtered ("...", stream); | |
27905 | + } | |
27906 | + if (pretty) | |
27907 | + { | |
27908 | + fputs_filtered ("\n", stream); | |
27909 | + print_spaces_filtered (2 * recurse, stream); | |
27910 | + } | |
27911 | + fputs_filtered ("}", stream); | |
27912 | + } | |
27913 | + | |
27914 | + done: | |
27915 | + do_cleanups (cleanups); | |
27916 | +} | |
27917 | + | |
27918 | +int | |
27919 | +apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, | |
27920 | + int embedded_offset, CORE_ADDR address, | |
27921 | + struct ui_file *stream, int recurse, | |
27922 | + const struct value_print_options *options, | |
27923 | + const struct language_defn *language) | |
27924 | +{ | |
27925 | + PyObject *printer = NULL; | |
27926 | + PyObject *val_obj = NULL; | |
27927 | + struct value *value; | |
27928 | + char *hint = NULL; | |
27929 | + struct cleanup *cleanups; | |
27930 | + int result = 0; | |
27931 | + PyGILState_STATE state; | |
27932 | + | |
27933 | + state = PyGILState_Ensure (); | |
27934 | + cleanups = make_cleanup_py_restore_gil (&state); | |
27935 | + | |
27936 | + /* Instantiate the printer. */ | |
27937 | + if (valaddr) | |
27938 | + valaddr += embedded_offset; | |
27939 | + value = value_from_contents_and_address (type, valaddr, address); | |
27940 | + | |
27941 | + val_obj = value_to_value_object (value); | |
27942 | + if (! val_obj) | |
27943 | + goto done; | |
27944 | + | |
27945 | + /* Find the constructor. */ | |
27946 | + printer = find_pretty_printer (val_obj); | |
27947 | + Py_DECREF (val_obj); | |
27948 | + make_cleanup_py_decref (printer); | |
27949 | + if (! printer || printer == Py_None) | |
27950 | + goto done; | |
27951 | + | |
27952 | + /* If we are printing a map, we want some special formatting. */ | |
27953 | + hint = gdbpy_get_display_hint (printer); | |
27954 | + make_cleanup (free_current_contents, &hint); | |
27955 | + | |
27956 | + /* Print the section */ | |
27957 | + print_string_repr (printer, hint, stream, recurse, options, language); | |
27958 | + print_children (printer, hint, stream, recurse, options, language); | |
27959 | + result = 1; | |
27960 | + | |
27961 | + | |
27962 | + done: | |
27963 | + if (PyErr_Occurred ()) | |
27964 | + gdbpy_print_stack (); | |
27965 | + do_cleanups (cleanups); | |
27966 | + return result; | |
27967 | +} | |
27968 | + | |
27969 | +/* Apply a pretty-printer for the varobj code. PRINTER_OBJ is the | |
27970 | + print object. It must have a 'to_string' method (but this is | |
27971 | + checked by varobj, not here) which takes no arguments and | |
27972 | + returns a string. This function returns an xmalloc()d string if | |
27973 | + the printer returns a string. The printer may return a replacement | |
27974 | + value instead; in this case *REPLACEMENT is set to the replacement | |
27975 | + value, and this function returns NULL. On error, *REPLACEMENT is | |
27976 | + set to NULL and this function also returns NULL. */ | |
27977 | +char * | |
27978 | +apply_varobj_pretty_printer (PyObject *printer_obj, | |
27979 | + struct value **replacement) | |
27980 | +{ | |
27981 | + char *result; | |
27982 | + PyGILState_STATE state = PyGILState_Ensure (); | |
27983 | + | |
27984 | + *replacement = NULL; | |
27985 | + result = pretty_print_one_value (printer_obj, replacement); | |
27986 | + if (result == NULL); | |
27987 | + gdbpy_print_stack (); | |
27988 | + PyGILState_Release (state); | |
27989 | + | |
27990 | + return result; | |
27991 | +} | |
27992 | + | |
27993 | +/* Find a pretty-printer object for the varobj module. Returns a new | |
27994 | + reference to the object if successful; returns NULL if not. VALUE | |
27995 | + is the value for which a printer tests to determine if it | |
27996 | + can pretty-print the value. */ | |
27997 | +PyObject * | |
27998 | +gdbpy_get_varobj_pretty_printer (struct value *value) | |
27999 | +{ | |
28000 | + PyObject *val_obj; | |
28001 | + PyObject *pretty_printer = NULL; | |
28002 | + volatile struct gdb_exception except; | |
28003 | + | |
28004 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
28005 | + { | |
28006 | + value = value_copy (value); | |
28007 | + } | |
28008 | + GDB_PY_HANDLE_EXCEPTION (except); | |
28009 | + | |
28010 | + val_obj = value_to_value_object (value); | |
28011 | + if (! val_obj) | |
28012 | + return NULL; | |
28013 | + | |
28014 | + pretty_printer = find_pretty_printer (val_obj); | |
28015 | + Py_DECREF (val_obj); | |
28016 | + return pretty_printer; | |
28017 | +} | |
28018 | + | |
28019 | +/* A Python function which wraps find_pretty_printer and instantiates | |
28020 | + the resulting class. This accepts a Value argument and returns a | |
28021 | + pretty printer instance, or None. This function is useful as an | |
28022 | + argument to the MI command -var-set-visualizer. */ | |
28023 | +static PyObject * | |
28024 | +gdbpy_default_visualizer (PyObject *self, PyObject *args) | |
28025 | +{ | |
28026 | + PyObject *val_obj; | |
28027 | + PyObject *cons, *printer = NULL; | |
28028 | + struct value *value; | |
28029 | + | |
28030 | + if (! PyArg_ParseTuple (args, "O", &val_obj)) | |
28031 | + return NULL; | |
28032 | + value = value_object_to_value (val_obj); | |
28033 | + if (! value) | |
28034 | + { | |
28035 | + PyErr_SetString (PyExc_TypeError, "argument must be a gdb.Value"); | |
28036 | + return NULL; | |
28037 | + } | |
28038 | + | |
28039 | + cons = find_pretty_printer (val_obj); | |
28040 | + return cons; | |
28041 | +} | |
28042 | + | |
28043 | #else /* HAVE_PYTHON */ | |
28044 | ||
28045 | /* Dummy implementation of the gdb "python" command. */ | |
28046 | @@ -328,6 +1677,24 @@ eval_python_from_control_command (struct command_line *cmd) | |
28047 | error (_("Python scripting is not supported in this copy of GDB.")); | |
28048 | } | |
28049 | ||
28050 | +int | |
28051 | +apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, | |
28052 | + int embedded_offset, CORE_ADDR address, | |
28053 | + struct ui_file *stream, int format, | |
28054 | + int deref_ref, int recurse, | |
28055 | + enum val_prettyprint pretty, | |
28056 | + const struct language_defn *language) | |
28057 | +{ | |
28058 | + return 0; | |
28059 | +} | |
28060 | + | |
28061 | +void | |
28062 | +source_python_script (FILE *stream) | |
28063 | +{ | |
28064 | + fclose (stream); | |
28065 | + error (_("Python scripting is not supported in this copy of GDB.")); | |
28066 | +} | |
28067 | + | |
28068 | #endif /* HAVE_PYTHON */ | |
28069 | ||
28070 | \f | |
28071 | @@ -355,9 +1722,6 @@ show_python (char *args, int from_tty) | |
28072 | ||
28073 | /* Initialize the Python code. */ | |
28074 | ||
28075 | -/* Provide a prototype to silence -Wmissing-prototypes. */ | |
28076 | -extern initialize_file_ftype _initialize_python; | |
28077 | - | |
28078 | void | |
28079 | _initialize_python (void) | |
28080 | { | |
28081 | @@ -400,6 +1764,15 @@ Enables or disables printing of Python stack traces."), | |
28082 | &set_python_list, | |
28083 | &show_python_list); | |
28084 | ||
28085 | + add_setshow_boolean_cmd ("auto-load", class_maintenance, | |
28086 | + &gdbpy_auto_load, _("\ | |
28087 | +Enable or disable auto-loading of Python code when an object is opened."), _("\ | |
28088 | +Show whether Python code will be auto-loaded when an object is opened."), _("\ | |
28089 | +Enables or disables auto-loading of Python code when an object is opened."), | |
28090 | + NULL, NULL, | |
28091 | + &set_python_list, | |
28092 | + &show_python_list); | |
28093 | + | |
28094 | #ifdef HAVE_PYTHON | |
28095 | Py_Initialize (); | |
28096 | PyEval_InitThreads (); | |
28097 | @@ -410,11 +1783,36 @@ Enables or disables printing of Python stack traces."), | |
28098 | PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version); | |
28099 | PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", (char*) host_name); | |
28100 | PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name); | |
28101 | +#ifdef PYTHONDIR | |
28102 | + PyModule_AddStringConstant (gdb_module, "pythondir", PYTHONDIR); | |
28103 | +#else | |
28104 | + if (gdb_datadir) | |
28105 | + PyModule_AddStringConstant (gdb_module, "datadir", gdb_datadir); | |
28106 | +#endif | |
28107 | ||
28108 | gdbpy_initialize_values (); | |
28109 | + gdbpy_initialize_breakpoints (); | |
28110 | + gdbpy_initialize_frames (); | |
28111 | + gdbpy_initialize_symtabs (); | |
28112 | gdbpy_initialize_commands (); | |
28113 | + gdbpy_initialize_symbols (); | |
28114 | + gdbpy_initialize_blocks (); | |
28115 | + gdbpy_initialize_functions (); | |
28116 | + gdbpy_initialize_types (); | |
28117 | + gdbpy_initialize_parameters (); | |
28118 | + gdbpy_initialize_objfile (); | |
28119 | + gdbpy_initialize_events (); | |
28120 | + gdbpy_initialize_membuf (); | |
28121 | ||
28122 | PyRun_SimpleString ("import gdb"); | |
28123 | + PyRun_SimpleString ("gdb.pretty_printers = []"); | |
28124 | + | |
28125 | + observer_attach_new_objfile (gdbpy_new_objfile); | |
28126 | + | |
28127 | + gdbpy_to_string_cst = PyString_FromString ("to_string"); | |
28128 | + gdbpy_children_cst = PyString_FromString ("children"); | |
28129 | + gdbpy_display_hint_cst = PyString_FromString ("display_hint"); | |
28130 | + gdbpy_doc_cst = PyString_FromString ("__doc__"); | |
28131 | ||
28132 | gdbpy_doc_cst = PyString_FromString ("__doc__"); | |
28133 | ||
28134 | @@ -442,6 +1840,15 @@ class GdbOutputFile:\n\ | |
28135 | \n\ | |
28136 | sys.stderr = GdbOutputFile()\n\ | |
28137 | sys.stdout = GdbOutputFile()\n\ | |
28138 | +if hasattr (gdb, 'datadir'):\n\ | |
28139 | + gdb.pythondir = gdb.datadir + '/python'\n\ | |
28140 | +if hasattr (gdb, 'pythondir'):\n\ | |
28141 | + sys.path.insert(0, gdb.pythondir)\n\ | |
28142 | + gdb.__path__ = [gdb.pythondir + '/gdb']\n\ | |
28143 | + from os.path import exists\n\ | |
28144 | + ipy = gdb.pythondir + '/gdb/__init__.py'\n\ | |
28145 | + if exists (ipy):\n\ | |
28146 | + execfile (ipy)\n\ | |
28147 | "); | |
28148 | ||
28149 | /* Release the GIL while gdb runs. */ | |
28150 | @@ -461,9 +1868,79 @@ static PyMethodDef GdbMethods[] = | |
28151 | "Get a value from history" }, | |
28152 | { "execute", execute_gdb_command, METH_VARARGS, | |
28153 | "Execute a gdb command" }, | |
28154 | - { "get_parameter", get_parameter, METH_VARARGS, | |
28155 | + { "cli", gdbpy_cli, METH_NOARGS, | |
28156 | + "Enter the gdb CLI" }, | |
28157 | + { "parameter", gdbpy_parameter, METH_VARARGS, | |
28158 | "Return a gdb parameter's value" }, | |
28159 | ||
28160 | + { "breakpoints", gdbpy_breakpoints, METH_NOARGS, | |
28161 | + "Return a tuple of all breakpoint objects" }, | |
28162 | + | |
28163 | + { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS, | |
28164 | + "Find the default visualizer for a Value." }, | |
28165 | + | |
28166 | + { "current_objfile", gdbpy_get_current_objfile, METH_NOARGS, | |
28167 | + "Return the current Objfile being loaded, or None." }, | |
28168 | + { "objfiles", gdbpy_objfiles, METH_NOARGS, | |
28169 | + "Return a sequence of all loaded objfiles." }, | |
28170 | + | |
28171 | + { "frames", gdbpy_frames, METH_NOARGS, | |
28172 | + "frames () -> (gdb.Frame, ...).\n\ | |
28173 | +Return a tuple of all frame objects." }, | |
28174 | + { "newest_frame", gdbpy_newest_frame, METH_NOARGS, | |
28175 | + "newest_frame () -> gdb.Frame.\n\ | |
28176 | +Return the newest frame object." }, | |
28177 | + { "selected_frame", gdbpy_selected_frame, METH_NOARGS, | |
28178 | + "selected_frame () -> gdb.Frame.\n\ | |
28179 | +Return the selected frame object." }, | |
28180 | + { "frame_stop_reason_string", gdbpy_frame_stop_reason_string, METH_VARARGS, | |
28181 | + "stop_reason_string (Integer) -> String.\n\ | |
28182 | +Return a string explaining unwind stop reason." }, | |
28183 | + | |
28184 | + { "lookup_symbol", (PyCFunction) gdbpy_lookup_symbol, | |
28185 | + METH_VARARGS | METH_KEYWORDS, | |
28186 | + "lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)\n\ | |
28187 | +Return a tuple with the symbol corresponding to the given name (or None) and\n\ | |
28188 | +a boolean indicating if name is a field of the current implied argument\n\ | |
28189 | +`this' (when the current language is object-oriented)." }, | |
28190 | + { "solib_address", gdbpy_solib_address, METH_VARARGS, | |
28191 | + "solib_address (Long) -> String.\n\ | |
28192 | +Return the name of the shared library holding a given address, or None." }, | |
28193 | + | |
28194 | + { "find_pc_function", gdbpy_find_pc_function, METH_VARARGS, | |
28195 | + "Return the function containing the given pc value, or None." }, | |
28196 | + | |
28197 | + { "block_for_pc", gdbpy_block_for_pc, METH_VARARGS, | |
28198 | + "Return the block containing the given pc value, or None." }, | |
28199 | + | |
28200 | + { "decode_line", gdbpy_decode_line, METH_VARARGS, | |
28201 | + "Decode a string argument the way that 'break' or 'edit' does.\n\ | |
28202 | +Return a tuple holding the file name (or None) and line number (or None).\n\ | |
28203 | +Note: may later change to return an object." }, | |
28204 | + | |
28205 | + { "threads", gdbpy_threads, METH_NOARGS, | |
28206 | + "Return a tuple holding all the valid thread IDs." }, | |
28207 | + { "current_thread", gdbpy_current_thread, METH_NOARGS, | |
28208 | + "Return the thread ID of the current thread." }, | |
28209 | + { "switch_to_thread", gdbpy_switch_to_thread, METH_VARARGS, | |
28210 | + "Switch to a thread, given the thread ID." }, | |
28211 | + | |
28212 | + { "parse_and_eval", gdbpy_parse_and_eval, METH_VARARGS, | |
28213 | + "Parse a string as an expression, evaluate it, and return the result." }, | |
28214 | + | |
28215 | + { "post_event", gdbpy_post_event, METH_VARARGS, | |
28216 | + "Post an event into gdb's event loop." }, | |
28217 | + | |
28218 | + { "read_memory", gdbpy_read_memory, METH_VARARGS, | |
28219 | + "read_memory (address, length) -> buffer\n\ | |
28220 | +Return a buffer object for reading from the inferior's memory." }, | |
28221 | + { "write_memory", gdbpy_write_memory, METH_VARARGS, | |
28222 | + "write_memory (address, buffer [, length])\n\ | |
28223 | +Write the given buffer object to the inferior's memory." }, | |
28224 | + { "search_memory", (PyCFunction) gdbpy_search_memory, METH_VARARGS | METH_KEYWORDS, | |
28225 | + "search_memory (address, length, pattern [, size] [, max_count]) -> list\n\ | |
28226 | +Return a list with the addresses where matches were found." }, | |
28227 | + | |
28228 | { "write", gdbpy_write, METH_VARARGS, | |
28229 | "Write a string using gdb's filtered stream." }, | |
28230 | { "flush", gdbpy_flush, METH_NOARGS, | |
28231 | diff --git a/gdb/python/python.h b/gdb/python/python.h | |
28232 | index e63c447..767af86 100644 | |
28233 | --- a/gdb/python/python.h | |
28234 | +++ b/gdb/python/python.h | |
28235 | @@ -26,4 +26,14 @@ extern struct value *values_in_python; | |
28236 | ||
28237 | void eval_python_from_control_command (struct command_line *); | |
28238 | ||
28239 | +void source_python_script (FILE *stream, char *file); | |
28240 | + | |
28241 | +void run_python_script (int argc, char **argv); | |
28242 | + | |
28243 | +int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, | |
28244 | + int embedded_offset, CORE_ADDR address, | |
28245 | + struct ui_file *stream, int recurse, | |
28246 | + const struct value_print_options *options, | |
28247 | + const struct language_defn *language); | |
28248 | + | |
28249 | #endif /* GDB_PYTHON_H */ | |
28250 | diff --git a/gdb/scm-lang.c b/gdb/scm-lang.c | |
28251 | index 345befd..e2568c8 100644 | |
28252 | --- a/gdb/scm-lang.c | |
28253 | +++ b/gdb/scm-lang.c | |
28254 | @@ -43,14 +43,14 @@ static int in_eval_c (void); | |
28255 | struct type *builtin_type_scm; | |
28256 | ||
28257 | void | |
28258 | -scm_printchar (int c, struct ui_file *stream) | |
28259 | +scm_printchar (int c, struct type *type, struct ui_file *stream) | |
28260 | { | |
28261 | fprintf_filtered (stream, "#\\%c", c); | |
28262 | } | |
28263 | ||
28264 | static void | |
28265 | -scm_printstr (struct ui_file *stream, const gdb_byte *string, | |
28266 | - unsigned int length, int width, int force_ellipses, | |
28267 | +scm_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, | |
28268 | + unsigned int length, int force_ellipses, | |
28269 | const struct value_print_options *options) | |
28270 | { | |
28271 | fprintf_filtered (stream, "\"%s\"", string); | |
28272 | diff --git a/gdb/scm-lang.h b/gdb/scm-lang.h | |
28273 | index 6bf88f5..1798b2f 100644 | |
28274 | --- a/gdb/scm-lang.h | |
28275 | +++ b/gdb/scm-lang.h | |
28276 | @@ -59,7 +59,7 @@ extern void scm_scmval_print (LONGEST, struct ui_file *, int, | |
28277 | ||
28278 | extern int is_scmvalue_type (struct type *); | |
28279 | ||
28280 | -extern void scm_printchar (int, struct ui_file *); | |
28281 | +extern void scm_printchar (int, struct type *, struct ui_file *); | |
28282 | ||
28283 | extern struct value *scm_evaluate_string (char *, int); | |
28284 | ||
28285 | diff --git a/gdb/scm-valprint.c b/gdb/scm-valprint.c | |
28286 | index f0a7642..a32add5 100644 | |
28287 | --- a/gdb/scm-valprint.c | |
28288 | +++ b/gdb/scm-valprint.c | |
28289 | @@ -187,7 +187,8 @@ taloop: | |
28290 | if (SCM_ICHRP (svalue)) | |
28291 | { | |
28292 | svalue = SCM_ICHR (svalue); | |
28293 | - scm_printchar (svalue, stream); | |
28294 | + scm_printchar (svalue, builtin_type (current_gdbarch)->builtin_char, | |
28295 | + stream); | |
28296 | break; | |
28297 | } | |
28298 | else if (SCM_IFLAGP (svalue) | |
28299 | diff --git a/gdb/stabsread.c b/gdb/stabsread.c | |
28300 | index 2d7eb15..7423b32 100644 | |
28301 | --- a/gdb/stabsread.c | |
28302 | +++ b/gdb/stabsread.c | |
28303 | @@ -322,7 +322,7 @@ dbx_alloc_type (int typenums[2], struct objfile *objfile) | |
28304 | ||
28305 | if (typenums[0] == -1) | |
28306 | { | |
28307 | - return (alloc_type (objfile)); | |
28308 | + return (alloc_type (objfile, NULL)); | |
28309 | } | |
28310 | ||
28311 | type_addr = dbx_lookup_type (typenums); | |
28312 | @@ -332,7 +332,7 @@ dbx_alloc_type (int typenums[2], struct objfile *objfile) | |
28313 | We will fill it in later if we find out how. */ | |
28314 | if (*type_addr == 0) | |
28315 | { | |
28316 | - *type_addr = alloc_type (objfile); | |
28317 | + *type_addr = alloc_type (objfile, NULL); | |
28318 | } | |
28319 | ||
28320 | return (*type_addr); | |
28321 | @@ -589,6 +589,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, | |
28322 | int deftype; | |
28323 | int synonym = 0; | |
28324 | int i; | |
28325 | + char *new_name = NULL; | |
28326 | ||
28327 | /* We would like to eliminate nameless symbols, but keep their types. | |
28328 | E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer | |
28329 | @@ -683,9 +684,37 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type, | |
28330 | { | |
28331 | normal: | |
28332 | SYMBOL_LANGUAGE (sym) = current_subfile->language; | |
28333 | - SYMBOL_SET_NAMES (sym, string, p - string, objfile); | |
28334 | + if (current_subfile->language == language_cplus) | |
28335 | + { | |
28336 | + char *name = alloca (p - string + 1); | |
28337 | + memcpy (name, string, p - string); | |
28338 | + name[p - string] = '\0'; | |
28339 | + new_name = cp_canonicalize_string (name); | |
28340 | + } | |
28341 | + | |
28342 | + if (new_name != NULL) | |
28343 | + { | |
28344 | + SYMBOL_SET_NAMES (sym, new_name, strlen (new_name), objfile); | |
28345 | + xfree (new_name); | |
28346 | + } | |
28347 | + else | |
28348 | + SYMBOL_SET_NAMES (sym, string, p - string, objfile); | |
28349 | + | |
28350 | if (SYMBOL_LANGUAGE (sym) == language_cplus) | |
28351 | - cp_scan_for_anonymous_namespaces (sym); | |
28352 | + { | |
28353 | + char *name = alloca (p - string + 1); | |
28354 | + memcpy (name, string, p - string); | |
28355 | + name[p - string] = '\0'; | |
28356 | + new_name = cp_canonicalize_string (name); | |
28357 | + cp_scan_for_anonymous_namespaces (sym); | |
28358 | + } | |
28359 | + if (new_name != NULL) | |
28360 | + { | |
28361 | + SYMBOL_SET_NAMES (sym, new_name, strlen (new_name), objfile); | |
28362 | + xfree (new_name); | |
28363 | + } | |
28364 | + else | |
28365 | + SYMBOL_SET_NAMES (sym, string, p - string, objfile); | |
28366 | } | |
28367 | p++; | |
28368 | ||
28369 | @@ -1519,18 +1548,35 @@ again: | |
28370 | if (*p != ':') | |
28371 | return error_type (pp, objfile); | |
28372 | } | |
28373 | - to = type_name = | |
28374 | - (char *) obstack_alloc (&objfile->objfile_obstack, p - *pp + 1); | |
28375 | - | |
28376 | - /* Copy the name. */ | |
28377 | - from = *pp + 1; | |
28378 | - while (from < p) | |
28379 | - *to++ = *from++; | |
28380 | - *to = '\0'; | |
28381 | + type_name = NULL; | |
28382 | + if (current_subfile->language == language_cplus) | |
28383 | + { | |
28384 | + char *new_name, *name = alloca (p - *pp + 1); | |
28385 | + memcpy (name, *pp, p - *pp); | |
28386 | + name[p - *pp] = '\0'; | |
28387 | + new_name = cp_canonicalize_string (name); | |
28388 | + if (new_name != NULL) | |
28389 | + { | |
28390 | + type_name = obsavestring (new_name, strlen (new_name), | |
28391 | + &objfile->objfile_obstack); | |
28392 | + xfree (new_name); | |
28393 | + } | |
28394 | + } | |
28395 | + if (type_name == NULL) | |
28396 | + { | |
28397 | + to = type_name = | |
28398 | + (char *) obstack_alloc (&objfile->objfile_obstack, p - *pp + 1); | |
28399 | + | |
28400 | + /* Copy the name. */ | |
28401 | + from = *pp + 1; | |
28402 | + while (from < p) | |
28403 | + *to++ = *from++; | |
28404 | + *to = '\0'; | |
28405 | + } | |
28406 | ||
28407 | /* Set the pointer ahead of the name which we just read, and | |
28408 | the colon. */ | |
28409 | - *pp = from + 1; | |
28410 | + *pp = p + 1; | |
28411 | } | |
28412 | ||
28413 | /* If this type has already been declared, then reuse the same | |
28414 | diff --git a/gdb/stack.c b/gdb/stack.c | |
28415 | index 3bcf758..fa7fc61 100644 | |
28416 | --- a/gdb/stack.c | |
28417 | +++ b/gdb/stack.c | |
28418 | @@ -380,6 +380,7 @@ print_frame_args (struct symbol *func, struct frame_info *frame, | |
28419 | ||
28420 | get_raw_print_options (&opts); | |
28421 | opts.deref_ref = 0; | |
28422 | + opts.summary = 1; | |
28423 | common_val_print (val, stb->stream, 2, | |
28424 | &opts, language); | |
28425 | ui_out_field_stream (uiout, "value", stb); | |
28426 | @@ -579,20 +580,16 @@ print_frame_info (struct frame_info *frame, int print_level, | |
28427 | gdb_flush (gdb_stdout); | |
28428 | } | |
28429 | ||
28430 | -static void | |
28431 | -print_frame (struct frame_info *frame, int print_level, | |
28432 | - enum print_what print_what, int print_args, | |
28433 | - struct symtab_and_line sal) | |
28434 | +/* Attempt to obtain the FUNNAME and FUNLANG of the function corresponding | |
28435 | + to FRAME. */ | |
28436 | +void | |
28437 | +find_frame_funname (struct frame_info *frame, char **funname, | |
28438 | + enum language *funlang) | |
28439 | { | |
28440 | struct symbol *func; | |
28441 | - char *funname = NULL; | |
28442 | - enum language funlang = language_unknown; | |
28443 | - struct ui_stream *stb; | |
28444 | - struct cleanup *old_chain, *list_chain; | |
28445 | - struct value_print_options opts; | |
28446 | ||
28447 | - stb = ui_out_stream_new (uiout); | |
28448 | - old_chain = make_cleanup_ui_out_stream_delete (stb); | |
28449 | + *funname = NULL; | |
28450 | + *funlang = language_unknown; | |
28451 | ||
28452 | func = find_pc_function (get_frame_address_in_block (frame)); | |
28453 | if (func) | |
28454 | @@ -625,24 +622,24 @@ print_frame (struct frame_info *frame, int print_level, | |
28455 | /* We also don't know anything about the function besides | |
28456 | its address and name. */ | |
28457 | func = 0; | |
28458 | - funname = SYMBOL_PRINT_NAME (msymbol); | |
28459 | - funlang = SYMBOL_LANGUAGE (msymbol); | |
28460 | + *funname = SYMBOL_PRINT_NAME (msymbol); | |
28461 | + *funlang = SYMBOL_LANGUAGE (msymbol); | |
28462 | } | |
28463 | else | |
28464 | { | |
28465 | - funname = SYMBOL_PRINT_NAME (func); | |
28466 | - funlang = SYMBOL_LANGUAGE (func); | |
28467 | - if (funlang == language_cplus) | |
28468 | + *funname = SYMBOL_PRINT_NAME (func); | |
28469 | + *funlang = SYMBOL_LANGUAGE (func); | |
28470 | + if (*funlang == language_cplus) | |
28471 | { | |
28472 | /* It seems appropriate to use SYMBOL_PRINT_NAME() here, | |
28473 | to display the demangled name that we already have | |
28474 | stored in the symbol table, but we stored a version | |
28475 | with DMGL_PARAMS turned on, and here we don't want to | |
28476 | display parameters. So remove the parameters. */ | |
28477 | - char *func_only = cp_remove_params (funname); | |
28478 | + char *func_only = cp_remove_params (*funname); | |
28479 | if (func_only) | |
28480 | { | |
28481 | - funname = func_only; | |
28482 | + *funname = func_only; | |
28483 | make_cleanup (xfree, func_only); | |
28484 | } | |
28485 | } | |
28486 | @@ -655,10 +652,27 @@ print_frame (struct frame_info *frame, int print_level, | |
28487 | ||
28488 | if (msymbol != NULL) | |
28489 | { | |
28490 | - funname = SYMBOL_PRINT_NAME (msymbol); | |
28491 | - funlang = SYMBOL_LANGUAGE (msymbol); | |
28492 | + *funname = SYMBOL_PRINT_NAME (msymbol); | |
28493 | + *funlang = SYMBOL_LANGUAGE (msymbol); | |
28494 | } | |
28495 | } | |
28496 | +} | |
28497 | + | |
28498 | +static void | |
28499 | +print_frame (struct frame_info *frame, int print_level, | |
28500 | + enum print_what print_what, int print_args, | |
28501 | + struct symtab_and_line sal) | |
28502 | +{ | |
28503 | + char *funname = NULL; | |
28504 | + enum language funlang = language_unknown; | |
28505 | + struct ui_stream *stb; | |
28506 | + struct cleanup *old_chain, *list_chain; | |
28507 | + struct value_print_options opts; | |
28508 | + | |
28509 | + stb = ui_out_stream_new (uiout); | |
28510 | + old_chain = make_cleanup_ui_out_stream_delete (stb); | |
28511 | + | |
28512 | + find_frame_funname (frame, &funname, &funlang); | |
28513 | ||
28514 | annotate_frame_begin (print_level ? frame_relative_level (frame) : 0, | |
28515 | get_frame_pc (frame)); | |
28516 | @@ -694,7 +708,7 @@ print_frame (struct frame_info *frame, int print_level, | |
28517 | struct print_args_args args; | |
28518 | struct cleanup *args_list_chain; | |
28519 | args.frame = frame; | |
28520 | - args.func = func; | |
28521 | + args.func = find_pc_function (get_frame_address_in_block (frame)); | |
28522 | args.stream = gdb_stdout; | |
28523 | args_list_chain = make_cleanup_ui_out_list_begin_end (uiout, "args"); | |
28524 | catch_errors (print_args_stub, &args, "", RETURN_MASK_ERROR); | |
28525 | @@ -1208,24 +1222,24 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty) | |
28526 | else | |
28527 | count = -1; | |
28528 | ||
28529 | - if (info_verbose) | |
28530 | - { | |
28531 | - struct partial_symtab *ps; | |
28532 | - | |
28533 | - /* Read in symbols for all of the frames. Need to do this in a | |
28534 | - separate pass so that "Reading in symbols for xxx" messages | |
28535 | - don't screw up the appearance of the backtrace. Also if | |
28536 | - people have strong opinions against reading symbols for | |
28537 | - backtrace this may have to be an option. */ | |
28538 | - i = count; | |
28539 | - for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi)) | |
28540 | - { | |
28541 | - QUIT; | |
28542 | - ps = find_pc_psymtab (get_frame_address_in_block (fi)); | |
28543 | - if (ps) | |
28544 | - PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in. */ | |
28545 | - } | |
28546 | - } | |
28547 | + { | |
28548 | + struct partial_symtab *ps; | |
28549 | + | |
28550 | + /* Read in symbols for all of the frames. Need to do this | |
28551 | + unconditionally to ensure that psymbols are read. Also need to | |
28552 | + do this in a separate pass so that "Reading in symbols for xxx" | |
28553 | + messages don't screw up the appearance of the backtrace. Also | |
28554 | + if people have strong opinions against reading symbols for | |
28555 | + backtrace this may have to be an option. */ | |
28556 | + i = count; | |
28557 | + for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi)) | |
28558 | + { | |
28559 | + QUIT; | |
28560 | + ps = find_pc_psymtab (get_frame_address_in_block (fi)); | |
28561 | + if (info_verbose && ps) | |
28562 | + PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in. */ | |
28563 | + } | |
28564 | + } | |
28565 | ||
28566 | for (i = 0, fi = trailing; fi && count--; i++, fi = get_prev_frame (fi)) | |
28567 | { | |
28568 | @@ -1373,6 +1387,8 @@ print_block_frame_locals (struct block *b, struct frame_info *frame, | |
28569 | case LOC_COMPUTED: | |
28570 | if (SYMBOL_IS_ARGUMENT (sym)) | |
28571 | break; | |
28572 | + if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN) | |
28573 | + break; | |
28574 | values_printed = 1; | |
28575 | print_variable_and_value (NULL, sym, frame, stream, 4 * num_tabs); | |
28576 | break; | |
28577 | @@ -1777,7 +1793,75 @@ down_command (char *count_exp, int from_tty) | |
28578 | down_silently_base (count_exp); | |
28579 | print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); | |
28580 | } | |
28581 | -\f | |
28582 | + | |
28583 | +/* Verify whether if RETURN_VALUE width gets extended to EXT_TYPE it will still | |
28584 | + be the same value after reading it back using the RETURN_VALUE type. */ | |
28585 | + | |
28586 | +static int | |
28587 | +return_extended_value_cast (struct value *return_value, struct type *ext_type) | |
28588 | +{ | |
28589 | + struct regcache *current_regcache = get_current_regcache (); | |
28590 | + struct gdbarch *gdbarch = get_regcache_arch (current_regcache); | |
28591 | + struct type *return_type = value_type (return_value); | |
28592 | + struct value *ext_value, *compare_value; | |
28593 | + | |
28594 | + if (gdbarch_return_value (gdbarch, NULL, ext_type, NULL, NULL, NULL) | |
28595 | + != RETURN_VALUE_REGISTER_CONVENTION) | |
28596 | + return 0; | |
28597 | + | |
28598 | + ext_value = value_cast (ext_type, return_value); | |
28599 | + gdbarch_return_value (gdbarch, NULL, ext_type, | |
28600 | + current_regcache, NULL /*read*/, | |
28601 | + value_contents (ext_value) /*write*/); | |
28602 | + | |
28603 | + compare_value = allocate_value (return_type); | |
28604 | + gdbarch_return_value (gdbarch, NULL, return_type, current_regcache, | |
28605 | + value_contents_raw (compare_value) /*read*/, | |
28606 | + NULL /*write*/); | |
28607 | + | |
28608 | + return value_equal (return_value, compare_value); | |
28609 | +} | |
28610 | + | |
28611 | +/* Set RETURN_VALUE extended to the largest type width which will still be the | |
28612 | + same value after reading it back using the RETURN_VALUE type. */ | |
28613 | + | |
28614 | +static void | |
28615 | +return_extended_value (struct value *return_value) | |
28616 | +{ | |
28617 | + struct type *return_type = value_type (return_value); | |
28618 | + struct regcache *current_regcache = get_current_regcache (); | |
28619 | + struct gdbarch *gdbarch = get_regcache_arch (current_regcache); | |
28620 | + const struct builtin_type *builtins = builtin_type (gdbarch); | |
28621 | + struct type **extp, *ext_tab[] = | |
28622 | + { | |
28623 | + builtins->builtin_long_long, | |
28624 | + builtins->builtin_long, | |
28625 | + return_type | |
28626 | + }; | |
28627 | + unsigned width_tried = 0; | |
28628 | + | |
28629 | + for (extp = ext_tab; extp < ext_tab + ARRAY_SIZE (ext_tab); extp++) | |
28630 | + { | |
28631 | + struct type *ext_type = *extp; | |
28632 | + | |
28633 | + /* Do not retry extension to the integer of an already tried width. */ | |
28634 | + if (ext_type != return_type && width_tried == TYPE_LENGTH (ext_type)) | |
28635 | + continue; | |
28636 | + | |
28637 | + /* Do not extend to non-original smaller (or the same size) type. */ | |
28638 | + if (ext_type != return_type | |
28639 | + && TYPE_LENGTH (ext_type) <= TYPE_LENGTH (return_type)) | |
28640 | + continue; | |
28641 | + | |
28642 | + gdb_assert (TYPE_LENGTH (return_type) <= TYPE_LENGTH (ext_type)); | |
28643 | + width_tried = TYPE_LENGTH (ext_type); | |
28644 | + if (return_extended_value_cast (return_value, ext_type)) | |
28645 | + break; | |
28646 | + } | |
28647 | + | |
28648 | + /* Ensure at least the attempt with original RETURN_TYPE was successful. */ | |
28649 | + gdb_assert (extp < ext_tab + ARRAY_SIZE (ext_tab)); | |
28650 | +} | |
28651 | ||
28652 | void | |
28653 | return_command (char *retval_exp, int from_tty) | |
28654 | @@ -1806,6 +1890,8 @@ return_command (char *retval_exp, int from_tty) | |
28655 | the cast fail, this call throws an error. */ | |
28656 | if (thisfun != NULL) | |
28657 | return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); | |
28658 | + else | |
28659 | + return_type = value_type (return_value); | |
28660 | if (return_type == NULL) | |
28661 | return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; | |
28662 | CHECK_TYPEDEF (return_type); | |
28663 | @@ -1862,9 +1948,13 @@ If you continue, the return value that you specified will be ignored.\n"; | |
28664 | gdb_assert (gdbarch_return_value (gdbarch, func_type, return_type, NULL, | |
28665 | NULL, NULL) | |
28666 | == RETURN_VALUE_REGISTER_CONVENTION); | |
28667 | - gdbarch_return_value (gdbarch, func_type, return_type, | |
28668 | - get_current_regcache (), NULL /*read*/, | |
28669 | - value_contents (return_value) /*write*/); | |
28670 | + | |
28671 | + if (thisfun != NULL) | |
28672 | + gdbarch_return_value (gdbarch, func_type, return_type, | |
28673 | + get_current_regcache (), NULL /*read*/, | |
28674 | + value_contents (return_value) /*write*/); | |
28675 | + else | |
28676 | + return_extended_value (return_value); | |
28677 | } | |
28678 | ||
28679 | /* If we are at the end of a call dummy now, pop the dummy frame | |
28680 | diff --git a/gdb/stack.h b/gdb/stack.h | |
28681 | index 973a57f..56b1d91 100644 | |
28682 | --- a/gdb/stack.h | |
28683 | +++ b/gdb/stack.h | |
28684 | @@ -22,4 +22,9 @@ | |
28685 | ||
28686 | void select_frame_command (char *level_exp, int from_tty); | |
28687 | ||
28688 | +/* Attempt to obtain the FUNNAME and FUNLANG of the function corresponding | |
28689 | + to FRAME. */ | |
28690 | +void find_frame_funname (struct frame_info *frame, char **funname, | |
28691 | + enum language *funlang); | |
28692 | + | |
28693 | #endif /* #ifndef STACK_H */ | |
28694 | diff --git a/gdb/symfile.c b/gdb/symfile.c | |
28695 | index 63b5c1d..b047e94 100644 | |
28696 | --- a/gdb/symfile.c | |
28697 | +++ b/gdb/symfile.c | |
28698 | @@ -929,6 +929,17 @@ new_symfile_objfile (struct objfile *objfile, int mainline, int verbo) | |
28699 | clear_complaints (&symfile_complaints, 0, verbo); | |
28700 | } | |
28701 | ||
28702 | +/* A helper function which returns true if OBJFILE has any debug | |
28703 | + symbols, and false otherwise. */ | |
28704 | +static int | |
28705 | +has_any_debug_symbols (struct objfile *objfile) | |
28706 | +{ | |
28707 | + return (objfile->psymtabs || objfile->quick_addrmap | |
28708 | + || (objfile->separate_debug_objfile | |
28709 | + && (objfile->separate_debug_objfile->psymtabs | |
28710 | + || objfile->separate_debug_objfile->quick_addrmap))); | |
28711 | +} | |
28712 | + | |
28713 | /* Process a symbol file, as either the main file or as a dynamically | |
28714 | loaded file. | |
28715 | ||
28716 | @@ -965,13 +976,15 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty, | |
28717 | /* Give user a chance to burp if we'd be | |
28718 | interactively wiping out any existing symbols. */ | |
28719 | ||
28720 | - if ((have_full_symbols () || have_partial_symbols ()) | |
28721 | - && mainline | |
28722 | + if (mainline | |
28723 | && from_tty | |
28724 | + && (have_full_symbols () || have_partial_symbols ()) | |
28725 | && !query (_("Load new symbol table from \"%s\"? "), name)) | |
28726 | error (_("Not confirmed.")); | |
28727 | ||
28728 | objfile = allocate_objfile (abfd, flags); | |
28729 | + if (mainline) | |
28730 | + objfile->flags |= OBJF_MAIN; | |
28731 | discard_cleanups (my_cleanups); | |
28732 | ||
28733 | if (addrs) | |
28734 | @@ -1007,6 +1020,8 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty, | |
28735 | ||
28736 | if ((flags & OBJF_READNOW) || readnow_symbol_files) | |
28737 | { | |
28738 | + require_partial_symbols (objfile); | |
28739 | + | |
28740 | if ((from_tty || info_verbose) && print_symbol_loading) | |
28741 | { | |
28742 | printf_unfiltered (_("expanding to full symbols...")); | |
28743 | @@ -1025,7 +1040,7 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty, | |
28744 | /* If the file has its own symbol tables it has no separate debug info. | |
28745 | `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to SYMTABS/PSYMTABS. | |
28746 | `.gnu_debuglink' may no longer be present with `.note.gnu.build-id'. */ | |
28747 | - if (objfile->psymtabs == NULL) | |
28748 | + if (!has_any_debug_symbols (objfile)) | |
28749 | debugfile = find_separate_debug_file (objfile); | |
28750 | if (debugfile) | |
28751 | { | |
28752 | @@ -1049,8 +1064,10 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty, | |
28753 | xfree (debugfile); | |
28754 | } | |
28755 | ||
28756 | - if (!have_partial_symbols () && !have_full_symbols () | |
28757 | - && print_symbol_loading) | |
28758 | + /* has_any_debug_symbols is not fully compatible with the former calls which | |
28759 | + would just be needlessly expensive here. */ | |
28760 | + if ((from_tty || info_verbose) && print_symbol_loading | |
28761 | + && !has_any_debug_symbols (objfile) && mainline) | |
28762 | { | |
28763 | wrap_here (""); | |
28764 | printf_unfiltered (_("(no debugging symbols found)")); | |
28765 | @@ -2423,13 +2440,15 @@ reread_symbols (void) | |
28766 | zero is OK since dbxread.c also does what it needs to do if | |
28767 | objfile->global_psymbols.size is 0. */ | |
28768 | (*objfile->sf->sym_read) (objfile, 0); | |
28769 | - if (!have_partial_symbols () && !have_full_symbols ()) | |
28770 | + if (!has_any_debug_symbols (objfile)) | |
28771 | { | |
28772 | wrap_here (""); | |
28773 | printf_unfiltered (_("(no debugging symbols found)\n")); | |
28774 | wrap_here (""); | |
28775 | } | |
28776 | ||
28777 | + objfile->flags &= ~OBJF_SYMTABS_READ; | |
28778 | + | |
28779 | /* We're done reading the symbol file; finish off complaints. */ | |
28780 | clear_complaints (&symfile_complaints, 0, 1); | |
28781 | ||
28782 | @@ -2726,7 +2745,7 @@ allocate_symtab (char *filename, struct objfile *objfile) | |
28783 | } | |
28784 | ||
28785 | struct partial_symtab * | |
28786 | -allocate_psymtab (char *filename, struct objfile *objfile) | |
28787 | +allocate_psymtab (const char *filename, struct objfile *objfile) | |
28788 | { | |
28789 | struct partial_symtab *psymtab; | |
28790 | ||
28791 | @@ -3040,7 +3059,8 @@ again2: | |
28792 | ||
28793 | struct partial_symtab * | |
28794 | start_psymtab_common (struct objfile *objfile, | |
28795 | - struct section_offsets *section_offsets, char *filename, | |
28796 | + struct section_offsets *section_offsets, | |
28797 | + const char *filename, | |
28798 | CORE_ADDR textlow, struct partial_symbol **global_syms, | |
28799 | struct partial_symbol **static_syms) | |
28800 | { | |
28801 | diff --git a/gdb/symfile.h b/gdb/symfile.h | |
28802 | index 88f8326..50671c1 100644 | |
28803 | --- a/gdb/symfile.h | |
28804 | +++ b/gdb/symfile.h | |
28805 | @@ -140,6 +140,12 @@ struct sym_fns | |
28806 | ||
28807 | void (*sym_read) (struct objfile *, int); | |
28808 | ||
28809 | + /* Read the partial symbols for an objfile. This may be NULL, in | |
28810 | + which case gdb assumes that sym_read already read the partial | |
28811 | + symbols. */ | |
28812 | + | |
28813 | + void (*sym_read_psymbols) (struct objfile *); | |
28814 | + | |
28815 | /* Called when we are finished with an objfile. Should do all | |
28816 | cleanup that is specific to the object file format for the | |
28817 | particular objfile. */ | |
28818 | @@ -250,7 +256,7 @@ extern void free_section_addr_info (struct section_addr_info *); | |
28819 | ||
28820 | extern struct partial_symtab *start_psymtab_common (struct objfile *, | |
28821 | struct section_offsets *, | |
28822 | - char *, CORE_ADDR, | |
28823 | + const char *, CORE_ADDR, | |
28824 | struct partial_symbol **, | |
28825 | struct partial_symbol **); | |
28826 | ||
28827 | @@ -300,7 +306,7 @@ extern int auto_solib_limit; | |
28828 | ||
28829 | extern void set_initial_language (void); | |
28830 | ||
28831 | -extern struct partial_symtab *allocate_psymtab (char *, struct objfile *); | |
28832 | +extern struct partial_symtab *allocate_psymtab (const char *, struct objfile *); | |
28833 | ||
28834 | extern void discard_psymtab (struct partial_symtab *); | |
28835 | ||
28836 | @@ -369,7 +375,7 @@ void free_symfile_segment_data (struct symfile_segment_data *data); | |
28837 | /* From dwarf2read.c */ | |
28838 | ||
28839 | extern int dwarf2_has_info (struct objfile *); | |
28840 | - | |
28841 | +extern void dwarf2_create_quick_addrmap (struct objfile *); | |
28842 | extern void dwarf2_build_psymtabs (struct objfile *, int); | |
28843 | extern void dwarf2_build_frame_info (struct objfile *); | |
28844 | ||
28845 | diff --git a/gdb/symtab.c b/gdb/symtab.c | |
28846 | index d2ba1f3..593cded 100644 | |
28847 | --- a/gdb/symtab.c | |
28848 | +++ b/gdb/symtab.c | |
28849 | @@ -42,6 +42,7 @@ | |
28850 | #include "ada-lang.h" | |
28851 | #include "p-lang.h" | |
28852 | #include "addrmap.h" | |
28853 | +#include "cp-support.h" | |
28854 | ||
28855 | #include "hashtab.h" | |
28856 | ||
28857 | @@ -55,6 +56,7 @@ | |
28858 | #include "gdb_stat.h" | |
28859 | #include <ctype.h> | |
28860 | #include "cp-abi.h" | |
28861 | +#include "cp-support.h" | |
28862 | #include "observer.h" | |
28863 | #include "gdb_assert.h" | |
28864 | #include "solist.h" | |
28865 | @@ -273,7 +275,7 @@ lookup_partial_symtab (const char *name) | |
28866 | make_cleanup (xfree, real_path); | |
28867 | } | |
28868 | ||
28869 | - ALL_PSYMTABS (objfile, pst) | |
28870 | + ALL_PSYMTABS_REQUIRED (objfile, pst) | |
28871 | { | |
28872 | if (FILENAME_CMP (name, pst->filename) == 0) | |
28873 | { | |
28874 | @@ -870,7 +872,13 @@ find_pc_sect_psymtab (CORE_ADDR pc, struct obj_section *section) | |
28875 | than the later used TEXTLOW/TEXTHIGH one. */ | |
28876 | ||
28877 | ALL_OBJFILES (objfile) | |
28878 | - if (objfile->psymtabs_addrmap != NULL) | |
28879 | + { | |
28880 | + if (objfile->quick_addrmap) | |
28881 | + { | |
28882 | + if (!addrmap_find (objfile->quick_addrmap, pc)) | |
28883 | + continue; | |
28884 | + } | |
28885 | + if (require_partial_symbols (objfile)->psymtabs_addrmap != NULL) | |
28886 | { | |
28887 | struct partial_symtab *pst; | |
28888 | ||
28889 | @@ -903,6 +911,7 @@ find_pc_sect_psymtab (CORE_ADDR pc, struct obj_section *section) | |
28890 | return pst; | |
28891 | } | |
28892 | } | |
28893 | + } | |
28894 | ||
28895 | /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs | |
28896 | which still have no corresponding full SYMTABs read. But it is not | |
28897 | @@ -1170,6 +1179,22 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile) | |
28898 | return psym; | |
28899 | } | |
28900 | ||
28901 | +/* Ensure that the partial symbols for OBJFILE have been loaded. This | |
28902 | + function always returns its argument, as a convenience. */ | |
28903 | + | |
28904 | +struct objfile * | |
28905 | +require_partial_symbols (struct objfile *objfile) | |
28906 | +{ | |
28907 | + if ((objfile->flags & OBJF_SYMTABS_READ) == 0) | |
28908 | + { | |
28909 | + objfile->flags |= OBJF_SYMTABS_READ; | |
28910 | + | |
28911 | + if (objfile->sf->sym_read_psymbols) | |
28912 | + (*objfile->sf->sym_read_psymbols) (objfile); | |
28913 | + } | |
28914 | + return objfile; | |
28915 | +} | |
28916 | + | |
28917 | /* Find the definition for a specified symbol name NAME | |
28918 | in domain DOMAIN, visible from lexical block BLOCK. | |
28919 | Returns the struct symbol pointer, or zero if no symbol is found. | |
28920 | @@ -1200,6 +1225,11 @@ lookup_symbol_in_language (const char *name, const struct block *block, | |
28921 | int needtofreename = 0; | |
28922 | struct symbol *returnval; | |
28923 | ||
28924 | + if(strncmp(name, "::", 2) == 0){/* this must be a global name */ | |
28925 | + name = name+2; | |
28926 | + block = NULL; | |
28927 | + } | |
28928 | + | |
28929 | modified_name = name; | |
28930 | ||
28931 | /* If we are using C++ or Java, demangle the name before doing a lookup, so | |
28932 | @@ -1213,6 +1243,17 @@ lookup_symbol_in_language (const char *name, const struct block *block, | |
28933 | modified_name = demangled_name; | |
28934 | needtofreename = 1; | |
28935 | } | |
28936 | + else | |
28937 | + { | |
28938 | + /* If we were given a non-mangled name, canonicalize it | |
28939 | + according to the language (so far only for C++). */ | |
28940 | + demangled_name = cp_canonicalize_string (name); | |
28941 | + if (demangled_name) | |
28942 | + { | |
28943 | + modified_name = demangled_name; | |
28944 | + needtofreename = 1; | |
28945 | + } | |
28946 | + } | |
28947 | } | |
28948 | else if (lang == language_java) | |
28949 | { | |
28950 | @@ -1361,22 +1402,23 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name, | |
28951 | const domain_enum domain) | |
28952 | { | |
28953 | struct symbol *sym; | |
28954 | - const struct block *static_block = block_static_block (block); | |
28955 | + const struct block *global_block = block_global_block (block); | |
28956 | ||
28957 | /* Check if either no block is specified or it's a global block. */ | |
28958 | ||
28959 | - if (static_block == NULL) | |
28960 | + if (global_block == NULL) | |
28961 | return NULL; | |
28962 | ||
28963 | - while (block != static_block) | |
28964 | + while (block != global_block) | |
28965 | { | |
28966 | sym = lookup_symbol_aux_block (name, linkage_name, block, domain); | |
28967 | if (sym != NULL) | |
28968 | return sym; | |
28969 | + | |
28970 | block = BLOCK_SUPERBLOCK (block); | |
28971 | } | |
28972 | ||
28973 | - /* We've reached the static block without finding a result. */ | |
28974 | + /* We've reached the global block without finding a result. */ | |
28975 | ||
28976 | return NULL; | |
28977 | } | |
28978 | @@ -1450,6 +1492,7 @@ lookup_global_symbol_from_objfile (const struct objfile *objfile, | |
28979 | } | |
28980 | ||
28981 | /* Now go through psymtabs. */ | |
28982 | + require_partial_symbols ((struct objfile *) objfile); | |
28983 | ALL_OBJFILE_PSYMTABS (objfile, ps) | |
28984 | { | |
28985 | if (!ps->readin | |
28986 | @@ -1520,7 +1563,7 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name, | |
28987 | struct symtab *s; | |
28988 | const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0); | |
28989 | ||
28990 | - ALL_PSYMTABS (objfile, ps) | |
28991 | + ALL_PSYMTABS_REQUIRED (objfile, ps) | |
28992 | { | |
28993 | if (!ps->readin | |
28994 | && lookup_partial_symbol (ps, name, linkage_name, | |
28995 | @@ -1805,7 +1848,11 @@ basic_lookup_transparent_type (const char *name) | |
28996 | } | |
28997 | } | |
28998 | ||
28999 | - ALL_PSYMTABS (objfile, ps) | |
29000 | + /* FIXME: .debug_pubnames should be read in. | |
29001 | + | |
29002 | + One may also try to the first pass without the require_partial_symbols | |
29003 | + call but that would behave nondeterministically. */ | |
29004 | + ALL_PSYMTABS_REQUIRED (objfile, ps) | |
29005 | { | |
29006 | if (!ps->readin && lookup_partial_symbol (ps, name, NULL, | |
29007 | 1, STRUCT_DOMAIN)) | |
29008 | @@ -1853,7 +1900,12 @@ basic_lookup_transparent_type (const char *name) | |
29009 | } | |
29010 | } | |
29011 | ||
29012 | - ALL_PSYMTABS (objfile, ps) | |
29013 | + /* FIXME: Something like .debug_pubnames containing also static symbols | |
29014 | + should be read in. Compiler needs to be taught to generate it first. | |
29015 | + | |
29016 | + One may also try to the first pass without the require_partial_symbols | |
29017 | + call but that would behave nondeterministically. */ | |
29018 | + ALL_PSYMTABS_REQUIRED (objfile, ps) | |
29019 | { | |
29020 | if (!ps->readin && lookup_partial_symbol (ps, name, NULL, 0, STRUCT_DOMAIN)) | |
29021 | { | |
29022 | @@ -1894,7 +1946,21 @@ find_main_psymtab (void) | |
29023 | struct partial_symtab *pst; | |
29024 | struct objfile *objfile; | |
29025 | ||
29026 | - ALL_PSYMTABS (objfile, pst) | |
29027 | + ALL_OBJFILES (objfile) | |
29028 | + { | |
29029 | + if ((objfile->flags & OBJF_MAIN) == 0) | |
29030 | + continue; | |
29031 | + require_partial_symbols (objfile); | |
29032 | + ALL_OBJFILE_PSYMTABS (objfile, pst) | |
29033 | + { | |
29034 | + if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN)) | |
29035 | + { | |
29036 | + return pst; | |
29037 | + } | |
29038 | + } | |
29039 | + } | |
29040 | + | |
29041 | + ALL_PSYMTABS_REQUIRED (objfile, pst) | |
29042 | { | |
29043 | if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN)) | |
29044 | { | |
29045 | @@ -3085,7 +3151,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[], | |
29046 | matching the regexp. That way we don't have to reproduce all of | |
29047 | the machinery below. */ | |
29048 | ||
29049 | - ALL_PSYMTABS (objfile, ps) | |
29050 | + ALL_PSYMTABS_REQUIRED (objfile, ps) | |
29051 | { | |
29052 | struct partial_symbol **bound, **gbound, **sbound; | |
29053 | int keep_going = 1; | |
29054 | diff --git a/gdb/symtab.h b/gdb/symtab.h | |
29055 | index 8b086f3..06bf7e8 100644 | |
29056 | --- a/gdb/symtab.h | |
29057 | +++ b/gdb/symtab.h | |
29058 | @@ -171,9 +171,6 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *); | |
29059 | #define SYMBOL_SECTION(symbol) (symbol)->ginfo.section | |
29060 | #define SYMBOL_OBJ_SECTION(symbol) (symbol)->ginfo.obj_section | |
29061 | ||
29062 | -#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol) \ | |
29063 | - (symbol)->ginfo.language_specific.cplus_specific.demangled_name | |
29064 | - | |
29065 | /* Initializes the language dependent portion of a symbol | |
29066 | depending upon the language for the symbol. */ | |
29067 | #define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \ | |
29068 | @@ -394,7 +391,10 @@ typedef enum domain_enum_tag | |
29069 | FUNCTIONS_DOMAIN, | |
29070 | ||
29071 | /* All defined types */ | |
29072 | - TYPES_DOMAIN | |
29073 | + TYPES_DOMAIN, | |
29074 | + | |
29075 | + /* Fortran common blocks. Their naming must be separate from VAR_DOMAIN. */ | |
29076 | + COMMON_BLOCK_DOMAIN | |
29077 | } | |
29078 | domain_enum; | |
29079 | ||
29080 | @@ -1027,6 +1027,8 @@ extern void clear_pc_function_cache (void); | |
29081 | ||
29082 | /* from symtab.c: */ | |
29083 | ||
29084 | +struct objfile *require_partial_symbols (struct objfile *); | |
29085 | + | |
29086 | /* lookup partial symbol table by filename */ | |
29087 | ||
29088 | extern struct partial_symtab *lookup_partial_symtab (const char *); | |
29089 | diff --git a/gdb/syscalls/gdb-syscalls.dtd b/gdb/syscalls/gdb-syscalls.dtd | |
29090 | new file mode 100644 | |
29091 | index 0000000..0d40ab4 | |
29092 | --- /dev/null | |
29093 | +++ b/gdb/syscalls/gdb-syscalls.dtd | |
29094 | @@ -0,0 +1,21 @@ | |
29095 | +<!-- Copyright (C) 2007, 2008 Free Software Foundation, Inc. | |
29096 | + | |
29097 | + Copying and distribution of this file, with or without modification, | |
29098 | + are permitted in any medium without royalty provided the copyright | |
29099 | + notice and this notice are preserved. --> | |
29100 | + | |
29101 | +<!-- The root element of a syscall info is <syscalls_info>. --> | |
29102 | + | |
29103 | +<!ELEMENT syscalls_info (syscall*)> | |
29104 | + | |
29105 | +<!-- Maybe the 'number' attribute will have to be changed from | |
29106 | + ID to CDATA. --> | |
29107 | +<!ELEMENT syscall EMPTY> | |
29108 | +<!ATTLIST syscall | |
29109 | + name CDATA #REQUIRED | |
29110 | + number ID #REQUIRED> | |
29111 | + | |
29112 | +<!ELEMENT xi:include (EMPTY)> | |
29113 | +<!ATTLIST xi:include | |
29114 | + xmlns:xi CDATA #FIXED "http://www.w3.org/2001/XInclude" | |
29115 | + href CDATA #REQUIRED> | |
29116 | diff --git a/gdb/syscalls/i386-linux.xml b/gdb/syscalls/i386-linux.xml | |
29117 | new file mode 100644 | |
29118 | index 0000000..6f2beee | |
29119 | --- /dev/null | |
29120 | +++ b/gdb/syscalls/i386-linux.xml | |
29121 | @@ -0,0 +1,334 @@ | |
29122 | +<?xml version="1.0"?> | |
29123 | +<!-- Copyright (C) 2007, 2008 Free Software Foundation, Inc. | |
29124 | + | |
29125 | + Copying and distribution of this file, with or without modification, | |
29126 | + are permitted in any medium without royalty provided the copyright | |
29127 | + notice and this notice are preserved. --> | |
29128 | + | |
29129 | +<!DOCTYPE feature SYSTEM "gdb-syscalls.dtd"> | |
29130 | + | |
29131 | +<syscalls_info> | |
29132 | + <syscall name="restart_syscall" number="0"/> | |
29133 | + <syscall name="exit" number="1"/> | |
29134 | + <syscall name="fork" number="2"/> | |
29135 | + <syscall name="read" number="3"/> | |
29136 | + <syscall name="write" number="4"/> | |
29137 | + <syscall name="open" number="5"/> | |
29138 | + <syscall name="close" number="6"/> | |
29139 | + <syscall name="waitpid" number="7"/> | |
29140 | + <syscall name="creat" number="8"/> | |
29141 | + <syscall name="link" number="9"/> | |
29142 | + <syscall name="unlink" number="10"/> | |
29143 | + <syscall name="execve" number="11"/> | |
29144 | + <syscall name="chdir" number="12"/> | |
29145 | + <syscall name="time" number="13"/> | |
29146 | + <syscall name="mknod" number="14"/> | |
29147 | + <syscall name="chmod" number="15"/> | |
29148 | + <syscall name="lchown" number="16"/> | |
29149 | + <syscall name="break" number="17"/> | |
29150 | + <syscall name="oldstat" number="18"/> | |
29151 | + <syscall name="lseek" number="19"/> | |
29152 | + <syscall name="getpid" number="20"/> | |
29153 | + <syscall name="mount" number="21"/> | |
29154 | + <syscall name="umount" number="22"/> | |
29155 | + <syscall name="setuid" number="23"/> | |
29156 | + <syscall name="getuid" number="24"/> | |
29157 | + <syscall name="stime" number="25"/> | |
29158 | + <syscall name="ptrace" number="26"/> | |
29159 | + <syscall name="alarm" number="27"/> | |
29160 | + <syscall name="oldfstat" number="28"/> | |
29161 | + <syscall name="pause" number="29"/> | |
29162 | + <syscall name="utime" number="30"/> | |
29163 | + <syscall name="stty" number="31"/> | |
29164 | + <syscall name="gtty" number="32"/> | |
29165 | + <syscall name="access" number="33"/> | |
29166 | + <syscall name="nice" number="34"/> | |
29167 | + <syscall name="ftime" number="35"/> | |
29168 | + <syscall name="sync" number="36"/> | |
29169 | + <syscall name="kill" number="37"/> | |
29170 | + <syscall name="rename" number="38"/> | |
29171 | + <syscall name="mkdir" number="39"/> | |
29172 | + <syscall name="rmdir" number="40"/> | |
29173 | + <syscall name="dup" number="41"/> | |
29174 | + <syscall name="pipe" number="42"/> | |
29175 | + <syscall name="times" number="43"/> | |
29176 | + <syscall name="prof" number="44"/> | |
29177 | + <syscall name="brk" number="45"/> | |
29178 | + <syscall name="setgid" number="46"/> | |
29179 | + <syscall name="getgid" number="47"/> | |
29180 | + <syscall name="signal" number="48"/> | |
29181 | + <syscall name="geteuid" number="49"/> | |
29182 | + <syscall name="getegid" number="50"/> | |
29183 | + <syscall name="acct" number="51"/> | |
29184 | + <syscall name="umount2" number="52"/> | |
29185 | + <syscall name="lock" number="53"/> | |
29186 | + <syscall name="ioctl" number="54"/> | |
29187 | + <syscall name="fcntl" number="55"/> | |
29188 | + <syscall name="mpx" number="56"/> | |
29189 | + <syscall name="setpgid" number="57"/> | |
29190 | + <syscall name="ulimit" number="58"/> | |
29191 | + <syscall name="oldolduname" number="59"/> | |
29192 | + <syscall name="umask" number="60"/> | |
29193 | + <syscall name="chroot" number="61"/> | |
29194 | + <syscall name="ustat" number="62"/> | |
29195 | + <syscall name="dup2" number="63"/> | |
29196 | + <syscall name="getppid" number="64"/> | |
29197 | + <syscall name="getpgrp" number="65"/> | |
29198 | + <syscall name="setsid" number="66"/> | |
29199 | + <syscall name="sigaction" number="67"/> | |
29200 | + <syscall name="sgetmask" number="68"/> | |
29201 | + <syscall name="ssetmask" number="69"/> | |
29202 | + <syscall name="setreuid" number="70"/> | |
29203 | + <syscall name="setregid" number="71"/> | |
29204 | + <syscall name="sigsuspend" number="72"/> | |
29205 | + <syscall name="sigpending" number="73"/> | |
29206 | + <syscall name="sethostname" number="74"/> | |
29207 | + <syscall name="setrlimit" number="75"/> | |
29208 | + <syscall name="getrlimit" number="76"/> | |
29209 | + <syscall name="getrusage" number="77"/> | |
29210 | + <syscall name="gettimeofday" number="78"/> | |
29211 | + <syscall name="settimeofday" number="79"/> | |
29212 | + <syscall name="getgroups" number="80"/> | |
29213 | + <syscall name="setgroups" number="81"/> | |
29214 | + <syscall name="select" number="82"/> | |
29215 | + <syscall name="symlink" number="83"/> | |
29216 | + <syscall name="oldlstat" number="84"/> | |
29217 | + <syscall name="readlink" number="85"/> | |
29218 | + <syscall name="uselib" number="86"/> | |
29219 | + <syscall name="swapon" number="87"/> | |
29220 | + <syscall name="reboot" number="88"/> | |
29221 | + <syscall name="readdir" number="89"/> | |
29222 | + <syscall name="mmap" number="90"/> | |
29223 | + <syscall name="munmap" number="91"/> | |
29224 | + <syscall name="truncate" number="92"/> | |
29225 | + <syscall name="ftruncate" number="93"/> | |
29226 | + <syscall name="fchmod" number="94"/> | |
29227 | + <syscall name="fchown" number="95"/> | |
29228 | + <syscall name="getpriority" number="96"/> | |
29229 | + <syscall name="setpriority" number="97"/> | |
29230 | + <syscall name="profil" number="98"/> | |
29231 | + <syscall name="statfs" number="99"/> | |
29232 | + <syscall name="fstatfs" number="100"/> | |
29233 | + <syscall name="ioperm" number="101"/> | |
29234 | + <syscall name="socketcall" number="102"/> | |
29235 | + <syscall name="syslog" number="103"/> | |
29236 | + <syscall name="setitimer" number="104"/> | |
29237 | + <syscall name="getitimer" number="105"/> | |
29238 | + <syscall name="stat" number="106"/> | |
29239 | + <syscall name="lstat" number="107"/> | |
29240 | + <syscall name="fstat" number="108"/> | |
29241 | + <syscall name="olduname" number="109"/> | |
29242 | + <syscall name="iopl" number="110"/> | |
29243 | + <syscall name="vhangup" number="111"/> | |
29244 | + <syscall name="idle" number="112"/> | |
29245 | + <syscall name="vm86old" number="113"/> | |
29246 | + <syscall name="wait4" number="114"/> | |
29247 | + <syscall name="swapoff" number="115"/> | |
29248 | + <syscall name="sysinfo" number="116"/> | |
29249 | + <syscall name="ipc" number="117"/> | |
29250 | + <syscall name="fsync" number="118"/> | |
29251 | + <syscall name="sigreturn" number="119"/> | |
29252 | + <syscall name="clone" number="120"/> | |
29253 | + <syscall name="setdomainname" number="121"/> | |
29254 | + <syscall name="uname" number="122"/> | |
29255 | + <syscall name="modify_ldt" number="123"/> | |
29256 | + <syscall name="adjtimex" number="124"/> | |
29257 | + <syscall name="mprotect" number="125"/> | |
29258 | + <syscall name="sigprocmask" number="126"/> | |
29259 | + <syscall name="create_module" number="127"/> | |
29260 | + <syscall name="init_module" number="128"/> | |
29261 | + <syscall name="delete_module" number="129"/> | |
29262 | + <syscall name="get_kernel_syms" number="130"/> | |
29263 | + <syscall name="quotactl" number="131"/> | |
29264 | + <syscall name="getpgid" number="132"/> | |
29265 | + <syscall name="fchdir" number="133"/> | |
29266 | + <syscall name="bdflush" number="134"/> | |
29267 | + <syscall name="sysfs" number="135"/> | |
29268 | + <syscall name="personality" number="136"/> | |
29269 | + <syscall name="afs_syscall" number="137"/> | |
29270 | + <syscall name="setfsuid" number="138"/> | |
29271 | + <syscall name="setfsgid" number="139"/> | |
29272 | + <syscall name="_llseek" number="140"/> | |
29273 | + <syscall name="getdents" number="141"/> | |
29274 | + <syscall name="_newselect" number="142"/> | |
29275 | + <syscall name="flock" number="143"/> | |
29276 | + <syscall name="msync" number="144"/> | |
29277 | + <syscall name="readv" number="145"/> | |
29278 | + <syscall name="writev" number="146"/> | |
29279 | + <syscall name="getsid" number="147"/> | |
29280 | + <syscall name="fdatasync" number="148"/> | |
29281 | + <syscall name="_sysctl" number="149"/> | |
29282 | + <syscall name="mlock" number="150"/> | |
29283 | + <syscall name="munlock" number="151"/> | |
29284 | + <syscall name="mlockall" number="152"/> | |
29285 | + <syscall name="munlockall" number="153"/> | |
29286 | + <syscall name="sched_setparam" number="154"/> | |
29287 | + <syscall name="sched_getparam" number="155"/> | |
29288 | + <syscall name="sched_setscheduler" number="156"/> | |
29289 | + <syscall name="sched_getscheduler" number="157"/> | |
29290 | + <syscall name="sched_yield" number="158"/> | |
29291 | + <syscall name="sched_get_priority_max" number="159"/> | |
29292 | + <syscall name="sched_get_priority_min" number="160"/> | |
29293 | + <syscall name="sched_rr_get_interval" number="161"/> | |
29294 | + <syscall name="nanosleep" number="162"/> | |
29295 | + <syscall name="mremap" number="163"/> | |
29296 | + <syscall name="setresuid" number="164"/> | |
29297 | + <syscall name="getresuid" number="165"/> | |
29298 | + <syscall name="vm86" number="166"/> | |
29299 | + <syscall name="query_module" number="167"/> | |
29300 | + <syscall name="poll" number="168"/> | |
29301 | + <syscall name="nfsservctl" number="169"/> | |
29302 | + <syscall name="setresgid" number="170"/> | |
29303 | + <syscall name="getresgid" number="171"/> | |
29304 | + <syscall name="prctl" number="172"/> | |
29305 | + <syscall name="rt_sigreturn" number="173"/> | |
29306 | + <syscall name="rt_sigaction" number="174"/> | |
29307 | + <syscall name="rt_sigprocmask" number="175"/> | |
29308 | + <syscall name="rt_sigpending" number="176"/> | |
29309 | + <syscall name="rt_sigtimedwait" number="177"/> | |
29310 | + <syscall name="rt_sigqueueinfo" number="178"/> | |
29311 | + <syscall name="rt_sigsuspend" number="179"/> | |
29312 | + <syscall name="pread64" number="180"/> | |
29313 | + <syscall name="pwrite64" number="181"/> | |
29314 | + <syscall name="chown" number="182"/> | |
29315 | + <syscall name="getcwd" number="183"/> | |
29316 | + <syscall name="capget" number="184"/> | |
29317 | + <syscall name="capset" number="185"/> | |
29318 | + <syscall name="sigaltstack" number="186"/> | |
29319 | + <syscall name="sendfile" number="187"/> | |
29320 | + <syscall name="getpmsg" number="188"/> | |
29321 | + <syscall name="putpmsg" number="189"/> | |
29322 | + <syscall name="vfork" number="190"/> | |
29323 | + <syscall name="ugetrlimit" number="191"/> | |
29324 | + <syscall name="mmap2" number="192"/> | |
29325 | + <syscall name="truncate64" number="193"/> | |
29326 | + <syscall name="ftruncate64" number="194"/> | |
29327 | + <syscall name="stat64" number="195"/> | |
29328 | + <syscall name="lstat64" number="196"/> | |
29329 | + <syscall name="fstat64" number="197"/> | |
29330 | + <syscall name="lchown32" number="198"/> | |
29331 | + <syscall name="getuid32" number="199"/> | |
29332 | + <syscall name="getgid32" number="200"/> | |
29333 | + <syscall name="geteuid32" number="201"/> | |
29334 | + <syscall name="getegid32" number="202"/> | |
29335 | + <syscall name="setreuid32" number="203"/> | |
29336 | + <syscall name="setregid32" number="204"/> | |
29337 | + <syscall name="getgroups32" number="205"/> | |
29338 | + <syscall name="setgroups32" number="206"/> | |
29339 | + <syscall name="fchown32" number="207"/> | |
29340 | + <syscall name="setresuid32" number="208"/> | |
29341 | + <syscall name="getresuid32" number="209"/> | |
29342 | + <syscall name="setresgid32" number="210"/> | |
29343 | + <syscall name="getresgid32" number="211"/> | |
29344 | + <syscall name="chown32" number="212"/> | |
29345 | + <syscall name="setuid32" number="213"/> | |
29346 | + <syscall name="setgid32" number="214"/> | |
29347 | + <syscall name="setfsuid32" number="215"/> | |
29348 | + <syscall name="setfsgid32" number="216"/> | |
29349 | + <syscall name="pivot_root" number="217"/> | |
29350 | + <syscall name="mincore" number="218"/> | |
29351 | + <syscall name="madvise" number="219"/> | |
29352 | + <syscall name="madvise1" number="220"/> | |
29353 | + <syscall name="getdents64" number="221"/> | |
29354 | + <syscall name="fcntl64" number="222"/> | |
29355 | + <syscall name="gettid" number="224"/> | |
29356 | + <syscall name="readahead" number="225"/> | |
29357 | + <syscall name="setxattr" number="226"/> | |
29358 | + <syscall name="lsetxattr" number="227"/> | |
29359 | + <syscall name="fsetxattr" number="228"/> | |
29360 | + <syscall name="getxattr" number="229"/> | |
29361 | + <syscall name="lgetxattr" number="230"/> | |
29362 | + <syscall name="fgetxattr" number="231"/> | |
29363 | + <syscall name="listxattr" number="232"/> | |
29364 | + <syscall name="llistxattr" number="233"/> | |
29365 | + <syscall name="flistxattr" number="234"/> | |
29366 | + <syscall name="removexattr" number="235"/> | |
29367 | + <syscall name="lremovexattr" number="236"/> | |
29368 | + <syscall name="fremovexattr" number="237"/> | |
29369 | + <syscall name="tkill" number="238"/> | |
29370 | + <syscall name="sendfile64" number="239"/> | |
29371 | + <syscall name="futex" number="240"/> | |
29372 | + <syscall name="sched_setaffinity" number="241"/> | |
29373 | + <syscall name="sched_getaffinity" number="242"/> | |
29374 | + <syscall name="set_thread_area" number="243"/> | |
29375 | + <syscall name="get_thread_area" number="244"/> | |
29376 | + <syscall name="io_setup" number="245"/> | |
29377 | + <syscall name="io_destroy" number="246"/> | |
29378 | + <syscall name="io_getevents" number="247"/> | |
29379 | + <syscall name="io_submit" number="248"/> | |
29380 | + <syscall name="io_cancel" number="249"/> | |
29381 | + <syscall name="fadvise64" number="250"/> | |
29382 | + <syscall name="exit_group" number="252"/> | |
29383 | + <syscall name="lookup_dcookie" number="253"/> | |
29384 | + <syscall name="epoll_create" number="254"/> | |
29385 | + <syscall name="epoll_ctl" number="255"/> | |
29386 | + <syscall name="epoll_wait" number="256"/> | |
29387 | + <syscall name="remap_file_pages" number="257"/> | |
29388 | + <syscall name="set_tid_address" number="258"/> | |
29389 | + <syscall name="timer_create" number="259"/> | |
29390 | + <syscall name="timer_settime" number="260"/> | |
29391 | + <syscall name="timer_gettime" number="261"/> | |
29392 | + <syscall name="timer_getoverrun" number="262"/> | |
29393 | + <syscall name="timer_delete" number="263"/> | |
29394 | + <syscall name="clock_settime" number="264"/> | |
29395 | + <syscall name="clock_gettime" number="265"/> | |
29396 | + <syscall name="clock_getres" number="266"/> | |
29397 | + <syscall name="clock_nanosleep" number="267"/> | |
29398 | + <syscall name="statfs64" number="268"/> | |
29399 | + <syscall name="fstatfs64" number="269"/> | |
29400 | + <syscall name="tgkill" number="270"/> | |
29401 | + <syscall name="utimes" number="271"/> | |
29402 | + <syscall name="fadvise64_64" number="272"/> | |
29403 | + <syscall name="vserver" number="273"/> | |
29404 | + <syscall name="mbind" number="274"/> | |
29405 | + <syscall name="get_mempolicy" number="275"/> | |
29406 | + <syscall name="set_mempolicy" number="276"/> | |
29407 | + <syscall name="mq_open" number="277"/> | |
29408 | + <syscall name="mq_unlink" number="278"/> | |
29409 | + <syscall name="mq_timedsend" number="279"/> | |
29410 | + <syscall name="mq_timedreceive" number="280"/> | |
29411 | + <syscall name="mq_notify" number="281"/> | |
29412 | + <syscall name="mq_getsetattr" number="282"/> | |
29413 | + <syscall name="kexec_load" number="283"/> | |
29414 | + <syscall name="waitid" number="284"/> | |
29415 | + <syscall name="add_key" number="286"/> | |
29416 | + <syscall name="request_key" number="287"/> | |
29417 | + <syscall name="keyctl" number="288"/> | |
29418 | + <syscall name="ioprio_set" number="289"/> | |
29419 | + <syscall name="ioprio_get" number="290"/> | |
29420 | + <syscall name="inotify_init" number="291"/> | |
29421 | + <syscall name="inotify_add_watch" number="292"/> | |
29422 | + <syscall name="inotify_rm_watch" number="293"/> | |
29423 | + <syscall name="migrate_pages" number="294"/> | |
29424 | + <syscall name="openat" number="295"/> | |
29425 | + <syscall name="mkdirat" number="296"/> | |
29426 | + <syscall name="mknodat" number="297"/> | |
29427 | + <syscall name="fchownat" number="298"/> | |
29428 | + <syscall name="futimesat" number="299"/> | |
29429 | + <syscall name="fstatat64" number="300"/> | |
29430 | + <syscall name="unlinkat" number="301"/> | |
29431 | + <syscall name="renameat" number="302"/> | |
29432 | + <syscall name="linkat" number="303"/> | |
29433 | + <syscall name="symlinkat" number="304"/> | |
29434 | + <syscall name="readlinkat" number="305"/> | |
29435 | + <syscall name="fchmodat" number="306"/> | |
29436 | + <syscall name="faccessat" number="307"/> | |
29437 | + <syscall name="pselect6" number="308"/> | |
29438 | + <syscall name="ppoll" number="309"/> | |
29439 | + <syscall name="unshare" number="310"/> | |
29440 | + <syscall name="set_robust_list" number="311"/> | |
29441 | + <syscall name="get_robust_list" number="312"/> | |
29442 | + <syscall name="splice" number="313"/> | |
29443 | + <syscall name="sync_file_range" number="314"/> | |
29444 | + <syscall name="tee" number="315"/> | |
29445 | + <syscall name="vmsplice" number="316"/> | |
29446 | + <syscall name="move_pages" number="317"/> | |
29447 | + <syscall name="getcpu" number="318"/> | |
29448 | + <syscall name="epoll_pwait" number="319"/> | |
29449 | + <syscall name="utimensat" number="320"/> | |
29450 | + <syscall name="signalfd" number="321"/> | |
29451 | + <syscall name="timerfd_create" number="322"/> | |
29452 | + <syscall name="eventfd" number="323"/> | |
29453 | + <syscall name="fallocate" number="324"/> | |
29454 | + <syscall name="timerfd_settime" number="325"/> | |
29455 | +</syscalls_info> | |
29456 | diff --git a/gdb/syscalls/ppc-linux.xml b/gdb/syscalls/ppc-linux.xml | |
29457 | new file mode 100644 | |
29458 | index 0000000..f09fabd | |
29459 | --- /dev/null | |
29460 | +++ b/gdb/syscalls/ppc-linux.xml | |
29461 | @@ -0,0 +1,304 @@ | |
29462 | +<?xml version="1.0"?> | |
29463 | +<!-- Copyright (C) 2007, 2008 Free Software Foundation, Inc. | |
29464 | + | |
29465 | + Copying and distribution of this file, with or without modification, | |
29466 | + are permitted in any medium without royalty provided the copyright | |
29467 | + notice and this notice are preserved. --> | |
29468 | + | |
29469 | +<!DOCTYPE feature SYSTEM "gdb-syscalls.dtd"> | |
29470 | + | |
29471 | +<syscalls_info> | |
29472 | + <syscall name="restart_syscall" number="0"/> | |
29473 | + <syscall name="exit" number="1"/> | |
29474 | + <syscall name="fork" number="2"/> | |
29475 | + <syscall name="read" number="3"/> | |
29476 | + <syscall name="write" number="4"/> | |
29477 | + <syscall name="open" number="5"/> | |
29478 | + <syscall name="close" number="6"/> | |
29479 | + <syscall name="waitpid" number="7"/> | |
29480 | + <syscall name="creat" number="8"/> | |
29481 | + <syscall name="link" number="9"/> | |
29482 | + <syscall name="unlink" number="10"/> | |
29483 | + <syscall name="execve" number="11"/> | |
29484 | + <syscall name="chdir" number="12"/> | |
29485 | + <syscall name="time" number="13"/> | |
29486 | + <syscall name="mknod" number="14"/> | |
29487 | + <syscall name="chmod" number="15"/> | |
29488 | + <syscall name="lchown" number="16"/> | |
29489 | + <syscall name="break" number="17"/> | |
29490 | + <syscall name="oldstat" number="18"/> | |
29491 | + <syscall name="lseek" number="19"/> | |
29492 | + <syscall name="getpid" number="20"/> | |
29493 | + <syscall name="mount" number="21"/> | |
29494 | + <syscall name="umount" number="22"/> | |
29495 | + <syscall name="setuid" number="23"/> | |
29496 | + <syscall name="getuid" number="24"/> | |
29497 | + <syscall name="stime" number="25"/> | |
29498 | + <syscall name="ptrace" number="26"/> | |
29499 | + <syscall name="alarm" number="27"/> | |
29500 | + <syscall name="oldfstat" number="28"/> | |
29501 | + <syscall name="pause" number="29"/> | |
29502 | + <syscall name="utime" number="30"/> | |
29503 | + <syscall name="stty" number="31"/> | |
29504 | + <syscall name="gtty" number="32"/> | |
29505 | + <syscall name="access" number="33"/> | |
29506 | + <syscall name="nice" number="34"/> | |
29507 | + <syscall name="ftime" number="35"/> | |
29508 | + <syscall name="sync" number="36"/> | |
29509 | + <syscall name="kill" number="37"/> | |
29510 | + <syscall name="rename" number="38"/> | |
29511 | + <syscall name="mkdir" number="39"/> | |
29512 | + <syscall name="rmdir" number="40"/> | |
29513 | + <syscall name="dup" number="41"/> | |
29514 | + <syscall name="pipe" number="42"/> | |
29515 | + <syscall name="times" number="43"/> | |
29516 | + <syscall name="prof" number="44"/> | |
29517 | + <syscall name="brk" number="45"/> | |
29518 | + <syscall name="setgid" number="46"/> | |
29519 | + <syscall name="getgid" number="47"/> | |
29520 | + <syscall name="signal" number="48"/> | |
29521 | + <syscall name="geteuid" number="49"/> | |
29522 | + <syscall name="getegid" number="50"/> | |
29523 | + <syscall name="acct" number="51"/> | |
29524 | + <syscall name="umount2" number="52"/> | |
29525 | + <syscall name="lock" number="53"/> | |
29526 | + <syscall name="ioctl" number="54"/> | |
29527 | + <syscall name="fcntl" number="55"/> | |
29528 | + <syscall name="mpx" number="56"/> | |
29529 | + <syscall name="setpgid" number="57"/> | |
29530 | + <syscall name="ulimit" number="58"/> | |
29531 | + <syscall name="oldolduname" number="59"/> | |
29532 | + <syscall name="umask" number="60"/> | |
29533 | + <syscall name="chroot" number="61"/> | |
29534 | + <syscall name="ustat" number="62"/> | |
29535 | + <syscall name="dup2" number="63"/> | |
29536 | + <syscall name="getppid" number="64"/> | |
29537 | + <syscall name="getpgrp" number="65"/> | |
29538 | + <syscall name="setsid" number="66"/> | |
29539 | + <syscall name="sigaction" number="67"/> | |
29540 | + <syscall name="sgetmask" number="68"/> | |
29541 | + <syscall name="ssetmask" number="69"/> | |
29542 | + <syscall name="setreuid" number="70"/> | |
29543 | + <syscall name="setregid" number="71"/> | |
29544 | + <syscall name="sigsuspend" number="72"/> | |
29545 | + <syscall name="sigpending" number="73"/> | |
29546 | + <syscall name="sethostname" number="74"/> | |
29547 | + <syscall name="setrlimit" number="75"/> | |
29548 | + <syscall name="getrlimit" number="76"/> | |
29549 | + <syscall name="getrusage" number="77"/> | |
29550 | + <syscall name="gettimeofday" number="78"/> | |
29551 | + <syscall name="settimeofday" number="79"/> | |
29552 | + <syscall name="getgroups" number="80"/> | |
29553 | + <syscall name="setgroups" number="81"/> | |
29554 | + <syscall name="select" number="82"/> | |
29555 | + <syscall name="symlink" number="83"/> | |
29556 | + <syscall name="oldlstat" number="84"/> | |
29557 | + <syscall name="readlink" number="85"/> | |
29558 | + <syscall name="uselib" number="86"/> | |
29559 | + <syscall name="swapon" number="87"/> | |
29560 | + <syscall name="reboot" number="88"/> | |
29561 | + <syscall name="readdir" number="89"/> | |
29562 | + <syscall name="mmap" number="90"/> | |
29563 | + <syscall name="munmap" number="91"/> | |
29564 | + <syscall name="truncate" number="92"/> | |
29565 | + <syscall name="ftruncate" number="93"/> | |
29566 | + <syscall name="fchmod" number="94"/> | |
29567 | + <syscall name="fchown" number="95"/> | |
29568 | + <syscall name="getpriority" number="96"/> | |
29569 | + <syscall name="setpriority" number="97"/> | |
29570 | + <syscall name="profil" number="98"/> | |
29571 | + <syscall name="statfs" number="99"/> | |
29572 | + <syscall name="fstatfs" number="100"/> | |
29573 | + <syscall name="ioperm" number="101"/> | |
29574 | + <syscall name="socketcall" number="102"/> | |
29575 | + <syscall name="syslog" number="103"/> | |
29576 | + <syscall name="setitimer" number="104"/> | |
29577 | + <syscall name="getitimer" number="105"/> | |
29578 | + <syscall name="stat" number="106"/> | |
29579 | + <syscall name="lstat" number="107"/> | |
29580 | + <syscall name="fstat" number="108"/> | |
29581 | + <syscall name="olduname" number="109"/> | |
29582 | + <syscall name="iopl" number="110"/> | |
29583 | + <syscall name="vhangup" number="111"/> | |
29584 | + <syscall name="idle" number="112"/> | |
29585 | + <syscall name="vm86" number="113"/> | |
29586 | + <syscall name="wait4" number="114"/> | |
29587 | + <syscall name="swapoff" number="115"/> | |
29588 | + <syscall name="sysinfo" number="116"/> | |
29589 | + <syscall name="ipc" number="117"/> | |
29590 | + <syscall name="fsync" number="118"/> | |
29591 | + <syscall name="sigreturn" number="119"/> | |
29592 | + <syscall name="clone" number="120"/> | |
29593 | + <syscall name="setdomainname" number="121"/> | |
29594 | + <syscall name="uname" number="122"/> | |
29595 | + <syscall name="modify_ldt" number="123"/> | |
29596 | + <syscall name="adjtimex" number="124"/> | |
29597 | + <syscall name="mprotect" number="125"/> | |
29598 | + <syscall name="sigprocmask" number="126"/> | |
29599 | + <syscall name="create_module" number="127"/> | |
29600 | + <syscall name="init_module" number="128"/> | |
29601 | + <syscall name="delete_module" number="129"/> | |
29602 | + <syscall name="get_kernel_syms" number="130"/> | |
29603 | + <syscall name="quotactl" number="131"/> | |
29604 | + <syscall name="getpgid" number="132"/> | |
29605 | + <syscall name="fchdir" number="133"/> | |
29606 | + <syscall name="bdflush" number="134"/> | |
29607 | + <syscall name="sysfs" number="135"/> | |
29608 | + <syscall name="personality" number="136"/> | |
29609 | + <syscall name="afs_syscall" number="137"/> | |
29610 | + <syscall name="setfsuid" number="138"/> | |
29611 | + <syscall name="setfsgid" number="139"/> | |
29612 | + <syscall name="_llseek" number="140"/> | |
29613 | + <syscall name="getdents" number="141"/> | |
29614 | + <syscall name="_newselect" number="142"/> | |
29615 | + <syscall name="flock" number="143"/> | |
29616 | + <syscall name="msync" number="144"/> | |
29617 | + <syscall name="readv" number="145"/> | |
29618 | + <syscall name="writev" number="146"/> | |
29619 | + <syscall name="getsid" number="147"/> | |
29620 | + <syscall name="fdatasync" number="148"/> | |
29621 | + <syscall name="_sysctl" number="149"/> | |
29622 | + <syscall name="mlock" number="150"/> | |
29623 | + <syscall name="munlock" number="151"/> | |
29624 | + <syscall name="mlockall" number="152"/> | |
29625 | + <syscall name="munlockall" number="153"/> | |
29626 | + <syscall name="sched_setparam" number="154"/> | |
29627 | + <syscall name="sched_getparam" number="155"/> | |
29628 | + <syscall name="sched_setscheduler" number="156"/> | |
29629 | + <syscall name="sched_getscheduler" number="157"/> | |
29630 | + <syscall name="sched_yield" number="158"/> | |
29631 | + <syscall name="sched_get_priority_max" number="159"/> | |
29632 | + <syscall name="sched_get_priority_min" number="160"/> | |
29633 | + <syscall name="sched_rr_get_interval" number="161"/> | |
29634 | + <syscall name="nanosleep" number="162"/> | |
29635 | + <syscall name="mremap" number="163"/> | |
29636 | + <syscall name="setresuid" number="164"/> | |
29637 | + <syscall name="getresuid" number="165"/> | |
29638 | + <syscall name="query_module" number="166"/> | |
29639 | + <syscall name="poll" number="167"/> | |
29640 | + <syscall name="nfsservctl" number="168"/> | |
29641 | + <syscall name="setresgid" number="169"/> | |
29642 | + <syscall name="getresgid" number="170"/> | |
29643 | + <syscall name="prctl" number="171"/> | |
29644 | + <syscall name="rt_sigreturn" number="172"/> | |
29645 | + <syscall name="rt_sigaction" number="173"/> | |
29646 | + <syscall name="rt_sigprocmask" number="174"/> | |
29647 | + <syscall name="rt_sigpending" number="175"/> | |
29648 | + <syscall name="rt_sigtimedwait" number="176"/> | |
29649 | + <syscall name="rt_sigqueueinfo" number="177"/> | |
29650 | + <syscall name="rt_sigsuspend" number="178"/> | |
29651 | + <syscall name="pread64" number="179"/> | |
29652 | + <syscall name="pwrite64" number="180"/> | |
29653 | + <syscall name="chown" number="181"/> | |
29654 | + <syscall name="getcwd" number="182"/> | |
29655 | + <syscall name="capget" number="183"/> | |
29656 | + <syscall name="capset" number="184"/> | |
29657 | + <syscall name="sigaltstack" number="185"/> | |
29658 | + <syscall name="sendfile" number="186"/> | |
29659 | + <syscall name="getpmsg" number="187"/> | |
29660 | + <syscall name="putpmsg" number="188"/> | |
29661 | + <syscall name="vfork" number="189"/> | |
29662 | + <syscall name="ugetrlimit" number="190"/> | |
29663 | + <syscall name="readahead" number="191"/> | |
29664 | + <syscall name="mmap2" number="192"/> | |
29665 | + <syscall name="truncate64" number="193"/> | |
29666 | + <syscall name="ftruncate64" number="194"/> | |
29667 | + <syscall name="stat64" number="195"/> | |
29668 | + <syscall name="lstat64" number="196"/> | |
29669 | + <syscall name="fstat64" number="197"/> | |
29670 | + <syscall name="pciconfig_read" number="198"/> | |
29671 | + <syscall name="pciconfig_write" number="199"/> | |
29672 | + <syscall name="pciconfig_iobase" number="200"/> | |
29673 | + <syscall name="multiplexer" number="201"/> | |
29674 | + <syscall name="getdents64" number="202"/> | |
29675 | + <syscall name="pivot_root" number="203"/> | |
29676 | + <syscall name="fcntl64" number="204"/> | |
29677 | + <syscall name="madvise" number="205"/> | |
29678 | + <syscall name="mincore" number="206"/> | |
29679 | + <syscall name="gettid" number="207"/> | |
29680 | + <syscall name="tkill" number="208"/> | |
29681 | + <syscall name="setxattr" number="209"/> | |
29682 | + <syscall name="lsetxattr" number="210"/> | |
29683 | + <syscall name="fsetxattr" number="211"/> | |
29684 | + <syscall name="getxattr" number="212"/> | |
29685 | + <syscall name="lgetxattr" number="213"/> | |
29686 | + <syscall name="fgetxattr" number="214"/> | |
29687 | + <syscall name="listxattr" number="215"/> | |
29688 | + <syscall name="llistxattr" number="216"/> | |
29689 | + <syscall name="flistxattr" number="217"/> | |
29690 | + <syscall name="removexattr" number="218"/> | |
29691 | + <syscall name="lremovexattr" number="219"/> | |
29692 | + <syscall name="fremovexattr" number="220"/> | |
29693 | + <syscall name="futex" number="221"/> | |
29694 | + <syscall name="sched_setaffinity" number="222"/> | |
29695 | + <syscall name="sched_getaffinity" number="223"/> | |
29696 | + <syscall name="tuxcall" number="225"/> | |
29697 | + <syscall name="sendfile64" number="226"/> | |
29698 | + <syscall name="io_setup" number="227"/> | |
29699 | + <syscall name="io_destroy" number="228"/> | |
29700 | + <syscall name="io_getevents" number="229"/> | |
29701 | + <syscall name="io_submit" number="230"/> | |
29702 | + <syscall name="io_cancel" number="231"/> | |
29703 | + <syscall name="set_tid_address" number="232"/> | |
29704 | + <syscall name="fadvise64" number="233"/> | |
29705 | + <syscall name="exit_group" number="234"/> | |
29706 | + <syscall name="lookup_dcookie" number="235"/> | |
29707 | + <syscall name="epoll_create" number="236"/> | |
29708 | + <syscall name="epoll_ctl" number="237"/> | |
29709 | + <syscall name="epoll_wait" number="238"/> | |
29710 | + <syscall name="remap_file_pages" number="239"/> | |
29711 | + <syscall name="timer_create" number="240"/> | |
29712 | + <syscall name="timer_settime" number="241"/> | |
29713 | + <syscall name="timer_gettime" number="242"/> | |
29714 | + <syscall name="timer_getoverrun" number="243"/> | |
29715 | + <syscall name="timer_delete" number="244"/> | |
29716 | + <syscall name="clock_settime" number="245"/> | |
29717 | + <syscall name="clock_gettime" number="246"/> | |
29718 | + <syscall name="clock_getres" number="247"/> | |
29719 | + <syscall name="clock_nanosleep" number="248"/> | |
29720 | + <syscall name="swapcontext" number="249"/> | |
29721 | + <syscall name="tgkill" number="250"/> | |
29722 | + <syscall name="utimes" number="251"/> | |
29723 | + <syscall name="statfs64" number="252"/> | |
29724 | + <syscall name="fstatfs64" number="253"/> | |
29725 | + <syscall name="fadvise64_64" number="254"/> | |
29726 | + <syscall name="rtas" number="255"/> | |
29727 | + <syscall name="sys_debug_setcontext" number="256"/> | |
29728 | + <syscall name="mbind" number="259"/> | |
29729 | + <syscall name="get_mempolicy" number="260"/> | |
29730 | + <syscall name="set_mempolicy" number="261"/> | |
29731 | + <syscall name="mq_open" number="262"/> | |
29732 | + <syscall name="mq_unlink" number="263"/> | |
29733 | + <syscall name="mq_timedsend" number="264"/> | |
29734 | + <syscall name="mq_timedreceive" number="265"/> | |
29735 | + <syscall name="mq_notify" number="266"/> | |
29736 | + <syscall name="mq_getsetattr" number="267"/> | |
29737 | + <syscall name="kexec_load" number="268"/> | |
29738 | + <syscall name="add_key" number="269"/> | |
29739 | + <syscall name="request_key" number="270"/> | |
29740 | + <syscall name="keyctl" number="271"/> | |
29741 | + <syscall name="waitid" number="272"/> | |
29742 | + <syscall name="ioprio_set" number="273"/> | |
29743 | + <syscall name="ioprio_get" number="274"/> | |
29744 | + <syscall name="inotify_init" number="275"/> | |
29745 | + <syscall name="inotify_add_watch" number="276"/> | |
29746 | + <syscall name="inotify_rm_watch" number="277"/> | |
29747 | + <syscall name="spu_run" number="278"/> | |
29748 | + <syscall name="spu_create" number="279"/> | |
29749 | + <syscall name="pselect6" number="280"/> | |
29750 | + <syscall name="ppoll" number="281"/> | |
29751 | + <syscall name="unshare" number="282"/> | |
29752 | + <syscall name="openat" number="286"/> | |
29753 | + <syscall name="mkdirat" number="287"/> | |
29754 | + <syscall name="mknodat" number="288"/> | |
29755 | + <syscall name="fchownat" number="289"/> | |
29756 | + <syscall name="futimesat" number="290"/> | |
29757 | + <syscall name="fstatat64" number="291"/> | |
29758 | + <syscall name="unlinkat" number="292"/> | |
29759 | + <syscall name="renameat" number="293"/> | |
29760 | + <syscall name="linkat" number="294"/> | |
29761 | + <syscall name="symlinkat" number="295"/> | |
29762 | + <syscall name="readlinkat" number="296"/> | |
29763 | + <syscall name="fchmodat" number="297"/> | |
29764 | + <syscall name="faccessat" number="298"/> | |
29765 | +</syscalls_info> | |
29766 | diff --git a/gdb/syscalls/ppc64-linux.xml b/gdb/syscalls/ppc64-linux.xml | |
29767 | new file mode 100644 | |
29768 | index 0000000..7ee929c | |
29769 | --- /dev/null | |
29770 | +++ b/gdb/syscalls/ppc64-linux.xml | |
29771 | @@ -0,0 +1,289 @@ | |
29772 | +<?xml version="1.0"?> | |
29773 | +<!-- Copyright (C) 2007, 2008 Free Software Foundation, Inc. | |
29774 | + | |
29775 | + Copying and distribution of this file, with or without modification, | |
29776 | + are permitted in any medium without royalty provided the copyright | |
29777 | + notice and this notice are preserved. --> | |
29778 | + | |
29779 | +<!DOCTYPE feature SYSTEM "gdb-syscalls.dtd"> | |
29780 | + | |
29781 | +<syscalls_info> | |
29782 | + <syscall name="restart_syscall" number="0"/> | |
29783 | + <syscall name="exit" number="1"/> | |
29784 | + <syscall name="fork" number="2"/> | |
29785 | + <syscall name="read" number="3"/> | |
29786 | + <syscall name="write" number="4"/> | |
29787 | + <syscall name="open" number="5"/> | |
29788 | + <syscall name="close" number="6"/> | |
29789 | + <syscall name="waitpid" number="7"/> | |
29790 | + <syscall name="creat" number="8"/> | |
29791 | + <syscall name="link" number="9"/> | |
29792 | + <syscall name="unlink" number="10"/> | |
29793 | + <syscall name="execve" number="11"/> | |
29794 | + <syscall name="chdir" number="12"/> | |
29795 | + <syscall name="time" number="13"/> | |
29796 | + <syscall name="mknod" number="14"/> | |
29797 | + <syscall name="chmod" number="15"/> | |
29798 | + <syscall name="lchown" number="16"/> | |
29799 | + <syscall name="break" number="17"/> | |
29800 | + <syscall name="oldstat" number="18"/> | |
29801 | + <syscall name="lseek" number="19"/> | |
29802 | + <syscall name="getpid" number="20"/> | |
29803 | + <syscall name="mount" number="21"/> | |
29804 | + <syscall name="umount" number="22"/> | |
29805 | + <syscall name="setuid" number="23"/> | |
29806 | + <syscall name="getuid" number="24"/> | |
29807 | + <syscall name="stime" number="25"/> | |
29808 | + <syscall name="ptrace" number="26"/> | |
29809 | + <syscall name="alarm" number="27"/> | |
29810 | + <syscall name="oldfstat" number="28"/> | |
29811 | + <syscall name="pause" number="29"/> | |
29812 | + <syscall name="utime" number="30"/> | |
29813 | + <syscall name="stty" number="31"/> | |
29814 | + <syscall name="gtty" number="32"/> | |
29815 | + <syscall name="access" number="33"/> | |
29816 | + <syscall name="nice" number="34"/> | |
29817 | + <syscall name="ftime" number="35"/> | |
29818 | + <syscall name="sync" number="36"/> | |
29819 | + <syscall name="kill" number="37"/> | |
29820 | + <syscall name="rename" number="38"/> | |
29821 | + <syscall name="mkdir" number="39"/> | |
29822 | + <syscall name="rmdir" number="40"/> | |
29823 | + <syscall name="dup" number="41"/> | |
29824 | + <syscall name="pipe" number="42"/> | |
29825 | + <syscall name="times" number="43"/> | |
29826 | + <syscall name="prof" number="44"/> | |
29827 | + <syscall name="brk" number="45"/> | |
29828 | + <syscall name="setgid" number="46"/> | |
29829 | + <syscall name="getgid" number="47"/> | |
29830 | + <syscall name="signal" number="48"/> | |
29831 | + <syscall name="geteuid" number="49"/> | |
29832 | + <syscall name="getegid" number="50"/> | |
29833 | + <syscall name="acct" number="51"/> | |
29834 | + <syscall name="umount2" number="52"/> | |
29835 | + <syscall name="lock" number="53"/> | |
29836 | + <syscall name="ioctl" number="54"/> | |
29837 | + <syscall name="fcntl" number="55"/> | |
29838 | + <syscall name="mpx" number="56"/> | |
29839 | + <syscall name="setpgid" number="57"/> | |
29840 | + <syscall name="ulimit" number="58"/> | |
29841 | + <syscall name="oldolduname" number="59"/> | |
29842 | + <syscall name="umask" number="60"/> | |
29843 | + <syscall name="chroot" number="61"/> | |
29844 | + <syscall name="ustat" number="62"/> | |
29845 | + <syscall name="dup2" number="63"/> | |
29846 | + <syscall name="getppid" number="64"/> | |
29847 | + <syscall name="getpgrp" number="65"/> | |
29848 | + <syscall name="setsid" number="66"/> | |
29849 | + <syscall name="sigaction" number="67"/> | |
29850 | + <syscall name="sgetmask" number="68"/> | |
29851 | + <syscall name="ssetmask" number="69"/> | |
29852 | + <syscall name="setreuid" number="70"/> | |
29853 | + <syscall name="setregid" number="71"/> | |
29854 | + <syscall name="sigsuspend" number="72"/> | |
29855 | + <syscall name="sigpending" number="73"/> | |
29856 | + <syscall name="sethostname" number="74"/> | |
29857 | + <syscall name="setrlimit" number="75"/> | |
29858 | + <syscall name="getrlimit" number="76"/> | |
29859 | + <syscall name="getrusage" number="77"/> | |
29860 | + <syscall name="gettimeofday" number="78"/> | |
29861 | + <syscall name="settimeofday" number="79"/> | |
29862 | + <syscall name="getgroups" number="80"/> | |
29863 | + <syscall name="setgroups" number="81"/> | |
29864 | + <syscall name="select" number="82"/> | |
29865 | + <syscall name="symlink" number="83"/> | |
29866 | + <syscall name="oldlstat" number="84"/> | |
29867 | + <syscall name="readlink" number="85"/> | |
29868 | + <syscall name="uselib" number="86"/> | |
29869 | + <syscall name="swapon" number="87"/> | |
29870 | + <syscall name="reboot" number="88"/> | |
29871 | + <syscall name="readdir" number="89"/> | |
29872 | + <syscall name="mmap" number="90"/> | |
29873 | + <syscall name="munmap" number="91"/> | |
29874 | + <syscall name="truncate" number="92"/> | |
29875 | + <syscall name="ftruncate" number="93"/> | |
29876 | + <syscall name="fchmod" number="94"/> | |
29877 | + <syscall name="fchown" number="95"/> | |
29878 | + <syscall name="getpriority" number="96"/> | |
29879 | + <syscall name="setpriority" number="97"/> | |
29880 | + <syscall name="profil" number="98"/> | |
29881 | + <syscall name="statfs" number="99"/> | |
29882 | + <syscall name="fstatfs" number="100"/> | |
29883 | + <syscall name="ioperm" number="101"/> | |
29884 | + <syscall name="socketcall" number="102"/> | |
29885 | + <syscall name="syslog" number="103"/> | |
29886 | + <syscall name="setitimer" number="104"/> | |
29887 | + <syscall name="getitimer" number="105"/> | |
29888 | + <syscall name="stat" number="106"/> | |
29889 | + <syscall name="lstat" number="107"/> | |
29890 | + <syscall name="fstat" number="108"/> | |
29891 | + <syscall name="olduname" number="109"/> | |
29892 | + <syscall name="iopl" number="110"/> | |
29893 | + <syscall name="vhangup" number="111"/> | |
29894 | + <syscall name="idle" number="112"/> | |
29895 | + <syscall name="vm86" number="113"/> | |
29896 | + <syscall name="wait4" number="114"/> | |
29897 | + <syscall name="swapoff" number="115"/> | |
29898 | + <syscall name="sysinfo" number="116"/> | |
29899 | + <syscall name="ipc" number="117"/> | |
29900 | + <syscall name="fsync" number="118"/> | |
29901 | + <syscall name="sigreturn" number="119"/> | |
29902 | + <syscall name="clone" number="120"/> | |
29903 | + <syscall name="setdomainname" number="121"/> | |
29904 | + <syscall name="uname" number="122"/> | |
29905 | + <syscall name="modify_ldt" number="123"/> | |
29906 | + <syscall name="adjtimex" number="124"/> | |
29907 | + <syscall name="mprotect" number="125"/> | |
29908 | + <syscall name="sigprocmask" number="126"/> | |
29909 | + <syscall name="create_module" number="127"/> | |
29910 | + <syscall name="init_module" number="128"/> | |
29911 | + <syscall name="delete_module" number="129"/> | |
29912 | + <syscall name="get_kernel_syms" number="130"/> | |
29913 | + <syscall name="quotactl" number="131"/> | |
29914 | + <syscall name="getpgid" number="132"/> | |
29915 | + <syscall name="fchdir" number="133"/> | |
29916 | + <syscall name="bdflush" number="134"/> | |
29917 | + <syscall name="sysfs" number="135"/> | |
29918 | + <syscall name="personality" number="136"/> | |
29919 | + <syscall name="afs_syscall" number="137"/> | |
29920 | + <syscall name="setfsuid" number="138"/> | |
29921 | + <syscall name="setfsgid" number="139"/> | |
29922 | + <syscall name="_llseek" number="140"/> | |
29923 | + <syscall name="getdents" number="141"/> | |
29924 | + <syscall name="_newselect" number="142"/> | |
29925 | + <syscall name="flock" number="143"/> | |
29926 | + <syscall name="msync" number="144"/> | |
29927 | + <syscall name="readv" number="145"/> | |
29928 | + <syscall name="writev" number="146"/> | |
29929 | + <syscall name="getsid" number="147"/> | |
29930 | + <syscall name="fdatasync" number="148"/> | |
29931 | + <syscall name="_sysctl" number="149"/> | |
29932 | + <syscall name="mlock" number="150"/> | |
29933 | + <syscall name="munlock" number="151"/> | |
29934 | + <syscall name="mlockall" number="152"/> | |
29935 | + <syscall name="munlockall" number="153"/> | |
29936 | + <syscall name="sched_setparam" number="154"/> | |
29937 | + <syscall name="sched_getparam" number="155"/> | |
29938 | + <syscall name="sched_setscheduler" number="156"/> | |
29939 | + <syscall name="sched_getscheduler" number="157"/> | |
29940 | + <syscall name="sched_yield" number="158"/> | |
29941 | + <syscall name="sched_get_priority_max" number="159"/> | |
29942 | + <syscall name="sched_get_priority_min" number="160"/> | |
29943 | + <syscall name="sched_rr_get_interval" number="161"/> | |
29944 | + <syscall name="nanosleep" number="162"/> | |
29945 | + <syscall name="mremap" number="163"/> | |
29946 | + <syscall name="setresuid" number="164"/> | |
29947 | + <syscall name="getresuid" number="165"/> | |
29948 | + <syscall name="query_module" number="166"/> | |
29949 | + <syscall name="poll" number="167"/> | |
29950 | + <syscall name="nfsservctl" number="168"/> | |
29951 | + <syscall name="setresgid" number="169"/> | |
29952 | + <syscall name="getresgid" number="170"/> | |
29953 | + <syscall name="prctl" number="171"/> | |
29954 | + <syscall name="rt_sigreturn" number="172"/> | |
29955 | + <syscall name="rt_sigaction" number="173"/> | |
29956 | + <syscall name="rt_sigprocmask" number="174"/> | |
29957 | + <syscall name="rt_sigpending" number="175"/> | |
29958 | + <syscall name="rt_sigtimedwait" number="176"/> | |
29959 | + <syscall name="rt_sigqueueinfo" number="177"/> | |
29960 | + <syscall name="rt_sigsuspend" number="178"/> | |
29961 | + <syscall name="pread64" number="179"/> | |
29962 | + <syscall name="pwrite64" number="180"/> | |
29963 | + <syscall name="chown" number="181"/> | |
29964 | + <syscall name="getcwd" number="182"/> | |
29965 | + <syscall name="capget" number="183"/> | |
29966 | + <syscall name="capset" number="184"/> | |
29967 | + <syscall name="sigaltstack" number="185"/> | |
29968 | + <syscall name="sendfile" number="186"/> | |
29969 | + <syscall name="getpmsg" number="187"/> | |
29970 | + <syscall name="putpmsg" number="188"/> | |
29971 | + <syscall name="vfork" number="189"/> | |
29972 | + <syscall name="ugetrlimit" number="190"/> | |
29973 | + <syscall name="readahead" number="191"/> | |
29974 | + <syscall name="pciconfig_read" number="198"/> | |
29975 | + <syscall name="pciconfig_write" number="199"/> | |
29976 | + <syscall name="pciconfig_iobase" number="200"/> | |
29977 | + <syscall name="multiplexer" number="201"/> | |
29978 | + <syscall name="getdents64" number="202"/> | |
29979 | + <syscall name="pivot_root" number="203"/> | |
29980 | + <syscall name="madvise" number="205"/> | |
29981 | + <syscall name="mincore" number="206"/> | |
29982 | + <syscall name="gettid" number="207"/> | |
29983 | + <syscall name="tkill" number="208"/> | |
29984 | + <syscall name="setxattr" number="209"/> | |
29985 | + <syscall name="lsetxattr" number="210"/> | |
29986 | + <syscall name="fsetxattr" number="211"/> | |
29987 | + <syscall name="getxattr" number="212"/> | |
29988 | + <syscall name="lgetxattr" number="213"/> | |
29989 | + <syscall name="fgetxattr" number="214"/> | |
29990 | + <syscall name="listxattr" number="215"/> | |
29991 | + <syscall name="llistxattr" number="216"/> | |
29992 | + <syscall name="flistxattr" number="217"/> | |
29993 | + <syscall name="removexattr" number="218"/> | |
29994 | + <syscall name="lremovexattr" number="219"/> | |
29995 | + <syscall name="fremovexattr" number="220"/> | |
29996 | + <syscall name="futex" number="221"/> | |
29997 | + <syscall name="sched_setaffinity" number="222"/> | |
29998 | + <syscall name="sched_getaffinity" number="223"/> | |
29999 | + <syscall name="tuxcall" number="225"/> | |
30000 | + <syscall name="io_setup" number="227"/> | |
30001 | + <syscall name="io_destroy" number="228"/> | |
30002 | + <syscall name="io_getevents" number="229"/> | |
30003 | + <syscall name="io_submit" number="230"/> | |
30004 | + <syscall name="io_cancel" number="231"/> | |
30005 | + <syscall name="set_tid_address" number="232"/> | |
30006 | + <syscall name="fadvise64" number="233"/> | |
30007 | + <syscall name="exit_group" number="234"/> | |
30008 | + <syscall name="lookup_dcookie" number="235"/> | |
30009 | + <syscall name="epoll_create" number="236"/> | |
30010 | + <syscall name="epoll_ctl" number="237"/> | |
30011 | + <syscall name="epoll_wait" number="238"/> | |
30012 | + <syscall name="remap_file_pages" number="239"/> | |
30013 | + <syscall name="timer_create" number="240"/> | |
30014 | + <syscall name="timer_settime" number="241"/> | |
30015 | + <syscall name="timer_gettime" number="242"/> | |
30016 | + <syscall name="timer_getoverrun" number="243"/> | |
30017 | + <syscall name="timer_delete" number="244"/> | |
30018 | + <syscall name="clock_settime" number="245"/> | |
30019 | + <syscall name="clock_gettime" number="246"/> | |
30020 | + <syscall name="clock_getres" number="247"/> | |
30021 | + <syscall name="clock_nanosleep" number="248"/> | |
30022 | + <syscall name="swapcontext" number="249"/> | |
30023 | + <syscall name="tgkill" number="250"/> | |
30024 | + <syscall name="utimes" number="251"/> | |
30025 | + <syscall name="statfs64" number="252"/> | |
30026 | + <syscall name="fstatfs64" number="253"/> | |
30027 | + <syscall name="rtas" number="255"/> | |
30028 | + <syscall name="sys_debug_setcontext" number="256"/> | |
30029 | + <syscall name="mbind" number="259"/> | |
30030 | + <syscall name="get_mempolicy" number="260"/> | |
30031 | + <syscall name="set_mempolicy" number="261"/> | |
30032 | + <syscall name="mq_open" number="262"/> | |
30033 | + <syscall name="mq_unlink" number="263"/> | |
30034 | + <syscall name="mq_timedsend" number="264"/> | |
30035 | + <syscall name="mq_timedreceive" number="265"/> | |
30036 | + <syscall name="mq_notify" number="266"/> | |
30037 | + <syscall name="mq_getsetattr" number="267"/> | |
30038 | + <syscall name="kexec_load" number="268"/> | |
30039 | + <syscall name="add_key" number="269"/> | |
30040 | + <syscall name="request_key" number="270"/> | |
30041 | + <syscall name="keyctl" number="271"/> | |
30042 | + <syscall name="waitid" number="272"/> | |
30043 | + <syscall name="ioprio_set" number="273"/> | |
30044 | + <syscall name="ioprio_get" number="274"/> | |
30045 | + <syscall name="inotify_init" number="275"/> | |
30046 | + <syscall name="inotify_add_watch" number="276"/> | |
30047 | + <syscall name="inotify_rm_watch" number="277"/> | |
30048 | + <syscall name="spu_run" number="278"/> | |
30049 | + <syscall name="spu_create" number="279"/> | |
30050 | + <syscall name="pselect6" number="280"/> | |
30051 | + <syscall name="ppoll" number="281"/> | |
30052 | + <syscall name="unshare" number="282"/> | |
30053 | + <syscall name="unlinkat" number="286"/> | |
30054 | + <syscall name="renameat" number="287"/> | |
30055 | + <syscall name="linkat" number="288"/> | |
30056 | + <syscall name="symlinkat" number="289"/> | |
30057 | + <syscall name="readlinkat" number="290"/> | |
30058 | + <syscall name="fchmodat" number="291"/> | |
30059 | + <syscall name="faccessat" number="292"/> | |
30060 | +</syscalls_info> | |
30061 | diff --git a/gdb/target.c b/gdb/target.c | |
30062 | index b89d551..831070c 100644 | |
30063 | --- a/gdb/target.c | |
30064 | +++ b/gdb/target.c | |
30065 | @@ -443,6 +443,8 @@ update_current_target (void) | |
30066 | /* Do not inherit to_follow_fork. */ | |
30067 | INHERIT (to_insert_exec_catchpoint, t); | |
30068 | INHERIT (to_remove_exec_catchpoint, t); | |
30069 | + INHERIT (to_passed_by_entrypoint, t); | |
30070 | + INHERIT (to_set_syscall_catchpoint, t); | |
30071 | INHERIT (to_has_exited, t); | |
30072 | /* Do not inherit to_mourn_inferiour. */ | |
30073 | INHERIT (to_can_run, t); | |
30074 | @@ -586,9 +588,15 @@ update_current_target (void) | |
30075 | de_fault (to_insert_exec_catchpoint, | |
30076 | (void (*) (int)) | |
30077 | tcomplain); | |
30078 | + de_fault (to_passed_by_entrypoint, | |
30079 | + (int (*) (void)) | |
30080 | + tcomplain); | |
30081 | de_fault (to_remove_exec_catchpoint, | |
30082 | (int (*) (int)) | |
30083 | tcomplain); | |
30084 | + de_fault (to_set_syscall_catchpoint, | |
30085 | + (int (*) (int, int, int, int, int *)) | |
30086 | + tcomplain); | |
30087 | de_fault (to_has_exited, | |
30088 | (int (*) (int, int, int *)) | |
30089 | return_zero); | |
30090 | @@ -2677,9 +2685,9 @@ target_waitstatus_to_string (const struct target_waitstatus *ws) | |
30091 | case TARGET_WAITKIND_EXECD: | |
30092 | return xstrprintf ("%sexecd", kind_str); | |
30093 | case TARGET_WAITKIND_SYSCALL_ENTRY: | |
30094 | - return xstrprintf ("%ssyscall-entry", kind_str); | |
30095 | + return xstrprintf ("%sentered syscall", kind_str); | |
30096 | case TARGET_WAITKIND_SYSCALL_RETURN: | |
30097 | - return xstrprintf ("%ssyscall-return", kind_str); | |
30098 | + return xstrprintf ("%sexited syscall", kind_str); | |
30099 | case TARGET_WAITKIND_SPURIOUS: | |
30100 | return xstrprintf ("%sspurious", kind_str); | |
30101 | case TARGET_WAITKIND_IGNORE: | |
30102 | diff --git a/gdb/target.h b/gdb/target.h | |
30103 | index 7f4cd8f..8dcc3d6 100644 | |
30104 | --- a/gdb/target.h | |
30105 | +++ b/gdb/target.h | |
30106 | @@ -140,18 +140,34 @@ struct target_waitstatus | |
30107 | { | |
30108 | enum target_waitkind kind; | |
30109 | ||
30110 | - /* Forked child pid, execd pathname, exit status or signal number. */ | |
30111 | + /* Forked child pid, execd pathname, exit status, signal number or | |
30112 | + syscall name. */ | |
30113 | union | |
30114 | { | |
30115 | int integer; | |
30116 | enum target_signal sig; | |
30117 | ptid_t related_pid; | |
30118 | char *execd_pathname; | |
30119 | - int syscall_id; | |
30120 | + int syscall_number; | |
30121 | } | |
30122 | value; | |
30123 | }; | |
30124 | ||
30125 | +/* The structure below stores information about a system call. | |
30126 | + It is basically used in the "catch syscall" command, and in | |
30127 | + every function that gives information about a system call. | |
30128 | + | |
30129 | + It's also good to mention that its fields represent everything | |
30130 | + that we currently know about a syscall in GDB. */ | |
30131 | +struct syscall | |
30132 | + { | |
30133 | + /* The syscall number. */ | |
30134 | + int number; | |
30135 | + | |
30136 | + /* The syscall name. */ | |
30137 | + const char *name; | |
30138 | + }; | |
30139 | + | |
30140 | /* Return a pretty printed form of target_waitstatus. | |
30141 | Space for the result is malloc'd, caller must free. */ | |
30142 | extern char *target_waitstatus_to_string (const struct target_waitstatus *); | |
30143 | @@ -392,6 +408,8 @@ struct target_ops | |
30144 | int (*to_follow_fork) (struct target_ops *, int); | |
30145 | void (*to_insert_exec_catchpoint) (int); | |
30146 | int (*to_remove_exec_catchpoint) (int); | |
30147 | + int (*to_passed_by_entrypoint) (void); | |
30148 | + int (*to_set_syscall_catchpoint) (int, int, int, int, int *); | |
30149 | int (*to_has_exited) (int, int, int *); | |
30150 | void (*to_mourn_inferior) (struct target_ops *); | |
30151 | int (*to_can_run) (void); | |
30152 | @@ -723,6 +741,8 @@ extern int inferior_has_vforked (ptid_t pid, ptid_t *child_pid); | |
30153 | ||
30154 | extern int inferior_has_execd (ptid_t pid, char **execd_pathname); | |
30155 | ||
30156 | +extern int inferior_has_called_syscall (ptid_t pid, int *syscall_number); | |
30157 | + | |
30158 | /* From exec.c */ | |
30159 | ||
30160 | extern void print_section_info (struct target_ops *, bfd *); | |
30161 | @@ -881,6 +901,21 @@ int target_follow_fork (int follow_child); | |
30162 | #define target_remove_exec_catchpoint(pid) \ | |
30163 | (*current_target.to_remove_exec_catchpoint) (pid) | |
30164 | ||
30165 | +/* Has the inferior already passed through its entrypoint? */ | |
30166 | +#define target_passed_by_entrypoint() \ | |
30167 | + (*current_target.to_passed_by_entrypoint) () | |
30168 | + | |
30169 | +/* Syscall catch. NEEDED is nonzero if any syscall catch (of any | |
30170 | + kind) is requested. ANY_COUNT is nonzero if a generic | |
30171 | + (filter-less) syscall catch is being requested. TABLE is an array | |
30172 | + of ints, indexed by syscall number. An element in this array is | |
30173 | + nonzero if that syscall should be caught. TABLE_SIZE is the number | |
30174 | + of elements in TABLE. */ | |
30175 | + | |
30176 | +#define target_set_syscall_catchpoint(pid, needed, any_count, table_size, table) \ | |
30177 | + (*current_target.to_set_syscall_catchpoint) (pid, needed, any_count, \ | |
30178 | + table_size, table) | |
30179 | + | |
30180 | /* Returns TRUE if PID has exited. And, also sets EXIT_STATUS to the | |
30181 | exit code of PID, if any. */ | |
30182 | ||
30183 | @@ -1146,6 +1181,20 @@ extern int target_search_memory (CORE_ADDR start_addr, | |
30184 | ULONGEST pattern_len, | |
30185 | CORE_ADDR *found_addrp); | |
30186 | ||
30187 | +/* Utility functions which can be used by search_memory implementations. */ | |
30188 | + | |
30189 | +void allocate_pattern_buffer (char **pattern_bufp, char **pattern_buf_end, | |
30190 | + ULONGEST *pattern_buf_size); | |
30191 | + | |
30192 | +void increase_pattern_buffer (char **pattern_bufp, char **pattern_buf_end, | |
30193 | + ULONGEST *pattern_buf_size, int val_bytes); | |
30194 | + | |
30195 | +int search_memory (CORE_ADDR *start_addr, ULONGEST *search_space_len, | |
30196 | + const char *pattern_buf, ULONGEST pattern_len, | |
30197 | + CORE_ADDR *found_addr); | |
30198 | + | |
30199 | +void put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p); | |
30200 | + | |
30201 | /* Command logging facility. */ | |
30202 | ||
30203 | #define target_log_command(p) \ | |
30204 | diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog | |
30205 | index e3aaeab..e886869 100644 | |
30206 | --- a/gdb/testsuite/ChangeLog | |
30207 | +++ b/gdb/testsuite/ChangeLog | |
30208 | @@ -1,3 +1,7 @@ | |
30209 | +2009-03-05 Pedro Alves <pedro@codesourcery.com> | |
30210 | + | |
30211 | + * gdb.arch/i386-permbkpt.S, gdb.arch/i386-permbkpt.exp: New. | |
30212 | + | |
30213 | 2009-02-18 Jan Kratochvil <jan.kratochvil@redhat.com> | |
30214 | ||
30215 | * gdb.base/macscp.exp (objfile): Move it to ${objdir}/${subdir}/. | |
30216 | diff --git a/gdb/testsuite/configure.ac b/gdb/testsuite/configure.ac | |
30217 | index 3d8fae4..5fb9067 100644 | |
30218 | --- a/gdb/testsuite/configure.ac | |
30219 | +++ b/gdb/testsuite/configure.ac | |
30220 | @@ -1,7 +1,7 @@ | |
30221 | # -*- Autoconf -*- | |
30222 | # Process this file with autoconf to produce a configure script. | |
30223 | ||
30224 | -# Copyright 2002, 2003, 2004, 2005 | |
30225 | +# Copyright 2002, 2003, 2004, 2005, 2008 | |
30226 | # Free Software Foundation, Inc. | |
30227 | # | |
30228 | # This program is free software; you can redistribute it and/or modify | |
30229 | diff --git a/gdb/testsuite/gdb.arch/i386-permbkpt.S b/gdb/testsuite/gdb.arch/i386-permbkpt.S | |
30230 | new file mode 100644 | |
30231 | index 0000000..02a31d6 | |
30232 | --- /dev/null | |
30233 | +++ b/gdb/testsuite/gdb.arch/i386-permbkpt.S | |
30234 | @@ -0,0 +1,30 @@ | |
30235 | +/* Copyright 2009 Free Software Foundation, Inc. | |
30236 | + | |
30237 | + This program is free software; you can redistribute it and/or modify | |
30238 | + it under the terms of the GNU General Public License as published by | |
30239 | + the Free Software Foundation; either version 3 of the License, or | |
30240 | + (at your option) any later version. | |
30241 | + | |
30242 | + This program is distributed in the hope that it will be useful, | |
30243 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
30244 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
30245 | + GNU General Public License for more details. | |
30246 | + | |
30247 | + You should have received a copy of the GNU General Public License | |
30248 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
30249 | + | |
30250 | + This file is part of the gdb testsuite. */ | |
30251 | + | |
30252 | +#define CONCAT1(a, b) CONCAT2(a, b) | |
30253 | +#define CONCAT2(a, b) a ## b | |
30254 | + | |
30255 | +#ifdef SYMBOL_PREFIX | |
30256 | +# define SYMBOL(str) CONCAT1(SYMBOL_PREFIX, str) | |
30257 | +#else | |
30258 | +# define SYMBOL(str) str | |
30259 | +#endif | |
30260 | + | |
30261 | + .global SYMBOL(main) | |
30262 | +SYMBOL(main): | |
30263 | + int3 | |
30264 | + ret | |
30265 | diff --git a/gdb/testsuite/gdb.arch/i386-permbkpt.exp b/gdb/testsuite/gdb.arch/i386-permbkpt.exp | |
30266 | new file mode 100644 | |
30267 | index 0000000..f1930e5 | |
30268 | --- /dev/null | |
30269 | +++ b/gdb/testsuite/gdb.arch/i386-permbkpt.exp | |
30270 | @@ -0,0 +1,52 @@ | |
30271 | +# Copyright (C) 2009 Free Software Foundation, Inc. | |
30272 | + | |
30273 | +# This program is free software; you can redistribute it and/or modify | |
30274 | +# it under the terms of the GNU General Public License as published by | |
30275 | +# the Free Software Foundation; either version 3 of the License, or | |
30276 | +# (at your option) any later version. | |
30277 | +# | |
30278 | +# This program is distributed in the hope that it will be useful, | |
30279 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
30280 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
30281 | +# GNU General Public License for more details. | |
30282 | +# | |
30283 | +# You should have received a copy of the GNU General Public License | |
30284 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
30285 | + | |
30286 | + | |
30287 | +# This file is part of the gdb testsuite. | |
30288 | + | |
30289 | +if $tracelevel { | |
30290 | + strace $tracelevel | |
30291 | +} | |
30292 | + | |
30293 | +# Test inserting breakpoints over permanent breakpoints on i386 and amd64. | |
30294 | + | |
30295 | +if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } then { | |
30296 | + verbose "Skipping i386 test for multi break at permanent breakpoint location." | |
30297 | + return | |
30298 | +} | |
30299 | + | |
30300 | +set testfile "i386-permbkpt" | |
30301 | +set srcfile ${testfile}.S | |
30302 | +set binfile ${objdir}/${subdir}/${testfile} | |
30303 | + | |
30304 | +# Some targets have leading underscores on assembly symbols. | |
30305 | +# TODO: detect this automatically | |
30306 | +set additional_flags "" | |
30307 | +if { [istarget "*-*-cygwin*"] || [istarget "*-*-mingw*"] } then { | |
30308 | + set additional_flags "additional_flags=-DSYMBOL_PREFIX=_" | |
30309 | +} | |
30310 | + | |
30311 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $additional_flags]] != "" } { | |
30312 | + untested i386-permbkpt.exp | |
30313 | + return -1 | |
30314 | +} | |
30315 | + | |
30316 | +gdb_exit | |
30317 | +gdb_start | |
30318 | +gdb_reinitialize_dir $srcdir/$subdir | |
30319 | +gdb_load ${binfile} | |
30320 | + | |
30321 | +gdb_test "break main" "" "First permanent break" | |
30322 | +gdb_test "break main" "" "Second permanent break" | |
30323 | diff --git a/gdb/testsuite/gdb.arch/powerpc-power7.exp b/gdb/testsuite/gdb.arch/powerpc-power7.exp | |
30324 | new file mode 100644 | |
30325 | index 0000000..d9c48f9 | |
30326 | --- /dev/null | |
30327 | +++ b/gdb/testsuite/gdb.arch/powerpc-power7.exp | |
30328 | @@ -0,0 +1,166 @@ | |
30329 | +# Copyright 2009 Free Software Foundation, Inc. | |
30330 | + | |
30331 | +# This program is free software; you can redistribute it and/or modify | |
30332 | +# it under the terms of the GNU General Public License as published by | |
30333 | +# the Free Software Foundation; either version 2 of the License, or | |
30334 | +# (at your option) any later version. | |
30335 | +# | |
30336 | +# This program is distributed in the hope that it will be useful, | |
30337 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
30338 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
30339 | +# GNU General Public License for more details. | |
30340 | +# | |
30341 | +# You should have received a copy of the GNU General Public License | |
30342 | +# along with this program; if not, write to the Free Software | |
30343 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
30344 | + | |
30345 | +# Test PowerPC Power7 instructions disassembly. | |
30346 | + | |
30347 | +if {![istarget "powerpc*-*-*"]} then { | |
30348 | + verbose "Skipping PowerPC Power7 instructions disassembly." | |
30349 | + return | |
30350 | +} | |
30351 | + | |
30352 | +set testfile "powerpc-power7" | |
30353 | +set srcfile ${testfile}.s | |
30354 | +set objfile ${objdir}/${subdir}/${testfile}.o | |
30355 | + | |
30356 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] != "" } { | |
30357 | + untested "PowerPC Power7 instructions disassembly" | |
30358 | + return -1 | |
30359 | +} | |
30360 | + | |
30361 | + | |
30362 | +gdb_exit | |
30363 | +gdb_start | |
30364 | +gdb_reinitialize_dir $srcdir/$subdir | |
30365 | +gdb_load ${objfile} | |
30366 | + | |
30367 | + | |
30368 | +# Disassemble the function. | |
30369 | + | |
30370 | +set test "disass func" | |
30371 | +gdb_test_multiple $test $test { | |
30372 | + -re "\r\nDump of assembler code for function func:(\r\n.*\r\n)End of assembler dump.\r\n$gdb_prompt $" { | |
30373 | + set func $expect_out(1,string) | |
30374 | + pass $test | |
30375 | + } | |
30376 | +} | |
30377 | + | |
30378 | +proc func_check {offset instr} { | |
30379 | + global func | |
30380 | + | |
30381 | + # 0x0000000000000018 <func+24>: stxvd2x vs43,r4,r5 | |
30382 | + set patt ".*\r\n[string map {0x 0x0*} $offset] <func\\+?\[0-9\]*>:\[ \t\]*[string map [list { } "\[ \t\]+" . {\.}] $instr]\[ \t\]*\r\n.*" | |
30383 | + set test "Found $offset: $instr" | |
30384 | + if [regexp -nocase -line $patt $func] { | |
30385 | + pass $test | |
30386 | + } else { | |
30387 | + fail $test | |
30388 | + } | |
30389 | +} | |
30390 | + | |
30391 | +func_check 0x0 "lxvd2x vs3,r4,r5" | |
30392 | +func_check 0x4 "lxvd2ux vs3,r4,r5" | |
30393 | +func_check 0x8 "lxvd2x vs43,r4,r5" | |
30394 | +func_check 0xc "lxvd2ux vs43,r4,r5" | |
30395 | +func_check 0x10 "stxvd2x vs3,r4,r5" | |
30396 | +func_check 0x14 "stxvd2ux vs3,r4,r5" | |
30397 | +func_check 0x18 "stxvd2x vs43,r4,r5" | |
30398 | +func_check 0x1c "stxvd2ux vs43,r4,r5" | |
30399 | +func_check 0x20 "xxmrghd vs3,vs4,vs5" | |
30400 | +func_check 0x24 "xxmrghd vs43,vs44,vs45" | |
30401 | +func_check 0x28 "xxmrgld vs3,vs4,vs5" | |
30402 | +func_check 0x2c "xxmrgld vs43,vs44,vs45" | |
30403 | +func_check 0x30 "xxmrghd vs3,vs4,vs5" | |
30404 | +func_check 0x34 "xxmrghd vs43,vs44,vs45" | |
30405 | +func_check 0x38 "xxmrgld vs3,vs4,vs5" | |
30406 | +func_check 0x3c "xxmrgld vs43,vs44,vs45" | |
30407 | +func_check 0x40 "xxpermdi vs3,vs4,vs5,1" | |
30408 | +func_check 0x44 "xxpermdi vs43,vs44,vs45,1" | |
30409 | +func_check 0x48 "xxpermdi vs3,vs4,vs5,2" | |
30410 | +func_check 0x4c "xxpermdi vs43,vs44,vs45,2" | |
30411 | +func_check 0x50 "xvmovdp vs3,vs4" | |
30412 | +func_check 0x54 "xvmovdp vs43,vs44" | |
30413 | +func_check 0x58 "xvmovdp vs3,vs4" | |
30414 | +func_check 0x5c "xvmovdp vs43,vs44" | |
30415 | +func_check 0x60 "xvcpsgndp vs3,vs4,vs5" | |
30416 | +func_check 0x64 "xvcpsgndp vs43,vs44,vs45" | |
30417 | +func_check 0x68 "wait" | |
30418 | +func_check 0x6c "wait" | |
30419 | +func_check 0x70 "waitrsv" | |
30420 | +func_check 0x74 "waitrsv" | |
30421 | +func_check 0x78 "waitimpl" | |
30422 | +func_check 0x7c "waitimpl" | |
30423 | +func_check 0x80 "doze" | |
30424 | +func_check 0x84 "nap" | |
30425 | +func_check 0x88 "sleep" | |
30426 | +func_check 0x8c "rvwinkle" | |
30427 | +func_check 0x90 "prtyw r3,r4" | |
30428 | +func_check 0x94 "prtyd r13,r14" | |
30429 | +func_check 0x98 "mfcfar r10" | |
30430 | +func_check 0x9c "mtcfar r11" | |
30431 | +func_check 0xa0 "cmpb r3,r4,r5" | |
30432 | +func_check 0xa4 "lwzcix r10,r11,r12" | |
30433 | +func_check 0xa8 "dadd f16,f17,f18" | |
30434 | +func_check 0xac "daddq f20,f22,f24" | |
30435 | +func_check 0xb0 "dss 3" | |
30436 | +func_check 0xb4 "dssall" | |
30437 | +func_check 0xb8 "dst r5,r4,1" | |
30438 | +func_check 0xbc "dstt r8,r7,0" | |
30439 | +func_check 0xc0 "dstst r5,r6,3" | |
30440 | +func_check 0xc4 "dststt r4,r5,2" | |
30441 | +func_check 0xc8 "divwe r10,r11,r12" | |
30442 | +func_check 0xcc "divwe. r11,r12,r13" | |
30443 | +func_check 0xd0 "divweo r12,r13,r14" | |
30444 | +func_check 0xd4 "divweo. r13,r14,r15" | |
30445 | +func_check 0xd8 "divweu r10,r11,r12" | |
30446 | +func_check 0xdc "divweu. r11,r12,r13" | |
30447 | +func_check 0xe0 "divweuo r12,r13,r14" | |
30448 | +func_check 0xe4 "divweuo. r13,r14,r15" | |
30449 | +func_check 0xe8 "bpermd r7,r17,r27" | |
30450 | +func_check 0xec "popcntw r10,r20" | |
30451 | +func_check 0xf0 "popcntd r10,r20" | |
30452 | +func_check 0xf4 "ldbrx r20,r21,r22" | |
30453 | +func_check 0xf8 "stdbrx r20,r21,r22" | |
30454 | +func_check 0xfc "lfiwzx f10,0,r10" | |
30455 | +func_check 0x100 "lfiwzx f10,r9,r10" | |
30456 | +func_check 0x104 "fcfids f4,f5" | |
30457 | +func_check 0x108 "fcfids. f4,f5" | |
30458 | +func_check 0x10c "fcfidus f4,f5" | |
30459 | +func_check 0x110 "fcfidus. f4,f5" | |
30460 | +func_check 0x114 "fctiwu f4,f5" | |
30461 | +func_check 0x118 "fctiwu. f4,f5" | |
30462 | +func_check 0x11c "fctiwuz f4,f5" | |
30463 | +func_check 0x120 "fctiwuz. f4,f5" | |
30464 | +func_check 0x124 "fctidu f4,f5" | |
30465 | +func_check 0x128 "fctidu. f4,f5" | |
30466 | +func_check 0x12c "fctiduz f4,f5" | |
30467 | +func_check 0x130 "fctiduz. f4,f5" | |
30468 | +func_check 0x134 "fcfidu f4,f5" | |
30469 | +func_check 0x138 "fcfidu. f4,f5" | |
30470 | +func_check 0x13c "ftdiv cr0,f10,f11" | |
30471 | +func_check 0x140 "ftdiv cr7,f10,f11" | |
30472 | +func_check 0x144 "ftsqrt cr0,f10" | |
30473 | +func_check 0x148 "ftsqrt cr7,f10" | |
30474 | +func_check 0x14c "dcbtt r8,r9" | |
30475 | +func_check 0x150 "dcbtstt r8,r9" | |
30476 | +func_check 0x154 "dcffix f10,f12" | |
30477 | +func_check 0x158 "dcffix. f20,f22" | |
30478 | +func_check 0x15c "lbarx r10,r11,r12" | |
30479 | +func_check 0x160 "lbarx r10,r11,r12" | |
30480 | +func_check 0x164 "lbarx r10,r11,r12,1" | |
30481 | +func_check 0x168 "lharx r20,r21,r22" | |
30482 | +func_check 0x16c "lharx r20,r21,r22" | |
30483 | +func_check 0x170 "lharx r20,r21,r22,1" | |
30484 | +func_check 0x174 "stbcx. r10,r11,r12" | |
30485 | +func_check 0x178 "sthcx. r10,r11,r12" | |
30486 | +func_check 0x17c "fre f14,f15" | |
30487 | +func_check 0x180 "fre. f14,f15" | |
30488 | +func_check 0x184 "fres f14,f15" | |
30489 | +func_check 0x188 "fres. f14,f15" | |
30490 | +func_check 0x18c "frsqrte f14,f15" | |
30491 | +func_check 0x190 "frsqrte. f14,f15" | |
30492 | +func_check 0x194 "frsqrtes f14,f15" | |
30493 | +func_check 0x198 "frsqrtes. f14,f15" | |
30494 | +func_check 0x19c "isel r2,r3,r4,28" | |
30495 | diff --git a/gdb/testsuite/gdb.arch/powerpc-power7.s b/gdb/testsuite/gdb.arch/powerpc-power7.s | |
30496 | new file mode 100644 | |
30497 | index 0000000..98b2e79 | |
30498 | --- /dev/null | |
30499 | +++ b/gdb/testsuite/gdb.arch/powerpc-power7.s | |
30500 | @@ -0,0 +1,107 @@ | |
30501 | + .text | |
30502 | + .globl func | |
30503 | +func: | |
30504 | + .long 0x7c642e98 /* 0: lxvd2x vs3,r4,r5 */ | |
30505 | + .long 0x7c642ed8 /* 4: lxvd2ux vs3,r4,r5 */ | |
30506 | + .long 0x7d642e99 /* 8: lxvd2x vs43,r4,r5 */ | |
30507 | + .long 0x7d642ed9 /* c: lxvd2ux vs43,r4,r5 */ | |
30508 | + .long 0x7c642f98 /* 10: stxvd2x vs3,r4,r5 */ | |
30509 | + .long 0x7c642fd8 /* 14: stxvd2ux vs3,r4,r5 */ | |
30510 | + .long 0x7d642f99 /* 18: stxvd2x vs43,r4,r5 */ | |
30511 | + .long 0x7d642fd9 /* 1c: stxvd2ux vs43,r4,r5 */ | |
30512 | + .long 0xf0642850 /* 20: xxmrghd vs3,vs4,vs5 */ | |
30513 | + .long 0xf16c6857 /* 24: xxmrghd vs43,vs44,vs45 */ | |
30514 | + .long 0xf0642b50 /* 28: xxmrgld vs3,vs4,vs5 */ | |
30515 | + .long 0xf16c6b57 /* 2c: xxmrgld vs43,vs44,vs45 */ | |
30516 | + .long 0xf0642850 /* 30: xxmrghd vs3,vs4,vs5 */ | |
30517 | + .long 0xf16c6857 /* 34: xxmrghd vs43,vs44,vs45 */ | |
30518 | + .long 0xf0642b50 /* 38: xxmrgld vs3,vs4,vs5 */ | |
30519 | + .long 0xf16c6b57 /* 3c: xxmrgld vs43,vs44,vs45 */ | |
30520 | + .long 0xf0642950 /* 40: xxpermdi vs3,vs4,vs5,1 */ | |
30521 | + .long 0xf16c6957 /* 44: xxpermdi vs43,vs44,vs45,1 */ | |
30522 | + .long 0xf0642a50 /* 48: xxpermdi vs3,vs4,vs5,2 */ | |
30523 | + .long 0xf16c6a57 /* 4c: xxpermdi vs43,vs44,vs45,2 */ | |
30524 | + .long 0xf0642780 /* 50: xvmovdp vs3,vs4 */ | |
30525 | + .long 0xf16c6787 /* 54: xvmovdp vs43,vs44 */ | |
30526 | + .long 0xf0642780 /* 58: xvmovdp vs3,vs4 */ | |
30527 | + .long 0xf16c6787 /* 5c: xvmovdp vs43,vs44 */ | |
30528 | + .long 0xf0642f80 /* 60: xvcpsgndp vs3,vs4,vs5 */ | |
30529 | + .long 0xf16c6f87 /* 64: xvcpsgndp vs43,vs44,vs45 */ | |
30530 | + .long 0x7c00007c /* 68: wait */ | |
30531 | + .long 0x7c00007c /* 6c: wait */ | |
30532 | + .long 0x7c20007c /* 70: waitrsv */ | |
30533 | + .long 0x7c20007c /* 74: waitrsv */ | |
30534 | + .long 0x7c40007c /* 78: waitimpl */ | |
30535 | + .long 0x7c40007c /* 7c: waitimpl */ | |
30536 | + .long 0x4c000324 /* 80: doze */ | |
30537 | + .long 0x4c000364 /* 84: nap */ | |
30538 | + .long 0x4c0003a4 /* 88: sleep */ | |
30539 | + .long 0x4c0003e4 /* 8c: rvwinkle */ | |
30540 | + .long 0x7c830134 /* 90: prtyw r3,r4 */ | |
30541 | + .long 0x7dcd0174 /* 94: prtyd r13,r14 */ | |
30542 | + .long 0x7d5c02a6 /* 98: mfcfar r10 */ | |
30543 | + .long 0x7d7c03a6 /* 9c: mtcfar r11 */ | |
30544 | + .long 0x7c832bf8 /* a0: cmpb r3,r4,r5 */ | |
30545 | + .long 0x7d4b662a /* a4: lwzcix r10,r11,r12 */ | |
30546 | + .long 0xee119004 /* a8: dadd f16,f17,f18 */ | |
30547 | + .long 0xfe96c004 /* ac: daddq f20,f22,f24 */ | |
30548 | + .long 0x7c60066c /* b0: dss 3 */ | |
30549 | + .long 0x7e00066c /* b4: dssall */ | |
30550 | + .long 0x7c2522ac /* b8: dst r5,r4,1 */ | |
30551 | + .long 0x7e083aac /* bc: dstt r8,r7,0 */ | |
30552 | + .long 0x7c6532ec /* c0: dstst r5,r6,3 */ | |
30553 | + .long 0x7e442aec /* c4: dststt r4,r5,2 */ | |
30554 | + .long 0x7d4b6356 /* c8: divwe r10,r11,r12 */ | |
30555 | + .long 0x7d6c6b57 /* cc: divwe. r11,r12,r13 */ | |
30556 | + .long 0x7d8d7756 /* d0: divweo r12,r13,r14 */ | |
30557 | + .long 0x7dae7f57 /* d4: divweo. r13,r14,r15 */ | |
30558 | + .long 0x7d4b6316 /* d8: divweu r10,r11,r12 */ | |
30559 | + .long 0x7d6c6b17 /* dc: divweu. r11,r12,r13 */ | |
30560 | + .long 0x7d8d7716 /* e0: divweuo r12,r13,r14 */ | |
30561 | + .long 0x7dae7f17 /* e4: divweuo. r13,r14,r15 */ | |
30562 | + .long 0x7e27d9f8 /* e8: bpermd r7,r17,r27 */ | |
30563 | + .long 0x7e8a02f4 /* ec: popcntw r10,r20 */ | |
30564 | + .long 0x7e8a03f4 /* f0: popcntd r10,r20 */ | |
30565 | + .long 0x7e95b428 /* f4: ldbrx r20,r21,r22 */ | |
30566 | + .long 0x7e95b528 /* f8: stdbrx r20,r21,r22 */ | |
30567 | + .long 0x7d4056ee /* fc: lfiwzx f10,0,r10 */ | |
30568 | + .long 0x7d4956ee /* 100: lfiwzx f10,r9,r10 */ | |
30569 | + .long 0xec802e9c /* 104: fcfids f4,f5 */ | |
30570 | + .long 0xec802e9d /* 108: fcfids. f4,f5 */ | |
30571 | + .long 0xec802f9c /* 10c: fcfidus f4,f5 */ | |
30572 | + .long 0xec802f9d /* 110: fcfidus. f4,f5 */ | |
30573 | + .long 0xfc80291c /* 114: fctiwu f4,f5 */ | |
30574 | + .long 0xfc80291d /* 118: fctiwu. f4,f5 */ | |
30575 | + .long 0xfc80291e /* 11c: fctiwuz f4,f5 */ | |
30576 | + .long 0xfc80291f /* 120: fctiwuz. f4,f5 */ | |
30577 | + .long 0xfc802f5c /* 124: fctidu f4,f5 */ | |
30578 | + .long 0xfc802f5d /* 128: fctidu. f4,f5 */ | |
30579 | + .long 0xfc802f5e /* 12c: fctiduz f4,f5 */ | |
30580 | + .long 0xfc802f5f /* 130: fctiduz. f4,f5 */ | |
30581 | + .long 0xfc802f9c /* 134: fcfidu f4,f5 */ | |
30582 | + .long 0xfc802f9d /* 138: fcfidu. f4,f5 */ | |
30583 | + .long 0xfc0a5900 /* 13c: ftdiv cr0,f10,f11 */ | |
30584 | + .long 0xff8a5900 /* 140: ftdiv cr7,f10,f11 */ | |
30585 | + .long 0xfc005140 /* 144: ftsqrt cr0,f10 */ | |
30586 | + .long 0xff805140 /* 148: ftsqrt cr7,f10 */ | |
30587 | + .long 0x7e084a2c /* 14c: dcbtt r8,r9 */ | |
30588 | + .long 0x7e0849ec /* 150: dcbtstt r8,r9 */ | |
30589 | + .long 0xed406644 /* 154: dcffix f10,f12 */ | |
30590 | + .long 0xee80b645 /* 158: dcffix. f20,f22 */ | |
30591 | + .long 0x7d4b6068 /* 15c: lbarx r10,r11,r12 */ | |
30592 | + .long 0x7d4b6068 /* 160: lbarx r10,r11,r12 */ | |
30593 | + .long 0x7d4b6069 /* 164: lbarx r10,r11,r12,1 */ | |
30594 | + .long 0x7e95b0e8 /* 168: lharx r20,r21,r22 */ | |
30595 | + .long 0x7e95b0e8 /* 16c: lharx r20,r21,r22 */ | |
30596 | + .long 0x7e95b0e9 /* 170: lharx r20,r21,r22,1 */ | |
30597 | + .long 0x7d4b656d /* 174: stbcx. r10,r11,r12 */ | |
30598 | + .long 0x7d4b65ad /* 178: sthcx. r10,r11,r12 */ | |
30599 | + .long 0xfdc07830 /* 17c: fre f14,f15 */ | |
30600 | + .long 0xfdc07831 /* 180: fre. f14,f15 */ | |
30601 | + .long 0xedc07830 /* 184: fres f14,f15 */ | |
30602 | + .long 0xedc07831 /* 188: fres. f14,f15 */ | |
30603 | + .long 0xfdc07834 /* 18c: frsqrte f14,f15 */ | |
30604 | + .long 0xfdc07835 /* 190: frsqrte. f14,f15 */ | |
30605 | + .long 0xedc07834 /* 194: frsqrtes f14,f15 */ | |
30606 | + .long 0xedc07835 /* 198: frsqrtes. f14,f15 */ | |
30607 | + .long 0x7c43271e /* 19c: isel r2,r3,r4,28 */ | |
30608 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S | |
30609 | new file mode 100644 | |
30610 | index 0000000..66f7a39 | |
30611 | --- /dev/null | |
30612 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S | |
30613 | @@ -0,0 +1,455 @@ | |
30614 | + .file "x86_64-vla-typedef.c" | |
30615 | + .section .debug_abbrev,"",@progbits | |
30616 | +.Ldebug_abbrev0: | |
30617 | + .section .debug_info,"",@progbits | |
30618 | +.Ldebug_info0: | |
30619 | + .section .debug_line,"",@progbits | |
30620 | +.Ldebug_line0: | |
30621 | + .text | |
30622 | +.Ltext0: | |
30623 | +.globl foo | |
30624 | + .type foo, @function | |
30625 | +foo: | |
30626 | +.LFB2: | |
30627 | + .file 1 "x86_64-vla-typedef.c" | |
30628 | + .loc 1 22 0 | |
30629 | + pushq %rbp | |
30630 | +.LCFI0: | |
30631 | + movq %rsp, %rbp | |
30632 | +.LCFI1: | |
30633 | + subq $64, %rsp | |
30634 | +.LCFI2: | |
30635 | + movl %edi, -36(%rbp) | |
30636 | + .loc 1 22 0 | |
30637 | + movq %rsp, %rax | |
30638 | + movq %rax, -48(%rbp) | |
30639 | + .loc 1 23 0 | |
30640 | + movl -36(%rbp), %edx | |
30641 | + movslq %edx,%rax | |
30642 | + subq $1, %rax | |
30643 | + movq %rax, -24(%rbp) | |
30644 | + .loc 1 24 0 | |
30645 | + movslq %edx,%rax | |
30646 | + addq $15, %rax | |
30647 | + addq $15, %rax | |
30648 | + shrq $4, %rax | |
30649 | + salq $4, %rax | |
30650 | + subq %rax, %rsp | |
30651 | + movq %rsp, -56(%rbp) | |
30652 | + movq -56(%rbp), %rax | |
30653 | + addq $15, %rax | |
30654 | + shrq $4, %rax | |
30655 | + salq $4, %rax | |
30656 | + movq %rax, -56(%rbp) | |
30657 | + movq -56(%rbp), %rax | |
30658 | + movq %rax, -16(%rbp) | |
30659 | + .loc 1 27 0 | |
30660 | + movl $0, -4(%rbp) | |
30661 | + jmp .L2 | |
30662 | +.L3: | |
30663 | + .loc 1 28 0 | |
30664 | + movl -4(%rbp), %esi | |
30665 | + movl -4(%rbp), %eax | |
30666 | + movl %eax, %ecx | |
30667 | + movq -16(%rbp), %rdx | |
30668 | + movslq %esi,%rax | |
30669 | + movb %cl, (%rdx,%rax) | |
30670 | + .loc 1 27 0 | |
30671 | + addl $1, -4(%rbp) | |
30672 | +.L2: | |
30673 | + movl -4(%rbp), %eax | |
30674 | + cmpl -36(%rbp), %eax | |
30675 | + jl .L3 | |
30676 | + .loc 1 30 0 | |
30677 | + .globl break_here | |
30678 | +break_here: | |
30679 | + movq -16(%rbp), %rax | |
30680 | + movb $0, (%rax) | |
30681 | + movq -48(%rbp), %rsp | |
30682 | + .loc 1 31 0 | |
30683 | + leave | |
30684 | + ret | |
30685 | +.LFE2: | |
30686 | + .size foo, .-foo | |
30687 | + .section .debug_frame,"",@progbits | |
30688 | +.Lframe0: | |
30689 | + .long .LECIE0-.LSCIE0 | |
30690 | +.LSCIE0: | |
30691 | + .long 0xffffffff | |
30692 | + .byte 0x1 | |
30693 | + .string "" | |
30694 | + .uleb128 0x1 | |
30695 | + .sleb128 -8 | |
30696 | + .byte 0x10 | |
30697 | + .byte 0xc | |
30698 | + .uleb128 0x7 | |
30699 | + .uleb128 0x8 | |
30700 | + .byte 0x90 | |
30701 | + .uleb128 0x1 | |
30702 | + .align 8 | |
30703 | +.LECIE0: | |
30704 | +.LSFDE0: | |
30705 | + .long .LEFDE0-.LASFDE0 | |
30706 | +.LASFDE0: | |
30707 | + .long .Lframe0 | |
30708 | + .quad .LFB2 | |
30709 | + .quad .LFE2-.LFB2 | |
30710 | + .byte 0x4 | |
30711 | + .long .LCFI0-.LFB2 | |
30712 | + .byte 0xe | |
30713 | + .uleb128 0x10 | |
30714 | + .byte 0x86 | |
30715 | + .uleb128 0x2 | |
30716 | + .byte 0x4 | |
30717 | + .long .LCFI1-.LCFI0 | |
30718 | + .byte 0xd | |
30719 | + .uleb128 0x6 | |
30720 | + .align 8 | |
30721 | +.LEFDE0: | |
30722 | + .section .eh_frame,"a",@progbits | |
30723 | +.Lframe1: | |
30724 | + .long .LECIE1-.LSCIE1 | |
30725 | +.LSCIE1: | |
30726 | + .long 0x0 | |
30727 | + .byte 0x1 | |
30728 | + .string "zR" | |
30729 | + .uleb128 0x1 | |
30730 | + .sleb128 -8 | |
30731 | + .byte 0x10 | |
30732 | + .uleb128 0x1 | |
30733 | + .byte 0x3 | |
30734 | + .byte 0xc | |
30735 | + .uleb128 0x7 | |
30736 | + .uleb128 0x8 | |
30737 | + .byte 0x90 | |
30738 | + .uleb128 0x1 | |
30739 | + .align 8 | |
30740 | +.LECIE1: | |
30741 | +.LSFDE1: | |
30742 | + .long .LEFDE1-.LASFDE1 | |
30743 | +.LASFDE1: | |
30744 | + .long .LASFDE1-.Lframe1 | |
30745 | + .long .LFB2 | |
30746 | + .long .LFE2-.LFB2 | |
30747 | + .uleb128 0x0 | |
30748 | + .byte 0x4 | |
30749 | + .long .LCFI0-.LFB2 | |
30750 | + .byte 0xe | |
30751 | + .uleb128 0x10 | |
30752 | + .byte 0x86 | |
30753 | + .uleb128 0x2 | |
30754 | + .byte 0x4 | |
30755 | + .long .LCFI1-.LCFI0 | |
30756 | + .byte 0xd | |
30757 | + .uleb128 0x6 | |
30758 | + .align 8 | |
30759 | +.LEFDE1: | |
30760 | + .text | |
30761 | +.Letext0: | |
30762 | + .section .debug_loc,"",@progbits | |
30763 | +.Ldebug_loc0: | |
30764 | +.LLST0: | |
30765 | + .quad .LFB2-.Ltext0 | |
30766 | + .quad .LCFI0-.Ltext0 | |
30767 | + .value 0x2 | |
30768 | + .byte 0x77 | |
30769 | + .sleb128 8 | |
30770 | + .quad .LCFI0-.Ltext0 | |
30771 | + .quad .LCFI1-.Ltext0 | |
30772 | + .value 0x2 | |
30773 | + .byte 0x77 | |
30774 | + .sleb128 16 | |
30775 | + .quad .LCFI1-.Ltext0 | |
30776 | + .quad .LFE2-.Ltext0 | |
30777 | + .value 0x2 | |
30778 | + .byte 0x76 | |
30779 | + .sleb128 16 | |
30780 | + .quad 0x0 | |
30781 | + .quad 0x0 | |
30782 | + .section .debug_info | |
30783 | + .long .Ldebug_end - .Ldebug_start | |
30784 | +.Ldebug_start: | |
30785 | + .value 0x2 | |
30786 | + .long .Ldebug_abbrev0 | |
30787 | + .byte 0x8 | |
30788 | + .uleb128 0x1 | |
30789 | + .long .LASF2 | |
30790 | + .byte 0x1 | |
30791 | + .long .LASF3 | |
30792 | + .long .LASF4 | |
30793 | + .quad .Ltext0 | |
30794 | + .quad .Letext0 | |
30795 | + .long .Ldebug_line0 | |
30796 | + .uleb128 0x2 | |
30797 | + .byte 0x1 | |
30798 | + .string "foo" | |
30799 | + .byte 0x1 | |
30800 | + .byte 0x16 | |
30801 | + .byte 0x1 | |
30802 | + .quad .LFB2 | |
30803 | + .quad .LFE2 | |
30804 | + .long .LLST0 | |
30805 | + .long 0x83 | |
30806 | + .uleb128 0x3 | |
30807 | + .long .LASF5 | |
30808 | + .byte 0x1 | |
30809 | + .byte 0x15 | |
30810 | + .long 0x83 | |
30811 | + .byte 0x2 | |
30812 | + .byte 0x91 | |
30813 | + .sleb128 -52 | |
30814 | +.Ltag_typedef: | |
30815 | + .uleb128 0x4 | |
30816 | + .long .LASF6 | |
30817 | + .byte 0x1 | |
30818 | + .byte 0x17 | |
30819 | + .long .Ltag_array_type - .debug_info | |
30820 | + .uleb128 0x5 /* Abbrev Number: 5 (DW_TAG_variable) */ | |
30821 | + .long .LASF0 | |
30822 | + .byte 0x1 | |
30823 | + .byte 0x18 | |
30824 | +#if 1 | |
30825 | + .long .Ltag_typedef - .debug_info | |
30826 | +#else | |
30827 | + /* Debugging only: Skip the typedef indirection. */ | |
30828 | + .long .Ltag_array_type - .debug_info | |
30829 | +#endif | |
30830 | + /* DW_AT_location: DW_FORM_block1: start */ | |
30831 | + .byte 0x3 | |
30832 | + .byte 0x91 | |
30833 | + .sleb128 -32 | |
30834 | +#if 0 | |
30835 | + .byte 0x6 /* DW_OP_deref */ | |
30836 | +#else | |
30837 | + .byte 0x96 /* DW_OP_nop */ | |
30838 | +#endif | |
30839 | + /* DW_AT_location: DW_FORM_block1: end */ | |
30840 | + .uleb128 0x6 | |
30841 | + .string "i" | |
30842 | + .byte 0x1 | |
30843 | + .byte 0x19 | |
30844 | + .long 0x83 | |
30845 | + .byte 0x2 | |
30846 | + .byte 0x91 | |
30847 | + .sleb128 -20 | |
30848 | + .byte 0x0 | |
30849 | + .uleb128 0x7 | |
30850 | + .byte 0x4 | |
30851 | + .byte 0x5 | |
30852 | + .string "int" | |
30853 | +.Ltag_array_type: | |
30854 | + .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */ | |
30855 | + .long 0xa0 + (2f - 1f) /* DW_AT_type: DW_FORM_ref4 */ | |
30856 | + .long 0x9d + (2f - 1f) /* DW_AT_sibling: DW_FORM_ref4 */ | |
30857 | +1: /* DW_AT_data_location: DW_FORM_block1: start */ | |
30858 | + .byte 2f - 3f /* length */ | |
30859 | +3: | |
30860 | + .byte 0x97 /* DW_OP_push_object_address */ | |
30861 | + .byte 0x6 /* DW_OP_deref */ | |
30862 | +2: /* DW_AT_data_location: DW_FORM_block1: end */ | |
30863 | + .uleb128 0x9 | |
30864 | + .long 0x9d + (2b - 1b) /* DW_AT_type: DW_FORM_ref4 */ | |
30865 | + .byte 0x3 | |
30866 | + .byte 0x91 | |
30867 | + .sleb128 -40 | |
30868 | + .byte 0x6 | |
30869 | + .byte 0x0 | |
30870 | + .uleb128 0xa | |
30871 | + .byte 0x8 | |
30872 | + .byte 0x7 | |
30873 | + .uleb128 0xb | |
30874 | + .byte 0x1 | |
30875 | + .byte 0x6 | |
30876 | + .long .LASF1 | |
30877 | + .byte 0x0 | |
30878 | +.Ldebug_end: | |
30879 | + .section .debug_abbrev | |
30880 | + .uleb128 0x1 | |
30881 | + .uleb128 0x11 | |
30882 | + .byte 0x1 | |
30883 | + .uleb128 0x25 | |
30884 | + .uleb128 0xe | |
30885 | + .uleb128 0x13 | |
30886 | + .uleb128 0xb | |
30887 | + .uleb128 0x3 | |
30888 | + .uleb128 0xe | |
30889 | + .uleb128 0x1b | |
30890 | + .uleb128 0xe | |
30891 | + .uleb128 0x11 | |
30892 | + .uleb128 0x1 | |
30893 | + .uleb128 0x12 | |
30894 | + .uleb128 0x1 | |
30895 | + .uleb128 0x10 | |
30896 | + .uleb128 0x6 | |
30897 | + .byte 0x0 | |
30898 | + .byte 0x0 | |
30899 | + .uleb128 0x2 | |
30900 | + .uleb128 0x2e | |
30901 | + .byte 0x1 | |
30902 | + .uleb128 0x3f | |
30903 | + .uleb128 0xc | |
30904 | + .uleb128 0x3 | |
30905 | + .uleb128 0x8 | |
30906 | + .uleb128 0x3a | |
30907 | + .uleb128 0xb | |
30908 | + .uleb128 0x3b | |
30909 | + .uleb128 0xb | |
30910 | + .uleb128 0x27 | |
30911 | + .uleb128 0xc | |
30912 | + .uleb128 0x11 | |
30913 | + .uleb128 0x1 | |
30914 | + .uleb128 0x12 | |
30915 | + .uleb128 0x1 | |
30916 | + .uleb128 0x40 | |
30917 | + .uleb128 0x6 | |
30918 | + .uleb128 0x1 | |
30919 | + .uleb128 0x13 | |
30920 | + .byte 0x0 | |
30921 | + .byte 0x0 | |
30922 | + .uleb128 0x3 | |
30923 | + .uleb128 0x5 | |
30924 | + .byte 0x0 | |
30925 | + .uleb128 0x3 | |
30926 | + .uleb128 0xe | |
30927 | + .uleb128 0x3a | |
30928 | + .uleb128 0xb | |
30929 | + .uleb128 0x3b | |
30930 | + .uleb128 0xb | |
30931 | + .uleb128 0x49 | |
30932 | + .uleb128 0x13 | |
30933 | + .uleb128 0x2 | |
30934 | + .uleb128 0xa | |
30935 | + .byte 0x0 | |
30936 | + .byte 0x0 | |
30937 | + .uleb128 0x4 | |
30938 | + .uleb128 0x16 | |
30939 | + .byte 0x0 | |
30940 | + .uleb128 0x3 | |
30941 | + .uleb128 0xe | |
30942 | + .uleb128 0x3a | |
30943 | + .uleb128 0xb | |
30944 | + .uleb128 0x3b | |
30945 | + .uleb128 0xb | |
30946 | + .uleb128 0x49 | |
30947 | + .uleb128 0x13 | |
30948 | + .byte 0x0 | |
30949 | + .byte 0x0 | |
30950 | + .uleb128 0x5 | |
30951 | + .uleb128 0x34 | |
30952 | + .byte 0x0 | |
30953 | + .uleb128 0x3 | |
30954 | + .uleb128 0xe | |
30955 | + .uleb128 0x3a | |
30956 | + .uleb128 0xb | |
30957 | + .uleb128 0x3b | |
30958 | + .uleb128 0xb | |
30959 | + .uleb128 0x49 | |
30960 | + .uleb128 0x13 | |
30961 | + .uleb128 0x2 | |
30962 | + .uleb128 0xa | |
30963 | + .byte 0x0 | |
30964 | + .byte 0x0 | |
30965 | + .uleb128 0x6 | |
30966 | + .uleb128 0x34 | |
30967 | + .byte 0x0 | |
30968 | + .uleb128 0x3 | |
30969 | + .uleb128 0x8 | |
30970 | + .uleb128 0x3a | |
30971 | + .uleb128 0xb | |
30972 | + .uleb128 0x3b | |
30973 | + .uleb128 0xb | |
30974 | + .uleb128 0x49 | |
30975 | + .uleb128 0x13 | |
30976 | + .uleb128 0x2 | |
30977 | + .uleb128 0xa | |
30978 | + .byte 0x0 | |
30979 | + .byte 0x0 | |
30980 | + .uleb128 0x7 | |
30981 | + .uleb128 0x24 | |
30982 | + .byte 0x0 | |
30983 | + .uleb128 0xb | |
30984 | + .uleb128 0xb | |
30985 | + .uleb128 0x3e | |
30986 | + .uleb128 0xb | |
30987 | + .uleb128 0x3 | |
30988 | + .uleb128 0x8 | |
30989 | + .byte 0x0 | |
30990 | + .byte 0x0 | |
30991 | + .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */ | |
30992 | + .uleb128 0x1 | |
30993 | + .byte 0x1 | |
30994 | + .uleb128 0x49 /* DW_AT_type */ | |
30995 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
30996 | + .uleb128 0x1 /* DW_AT_sibling */ | |
30997 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
30998 | + .uleb128 0x50 /* DW_AT_data_location */ | |
30999 | + .uleb128 0xa /* DW_FORM_block1 */ | |
31000 | + .byte 0x0 | |
31001 | + .byte 0x0 | |
31002 | + .uleb128 0x9 | |
31003 | + .uleb128 0x21 | |
31004 | + .byte 0x0 | |
31005 | + .uleb128 0x49 /* DW_AT_type */ | |
31006 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
31007 | + .uleb128 0x2f | |
31008 | + .uleb128 0xa | |
31009 | + .byte 0x0 | |
31010 | + .byte 0x0 | |
31011 | + .uleb128 0xa | |
31012 | + .uleb128 0x24 | |
31013 | + .byte 0x0 | |
31014 | + .uleb128 0xb | |
31015 | + .uleb128 0xb | |
31016 | + .uleb128 0x3e | |
31017 | + .uleb128 0xb | |
31018 | + .byte 0x0 | |
31019 | + .byte 0x0 | |
31020 | + .uleb128 0xb | |
31021 | + .uleb128 0x24 | |
31022 | + .byte 0x0 | |
31023 | + .uleb128 0xb | |
31024 | + .uleb128 0xb | |
31025 | + .uleb128 0x3e | |
31026 | + .uleb128 0xb | |
31027 | + .uleb128 0x3 | |
31028 | + .uleb128 0xe | |
31029 | + .byte 0x0 | |
31030 | + .byte 0x0 | |
31031 | + .byte 0x0 | |
31032 | + .section .debug_pubnames,"",@progbits | |
31033 | + .long 0x16 | |
31034 | + .value 0x2 | |
31035 | + .long .Ldebug_info0 | |
31036 | + .long 0xa8 | |
31037 | + .long 0x2d | |
31038 | + .string "foo" | |
31039 | + .long 0x0 | |
31040 | + .section .debug_aranges,"",@progbits | |
31041 | + .long 0x2c | |
31042 | + .value 0x2 | |
31043 | + .long .Ldebug_info0 | |
31044 | + .byte 0x8 | |
31045 | + .byte 0x0 | |
31046 | + .value 0x0 | |
31047 | + .value 0x0 | |
31048 | + .quad .Ltext0 | |
31049 | + .quad .Letext0-.Ltext0 | |
31050 | + .quad 0x0 | |
31051 | + .quad 0x0 | |
31052 | + .section .debug_str,"MS",@progbits,1 | |
31053 | +.LASF0: | |
31054 | + .string "array" | |
31055 | +.LASF5: | |
31056 | + .string "size" | |
31057 | +.LASF3: | |
31058 | + .string "x86_64-vla-typedef.c" | |
31059 | +.LASF6: | |
31060 | + .string "array_t" | |
31061 | +.LASF1: | |
31062 | + .string "char" | |
31063 | +.LASF4: | |
31064 | + .string "gdb.arch" | |
31065 | +.LASF2: | |
31066 | + .string "GNU C 4.3.2 20081105 (Red Hat 4.3.2-7)" | |
31067 | + .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)" | |
31068 | + .section .note.GNU-stack,"",@progbits | |
31069 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c | |
31070 | new file mode 100644 | |
31071 | index 0000000..b809c4e | |
31072 | --- /dev/null | |
31073 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c | |
31074 | @@ -0,0 +1,43 @@ | |
31075 | +/* This testcase is part of GDB, the GNU debugger. | |
31076 | + | |
31077 | + Copyright 2008 Free Software Foundation, Inc. | |
31078 | + | |
31079 | + This program is free software; you can redistribute it and/or modify | |
31080 | + it under the terms of the GNU General Public License as published by | |
31081 | + the Free Software Foundation; either version 3 of the License, or | |
31082 | + (at your option) any later version. | |
31083 | + | |
31084 | + This program is distributed in the hope that it will be useful, | |
31085 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31086 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
31087 | + GNU General Public License for more details. | |
31088 | + | |
31089 | + You should have received a copy of the GNU General Public License | |
31090 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
31091 | + | |
31092 | +#if 0 | |
31093 | + | |
31094 | +void | |
31095 | +foo (int size) | |
31096 | +{ | |
31097 | + typedef char array_t[size]; | |
31098 | + array_t array; | |
31099 | + int i; | |
31100 | + | |
31101 | + for (i = 0; i < size; i++) | |
31102 | + array[i] = i; | |
31103 | + | |
31104 | + array[0] = 0; /* break-here */ | |
31105 | +} | |
31106 | + | |
31107 | +#else | |
31108 | + | |
31109 | +int | |
31110 | +main (void) | |
31111 | +{ | |
31112 | + foo (26); | |
31113 | + foo (78); | |
31114 | + return 0; | |
31115 | +} | |
31116 | + | |
31117 | +#endif | |
31118 | diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp | |
31119 | new file mode 100644 | |
31120 | index 0000000..534120a | |
31121 | --- /dev/null | |
31122 | +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp | |
31123 | @@ -0,0 +1,64 @@ | |
31124 | +# Copyright 2009 Free Software Foundation, Inc. | |
31125 | + | |
31126 | +# This program is free software; you can redistribute it and/or modify | |
31127 | +# it under the terms of the GNU General Public License as published by | |
31128 | +# the Free Software Foundation; either version 3 of the License, or | |
31129 | +# (at your option) any later version. | |
31130 | +# | |
31131 | +# This program is distributed in the hope that it will be useful, | |
31132 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31133 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
31134 | +# GNU General Public License for more details. | |
31135 | +# | |
31136 | +# You should have received a copy of the GNU General Public License | |
31137 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31138 | + | |
31139 | +# Test DW_AT_data_location accessed through DW_TAG_typedef intermediate. | |
31140 | + | |
31141 | +if ![istarget "x86_64-*-*"] then { | |
31142 | + verbose "Skipping over gdb.arch/x86_64-vla-typedef.exp test made only for x86_64." | |
31143 | + return | |
31144 | +} | |
31145 | + | |
31146 | +set testfile x86_64-vla-typedef | |
31147 | +set srcasmfile ${testfile}-foo.S | |
31148 | +set srcfile ${testfile}.c | |
31149 | +set binfile ${objdir}/${subdir}/${testfile} | |
31150 | +set binobjfile ${objdir}/${subdir}/${testfile}-foo.o | |
31151 | +if { [gdb_compile "${srcdir}/${subdir}/${srcasmfile}" "${binobjfile}" object {}] != "" } { | |
31152 | + untested "Couldn't compile test program" | |
31153 | + return -1 | |
31154 | +} | |
31155 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${binobjfile}" "${binfile}" executable {debug}] != "" } { | |
31156 | + untested "Couldn't compile test program" | |
31157 | + return -1 | |
31158 | +} | |
31159 | + | |
31160 | +gdb_exit | |
31161 | +gdb_start | |
31162 | +gdb_reinitialize_dir $srcdir/$subdir | |
31163 | +gdb_load ${binfile} | |
31164 | + | |
31165 | +if ![runto_main] { | |
31166 | + untested x86_64-vla-typedef | |
31167 | + return -1 | |
31168 | +} | |
31169 | + | |
31170 | +gdb_breakpoint "break_here" | |
31171 | + | |
31172 | +gdb_continue_to_breakpoint "break_here" | |
31173 | + | |
31174 | +gdb_test "whatis array" "type = array_t" "first: whatis array" | |
31175 | + | |
31176 | +gdb_test "ptype array" "type = char \\\[26\\\]" "first: ptype array" | |
31177 | + | |
31178 | +gdb_test "p array\[1\]" "\\$\[0-9\] = 1 '\\\\1'" | |
31179 | +gdb_test "p array\[2\]" "\\$\[0-9\] = 2 '\\\\2'" | |
31180 | +gdb_test "p array\[3\]" "\\$\[0-9\] = 3 '\\\\3'" | |
31181 | +gdb_test "p array\[4\]" "\\$\[0-9\] = 4 '\\\\4'" | |
31182 | + | |
31183 | +gdb_continue_to_breakpoint "break_here" | |
31184 | + | |
31185 | +gdb_test "whatis array" "type = array_t" "second: whatis array" | |
31186 | + | |
31187 | +gdb_test "ptype array" "type = char \\\[78\\\]" "second: ptype array" | |
31188 | diff --git a/gdb/testsuite/gdb.base/Makefile.in b/gdb/testsuite/gdb.base/Makefile.in | |
31189 | index 9f382db..12db521 100644 | |
31190 | --- a/gdb/testsuite/gdb.base/Makefile.in | |
31191 | +++ b/gdb/testsuite/gdb.base/Makefile.in | |
31192 | @@ -12,7 +12,7 @@ EXECUTABLES = all-types annota1 bitfields break \ | |
31193 | scope section_command setshow setvar shmain sigall signals \ | |
31194 | solib solib_sl so-impl-ld so-indr-cl \ | |
31195 | step-line step-test structs structs2 \ | |
31196 | - twice-tmp varargs vforked-prog watchpoint whatis | |
31197 | + twice-tmp varargs vforked-prog watchpoint whatis catch-syscall | |
31198 | ||
31199 | MISCELLANEOUS = coremmap.data ../foobar.baz \ | |
31200 | shr1.sl shr2.sl solib_sl.sl solib1.sl solib2.sl | |
31201 | diff --git a/gdb/testsuite/gdb.base/call-rt-st.exp b/gdb/testsuite/gdb.base/call-rt-st.exp | |
31202 | index 3359c70..f73dd7f 100644 | |
31203 | --- a/gdb/testsuite/gdb.base/call-rt-st.exp | |
31204 | +++ b/gdb/testsuite/gdb.base/call-rt-st.exp | |
31205 | @@ -186,7 +186,7 @@ if {![gdb_skip_float_test "print print_two_floats(*f3)"] && \ | |
31206 | ||
31207 | if ![gdb_skip_stdio_test "print print_bit_flags_char(*cflags)"] { | |
31208 | print_struct_call "print_bit_flags_char(*cflags)" \ | |
31209 | - ".*alpha\[ \r\n\]+gamma\[ \r\n\]+epsilon\[ \r\n\]+.\[0-9\]+ = \\{alpha = 1 '\\\\001', beta = 0 '\\\\0', gamma = 1 '\\\\001', delta = 0 '\\\\0', epsilon = 1 '\\\\001', omega = 0 '\\\\0'\\}" | |
31210 | + ".*alpha\[ \r\n\]+gamma\[ \r\n\]+epsilon\[ \r\n\]+.\[0-9\]+ = \\{alpha = 1 '\\\\1', beta = 0 '\\\\0', gamma = 1 '\\\\1', delta = 0 '\\\\0', epsilon = 1 '\\\\1', omega = 0 '\\\\0'\\}" | |
31211 | } | |
31212 | ||
31213 | if ![gdb_skip_stdio_test "print print_bit_flags_short(*sflags)"] { | |
31214 | diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp | |
31215 | index 6d8aa45..be6a872 100644 | |
31216 | --- a/gdb/testsuite/gdb.base/callfuncs.exp | |
31217 | +++ b/gdb/testsuite/gdb.base/callfuncs.exp | |
31218 | @@ -437,7 +437,7 @@ gdb_test "print t_small_values(1,3,5,7,9,11,13,15,17,19)" \ | |
31219 | "The program being debugged stopped while.*" \ | |
31220 | "stop at nested call level 4" | |
31221 | gdb_test "backtrace" \ | |
31222 | - "\#0 t_small_values \\(arg1=1 '.001', arg2=3, arg3=5, arg4=7 '.a', arg5=9, arg6=11 '.v', arg7=13, arg8=15, arg9=17, arg10=19\\).*\#2 sum10 \\(i0=2, i1=4, i2=6, i3=8, i4=10, i5=12, i6=14, i7=16, i8=18, i9=20\\).*\#3 <function called from gdb>.*\#4 add \\(a=4, b=5\\).*\#5 <function called from gdb>.*\#6 add \\(a=2, b=3\\).*\#7 <function called from gdb>.*\#8 main.*" \ | |
31223 | + "\#0 t_small_values \\(arg1=1 '.1', arg2=3, arg3=5, arg4=7 '.a', arg5=9, arg6=11 '.v', arg7=13, arg8=15, arg9=17, arg10=19\\).*\#2 sum10 \\(i0=2, i1=4, i2=6, i3=8, i4=10, i5=12, i6=14, i7=16, i8=18, i9=20\\).*\#3 <function called from gdb>.*\#4 add \\(a=4, b=5\\).*\#5 <function called from gdb>.*\#6 add \\(a=2, b=3\\).*\#7 <function called from gdb>.*\#8 main.*" \ | |
31224 | "backtrace at nested call level 4" | |
31225 | gdb_test "finish" "Value returned is .* = 100" \ | |
31226 | "Finish from nested call level 4" | |
31227 | diff --git a/gdb/testsuite/gdb.base/catch-syscall.c b/gdb/testsuite/gdb.base/catch-syscall.c | |
31228 | new file mode 100644 | |
31229 | index 0000000..64850de | |
31230 | --- /dev/null | |
31231 | +++ b/gdb/testsuite/gdb.base/catch-syscall.c | |
31232 | @@ -0,0 +1,25 @@ | |
31233 | +/* This file is used to test the 'catch syscall' feature on GDB. | |
31234 | + | |
31235 | + Please, if you are going to edit this file DO NOT change the syscalls | |
31236 | + being called (nor the order of them). If you really must do this, then | |
31237 | + take a look at catch-syscall.exp and modify there too. | |
31238 | + | |
31239 | + Written by Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> | |
31240 | + September, 2008 */ | |
31241 | + | |
31242 | +#include <unistd.h> | |
31243 | +#include <fcntl.h> | |
31244 | +#include <sys/stat.h> | |
31245 | + | |
31246 | +int | |
31247 | +main (void) | |
31248 | +{ | |
31249 | + /* A close() with a wrong argument. We are only | |
31250 | + interested in the syscall. */ | |
31251 | + close (-1); | |
31252 | + | |
31253 | + chroot ("."); | |
31254 | + | |
31255 | + /* The last syscall. Do not change this. */ | |
31256 | + _exit (0); | |
31257 | +} | |
31258 | diff --git a/gdb/testsuite/gdb.base/catch-syscall.exp b/gdb/testsuite/gdb.base/catch-syscall.exp | |
31259 | new file mode 100644 | |
31260 | index 0000000..a9f6937 | |
31261 | --- /dev/null | |
31262 | +++ b/gdb/testsuite/gdb.base/catch-syscall.exp | |
31263 | @@ -0,0 +1,386 @@ | |
31264 | +# Copyright 1997, 1999, 2007, 2008 Free Software Foundation, Inc. | |
31265 | + | |
31266 | +# This program is free software; you can redistribute it and/or modify | |
31267 | +# it under the terms of the GNU General Public License as published by | |
31268 | +# the Free Software Foundation; either version 3 of the License, or | |
31269 | +# (at your option) any later version. | |
31270 | +# | |
31271 | +# This program is distributed in the hope that it will be useful, | |
31272 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31273 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
31274 | +# GNU General Public License for more details. | |
31275 | +# | |
31276 | +# You should have received a copy of the GNU General Public License | |
31277 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31278 | + | |
31279 | + | |
31280 | +# This program tests the 'catch syscall' functionality. | |
31281 | +# | |
31282 | +# It was written by Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> | |
31283 | +# on September/2008. | |
31284 | + | |
31285 | +if { [is_remote target] || ![isnative] } then { | |
31286 | + continue | |
31287 | +} | |
31288 | + | |
31289 | +set prms_id 0 | |
31290 | +set bug_id 0 | |
31291 | + | |
31292 | +global srcfile | |
31293 | +set testfile "catch-syscall" | |
31294 | +set srcfile ${testfile}.c | |
31295 | +set binfile ${objdir}/${subdir}/${testfile} | |
31296 | + | |
31297 | +# All (but the last) syscalls from the example code | |
31298 | +# They are ordered according to the file, so do not change this. | |
31299 | +set all_syscalls { "close" "chroot" } | |
31300 | +# The last syscall (exit()) does not return, so | |
31301 | +# we cannot expect the catchpoint to be triggered | |
31302 | +# twice. It is a special case. | |
31303 | +set last_syscall "exit_group" | |
31304 | + | |
31305 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
31306 | + untested catch-syscall.exp | |
31307 | + return -1 | |
31308 | +} | |
31309 | + | |
31310 | +# Until "catch syscall" is implemented on other targets... | |
31311 | +if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then { | |
31312 | + continue | |
31313 | +} | |
31314 | + | |
31315 | +# This shall be updated whenever 'catch syscall' is implemented | |
31316 | +# on some architecture. | |
31317 | +#if { ![istarget "x86_64-*-linux*"] && ![istarget "i\[34567\]86-*-linux*"] | |
31318 | +if { ![istarget "i\[34567\]86-*-linux*"] | |
31319 | + && ![istarget "powerpc-*-linux*"] && ![istarget "powerpc64-*-linux*"] } { | |
31320 | + continue | |
31321 | +} | |
31322 | + | |
31323 | +# Internal procedure used to check if, before any syscall is caught, | |
31324 | +# the command 'info breakpoints' correctly lists the catchpoints AND | |
31325 | +# says that nothing was caught yet. | |
31326 | +proc check_init_info_breakpoints {} { | |
31327 | + global gdb_prompt | |
31328 | + | |
31329 | + # Verifying that the catchpoint appears in the 'info breakpoints' | |
31330 | + # command, but with "<any syscall>". | |
31331 | + set thistest "catch syscall appears in 'info breakpoints'" | |
31332 | + gdb_test "info breakpoints" ".*catchpoint.*keep y.*syscall \"<any syscall>\".*" $thistest | |
31333 | +} | |
31334 | + | |
31335 | +# This procedure checks if, after a syscall catchpoint is hit, the | |
31336 | +# command 'info breakpoints' correctly lists the syscall name. | |
31337 | +proc check_info_breakpoints { syscall } { | |
31338 | + global gdb_prompt | |
31339 | + | |
31340 | + set thistest "syscall $syscall appears in 'info breakpoints'" | |
31341 | + gdb_test "info breakpoints" ".*catchpoint.*keep y.*syscall (.)?${syscall}(.)?.*" $thistest | |
31342 | +} | |
31343 | + | |
31344 | +# This procedure checks if there was a call to a syscall. | |
31345 | +proc check_call_to_syscall { syscall } { | |
31346 | + global gdb_prompt | |
31347 | + | |
31348 | + set thistest "program has called $syscall" | |
31349 | + gdb_test "continue" "Catchpoint .*(call to syscall .?${syscall}.?).*" $thistest | |
31350 | + | |
31351 | + # Checking if the syscall is reported to be caught in | |
31352 | + # 'info breakpoints'. | |
31353 | + check_info_breakpoints "$syscall" | |
31354 | +} | |
31355 | + | |
31356 | +# This procedure checks if the syscall returned. | |
31357 | +proc check_return_from_syscall { syscall } { | |
31358 | + global gdb_prompt | |
31359 | + | |
31360 | + set thistest "syscall $syscall has returned" | |
31361 | + gdb_test "continue" "Catchpoint .*(returned from syscall (.)?${syscall}(.)?).*" $thistest | |
31362 | + | |
31363 | + # Checking if the syscall is reported to be caught in | |
31364 | + # 'info breakpoints'. | |
31365 | + check_info_breakpoints "$syscall" | |
31366 | +} | |
31367 | + | |
31368 | +# Internal procedure that performs two 'continue' commands and checks if | |
31369 | +# a syscall call AND return occur. | |
31370 | +proc check_continue { syscall } { | |
31371 | + global gdb_prompt | |
31372 | + | |
31373 | + # Testing if the 'continue' stops at the | |
31374 | + # specified syscall_name. If it does, then it should | |
31375 | + # first print that the infeior has called the syscall, | |
31376 | + # and after print that the syscall has returned. | |
31377 | + | |
31378 | + # Testing if the inferiorr has called the syscall. | |
31379 | + check_call_to_syscall $syscall | |
31380 | + # And now, that the syscall has returned. | |
31381 | + check_return_from_syscall $syscall | |
31382 | +} | |
31383 | + | |
31384 | +# Inserts a syscall catchpoint with an argument. | |
31385 | +proc insert_catch_syscall_with_arg { syscall } { | |
31386 | + global gdb_prompt | |
31387 | + | |
31388 | + # Trying to set the syscall | |
31389 | + set thistest "catch syscall with arguments ($syscall)" | |
31390 | + gdb_test "catch syscall $syscall" "Catchpoint .*(syscall\[(\]s\[)\] (.)?${syscall}(.)?).*" $thistest | |
31391 | +} | |
31392 | + | |
31393 | +proc check_for_program_end {} { | |
31394 | + global gdb_prompt | |
31395 | + | |
31396 | + # Deleting the catchpoints | |
31397 | + delete_breakpoints | |
31398 | + | |
31399 | + set thistest "successful program end" | |
31400 | + gdb_test "continue" "Program exited normally.*" $thistest | |
31401 | + | |
31402 | +} | |
31403 | + | |
31404 | +proc test_catch_syscall_without_args {} { | |
31405 | + global gdb_prompt all_syscalls last_syscall | |
31406 | + | |
31407 | + # Trying to set the syscall | |
31408 | + set thistest "setting catch syscall without arguments" | |
31409 | + gdb_test "catch syscall" "Catchpoint .*(syscall).*" $thistest | |
31410 | + | |
31411 | + check_init_info_breakpoints | |
31412 | + | |
31413 | + # We have to check every syscall | |
31414 | + foreach name $all_syscalls { | |
31415 | + check_continue $name | |
31416 | + } | |
31417 | + | |
31418 | + # At last but not least, we check if the inferior | |
31419 | + # has called the last (exit) syscall. | |
31420 | + check_call_to_syscall $last_syscall | |
31421 | + | |
31422 | + # Now let's see if the inferior correctly finishes. | |
31423 | + check_for_program_end | |
31424 | +} | |
31425 | + | |
31426 | +proc test_catch_syscall_with_args {} { | |
31427 | + global gdb_prompt | |
31428 | + set syscall_name "close" | |
31429 | + | |
31430 | + insert_catch_syscall_with_arg $syscall_name | |
31431 | + check_init_info_breakpoints | |
31432 | + | |
31433 | + # Can we continue until we catch the syscall? | |
31434 | + check_continue $syscall_name | |
31435 | + | |
31436 | + # Now let's see if the inferior correctly finishes. | |
31437 | + check_for_program_end | |
31438 | +} | |
31439 | + | |
31440 | +proc test_catch_syscall_with_wrong_args {} { | |
31441 | + global gdb_prompt | |
31442 | + # mlock is not called from the source | |
31443 | + set syscall_name "mlock" | |
31444 | + | |
31445 | + insert_catch_syscall_with_arg $syscall_name | |
31446 | + check_init_info_breakpoints | |
31447 | + | |
31448 | + # Now, we must verify if the program stops with a continue. | |
31449 | + # If it doesn't, everything is right (since we don't have | |
31450 | + # a syscall named "mlock" in it). Otherwise, this is a failure. | |
31451 | + set thistest "catch syscall with unused syscall ($syscall_name)" | |
31452 | + gdb_test "continue" "Program exited normally.*" $thistest | |
31453 | +} | |
31454 | + | |
31455 | +proc test_catch_syscall_restarting_inferior {} { | |
31456 | + global gdb_prompt | |
31457 | + set syscall_name "chroot" | |
31458 | + | |
31459 | + insert_catch_syscall_with_arg $syscall_name | |
31460 | + check_init_info_breakpoints | |
31461 | + | |
31462 | + # Let's first reach the call of the syscall. | |
31463 | + check_call_to_syscall $syscall_name | |
31464 | + | |
31465 | + # Now, restart the program | |
31466 | + rerun_to_main | |
31467 | + | |
31468 | + # And check for call/return | |
31469 | + check_continue $syscall_name | |
31470 | + | |
31471 | + # Can we finish? | |
31472 | + check_for_program_end | |
31473 | +} | |
31474 | + | |
31475 | +proc do_syscall_tests {} { | |
31476 | + global gdb_prompt srcdir | |
31477 | + | |
31478 | + # First, we need to set GDB datadir. | |
31479 | + send_gdb "maintenance set gdb_datadir $srcdir/..\n" | |
31480 | + gdb_expect 10 { | |
31481 | + -re "$gdb_prompt $" { | |
31482 | + verbose "Setting GDB datadir to $srcdir/..." 2 | |
31483 | + } | |
31484 | + timeout { | |
31485 | + error "Couldn't set GDB datadir." | |
31486 | + } | |
31487 | + } | |
31488 | + | |
31489 | + # Verify that the 'catch syscall' help is available | |
31490 | + set thistest "help catch syscall" | |
31491 | + gdb_test "help catch syscall" "Catch system calls.*" $thistest | |
31492 | + | |
31493 | + # Try to set a catchpoint to a nonsense syscall | |
31494 | + set thistest "catch syscall to a nonsense syscall is prohibited" | |
31495 | + gdb_test "catch syscall nonsense_syscall" "Unknown syscall name .*" $thistest | |
31496 | + | |
31497 | + # Testing the 'catch syscall' command without arguments. | |
31498 | + # This test should catch any syscalls. | |
31499 | + if [runto_main] then { test_catch_syscall_without_args } | |
31500 | + | |
31501 | + # Testing the 'catch syscall' command with arguments. | |
31502 | + # This test should only catch the specified syscall. | |
31503 | + if [runto_main] then { test_catch_syscall_with_args } | |
31504 | + | |
31505 | + # Testing the 'catch syscall' command with WRONG arguments. | |
31506 | + # This test should not trigger any catchpoints. | |
31507 | + if [runto_main] then { test_catch_syscall_with_wrong_args } | |
31508 | + | |
31509 | + # Testing the 'catch' syscall command during a restart of | |
31510 | + # the inferior. | |
31511 | + if [runto_main] then { test_catch_syscall_restarting_inferior } | |
31512 | +} | |
31513 | + | |
31514 | +proc test_catch_syscall_fail_noxml {} { | |
31515 | + global gdb_prompt | |
31516 | + | |
31517 | + # Sanitizing. | |
31518 | + delete_breakpoints | |
31519 | + | |
31520 | + # Testing to see if we receive a warning when calling "catch syscall" | |
31521 | + # without XML support. | |
31522 | + set thistest "Catch syscall displays a warning when there is no XML support" | |
31523 | + gdb_test "catch syscall" "warning: Could not open .*warning: Could not load the syscall XML file .*GDB will not be able to display syscall names.*Catchpoint .*(syscall).*" $thistest | |
31524 | + | |
31525 | + # Since the catchpoint was set, we must check if it's present at | |
31526 | + # "info breakpoints" | |
31527 | + check_init_info_breakpoints | |
31528 | + | |
31529 | + # Sanitizing. | |
31530 | + delete_breakpoints | |
31531 | +} | |
31532 | + | |
31533 | +proc test_catch_syscall_without_args_noxml {} { | |
31534 | + # We will need the syscall names even not using it | |
31535 | + # because we need to know know many syscalls are in | |
31536 | + # the example file. | |
31537 | + global gdb_prompt all_syscalls last_syscall | |
31538 | + | |
31539 | + delete_breakpoints | |
31540 | + | |
31541 | + set thistest "Catch syscall without arguments and without XML support" | |
31542 | + gdb_test "catch syscall" "Catchpoint .*(syscall).*" | |
31543 | + | |
31544 | + # Now, we should be able to set a catchpoint, | |
31545 | + # and GDB shall not display the warning anymore. | |
31546 | + foreach name $all_syscalls { | |
31547 | + # Unfortunately, we don't know the syscall number | |
31548 | + # that will be caught because this information is | |
31549 | + # arch-dependent. Thus, we try to catch anything | |
31550 | + # similar to a number. | |
31551 | + check_continue "\[0-9\]*" | |
31552 | + } | |
31553 | + | |
31554 | + # At last but not least, we check if the inferior | |
31555 | + # has called the last (exit) syscall. | |
31556 | + check_call_to_syscall "\[0-9\]*" | |
31557 | + | |
31558 | + delete_breakpoints | |
31559 | +} | |
31560 | + | |
31561 | +proc test_catch_syscall_with_args_noxml {} { | |
31562 | + global gdb_prompt | |
31563 | + | |
31564 | + # The number of the "close" syscall. This is our | |
31565 | + # options for a "long-estabilished" syscall in all | |
31566 | + # Linux architectures, but unfortunately x86_64 and | |
31567 | + # a few other platforms don't "follow the convention". | |
31568 | + # Because of this, we need this ugly check :-(. | |
31569 | + set close_number "" | |
31570 | + if { [istarget "x86_64-*-linux*"] } { | |
31571 | + set close_number "3" | |
31572 | + } else { | |
31573 | + set close_number "6" | |
31574 | + } | |
31575 | + | |
31576 | + delete_breakpoints | |
31577 | + | |
31578 | + insert_catch_syscall_with_arg $close_number | |
31579 | + check_init_info_breakpoints | |
31580 | + | |
31581 | + check_continue $close_number | |
31582 | + | |
31583 | + delete_breakpoints | |
31584 | +} | |
31585 | + | |
31586 | +proc test_catch_syscall_with_wrong_args_noxml {} { | |
31587 | + global gdb_prompt | |
31588 | + | |
31589 | + delete_breakpoints | |
31590 | + | |
31591 | + # Even without XML support, GDB should not accept unknown | |
31592 | + # syscall names for the catchpoint. | |
31593 | + set thistest "Catch a nonsense syscall without XML support" | |
31594 | + gdb_test "catch syscall nonsense_syscall" "Unknown syscall name .nonsense_syscall.*" $thistest | |
31595 | + | |
31596 | + delete_breakpoints | |
31597 | +} | |
31598 | + | |
31599 | +proc do_syscall_tests_without_xml {} { | |
31600 | + global gdb_prompt srcdir | |
31601 | + | |
31602 | + # In this case, we don't need to set GDB's datadir because | |
31603 | + # we want GDB to display only numbers, not names. So, let's | |
31604 | + # begin with the tests. | |
31605 | + | |
31606 | + # The first test is to see if GDB displays a warning when we | |
31607 | + # try to catch syscalls without the XML support. | |
31608 | + test_catch_syscall_fail_noxml | |
31609 | + | |
31610 | + # Now, let's test if we can catch syscalls without XML support. | |
31611 | + # We should succeed, but GDB is not supposed to print syscall names. | |
31612 | + if [runto_main] then { test_catch_syscall_without_args_noxml } | |
31613 | + | |
31614 | + # The only valid argument "catch syscall" should accept is the | |
31615 | + # syscall number, and not the name (since it can't translate a | |
31616 | + # name to a number). | |
31617 | + # | |
31618 | + # It's worth mentioning that we only try to catch the syscall | |
31619 | + # close(). This is because the syscall number is an arch-dependent | |
31620 | + # information, so we can't assume that we know every syscall number | |
31621 | + # in this system. Therefore, we have decided to use a "long-estabilished" | |
31622 | + # system call, and close() just sounded the right choice :-). | |
31623 | + if [runto_main] then { test_catch_syscall_with_args_noxml } | |
31624 | + | |
31625 | + # Now, we'll try to provide a syscall name (valid or not) to the command, | |
31626 | + # and expect it to fail. | |
31627 | + if [runto_main] then { test_catch_syscall_with_wrong_args_noxml } | |
31628 | +} | |
31629 | + | |
31630 | +# Start with a fresh gdb | |
31631 | + | |
31632 | +gdb_exit | |
31633 | +gdb_start | |
31634 | +gdb_reinitialize_dir $srcdir/$subdir | |
31635 | +gdb_load ${binfile} | |
31636 | + | |
31637 | +# Execute the tests, using XML support | |
31638 | +do_syscall_tests | |
31639 | + | |
31640 | +# Restart gdb | |
31641 | + | |
31642 | +gdb_exit | |
31643 | +gdb_start | |
31644 | +gdb_reinitialize_dir $srcdir/$subdir | |
31645 | +gdb_load ${binfile} | |
31646 | + | |
31647 | +# Execute the tests, without XML support. In this case, GDB will | |
31648 | +# only display syscall numbers, and not syscall names. | |
31649 | +do_syscall_tests_without_xml | |
31650 | diff --git a/gdb/testsuite/gdb.base/charset.c b/gdb/testsuite/gdb.base/charset.c | |
31651 | index b640702..55a50ce 100644 | |
31652 | --- a/gdb/testsuite/gdb.base/charset.c | |
31653 | +++ b/gdb/testsuite/gdb.base/charset.c | |
31654 | @@ -20,11 +20,6 @@ | |
31655 | Please email any bugs, comments, and/or additions to this file to: | |
31656 | bug-gdb@gnu.org */ | |
31657 | ||
31658 | -#include <stdio.h> | |
31659 | -#include <stdlib.h> | |
31660 | -#include <string.h> | |
31661 | - | |
31662 | - | |
31663 | /* X_string is a null-terminated string in the X charset whose | |
31664 | elements are as follows. X should be the name the `set charset' | |
31665 | command uses for the character set, in lower-case, with any | |
31666 | @@ -54,6 +49,21 @@ char iso_8859_1_string[NUM_CHARS]; | |
31667 | char ebcdic_us_string[NUM_CHARS]; | |
31668 | char ibm1047_string[NUM_CHARS]; | |
31669 | ||
31670 | +/* We make a phony wchar_t and then pretend that this platform uses | |
31671 | + UCS-4 (or UCS-2, depending on the size -- same difference for the | |
31672 | + purposes of this test). */ | |
31673 | +typedef unsigned int wchar_t; | |
31674 | +wchar_t ucs_4_string[NUM_CHARS]; | |
31675 | + | |
31676 | +/* We also define a couple phony types for testing the u'' and U'' | |
31677 | + support. It is ok if these have the wrong size on some platforms | |
31678 | + -- the test case will skip the tests in that case. */ | |
31679 | +typedef unsigned short char16_t; | |
31680 | +typedef unsigned int char32_t; | |
31681 | + | |
31682 | +/* Make sure to use the typedefs. */ | |
31683 | +char16_t uvar; | |
31684 | +char32_t Uvar; | |
31685 | ||
31686 | void | |
31687 | init_string (char string[], | |
31688 | @@ -62,7 +72,10 @@ init_string (char string[], | |
31689 | char line_feed, char carriage_return, char horizontal_tab, | |
31690 | char vertical_tab, char cent, char misc_ctrl) | |
31691 | { | |
31692 | - memset (string, x, NUM_CHARS); | |
31693 | + int i; | |
31694 | + | |
31695 | + for (i = 0; i < NUM_CHARS; ++i) | |
31696 | + string[i] = x; | |
31697 | string[0] = alert; | |
31698 | string[1] = backspace; | |
31699 | string[2] = form_feed; | |
31700 | @@ -85,13 +98,21 @@ fill_run (char string[], int start, int len, int first) | |
31701 | } | |
31702 | ||
31703 | ||
31704 | +void | |
31705 | +init_ucs4 () | |
31706 | +{ | |
31707 | + int i; | |
31708 | + | |
31709 | + for (i = 0; i < NUM_CHARS; ++i) | |
31710 | + ucs_4_string[i] = iso_8859_1_string[i] & 0xff; | |
31711 | +} | |
31712 | + | |
31713 | int main () | |
31714 | { | |
31715 | #ifdef usestubs | |
31716 | set_debug_traps(); | |
31717 | breakpoint(); | |
31718 | #endif | |
31719 | - (void) malloc (1); | |
31720 | /* Initialize ascii_string. */ | |
31721 | init_string (ascii_string, | |
31722 | 120, | |
31723 | @@ -146,5 +167,7 @@ int main () | |
31724 | /* The digits, at least, are contiguous. */ | |
31725 | fill_run (ibm1047_string, 59, 10, 240); | |
31726 | ||
31727 | - puts ("All set!"); /* all strings initialized */ | |
31728 | + init_ucs4 (); | |
31729 | + | |
31730 | + return 0; /* all strings initialized */ | |
31731 | } | |
31732 | diff --git a/gdb/testsuite/gdb.base/charset.exp b/gdb/testsuite/gdb.base/charset.exp | |
31733 | index fa26521..93f66c0 100644 | |
31734 | --- a/gdb/testsuite/gdb.base/charset.exp | |
31735 | +++ b/gdb/testsuite/gdb.base/charset.exp | |
31736 | @@ -47,13 +47,7 @@ proc parse_show_charset_output {testname} { | |
31737 | global gdb_prompt | |
31738 | ||
31739 | gdb_expect { | |
31740 | - -re "The current host and target character set is `(.*)'\\.\[\r\n\]+$gdb_prompt $" { | |
31741 | - set host_charset $expect_out(1,string) | |
31742 | - set target_charset $expect_out(1,string) | |
31743 | - set retlist [list $host_charset $target_charset] | |
31744 | - pass $testname | |
31745 | - } | |
31746 | - -re "The current host character set is `(.*)'\\.\[\r\n\]+The current target character set is `(.*)'\\.\[\r\n\]+$gdb_prompt $" { | |
31747 | + -re "The host character set is \"(.*)\"\\.\[\r\n\]+The target character set is \"(.*)\"\\.\[\r\n\]+The target wide character set is \"(.*)\"\\.\[\r\n\]+$gdb_prompt $" { | |
31748 | set host_charset $expect_out(1,string) | |
31749 | set target_charset $expect_out(2,string) | |
31750 | set retlist [list $host_charset $target_charset] | |
31751 | @@ -81,79 +75,35 @@ proc parse_show_charset_output {testname} { | |
31752 | } | |
31753 | ||
31754 | ||
31755 | -# Try the various `show charset' commands. These are all aliases of each | |
31756 | -# other; `show target-charset' and `show host-charset' actually print | |
31757 | -# both the host and target charsets. | |
31758 | +# Try the various `show charset' commands. | |
31759 | ||
31760 | send_gdb "show charset\n" | |
31761 | set show_charset [parse_show_charset_output "show charset"] | |
31762 | ||
31763 | send_gdb "show target-charset\n" | |
31764 | -set show_target_charset [parse_show_charset_output "show target-charset"] | |
31765 | +set show_target_charset \ | |
31766 | + [lindex [parse_show_charset_output "show target-charset"] 0] | |
31767 | ||
31768 | -if {[lsearch $show_charset $show_target_charset] >= 0} { | |
31769 | +if {[lsearch -exact $show_charset $show_target_charset] >= 0} { | |
31770 | pass "check `show target-charset' against `show charset'" | |
31771 | } else { | |
31772 | fail "check `show target-charset' against `show charset'" | |
31773 | } | |
31774 | ||
31775 | send_gdb "show host-charset\n" | |
31776 | -set show_host_charset [parse_show_charset_output "show host-charset"] | |
31777 | +set show_host_charset \ | |
31778 | + [lindex [parse_show_charset_output "show host-charset"] 0] | |
31779 | ||
31780 | -if {[lsearch $show_charset $show_host_charset] >= 0} { | |
31781 | +if {[lsearch -exact $show_charset $show_host_charset] >= 0} { | |
31782 | pass "check `show host-charset' against `show charset'" | |
31783 | } else { | |
31784 | fail "check `show host-charset' against `show charset'" | |
31785 | } | |
31786 | ||
31787 | - | |
31788 | -# Get the list of supported (host) charsets as possible completions. | |
31789 | -send_gdb "set charset \t\t" | |
31790 | - | |
31791 | -# Check that we can at least use ASCII as a host character set. | |
31792 | -sleep 1 | |
31793 | -gdb_expect { | |
31794 | - -re "^set charset .*\r\nASCII.*\r\n$gdb_prompt set charset " { | |
31795 | - # We got the output that we wanted, including ASCII as possible | |
31796 | - # charset. Send a newline to get us back to the prompt. This will | |
31797 | - # also generate an error message. Let's not check here that the error | |
31798 | - # message makes sense, we do that below, as a separate testcase. | |
31799 | - send_gdb "\n" | |
31800 | - gdb_expect { | |
31801 | - -re ".*Requires an argument.*$gdb_prompt $" { | |
31802 | - pass "get valid character sets" | |
31803 | - } | |
31804 | - -re ".*$gdb_prompt $" { | |
31805 | - send_gdb "\n" | |
31806 | - gdb_expect { | |
31807 | - -re ".*$gdb_prompt $" { | |
31808 | - fail "get valid character sets" | |
31809 | - } | |
31810 | - } | |
31811 | - } | |
31812 | - timeout { | |
31813 | - fail "(timeout) get valid character sets" | |
31814 | - } | |
31815 | - } | |
31816 | - } | |
31817 | - -re ".*$gdb_prompt $" { | |
31818 | - # We got some output that ended with a regular prompt | |
31819 | - fail "get valid character sets" | |
31820 | - } | |
31821 | - -re ".*$gdb_prompt set charset.*$" { | |
31822 | - # We got some other output, send a cntrl-c to gdb to get us back | |
31823 | - # to the prompt. | |
31824 | - send_gdb "\003" | |
31825 | - fail "get valid character sets" | |
31826 | - } | |
31827 | - timeout { | |
31828 | - fail "get valid character sets (timeout)" | |
31829 | - } | |
31830 | -} | |
31831 | - | |
31832 | # Try a malformed `set charset'. | |
31833 | +# Also check that we can at least use ASCII as a host character set. | |
31834 | gdb_test "set charset" \ | |
31835 | - "Requires an argument. Valid arguments are.*" \ | |
31836 | + "Requires an argument. Valid arguments are.* ASCII,.*" \ | |
31837 | "try malformed `set charset'" | |
31838 | ||
31839 | # Try using `set host-charset' on an invalid character set. | |
31840 | @@ -244,8 +194,10 @@ gdb_expect { | |
31841 | } | |
31842 | } | |
31843 | ||
31844 | -# Make sure that GDB supports every host/target charset combination. | |
31845 | -foreach host_charset [all_charset_names] { | |
31846 | +# We don't want to test all the charset names here, since that would | |
31847 | +# be too many combinations. We we pick a subset. | |
31848 | +set charset_subset {ASCII ISO-8859-1 EBCDIC-US IBM1047} | |
31849 | +foreach host_charset $charset_subset { | |
31850 | if {[valid_host_charset $host_charset]} { | |
31851 | ||
31852 | set testname "try `set host-charset $host_charset'" | |
31853 | @@ -279,7 +231,7 @@ foreach host_charset [all_charset_names] { | |
31854 | ||
31855 | # Now try setting every possible target character set, | |
31856 | # given that host charset. | |
31857 | - foreach target_charset [all_charset_names] { | |
31858 | + foreach target_charset $charset_subset { | |
31859 | set testname "try `set target-charset $target_charset'" | |
31860 | send_gdb "set target-charset $target_charset\n" | |
31861 | gdb_expect { | |
31862 | @@ -404,23 +356,42 @@ gdb_expect { | |
31863 | } | |
31864 | ||
31865 | ||
31866 | +# We only try the wide character tests on machines where the wchar_t | |
31867 | +# typedef in the test case has the right size. | |
31868 | +set wchar_size [get_sizeof wchar_t 99] | |
31869 | +set wchar_ok 0 | |
31870 | +if {$wchar_size == 2} { | |
31871 | + lappend charset_subset UCS-2 | |
31872 | + set wchar_ok 1 | |
31873 | +} elseif {$wchar_size == 4} { | |
31874 | + lappend charset_subset UCS-4 | |
31875 | + set wchar_ok 1 | |
31876 | +} | |
31877 | + | |
31878 | gdb_test "set host-charset ASCII" "" | |
31879 | -foreach target_charset [all_charset_names] { | |
31880 | - send_gdb "set target-charset $target_charset\n" | |
31881 | +foreach target_charset $charset_subset { | |
31882 | + if {$target_charset == "UCS-4" || $target_charset == "UCS-2"} { | |
31883 | + set param target-wide-charset | |
31884 | + set L L | |
31885 | + } else { | |
31886 | + set param target-charset | |
31887 | + set L "" | |
31888 | + } | |
31889 | + send_gdb "set $param $target_charset\n" | |
31890 | gdb_expect { | |
31891 | -re "$gdb_prompt $" { | |
31892 | - pass "set target-charset $target_charset" | |
31893 | + pass "set $param $target_charset" | |
31894 | } | |
31895 | timeout { | |
31896 | - fail "set target-charset $target_charset (timeout)" | |
31897 | + fail "set $param $target_charset (timeout)" | |
31898 | } | |
31899 | } | |
31900 | ||
31901 | # Try printing the null character. There seems to be a bug in | |
31902 | # gdb_test that requires us to use gdb_expect here. | |
31903 | - send_gdb "print '\\0'\n" | |
31904 | + send_gdb "print $L'\\0'\n" | |
31905 | gdb_expect { | |
31906 | - -re "\\\$${decimal} = 0 '\\\\0'\[\r\n\]+$gdb_prompt $" { | |
31907 | + -re "\\\$${decimal} = 0 $L'\\\\0'\[\r\n\]+$gdb_prompt $" { | |
31908 | pass "print the null character in ${target_charset}" | |
31909 | } | |
31910 | -re "$gdb_prompt $" { | |
31911 | @@ -435,8 +406,14 @@ foreach target_charset [all_charset_names] { | |
31912 | # a string in $target_charset. The variable's name is the | |
31913 | # character set's name, in lower-case, with all non-identifier | |
31914 | # characters replaced with '_', with "_string" stuck on the end. | |
31915 | - set var_name [string tolower "${target_charset}_string"] | |
31916 | - regsub -all -- "\[^a-z0-9_\]" $var_name "_" var_name | |
31917 | + if {$target_charset == "UCS-2"} { | |
31918 | + # We still use the ucs_4_string variable -- but the size is | |
31919 | + # correct for UCS-2. | |
31920 | + set var_name ucs_4_string | |
31921 | + } else { | |
31922 | + set var_name [string tolower "${target_charset}_string"] | |
31923 | + regsub -all -- "\[^a-z0-9_\]" $var_name "_" var_name | |
31924 | + } | |
31925 | ||
31926 | # Compute a regexp matching the results we expect. This is static, | |
31927 | # but it's easier than writing it out. | |
31928 | @@ -444,12 +421,12 @@ foreach target_charset [all_charset_names] { | |
31929 | set uppercase "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
31930 | set lowercase "abcdefghijklmnopqrstuvwxyz" | |
31931 | set digits "0123456789" | |
31932 | - set octal_escape "\\\\\[0-9\]\[0-9\]\[0-9\]" | |
31933 | + set octal_escape "\\\\\[0-9\]+" | |
31934 | ||
31935 | send_gdb "print $var_name\n" | |
31936 | # ${escapes}${uppercase}${lowercase}${digits}${octal}${octal} | |
31937 | gdb_expect { | |
31938 | - -re ".* = \"(\\\\a|x)(\\\\b|x)(\\\\f|x)(\\\\n|x)(\\\\r|x)(\\\\t|x)(\\\\v|x)${uppercase}${lowercase}${digits}(\\\\\[0-9\]\[0-9\]\[0-9\]|x)(\\\\\[0-9\]\[0-9\]\[0-9\]|x).*\"\[\r\n\]+$gdb_prompt $" { | |
31939 | + -re ".* = $L\"(\\\\a|x)(\\\\b|x)(\\\\f|x)(\\\\n|x)(\\\\r|x)(\\\\t|x)(\\\\v|x)${uppercase}${lowercase}${digits}(${octal_escape}|x)+\"\[\r\n\]+$gdb_prompt $" { | |
31940 | pass "print string in $target_charset" | |
31941 | } | |
31942 | -re "$gdb_prompt $" { | |
31943 | @@ -461,22 +438,22 @@ foreach target_charset [all_charset_names] { | |
31944 | } | |
31945 | ||
31946 | # Try entering a character literal, and see if it comes back unchanged. | |
31947 | - gdb_test "print 'A'" \ | |
31948 | - " = \[0-9-\]+ 'A'" \ | |
31949 | + gdb_test "print $L'A'" \ | |
31950 | + " = \[0-9-\]+ $L'A'" \ | |
31951 | "parse character literal in ${target_charset}" | |
31952 | ||
31953 | # Check that the character literal was encoded correctly. | |
31954 | - gdb_test "print 'A' == $var_name\[7\]" \ | |
31955 | + gdb_test "print $L'A' == $var_name\[7\]" \ | |
31956 | " = 1" \ | |
31957 | "check value of parsed character literal in ${target_charset}" | |
31958 | ||
31959 | # Try entering a string literal, and see if it comes back unchanged. | |
31960 | - gdb_test "print \"abcdefABCDEF012345\"" \ | |
31961 | - " = \"abcdefABCDEF012345\"" \ | |
31962 | + gdb_test "print $L\"abcdefABCDEF012345\"" \ | |
31963 | + " = $L\"abcdefABCDEF012345\"" \ | |
31964 | "parse string literal in ${target_charset}" | |
31965 | ||
31966 | # Check that the string literal was encoded correctly. | |
31967 | - gdb_test "print \"q\"\[0\] == $var_name\[49\]" \ | |
31968 | + gdb_test "print $L\"q\"\[0\] == $var_name\[49\]" \ | |
31969 | " = 1" \ | |
31970 | "check value of parsed string literal in ${target_charset}" | |
31971 | ||
31972 | @@ -509,7 +486,7 @@ foreach target_charset [all_charset_names] { | |
31973 | send_gdb "print $var_name\[$i\]\n" | |
31974 | set have_escape 1 | |
31975 | gdb_expect { | |
31976 | - -re "= \[0-9-\]+ '\\\\${escape}'\[\r\n\]+$gdb_prompt $" { | |
31977 | + -re "= \[0-9-\]+ $L'\\\\${escape}'\[\r\n\]+$gdb_prompt $" { | |
31978 | pass "try printing '\\${escape}' in ${target_charset}" | |
31979 | } | |
31980 | -re "= \[0-9-\]+ 'x'\[\r\n\]+$gdb_prompt $" { | |
31981 | @@ -527,12 +504,12 @@ foreach target_charset [all_charset_names] { | |
31982 | if {$have_escape} { | |
31983 | ||
31984 | # Try parsing a backslash escape in a character literal. | |
31985 | - gdb_test "print '\\${escape}' == $var_name\[$i\]" \ | |
31986 | + gdb_test "print $L'\\${escape}' == $var_name\[$i\]" \ | |
31987 | " = 1" \ | |
31988 | "check value of '\\${escape}' in ${target_charset}" | |
31989 | ||
31990 | # Try parsing a backslash escape in a string literal. | |
31991 | - gdb_test "print \"\\${escape}\"\[0\] == $var_name\[$i\]" \ | |
31992 | + gdb_test "print $L\"\\${escape}\"\[0\] == $var_name\[$i\]" \ | |
31993 | " = 1" \ | |
31994 | "check value of \"\\${escape}\" in ${target_charset}" | |
31995 | } | |
31996 | @@ -540,10 +517,73 @@ foreach target_charset [all_charset_names] { | |
31997 | ||
31998 | # Try printing a character escape that doesn't exist. We should | |
31999 | # get the unescaped character, in the target character set. | |
32000 | - gdb_test "print '\\q'" " = \[0-9-\]+ 'q'" \ | |
32001 | + gdb_test "print $L'\\q'" " = \[0-9-\]+ $L'q'" \ | |
32002 | "print escape that doesn't exist in $target_charset" | |
32003 | - gdb_test "print '\\q' == $var_name\[49\]" " = 1" \ | |
32004 | + gdb_test "print $L'\\q' == $var_name\[49\]" " = 1" \ | |
32005 | "check value of escape that doesn't exist in $target_charset" | |
32006 | } | |
32007 | ||
32008 | +# Reset the target charset. | |
32009 | +gdb_test "set target-charset UTF-8" "" | |
32010 | + | |
32011 | +# \242 is not a valid UTF-8 character. | |
32012 | +gdb_test "print \"\\242\"" " = \"\\\\242\"" \ | |
32013 | + "non-representable target character" | |
32014 | + | |
32015 | +gdb_test "print '\\x'" "\\\\x escape without a following hex digit." | |
32016 | +gdb_test "print '\\u'" "\\\\u escape without a following hex digit." | |
32017 | +gdb_test "print '\\9'" " = \[0-9\]+ '9'" | |
32018 | + | |
32019 | +# Tests for wide- or unicode- strings. L is the prefix letter to use, | |
32020 | +# either "L" (for wide strings), "u" (for UCS-2), or "U" (for UCS-4). | |
32021 | +# NAME is used in the test names and should be related to the prefix | |
32022 | +# letter in some easy-to-undestand way. | |
32023 | +proc test_wide_or_unicode {L name} { | |
32024 | + gdb_test "print $L\"ab\" $L\"c\"" " = $L\"abc\"" \ | |
32025 | + "basic $name string concatenation" | |
32026 | + gdb_test "print $L\"ab\" \"c\"" " = $L\"abc\"" \ | |
32027 | + "narrow and $name string concatenation" | |
32028 | + gdb_test "print \"ab\" $L\"c\"" " = $L\"abc\"" \ | |
32029 | + "$name and narrow string concatenation" | |
32030 | + gdb_test "print $L\"\\xe\" $L\"c\"" " = $L\"\\\\16c\"" \ | |
32031 | + "$name string concatenation with escape" | |
32032 | + gdb_test "print $L\"\" \"abcdef\" \"g\"" \ | |
32033 | + "$L\"abcdefg\"" \ | |
32034 | + "concatenate three strings with empty $name string" | |
32035 | + | |
32036 | + gdb_test "print $L'a'" "= \[0-9\]+ $L'a'" \ | |
32037 | + "basic $name character" | |
32038 | +} | |
32039 | + | |
32040 | +if {$wchar_ok} { | |
32041 | + test_wide_or_unicode L wide | |
32042 | +} | |
32043 | + | |
32044 | +set ucs2_ok [expr {[get_sizeof char16_t 99] == 2}] | |
32045 | +if {$ucs2_ok} { | |
32046 | + test_wide_or_unicode u UCS-2 | |
32047 | +} | |
32048 | + | |
32049 | +set ucs4_ok [expr {[get_sizeof char32_t 99] == 4}] | |
32050 | +if {$ucs4_ok} { | |
32051 | + test_wide_or_unicode U UCS-4 | |
32052 | +} | |
32053 | + | |
32054 | +# Test an invalid string combination. | |
32055 | +proc test_combination {L1 name1 L2 name2} { | |
32056 | + gdb_test "print $L1\"abc\" $L2\"def\"" \ | |
32057 | + "Undefined string concatenation." \ | |
32058 | + "undefined concatenation of $name1 and $name2" | |
32059 | +} | |
32060 | + | |
32061 | +if {$wchar_ok && $ucs2_ok} { | |
32062 | + test_combination L wide u UCS-2 | |
32063 | +} | |
32064 | +if {$wchar_ok && $ucs4_ok} { | |
32065 | + test_combination L wide U UCS-4 | |
32066 | +} | |
32067 | +if {$ucs2_ok && $ucs4_ok} { | |
32068 | + test_combination u UCS-2 U UCS-4 | |
32069 | +} | |
32070 | + | |
32071 | gdb_exit | |
32072 | diff --git a/gdb/testsuite/gdb.base/constvars.exp b/gdb/testsuite/gdb.base/constvars.exp | |
32073 | index d53a826..6d1bd12 100644 | |
32074 | --- a/gdb/testsuite/gdb.base/constvars.exp | |
32075 | +++ b/gdb/testsuite/gdb.base/constvars.exp | |
32076 | @@ -161,7 +161,7 @@ proc do_constvar_tests {} { | |
32077 | gdb_test "print laconic" " = 65 'A'" | |
32078 | local_compiler_xfail_check | |
32079 | gdb_test "ptype laconic" "type = const char" | |
32080 | - gdb_test "print laggard" " = 1 '.001'" | |
32081 | + gdb_test "print laggard" " = 1 '.1'" | |
32082 | local_compiler_xfail_check | |
32083 | gdb_test "ptype laggard" "type = const unsigned char" | |
32084 | gdb_test "print lagoon" " = 2" | |
32085 | @@ -209,7 +209,7 @@ proc do_constvar_tests {} { | |
32086 | gdb_test "print *lewd" " = 65 'A'" | |
32087 | local_compiler_xfail_check | |
32088 | gdb_test "ptype lewd" "type = const char \\* const" | |
32089 | - gdb_test "print *lexicographer" " = 1 '.001'" | |
32090 | + gdb_test "print *lexicographer" " = 1 '.1'" | |
32091 | local_compiler_xfail_check | |
32092 | gdb_test "ptype lexicographer" "type = const unsigned char \\* const" | |
32093 | gdb_test "print *lexicon" " = 2" | |
32094 | @@ -233,7 +233,7 @@ proc do_constvar_tests {} { | |
32095 | gdb_test "print *languish" " = 65 'A'" | |
32096 | local_compiler_xfail_check | |
32097 | gdb_test "ptype languish" "type = const char \\*" | |
32098 | - gdb_test "print *languor" " = 1 '.001'" | |
32099 | + gdb_test "print *languor" " = 1 '.1'" | |
32100 | local_compiler_xfail_check | |
32101 | gdb_test "ptype languor" "type = const unsigned char \\*" | |
32102 | gdb_test "print *lank" " = 2" | |
32103 | diff --git a/gdb/testsuite/gdb.base/display.exp b/gdb/testsuite/gdb.base/display.exp | |
32104 | index d62e8bf..aa65373 100644 | |
32105 | --- a/gdb/testsuite/gdb.base/display.exp | |
32106 | +++ b/gdb/testsuite/gdb.base/display.exp | |
32107 | @@ -180,8 +180,12 @@ gdb_test "printf \"%p\\n\", 1" "0x1" | |
32108 | ||
32109 | # play with "print", too | |
32110 | # | |
32111 | -gdb_test "print/r j" ".*Undefined output format.*" | |
32112 | -gdb_test "print j" ".*" "debug test output" | |
32113 | +gdb_test "print/z j" ".*Undefined output format.*" | |
32114 | +gdb_test "print/d j" " = 0\[\\r\\n\]+" "debug test output 1" | |
32115 | +gdb_test "print/r j" " = 0\[\\r\\n\]+" "debug test output 1a" | |
32116 | +gdb_test "print/x j" " = 0x0\[\\r\\n\]+" "debug test output 2" | |
32117 | +gdb_test "print/r j" " = 0x0\[\\r\\n\]+" "debug test output 2a" | |
32118 | +gdb_test "print j" " = 0\[\\r\\n\]+" "debug test output 3" | |
32119 | ||
32120 | # x/0 j doesn't produce any output and terminates PA64 process when testing | |
32121 | if [istarget "hppa2.0w-hp-hpux11*"] { | |
32122 | diff --git a/gdb/testsuite/gdb.base/help.exp b/gdb/testsuite/gdb.base/help.exp | |
32123 | index 4618a2c..40830c3 100644 | |
32124 | --- a/gdb/testsuite/gdb.base/help.exp | |
32125 | +++ b/gdb/testsuite/gdb.base/help.exp | |
32126 | @@ -603,7 +603,7 @@ gdb_test "help stepi" "Step one instruction exactly\.\[\r\n\]+Argument N means d | |
32127 | gdb_test "help signal" "Continue program giving it signal.*" "help signal" | |
32128 | # test help source | |
32129 | # vxgdb reads .vxgdbinit | |
32130 | -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" | |
32131 | +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" | |
32132 | # test help stack | |
32133 | test_class_help "stack" { | |
32134 | "Examining the stack\..*\[\r\n\]+" | |
32135 | diff --git a/gdb/testsuite/gdb.base/lineno-makeup-func.c b/gdb/testsuite/gdb.base/lineno-makeup-func.c | |
32136 | new file mode 100644 | |
32137 | index 0000000..1a0220e | |
32138 | --- /dev/null | |
32139 | +++ b/gdb/testsuite/gdb.base/lineno-makeup-func.c | |
32140 | @@ -0,0 +1,21 @@ | |
32141 | +/* This testcase is part of GDB, the GNU debugger. | |
32142 | + | |
32143 | + Copyright 2009 Free Software Foundation, Inc. | |
32144 | + | |
32145 | + This program is free software; you can redistribute it and/or modify | |
32146 | + it under the terms of the GNU General Public License as published by | |
32147 | + the Free Software Foundation; either version 3 of the License, or | |
32148 | + (at your option) any later version. | |
32149 | + | |
32150 | + This program is distributed in the hope that it will be useful, | |
32151 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32152 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32153 | + GNU General Public License for more details. | |
32154 | + | |
32155 | + You should have received a copy of the GNU General Public License | |
32156 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
32157 | + | |
32158 | +void | |
32159 | +func (void) | |
32160 | +{ | |
32161 | +} | |
32162 | diff --git a/gdb/testsuite/gdb.base/lineno-makeup.c b/gdb/testsuite/gdb.base/lineno-makeup.c | |
32163 | new file mode 100644 | |
32164 | index 0000000..bb20e98 | |
32165 | --- /dev/null | |
32166 | +++ b/gdb/testsuite/gdb.base/lineno-makeup.c | |
32167 | @@ -0,0 +1,35 @@ | |
32168 | +/* This testcase is part of GDB, the GNU debugger. | |
32169 | + | |
32170 | + Copyright 2009 Free Software Foundation, Inc. | |
32171 | + | |
32172 | + This program is free software; you can redistribute it and/or modify | |
32173 | + it under the terms of the GNU General Public License as published by | |
32174 | + the Free Software Foundation; either version 3 of the License, or | |
32175 | + (at your option) any later version. | |
32176 | + | |
32177 | + This program is distributed in the hope that it will be useful, | |
32178 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32179 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32180 | + GNU General Public License for more details. | |
32181 | + | |
32182 | + You should have received a copy of the GNU General Public License | |
32183 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
32184 | + | |
32185 | +/* DW_AT_low_pc-DW_AT_high_pc should cover the function without line number | |
32186 | + information (.debug_line) so we cannot use an external object file. | |
32187 | + | |
32188 | + It must not be just a label as it would alias on the next function even for | |
32189 | + correct GDB. Therefore some stub data must be placed there. | |
32190 | + | |
32191 | + We need to provide a real stub function body as at least s390 | |
32192 | + (s390_analyze_prologue) would skip the whole body till reaching `main'. */ | |
32193 | + | |
32194 | +extern void func (void); | |
32195 | +asm ("func: .incbin \"gdb.base/lineno-makeup-func.bin\""); | |
32196 | + | |
32197 | +int | |
32198 | +main (void) | |
32199 | +{ | |
32200 | + func (); | |
32201 | + return 0; | |
32202 | +} | |
32203 | diff --git a/gdb/testsuite/gdb.base/lineno-makeup.exp b/gdb/testsuite/gdb.base/lineno-makeup.exp | |
32204 | new file mode 100644 | |
32205 | index 0000000..0c75b84 | |
32206 | --- /dev/null | |
32207 | +++ b/gdb/testsuite/gdb.base/lineno-makeup.exp | |
32208 | @@ -0,0 +1,78 @@ | |
32209 | +# Copyright 2009 Free Software Foundation, Inc. | |
32210 | + | |
32211 | +# This program is free software; you can redistribute it and/or modify | |
32212 | +# it under the terms of the GNU General Public License as published by | |
32213 | +# the Free Software Foundation; either version 3 of the License, or | |
32214 | +# (at your option) any later version. | |
32215 | +# | |
32216 | +# This program is distributed in the hope that it will be useful, | |
32217 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32218 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32219 | +# GNU General Public License for more details. | |
32220 | +# | |
32221 | +# You should have received a copy of the GNU General Public License | |
32222 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
32223 | + | |
32224 | +set testfile "lineno-makeup" | |
32225 | +set srcfuncfile ${testfile}-func.c | |
32226 | +set srcfile ${testfile}.c | |
32227 | +set objfuncfile ${objdir}/${subdir}/${testfile}-func.o | |
32228 | +set binfuncfile ${objdir}/${subdir}/${testfile}-func.bin | |
32229 | +set binfile ${objdir}/${subdir}/${testfile} | |
32230 | + | |
32231 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfuncfile}" "${objfuncfile}" object {}] != "" } { | |
32232 | + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." | |
32233 | +} | |
32234 | + | |
32235 | +set objcopy [catch "exec objcopy -O binary --only-section .text ${objfuncfile} ${binfuncfile}" output] | |
32236 | +verbose -log "objcopy=$objcopy: $output" | |
32237 | +if { $objcopy != 0 } { | |
32238 | + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." | |
32239 | +} | |
32240 | +set binfuncfilesize [file size $binfuncfile] | |
32241 | +verbose -log "file size $binfuncfile = $binfuncfilesize" | |
32242 | + | |
32243 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
32244 | + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." | |
32245 | +} | |
32246 | + | |
32247 | +gdb_exit | |
32248 | +gdb_start | |
32249 | +gdb_reinitialize_dir $srcdir/$subdir | |
32250 | +gdb_load ${binfile} | |
32251 | + | |
32252 | +set b_addr "" | |
32253 | +set test "break func" | |
32254 | +gdb_test_multiple $test $test { | |
32255 | + -re "Breakpoint \[0-9\]+ at (0x\[0-9a-f\]+)\r\n$gdb_prompt $" { | |
32256 | + set b_addr $expect_out(1,string) | |
32257 | + pass $test | |
32258 | + } | |
32259 | + -re "Breakpoint \[0-9\]+ at (0x\[0-9a-f\]+): .*\r\n$gdb_prompt $" { | |
32260 | + set b_addr $expect_out(1,string) | |
32261 | + fail $test | |
32262 | + } | |
32263 | +} | |
32264 | +verbose -log "b_addr=<$b_addr>" | |
32265 | + | |
32266 | +set p_addr "" | |
32267 | +set test "print func" | |
32268 | +gdb_test_multiple $test $test { | |
32269 | + -re "\\$\[0-9\]+ = {<text variable, no debug info>} (0x\[0-9a-f\]+) <func>\r\n$gdb_prompt $" { | |
32270 | + set p_addr $expect_out(1,string) | |
32271 | + pass $test | |
32272 | + } | |
32273 | +} | |
32274 | +verbose -log "p_addr=<$p_addr>" | |
32275 | + | |
32276 | +set test "break address belongs to func" | |
32277 | +if {$b_addr == $p_addr} { | |
32278 | + pass "$test (exact match)" | |
32279 | +} else { | |
32280 | + set skip [expr $b_addr - $p_addr] | |
32281 | + if {$skip > 0 && $skip < $binfuncfilesize} { | |
32282 | + pass "$test (prologue skip by $skip bytes)" | |
32283 | + } else { | |
32284 | + fail $test | |
32285 | + } | |
32286 | +} | |
32287 | diff --git a/gdb/testsuite/gdb.base/long_long.exp b/gdb/testsuite/gdb.base/long_long.exp | |
32288 | index d0ad5ba..5189324 100644 | |
32289 | --- a/gdb/testsuite/gdb.base/long_long.exp | |
32290 | +++ b/gdb/testsuite/gdb.base/long_long.exp | |
32291 | @@ -210,7 +210,7 @@ gdb_test_char "p/o *(char *)c" "01" | |
32292 | gdb_test_char "p/t *(char *)c" "1" | |
32293 | gdb_test_char "p/a *(char *)c" "0x1( <.*>)?" | |
32294 | gdb_test_char "p/f *(char *)c" "1" | |
32295 | -gdb_test_char "p/c *(char *)c" "1 '.001'" | |
32296 | +gdb_test_char "p/c *(char *)c" "1 '.1'" | |
32297 | ||
32298 | gdb_test_short "p/x *(short *)s" "" "0x123" "" | |
32299 | gdb_test_short "p/d *(short *)s" "" "291" "" | |
32300 | @@ -257,7 +257,7 @@ gdb_test "x/u w" "19088743" | |
32301 | gdb_test "x/o w" "0110642547" | |
32302 | gdb_test "x/t w" "00000001001000110100010101100111" | |
32303 | gdb_test_xptr "x/a" { b "" } { h "" } { w "0x1234567" } { g "0x123456789abcdef" } | |
32304 | -gdb_test "x/c b" "1 '.001'" | |
32305 | +gdb_test "x/c b" "1 '.1'" | |
32306 | if { $sizeof_double == 8 || $sizeof_long_double == 8 } { | |
32307 | gdb_test "x/f &val.oct" "-5.9822653797615723e-120" | |
32308 | } else { | |
32309 | @@ -273,7 +273,7 @@ gdb_test "x/2u g" "81985529216486895.*12046818088235383159" | |
32310 | gdb_test "x/2o g" "04432126361152746757.*01234567123456701234567" | |
32311 | gdb_test "x/2t g" "0000000100100011010001010110011110001001101010111100110111101111.*1010011100101110111001010011100101110111000001010011100101110111" | |
32312 | gdb_test_xptr "x/2a" { b "" } { h "" } { w "0x1234567.*0xa72ee539" } { g "0x123456789abcdef.*0xa72ee53977053977" } | |
32313 | -gdb_test "x/2c b" "1 '.001'.*-89 '.'" | |
32314 | +gdb_test "x/2c b" "1 '.1'.*-89 '.\[0-9\]*'" | |
32315 | if { $sizeof_double == 8 || $sizeof_long_double == 8 } { | |
32316 | gdb_test "x/2f &val.oct" "-5.9822653797615723e-120.*-5.9041889495880968e-100" | |
32317 | } else { | |
32318 | @@ -288,7 +288,7 @@ gdb_test "x/2bu b" "1.*167" | |
32319 | gdb_test "x/2bo b" "01.*0247" | |
32320 | gdb_test "x/2bt b" "00000001.*10100111" | |
32321 | gdb_test_ptr "x/2ba b" "" "" "0x1.*0xffffffa7" "0x1.*0xffffffffffffffa7" | |
32322 | -gdb_test "x/2bc b" "1 '.001'.*-89 '.'" | |
32323 | +gdb_test "x/2bc b" "1 '.1'.*-89 '.\[0-9\]*'" | |
32324 | gdb_test "x/2bf b" "1.*-89" | |
32325 | ||
32326 | gdb_test "x/2hx h" "0x0123.*0xa72e" | |
32327 | @@ -315,7 +315,7 @@ gdb_test "x/2gu g" "81985529216486895.*12046818088235383159" | |
32328 | gdb_test "x/2go g" "04432126361152746757.*01234567123456701234567" | |
32329 | gdb_test "x/2gt g" "0000000100100011010001010110011110001001101010111100110111101111.*1010011100101110111001010011100101110111000001010011100101110111" | |
32330 | gdb_test_ptr "x/2ga g" "" "" "0x89abcdef.*0x77053977" "0x123456789abcdef.*0xa72ee53977053977" | |
32331 | -gdb_test "x/2gc g" "-17 '.'.*119 'w'" | |
32332 | +gdb_test "x/2gc g" "-17 '.\[0-9\]*'.*119 'w'" | |
32333 | gdb_test "x/2gf g" "3.5127005640885037e-303.*-5.9822653797615723e-120" | |
32334 | ||
32335 | gdb_exit | |
32336 | diff --git a/gdb/testsuite/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp | |
32337 | index 7086e90..dd196d7 100644 | |
32338 | --- a/gdb/testsuite/gdb.base/macscp.exp | |
32339 | +++ b/gdb/testsuite/gdb.base/macscp.exp | |
32340 | @@ -26,13 +26,21 @@ set testfile "macscp" | |
32341 | set objfile ${objdir}/${subdir}/${testfile}.o | |
32342 | set binfile ${objdir}/${subdir}/${testfile} | |
32343 | ||
32344 | -set options { debug } | |
32345 | +set options { debug additional_flags=-DFROM_COMMANDLINE=ARG} | |
32346 | ||
32347 | get_compiler_info ${binfile} | |
32348 | if [test_compiler_info gcc*] { | |
32349 | lappend options additional_flags=-g3 | |
32350 | } | |
32351 | ||
32352 | +# Workaround ccache making lineno non-zero for command-line definitions. | |
32353 | +if {[find_gcc] == "gcc" && [file executable "/usr/bin/gcc"]} { | |
32354 | + set result [catch "exec which gcc" output] | |
32355 | + if {$result == 0 && [string first "/ccache/" $output] >= -1} { | |
32356 | + lappend options "compiler=/usr/bin/gcc" | |
32357 | + } | |
32358 | +} | |
32359 | + | |
32360 | # Generate the intermediate object file. This is required by Darwin to | |
32361 | # have access to the .debug_macinfo section. | |
32362 | if {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${objfile}" \ | |
32363 | @@ -79,11 +87,15 @@ proc info_macro {macro} { | |
32364 | ||
32365 | if {$debug_me} {exp_internal 1} | |
32366 | gdb_expect { | |
32367 | - -re "Defined at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" { | |
32368 | + -re "Defined at \[^\r\n\]*(${filepat}):(${decimal})\[\r\n\]" { | |
32369 | # `location' and `definition' should be empty when we see | |
32370 | # this message. | |
32371 | if {[llength $location] == 0 && [llength $definition] == 0} { | |
32372 | set location $expect_out(1,string) | |
32373 | + # Definitions from gcc command-line get suffixed by the lineno. | |
32374 | + if {$expect_out(2,string) == "0" } { | |
32375 | + set location "$location:$expect_out(2,string)" | |
32376 | + } | |
32377 | exp_continue | |
32378 | } else { | |
32379 | # Exit this expect loop, with a result indicating failure. | |
32380 | @@ -198,6 +210,8 @@ proc list_and_check_macro {func macro expected} { | |
32381 | } | |
32382 | ||
32383 | ||
32384 | +list_and_check_macro main FROM_COMMANDLINE "macscp1.c:0 ARG" | |
32385 | + | |
32386 | if {[list_and_check_macro main WHERE {macscp1.c {before macscp1_3}}]} { | |
32387 | return 0 | |
32388 | } | |
32389 | diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp | |
32390 | index 4c01be4..31fb88e 100644 | |
32391 | --- a/gdb/testsuite/gdb.base/nodebug.exp | |
32392 | +++ b/gdb/testsuite/gdb.base/nodebug.exp | |
32393 | @@ -215,5 +215,12 @@ if [runto inner] then { | |
32394 | if [runto middle] then { | |
32395 | gdb_test "backtrace 10" "#0.*middle.*#1.*top.*#2.*main.*" \ | |
32396 | "backtrace from middle in nodebug.exp" | |
32397 | + | |
32398 | + # Test return from a function with no debug info (symbol; still it may | |
32399 | + # have a minimal-symbol). In gdb.base/return*.exp we would need to | |
32400 | + # build a separate executable with no "debug" option. | |
32401 | + gdb_test "return 0" "#0 .* top \\(.*" \ | |
32402 | + "return from function with no debug info" \ | |
32403 | + "Make selected stack frame return now\\? \\(y or n\\) " "y" | |
32404 | } | |
32405 | } | |
32406 | diff --git a/gdb/testsuite/gdb.base/pointers.exp b/gdb/testsuite/gdb.base/pointers.exp | |
32407 | index 91838a2..2d0a70e 100644 | |
32408 | --- a/gdb/testsuite/gdb.base/pointers.exp | |
32409 | +++ b/gdb/testsuite/gdb.base/pointers.exp | |
32410 | @@ -389,7 +389,7 @@ gdb_expect { | |
32411 | ||
32412 | send_gdb "print *pUC\n" | |
32413 | gdb_expect { | |
32414 | - -re ".\[0-9\]* = 21 \'.025\'.*$gdb_prompt $" { | |
32415 | + -re ".\[0-9\]* = 21 \'.25\'.*$gdb_prompt $" { | |
32416 | pass "print value of *pUC" | |
32417 | } | |
32418 | -re ".*$gdb_prompt $" { fail "print value of *pUC" } | |
32419 | diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp | |
32420 | index 1e17da4..b6f8a1f 100644 | |
32421 | --- a/gdb/testsuite/gdb.base/printcmds.exp | |
32422 | +++ b/gdb/testsuite/gdb.base/printcmds.exp | |
32423 | @@ -137,12 +137,12 @@ proc test_print_all_chars {} { | |
32424 | global gdb_prompt | |
32425 | ||
32426 | gdb_test "p ctable1\[0\]" " = 0 '\\\\0'" | |
32427 | - gdb_test "p ctable1\[1\]" " = 1 '\\\\001'" | |
32428 | - gdb_test "p ctable1\[2\]" " = 2 '\\\\002'" | |
32429 | - gdb_test "p ctable1\[3\]" " = 3 '\\\\003'" | |
32430 | - gdb_test "p ctable1\[4\]" " = 4 '\\\\004'" | |
32431 | - gdb_test "p ctable1\[5\]" " = 5 '\\\\005'" | |
32432 | - gdb_test "p ctable1\[6\]" " = 6 '\\\\006'" | |
32433 | + gdb_test "p ctable1\[1\]" " = 1 '\\\\1'" | |
32434 | + gdb_test "p ctable1\[2\]" " = 2 '\\\\2'" | |
32435 | + gdb_test "p ctable1\[3\]" " = 3 '\\\\3'" | |
32436 | + gdb_test "p ctable1\[4\]" " = 4 '\\\\4'" | |
32437 | + gdb_test "p ctable1\[5\]" " = 5 '\\\\5'" | |
32438 | + gdb_test "p ctable1\[6\]" " = 6 '\\\\6'" | |
32439 | gdb_test "p ctable1\[7\]" " = 7 '\\\\a'" | |
32440 | gdb_test "p ctable1\[8\]" " = 8 '\\\\b'" | |
32441 | gdb_test "p ctable1\[9\]" " = 9 '\\\\t'" | |
32442 | @@ -150,24 +150,24 @@ proc test_print_all_chars {} { | |
32443 | gdb_test "p ctable1\[11\]" " = 11 '\\\\v'" | |
32444 | gdb_test "p ctable1\[12\]" " = 12 '\\\\f'" | |
32445 | gdb_test "p ctable1\[13\]" " = 13 '\\\\r'" | |
32446 | - gdb_test "p ctable1\[14\]" " = 14 '\\\\016'" | |
32447 | - gdb_test "p ctable1\[15\]" " = 15 '\\\\017'" | |
32448 | - gdb_test "p ctable1\[16\]" " = 16 '\\\\020'" | |
32449 | - gdb_test "p ctable1\[17\]" " = 17 '\\\\021'" | |
32450 | - gdb_test "p ctable1\[18\]" " = 18 '\\\\022'" | |
32451 | - gdb_test "p ctable1\[19\]" " = 19 '\\\\023'" | |
32452 | - gdb_test "p ctable1\[20\]" " = 20 '\\\\024'" | |
32453 | - gdb_test "p ctable1\[21\]" " = 21 '\\\\025'" | |
32454 | - gdb_test "p ctable1\[22\]" " = 22 '\\\\026'" | |
32455 | - gdb_test "p ctable1\[23\]" " = 23 '\\\\027'" | |
32456 | - gdb_test "p ctable1\[24\]" " = 24 '\\\\030'" | |
32457 | - gdb_test "p ctable1\[25\]" " = 25 '\\\\031'" | |
32458 | - gdb_test "p ctable1\[26\]" " = 26 '\\\\032'" | |
32459 | - gdb_test "p ctable1\[27\]" " = 27 '\\\\033'" | |
32460 | - gdb_test "p ctable1\[28\]" " = 28 '\\\\034'" | |
32461 | - gdb_test "p ctable1\[29\]" " = 29 '\\\\035'" | |
32462 | - gdb_test "p ctable1\[30\]" " = 30 '\\\\036'" | |
32463 | - gdb_test "p ctable1\[31\]" " = 31 '\\\\037'" | |
32464 | + gdb_test "p ctable1\[14\]" " = 14 '\\\\16'" | |
32465 | + gdb_test "p ctable1\[15\]" " = 15 '\\\\17'" | |
32466 | + gdb_test "p ctable1\[16\]" " = 16 '\\\\20'" | |
32467 | + gdb_test "p ctable1\[17\]" " = 17 '\\\\21'" | |
32468 | + gdb_test "p ctable1\[18\]" " = 18 '\\\\22'" | |
32469 | + gdb_test "p ctable1\[19\]" " = 19 '\\\\23'" | |
32470 | + gdb_test "p ctable1\[20\]" " = 20 '\\\\24'" | |
32471 | + gdb_test "p ctable1\[21\]" " = 21 '\\\\25'" | |
32472 | + gdb_test "p ctable1\[22\]" " = 22 '\\\\26'" | |
32473 | + gdb_test "p ctable1\[23\]" " = 23 '\\\\27'" | |
32474 | + gdb_test "p ctable1\[24\]" " = 24 '\\\\30'" | |
32475 | + gdb_test "p ctable1\[25\]" " = 25 '\\\\31'" | |
32476 | + gdb_test "p ctable1\[26\]" " = 26 '\\\\32'" | |
32477 | + gdb_test "p ctable1\[27\]" " = 27 '\\\\33'" | |
32478 | + gdb_test "p ctable1\[28\]" " = 28 '\\\\34'" | |
32479 | + gdb_test "p ctable1\[29\]" " = 29 '\\\\35'" | |
32480 | + gdb_test "p ctable1\[30\]" " = 30 '\\\\36'" | |
32481 | + gdb_test "p ctable1\[31\]" " = 31 '\\\\37'" | |
32482 | gdb_test "p ctable1\[32\]" " = 32 ' '" | |
32483 | gdb_test "p ctable1\[33\]" " = 33 '!'" | |
32484 | gdb_test "p ctable1\[34\]" " = 34 '\"'" | |
32485 | @@ -475,13 +475,13 @@ proc test_print_strings {} { | |
32486 | gdb_test "p &ctable1\[0\]" \ | |
32487 | " = \\(unsigned char \\*\\) \"\"" | |
32488 | gdb_test "p &ctable1\[1\]" \ | |
32489 | - " = \\(unsigned char \\*\\) \"\\\\001\\\\002\\\\003\\\\004\\\\005\\\\006\\\\a\\\\b\"..." | |
32490 | + " = \\(unsigned char \\*\\) \"\\\\1\\\\2\\\\3\\\\4\\\\5\\\\6\\\\a\\\\b\"..." | |
32491 | gdb_test "p &ctable1\[1*8\]" \ | |
32492 | - " = \\(unsigned char \\*\\) \"\\\\b\\\\t\\\\n\\\\v\\\\f\\\\r\\\\016\\\\017\"..." | |
32493 | + " = \\(unsigned char \\*\\) \"\\\\b\\\\t\\\\n\\\\v\\\\f\\\\r\\\\16\\\\17\"..." | |
32494 | gdb_test "p &ctable1\[2*8\]" \ | |
32495 | - " = \\(unsigned char \\*\\) \"\\\\020\\\\021\\\\022\\\\023\\\\024\\\\025\\\\026\\\\027\"..." | |
32496 | + " = \\(unsigned char \\*\\) \"\\\\20\\\\21\\\\22\\\\23\\\\24\\\\25\\\\26\\\\27\"..." | |
32497 | gdb_test "p &ctable1\[3*8\]" \ | |
32498 | - " = \\(unsigned char \\*\\) \"\\\\030\\\\031\\\\032\\\\033\\\\034\\\\035\\\\036\\\\037\"..." | |
32499 | + " = \\(unsigned char \\*\\) \"\\\\30\\\\31\\\\32\\\\33\\\\34\\\\35\\\\36\\\\37\"..." | |
32500 | gdb_test "p &ctable1\[4*8\]" \ | |
32501 | " = \\(unsigned char \\*\\) \" !\\\\\"#\\\$%&'\"..." | |
32502 | gdb_test "p &ctable1\[5*8\]" \ | |
32503 | @@ -622,7 +622,7 @@ proc test_print_string_constants {} { | |
32504 | set timeout 60; | |
32505 | ||
32506 | gdb_test "p \"a string\"" " = \"a string\"" | |
32507 | - gdb_test "p \"embedded \\000 null\"" " = \"embedded \\\\000 null\"" | |
32508 | + gdb_test "p \"embedded \\000 null\"" " = \"embedded \\\\0 null\"" | |
32509 | gdb_test "p \"abcd\"\[2\]" " = 99 'c'" | |
32510 | gdb_test "p sizeof (\"abcdef\")" " = 7" | |
32511 | gdb_test "ptype \"foo\"" " = char \\\[4\\\]" | |
32512 | diff --git a/gdb/testsuite/gdb.base/return-nodebug.c b/gdb/testsuite/gdb.base/return-nodebug.c | |
32513 | new file mode 100644 | |
32514 | index 0000000..e1211b3 | |
32515 | --- /dev/null | |
32516 | +++ b/gdb/testsuite/gdb.base/return-nodebug.c | |
32517 | @@ -0,0 +1,49 @@ | |
32518 | +/* This testcase is part of GDB, the GNU debugger. | |
32519 | + | |
32520 | + Copyright 2009 Free Software Foundation, Inc. | |
32521 | + | |
32522 | + This program is free software; you can redistribute it and/or modify | |
32523 | + it under the terms of the GNU General Public License as published by | |
32524 | + the Free Software Foundation; either version 3 of the License, or | |
32525 | + (at your option) any later version. | |
32526 | + | |
32527 | + This program is distributed in the hope that it will be useful, | |
32528 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32529 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32530 | + GNU General Public License for more details. | |
32531 | + | |
32532 | + You should have received a copy of the GNU General Public License | |
32533 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
32534 | + | |
32535 | +#include <stdio.h> | |
32536 | + | |
32537 | +static TYPE | |
32538 | +init (void) | |
32539 | +{ | |
32540 | + return 0; | |
32541 | +} | |
32542 | + | |
32543 | +static TYPE | |
32544 | +func (void) | |
32545 | +{ | |
32546 | + return 31; | |
32547 | +} | |
32548 | + | |
32549 | +static void | |
32550 | +marker (void) | |
32551 | +{ | |
32552 | +} | |
32553 | + | |
32554 | +int | |
32555 | +main (void) | |
32556 | +{ | |
32557 | + /* Preinitialize registers to 0 to avoid false PASS by leftover garbage. */ | |
32558 | + init (); | |
32559 | + | |
32560 | + printf ("result=" FORMAT "\n", CAST func ()); | |
32561 | + | |
32562 | + /* Cannot `next' with no debug info. */ | |
32563 | + marker (); | |
32564 | + | |
32565 | + return 0; | |
32566 | +} | |
32567 | diff --git a/gdb/testsuite/gdb.base/return-nodebug.exp b/gdb/testsuite/gdb.base/return-nodebug.exp | |
32568 | new file mode 100644 | |
32569 | index 0000000..6f32aa9 | |
32570 | --- /dev/null | |
32571 | +++ b/gdb/testsuite/gdb.base/return-nodebug.exp | |
32572 | @@ -0,0 +1,54 @@ | |
32573 | +# Copyright (C) 2009 Free Software Foundation, Inc. | |
32574 | + | |
32575 | +# This program is free software; you can redistribute it and/or modify | |
32576 | +# it under the terms of the GNU General Public License as published by | |
32577 | +# the Free Software Foundation; either version 3 of the License, or | |
32578 | +# (at your option) any later version. | |
32579 | +# | |
32580 | +# This program is distributed in the hope that it will be useful, | |
32581 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32582 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32583 | +# GNU General Public License for more details. | |
32584 | +# | |
32585 | +# You should have received a copy of the GNU General Public License | |
32586 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
32587 | + | |
32588 | +proc do_test {type} { | |
32589 | + set typenospace [string map {{ } -} $type] | |
32590 | + | |
32591 | + global pf_prefix | |
32592 | + set old_prefix $pf_prefix | |
32593 | + lappend pf_prefix "$typenospace:" | |
32594 | + | |
32595 | + if {[runto "func"]} { | |
32596 | + # Test return from a function with no debug info (symbol; still it may | |
32597 | + # have a minimal-symbol) if it does not crash. | |
32598 | + gdb_test "return -1" "#0 .* main \\(.*" \ | |
32599 | + "return from function with no debug info" \ | |
32600 | + "Make selected stack frame return now\\? \\(y or n\\) " "y" | |
32601 | + | |
32602 | + # And if it returned the full width of the result. | |
32603 | + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ | |
32604 | + "full width of the returned result" | |
32605 | + } | |
32606 | + | |
32607 | + set pf_prefix $old_prefix | |
32608 | +} | |
32609 | + | |
32610 | +foreach case {{{signed char} %d (int)} \ | |
32611 | + {{short} %d (int)} \ | |
32612 | + {{int} %d} \ | |
32613 | + {{long} %ld} \ | |
32614 | + {{long long} %lld}} { | |
32615 | + set type [lindex $case 0] | |
32616 | + set format [lindex $case 1] | |
32617 | + set cast [lindex $case 2] | |
32618 | + | |
32619 | + set typeesc [string map {{ } {\ }} $type] | |
32620 | + set typenospace [string map {{ } -} $type] | |
32621 | + | |
32622 | + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ | |
32623 | + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { | |
32624 | + do_test $type | |
32625 | + } | |
32626 | +} | |
32627 | diff --git a/gdb/testsuite/gdb.base/setvar.exp b/gdb/testsuite/gdb.base/setvar.exp | |
32628 | index 2350a33..3be8424 100644 | |
32629 | --- a/gdb/testsuite/gdb.base/setvar.exp | |
32630 | +++ b/gdb/testsuite/gdb.base/setvar.exp | |
32631 | @@ -121,7 +121,7 @@ proc test_set { args } { | |
32632 | # | |
32633 | ||
32634 | test_set "set variable v_char=0" "print v_char" ".\[0-9\]* = 0 \'.0\'" "set variable char=0" | |
32635 | -test_set "set variable v_char=1" "print v_char" ".\[0-9\]* = 1 \'.001\'" "set variable char=1" | |
32636 | +test_set "set variable v_char=1" "print v_char" ".\[0-9\]* = 1 \'.1\'" "set variable char=1" | |
32637 | test_set "set variable v_char=7" "print v_char" ".\[0-9\]* = 7 \'.a\'" "set variable char=7 (Bel)" | |
32638 | test_set "set variable v_char=32" "print v_char" ".\[0-9\]* = 32 \' \'" "set variable char=32 (SPC)" | |
32639 | test_set "set variable v_char=65" "print v_char" ".\[0-9\]* = 65 \'A\'" "set variable char=65 ('A')" | |
32640 | @@ -132,7 +132,7 @@ test_set "set variable v_char=127" "print v_char" ".\[0-9\]* = 127 \'.177\'" | |
32641 | # test "set variable" for type "signed char" | |
32642 | # | |
32643 | test_set "set variable v_char=0" "print v_signed_char" ".\[0-9\]* = 0 \'.0\'" "set variable signed char=0" | |
32644 | -test_set "set variable v_signed_char=1" "print v_signed_char" ".\[0-9\]* = 1 \'.001\'" "set variable signed char=1" | |
32645 | +test_set "set variable v_signed_char=1" "print v_signed_char" ".\[0-9\]* = 1 \'.1\'" "set variable signed char=1" | |
32646 | test_set "set variable v_signed_char=7" "print v_signed_char" ".\[0-9\]* = 7 \'.a\'" "set variable signed char=7 (Bel)" | |
32647 | test_set "set variable v_signed_char=32" "print v_signed_char" ".\[0-9\]* = 32 \' \'" "set variable signed char=32 (SPC)" | |
32648 | test_set "set variable v_signed_char=65" "print v_signed_char" ".\[0-9\]* = 65 \'A\'" "set variable signed char=65 ('A')" | |
32649 | @@ -151,7 +151,7 @@ gdb_test "print v_signed_char" ".\[0-9\]* = -1 \'.377\'" \ | |
32650 | # test "set variable" for type "unsigned char" | |
32651 | # | |
32652 | test_set "set variable v_unsigned_char=0" "print v_unsigned_char" ".\[0-9\]* = 0 \'.0\'" "set variable unsigned char=0" | |
32653 | -test_set "set variable v_unsigned_char=1" "print v_unsigned_char" ".\[0-9\]* = 1 \'.001\'" "set variable unsigned char=1" | |
32654 | +test_set "set variable v_unsigned_char=1" "print v_unsigned_char" ".\[0-9\]* = 1 \'.1\'" "set variable unsigned char=1" | |
32655 | test_set "set variable v_unsigned_char=7" "print v_unsigned_char" ".\[0-9\]* = 7 \'.a\'" "set variable unsigned char=7 (Bel)" | |
32656 | test_set "set variable v_unsigned_char=32" "print v_unsigned_char" ".\[0-9\]* = 32 \' \'" "set variable unsigned char=32 (SPC)" | |
32657 | test_set "set variable v_unsigned_char=65" "print v_unsigned_char" ".\[0-9\]* = 65 \'A\'" "set variable unsigned char=65 ('A')" | |
32658 | diff --git a/gdb/testsuite/gdb.base/store.exp b/gdb/testsuite/gdb.base/store.exp | |
32659 | index 963bb19..feab6bd 100644 | |
32660 | --- a/gdb/testsuite/gdb.base/store.exp | |
32661 | +++ b/gdb/testsuite/gdb.base/store.exp | |
32662 | @@ -74,7 +74,7 @@ proc check_set { t l r new add } { | |
32663 | "${prefix}; print incremented l, expecting ${add}" | |
32664 | } | |
32665 | ||
32666 | -check_set "charest" "-1 .*" "-2 .*" "4 ..004." "2 ..002." | |
32667 | +check_set "charest" "-1 .*" "-2 .*" "4 ..4." "2 ..2." | |
32668 | check_set "short" "-1" "-2" "4" "2" | |
32669 | check_set "int" "-1" "-2" "4" "2" | |
32670 | check_set "long" "-1" "-2" "4" "2" | |
32671 | @@ -102,7 +102,7 @@ proc up_set { t l r new } { | |
32672 | "${prefix}; print new l, expecting ${new}" | |
32673 | } | |
32674 | ||
32675 | -up_set "charest" "-1 .*" "-2 .*" "4 ..004." | |
32676 | +up_set "charest" "-1 .*" "-2 .*" "4 ..4." | |
32677 | up_set "short" "-1" "-2" "4" | |
32678 | up_set "int" "-1" "-2" "4" | |
32679 | up_set "long" "-1" "-2" "4" | |
32680 | diff --git a/gdb/testsuite/gdb.base/valgrind-attach.c b/gdb/testsuite/gdb.base/valgrind-attach.c | |
32681 | new file mode 100644 | |
32682 | index 0000000..84b57db | |
32683 | --- /dev/null | |
32684 | +++ b/gdb/testsuite/gdb.base/valgrind-attach.c | |
32685 | @@ -0,0 +1,28 @@ | |
32686 | +/* This testcase is part of GDB, the GNU debugger. | |
32687 | + | |
32688 | + Copyright 2009 Free Software Foundation, Inc. | |
32689 | + | |
32690 | + This program is free software; you can redistribute it and/or modify | |
32691 | + it under the terms of the GNU General Public License as published by | |
32692 | + the Free Software Foundation; either version 3 of the License, or | |
32693 | + (at your option) any later version. | |
32694 | + | |
32695 | + This program is distributed in the hope that it will be useful, | |
32696 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32697 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32698 | + GNU General Public License for more details. | |
32699 | + | |
32700 | + You should have received a copy of the GNU General Public License | |
32701 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
32702 | + | |
32703 | +#include <stdlib.h> | |
32704 | + | |
32705 | +int | |
32706 | +main (void) | |
32707 | +{ | |
32708 | + int *a = malloc (1); | |
32709 | + | |
32710 | + a[10] = 0; /* crash-here */ | |
32711 | + | |
32712 | + return 0; | |
32713 | +} | |
32714 | diff --git a/gdb/testsuite/gdb.base/valgrind-attach.exp b/gdb/testsuite/gdb.base/valgrind-attach.exp | |
32715 | new file mode 100644 | |
32716 | index 0000000..1f9b26e | |
32717 | --- /dev/null | |
32718 | +++ b/gdb/testsuite/gdb.base/valgrind-attach.exp | |
32719 | @@ -0,0 +1,94 @@ | |
32720 | +# Copyright 2009 Free Software Foundation, Inc. | |
32721 | + | |
32722 | +# This program is free software; you can redistribute it and/or modify | |
32723 | +# it under the terms of the GNU General Public License as published by | |
32724 | +# the Free Software Foundation; either version 3 of the License, or | |
32725 | +# (at your option) any later version. | |
32726 | +# | |
32727 | +# This program is distributed in the hope that it will be useful, | |
32728 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32729 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32730 | +# GNU General Public License for more details. | |
32731 | +# | |
32732 | +# You should have received a copy of the GNU General Public License | |
32733 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
32734 | + | |
32735 | +set testfile valgrind-attach | |
32736 | +set shfile ${testfile}.sh | |
32737 | +set srcfile ${testfile}.c | |
32738 | +set binfile ${objdir}/${subdir}/${testfile} | |
32739 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
32740 | + untested "Couldn't compile test program" | |
32741 | + return -1 | |
32742 | +} | |
32743 | + | |
32744 | +gdb_exit | |
32745 | +gdb_stop_suppressing_tests; | |
32746 | + | |
32747 | +set VALGRIND "valgrind" | |
32748 | + | |
32749 | +# Syntax for ${shfile} is: <binfile> <valgrind> <db-command-arguments> | |
32750 | +set VALGRIND_SPAWN "sh ${srcdir}/${subdir}/${shfile} $binfile $VALGRIND $GDB $INTERNAL_GDBFLAGS $GDBFLAGS [host_info gdb_opts]" | |
32751 | + | |
32752 | +set test "spawn valgrind" | |
32753 | +verbose "Spawning $VALGRIND_SPAWN" | |
32754 | + | |
32755 | +if [info exists gdb_spawn_id] { | |
32756 | + fail $test | |
32757 | + return -1 | |
32758 | +} | |
32759 | + | |
32760 | +if ![is_remote host] { | |
32761 | + if { [which $VALGRIND] == 0 } then { | |
32762 | + untested "Couldn't find $VALGRIND" | |
32763 | + return -1 | |
32764 | + } | |
32765 | +} | |
32766 | +set res [remote_spawn host "$VALGRIND_SPAWN"] | |
32767 | +if { $res < 0 || $res == "" } { | |
32768 | + perror "Spawning $VALGRIND_SPAWN failed." | |
32769 | + return -1 | |
32770 | +} | |
32771 | +set gdb_spawn_id -1; | |
32772 | + | |
32773 | +gdb_expect { | |
32774 | + -re "---- Attach to debugger \\? --- \\\[Return/N/n/Y/y/C/c\\\] ---- $" { | |
32775 | + pass $test | |
32776 | + } | |
32777 | + eof { | |
32778 | + perror "(eof) $VALGRIND never initialized" | |
32779 | + remote_close host | |
32780 | + return -1 | |
32781 | + } | |
32782 | + timeout { | |
32783 | + perror "(timeout) $VALGRIND never initialized" | |
32784 | + remote_close host | |
32785 | + return -1 | |
32786 | + } | |
32787 | +} | |
32788 | +send_gdb "y\n" | |
32789 | + | |
32790 | +set test "spawn gdb" | |
32791 | +set test2 "crash line caught" | |
32792 | +gdb_expect { | |
32793 | + -re "starting debugger with cmd:.* in main .* crash-here .*\[\r\n\]$gdb_prompt $" { | |
32794 | + pass $test | |
32795 | + pass $test2 | |
32796 | + } | |
32797 | + -re "starting debugger with cmd:.*\[\r\n\]$gdb_prompt $" { | |
32798 | + pass $test | |
32799 | + fail $test2 | |
32800 | + } | |
32801 | + eof { | |
32802 | + perror "(eof) $GDB never initialized" | |
32803 | + remote_close host | |
32804 | + return -1 | |
32805 | + } | |
32806 | + timeout { | |
32807 | + perror "(timeout) $GDB never initialized" | |
32808 | + remote_close host | |
32809 | + return -1 | |
32810 | + } | |
32811 | +} | |
32812 | + | |
32813 | +remote_close host | |
32814 | diff --git a/gdb/testsuite/gdb.base/valgrind-attach.sh b/gdb/testsuite/gdb.base/valgrind-attach.sh | |
32815 | new file mode 100755 | |
32816 | index 0000000..f02c6f7 | |
32817 | --- /dev/null | |
32818 | +++ b/gdb/testsuite/gdb.base/valgrind-attach.sh | |
32819 | @@ -0,0 +1,20 @@ | |
32820 | +#! /bin/sh | |
32821 | + | |
32822 | +# Copyright 2009 Free Software Foundation, Inc. | |
32823 | + | |
32824 | +# This program is free software; you can redistribute it and/or modify | |
32825 | +# it under the terms of the GNU General Public License as published by | |
32826 | +# the Free Software Foundation; either version 3 of the License, or | |
32827 | +# (at your option) any later version. | |
32828 | +# | |
32829 | +# This program is distributed in the hope that it will be useful, | |
32830 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32831 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32832 | +# GNU General Public License for more details. | |
32833 | +# | |
32834 | +# You should have received a copy of the GNU General Public License | |
32835 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
32836 | + | |
32837 | +BINFILE="$1"; shift | |
32838 | +VALGRIND="$1"; shift | |
32839 | +"$VALGRIND" --db-attach=yes --db-command="$* %f %p" "$BINFILE" | |
32840 | diff --git a/gdb/testsuite/gdb.base/vla-overflow.c b/gdb/testsuite/gdb.base/vla-overflow.c | |
32841 | new file mode 100644 | |
32842 | index 0000000..c5d5ee0 | |
32843 | --- /dev/null | |
32844 | +++ b/gdb/testsuite/gdb.base/vla-overflow.c | |
32845 | @@ -0,0 +1,30 @@ | |
32846 | +/* This testcase is part of GDB, the GNU debugger. | |
32847 | + | |
32848 | + Copyright 2008 Free Software Foundation, Inc. | |
32849 | + | |
32850 | + This program is free software; you can redistribute it and/or modify | |
32851 | + it under the terms of the GNU General Public License as published by | |
32852 | + the Free Software Foundation; either version 3 of the License, or | |
32853 | + (at your option) any later version. | |
32854 | + | |
32855 | + This program is distributed in the hope that it will be useful, | |
32856 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32857 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32858 | + GNU General Public License for more details. | |
32859 | + | |
32860 | + You should have received a copy of the GNU General Public License | |
32861 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
32862 | + | |
32863 | +#include <stdlib.h> | |
32864 | + | |
32865 | +int | |
32866 | +main (int argc, char **argv) | |
32867 | +{ | |
32868 | + int array[argc]; | |
32869 | + | |
32870 | + array[0] = array[0]; | |
32871 | + | |
32872 | + abort (); | |
32873 | + | |
32874 | + return 0; | |
32875 | +} | |
32876 | diff --git a/gdb/testsuite/gdb.base/vla-overflow.exp b/gdb/testsuite/gdb.base/vla-overflow.exp | |
32877 | new file mode 100644 | |
32878 | index 0000000..7203a48 | |
32879 | --- /dev/null | |
32880 | +++ b/gdb/testsuite/gdb.base/vla-overflow.exp | |
32881 | @@ -0,0 +1,108 @@ | |
32882 | +# Copyright 2008 Free Software Foundation, Inc. | |
32883 | + | |
32884 | +# This program is free software; you can redistribute it and/or modify | |
32885 | +# it under the terms of the GNU General Public License as published by | |
32886 | +# the Free Software Foundation; either version 3 of the License, or | |
32887 | +# (at your option) any later version. | |
32888 | +# | |
32889 | +# This program is distributed in the hope that it will be useful, | |
32890 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32891 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32892 | +# GNU General Public License for more details. | |
32893 | +# | |
32894 | +# You should have received a copy of the GNU General Public License | |
32895 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
32896 | + | |
32897 | +# We could crash in: | |
32898 | +# #0 block_linkage_function (bl=0x0) at ../../gdb/block.c:69 | |
32899 | +# #1 in dwarf_block_get_frame_base (...) at ../../gdb/dwarf2block.c:97 | |
32900 | +# 97 framefunc = block_linkage_function (get_frame_block (frame, NULL)); | |
32901 | +# #2 in execute_stack_op (...) at ../../gdb/dwarf2expr.c:496 | |
32902 | +# #3 in dwarf_block_exec_core () at ../../gdb/dwarf2block.c:156 | |
32903 | +# #4 dwarf_block_exec (...) at ../../gdb/dwarf2block.c:206 | |
32904 | +# #5 in range_type_count_bound_internal (...) at ../../gdb/gdbtypes.c:1430 | |
32905 | +# #6 in create_array_type (...) at ../../gdb/gdbtypes.c:840 | |
32906 | +# ... | |
32907 | +# #21 in psymtab_to_symtab (...) at ../../gdb/symfile.c:292 | |
32908 | +# ... | |
32909 | +# #29 in backtrace_command_1 () at ../../gdb/stack.c:1273 | |
32910 | + | |
32911 | +set testfile vla-overflow | |
32912 | +set shfile ${objdir}/${subdir}/${testfile}-gdb.sh | |
32913 | +set srcfile ${testfile}.c | |
32914 | +set binfile ${objdir}/${subdir}/${testfile} | |
32915 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
32916 | + untested "Couldn't compile test program" | |
32917 | + return -1 | |
32918 | +} | |
32919 | + | |
32920 | +set f [open "|getconf PAGESIZE" "r"] | |
32921 | +gets $f pagesize | |
32922 | +close $f | |
32923 | + | |
32924 | +gdb_exit | |
32925 | +gdb_start | |
32926 | +gdb_reinitialize_dir $srcdir/$subdir | |
32927 | +gdb_load ${binfile} | |
32928 | + | |
32929 | +set pid_of_gdb [exp_pid -i [board_info host fileid]] | |
32930 | + | |
32931 | +if { [runto_main] < 0 } { | |
32932 | + untested vla-overflow | |
32933 | + return -1 | |
32934 | +} | |
32935 | + | |
32936 | +# Get the GDB memory size when we stay at main. | |
32937 | + | |
32938 | +proc memory_v_pages_get {} { | |
32939 | + global pid_of_gdb pagesize | |
32940 | + set fd [open "/proc/$pid_of_gdb/statm"] | |
32941 | + gets $fd line | |
32942 | + close $fd | |
32943 | + # number of pages of virtual memory | |
32944 | + scan $line "%d" drs | |
32945 | + return $drs | |
32946 | +} | |
32947 | + | |
32948 | +set pages_found [memory_v_pages_get] | |
32949 | + | |
32950 | +set mb_reserve 10 | |
32951 | +verbose -log "pages_found = $pages_found, mb_reserve = $mb_reserve" | |
32952 | +set kb_found [expr $pages_found * $pagesize / 1024] | |
32953 | +set kb_permit [expr $kb_found + 1 * 1024 + $mb_reserve * 1024] | |
32954 | +verbose -log "kb_found = $kb_found, kb_permit = $kb_permit" | |
32955 | + | |
32956 | +# Create the ulimit wrapper. | |
32957 | +set f [open $shfile "w"] | |
32958 | +puts $f "#! /bin/sh" | |
32959 | +puts $f "ulimit -v $kb_permit" | |
32960 | +puts $f "exec $GDB \"\$@\"" | |
32961 | +close $f | |
32962 | +remote_exec host "chmod +x $shfile" | |
32963 | + | |
32964 | +gdb_exit | |
32965 | +set GDBold $GDB | |
32966 | +set GDB "$shfile" | |
32967 | +gdb_start | |
32968 | +set GDB $GDBold | |
32969 | + | |
32970 | +gdb_reinitialize_dir $srcdir/$subdir | |
32971 | +gdb_load ${binfile} | |
32972 | + | |
32973 | +set pid_of_gdb [exp_pid -i [board_info host fileid]] | |
32974 | + | |
32975 | +# Check the size again after the second run. | |
32976 | +# We must not stop in main as it would cache `array' and never crash later. | |
32977 | + | |
32978 | +gdb_run_cmd | |
32979 | + | |
32980 | +verbose -log "kb_found before abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" | |
32981 | + | |
32982 | +gdb_test "" "Program received signal SIGABRT, Aborted..*" "Enter abort()" | |
32983 | + | |
32984 | +verbose -log "kb_found in abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" | |
32985 | + | |
32986 | +# `abort' can get expressed as `*__GI_abort'. | |
32987 | +gdb_test "bt" "in \[^ \]*abort \\(.* in main \\(.*" "Backtrace after abort()" | |
32988 | + | |
32989 | +verbose -log "kb_found in bt after abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" | |
32990 | diff --git a/gdb/testsuite/gdb.base/vla.c b/gdb/testsuite/gdb.base/vla.c | |
32991 | new file mode 100644 | |
32992 | index 0000000..e1f3ed1 | |
32993 | --- /dev/null | |
32994 | +++ b/gdb/testsuite/gdb.base/vla.c | |
32995 | @@ -0,0 +1,55 @@ | |
32996 | +/* This testcase is part of GDB, the GNU debugger. | |
32997 | + | |
32998 | + Copyright 2008 Free Software Foundation, Inc. | |
32999 | + | |
33000 | + This program is free software; you can redistribute it and/or modify | |
33001 | + it under the terms of the GNU General Public License as published by | |
33002 | + the Free Software Foundation; either version 3 of the License, or | |
33003 | + (at your option) any later version. | |
33004 | + | |
33005 | + This program is distributed in the hope that it will be useful, | |
33006 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
33007 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
33008 | + GNU General Public License for more details. | |
33009 | + | |
33010 | + You should have received a copy of the GNU General Public License | |
33011 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
33012 | + | |
33013 | +#include <string.h> | |
33014 | + | |
33015 | +void | |
33016 | +marker (void) | |
33017 | +{ | |
33018 | +} | |
33019 | + | |
33020 | +void | |
33021 | +bar (char *a, char *b, char *c, int size) | |
33022 | +{ | |
33023 | + memset (a, '1', size); | |
33024 | + memset (b, '2', size); | |
33025 | + memset (c, '3', 48); | |
33026 | +} | |
33027 | + | |
33028 | +void | |
33029 | +foo (int size) | |
33030 | +{ | |
33031 | + char temp1[size]; | |
33032 | + char temp3[48]; | |
33033 | + | |
33034 | + temp1[size - 1] = '\0'; | |
33035 | + { | |
33036 | + char temp2[size]; | |
33037 | + | |
33038 | + bar (temp1, temp2, temp3, size); | |
33039 | + | |
33040 | + marker (); /* break-here */ | |
33041 | + } | |
33042 | +} | |
33043 | + | |
33044 | +int | |
33045 | +main (void) | |
33046 | +{ | |
33047 | + foo (26); | |
33048 | + foo (78); | |
33049 | + return 0; | |
33050 | +} | |
33051 | diff --git a/gdb/testsuite/gdb.base/vla.exp b/gdb/testsuite/gdb.base/vla.exp | |
33052 | new file mode 100644 | |
33053 | index 0000000..5da7378 | |
33054 | --- /dev/null | |
33055 | +++ b/gdb/testsuite/gdb.base/vla.exp | |
33056 | @@ -0,0 +1,62 @@ | |
33057 | +# Copyright 2008 Free Software Foundation, Inc. | |
33058 | + | |
33059 | +# This program is free software; you can redistribute it and/or modify | |
33060 | +# it under the terms of the GNU General Public License as published by | |
33061 | +# the Free Software Foundation; either version 3 of the License, or | |
33062 | +# (at your option) any later version. | |
33063 | +# | |
33064 | +# This program is distributed in the hope that it will be useful, | |
33065 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
33066 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
33067 | +# GNU General Public License for more details. | |
33068 | +# | |
33069 | +# You should have received a copy of the GNU General Public License | |
33070 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
33071 | + | |
33072 | +set testfile vla | |
33073 | +set srcfile ${testfile}.c | |
33074 | +set binfile ${objdir}/${subdir}/${testfile} | |
33075 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
33076 | + untested "Couldn't compile test program" | |
33077 | + return -1 | |
33078 | +} | |
33079 | + | |
33080 | +gdb_exit | |
33081 | +gdb_start | |
33082 | +gdb_reinitialize_dir $srcdir/$subdir | |
33083 | +gdb_load ${binfile} | |
33084 | + | |
33085 | +if ![runto_main] { | |
33086 | + untested vla | |
33087 | + return -1 | |
33088 | +} | |
33089 | + | |
33090 | +gdb_breakpoint [gdb_get_line_number "break-here"] | |
33091 | + | |
33092 | +gdb_continue_to_breakpoint "break-here" | |
33093 | + | |
33094 | +gdb_test "whatis temp1" "type = char \\\[variable\\\]" "first: whatis temp1" | |
33095 | +gdb_test "whatis temp2" "type = char \\\[variable\\\]" "first: whatis temp2" | |
33096 | +gdb_test "whatis temp3" "type = char \\\[48\\\]" "first: whatis temp3" | |
33097 | + | |
33098 | +gdb_test "ptype temp1" "type = char \\\[26\\\]" "first: ptype temp1" | |
33099 | +gdb_test "ptype temp2" "type = char \\\[26\\\]" "first: ptype temp2" | |
33100 | +gdb_test "ptype temp3" "type = char \\\[48\\\]" "first: ptype temp3" | |
33101 | + | |
33102 | +gdb_test "p temp1" " = '1' <repeats 26 times>" "first: print temp1" | |
33103 | +gdb_test "p temp2" " = '2' <repeats 26 times>" "first: print temp2" | |
33104 | +gdb_test "p temp3" " = '3' <repeats 48 times>" "first: print temp3" | |
33105 | + | |
33106 | +gdb_continue_to_breakpoint "break-here" | |
33107 | + | |
33108 | +gdb_test "whatis temp1" "type = char \\\[variable\\\]" "second: whatis temp1" | |
33109 | +gdb_test "whatis temp2" "type = char \\\[variable\\\]" "second: whatis temp2" | |
33110 | +gdb_test "whatis temp3" "type = char \\\[48\\\]" "second: whatis temp3" | |
33111 | + | |
33112 | +gdb_test "ptype temp1" "type = char \\\[78\\\]" "second: ptype temp1" | |
33113 | +gdb_test "ptype temp2" "type = char \\\[78\\\]" "second: ptype temp2" | |
33114 | +gdb_test "ptype temp3" "type = char \\\[48\\\]" "second: ptype temp3" | |
33115 | + | |
33116 | +gdb_test "p temp1" " = '1' <repeats 78 times>" "second: print temp1" | |
33117 | +gdb_test "p temp2" " = '2' <repeats 78 times>" "second: print temp2" | |
33118 | +gdb_test "p temp3" " = '3' <repeats 48 times>" "second: print temp3" | |
33119 | diff --git a/gdb/testsuite/gdb.cp/Makefile.in b/gdb/testsuite/gdb.cp/Makefile.in | |
33120 | index 1787ad5..391bfc2 100644 | |
33121 | --- a/gdb/testsuite/gdb.cp/Makefile.in | |
33122 | +++ b/gdb/testsuite/gdb.cp/Makefile.in | |
33123 | @@ -4,7 +4,7 @@ srcdir = @srcdir@ | |
33124 | EXECUTABLES = ambiguous annota2 anon-union cplusfuncs cttiadd \ | |
33125 | derivation inherit local member-ptr method misc \ | |
33126 | overload ovldbreak ref-typ ref-typ2 templates userdef virtfunc namespace \ | |
33127 | - ref-types ref-params method2 pr9594 | |
33128 | + ref-types ref-params method2 pr9594 gdb2495 | |
33129 | ||
33130 | all info install-info dvi install uninstall installcheck check: | |
33131 | @echo "Nothing to be done for $@..." | |
33132 | diff --git a/gdb/testsuite/gdb.cp/abstract-origin.cc b/gdb/testsuite/gdb.cp/abstract-origin.cc | |
33133 | new file mode 100644 | |
33134 | index 0000000..e2de3fb | |
33135 | --- /dev/null | |
33136 | +++ b/gdb/testsuite/gdb.cp/abstract-origin.cc | |
33137 | @@ -0,0 +1,42 @@ | |
33138 | +/* This testcase is part of GDB, the GNU debugger. | |
33139 | + | |
33140 | + Copyright 2008 Free Software Foundation, Inc. | |
33141 | + | |
33142 | + This program is free software; you can redistribute it and/or modify | |
33143 | + it under the terms of the GNU General Public License as published by | |
33144 | + the Free Software Foundation; either version 3 of the License, or | |
33145 | + (at your option) any later version. | |
33146 | + | |
33147 | + This program is distributed in the hope that it will be useful, | |
33148 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
33149 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
33150 | + GNU General Public License for more details. | |
33151 | + | |
33152 | + You should have received a copy of the GNU General Public License | |
33153 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
33154 | + */ | |
33155 | + | |
33156 | +extern void f (int *); | |
33157 | + | |
33158 | +class A | |
33159 | +{ | |
33160 | +public: | |
33161 | + A(int i); | |
33162 | +}; | |
33163 | + | |
33164 | +A::A(int i) | |
33165 | +{ | |
33166 | + static int *problem = new int(i); | |
33167 | + f (problem); /* break-here */ | |
33168 | +} | |
33169 | + | |
33170 | +void f (int *) | |
33171 | +{ | |
33172 | +} | |
33173 | + | |
33174 | +int | |
33175 | +main (void) | |
33176 | +{ | |
33177 | + A a(42); | |
33178 | + return 0; | |
33179 | +} | |
33180 | diff --git a/gdb/testsuite/gdb.cp/abstract-origin.exp b/gdb/testsuite/gdb.cp/abstract-origin.exp | |
33181 | new file mode 100644 | |
33182 | index 0000000..92cc23c | |
33183 | --- /dev/null | |
33184 | +++ b/gdb/testsuite/gdb.cp/abstract-origin.exp | |
33185 | @@ -0,0 +1,40 @@ | |
33186 | +# Copyright 2008 Free Software Foundation, Inc. | |
33187 | + | |
33188 | +# This program is free software; you can redistribute it and/or modify | |
33189 | +# it under the terms of the GNU General Public License as published by | |
33190 | +# the Free Software Foundation; either version 3 of the License, or | |
33191 | +# (at your option) any later version. | |
33192 | +# | |
33193 | +# This program is distributed in the hope that it will be useful, | |
33194 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
33195 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
33196 | +# GNU General Public License for more details. | |
33197 | +# | |
33198 | +# You should have received a copy of the GNU General Public License | |
33199 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
33200 | + | |
33201 | +set testfile abstract-origin | |
33202 | +set srcfile ${testfile}.cc | |
33203 | +set binfile ${objdir}/${subdir}/${testfile} | |
33204 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
33205 | + untested "Couldn't compile test program" | |
33206 | + return -1 | |
33207 | +} | |
33208 | + | |
33209 | +# Get things started. | |
33210 | + | |
33211 | +gdb_exit | |
33212 | +gdb_start | |
33213 | +gdb_reinitialize_dir $srcdir/$subdir | |
33214 | +gdb_load ${binfile} | |
33215 | + | |
33216 | +if ![runto_main] { | |
33217 | + untested abstract-origin | |
33218 | + return -1 | |
33219 | +} | |
33220 | + | |
33221 | +gdb_breakpoint [gdb_get_line_number "break-here"] | |
33222 | +gdb_continue_to_breakpoint "break-here" | |
33223 | + | |
33224 | +# The Bug was: No symbol "problem" in current context. | |
33225 | +gdb_test "p problem" " = \\(int \\*\\) 0x.*" | |
33226 | diff --git a/gdb/testsuite/gdb.cp/cplusfuncs.cc b/gdb/testsuite/gdb.cp/cplusfuncs.cc | |
33227 | index 7f033d6..1a50a32 100644 | |
33228 | --- a/gdb/testsuite/gdb.cp/cplusfuncs.cc | |
33229 | +++ b/gdb/testsuite/gdb.cp/cplusfuncs.cc | |
33230 | @@ -191,6 +191,12 @@ char * dm_type_char_star (char * p) { return p; } | |
33231 | int dm_type_foo_ref (foo & foo) { return foo.ifoo; } | |
33232 | int * dm_type_int_star (int * p) { return p; } | |
33233 | long * dm_type_long_star (long * p) { return p; } | |
33234 | +int dm_type_short (short i) { return i; } | |
33235 | +int dm_type_long (long i) { return i; } | |
33236 | int dm_type_unsigned_int (unsigned int i) { return i; } | |
33237 | +int dm_type_unsigned_short (unsigned short i) { return i; } | |
33238 | +int dm_type_unsigned_long (unsigned long i) { return i; } | |
33239 | int dm_type_void (void) { return 0; } | |
33240 | void * dm_type_void_star (void * p) { return p; } | |
33241 | +typedef int myint; | |
33242 | +int dm_type_typedef (myint i) { return i; } | |
33243 | diff --git a/gdb/testsuite/gdb.cp/cplusfuncs.exp b/gdb/testsuite/gdb.cp/cplusfuncs.exp | |
33244 | index 5e08768..8c8e038 100644 | |
33245 | --- a/gdb/testsuite/gdb.cp/cplusfuncs.exp | |
33246 | +++ b/gdb/testsuite/gdb.cp/cplusfuncs.exp | |
33247 | @@ -66,9 +66,25 @@ set dm_type_unsigned_int "unsigned" | |
33248 | set dm_type_void "" | |
33249 | set dm_type_void_star "void*" | |
33250 | ||
33251 | +# Some other vagaries of GDB's type printing machinery. The integer types | |
33252 | +# may have unsigned before or after their length, and may have "int" | |
33253 | +# appended. The char* conversion operator may have name "char*" even if | |
33254 | +# the type is "char *", because the name comes from the debug information | |
33255 | +# and the type from GDB. Function types may not see through typedefs. | |
33256 | + | |
33257 | +set dm_type_short "short" | |
33258 | +set dm_type_long "long" | |
33259 | +set dm_type_unsigned_short "unsigned short" | |
33260 | +set dm_type_unsigned_long "unsigned long" | |
33261 | +set dm_operator_char_star "char*" | |
33262 | +set dm_operator_char_star_quoted "char\\*" | |
33263 | +set dm_type_typedef 0 | |
33264 | + | |
33265 | proc probe_demangler { } { | |
33266 | global gdb_prompt | |
33267 | global dm_operator_comma | |
33268 | + global dm_operator_char_star | |
33269 | + global dm_operator_char_star_quoted | |
33270 | global dm_type_char_star | |
33271 | global dm_type_char_star_quoted | |
33272 | global dm_type_foo_ref | |
33273 | @@ -77,6 +93,11 @@ proc probe_demangler { } { | |
33274 | global dm_type_unsigned_int | |
33275 | global dm_type_void | |
33276 | global dm_type_void_star | |
33277 | + global dm_type_short | |
33278 | + global dm_type_unsigned_short | |
33279 | + global dm_type_long | |
33280 | + global dm_type_unsigned_long | |
33281 | + global dm_type_typedef | |
33282 | ||
33283 | send_gdb "print &'foo::operator,(foo&)'\n" | |
33284 | gdb_expect { | |
33285 | @@ -97,6 +118,26 @@ proc probe_demangler { } { | |
33286 | } | |
33287 | } | |
33288 | ||
33289 | + send_gdb "print &'foo::operator char*()'\n" | |
33290 | + gdb_expect { | |
33291 | + -re ".*foo::operator char \\*\\(void\\).*\r\n$gdb_prompt $" { | |
33292 | + # v2 demangler or GDB type printer | |
33293 | + set dm_operator_char_star "char *" | |
33294 | + set dm_operator_char_star_quoted "char \\*" | |
33295 | + pass "detect dm_operator_char_star" | |
33296 | + } | |
33297 | + -re ".*foo::operator char\\*\\(\\).*\r\n$gdb_prompt $" { | |
33298 | + # v3 demangler | |
33299 | + pass "detect dm_operator_char_star" | |
33300 | + } | |
33301 | + -re ".*$gdb_prompt $" { | |
33302 | + fail "detect dm_operator_char_star" | |
33303 | + } | |
33304 | + timeout { | |
33305 | + fail "detect dm_operator_char_star" | |
33306 | + } | |
33307 | + } | |
33308 | + | |
33309 | send_gdb "print &'dm_type_char_star'\n" | |
33310 | gdb_expect { | |
33311 | -re ".*dm_type_char_star\\(char \\*\\).*\r\n$gdb_prompt $" { | |
33312 | @@ -166,6 +207,11 @@ proc probe_demangler { } { | |
33313 | # v3 demangler | |
33314 | pass "detect dm_type_long_star" | |
33315 | } | |
33316 | + -re ".*dm_type_long_star\\(long int \\*\\).*\r\n$gdb_prompt $" { | |
33317 | + # GCC v3 and GDB's type printer | |
33318 | + set dm_type_long_star "long int *" | |
33319 | + pass "detect dm_type_long_star" | |
33320 | + } | |
33321 | -re ".*$gdb_prompt $" { | |
33322 | fail "detect dm_type_long_star" | |
33323 | } | |
33324 | @@ -230,6 +276,101 @@ proc probe_demangler { } { | |
33325 | fail "detect dm_type_void_star (timeout)" | |
33326 | } | |
33327 | } | |
33328 | + | |
33329 | + send_gdb "print &'dm_type_short'\n" | |
33330 | + gdb_expect { | |
33331 | + -re ".*dm_type_short\\(short\\).*\r\n$gdb_prompt $" { | |
33332 | + # v2 and v3 demanglers | |
33333 | + pass "detect dm_type_short" | |
33334 | + } | |
33335 | + -re ".*dm_type_short\\(short int\\).*\r\n$gdb_prompt $" { | |
33336 | + # GDB type printer | |
33337 | + set dm_type_short "short int" | |
33338 | + pass "detect dm_type_short" | |
33339 | + } | |
33340 | + -re ".*$gdb_prompt $" { | |
33341 | + fail "detect dm_type_short" | |
33342 | + } | |
33343 | + timeout { | |
33344 | + fail "detect dm_type_short (timeout)" | |
33345 | + } | |
33346 | + } | |
33347 | + | |
33348 | + send_gdb "print &'dm_type_unsigned_short'\n" | |
33349 | + gdb_expect { | |
33350 | + -re ".*dm_type_unsigned_short\\(unsigned short\\).*\r\n$gdb_prompt $" { | |
33351 | + # v2 and v3 demanglers | |
33352 | + pass "detect dm_type_unsigned_short" | |
33353 | + } | |
33354 | + -re ".*dm_type_unsigned_short\\(short unsigned int\\).*\r\n$gdb_prompt $" { | |
33355 | + # GDB type printer | |
33356 | + set dm_type_unsigned_short "short unsigned int" | |
33357 | + pass "detect dm_type_unsigned_short" | |
33358 | + } | |
33359 | + -re ".*$gdb_prompt $" { | |
33360 | + fail "detect dm_type_unsigned_short" | |
33361 | + } | |
33362 | + timeout { | |
33363 | + fail "detect dm_type_unsigned_short (timeout)" | |
33364 | + } | |
33365 | + } | |
33366 | + | |
33367 | + send_gdb "print &'dm_type_long'\n" | |
33368 | + gdb_expect { | |
33369 | + -re ".*dm_type_long\\(long\\).*\r\n$gdb_prompt $" { | |
33370 | + # v2 and v3 demanglers | |
33371 | + pass "detect dm_type_long" | |
33372 | + } | |
33373 | + -re ".*dm_type_long\\(long int\\).*\r\n$gdb_prompt $" { | |
33374 | + # GDB type printer | |
33375 | + set dm_type_long "long int" | |
33376 | + pass "detect dm_type_long" | |
33377 | + } | |
33378 | + -re ".*$gdb_prompt $" { | |
33379 | + fail "detect dm_type_long" | |
33380 | + } | |
33381 | + timeout { | |
33382 | + fail "detect dm_type_long (timeout)" | |
33383 | + } | |
33384 | + } | |
33385 | + | |
33386 | + send_gdb "print &'dm_type_unsigned_long'\n" | |
33387 | + gdb_expect { | |
33388 | + -re ".*dm_type_unsigned_long\\(unsigned long\\).*\r\n$gdb_prompt $" { | |
33389 | + # v2 and v3 demanglers | |
33390 | + pass "detect dm_type_unsigned_long" | |
33391 | + } | |
33392 | + -re ".*dm_type_unsigned_long\\(long unsigned int\\).*\r\n$gdb_prompt $" { | |
33393 | + # GDB type printer | |
33394 | + set dm_type_unsigned_long "long unsigned int" | |
33395 | + pass "detect dm_type_unsigned_long" | |
33396 | + } | |
33397 | + -re ".*$gdb_prompt $" { | |
33398 | + fail "detect dm_type_unsigned_long" | |
33399 | + } | |
33400 | + timeout { | |
33401 | + fail "detect dm_type_unsigned_long (timeout)" | |
33402 | + } | |
33403 | + } | |
33404 | + | |
33405 | + send_gdb "print &'dm_type_typedef'\n" | |
33406 | + gdb_expect { | |
33407 | + -re ".*dm_type_typedef\\(int\\).*\r\n$gdb_prompt $" { | |
33408 | + # v2 and v3 demanglers | |
33409 | + pass "detect dm_type_typedef" | |
33410 | + } | |
33411 | + -re ".*dm_type_typedef\\(myint\\).*\r\n$gdb_prompt $" { | |
33412 | + # GDB type printer | |
33413 | + set dm_type_typedef 1 | |
33414 | + pass "detect dm_type_typedef" | |
33415 | + } | |
33416 | + -re ".*$gdb_prompt $" { | |
33417 | + fail "detect dm_type_typedef" | |
33418 | + } | |
33419 | + timeout { | |
33420 | + fail "detect dm_type_typedef (timeout)" | |
33421 | + } | |
33422 | + } | |
33423 | } | |
33424 | ||
33425 | # | |
33426 | @@ -345,8 +486,9 @@ proc print_addr { name } { | |
33427 | ||
33428 | proc test_lookup_operator_functions {} { | |
33429 | global dm_operator_comma | |
33430 | + global dm_operator_char_star | |
33431 | global dm_type_char_star | |
33432 | - global dm_type_char_star_quoted | |
33433 | + global dm_operator_char_star_quoted | |
33434 | global dm_type_foo_ref | |
33435 | global dm_type_void | |
33436 | global dm_type_void_star | |
33437 | @@ -404,8 +546,8 @@ proc test_lookup_operator_functions {} { | |
33438 | ||
33439 | info_func "operator int(" "int foo::operator int($dm_type_void);" | |
33440 | info_func "operator()(" "void foo::operator()($dm_type_foo_ref);" | |
33441 | - info_func "operator $dm_type_char_star_quoted\(" \ | |
33442 | - "char *foo::operator $dm_type_char_star\($dm_type_void);" | |
33443 | + info_func "operator $dm_operator_char_star_quoted\(" \ | |
33444 | + "char *foo::operator $dm_operator_char_star\($dm_type_void);" | |
33445 | ||
33446 | } | |
33447 | ||
33448 | @@ -420,6 +562,7 @@ proc test_paddr_operator_functions {} { | |
33449 | global dm_type_unsigned_int | |
33450 | global dm_type_void | |
33451 | global dm_type_void_star | |
33452 | + global dm_operator_char_star | |
33453 | ||
33454 | print_addr "foo::operator*($dm_type_foo_ref)" | |
33455 | print_addr "foo::operator%($dm_type_foo_ref)" | |
33456 | @@ -470,7 +613,7 @@ proc test_paddr_operator_functions {} { | |
33457 | } | |
33458 | ||
33459 | print_addr "foo::operator int($dm_type_void)" | |
33460 | - print_addr "foo::operator $dm_type_char_star\($dm_type_void)" | |
33461 | + print_addr "foo::operator $dm_operator_char_star\($dm_type_void)" | |
33462 | } | |
33463 | ||
33464 | # | |
33465 | @@ -480,17 +623,21 @@ proc test_paddr_operator_functions {} { | |
33466 | proc test_paddr_overloaded_functions {} { | |
33467 | global dm_type_unsigned_int | |
33468 | global dm_type_void | |
33469 | + global dm_type_short | |
33470 | + global dm_type_unsigned_short | |
33471 | + global dm_type_long | |
33472 | + global dm_type_unsigned_long | |
33473 | ||
33474 | print_addr "overload1arg($dm_type_void)" | |
33475 | print_addr "overload1arg(char)" | |
33476 | print_addr "overload1arg(signed char)" | |
33477 | print_addr "overload1arg(unsigned char)" | |
33478 | - print_addr "overload1arg(short)" | |
33479 | - print_addr "overload1arg(unsigned short)" | |
33480 | + print_addr "overload1arg($dm_type_short)" | |
33481 | + print_addr "overload1arg($dm_type_unsigned_short)" | |
33482 | print_addr "overload1arg(int)" | |
33483 | print_addr "overload1arg($dm_type_unsigned_int)" | |
33484 | - print_addr "overload1arg(long)" | |
33485 | - print_addr "overload1arg(unsigned long)" | |
33486 | + print_addr "overload1arg($dm_type_long)" | |
33487 | + print_addr "overload1arg($dm_type_unsigned_long)" | |
33488 | print_addr "overload1arg(float)" | |
33489 | print_addr "overload1arg(double)" | |
33490 | ||
33491 | @@ -513,17 +660,31 @@ proc test_paddr_hairy_functions {} { | |
33492 | global dm_type_char_star | |
33493 | global dm_type_int_star | |
33494 | global dm_type_long_star | |
33495 | + global dm_type_typedef | |
33496 | ||
33497 | print_addr_2 "hairyfunc1" "hairyfunc1(int)" | |
33498 | - print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))" | |
33499 | - print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))" | |
33500 | - print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))" | |
33501 | - | |
33502 | - # gdb-gnats bug gdb/19: | |
33503 | - # "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7" | |
33504 | - print_addr_2_kfail "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))" "hairyfunc5(int (*)(long) (*)(char*))" "gdb/19" | |
33505 | - print_addr_2_kfail "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))" "hairyfunc6(int (*)(long) (*)(int*))" "gdb/19" | |
33506 | - print_addr_2_kfail "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))" "hairyfunc7(int (*)(long) (*)(int (*)(char*)))" "gdb/19" | |
33507 | + | |
33508 | + if {$dm_type_typedef == 0} { | |
33509 | + print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))" | |
33510 | + print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))" | |
33511 | + print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))" | |
33512 | + | |
33513 | + # gdb-gnats bug gdb/19: | |
33514 | + # "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7" | |
33515 | + print_addr_2_kfail "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))" "hairyfunc5(int (*)(long) (*)(char*))" "gdb/19" | |
33516 | + print_addr_2_kfail "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))" "hairyfunc6(int (*)(long) (*)(int*))" "gdb/19" | |
33517 | + print_addr_2_kfail "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))" "hairyfunc7(int (*)(long) (*)(int (*)(char*)))" "gdb/19" | |
33518 | + } else { | |
33519 | + print_addr_2 "hairyfunc2" "hairyfunc2(PFPc_i)" | |
33520 | + print_addr_2 "hairyfunc3" "hairyfunc3(PFPFPl_s_i)" | |
33521 | + print_addr_2 "hairyfunc4" "hairyfunc4(PFPFPc_s_i)" | |
33522 | + | |
33523 | + # gdb-gnats bug gdb/19: | |
33524 | + # "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7" | |
33525 | + print_addr_2 "hairyfunc5" "hairyfunc5(PFPc_PFl_i)" | |
33526 | + print_addr_2 "hairyfunc6" "hairyfunc6(PFPi_PFl_i)" | |
33527 | + print_addr_2 "hairyfunc7" "hairyfunc7(PFPFPc_i_PFl_i)" | |
33528 | + } | |
33529 | } | |
33530 | ||
33531 | proc do_tests {} { | |
33532 | diff --git a/gdb/testsuite/gdb.cp/expand-sals.cc b/gdb/testsuite/gdb.cp/expand-sals.cc | |
33533 | new file mode 100644 | |
33534 | index 0000000..6169a05 | |
33535 | --- /dev/null | |
33536 | +++ b/gdb/testsuite/gdb.cp/expand-sals.cc | |
33537 | @@ -0,0 +1,53 @@ | |
33538 | +/* This testcase is part of GDB, the GNU debugger. | |
33539 | + | |
33540 | + Copyright (C) 2009 Free Software Foundation, Inc. | |
33541 | + | |
33542 | + This file is part of GDB. | |
33543 | + | |
33544 | + This program is free software; you can redistribute it and/or modify | |
33545 | + it under the terms of the GNU General Public License as published by | |
33546 | + the Free Software Foundation; either version 3 of the License, or | |
33547 | + (at your option) any later version. | |
33548 | + | |
33549 | + This program is distributed in the hope that it will be useful, | |
33550 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
33551 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
33552 | + GNU General Public License for more details. | |
33553 | + | |
33554 | + You should have received a copy of the GNU General Public License | |
33555 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
33556 | + | |
33557 | +int | |
33558 | +func () | |
33559 | +{ | |
33560 | + return 42; /* func-line */ | |
33561 | +} | |
33562 | + | |
33563 | +volatile int global_x; | |
33564 | + | |
33565 | +class A | |
33566 | +{ | |
33567 | +public: | |
33568 | + A () | |
33569 | + { | |
33570 | + global_x = func (); /* caller-line */ | |
33571 | + } | |
33572 | +}; | |
33573 | + | |
33574 | +/* class B is here just to make the `func' calling line above having multiple | |
33575 | + instances - multiple locations. Template cannot be used as its instances | |
33576 | + would have different function names which get discarded by GDB | |
33577 | + expand_line_sal_maybe. */ | |
33578 | + | |
33579 | +class B : public A | |
33580 | +{ | |
33581 | +}; | |
33582 | + | |
33583 | +int | |
33584 | +main (void) | |
33585 | +{ | |
33586 | + A a; | |
33587 | + B b; | |
33588 | + | |
33589 | + return 0; /* exit-line */ | |
33590 | +} | |
33591 | diff --git a/gdb/testsuite/gdb.cp/expand-sals.exp b/gdb/testsuite/gdb.cp/expand-sals.exp | |
33592 | new file mode 100644 | |
33593 | index 0000000..a2631fb | |
33594 | --- /dev/null | |
33595 | +++ b/gdb/testsuite/gdb.cp/expand-sals.exp | |
33596 | @@ -0,0 +1,100 @@ | |
33597 | +# Copyright 2009 Free Software Foundation, Inc. | |
33598 | + | |
33599 | +# This program is free software; you can redistribute it and/or modify | |
33600 | +# it under the terms of the GNU General Public License as published by | |
33601 | +# the Free Software Foundation; either version 3 of the License, or | |
33602 | +# (at your option) any later version. | |
33603 | +# | |
33604 | +# This program is distributed in the hope that it will be useful, | |
33605 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
33606 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
33607 | +# GNU General Public License for more details. | |
33608 | +# | |
33609 | +# You should have received a copy of the GNU General Public License | |
33610 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
33611 | + | |
33612 | +if { [skip_cplus_tests] } { continue } | |
33613 | + | |
33614 | +set srcfile expand-sals.cc | |
33615 | +if { [prepare_for_testing expand-sals.exp expand-sals $srcfile {debug c++}] } { | |
33616 | + return -1 | |
33617 | +} | |
33618 | +if ![runto_main] { | |
33619 | + return -1 | |
33620 | +} | |
33621 | + | |
33622 | +gdb_breakpoint [gdb_get_line_number "exit-line"] | |
33623 | + | |
33624 | +gdb_breakpoint [gdb_get_line_number "func-line"] | |
33625 | +gdb_continue_to_breakpoint "func" ".*func-line.*" | |
33626 | + | |
33627 | +gdb_test "up" "caller-line.*" | |
33628 | + | |
33629 | +# PC should not be at the boundary of source lines to make the original bug | |
33630 | +# exploitable. | |
33631 | + | |
33632 | +set test "p/x \$pc" | |
33633 | +set pc {} | |
33634 | +gdb_test_multiple $test $test { | |
33635 | + -re "\\$\[0-9\]+ = (0x\[0-9a-f\]+)\r\n$gdb_prompt $" { | |
33636 | + set pc $expect_out(1,string) | |
33637 | + pass $test | |
33638 | + } | |
33639 | +} | |
33640 | + | |
33641 | +set test "info line" | |
33642 | +set end {} | |
33643 | +gdb_test_multiple $test $test { | |
33644 | + -re "Line \[0-9\]+ of .* starts at address 0x\[0-9a-f\]+.* and ends at (0x\[0-9a-f\]+).*\\.\r\n$gdb_prompt $" { | |
33645 | + set end $expect_out(1,string) | |
33646 | + pass $test | |
33647 | + } | |
33648 | +} | |
33649 | + | |
33650 | +set test "caller line has trailing code" | |
33651 | +if {$pc != $end} { | |
33652 | + pass $test | |
33653 | +} else { | |
33654 | + fail $test | |
33655 | +} | |
33656 | + | |
33657 | +# Original problem was an internal error here. Still sanity multiple locations | |
33658 | +# were found at this code place as otherwise this test would not test anything. | |
33659 | +set test "break" | |
33660 | +gdb_test_multiple $test $test { | |
33661 | + -re "Breakpoint \[0-9\]+ at .*, line \[0-9\]+\\. \\(\[2-9\] locations\\)\r\n$gdb_prompt $" { | |
33662 | + pass $test | |
33663 | + } | |
33664 | + -re "Breakpoint \[0-9\]+ at .*, line \[0-9\]+\\.\r\n$gdb_prompt $" { | |
33665 | + # It just could not be decided if GDB is OK by this testcase. | |
33666 | + setup_xfail *-*-* | |
33667 | + fail $test | |
33668 | + return 0 | |
33669 | + } | |
33670 | +} | |
33671 | + | |
33672 | +gdb_continue_to_breakpoint "caller" ".*caller-line.*" | |
33673 | + | |
33674 | +# Test GDB caught this return call and not the next one through B::B() | |
33675 | +gdb_test "bt" \ | |
33676 | + "#0 \[^\r\n\]* A \[^\r\n\]*\r\n#1 \[^\r\n\]* main \[^\r\n\]*" \ | |
33677 | + "bt from A" | |
33678 | + | |
33679 | +gdb_continue_to_breakpoint "next caller instance" ".*caller-line.*" | |
33680 | + | |
33681 | +# Test that GDB caught now already A through B::B() in the other instance. | |
33682 | +# As discussed in GDB expand_line_sal_maybe it would more match the original | |
33683 | +# instance behavior to catch here the `func' breakpoint and catch the | |
33684 | +# multiple-locations breakpoint only during the call return. This is not the | |
33685 | +# case, expecting here to catch the breakpoint before the call happens. | |
33686 | + | |
33687 | +gdb_test "bt" \ | |
33688 | + "#0 \[^\r\n\]* A \[^\r\n\]*\r\n#1 \[^\r\n\]* B \[^\r\n\]*\r\n#2 \[^\r\n\]* main \[^\r\n\]*" \ | |
33689 | + "bt from B before the call" | |
33690 | + | |
33691 | +gdb_continue_to_breakpoint "next caller func" ".*func-line.*" | |
33692 | + | |
33693 | +# Verify GDB really could not catch the originally intended point of the return | |
33694 | +# from func. | |
33695 | + | |
33696 | +gdb_continue_to_breakpoint "uncaught return" ".*exit-line.*" | |
33697 | diff --git a/gdb/testsuite/gdb.cp/gdb1355.exp b/gdb/testsuite/gdb.cp/gdb1355.exp | |
33698 | index 77687a6..66d16cf 100644 | |
33699 | --- a/gdb/testsuite/gdb.cp/gdb1355.exp | |
33700 | +++ b/gdb/testsuite/gdb.cp/gdb1355.exp | |
33701 | @@ -68,11 +68,11 @@ set s_tail ".*" | |
33702 | ||
33703 | set f_i "${ws}int m_int;" | |
33704 | set f_c "${ws}char m_char;" | |
33705 | -set f_li "${ws}long int m_long_int;" | |
33706 | +set f_li "${ws}long m_long_int;" | |
33707 | set f_ui "${ws}unsigned int m_unsigned_int;" | |
33708 | -set f_lui "${ws}long unsigned int m_long_unsigned_int;" | |
33709 | -set f_si "${ws}short int m_short_int;" | |
33710 | -set f_sui "${ws}short unsigned int m_short_unsigned_int;" | |
33711 | +set f_lui "${ws}unsigned long m_long_unsigned_int;" | |
33712 | +set f_si "${ws}short m_short_int;" | |
33713 | +set f_sui "${ws}unsigned short m_short_unsigned_int;" | |
33714 | set f_uc "${ws}unsigned char m_unsigned_char;" | |
33715 | set f_f "${ws}float m_float;" | |
33716 | set f_d "${ws}double m_double;" | |
33717 | diff --git a/gdb/testsuite/gdb.cp/gdb2495.cc b/gdb/testsuite/gdb.cp/gdb2495.cc | |
33718 | new file mode 100644 | |
33719 | index 0000000..4df265f | |
33720 | --- /dev/null | |
33721 | +++ b/gdb/testsuite/gdb.cp/gdb2495.cc | |
33722 | @@ -0,0 +1,90 @@ | |
33723 | +/* This testcase is part of GDB, the GNU debugger. | |
33724 | + | |
33725 | + Copyright 2008 Free Software Foundation, Inc. | |
33726 | + | |
33727 | + This program is free software; you can redistribute it and/or modify | |
33728 | + it under the terms of the GNU General Public License as published by | |
33729 | + the Free Software Foundation; either version 3 of the License, or | |
33730 | + (at your option) any later version. | |
33731 | + | |
33732 | + This program is distributed in the hope that it will be useful, | |
33733 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
33734 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
33735 | + GNU General Public License for more details. | |
33736 | + | |
33737 | + You should have received a copy of the GNU General Public License | |
33738 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
33739 | + */ | |
33740 | + | |
33741 | +#include <iostream> | |
33742 | +#include <signal.h> | |
33743 | + | |
33744 | +using namespace std; | |
33745 | + | |
33746 | +class SimpleException | |
33747 | +{ | |
33748 | + | |
33749 | +public: | |
33750 | + | |
33751 | + void raise_signal (int dummy) | |
33752 | + { | |
33753 | + if (dummy > 0) | |
33754 | + raise(SIGABRT); | |
33755 | + } | |
33756 | + | |
33757 | + int no_throw_function () | |
33758 | + { | |
33759 | + return 1; | |
33760 | + } | |
33761 | + | |
33762 | + void throw_function () | |
33763 | + { | |
33764 | + throw 1; | |
33765 | + } | |
33766 | + | |
33767 | + int throw_function_with_handler () | |
33768 | + { | |
33769 | + try | |
33770 | + { | |
33771 | + throw 1; | |
33772 | + } | |
33773 | + catch (...) | |
33774 | + { | |
33775 | + cout << "Handled" << endl; | |
33776 | + } | |
33777 | + | |
33778 | + return 2; | |
33779 | + } | |
33780 | + | |
33781 | + void call_throw_function_no_handler () | |
33782 | + { | |
33783 | + throw_function (); | |
33784 | + } | |
33785 | + | |
33786 | + void call_throw_function_handler () | |
33787 | + { | |
33788 | + throw_function_with_handler (); | |
33789 | + } | |
33790 | +}; | |
33791 | +SimpleException exceptions; | |
33792 | + | |
33793 | +int | |
33794 | +main() | |
33795 | +{ | |
33796 | + // Have to call all these functions | |
33797 | + // so not optimized away. | |
33798 | + exceptions.raise_signal (-1); | |
33799 | + exceptions.no_throw_function (); | |
33800 | + exceptions.throw_function_with_handler (); | |
33801 | + exceptions.call_throw_function_handler (); | |
33802 | + try | |
33803 | + { | |
33804 | + exceptions.throw_function (); | |
33805 | + exceptions.call_throw_function_no_handler (); | |
33806 | + } | |
33807 | + catch (...) | |
33808 | + { | |
33809 | + } | |
33810 | + return 0; | |
33811 | +} | |
33812 | + | |
33813 | diff --git a/gdb/testsuite/gdb.cp/gdb2495.exp b/gdb/testsuite/gdb.cp/gdb2495.exp | |
33814 | new file mode 100644 | |
33815 | index 0000000..62c09c2 | |
33816 | --- /dev/null | |
33817 | +++ b/gdb/testsuite/gdb.cp/gdb2495.exp | |
33818 | @@ -0,0 +1,160 @@ | |
33819 | +# Copyright 2008 Free Software Foundation, Inc. | |
33820 | + | |
33821 | +# This program is free software; you can redistribute it and/or modify | |
33822 | +# it under the terms of the GNU General Public License as published by | |
33823 | +# the Free Software Foundation; either version 3 of the License, or | |
33824 | +# (at your option) any later version. | |
33825 | +# | |
33826 | +# This program is distributed in the hope that it will be useful, | |
33827 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
33828 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
33829 | +# GNU General Public License for more details. | |
33830 | +# | |
33831 | +# You should have received a copy of the GNU General Public License | |
33832 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
33833 | + | |
33834 | + | |
33835 | +# In gdb inferior function calls, if a C++ exception is raised in the | |
33836 | +# dummy-frame, and the exception handler is (normally, and expected to | |
33837 | +# be) out-of-frame, the default C++ handler will (wrongly) be called | |
33838 | +# in an inferior function call. | |
33839 | +# This is incorrect as an exception can normally and legally be handled | |
33840 | +# out-of-frame. The confines of the dummy frame prevent the unwinder | |
33841 | +# from finding the correct handler (or any handler, unless it is | |
33842 | +# in-frame). The default handler calls std::terminate. This will kill | |
33843 | +# the inferior. Assert that terminate should never be called in an | |
33844 | +# inferior function call. These tests test the functionality around | |
33845 | +# unwinding that sequence and also tests the flag behaviour gating this | |
33846 | +# functionality. | |
33847 | + | |
33848 | +# This test is largley based off gdb.base/callfuncs.exp. | |
33849 | + | |
33850 | +if $tracelevel then { | |
33851 | + strace $tracelevel | |
33852 | +} | |
33853 | + | |
33854 | +if { [skip_cplus_tests] } { continue } | |
33855 | + | |
33856 | +set prms_id 2495 | |
33857 | +set bug_id 0 | |
33858 | + | |
33859 | +set testfile "gdb2495" | |
33860 | +set srcfile ${testfile}.cc | |
33861 | +set binfile $objdir/$subdir/$testfile | |
33862 | + | |
33863 | +# Create and source the file that provides information about the compiler | |
33864 | +# used to compile the test case. | |
33865 | +if [get_compiler_info ${binfile} "c++"] { | |
33866 | + return -1 | |
33867 | +} | |
33868 | + | |
33869 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
33870 | + untested gdb2495.exp | |
33871 | + return -1 | |
33872 | +} | |
33873 | + | |
33874 | +# Some targets can't do function calls, so don't even bother with this | |
33875 | +# test. | |
33876 | +if [target_info exists gdb,cannot_call_functions] { | |
33877 | + setup_xfail "*-*-*" 2416 | |
33878 | + fail "This target can not call functions" | |
33879 | + continue | |
33880 | +} | |
33881 | + | |
33882 | +gdb_exit | |
33883 | +gdb_start | |
33884 | +gdb_reinitialize_dir $srcdir/$subdir | |
33885 | +gdb_load ${binfile} | |
33886 | + | |
33887 | +if ![runto_main] then { | |
33888 | + perror "couldn't run to main" | |
33889 | + continue | |
33890 | +} | |
33891 | + | |
33892 | +# See http://sources.redhat.com/gdb/bugs/2495 | |
33893 | + | |
33894 | +# Test normal baseline behaviour. Call a function that | |
33895 | +# does not raise an exception ... | |
33896 | +gdb_test "p exceptions.no_throw_function()" " = 1" | |
33897 | +# And one that does but handles it in-frame ... | |
33898 | +gdb_test "p exceptions.throw_function_with_handler()" " = 2" | |
33899 | +# Both should return normally. | |
33900 | + | |
33901 | +# Test basic unwind. Call a function that raises an exception but | |
33902 | +# does not handle it. It should be rewound ... | |
33903 | +gdb_test "p exceptions.throw_function()" \ | |
33904 | + "The program being debugged entered a std::terminate call .*" \ | |
33905 | + "Call a function that raises an exception without a handler." | |
33906 | + | |
33907 | +# Make sure that after rewinding we are back at the call parent. | |
33908 | +gdb_test "bt" \ | |
33909 | + "#0 main.*" \ | |
33910 | + "bt after returning from a popped frame" | |
33911 | + | |
33912 | +# Make sure the only breakpoint is the one set via the runto_main | |
33913 | +# call and that the std::terminate breakpoint has evaporated and | |
33914 | +# cleaned-up. | |
33915 | +gdb_test "info breakpoints" \ | |
33916 | + "gdb.cp/gdb2495\.cc.*" | |
33917 | + | |
33918 | +# Turn off this new behaviour ... | |
33919 | +send_gdb "set unwind-on-terminating-exception off\n" | |
33920 | +gdb_expect { | |
33921 | + -re "$gdb_prompt $" {pass "set unwind-on-terminating-exception"} | |
33922 | + timeout {fail "(timeout) set unwind-on-terminating-exception"} | |
33923 | +} | |
33924 | + | |
33925 | +# Check that it is turned off ... | |
33926 | +gdb_test "show unwind-on-terminating-exception" \ | |
33927 | + "exception is unhandled while in a call dummy is off.*" \ | |
33928 | + "Turn off unwind on terminating exception flag" | |
33929 | + | |
33930 | +# Check that the old behaviour is restored. | |
33931 | +gdb_test "p exceptions.throw_function()" \ | |
33932 | + "The program being debugged stopped while in a function called .*" \ | |
33933 | + "Call a function that raises an exception with unwinding off.." | |
33934 | + | |
33935 | + | |
33936 | +# Restart back at main | |
33937 | +if ![runto_main] then { | |
33938 | + perror "couldn't run to main" | |
33939 | + continue | |
33940 | +} | |
33941 | + | |
33942 | + | |
33943 | +# Check to see if our new behaviour alters the unwind signal | |
33944 | +# behaviour. It should not. Test both on and off states. | |
33945 | + | |
33946 | +# Turn on unwind on signal behaviour ... | |
33947 | +send_gdb "set unwindonsignal on\n" | |
33948 | +gdb_expect { | |
33949 | + -re "$gdb_prompt $" {pass "set unwindonsignal on"} | |
33950 | + timeout {fail "(timeout) set unwindonsignal on"} | |
33951 | +} | |
33952 | + | |
33953 | +# Check that it is turned on ... | |
33954 | +gdb_test "show unwindonsignal" \ | |
33955 | + "signal is received while in a call dummy is on.*" \ | |
33956 | + "Turn on unwind on signal" | |
33957 | + | |
33958 | +# Check to see if new behaviour interferes with | |
33959 | +# normal signal handling in inferior function calls. | |
33960 | +gdb_test "p exceptions.raise_signal(1)" \ | |
33961 | + "To change this behavior use \"set unwindonsignal off\".*" | |
33962 | + | |
33963 | +# And reverse. Turn off | |
33964 | +send_gdb "set unwindonsignal off\n" | |
33965 | +gdb_expect { | |
33966 | + -re "$gdb_prompt $" {pass "set unwindonsignal off"} | |
33967 | + timeout {fail "(timeout) set unwindonsignal off"} | |
33968 | +} | |
33969 | + | |
33970 | +# Check that it is turned off ... | |
33971 | +gdb_test "show unwindonsignal" \ | |
33972 | + "signal is received while in a call dummy is off.*" \ | |
33973 | + "Turn off unwind on signal" | |
33974 | + | |
33975 | +# Check to see if new behaviour interferes with | |
33976 | +# normal signal handling in inferior function calls. | |
33977 | +gdb_test "p exceptions.raise_signal(1)" \ | |
33978 | + "To change this behavior use \"set unwindonsignal on\".*" | |
33979 | diff --git a/gdb/testsuite/gdb.cp/member-ptr.cc b/gdb/testsuite/gdb.cp/member-ptr.cc | |
33980 | index 1dff70a..648b2af 100644 | |
33981 | --- a/gdb/testsuite/gdb.cp/member-ptr.cc | |
33982 | +++ b/gdb/testsuite/gdb.cp/member-ptr.cc | |
33983 | @@ -138,6 +138,7 @@ class Diamond : public Padding, public Left, public Right | |
33984 | { | |
33985 | public: | |
33986 | virtual int vget_base (); | |
33987 | + int (*func_ptr) (int); | |
33988 | }; | |
33989 | ||
33990 | int Diamond::vget_base () | |
33991 | @@ -145,6 +146,12 @@ int Diamond::vget_base () | |
33992 | return this->Left::x + 2000; | |
33993 | } | |
33994 | ||
33995 | +int | |
33996 | +func (int x) | |
33997 | +{ | |
33998 | + return 19 + x; | |
33999 | +} | |
34000 | + | |
34001 | int main () | |
34002 | { | |
34003 | A a; | |
34004 | @@ -162,6 +169,7 @@ int main () | |
34005 | int (Diamond::*right_vpmf) (); | |
34006 | int (Base::*base_vpmf) (); | |
34007 | int Diamond::*diamond_pmi; | |
34008 | + int (* Diamond::*diamond_pfunc_ptr) (int); | |
34009 | ||
34010 | PMI null_pmi; | |
34011 | PMF null_pmf; | |
34012 | @@ -179,6 +187,7 @@ int main () | |
34013 | ||
34014 | diamond.Left::x = 77; | |
34015 | diamond.Right::x = 88; | |
34016 | + diamond.func_ptr = func; | |
34017 | ||
34018 | /* Some valid pointer to members from a base class. */ | |
34019 | left_pmf = (int (Diamond::*) ()) (int (Left::*) ()) (&Base::get_x); | |
34020 | @@ -193,11 +202,19 @@ int main () | |
34021 | /* A pointer to data member from a base class. */ | |
34022 | diamond_pmi = (int Diamond::*) (int Left::*) &Base::x; | |
34023 | ||
34024 | + /* A pointer to data member, where the member is itself a pointer to | |
34025 | + a function. */ | |
34026 | + diamond_pfunc_ptr = (int (* Diamond::*) (int)) &Diamond::func_ptr; | |
34027 | + | |
34028 | null_pmi = NULL; | |
34029 | null_pmf = NULL; | |
34030 | ||
34031 | pmi = NULL; /* Breakpoint 1 here. */ | |
34032 | ||
34033 | + // Invalid (uses diamond_pfunc_ptr as a function): | |
34034 | + // diamond.*diamond_pfunc_ptr (20); | |
34035 | + (diamond.*diamond_pfunc_ptr) (20); | |
34036 | + | |
34037 | k = (a.*pmf)(3); | |
34038 | ||
34039 | pmi = &A::jj; | |
34040 | diff --git a/gdb/testsuite/gdb.cp/member-ptr.exp b/gdb/testsuite/gdb.cp/member-ptr.exp | |
34041 | index b69d4ad..476711f 100644 | |
34042 | --- a/gdb/testsuite/gdb.cp/member-ptr.exp | |
34043 | +++ b/gdb/testsuite/gdb.cp/member-ptr.exp | |
34044 | @@ -390,6 +390,33 @@ gdb_test_multiple "print ((int) pmi) == ((char *) &a.j - (char *) & a)" $name { | |
34045 | } | |
34046 | } | |
34047 | ||
34048 | +# Check pointers to data members, which are themselves pointers to | |
34049 | +# functions. These behave like data members, not like pointers to | |
34050 | +# member functions. | |
34051 | + | |
34052 | +gdb_test "ptype diamond_pfunc_ptr" \ | |
34053 | + "type = int \\(\\*Diamond::\\*\\)\\(int\\)" | |
34054 | + | |
34055 | +gdb_test "ptype diamond.*diamond_pfunc_ptr" \ | |
34056 | + "type = int \\(\\*\\)\\(int\\)" | |
34057 | + | |
34058 | +# This one is invalid; () binds more tightly than .*, so it tries to | |
34059 | +# call the member pointer as a normal pointer-to-function. | |
34060 | + | |
34061 | +gdb_test "print diamond.*diamond_pfunc_ptr (20)" \ | |
34062 | + "Invalid data type for function to be called." | |
34063 | + | |
34064 | +# With parentheses, it is valid. | |
34065 | + | |
34066 | +gdb_test "print (diamond.*diamond_pfunc_ptr) (20)" \ | |
34067 | + "$vhn = 39" | |
34068 | + | |
34069 | +# Make sure that we do not interpret this as either a member pointer | |
34070 | +# call or a member function call. | |
34071 | + | |
34072 | +gdb_test "print diamond.func_ptr (20)" \ | |
34073 | + "$vhn = 39" | |
34074 | + | |
34075 | # ========================== | |
34076 | # pointer to member function | |
34077 | # ========================== | |
34078 | @@ -608,6 +635,9 @@ gdb_test_multiple "print (a.*pmf)(3)" $name { | |
34079 | } | |
34080 | } | |
34081 | ||
34082 | +gdb_test "ptype a.*pmf" "type = int \\(A \\*, int\\)" | |
34083 | +gdb_test "ptype (a.*pmf)(3)" "type = int" | |
34084 | + | |
34085 | # Print out a pointer to data member which requires looking into | |
34086 | # a base class. | |
34087 | gdb_test "print diamond_pmi" "$vhn = &Base::x" | |
34088 | diff --git a/gdb/testsuite/gdb.cp/namespace-multiple-imports.cc b/gdb/testsuite/gdb.cp/namespace-multiple-imports.cc | |
34089 | new file mode 100644 | |
34090 | index 0000000..6b180d6 | |
34091 | --- /dev/null | |
34092 | +++ b/gdb/testsuite/gdb.cp/namespace-multiple-imports.cc | |
34093 | @@ -0,0 +1,20 @@ | |
34094 | +namespace A { | |
34095 | + int x = 11; | |
34096 | + namespace{ | |
34097 | + int xx = 22; | |
34098 | + } | |
34099 | +} | |
34100 | + | |
34101 | +using namespace A; | |
34102 | + | |
34103 | +namespace{ | |
34104 | + int xxx = 33; | |
34105 | +}; | |
34106 | + | |
34107 | +int main() | |
34108 | +{ | |
34109 | + x; | |
34110 | + xx; | |
34111 | + xxx; | |
34112 | + return 0; | |
34113 | +} | |
34114 | diff --git a/gdb/testsuite/gdb.cp/namespace-multiple-imports.exp b/gdb/testsuite/gdb.cp/namespace-multiple-imports.exp | |
34115 | new file mode 100644 | |
34116 | index 0000000..e4bb9f8 | |
34117 | --- /dev/null | |
34118 | +++ b/gdb/testsuite/gdb.cp/namespace-multiple-imports.exp | |
34119 | @@ -0,0 +1,49 @@ | |
34120 | +# Copyright 2008 Free Software Foundation, Inc. | |
34121 | + | |
34122 | +# This program is free software; you can redistribute it and/or modify | |
34123 | +# it under the terms of the GNU General Public License as published by | |
34124 | +# the Free Software Foundation; either version 3 of the License, or | |
34125 | +# (at your option) any later version. | |
34126 | +# | |
34127 | +# This program is distributed in the hope that it will be useful, | |
34128 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34129 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
34130 | +# GNU General Public License for more details. | |
34131 | +# | |
34132 | +# You should have received a copy of the GNU General Public License | |
34133 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
34134 | + | |
34135 | +if $tracelevel then { | |
34136 | + strace $tracelevel | |
34137 | +} | |
34138 | + | |
34139 | +set prms_id 0 | |
34140 | +set bug_id 0 | |
34141 | + | |
34142 | +set testfile namespace-multiple-imports | |
34143 | +set srcfile ${testfile}.cc | |
34144 | +set binfile ${objdir}/${subdir}/${testfile} | |
34145 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
34146 | + untested "Couldn't compile test program" | |
34147 | + return -1 | |
34148 | +} | |
34149 | + | |
34150 | +# Get things started. | |
34151 | + | |
34152 | +gdb_exit | |
34153 | +gdb_start | |
34154 | +gdb_reinitialize_dir $srcdir/$subdir | |
34155 | +gdb_load ${binfile} | |
34156 | + | |
34157 | +############################################ | |
34158 | +# test printing of namespace imported within | |
34159 | +# the function. | |
34160 | + | |
34161 | +if ![runto_main] then { | |
34162 | + perror "couldn't run to breakpoint main" | |
34163 | + continue | |
34164 | +} | |
34165 | + | |
34166 | +gdb_test "print x" "\\$\[0-9\].* = 11" | |
34167 | +gdb_test "print xx" "\\$\[0-9\].* = 22" | |
34168 | +gdb_test "print xxx" "\\$\[0-9\].* = 33" | |
34169 | diff --git a/gdb/testsuite/gdb.cp/namespace-using.cc b/gdb/testsuite/gdb.cp/namespace-using.cc | |
34170 | new file mode 100644 | |
34171 | index 0000000..97af850 | |
34172 | --- /dev/null | |
34173 | +++ b/gdb/testsuite/gdb.cp/namespace-using.cc | |
34174 | @@ -0,0 +1,131 @@ | |
34175 | +//-------------------------- | |
34176 | +namespace M{ | |
34177 | + int x = 911; | |
34178 | +} | |
34179 | + | |
34180 | +namespace N{ | |
34181 | + int x = 912; | |
34182 | +} | |
34183 | + | |
34184 | +int marker10(){ | |
34185 | + using namespace M; | |
34186 | + int y = x+1; // marker10 stop | |
34187 | + using namespace N; | |
34188 | + return y; | |
34189 | +} | |
34190 | +//-------------------------- | |
34191 | +namespace J { | |
34192 | + int jx = 44; | |
34193 | +} | |
34194 | + | |
34195 | +namespace K{ | |
34196 | + int marker9(){ | |
34197 | + //x; | |
34198 | + return marker10(); | |
34199 | + } | |
34200 | +} | |
34201 | + | |
34202 | +namespace L{ | |
34203 | + using namespace J; | |
34204 | + int marker8(){ | |
34205 | + jx; | |
34206 | + return K::marker9(); | |
34207 | + } | |
34208 | +} | |
34209 | +//-------------------------- | |
34210 | + | |
34211 | +//-------------------------- | |
34212 | +namespace G{ | |
34213 | + namespace H { | |
34214 | + int ghx = 6; | |
34215 | + } | |
34216 | +} | |
34217 | + | |
34218 | +namespace I{ | |
34219 | + | |
34220 | + int marker7(){ | |
34221 | + using namespace G::H; | |
34222 | + ghx; | |
34223 | + return L::marker8(); | |
34224 | + } | |
34225 | +} | |
34226 | +//-------------------------- | |
34227 | + | |
34228 | +//-------------------------- | |
34229 | +namespace E{ | |
34230 | + namespace F{ | |
34231 | + int efx = 5; | |
34232 | + } | |
34233 | +} | |
34234 | +using namespace E::F; | |
34235 | +int marker6(){ | |
34236 | + efx; | |
34237 | + return I::marker7(); | |
34238 | +} | |
34239 | +//-------------------------- | |
34240 | + | |
34241 | +namespace A | |
34242 | +{ | |
34243 | + int _a = 1; | |
34244 | + int x = 2; | |
34245 | + | |
34246 | +} | |
34247 | + | |
34248 | +namespace C | |
34249 | +{ | |
34250 | + int cc = 3; | |
34251 | +} | |
34252 | + | |
34253 | +namespace D | |
34254 | +{ | |
34255 | + int dx = 4; | |
34256 | +} | |
34257 | + | |
34258 | +using namespace C; | |
34259 | +int marker5() | |
34260 | +{ | |
34261 | + cc; | |
34262 | + return marker6(); | |
34263 | +} | |
34264 | + | |
34265 | +int marker4() | |
34266 | +{ | |
34267 | + using D::dx; | |
34268 | + return marker5(); | |
34269 | +} | |
34270 | + | |
34271 | +int marker3() | |
34272 | +{ | |
34273 | + return marker4(); | |
34274 | +} | |
34275 | + | |
34276 | +int marker2() | |
34277 | +{ | |
34278 | + namespace B = A; | |
34279 | + B::_a; | |
34280 | + return marker3(); | |
34281 | +} | |
34282 | + | |
34283 | +int marker1() | |
34284 | +{ | |
34285 | + int total = 0; | |
34286 | + { | |
34287 | + int b = 1; | |
34288 | + { | |
34289 | + using namespace A; | |
34290 | + int c = 2; | |
34291 | + { | |
34292 | + int d = 3; | |
34293 | + total = _a + b + c + d + marker2(); // marker1 stop | |
34294 | + } | |
34295 | + } | |
34296 | + } | |
34297 | + return total; | |
34298 | +} | |
34299 | + | |
34300 | +int main() | |
34301 | +{ | |
34302 | + using namespace A; | |
34303 | + _a; | |
34304 | + return marker1(); | |
34305 | +} | |
34306 | diff --git a/gdb/testsuite/gdb.cp/namespace-using.exp b/gdb/testsuite/gdb.cp/namespace-using.exp | |
34307 | new file mode 100644 | |
34308 | index 0000000..f73fa67 | |
34309 | --- /dev/null | |
34310 | +++ b/gdb/testsuite/gdb.cp/namespace-using.exp | |
34311 | @@ -0,0 +1,186 @@ | |
34312 | +# Copyright 2008 Free Software Foundation, Inc. | |
34313 | + | |
34314 | +# This program is free software; you can redistribute it and/or modify | |
34315 | +# it under the terms of the GNU General Public License as published by | |
34316 | +# the Free Software Foundation; either version 3 of the License, or | |
34317 | +# (at your option) any later version. | |
34318 | +# | |
34319 | +# This program is distributed in the hope that it will be useful, | |
34320 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34321 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
34322 | +# GNU General Public License for more details. | |
34323 | +# | |
34324 | +# You should have received a copy of the GNU General Public License | |
34325 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
34326 | + | |
34327 | +if $tracelevel then { | |
34328 | + strace $tracelevel | |
34329 | +} | |
34330 | + | |
34331 | +set prms_id 0 | |
34332 | +set bug_id 0 | |
34333 | + | |
34334 | +set testfile namespace-using | |
34335 | +set srcfile ${testfile}.cc | |
34336 | +set binfile ${objdir}/${subdir}/${testfile} | |
34337 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { | |
34338 | + untested "Couldn't compile test program" | |
34339 | + return -1 | |
34340 | +} | |
34341 | + | |
34342 | +# Get things started. | |
34343 | + | |
34344 | +gdb_exit | |
34345 | +gdb_start | |
34346 | +gdb_reinitialize_dir $srcdir/$subdir | |
34347 | +gdb_load ${binfile} | |
34348 | + | |
34349 | +############################################ | |
34350 | +# test printing of namespace imported within | |
34351 | +# the function. | |
34352 | + | |
34353 | +if ![runto_main] then { | |
34354 | + perror "couldn't run to breakpoint main" | |
34355 | + continue | |
34356 | +} | |
34357 | + | |
34358 | +gdb_test "print _a" "= 1" | |
34359 | + | |
34360 | +# Test that names are not printed when they | |
34361 | +# are not imported | |
34362 | + | |
34363 | +gdb_breakpoint marker3 | |
34364 | +gdb_continue_to_breakpoint "marker3" | |
34365 | + | |
34366 | +#send_gdb "break marker3\n" | |
34367 | +#send_gdb "continue\n" | |
34368 | + | |
34369 | +gdb_test "print _a" "No symbol \"_a\" in current context." "Print _a without import" | |
34370 | + | |
34371 | +gdb_exit | |
34372 | +gdb_start | |
34373 | +gdb_reinitialize_dir $srcdir/$subdir | |
34374 | +gdb_load ${binfile} | |
34375 | + | |
34376 | + | |
34377 | +############################################ | |
34378 | +# test printing of namespace imported into | |
34379 | +# a scope containing the pc. | |
34380 | + | |
34381 | +if ![runto_main] then { | |
34382 | + perror "couldn't run to breakpoint main" | |
34383 | + continue | |
34384 | +} | |
34385 | + | |
34386 | +gdb_breakpoint [gdb_get_line_number "marker1 stop"] | |
34387 | +gdb_continue_to_breakpoint "marker1 stop" | |
34388 | + | |
34389 | +gdb_test "print _a" "= 1" "print _a in a nested scope" | |
34390 | + | |
34391 | + | |
34392 | +gdb_exit | |
34393 | +gdb_start | |
34394 | +gdb_reinitialize_dir $srcdir/$subdir | |
34395 | +gdb_load ${binfile} | |
34396 | + | |
34397 | +############################################ | |
34398 | +# test printing of namespace imported into | |
34399 | +# file scope. | |
34400 | + | |
34401 | + | |
34402 | +if ![runto marker5] then { | |
34403 | + perror "couldn't run to breakpoint marker5" | |
34404 | + continue | |
34405 | +} | |
34406 | + | |
34407 | +gdb_test "print cc" "= 3" | |
34408 | + | |
34409 | +gdb_exit | |
34410 | +gdb_start | |
34411 | +gdb_reinitialize_dir $srcdir/$subdir | |
34412 | +gdb_load ${binfile} | |
34413 | + | |
34414 | + | |
34415 | +############################################ | |
34416 | +# Test printing of namespace aliases | |
34417 | + | |
34418 | +if ![runto marker2] then { | |
34419 | + perror "couldn't run to breakpoint marker2" | |
34420 | + continue | |
34421 | +} | |
34422 | + | |
34423 | +gdb_test "print B::_a" "= 1" | |
34424 | + | |
34425 | +gdb_test "print _a" "No symbol \"_a\" in current context." "print _a in namespace alias scope" | |
34426 | +gdb_test "print x" "No symbol \"x\" in current context." "print x in namespace alias scope" | |
34427 | + | |
34428 | +gdb_exit | |
34429 | +gdb_start | |
34430 | +gdb_reinitialize_dir $srcdir/$subdir | |
34431 | +gdb_load ${binfile} | |
34432 | + | |
34433 | + | |
34434 | +############################################ | |
34435 | +# Test printing of namespace aliases | |
34436 | + | |
34437 | +if ![runto marker4] then { | |
34438 | + perror "couldn't run to breakpoint marker4" | |
34439 | + continue | |
34440 | +} | |
34441 | + | |
34442 | +gdb_test "print dx" "= 4" | |
34443 | + | |
34444 | +############################################ | |
34445 | +# Test printing of namespace aliases | |
34446 | + | |
34447 | +if ![runto marker6] then { | |
34448 | + perror "couldn't run to breakpoint marker6" | |
34449 | + continue | |
34450 | +} | |
34451 | + | |
34452 | +gdb_test "print efx" "= 5" | |
34453 | + | |
34454 | +############################################ | |
34455 | +# Test printing of variables imported from | |
34456 | +# nested namespaces | |
34457 | + | |
34458 | +if ![runto I::marker7] then { | |
34459 | + perror "couldn't run to breakpoint I::marker7" | |
34460 | + continue | |
34461 | +} | |
34462 | + | |
34463 | +gdb_test "print ghx" "= 6" | |
34464 | + | |
34465 | +############################################ | |
34466 | +# Test that variables are not printed in a namespace | |
34467 | +# that is sibling to the namespace containing an import | |
34468 | + | |
34469 | +if ![runto L::marker8] then { | |
34470 | + perror "couldn't run to breakpoint L::marker8" | |
34471 | + continue | |
34472 | +} | |
34473 | + | |
34474 | +gdb_test "print jx" "= 44" | |
34475 | + | |
34476 | +gdb_breakpoint "K::marker9" | |
34477 | +gdb_continue_to_breakpoint "K::marker9" | |
34478 | + | |
34479 | +gdb_test "print jx" "No symbol \"jx\" in current context." | |
34480 | + | |
34481 | +############################################ | |
34482 | +# Test that variables are only printed after the line | |
34483 | +# containing the import | |
34484 | + | |
34485 | +if ![runto_main] then { | |
34486 | + perror "couldn't run to breakpoint main" | |
34487 | + continue | |
34488 | +} | |
34489 | + | |
34490 | +gdb_breakpoint [gdb_get_line_number "marker10 stop"] | |
34491 | +gdb_continue_to_breakpoint "marker10 stop" | |
34492 | + | |
34493 | +gdb_test "print x" "= 911" "print x (from M::x)" | |
34494 | + | |
34495 | +gdb_test "next" "" | |
34496 | + | |
34497 | +gdb_test "print x" "= 912" "print x (from M::x)" | |
34498 | diff --git a/gdb/testsuite/gdb.cp/namespace.exp b/gdb/testsuite/gdb.cp/namespace.exp | |
34499 | index 76b1b82..2042db2 100644 | |
34500 | --- a/gdb/testsuite/gdb.cp/namespace.exp | |
34501 | +++ b/gdb/testsuite/gdb.cp/namespace.exp | |
34502 | @@ -24,6 +24,7 @@ | |
34503 | # for namespaces. | |
34504 | # Note: As of 2000-06-03, they passed under g++ - djb | |
34505 | ||
34506 | +load_lib "cp-support.exp" | |
34507 | ||
34508 | if $tracelevel then { | |
34509 | strace $tracelevel | |
34510 | @@ -259,11 +260,16 @@ gdb_test "ptype E" "type = namespace C::D::E" | |
34511 | gdb_test "ptype CClass" "type = (class C::CClass \{\r\n public:|struct C::CClass \{)\r\n int x;\r\n\}" | |
34512 | gdb_test "ptype CClass::NestedClass" "type = (class C::CClass::NestedClass \{\r\n public:|struct C::CClass::NestedClass \{)\r\n int y;\r\n\}" | |
34513 | gdb_test "ptype NestedClass" "No symbol \"NestedClass\" in current context." | |
34514 | -setup_kfail "gdb/1448" "*-*-*" | |
34515 | -gdb_test "ptype ::C::CClass" "type = class C::CClass \{\r\n public:\r\n int x;\r\n\}" | |
34516 | -setup_kfail "gdb/1448" "*-*-*" | |
34517 | -gdb_test "ptype ::C::CClass::NestedClass" "type = class C::CClass::NestedClass \{\r\n public:\r\n int y;\r\n\}" | |
34518 | -setup_kfail "gdb/1448" "*-*-*" | |
34519 | +cp_test_ptype_class \ | |
34520 | + "ptype ::C::CClass" "" "class" "C::CClass" \ | |
34521 | + { | |
34522 | + { field public "int x;" } | |
34523 | + } | |
34524 | +cp_test_ptype_class \ | |
34525 | + "ptype ::C::CClass::NestedClass" "" "class" "C::CClass::NestedClass" \ | |
34526 | + { | |
34527 | + { field public "int y;" } | |
34528 | + } | |
34529 | gdb_test "ptype ::C::NestedClass" "No symbol \"NestedClass\" in namespace \"C\"." | |
34530 | gdb_test "ptype C::CClass" "No symbol \"CClass\" in namespace \"C::C\"." | |
34531 | gdb_test "ptype C::CClass::NestedClass" "No type \"CClass\" within class or namespace \"C::C\"." | |
34532 | @@ -273,8 +279,11 @@ gdb_test "ptype C::NestedClass" "No symbol \"NestedClass\" in namespace \"C::C\" | |
34533 | ||
34534 | gdb_test "print cOtherFile" "\\$\[0-9\].* = 316" | |
34535 | gdb_test "ptype OtherFileClass" "type = (class C::OtherFileClass \{\r\n public:|struct C::OtherFileClass \{)\r\n int z;\r\n\}" | |
34536 | -setup_kfail "gdb/1448" "*-*-*" | |
34537 | -gdb_test "ptype ::C::OtherFileClass" "type = class C::OtherFileClass \{\r\n public:\r\n int z;\r\n\}" | |
34538 | +cp_test_ptype_class \ | |
34539 | + "ptype ::C::OtherFileClass" "" "class" "C::OtherFileClass" \ | |
34540 | + { | |
34541 | + { field public "int z;" } | |
34542 | + } | |
34543 | gdb_test "ptype C::OtherFileClass" "No symbol \"OtherFileClass\" in namespace \"C::C\"." | |
34544 | ||
34545 | # Some anonymous namespace tests. | |
34546 | diff --git a/gdb/testsuite/gdb.cp/overload.exp b/gdb/testsuite/gdb.cp/overload.exp | |
34547 | index 24025a2..a72932e 100644 | |
34548 | --- a/gdb/testsuite/gdb.cp/overload.exp | |
34549 | +++ b/gdb/testsuite/gdb.cp/overload.exp | |
34550 | @@ -74,12 +74,12 @@ set re_methods "${re_methods}${ws}int overload1arg\\((void|)\\);" | |
34551 | set re_methods "${re_methods}${ws}int overload1arg\\(char\\);" | |
34552 | set re_methods "${re_methods}${ws}int overload1arg\\(signed char\\);" | |
34553 | set re_methods "${re_methods}${ws}int overload1arg\\(unsigned char\\);" | |
34554 | -set re_methods "${re_methods}${ws}int overload1arg\\(short\\);" | |
34555 | -set re_methods "${re_methods}${ws}int overload1arg\\(unsigned short\\);" | |
34556 | +set re_methods "${re_methods}${ws}int overload1arg\\(short( int)?\\);" | |
34557 | +set re_methods "${re_methods}${ws}int overload1arg\\((unsigned short|short unsigned)( int)?\\);" | |
34558 | set re_methods "${re_methods}${ws}int overload1arg\\(int\\);" | |
34559 | set re_methods "${re_methods}${ws}int overload1arg\\(unsigned int\\);" | |
34560 | -set re_methods "${re_methods}${ws}int overload1arg\\(long\\);" | |
34561 | -set re_methods "${re_methods}${ws}int overload1arg\\(unsigned long\\);" | |
34562 | +set re_methods "${re_methods}${ws}int overload1arg\\(long( int)?\\);" | |
34563 | +set re_methods "${re_methods}${ws}int overload1arg\\((unsigned long|long unsigned)( int)?\\);" | |
34564 | set re_methods "${re_methods}${ws}int overload1arg\\(float\\);" | |
34565 | set re_methods "${re_methods}${ws}int overload1arg\\(double\\);" | |
34566 | set re_methods "${re_methods}${ws}int overloadfnarg\\((void|)\\);" | |
34567 | diff --git a/gdb/testsuite/gdb.cp/ovldbreak.exp b/gdb/testsuite/gdb.cp/ovldbreak.exp | |
34568 | index 8a6b795..897171c 100644 | |
34569 | --- a/gdb/testsuite/gdb.cp/ovldbreak.exp | |
34570 | +++ b/gdb/testsuite/gdb.cp/ovldbreak.exp | |
34571 | @@ -127,10 +127,24 @@ proc set_bp_overloaded {name expectedmenu mychoice bpnumber linenumber} { | |
34572 | } | |
34573 | ||
34574 | # This is the expected menu for overload1arg. | |
34575 | -# Note the arg type variations on lines 6 and 13. | |
34576 | +# Note the arg type variations for void and integer types. | |
34577 | # This accommodates different versions of g++. | |
34578 | ||
34579 | -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> $" | |
34580 | +set menu_overload1arg "\\\[0\\\] cancel\r\n" | |
34581 | +append menu_overload1arg "\\\[1\\\] all\r\n" | |
34582 | +append menu_overload1arg "\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n" | |
34583 | +append menu_overload1arg "\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n" | |
34584 | +append menu_overload1arg "\\\[4\\\] foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r\n" | |
34585 | +append menu_overload1arg "\\\[5\\\] foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r\n" | |
34586 | +append menu_overload1arg "\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n" | |
34587 | +append menu_overload1arg "\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n" | |
34588 | +append menu_overload1arg "\\\[8\\\] foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r\n" | |
34589 | +append menu_overload1arg "\\\[9\\\] foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r\n" | |
34590 | +append menu_overload1arg "\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n" | |
34591 | +append menu_overload1arg "\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n" | |
34592 | +append menu_overload1arg "\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n" | |
34593 | +append menu_overload1arg "\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n" | |
34594 | +append menu_overload1arg "> $" | |
34595 | ||
34596 | # Set multiple-symbols to "ask", to allow us to test the use | |
34597 | # of the multiple-choice menu when breaking on an overloaded method. | |
34598 | @@ -157,17 +171,17 @@ set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 13 13 110 | |
34599 | ||
34600 | gdb_test "info break" \ | |
34601 | "Num Type\[\t \]+Disp Enb Address\[\t \]+What.* | |
34602 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r | |
34603 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in main(\\(void\\))? at.*$srcfile:49\r | |
34604 | \[\t \]+breakpoint already hit 1 time\r | |
34605 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r | |
34606 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r | |
34607 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r | |
34608 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r | |
34609 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r | |
34610 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r | |
34611 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r | |
34612 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r | |
34613 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r | |
34614 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r | |
34615 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r | |
34616 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r | |
34617 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r | |
34618 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r | |
34619 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r | |
34620 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \ | |
34621 | @@ -215,17 +229,17 @@ gdb_expect { | |
34622 | ||
34623 | gdb_test "info break" \ | |
34624 | "Num Type\[\t \]+Disp Enb Address\[\t \]+What.* | |
34625 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r | |
34626 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in main(\\(void\\))? at.*$srcfile:49\r | |
34627 | \[\t \]+breakpoint already hit 1 time\r | |
34628 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r | |
34629 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r | |
34630 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r | |
34631 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r | |
34632 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r | |
34633 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r | |
34634 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r | |
34635 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r | |
34636 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r | |
34637 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r | |
34638 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r | |
34639 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r | |
34640 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r | |
34641 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r | |
34642 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r | |
34643 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \ | |
34644 | @@ -296,12 +310,12 @@ gdb_test "info break" \ | |
34645 | "Num Type\[\t \]+Disp Enb Address\[\t \]+What.* | |
34646 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r | |
34647 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r | |
34648 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r | |
34649 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r | |
34650 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r | |
34651 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r | |
34652 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r | |
34653 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r | |
34654 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r | |
34655 | -\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r | |
34656 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r | |
34657 | +\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r | |
34658 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r | |
34659 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r | |
34660 | \[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r | |
34661 | diff --git a/gdb/testsuite/gdb.cp/ref-types.exp b/gdb/testsuite/gdb.cp/ref-types.exp | |
34662 | index 4784cb2..b2e55cf 100644 | |
34663 | --- a/gdb/testsuite/gdb.cp/ref-types.exp | |
34664 | +++ b/gdb/testsuite/gdb.cp/ref-types.exp | |
34665 | @@ -284,7 +284,7 @@ gdb_expect { | |
34666 | ||
34667 | send_gdb "print UC\n" | |
34668 | gdb_expect { | |
34669 | - -re ".\[0-9\]* = 21 '\.025'\.*$gdb_prompt $" { | |
34670 | + -re ".\[0-9\]* = 21 '\.25'\.*$gdb_prompt $" { | |
34671 | pass "print value of UC" | |
34672 | } | |
34673 | -re ".*$gdb_prompt $" { fail "print value of UC" } | |
34674 | @@ -557,7 +557,7 @@ gdb_expect { | |
34675 | ||
34676 | send_gdb "print rUC\n" | |
34677 | gdb_expect { | |
34678 | - -re ".\[0-9\]* = \\(unsigned char &\\) @$hex: 21 \'.025\'.*$gdb_prompt $" { | |
34679 | + -re ".\[0-9\]* = \\(unsigned char &\\) @$hex: 21 \'.25\'.*$gdb_prompt $" { | |
34680 | pass "print value of rUC" | |
34681 | } | |
34682 | -re ".*$gdb_prompt $" { fail "print value of rUC" } | |
34683 | diff --git a/gdb/testsuite/gdb.cp/templates.exp b/gdb/testsuite/gdb.cp/templates.exp | |
34684 | index cd9b770..f49caff 100644 | |
34685 | --- a/gdb/testsuite/gdb.cp/templates.exp | |
34686 | +++ b/gdb/testsuite/gdb.cp/templates.exp | |
34687 | @@ -329,13 +329,11 @@ gdb_expect { | |
34688 | ||
34689 | send_gdb "print Foo<volatile char *>::foo\n" | |
34690 | gdb_expect { | |
34691 | - -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<volatile char ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char *>::foo" } | |
34692 | + -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<(volatile char|char volatile) ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char *>::foo" } | |
34693 | -re "No symbol \"Foo<volatile char \\*>\" in current context.\r\n$gdb_prompt $" | |
34694 | { | |
34695 | - # This used to be a kfail gdb/33. That problem has been | |
34696 | - # fixed, but now gdb/931 and gdb/1512 are rearing their ugly | |
34697 | - # heads. | |
34698 | - kfail "gdb/931" "print Foo<volatile char *>::foo" | |
34699 | + # This used to be a kfail gdb/33 and then kfail gdb/931. | |
34700 | + fail "print Foo<volatile char *>::foo" | |
34701 | } | |
34702 | -re "$gdb_prompt $" { fail "print Foo<volatile char *>::foo" } | |
34703 | timeout { fail "(timeout) print Foo<volatile char *>::foo" } | |
34704 | @@ -343,13 +341,11 @@ gdb_expect { | |
34705 | ||
34706 | send_gdb "print Foo<volatile char*>::foo\n" | |
34707 | gdb_expect { | |
34708 | - -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<volatile char ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char*>::foo" } | |
34709 | + -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<(volatile char|char volatile) ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char*>::foo" } | |
34710 | -re "No symbol \"Foo<volatile char\\*>\" in current context.\r\n$gdb_prompt $" | |
34711 | { | |
34712 | - # This used to be a kfail gdb/33. That problem has been | |
34713 | - # fixed, but now gdb/931 and gdb/1512 are rearing their ugly | |
34714 | - # heads. | |
34715 | - kfail "gdb/931" "print Foo<volatile char*>::foo" | |
34716 | + # This used to be a kfail gdb/33 and then kfail gdb/931. | |
34717 | + fail "print Foo<volatile char*>::foo" | |
34718 | } | |
34719 | -re "$gdb_prompt $" { fail "print Foo<volatile char*>::foo" } | |
34720 | timeout { fail "(timeout) print Foo<volatile char*>::foo" } | |
34721 | @@ -459,7 +455,7 @@ send_gdb "ptype quxint\n" | |
34722 | gdb_expect { | |
34723 | -re "type = class Qux<int, ?& ?string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int qux\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" } | |
34724 | -re "type = class Qux<int, ?& ?string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" } | |
34725 | - -re "type = class Qux<int, ?\\(char ?\\*\\)\\(& ?string\\)> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" } | |
34726 | + -re "type = class Qux<int, ?\\(char ?\\*\\)\\(& ?\\(?string\\)?\\)> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" } | |
34727 | -re "type = class Qux<int, ?& ?\\(string\\)> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { | |
34728 | kfail "gdb/1512" "ptype quxint" | |
34729 | } | |
34730 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.c b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c | |
34731 | new file mode 100644 | |
34732 | index 0000000..1f02d90 | |
34733 | --- /dev/null | |
34734 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c | |
34735 | @@ -0,0 +1,42 @@ | |
34736 | +/* This testcase is part of GDB, the GNU debugger. | |
34737 | + | |
34738 | + Copyright 2004 Free Software Foundation, Inc. | |
34739 | + | |
34740 | + This program is free software; you can redistribute it and/or modify | |
34741 | + it under the terms of the GNU General Public License as published by | |
34742 | + the Free Software Foundation; either version 2 of the License, or | |
34743 | + (at your option) any later version. | |
34744 | + | |
34745 | + This program is distributed in the hope that it will be useful, | |
34746 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34747 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
34748 | + GNU General Public License for more details. | |
34749 | + | |
34750 | + You should have received a copy of the GNU General Public License | |
34751 | + along with this program; if not, write to the Free Software | |
34752 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
34753 | + USA. */ | |
34754 | + | |
34755 | + | |
34756 | +/* The function `func1' traced into must have debug info on offset > 0; | |
34757 | + (DW_UNSND (attr)). This is the reason of `func0' existence. */ | |
34758 | + | |
34759 | +void | |
34760 | +func0(int a, int b) | |
34761 | +{ | |
34762 | +} | |
34763 | + | |
34764 | +/* `func1' being traced into must have some arguments to dump. */ | |
34765 | + | |
34766 | +void | |
34767 | +func1(int a, int b) | |
34768 | +{ | |
34769 | + func0 (a,b); | |
34770 | +} | |
34771 | + | |
34772 | +int | |
34773 | +main(void) | |
34774 | +{ | |
34775 | + func1 (1, 2); | |
34776 | + return 0; | |
34777 | +} | |
34778 | diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp | |
34779 | new file mode 100644 | |
34780 | index 0000000..1c6e84a | |
34781 | --- /dev/null | |
34782 | +++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp | |
34783 | @@ -0,0 +1,79 @@ | |
34784 | +# Copyright 2006 Free Software Foundation, Inc. | |
34785 | + | |
34786 | +# This program is free software; you can redistribute it and/or modify | |
34787 | +# it under the terms of the GNU General Public License as published by | |
34788 | +# the Free Software Foundation; either version 2 of the License, or | |
34789 | +# (at your option) any later version. | |
34790 | +# | |
34791 | +# This program is distributed in the hope that it will be useful, | |
34792 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34793 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
34794 | +# GNU General Public License for more details. | |
34795 | +# | |
34796 | +# You should have received a copy of the GNU General Public License | |
34797 | +# along with this program; if not, write to the Free Software | |
34798 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
34799 | + | |
34800 | +# Minimal DWARF-2 unit test | |
34801 | + | |
34802 | +# This test can only be run on targets which support DWARF-2. | |
34803 | +# For now pick a sampling of likely targets. | |
34804 | +if {![istarget *-*-linux*] | |
34805 | + && ![istarget *-*-gnu*] | |
34806 | + && ![istarget *-*-elf*] | |
34807 | + && ![istarget *-*-openbsd*] | |
34808 | + && ![istarget arm-*-eabi*] | |
34809 | + && ![istarget powerpc-*-eabi*]} { | |
34810 | + return 0 | |
34811 | +} | |
34812 | + | |
34813 | +set testfile "dw2-stripped" | |
34814 | +set srcfile ${testfile}.c | |
34815 | +set binfile ${objdir}/${subdir}/${testfile}.x | |
34816 | + | |
34817 | +remote_exec build "rm -f ${binfile}" | |
34818 | + | |
34819 | +# get the value of gcc_compiled | |
34820 | +if [get_compiler_info ${binfile}] { | |
34821 | + return -1 | |
34822 | +} | |
34823 | + | |
34824 | +# This test can only be run on gcc as we use additional_flags=FIXME | |
34825 | +if {$gcc_compiled == 0} { | |
34826 | + return 0 | |
34827 | +} | |
34828 | + | |
34829 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-ggdb3}] != "" } { | |
34830 | + return -1 | |
34831 | +} | |
34832 | + | |
34833 | +remote_exec build "objcopy -R .debug_loc ${binfile}" | |
34834 | +set strip_output [remote_exec build "objdump -h ${binfile}"] | |
34835 | + | |
34836 | +set test "stripping test file preservation" | |
34837 | +if [ regexp ".debug_info " $strip_output] { | |
34838 | + pass "$test (.debug_info preserved)" | |
34839 | +} else { | |
34840 | + fail "$test (.debug_info got also stripped)" | |
34841 | +} | |
34842 | + | |
34843 | +set test "stripping test file functionality" | |
34844 | +if [ regexp ".debug_loc " $strip_output] { | |
34845 | + fail "$test (.debug_loc still present)" | |
34846 | +} else { | |
34847 | + pass "$test (.debug_loc stripped)" | |
34848 | +} | |
34849 | + | |
34850 | +gdb_exit | |
34851 | +gdb_start | |
34852 | +gdb_reinitialize_dir $srcdir/$subdir | |
34853 | +gdb_load ${binfile} | |
34854 | + | |
34855 | +# For C programs, "start" should stop in main(). | |
34856 | + | |
34857 | +gdb_test "start" \ | |
34858 | + ".*main \\(\\) at .*" \ | |
34859 | + "start" | |
34860 | +gdb_test "step" \ | |
34861 | + "func.* \\(.*\\) at .*" \ | |
34862 | + "step" | |
34863 | diff --git a/gdb/testsuite/gdb.fortran/common-block.exp b/gdb/testsuite/gdb.fortran/common-block.exp | |
34864 | new file mode 100644 | |
34865 | index 0000000..888f6c3 | |
34866 | --- /dev/null | |
34867 | +++ b/gdb/testsuite/gdb.fortran/common-block.exp | |
34868 | @@ -0,0 +1,101 @@ | |
34869 | +# Copyright 2008 Free Software Foundation, Inc. | |
34870 | + | |
34871 | +# This program is free software; you can redistribute it and/or modify | |
34872 | +# it under the terms of the GNU General Public License as published by | |
34873 | +# the Free Software Foundation; either version 2 of the License, or | |
34874 | +# (at your option) any later version. | |
34875 | +# | |
34876 | +# This program is distributed in the hope that it will be useful, | |
34877 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34878 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
34879 | +# GNU General Public License for more details. | |
34880 | +# | |
34881 | +# You should have received a copy of the GNU General Public License | |
34882 | +# along with this program; if not, write to the Free Software | |
34883 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
34884 | + | |
34885 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
34886 | + | |
34887 | +set testfile "common-block" | |
34888 | +set srcfile ${testfile}.f90 | |
34889 | +set binfile ${objdir}/${subdir}/${testfile} | |
34890 | + | |
34891 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } { | |
34892 | + untested "Couldn't compile ${srcfile}" | |
34893 | + return -1 | |
34894 | +} | |
34895 | + | |
34896 | +gdb_exit | |
34897 | +gdb_start | |
34898 | +gdb_reinitialize_dir $srcdir/$subdir | |
34899 | +gdb_load ${binfile} | |
34900 | + | |
34901 | +if ![runto MAIN__] then { | |
34902 | + perror "couldn't run to breakpoint MAIN__" | |
34903 | + continue | |
34904 | +} | |
34905 | + | |
34906 | +gdb_breakpoint [gdb_get_line_number "stop-here-out"] | |
34907 | +gdb_continue_to_breakpoint "stop-here-out" | |
34908 | + | |
34909 | +# Common block naming with source name /foo/: | |
34910 | +# .symtab DW_TAG_common_block's DW_AT_name | |
34911 | +# Intel Fortran foo_ foo_ | |
34912 | +# GNU Fortran foo_ foo | |
34913 | +#set suffix "_" | |
34914 | +set suffix "" | |
34915 | + | |
34916 | +set int4 {(integer\(kind=4\)|INTEGER\(4\))} | |
34917 | +set real4 {(real\(kind=4\)|REAL\(4\))} | |
34918 | +set real8 {(real\(kind=8\)|REAL\(8\))} | |
34919 | + | |
34920 | +gdb_test "whatis foo$suffix" "No symbol \"foo$suffix\" in current context." | |
34921 | +gdb_test "ptype foo$suffix" "No symbol \"foo$suffix\" in current context." | |
34922 | +gdb_test "p foo$suffix" "No symbol \"foo$suffix\" in current context." | |
34923 | +gdb_test "whatis fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." | |
34924 | +gdb_test "ptype fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." | |
34925 | +gdb_test "p fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." | |
34926 | + | |
34927 | +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" | |
34928 | +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" | |
34929 | + | |
34930 | +gdb_test "ptype ix" "type = $int4" "ptype ix out" | |
34931 | +gdb_test "ptype iy" "type = $real4" "ptype iy out" | |
34932 | +gdb_test "ptype iz" "type = $real8" "ptype iz out" | |
34933 | +gdb_test "ptype ix_x" "type = $int4" "ptype ix_x out" | |
34934 | +gdb_test "ptype iy_y" "type = $real4" "ptype iy_y out" | |
34935 | +gdb_test "ptype iz_z" "type = $real8" "ptype iz_z out" | |
34936 | + | |
34937 | +gdb_test "p ix" " = 1 *" "p ix out" | |
34938 | +gdb_test "p iy" " = 2 *" "p iy out" | |
34939 | +gdb_test "p iz" " = 3 *" "p iz out" | |
34940 | +gdb_test "p ix_x" " = 11 *" "p ix_x out" | |
34941 | +gdb_test "p iy_y" " = 22 *" "p iy_y out" | |
34942 | +gdb_test "p iz_z" " = 33 *" "p iz_z out" | |
34943 | + | |
34944 | +gdb_breakpoint [gdb_get_line_number "stop-here-in"] | |
34945 | +gdb_continue_to_breakpoint "stop-here-in" | |
34946 | + | |
34947 | +gdb_test "whatis foo$suffix" "No symbol \"foo$suffix\" in current context." "whatis foo$suffix in" | |
34948 | +gdb_test "ptype foo$suffix" "No symbol \"foo$suffix\" in current context." "ptype foo$suffix in" | |
34949 | +gdb_test "p foo$suffix" "No symbol \"foo$suffix\" in current context." "p foo$suffix in" | |
34950 | +gdb_test "whatis fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." "whatis fo_o$suffix in" | |
34951 | +gdb_test "ptype fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." "ptype fo_o$suffix in" | |
34952 | +gdb_test "p fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." "p fo_o$suffix in" | |
34953 | + | |
34954 | +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" | |
34955 | +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" | |
34956 | + | |
34957 | +gdb_test "ptype ix" "type = $int4" "ptype ix in" | |
34958 | +gdb_test "ptype iy2" "type = $real4" "ptype iy2 in" | |
34959 | +gdb_test "ptype iz" "type = $real8" "ptype iz in" | |
34960 | +gdb_test "ptype ix_x" "type = $int4" "ptype ix_x in" | |
34961 | +gdb_test "ptype iy_y" "type = $real4" "ptype iy_y in" | |
34962 | +gdb_test "ptype iz_z2" "type = $real8" "ptype iz_z2 in" | |
34963 | + | |
34964 | +gdb_test "p ix" " = 11 *" "p ix in" | |
34965 | +gdb_test "p iy2" " = 22 *" "p iy2 in" | |
34966 | +gdb_test "p iz" " = 33 *" "p iz in" | |
34967 | +gdb_test "p ix_x" " = 1 *" "p ix_x in" | |
34968 | +gdb_test "p iy_y" " = 2 *" "p iy_y in" | |
34969 | +gdb_test "p iz_z2" " = 3 *" "p iz_z2 in" | |
34970 | diff --git a/gdb/testsuite/gdb.fortran/common-block.f90 b/gdb/testsuite/gdb.fortran/common-block.f90 | |
34971 | new file mode 100644 | |
34972 | index 0000000..b614e8a | |
34973 | --- /dev/null | |
34974 | +++ b/gdb/testsuite/gdb.fortran/common-block.f90 | |
34975 | @@ -0,0 +1,67 @@ | |
34976 | +! Copyright 2008 Free Software Foundation, Inc. | |
34977 | +! | |
34978 | +! This program is free software; you can redistribute it and/or modify | |
34979 | +! it under the terms of the GNU General Public License as published by | |
34980 | +! the Free Software Foundation; either version 2 of the License, or | |
34981 | +! (at your option) any later version. | |
34982 | +! | |
34983 | +! This program is distributed in the hope that it will be useful, | |
34984 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34985 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
34986 | +! GNU General Public License for more details. | |
34987 | +! | |
34988 | +! You should have received a copy of the GNU General Public License | |
34989 | +! along with this program; if not, write to the Free Software | |
34990 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
34991 | +! | |
34992 | +! Ihis file is the Fortran source file for dynamic.exp. | |
34993 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
34994 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
34995 | + | |
34996 | +subroutine in | |
34997 | + | |
34998 | + INTEGER*4 ix | |
34999 | + REAL*4 iy2 | |
35000 | + REAL*8 iz | |
35001 | + | |
35002 | + INTEGER*4 ix_x | |
35003 | + REAL*4 iy_y | |
35004 | + REAL*8 iz_z2 | |
35005 | + | |
35006 | + common /fo_o/ix,iy2,iz | |
35007 | + common /foo/ix_x,iy_y,iz_z2 | |
35008 | + | |
35009 | + iy = 5 | |
35010 | + iz_z = 55 | |
35011 | + | |
35012 | + if (ix .ne. 11 .or. iy2 .ne. 22.0 .or. iz .ne. 33.0) call abort | |
35013 | + if (ix_x .ne. 1 .or. iy_y .ne. 2.0 .or. iz_z2 .ne. 3.0) call abort | |
35014 | + | |
35015 | + ix = 0 ! stop-here-in | |
35016 | + | |
35017 | +end subroutine in | |
35018 | + | |
35019 | +program common_test | |
35020 | + | |
35021 | + INTEGER*4 ix | |
35022 | + REAL*4 iy | |
35023 | + REAL*8 iz | |
35024 | + | |
35025 | + INTEGER*4 ix_x | |
35026 | + REAL*4 iy_y | |
35027 | + REAL*8 iz_z | |
35028 | + | |
35029 | + common /foo/ix,iy,iz | |
35030 | + common /fo_o/ix_x,iy_y,iz_z | |
35031 | + | |
35032 | + ix = 1 | |
35033 | + iy = 2.0 | |
35034 | + iz = 3.0 | |
35035 | + | |
35036 | + ix_x = 11 | |
35037 | + iy_y = 22.0 | |
35038 | + iz_z = 33.0 | |
35039 | + | |
35040 | + call in ! stop-here-out | |
35041 | + | |
35042 | +end program common_test | |
35043 | diff --git a/gdb/testsuite/gdb.fortran/dynamic.exp b/gdb/testsuite/gdb.fortran/dynamic.exp | |
35044 | new file mode 100644 | |
35045 | index 0000000..77a1203 | |
35046 | --- /dev/null | |
35047 | +++ b/gdb/testsuite/gdb.fortran/dynamic.exp | |
35048 | @@ -0,0 +1,156 @@ | |
35049 | +# Copyright 2007 Free Software Foundation, Inc. | |
35050 | + | |
35051 | +# This program is free software; you can redistribute it and/or modify | |
35052 | +# it under the terms of the GNU General Public License as published by | |
35053 | +# the Free Software Foundation; either version 2 of the License, or | |
35054 | +# (at your option) any later version. | |
35055 | +# | |
35056 | +# This program is distributed in the hope that it will be useful, | |
35057 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35058 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35059 | +# GNU General Public License for more details. | |
35060 | +# | |
35061 | +# You should have received a copy of the GNU General Public License | |
35062 | +# along with this program; if not, write to the Free Software | |
35063 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
35064 | + | |
35065 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
35066 | + | |
35067 | +# This file is part of the gdb testsuite. It contains tests for dynamically | |
35068 | +# allocated Fortran arrays. | |
35069 | +# It depends on the GCC dynamic Fortran arrays DWARF support: | |
35070 | +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22244 | |
35071 | + | |
35072 | +set testfile "dynamic" | |
35073 | +set srcfile ${testfile}.f90 | |
35074 | +set binfile ${objdir}/${subdir}/${testfile} | |
35075 | + | |
35076 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } { | |
35077 | + untested "Couldn't compile ${srcfile}" | |
35078 | + return -1 | |
35079 | +} | |
35080 | + | |
35081 | +gdb_exit | |
35082 | +gdb_start | |
35083 | +gdb_reinitialize_dir $srcdir/$subdir | |
35084 | +gdb_load ${binfile} | |
35085 | + | |
35086 | +if ![runto MAIN__] then { | |
35087 | + perror "couldn't run to breakpoint MAIN__" | |
35088 | + continue | |
35089 | +} | |
35090 | + | |
35091 | +gdb_breakpoint [gdb_get_line_number "varx-init"] | |
35092 | +gdb_continue_to_breakpoint "varx-init" | |
35093 | +gdb_test "p varx" "\\$\[0-9\]* = <(object|the array) is not allocated>" "p varx unallocated" | |
35094 | +gdb_test "ptype varx" "type = <(object|the array) is not allocated>" "ptype varx unallocated" | |
35095 | +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" | |
35096 | +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" | |
35097 | +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" | |
35098 | + | |
35099 | +gdb_breakpoint [gdb_get_line_number "varx-allocated"] | |
35100 | +gdb_continue_to_breakpoint "varx-allocated" | |
35101 | +# $1 = (( ( 0, 0, 0, 0, 0, 0) ( 0, 0, 0, 0, 0, 0) --- , 0) ) ( ( 0, 0, ...) ...) ...) | |
35102 | +gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)" "ptype varx allocated" | |
35103 | +# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1. | |
35104 | +gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varx allocated" | |
35105 | + | |
35106 | +gdb_breakpoint [gdb_get_line_number "varx-filled"] | |
35107 | +gdb_continue_to_breakpoint "varx-filled" | |
35108 | +gdb_test "p varx(2, 5, 17)" "\\$\[0-9\]* = 6" | |
35109 | +gdb_test "p varx(1, 5, 17)" "\\$\[0-9\]* = 7" | |
35110 | +gdb_test "p varx(2, 6, 18)" "\\$\[0-9\]* = 8" | |
35111 | +gdb_test "p varx(6, 15, 28)" "\\$\[0-9\]* = 9" | |
35112 | +# The latter one is for the Intel Fortran Compiler 10.1.008 pointer type. | |
35113 | +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" | |
35114 | +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" | |
35115 | + | |
35116 | +gdb_breakpoint [gdb_get_line_number "varv-associated"] | |
35117 | +gdb_continue_to_breakpoint "varv-associated" | |
35118 | +gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 6" "p varx(3, 7, 19) with varv associated" | |
35119 | +gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 6" "p varv(3, 7, 19) associated" | |
35120 | +# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1. | |
35121 | +gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varv associated" | |
35122 | +gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)" "ptype varx with varv associated" | |
35123 | +# Intel Fortran Compiler 10.1.008 uses the pointer type. | |
35124 | +gdb_test "ptype varv" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)\\)?" "ptype varv associated" | |
35125 | + | |
35126 | +gdb_breakpoint [gdb_get_line_number "varv-filled"] | |
35127 | +gdb_continue_to_breakpoint "varv-filled" | |
35128 | +gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 10" "p varx(3, 7, 19) with varv filled" | |
35129 | +gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 10" "p varv(3, 7, 19) filled" | |
35130 | + | |
35131 | +gdb_breakpoint [gdb_get_line_number "varv-deassociated"] | |
35132 | +gdb_continue_to_breakpoint "varv-deassociated" | |
35133 | +# The latter one is for the Intel Fortran Compiler 10.1.008 pointer type. | |
35134 | +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" | |
35135 | +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" | |
35136 | +gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varv deassociated" | |
35137 | +gdb_test "p varv(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not associated\\." | |
35138 | +gdb_test "ptype varv(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not associated\\." | |
35139 | + | |
35140 | +gdb_breakpoint [gdb_get_line_number "varx-deallocated"] | |
35141 | +gdb_continue_to_breakpoint "varx-deallocated" | |
35142 | +gdb_test "p varx" "\\$\[0-9\]* = <(object|the array) is not allocated>" "p varx deallocated" | |
35143 | +gdb_test "ptype varx" "type = <(object|the array) is not allocated>" "ptype varx deallocated" | |
35144 | +gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varx deallocated" | |
35145 | +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" | |
35146 | +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" | |
35147 | + | |
35148 | +gdb_breakpoint [gdb_get_line_number "vary-passed"] | |
35149 | +gdb_continue_to_breakpoint "vary-passed" | |
35150 | +# $1 = (( ( 1, 1, 1, 1, 1, 1) ( 1, 1, 1, 1, 1, 1) --- , 1) ) ( ( 1, 1, ...) ...) ...) | |
35151 | +gdb_test "p vary" "\\$\[0-9\]* = \\(\[()1, .\]*\\)" | |
35152 | + | |
35153 | +gdb_breakpoint [gdb_get_line_number "vary-filled"] | |
35154 | +gdb_continue_to_breakpoint "vary-filled" | |
35155 | +gdb_test "ptype vary" "type = real(\\(kind=4\\)|\\*4) \\(10,10\\)" | |
35156 | +gdb_test "p vary(1, 1)" "\\$\[0-9\]* = 8" | |
35157 | +gdb_test "p vary(2, 2)" "\\$\[0-9\]* = 9" | |
35158 | +gdb_test "p vary(1, 3)" "\\$\[0-9\]* = 10" | |
35159 | +# $1 = (( ( 3, 3, 3, 3, 3, 3) ( 3, 3, 3, 3, 3, 3) --- , 3) ) ( ( 3, 3, ...) ...) ...) | |
35160 | +gdb_test "p varw" "\\$\[0-9\]* = \\(\[()3, .\]*\\)" | |
35161 | + | |
35162 | +gdb_breakpoint [gdb_get_line_number "varw-almostfilled"] | |
35163 | +gdb_continue_to_breakpoint "varw-almostfilled" | |
35164 | +gdb_test "ptype varw" "type = real(\\(kind=4\\)|\\*4) \\(5,4,3\\)" | |
35165 | +gdb_test "p varw(3,1,1)=1" "\\$\[0-9\]* = 1" | |
35166 | +# $1 = (( ( 6, 5, 1, 5, 5, 5) ( 5, 5, 5, 5, 5, 5) --- , 5) ) ( ( 5, 5, ...) ...) ...) | |
35167 | +gdb_test "p varw" "\\$\[0-9\]* = \\( *\\( *\\( *6, *5, *1,\[()5, .\]*\\)" "p varw filled" | |
35168 | +# "up" works with GCC but other Fortran compilers may copy the values into the | |
35169 | +# outer function only on the exit of the inner function. | |
35170 | +gdb_test "finish" ".*call bar \\(y, x\\)" | |
35171 | +gdb_test "p z(2,4,5)" "\\$\[0-9\]* = 3" | |
35172 | +gdb_test "p z(2,4,6)" "\\$\[0-9\]* = 6" | |
35173 | +gdb_test "p z(2,4,7)" "\\$\[0-9\]* = 5" | |
35174 | +gdb_test "p z(4,4,6)" "\\$\[0-9\]* = 1" | |
35175 | + | |
35176 | +gdb_breakpoint [gdb_get_line_number "varz-almostfilled"] | |
35177 | +gdb_continue_to_breakpoint "varz-almostfilled" | |
35178 | +# GCC uses the pointer type here, Intel Fortran Compiler 10.1.008 does not. | |
35179 | +gdb_test "ptype varz" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(\\*\\)\\)?" | |
35180 | +# Intel Fortran Compiler 10.1.008 has a bug here - (2:11,7:7) | |
35181 | +# as it produces DW_AT_lower_bound == DW_AT_upper_bound == 7. | |
35182 | +gdb_test "ptype vart" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(2:11,7:\\*\\)\\)?" | |
35183 | +gdb_test "p varz" "\\$\[0-9\]* = \\(\\)" | |
35184 | +gdb_test "p vart" "\\$\[0-9\]* = \\(\\)" | |
35185 | +gdb_test "p varz(3)" "\\$\[0-9\]* = 4" | |
35186 | +# maps to foo::vary(1,1) | |
35187 | +gdb_test "p vart(2,7)" "\\$\[0-9\]* = 8" | |
35188 | +# maps to foo::vary(2,2) | |
35189 | +gdb_test "p vart(3,8)" "\\$\[0-9\]* = 9" | |
35190 | +# maps to foo::vary(1,3) | |
35191 | +gdb_test "p vart(2,9)" "\\$\[0-9\]* = 10" | |
35192 | + | |
35193 | +set test "quit #1" | |
35194 | +gdb_test_multiple "quit" $test { | |
35195 | + -re "The program is running. Quit anyway \\(and kill it\\)\\? \\(y or n\\) " { | |
35196 | + pass $test | |
35197 | + } | |
35198 | +} | |
35199 | +set test "quit #2" | |
35200 | +gdb_test_multiple "y" $test { | |
35201 | + eof { | |
35202 | + pass $test | |
35203 | + } | |
35204 | +} | |
35205 | diff --git a/gdb/testsuite/gdb.fortran/dynamic.f90 b/gdb/testsuite/gdb.fortran/dynamic.f90 | |
35206 | new file mode 100644 | |
35207 | index 0000000..0f43564 | |
35208 | --- /dev/null | |
35209 | +++ b/gdb/testsuite/gdb.fortran/dynamic.f90 | |
35210 | @@ -0,0 +1,98 @@ | |
35211 | +! Copyright 2007 Free Software Foundation, Inc. | |
35212 | +! | |
35213 | +! This program is free software; you can redistribute it and/or modify | |
35214 | +! it under the terms of the GNU General Public License as published by | |
35215 | +! the Free Software Foundation; either version 2 of the License, or | |
35216 | +! (at your option) any later version. | |
35217 | +! | |
35218 | +! This program is distributed in the hope that it will be useful, | |
35219 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35220 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35221 | +! GNU General Public License for more details. | |
35222 | +! | |
35223 | +! You should have received a copy of the GNU General Public License | |
35224 | +! along with this program; if not, write to the Free Software | |
35225 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
35226 | +! | |
35227 | +! Ihis file is the Fortran source file for dynamic.exp. | |
35228 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
35229 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
35230 | + | |
35231 | +subroutine baz | |
35232 | + real, target, allocatable :: varx (:, :, :) | |
35233 | + real, pointer :: varv (:, :, :) | |
35234 | + real, target :: varu (1, 2, 3) | |
35235 | + logical :: l | |
35236 | + allocate (varx (1:6, 5:15, 17:28)) ! varx-init | |
35237 | + l = allocated (varx) | |
35238 | + varx(:, :, :) = 6 ! varx-allocated | |
35239 | + varx(1, 5, 17) = 7 | |
35240 | + varx(2, 6, 18) = 8 | |
35241 | + varx(6, 15, 28) = 9 | |
35242 | + varv => varx ! varx-filled | |
35243 | + l = associated (varv) | |
35244 | + varv(3, 7, 19) = 10 ! varv-associated | |
35245 | + varv => null () ! varv-filled | |
35246 | + l = associated (varv) | |
35247 | + deallocate (varx) ! varv-deassociated | |
35248 | + l = allocated (varx) | |
35249 | + varu(:, :, :) = 10 ! varx-deallocated | |
35250 | + allocate (varv (1:6, 5:15, 17:28)) | |
35251 | + l = associated (varv) | |
35252 | + varv(:, :, :) = 6 | |
35253 | + varv(1, 5, 17) = 7 | |
35254 | + varv(2, 6, 18) = 8 | |
35255 | + varv(6, 15, 28) = 9 | |
35256 | + deallocate (varv) | |
35257 | + l = associated (varv) | |
35258 | + varv => varu | |
35259 | + varv(1, 1, 1) = 6 | |
35260 | + varv(1, 2, 3) = 7 | |
35261 | + l = associated (varv) | |
35262 | +end subroutine baz | |
35263 | +subroutine foo (vary, varw) | |
35264 | + real :: vary (:, :) | |
35265 | + real :: varw (:, :, :) | |
35266 | + vary(:, :) = 4 ! vary-passed | |
35267 | + vary(1, 1) = 8 | |
35268 | + vary(2, 2) = 9 | |
35269 | + vary(1, 3) = 10 | |
35270 | + varw(:, :, :) = 5 ! vary-filled | |
35271 | + varw(1, 1, 1) = 6 | |
35272 | + varw(2, 2, 2) = 7 ! varw-almostfilled | |
35273 | +end subroutine foo | |
35274 | +subroutine bar (varz, vart) | |
35275 | + real :: varz (*) | |
35276 | + real :: vart (2:11, 7:*) | |
35277 | + varz(1:3) = 4 | |
35278 | + varz(2) = 5 ! varz-almostfilled | |
35279 | + vart(2,7) = vart(2,7) | |
35280 | +end subroutine bar | |
35281 | +program test | |
35282 | + interface | |
35283 | + subroutine foo (vary, varw) | |
35284 | + real :: vary (:, :) | |
35285 | + real :: varw (:, :, :) | |
35286 | + end subroutine | |
35287 | + end interface | |
35288 | + interface | |
35289 | + subroutine bar (varz, vart) | |
35290 | + real :: varz (*) | |
35291 | + real :: vart (2:11, 7:*) | |
35292 | + end subroutine | |
35293 | + end interface | |
35294 | + real :: x (10, 10), y (5), z(8, 8, 8) | |
35295 | + x(:,:) = 1 | |
35296 | + y(:) = 2 | |
35297 | + z(:,:,:) = 3 | |
35298 | + call baz | |
35299 | + call foo (x, z(2:6, 4:7, 6:8)) | |
35300 | + call bar (y, x) | |
35301 | + if (x (1, 1) .ne. 8 .or. x (2, 2) .ne. 9 .or. x (1, 2) .ne. 4) call abort | |
35302 | + if (x (1, 3) .ne. 10) call abort | |
35303 | + if (z (2, 4, 6) .ne. 6 .or. z (3, 5, 7) .ne. 7 .or. z (2, 4, 7) .ne. 5) call abort | |
35304 | + if (any (y .ne. (/4, 5, 4, 2, 2/))) call abort | |
35305 | + call foo (transpose (x), z) | |
35306 | + if (x (1, 1) .ne. 8 .or. x (2, 2) .ne. 9 .or. x (1, 2) .ne. 4) call abort | |
35307 | + if (x (3, 1) .ne. 10) call abort | |
35308 | +end | |
35309 | diff --git a/gdb/testsuite/gdb.fortran/logical.exp b/gdb/testsuite/gdb.fortran/logical.exp | |
35310 | new file mode 100644 | |
35311 | index 0000000..ef76f43 | |
35312 | --- /dev/null | |
35313 | +++ b/gdb/testsuite/gdb.fortran/logical.exp | |
35314 | @@ -0,0 +1,44 @@ | |
35315 | +# Copyright 2007 Free Software Foundation, Inc. | |
35316 | + | |
35317 | +# This program is free software; you can redistribute it and/or modify | |
35318 | +# it under the terms of the GNU General Public License as published by | |
35319 | +# the Free Software Foundation; either version 2 of the License, or | |
35320 | +# (at your option) any later version. | |
35321 | +# | |
35322 | +# This program is distributed in the hope that it will be useful, | |
35323 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35324 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35325 | +# GNU General Public License for more details. | |
35326 | +# | |
35327 | +# You should have received a copy of the GNU General Public License | |
35328 | +# along with this program; if not, write to the Free Software | |
35329 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
35330 | + | |
35331 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
35332 | + | |
35333 | +set testfile "logical" | |
35334 | +set srcfile ${testfile}.f90 | |
35335 | +set binfile ${objdir}/${subdir}/${testfile} | |
35336 | + | |
35337 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } { | |
35338 | + untested "Couldn't compile ${srcfile}" | |
35339 | + return -1 | |
35340 | +} | |
35341 | + | |
35342 | +gdb_exit | |
35343 | +gdb_start | |
35344 | +gdb_reinitialize_dir $srcdir/$subdir | |
35345 | +gdb_load ${binfile} | |
35346 | + | |
35347 | +if ![runto MAIN__] then { | |
35348 | + perror "couldn't run to breakpoint MAIN__" | |
35349 | + continue | |
35350 | +} | |
35351 | + | |
35352 | +gdb_breakpoint [gdb_get_line_number "stop-here"] | |
35353 | +gdb_continue_to_breakpoint "stop-here" | |
35354 | +gdb_test "p l" " = \\.TRUE\\." | |
35355 | +gdb_test "p l1" " = \\.TRUE\\." | |
35356 | +gdb_test "p l2" " = \\.TRUE\\." | |
35357 | +gdb_test "p l4" " = \\.TRUE\\." | |
35358 | +gdb_test "p l8" " = \\.TRUE\\." | |
35359 | diff --git a/gdb/testsuite/gdb.fortran/logical.f90 b/gdb/testsuite/gdb.fortran/logical.f90 | |
35360 | new file mode 100644 | |
35361 | index 0000000..4229304 | |
35362 | --- /dev/null | |
35363 | +++ b/gdb/testsuite/gdb.fortran/logical.f90 | |
35364 | @@ -0,0 +1,33 @@ | |
35365 | +! Copyright 2008 Free Software Foundation, Inc. | |
35366 | +! | |
35367 | +! This program is free software; you can redistribute it and/or modify | |
35368 | +! it under the terms of the GNU General Public License as published by | |
35369 | +! the Free Software Foundation; either version 2 of the License, or | |
35370 | +! (at your option) any later version. | |
35371 | +! | |
35372 | +! This program is distributed in the hope that it will be useful, | |
35373 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35374 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35375 | +! GNU General Public License for more details. | |
35376 | +! | |
35377 | +! You should have received a copy of the GNU General Public License | |
35378 | +! along with this program; if not, write to the Free Software | |
35379 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
35380 | +! | |
35381 | +! Ihis file is the Fortran source file for dynamic.exp. | |
35382 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
35383 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
35384 | + | |
35385 | +program test | |
35386 | + logical :: l | |
35387 | + logical (kind=1) :: l1 | |
35388 | + logical (kind=2) :: l2 | |
35389 | + logical (kind=4) :: l4 | |
35390 | + logical (kind=8) :: l8 | |
35391 | + l = .TRUE. | |
35392 | + l1 = .TRUE. | |
35393 | + l2 = .TRUE. | |
35394 | + l4 = .TRUE. | |
35395 | + l8 = .TRUE. | |
35396 | + l = .FALSE. ! stop-here | |
35397 | +end | |
35398 | diff --git a/gdb/testsuite/gdb.fortran/string.exp b/gdb/testsuite/gdb.fortran/string.exp | |
35399 | new file mode 100644 | |
35400 | index 0000000..ab72206 | |
35401 | --- /dev/null | |
35402 | +++ b/gdb/testsuite/gdb.fortran/string.exp | |
35403 | @@ -0,0 +1,72 @@ | |
35404 | +# Copyright 2008 Free Software Foundation, Inc. | |
35405 | + | |
35406 | +# This program is free software; you can redistribute it and/or modify | |
35407 | +# it under the terms of the GNU General Public License as published by | |
35408 | +# the Free Software Foundation; either version 2 of the License, or | |
35409 | +# (at your option) any later version. | |
35410 | +# | |
35411 | +# This program is distributed in the hope that it will be useful, | |
35412 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35413 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35414 | +# GNU General Public License for more details. | |
35415 | +# | |
35416 | +# You should have received a copy of the GNU General Public License | |
35417 | +# along with this program; if not, write to the Free Software | |
35418 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
35419 | + | |
35420 | +# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
35421 | + | |
35422 | +# This file is part of the gdb testsuite. It contains tests for Fortran | |
35423 | +# strings with dynamic length. | |
35424 | + | |
35425 | +set testfile "string" | |
35426 | +set srcfile ${testfile}.f90 | |
35427 | +set binfile ${objdir}/${subdir}/${testfile} | |
35428 | + | |
35429 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } { | |
35430 | + untested "Couldn't compile ${srcfile}" | |
35431 | + return -1 | |
35432 | +} | |
35433 | + | |
35434 | +gdb_exit | |
35435 | +gdb_start | |
35436 | +gdb_reinitialize_dir $srcdir/$subdir | |
35437 | +gdb_load ${binfile} | |
35438 | + | |
35439 | +if ![runto MAIN__] then { | |
35440 | + perror "couldn't run to breakpoint MAIN__" | |
35441 | + continue | |
35442 | +} | |
35443 | + | |
35444 | +gdb_breakpoint [gdb_get_line_number "var-init"] | |
35445 | +gdb_continue_to_breakpoint "var-init" | |
35446 | +gdb_test "ptype c" "type = character(\\(kind=1\\)|\\*1)" | |
35447 | +gdb_test "ptype d" "type = character(\\(kind=8\\)|\\*8)" | |
35448 | +gdb_test "ptype e" "type = character(\\(kind=4\\)|\\*4)" | |
35449 | +gdb_test "ptype f" "type = character(\\(kind=4\\)|\\*4) \\(7,8:10\\)" | |
35450 | +gdb_test "ptype *e" "Attempt to take contents of a non-pointer value." | |
35451 | +gdb_test "ptype *f" "type = character(\\(kind=4\\)|\\*4) \\(7\\)" | |
35452 | +gdb_test "p c" "\\$\[0-9\]* = 'c'" | |
35453 | +gdb_test "p d" "\\$\[0-9\]* = 'd '" | |
35454 | +gdb_test "p e" "\\$\[0-9\]* = 'g '" | |
35455 | +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 '\\) \\)" | |
35456 | +gdb_test "p *e" "Attempt to take contents of a non-pointer value." | |
35457 | +gdb_test "p *f" "Attempt to take contents of a non-pointer value." | |
35458 | + | |
35459 | +gdb_breakpoint [gdb_get_line_number "var-finish"] | |
35460 | +gdb_continue_to_breakpoint "var-finish" | |
35461 | +gdb_test "p e" "\\$\[0-9\]* = 'e '" "p e re-set" | |
35462 | +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" | |
35463 | + | |
35464 | +set test "quit #1" | |
35465 | +gdb_test_multiple "quit" $test { | |
35466 | + -re "The program is running. Quit anyway \\(and kill it\\)\\? \\(y or n\\) " { | |
35467 | + pass $test | |
35468 | + } | |
35469 | +} | |
35470 | +set test "quit #2" | |
35471 | +gdb_test_multiple "y" $test { | |
35472 | + eof { | |
35473 | + pass $test | |
35474 | + } | |
35475 | +} | |
35476 | diff --git a/gdb/testsuite/gdb.fortran/string.f90 b/gdb/testsuite/gdb.fortran/string.f90 | |
35477 | new file mode 100644 | |
35478 | index 0000000..226dc5d | |
35479 | --- /dev/null | |
35480 | +++ b/gdb/testsuite/gdb.fortran/string.f90 | |
35481 | @@ -0,0 +1,37 @@ | |
35482 | +! Copyright 2008 Free Software Foundation, Inc. | |
35483 | +! | |
35484 | +! This program is free software; you can redistribute it and/or modify | |
35485 | +! it under the terms of the GNU General Public License as published by | |
35486 | +! the Free Software Foundation; either version 2 of the License, or | |
35487 | +! (at your option) any later version. | |
35488 | +! | |
35489 | +! This program is distributed in the hope that it will be useful, | |
35490 | +! but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35491 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35492 | +! GNU General Public License for more details. | |
35493 | +! | |
35494 | +! You should have received a copy of the GNU General Public License | |
35495 | +! along with this program; if not, write to the Free Software | |
35496 | +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
35497 | +! | |
35498 | +! Ihis file is the Fortran source file for dynamic.exp. | |
35499 | +! Original file written by Jakub Jelinek <jakub@redhat.com>. | |
35500 | +! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>. | |
35501 | + | |
35502 | +subroutine foo (e, f) | |
35503 | + character (len=1) :: c | |
35504 | + character (len=8) :: d | |
35505 | + character (len=*) :: e | |
35506 | + character (len=*) :: f (1:7, 8:10) | |
35507 | + c = 'c' | |
35508 | + d = 'd' | |
35509 | + e = 'e' ! var-init | |
35510 | + f = 'f' | |
35511 | + f(1,9) = 'f2' | |
35512 | + c = 'c' ! var-finish | |
35513 | +end subroutine foo | |
35514 | + character (len=4) :: g, h (1:7, 8:10) | |
35515 | + g = 'g' | |
35516 | + h = 'h' | |
35517 | + call foo (g, h) | |
35518 | +end | |
35519 | diff --git a/gdb/testsuite/gdb.gdb/selftest.exp b/gdb/testsuite/gdb.gdb/selftest.exp | |
35520 | index 495ae45..d08d7a4 100644 | |
35521 | --- a/gdb/testsuite/gdb.gdb/selftest.exp | |
35522 | +++ b/gdb/testsuite/gdb.gdb/selftest.exp | |
35523 | @@ -95,6 +95,10 @@ proc do_steps_and_nexts {} { | |
35524 | set description "step over ttyarg initialization" | |
35525 | set command "step" | |
35526 | } | |
35527 | + -re ".*python_script = 0.*$gdb_prompt $" { | |
35528 | + set description "step over python_script initialization" | |
35529 | + set command "step" | |
35530 | + } | |
35531 | -re ".*time_at_startup = get_run_time.*$gdb_prompt $" { | |
35532 | set description "next over get_run_time and everything it calls" | |
35533 | set command "next" | |
35534 | diff --git a/gdb/testsuite/gdb.opt/array-from-register-func.c b/gdb/testsuite/gdb.opt/array-from-register-func.c | |
35535 | new file mode 100644 | |
35536 | index 0000000..729f457 | |
35537 | --- /dev/null | |
35538 | +++ b/gdb/testsuite/gdb.opt/array-from-register-func.c | |
35539 | @@ -0,0 +1,22 @@ | |
35540 | +/* This file is part of GDB, the GNU debugger. | |
35541 | + | |
35542 | + Copyright 2009 Free Software Foundation, Inc. | |
35543 | + | |
35544 | + This program is free software; you can redistribute it and/or modify | |
35545 | + it under the terms of the GNU General Public License as published by | |
35546 | + the Free Software Foundation; either version 3 of the License, or | |
35547 | + (at your option) any later version. | |
35548 | + | |
35549 | + This program is distributed in the hope that it will be useful, | |
35550 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35551 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35552 | + GNU General Public License for more details. | |
35553 | + | |
35554 | + You should have received a copy of the GNU General Public License | |
35555 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
35556 | + | |
35557 | +int | |
35558 | +func (int *arr) | |
35559 | +{ | |
35560 | + return arr[0]; | |
35561 | +} | |
35562 | diff --git a/gdb/testsuite/gdb.opt/array-from-register.c b/gdb/testsuite/gdb.opt/array-from-register.c | |
35563 | new file mode 100644 | |
35564 | index 0000000..3090e7e | |
35565 | --- /dev/null | |
35566 | +++ b/gdb/testsuite/gdb.opt/array-from-register.c | |
35567 | @@ -0,0 +1,28 @@ | |
35568 | +/* This file is part of GDB, the GNU debugger. | |
35569 | + | |
35570 | + Copyright 2009 Free Software Foundation, Inc. | |
35571 | + | |
35572 | + This program is free software; you can redistribute it and/or modify | |
35573 | + it under the terms of the GNU General Public License as published by | |
35574 | + the Free Software Foundation; either version 3 of the License, or | |
35575 | + (at your option) any later version. | |
35576 | + | |
35577 | + This program is distributed in the hope that it will be useful, | |
35578 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35579 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35580 | + GNU General Public License for more details. | |
35581 | + | |
35582 | + You should have received a copy of the GNU General Public License | |
35583 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
35584 | + | |
35585 | +extern int func (int *arr); | |
35586 | + | |
35587 | +int | |
35588 | +main (void) | |
35589 | +{ | |
35590 | + int arr[] = { 42 }; | |
35591 | + | |
35592 | + func (arr); | |
35593 | + | |
35594 | + return 0; | |
35595 | +} | |
35596 | diff --git a/gdb/testsuite/gdb.opt/array-from-register.exp b/gdb/testsuite/gdb.opt/array-from-register.exp | |
35597 | new file mode 100644 | |
35598 | index 0000000..f2de718 | |
35599 | --- /dev/null | |
35600 | +++ b/gdb/testsuite/gdb.opt/array-from-register.exp | |
35601 | @@ -0,0 +1,33 @@ | |
35602 | +# Copyright 2009 Free Software Foundation, Inc. | |
35603 | +# | |
35604 | +# This program is free software; you can redistribute it and/or modify | |
35605 | +# it under the terms of the GNU General Public License as published by | |
35606 | +# the Free Software Foundation; either version 2 of the License, or | |
35607 | +# (at your option) any later version. | |
35608 | +# | |
35609 | +# This program is distributed in the hope that it will be useful, | |
35610 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35611 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35612 | +# GNU General Public License for more details. | |
35613 | +# | |
35614 | +# You should have received a copy of the GNU General Public License | |
35615 | +# along with this program; if not, write to the Free Software | |
35616 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
35617 | +# | |
35618 | +# This file is part of the gdb testsuite. | |
35619 | + | |
35620 | +if { [prepare_for_testing array-from-register.exp "array-from-register" \ | |
35621 | + {array-from-register.c array-from-register-func.c} \ | |
35622 | + {debug optimize=-O2}] } { | |
35623 | + return -1 | |
35624 | +} | |
35625 | + | |
35626 | +if ![runto func] then { | |
35627 | + return -1 | |
35628 | +} | |
35629 | + | |
35630 | +gdb_test "p arr" "\\$\[0-9\]+ = \\(int \\*\\) *0x\[0-9a-f\]+" | |
35631 | + | |
35632 | +# Seen regression: | |
35633 | +# Address requested for identifier "arr" which is in register $rdi | |
35634 | +gdb_test "p arr\[0\]" "\\$\[0-9\]+ = 42" | |
35635 | diff --git a/gdb/testsuite/gdb.python/Makefile.in b/gdb/testsuite/gdb.python/Makefile.in | |
35636 | index 79be9e7..c49f713 100644 | |
35637 | --- a/gdb/testsuite/gdb.python/Makefile.in | |
35638 | +++ b/gdb/testsuite/gdb.python/Makefile.in | |
35639 | @@ -1,7 +1,7 @@ | |
35640 | VPATH = @srcdir@ | |
35641 | srcdir = @srcdir@ | |
35642 | ||
35643 | -EXECUTABLES = python-value | |
35644 | +EXECUTABLES = python-value python-prettyprint python-template | |
35645 | ||
35646 | all info install-info dvi install uninstall installcheck check: | |
35647 | @echo "Nothing to be done for $@..." | |
35648 | diff --git a/gdb/testsuite/gdb.python/find.c b/gdb/testsuite/gdb.python/find.c | |
35649 | new file mode 100644 | |
35650 | index 0000000..35ddd8c | |
35651 | --- /dev/null | |
35652 | +++ b/gdb/testsuite/gdb.python/find.c | |
35653 | @@ -0,0 +1,64 @@ | |
35654 | +/* Testcase for the search_memory Python function. | |
35655 | + This testcase is part of GDB, the GNU debugger. | |
35656 | + | |
35657 | + Copyright 2009 Free Software Foundation, Inc. | |
35658 | + | |
35659 | + This program is free software; you can redistribute it and/or modify | |
35660 | + it under the terms of the GNU General Public License as published by | |
35661 | + the Free Software Foundation; either version 3 of the License, or | |
35662 | + (at your option) any later version. | |
35663 | + | |
35664 | + This program is distributed in the hope that it will be useful, | |
35665 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35666 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35667 | + GNU General Public License for more details. | |
35668 | + | |
35669 | + You should have received a copy of the GNU General Public License | |
35670 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
35671 | + | |
35672 | + Please email any bugs, comments, and/or additions to this file to: | |
35673 | + bug-gdb@gnu.org */ | |
35674 | + | |
35675 | +/* Based on the gdb.base/find.c testcase. */ | |
35676 | + | |
35677 | +#include <stdlib.h> | |
35678 | +#include <stdint.h> | |
35679 | + | |
35680 | +#define CHUNK_SIZE 16000 /* same as findcmd.c's */ | |
35681 | +#define BUF_SIZE (2 * CHUNK_SIZE) /* at least two chunks */ | |
35682 | + | |
35683 | +static int8_t int8_search_buf[100]; | |
35684 | +static int16_t int16_search_buf[100]; | |
35685 | +static int32_t int32_search_buf[100]; | |
35686 | +static int64_t int64_search_buf[100]; | |
35687 | + | |
35688 | +static char *search_buf; | |
35689 | +static int search_buf_size; | |
35690 | + | |
35691 | +static int x; | |
35692 | + | |
35693 | +static void | |
35694 | +stop_here () | |
35695 | +{ | |
35696 | + x = 1; // stop here | |
35697 | +} | |
35698 | + | |
35699 | +static void | |
35700 | +init_bufs () | |
35701 | +{ | |
35702 | + search_buf_size = BUF_SIZE; | |
35703 | + search_buf = malloc (search_buf_size); | |
35704 | + if (search_buf == NULL) | |
35705 | + exit (1); | |
35706 | + memset (search_buf, 'x', search_buf_size); | |
35707 | +} | |
35708 | + | |
35709 | +int | |
35710 | +main () | |
35711 | +{ | |
35712 | + init_bufs (); | |
35713 | + | |
35714 | + stop_here (); | |
35715 | + | |
35716 | + return 0; | |
35717 | +} | |
35718 | diff --git a/gdb/testsuite/gdb.python/find.exp b/gdb/testsuite/gdb.python/find.exp | |
35719 | new file mode 100644 | |
35720 | index 0000000..dd9aabc | |
35721 | --- /dev/null | |
35722 | +++ b/gdb/testsuite/gdb.python/find.exp | |
35723 | @@ -0,0 +1,203 @@ | |
35724 | +# Copyright 2008, 2009 Free Software Foundation, Inc. | |
35725 | + | |
35726 | +# This program is free software; you can redistribute it and/or modify | |
35727 | +# it under the terms of the GNU General Public License as published by | |
35728 | +# the Free Software Foundation; either version 3 of the License, or | |
35729 | +# (at your option) any later version. | |
35730 | +# | |
35731 | +# This program is distributed in the hope that it will be useful, | |
35732 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35733 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
35734 | +# GNU General Public License for more details. | |
35735 | +# | |
35736 | +# You should have received a copy of the GNU General Public License | |
35737 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
35738 | + | |
35739 | +# This tests the search_memory Python function. | |
35740 | +# Based on the gdb.base/find.exp testcase. | |
35741 | + | |
35742 | +if $tracelevel then { | |
35743 | + strace $tracelevel | |
35744 | +} | |
35745 | + | |
35746 | +# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}... | |
35747 | +# Run a test named NAME, consisting of multiple lines of input. | |
35748 | +# After each input line INPUT, search for result line RESULT. | |
35749 | +# Succeed if all results are seen; fail otherwise. | |
35750 | +proc gdb_py_test_multiple {name args} { | |
35751 | + global gdb_prompt | |
35752 | + foreach {input result} $args { | |
35753 | + if {[gdb_test_multiple $input "$name - $input" { | |
35754 | + -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" { | |
35755 | + pass "$name - $input" | |
35756 | + } | |
35757 | + }]} { | |
35758 | + return 1 | |
35759 | + } | |
35760 | + } | |
35761 | + return 0 | |
35762 | +} | |
35763 | + | |
35764 | +set testfile "find" | |
35765 | +set srcfile ${testfile}.c | |
35766 | +set binfile ${objdir}/${subdir}/${testfile} | |
35767 | + | |
35768 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug nowarnings}] != "" } { | |
35769 | + untested find.exp | |
35770 | + return -1 | |
35771 | +} | |
35772 | + | |
35773 | +gdb_exit | |
35774 | +gdb_start | |
35775 | +gdb_reinitialize_dir $srcdir/$subdir | |
35776 | +gdb_load ${binfile} | |
35777 | + | |
35778 | +gdb_test_multiple "python print 'hello, world!'" "verify python support" { | |
35779 | + -re "not supported.*$gdb_prompt $" { | |
35780 | + unsupported "python support is disabled" | |
35781 | + return -1 | |
35782 | + } | |
35783 | + -re "$gdb_prompt $" {} | |
35784 | +} | |
35785 | + | |
35786 | +gdb_test "break $srcfile:stop_here" \ | |
35787 | + "Breakpoint.*at.* file .*$srcfile, line.*" \ | |
35788 | + "breakpoint function in file" | |
35789 | + | |
35790 | +gdb_run_cmd | |
35791 | +gdb_expect { | |
35792 | + -re "Breakpoint \[0-9\]+,.*stop_here.* at .*$srcfile:.*$gdb_prompt $" { | |
35793 | + pass "run until function breakpoint" | |
35794 | + } | |
35795 | + -re "$gdb_prompt $" { | |
35796 | + fail "run until function breakpoint" | |
35797 | + } | |
35798 | + timeout { | |
35799 | + fail "run until function breakpoint (timeout)" | |
35800 | + } | |
35801 | +} | |
35802 | + | |
35803 | +# We've now got the target program in a state where we can test "find". | |
35804 | + | |
35805 | +set hex_number {0x[0-9a-fA-F][0-9a-fA-F]*} | |
35806 | +set dec_number {[0-9]+} | |
35807 | +set history_prefix {[$][0-9]* = } | |
35808 | +set newline {[\r\n]+} | |
35809 | +set pattern_not_found "${newline}.]" | |
35810 | +set one_pattern_found "${newline}.${dec_number}L]" | |
35811 | +set two_patterns_found "${newline}.${dec_number}L, ${dec_number}L]" | |
35812 | + | |
35813 | +# Test string pattern. | |
35814 | + | |
35815 | +gdb_test "set *(int32_t*) &int8_search_buf\[10\] = 0x61616161" "" "" | |
35816 | +gdb_test "py search_buf = gdb.selected_frame ().read_var ('int8_search_buf')" "" "" | |
35817 | +gdb_test "py start_addr = search_buf.address ()" "" "" | |
35818 | +gdb_test "py length = search_buf.type ().sizeof ()" "" "" | |
35819 | + | |
35820 | +gdb_test "py print gdb.search_memory (start_addr, length, 'aaa')" \ | |
35821 | + "${two_patterns_found}" "find string pattern" | |
35822 | + | |
35823 | +# Test not finding pattern because search range too small, with | |
35824 | +# potential find at the edge of the range. | |
35825 | + | |
35826 | +gdb_test "py print gdb.search_memory (start_addr, 10+3, 'aaaa')" \ | |
35827 | + "${pattern_not_found}" "pattern not found at end of range" | |
35828 | + | |
35829 | +# Increase the search range by 1 and we should find the pattern. | |
35830 | + | |
35831 | +gdb_test "py print gdb.search_memory (start_addr, 10+3+1, \['a', 'a', 'a', 'a'\])" \ | |
35832 | + "${one_pattern_found}" "pattern found at end of range" | |
35833 | + | |
35834 | +# Test max-count with size, with different parameter position | |
35835 | + | |
35836 | +gdb_test "py print gdb.search_memory (start_addr, length, \[0x61, 0x61\], 1, 1)" \ | |
35837 | + "${one_pattern_found}" "size = 1, max_count = 1" | |
35838 | + | |
35839 | +gdb_test "py print gdb.search_memory (start_addr, length, \[0x61, 0x61\], 1, 2)" \ | |
35840 | + "${two_patterns_found}" "size = 1, max_count = 2, normal ordering" | |
35841 | + | |
35842 | +gdb_test "py print gdb.search_memory (start_addr, length, \[0x61, 0x61\], size = 1, max_count = 2)" \ | |
35843 | + "${two_patterns_found}" "size = 1, max_count = 2, normal ordering, with keywords" | |
35844 | + | |
35845 | +gdb_test "py print gdb.search_memory (start_addr, length, \[0x61, 0x61\], max_count = 2, size = 1)" \ | |
35846 | + "${two_patterns_found}" "size = 1, max_count = 2, inverted ordering" | |
35847 | + | |
35848 | +gdb_test "py print gdb.search_memory (start_addr, length, \['a', 'a'\], max_count = 2)" \ | |
35849 | + "${two_patterns_found}" "max_count = 2, with keyword" | |
35850 | + | |
35851 | +# Test 16-bit pattern. | |
35852 | + | |
35853 | +gdb_test "set int16_search_buf\[10\] = 0x1234" "" "" | |
35854 | +gdb_test "py search_buf = gdb.selected_frame ().read_var ('int16_search_buf')" "" "" | |
35855 | +gdb_test "py start_addr = search_buf.address ()" "" "" | |
35856 | +gdb_test "py length = search_buf.type ().sizeof ()" "" "" | |
35857 | +gdb_test "py pattern = gdb.parse_and_eval ('(int16_t) 0x1234')" "" "" | |
35858 | + | |
35859 | +gdb_test "py print gdb.search_memory (start_addr, length, 0x1234, 2)" \ | |
35860 | + "${one_pattern_found}" "find 16-bit pattern, with python pattern" | |
35861 | + | |
35862 | +gdb_test "py print gdb.search_memory (start_addr, length, pattern)" \ | |
35863 | + "${one_pattern_found}" "find 16-bit pattern, with value pattern" | |
35864 | + | |
35865 | +# Test 32-bit pattern. | |
35866 | + | |
35867 | +gdb_test "set int32_search_buf\[10\] = 0x12345678" "" "" | |
35868 | +gdb_test "py search_buf = gdb.selected_frame ().read_var ('int32_search_buf')" "" "" | |
35869 | +gdb_test "py start_addr = search_buf.address ()" "" "" | |
35870 | +gdb_test "py length = search_buf.type ().sizeof ()" "" "" | |
35871 | +gdb_test "py pattern = gdb.parse_and_eval ('(int32_t) 0x12345678')" "" "" | |
35872 | + | |
35873 | +gdb_test "py print gdb.search_memory (start_addr, length, 0x12345678, 4)" \ | |
35874 | + "${one_pattern_found}" "find 32-bit pattern, with python pattern" | |
35875 | +gdb_test "py print gdb.search_memory (start_addr, length, pattern)" \ | |
35876 | + "${one_pattern_found}" "find 32-bit pattern, with value pattern" | |
35877 | + | |
35878 | +# Test 64-bit pattern. | |
35879 | + | |
35880 | +gdb_test "set int64_search_buf\[10\] = 0xfedcba9876543210LL" "" "" | |
35881 | +gdb_test "py search_buf = gdb.selected_frame ().read_var ('int64_search_buf')" "" "" | |
35882 | +gdb_test "py start_addr = search_buf.address ()" "" "" | |
35883 | +gdb_test "py length = search_buf.type ().sizeof ()" "" "" | |
35884 | +gdb_test "py pattern = gdb.parse_and_eval ('(int64_t) 0xfedcba9876543210LL')" "" "" | |
35885 | + | |
35886 | +gdb_test "py print gdb.search_memory (start_addr, length, 0xfedcba9876543210, 8)" \ | |
35887 | + "${one_pattern_found}" "find 64-bit pattern, with python pattern" | |
35888 | +gdb_test "py print gdb.search_memory (start_addr, length, pattern)" \ | |
35889 | + "${one_pattern_found}" "find 64-bit pattern, with value pattern" | |
35890 | + | |
35891 | +# Test mixed-sized patterns. | |
35892 | + | |
35893 | +gdb_test "set *(int8_t*) &search_buf\[10\] = 0x62" "" "" | |
35894 | +gdb_test "set *(int16_t*) &search_buf\[11\] = 0x6363" "" "" | |
35895 | +gdb_test "set *(int32_t*) &search_buf\[13\] = 0x64646464" "" "" | |
35896 | +gdb_test "py search_buf = gdb.selected_frame ().read_var ('search_buf')" "" "" | |
35897 | +gdb_test "py start_addr = search_buf\[0\].address ()" "" "" | |
35898 | +gdb_test "py pattern1 = gdb.parse_and_eval ('(int8_t) 0x62')" "" "" | |
35899 | +gdb_test "py pattern2 = gdb.parse_and_eval ('(int16_t) 0x6363')" "" "" | |
35900 | +gdb_test "py pattern3 = gdb.parse_and_eval ('(int32_t) 0x64646464')" "" "" | |
35901 | + | |
35902 | +gdb_test "py print gdb.search_memory (start_addr, 100, \[pattern1, pattern2, pattern3\])" \ | |
35903 | + "${one_pattern_found}" "find mixed-sized pattern" | |
35904 | + | |
35905 | +# Test search spanning a large range, in the particular case of native | |
35906 | +# targets, test the search spanning multiple chunks. | |
35907 | +# Remote targets may implement the search differently. | |
35908 | + | |
35909 | +set CHUNK_SIZE 16000 ; | |
35910 | + | |
35911 | +gdb_test "set *(int32_t*) &search_buf\[0*${CHUNK_SIZE}+100\] = 0x12345678" "" "" | |
35912 | +gdb_test "set *(int32_t*) &search_buf\[1*${CHUNK_SIZE}+100\] = 0x12345678" "" "" | |
35913 | +gdb_test "py start_addr = gdb.selected_frame ().read_var ('search_buf')" "" "" | |
35914 | +gdb_test "py length = gdb.selected_frame ().read_var ('search_buf_size')" "" "" | |
35915 | + | |
35916 | +gdb_test "py print gdb.search_memory (start_addr, length, 0x12345678, 4)" \ | |
35917 | + "${two_patterns_found}" "search spanning large range" | |
35918 | + | |
35919 | +# For native targets, test a pattern straddling a chunk boundary. | |
35920 | + | |
35921 | +if [isnative] { | |
35922 | + gdb_test "set *(int32_t*) &search_buf\[${CHUNK_SIZE}-1\] = 0xfdb97531" "" "" | |
35923 | + | |
35924 | + gdb_test "py print gdb.search_memory (start_addr, length, 0xfdb97531, 4)" \ | |
35925 | + "${one_pattern_found}" "find pattern straddling chunk boundary" | |
35926 | +} | |
35927 | diff --git a/gdb/testsuite/gdb.python/python-cmd.exp b/gdb/testsuite/gdb.python/python-cmd.exp | |
35928 | index 6c73ff2..f6ef938 100644 | |
35929 | --- a/gdb/testsuite/gdb.python/python-cmd.exp | |
35930 | +++ b/gdb/testsuite/gdb.python/python-cmd.exp | |
35931 | @@ -92,6 +92,32 @@ gdb_py_test_multiple "input subcommand" \ | |
35932 | ||
35933 | gdb_test "prefix_cmd subcmd ugh" "subcmd output, arg = ugh" "call subcmd" | |
35934 | ||
35935 | +# Test prefix command using keyword arguments. | |
35936 | + | |
35937 | +gdb_py_test_multiple "input prefix command, keyword arguments" \ | |
35938 | + "python" "" \ | |
35939 | + "class prefix_cmd2 (gdb.Command):" "" \ | |
35940 | + " def __init__ (self):" "" \ | |
35941 | + " super (prefix_cmd2, self).__init__ (\"prefix_cmd2\", gdb.COMMAND_OBSCURE, prefix = True, completer_class = gdb.COMPLETE_FILENAME)" "" \ | |
35942 | + " def invoke (self, arg, from_tty):" "" \ | |
35943 | + " print \"prefix_cmd2 output, arg = %s\" % arg" "" \ | |
35944 | + "prefix_cmd2 ()" "" \ | |
35945 | + "end" "" | |
35946 | + | |
35947 | +gdb_test "prefix_cmd2 argh" "prefix_cmd2 output, arg = argh" "call prefix command, keyword arguments" | |
35948 | + | |
35949 | +gdb_py_test_multiple "input subcommand under prefix_cmd2" \ | |
35950 | + "python" "" \ | |
35951 | + "class subcmd (gdb.Command):" "" \ | |
35952 | + " def __init__ (self):" "" \ | |
35953 | + " super (subcmd, self).__init__ (\"prefix_cmd2 subcmd\", gdb.COMMAND_OBSCURE)" "" \ | |
35954 | + " def invoke (self, arg, from_tty):" "" \ | |
35955 | + " print \"subcmd output, arg = %s\" % arg" "" \ | |
35956 | + "subcmd ()" "" \ | |
35957 | + "end" "" | |
35958 | + | |
35959 | +gdb_test "prefix_cmd2 subcmd ugh" "subcmd output, arg = ugh" "call subcmd under prefix_cmd2" | |
35960 | + | |
35961 | # Test a subcommand in an existing GDB prefix. | |
35962 | ||
35963 | gdb_py_test_multiple "input new subcommand" \ | |
35964 | diff --git a/gdb/testsuite/gdb.python/python-frame.c b/gdb/testsuite/gdb.python/python-frame.c | |
35965 | new file mode 100644 | |
35966 | index 0000000..22eb9f2 | |
35967 | --- /dev/null | |
35968 | +++ b/gdb/testsuite/gdb.python/python-frame.c | |
35969 | @@ -0,0 +1,14 @@ | |
35970 | +int f2 (int a) | |
35971 | +{ | |
35972 | + return ++a; | |
35973 | +} | |
35974 | + | |
35975 | +int f1 (int a, int b) | |
35976 | +{ | |
35977 | + return f2(a) + b; | |
35978 | +} | |
35979 | + | |
35980 | +int main (int argc, char *argv[]) | |
35981 | +{ | |
35982 | + return f1 (1, 2); | |
35983 | +} | |
35984 | diff --git a/gdb/testsuite/gdb.python/python-frame.exp b/gdb/testsuite/gdb.python/python-frame.exp | |
35985 | new file mode 100644 | |
35986 | index 0000000..674c25e | |
35987 | --- /dev/null | |
35988 | +++ b/gdb/testsuite/gdb.python/python-frame.exp | |
35989 | @@ -0,0 +1,92 @@ | |
35990 | +# Copyright (C) 2009 Free Software Foundation, Inc. | |
35991 | + | |
35992 | +# This program is free software; you can redistribute it and/or modify | |
35993 | +# it under the terms of the GNU General Public License as published by | |
35994 | +# the Free Software Foundation; either version 3 of the License, or | |
35995 | +# (at your option) any later version. | |
35996 | +# | |
35997 | +# This program is distributed in the hope that it will be useful, | |
35998 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35999 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
36000 | +# GNU General Public License for more details. | |
36001 | +# | |
36002 | +# You should have received a copy of the GNU General Public License | |
36003 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
36004 | + | |
36005 | +# This file is part of the GDB testsuite. It tests the mechanism | |
36006 | +# exposing values to Python. | |
36007 | + | |
36008 | +if $tracelevel then { | |
36009 | + strace $tracelevel | |
36010 | +} | |
36011 | + | |
36012 | +set testfile "python-frame" | |
36013 | +set srcfile ${testfile}.c | |
36014 | +set binfile ${objdir}/${subdir}/${testfile} | |
36015 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { | |
36016 | + untested "Couldn't compile ${srcfile}" | |
36017 | + return -1 | |
36018 | +} | |
36019 | + | |
36020 | +# Run a command in GDB, and report a failure if a Python exception is thrown. | |
36021 | +# If report_pass is true, report a pass if no exception is thrown. | |
36022 | +proc gdb_py_test_silent_cmd {cmd name report_pass} { | |
36023 | + global gdb_prompt | |
36024 | + | |
36025 | + gdb_test_multiple $cmd $name { | |
36026 | + -re "Traceback.*$gdb_prompt $" { fail $name } | |
36027 | + -re "$gdb_prompt $" { if $report_pass { pass $name } } | |
36028 | + } | |
36029 | +} | |
36030 | + | |
36031 | +# Start with a fresh gdb. | |
36032 | + | |
36033 | +gdb_exit | |
36034 | +gdb_start | |
36035 | +gdb_reinitialize_dir $srcdir/$subdir | |
36036 | +gdb_load ${binfile} | |
36037 | + | |
36038 | +gdb_test_multiple "python print 'hello, world!'" "verify python support" { | |
36039 | + -re "not supported.*$gdb_prompt $" { | |
36040 | + unsupported "python support is disabled" | |
36041 | + return -1 | |
36042 | + } | |
36043 | + -re "$gdb_prompt $" {} | |
36044 | +} | |
36045 | + | |
36046 | +# The following tests require execution. | |
36047 | + | |
36048 | +if ![runto_main] then { | |
36049 | + fail "Can't run to main" | |
36050 | + return 0 | |
36051 | +} | |
36052 | + | |
36053 | +gdb_breakpoint "f2" | |
36054 | +gdb_continue_to_breakpoint "breakpoint at f2" | |
36055 | +gdb_test "up" "" "" | |
36056 | + | |
36057 | +gdb_py_test_silent_cmd "python frames = gdb.frames ()" "get frames list" 1 | |
36058 | +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" | |
36059 | +gdb_py_test_silent_cmd "python f0 = frames\[0\]" "get first frame" 0 | |
36060 | +gdb_py_test_silent_cmd "python f1 = frames\[1\]" "get second frame" 0 | |
36061 | + | |
36062 | +gdb_test "python print 'result =', f0.equals (f1)" " = False" "test equals (false)" | |
36063 | +gdb_test "python print 'result =', f0.equals (f0)" " = True" "test equals (true)" | |
36064 | +gdb_test "python print 'result =', f0.is_valid ()" " = True" "test Frame.is_valid" | |
36065 | +gdb_test "python print 'result =', f0.name ()" " = f2" "test Frame.name" | |
36066 | +gdb_test "python print 'result =', f0.type () == gdb.NORMAL_FRAME" " = True" "test Frame.type" | |
36067 | +gdb_test "python print 'result =', f0.unwind_stop_reason () == gdb.FRAME_UNWIND_NO_REASON" " = True" "test Frame.type" | |
36068 | +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" | |
36069 | +gdb_test "python print 'result =', f0.pc ()" " = \[0-9\]+" "test Frame.pc" | |
36070 | +gdb_test "python print 'result =', f0.addr_in_block ()" " = \[0-9\]+" "test Frame.addr_in_block" | |
36071 | +gdb_test "python print 'result =', f0.older ().equals (f1)" " = True" "test Frame.older" | |
36072 | +gdb_test "python print 'result =', f1.newer ().equals (f0)" " = True" "test Frame.newer" | |
36073 | +gdb_test "python print 'result =', f0.read_var ('variable_which_surely_doesnt_exist')" \ | |
36074 | + "ValueError: variable 'variable_which_surely_doesnt_exist' not found.*Error while executing Python code." \ | |
36075 | + "test Frame.read_var - error" | |
36076 | +gdb_test "python print 'result =', f0.read_var ('a')" " = 1" "test Frame.read_var - success" | |
36077 | + | |
36078 | +gdb_test "python print 'result =', gdb.newest_frame ().equals (f0)" " = True" "test gdb.newest_frame" | |
36079 | +gdb_test "python print 'result =', gdb.selected_frame ().equals (f1)" " = True" "test gdb.selected_frame" | |
36080 | + | |
36081 | +gdb_test "python print 'result =', f0.block ()" "<gdb.Block object at 0x\[\[:xdigit:\]\]+>" "test Frame.block" | |
36082 | diff --git a/gdb/testsuite/gdb.python/python-function.exp b/gdb/testsuite/gdb.python/python-function.exp | |
36083 | new file mode 100644 | |
36084 | index 0000000..7feca2b | |
36085 | --- /dev/null | |
36086 | +++ b/gdb/testsuite/gdb.python/python-function.exp | |
36087 | @@ -0,0 +1,79 @@ | |
36088 | +# Copyright (C) 2009 Free Software Foundation, Inc. | |
36089 | + | |
36090 | +# This program is free software; you can redistribute it and/or modify | |
36091 | +# it under the terms of the GNU General Public License as published by | |
36092 | +# the Free Software Foundation; either version 3 of the License, or | |
36093 | +# (at your option) any later version. | |
36094 | +# | |
36095 | +# This program is distributed in the hope that it will be useful, | |
36096 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36097 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
36098 | +# GNU General Public License for more details. | |
36099 | +# | |
36100 | +# You should have received a copy of the GNU General Public License | |
36101 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
36102 | + | |
36103 | +# This file is part of the GDB testsuite. It tests the mechanism | |
36104 | +# exposing convenience functions to Python. | |
36105 | + | |
36106 | +if $tracelevel then { | |
36107 | + strace $tracelevel | |
36108 | +} | |
36109 | + | |
36110 | +# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}... | |
36111 | +# Run a test named NAME, consisting of multiple lines of input. | |
36112 | +# After each input line INPUT, search for result line RESULT. | |
36113 | +# Succeed if all results are seen; fail otherwise. | |
36114 | +proc gdb_py_test_multiple {name args} { | |
36115 | + global gdb_prompt | |
36116 | + foreach {input result} $args { | |
36117 | + if {[gdb_test_multiple $input "$name - $input" { | |
36118 | + -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" { | |
36119 | + pass "$name - $input" | |
36120 | + } | |
36121 | + }]} { | |
36122 | + return 1 | |
36123 | + } | |
36124 | + } | |
36125 | + return 0 | |
36126 | +} | |
36127 | + | |
36128 | +# Start with a fresh gdb. | |
36129 | + | |
36130 | +gdb_exit | |
36131 | +gdb_start | |
36132 | +gdb_reinitialize_dir $srcdir/$subdir | |
36133 | + | |
36134 | +gdb_test_multiple "python print 'hello, world!'" "verify python support" { | |
36135 | + -re "not supported.*$gdb_prompt $" { | |
36136 | + unsupported "python support is disabled" | |
36137 | + return -1 | |
36138 | + } | |
36139 | + -re "$gdb_prompt $" {} | |
36140 | +} | |
36141 | + | |
36142 | +gdb_py_test_multiple "input convenience function" \ | |
36143 | + "python" "" \ | |
36144 | + "class test_func (gdb.Function):" "" \ | |
36145 | + " def __init__ (self):" "" \ | |
36146 | + " super (test_func, self).__init__ (\"test_func\")" "" \ | |
36147 | + " def invoke (self, arg):" "" \ | |
36148 | + " return \"test_func output, arg = %s\" % arg.string ()" "" \ | |
36149 | + "test_func ()" "" \ | |
36150 | + "end" "" | |
36151 | + | |
36152 | +gdb_test "print \$test_func (\"ugh\")" "= \"test_func output, arg = ugh\"" "call function" | |
36153 | + | |
36154 | +# Test returning a gdb.Value from the function. This segfaulted GDB at one point. | |
36155 | + | |
36156 | +gdb_py_test_multiple "input value-returning convenience function" \ | |
36157 | + "python" "" \ | |
36158 | + "class Double (gdb.Function):" "" \ | |
36159 | + " def __init__ (self):" "" \ | |
36160 | + " super (Double, self).__init__ (\"double\")" "" \ | |
36161 | + " def invoke (self, n):" "" \ | |
36162 | + " return n*2" "" \ | |
36163 | + "Double ()" "" \ | |
36164 | + "end" "" | |
36165 | + | |
36166 | +gdb_test "print \$double (1)" "= 2" "call value-returning function" | |
36167 | diff --git a/gdb/testsuite/gdb.python/python-mi.exp b/gdb/testsuite/gdb.python/python-mi.exp | |
36168 | new file mode 100644 | |
36169 | index 0000000..5c9f3c7 | |
36170 | --- /dev/null | |
36171 | +++ b/gdb/testsuite/gdb.python/python-mi.exp | |
36172 | @@ -0,0 +1,124 @@ | |
36173 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
36174 | + | |
36175 | +# This program is free software; you can redistribute it and/or modify | |
36176 | +# it under the terms of the GNU General Public License as published by | |
36177 | +# the Free Software Foundation; either version 3 of the License, or | |
36178 | +# (at your option) any later version. | |
36179 | +# | |
36180 | +# This program is distributed in the hope that it will be useful, | |
36181 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36182 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
36183 | +# GNU General Public License for more details. | |
36184 | +# | |
36185 | +# You should have received a copy of the GNU General Public License | |
36186 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
36187 | + | |
36188 | +# This file is part of the GDB testsuite. It tests Python-based | |
36189 | +# pretty-printing for MI. | |
36190 | + | |
36191 | +load_lib mi-support.exp | |
36192 | +set MIFLAGS "-i=mi2" | |
36193 | + | |
36194 | +gdb_exit | |
36195 | +if [mi_gdb_start] { | |
36196 | + continue | |
36197 | +} | |
36198 | + | |
36199 | +set testfile "python-prettyprint" | |
36200 | +set srcfile ${testfile}.c | |
36201 | +set binfile ${objdir}/${subdir}/${testfile} | |
36202 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DMI}] != "" } { | |
36203 | + untested mi2-var-child.exp | |
36204 | + return -1 | |
36205 | +} | |
36206 | + | |
36207 | +mi_delete_breakpoints | |
36208 | +mi_gdb_reinitialize_dir $srcdir/$subdir | |
36209 | +mi_gdb_load ${binfile} | |
36210 | + | |
36211 | +if {[lsearch -exact [mi_get_features] python] < 0} { | |
36212 | + unsupported "python support is disabled" | |
36213 | + return -1 | |
36214 | +} | |
36215 | + | |
36216 | +mi_runto main | |
36217 | + | |
36218 | +mi_gdb_test "python execfile ('${srcdir}/${subdir}/${testfile}.py')" "" | |
36219 | + | |
36220 | +mi_continue_to_line [gdb_get_line_number {MI breakpoint here} ${testfile}.c] \ | |
36221 | + "step to breakpoint" | |
36222 | + | |
36223 | +mi_create_floating_varobj container c "create container varobj" | |
36224 | + | |
36225 | +mi_list_varobj_children container { | |
36226 | +} "examine container children=0" | |
36227 | + | |
36228 | +mi_next "next over update 1" | |
36229 | + | |
36230 | +mi_varobj_update_dynamic container { | |
36231 | + { {container.\[0\]} {\[0\]} 0 int } | |
36232 | +} "varobj update 1" | |
36233 | + | |
36234 | +mi_next "next over update 2" | |
36235 | + | |
36236 | +mi_varobj_update_dynamic container { | |
36237 | + { {container.\[0\]} {\[0\]} 0 int } | |
36238 | + { {container.\[1\]} {\[1\]} 0 int } | |
36239 | +} "varobj update 2" | |
36240 | + | |
36241 | +mi_gdb_test "-var-set-visualizer container None" \ | |
36242 | + "\\^done" \ | |
36243 | + "clear visualizer" | |
36244 | + | |
36245 | +mi_gdb_test "-var-update container" \ | |
36246 | + "\\^done,changelist=\\\[\\\]" \ | |
36247 | + "varobj update after clearing" | |
36248 | + | |
36249 | +mi_gdb_test "-var-set-visualizer container gdb.default_visualizer" \ | |
36250 | + "\\^done" \ | |
36251 | + "choose default visualizer" | |
36252 | + | |
36253 | +mi_varobj_update_dynamic container { | |
36254 | + { {container.\[0\]} {\[0\]} 0 int } | |
36255 | + { {container.\[1\]} {\[1\]} 0 int } | |
36256 | +} "varobj update after choosing default" | |
36257 | + | |
36258 | +mi_gdb_test "-var-set-visualizer container ContainerPrinter" \ | |
36259 | + "\\^done" \ | |
36260 | + "choose visualizer using expression" | |
36261 | + | |
36262 | +mi_varobj_update_dynamic container { | |
36263 | + { {container.\[0\]} {\[0\]} 0 int } | |
36264 | + { {container.\[1\]} {\[1\]} 0 int } | |
36265 | +} "varobj update after choosing via expression" | |
36266 | + | |
36267 | +mi_gdb_test "-var-set-child-range container 1 2" \ | |
36268 | + "\\^done" \ | |
36269 | + "select child range" | |
36270 | + | |
36271 | +mi_gdb_test "-var-update container" \ | |
36272 | + "\\^done,changelist=\\\[\\\]" \ | |
36273 | + "varobj update after selecting child range" | |
36274 | + | |
36275 | +mi_list_varobj_children_range container 2 { | |
36276 | + { {container.\[1\]} {\[1\]} 0 int } | |
36277 | +} "list varobj children after selecting child range" | |
36278 | + | |
36279 | +mi_gdb_test "-var-set-child-range container -1 -1" \ | |
36280 | + "\\^done" \ | |
36281 | + "reset child range" | |
36282 | + | |
36283 | +mi_gdb_test "-var-update container" \ | |
36284 | + "\\^done,changelist=\\\[\\\]" \ | |
36285 | + "varobj update after resetting child range" | |
36286 | + | |
36287 | +mi_list_varobj_children container { | |
36288 | + { {container.\[0\]} {\[0\]} 0 int } | |
36289 | + { {container.\[1\]} {\[1\]} 0 int } | |
36290 | +} "list varobj children after resetting child range" | |
36291 | + | |
36292 | +mi_continue_to_line \ | |
36293 | + [gdb_get_line_number {Another MI breakpoint} ${testfile}.c] \ | |
36294 | + "step to second breakpoint" | |
36295 | + | |
36296 | +mi_varobj_update_with_type_change container int 0 "update after type change" | |
36297 | diff --git a/gdb/testsuite/gdb.python/python-prettyprint.c b/gdb/testsuite/gdb.python/python-prettyprint.c | |
36298 | new file mode 100644 | |
36299 | index 0000000..f8c2435 | |
36300 | --- /dev/null | |
36301 | +++ b/gdb/testsuite/gdb.python/python-prettyprint.c | |
36302 | @@ -0,0 +1,159 @@ | |
36303 | +/* This testcase is part of GDB, the GNU debugger. | |
36304 | + | |
36305 | + Copyright 2008 Free Software Foundation, Inc. | |
36306 | + | |
36307 | + This program is free software; you can redistribute it and/or modify | |
36308 | + it under the terms of the GNU General Public License as published by | |
36309 | + the Free Software Foundation; either version 3 of the License, or | |
36310 | + (at your option) any later version. | |
36311 | + | |
36312 | + This program is distributed in the hope that it will be useful, | |
36313 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36314 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
36315 | + GNU General Public License for more details. | |
36316 | + | |
36317 | + You should have received a copy of the GNU General Public License | |
36318 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
36319 | + | |
36320 | +struct s | |
36321 | +{ | |
36322 | + int a; | |
36323 | + int *b; | |
36324 | +}; | |
36325 | + | |
36326 | +struct ss | |
36327 | +{ | |
36328 | + struct s a; | |
36329 | + struct s b; | |
36330 | +}; | |
36331 | + | |
36332 | +#ifdef __cplusplus | |
36333 | +struct S : public s { | |
36334 | + int zs; | |
36335 | +}; | |
36336 | + | |
36337 | +struct SS { | |
36338 | + int zss; | |
36339 | + S s; | |
36340 | +}; | |
36341 | + | |
36342 | +struct SSS | |
36343 | +{ | |
36344 | + SSS (int x, const S& r); | |
36345 | + int a; | |
36346 | + const S &b; | |
36347 | +}; | |
36348 | +SSS::SSS (int x, const S& r) : a(x), b(r) { } | |
36349 | +#endif | |
36350 | + | |
36351 | +typedef struct string_repr | |
36352 | +{ | |
36353 | + struct whybother | |
36354 | + { | |
36355 | + const char *contents; | |
36356 | + } whybother; | |
36357 | +} string; | |
36358 | + | |
36359 | +/* This lets us avoid malloc. */ | |
36360 | +int array[100]; | |
36361 | + | |
36362 | +struct container | |
36363 | +{ | |
36364 | + string name; | |
36365 | + int len; | |
36366 | + int *elements; | |
36367 | +}; | |
36368 | + | |
36369 | +typedef struct container zzz_type; | |
36370 | + | |
36371 | +string | |
36372 | +make_string (const char *s) | |
36373 | +{ | |
36374 | + string result; | |
36375 | + result.whybother.contents = s; | |
36376 | + return result; | |
36377 | +} | |
36378 | + | |
36379 | +zzz_type | |
36380 | +make_container (const char *s) | |
36381 | +{ | |
36382 | + zzz_type result; | |
36383 | + | |
36384 | + result.name = make_string (s); | |
36385 | + result.len = 0; | |
36386 | + result.elements = 0; | |
36387 | + | |
36388 | + return result; | |
36389 | +} | |
36390 | + | |
36391 | +void | |
36392 | +add_item (zzz_type *c, int val) | |
36393 | +{ | |
36394 | + if (c->len == 0) | |
36395 | + c->elements = array; | |
36396 | + c->elements[c->len] = val; | |
36397 | + ++c->len; | |
36398 | +} | |
36399 | + | |
36400 | +void init_s(struct s *s, int a) | |
36401 | +{ | |
36402 | + s->a = a; | |
36403 | + s->b = &s->a; | |
36404 | +} | |
36405 | + | |
36406 | +void init_ss(struct ss *s, int a, int b) | |
36407 | +{ | |
36408 | + init_s(&s->a, a); | |
36409 | + init_s(&s->b, b); | |
36410 | +} | |
36411 | + | |
36412 | +void do_nothing(void) | |
36413 | +{ | |
36414 | + int c; | |
36415 | + | |
36416 | + c = 23; /* Another MI breakpoint */ | |
36417 | +} | |
36418 | + | |
36419 | +int | |
36420 | +main () | |
36421 | +{ | |
36422 | + struct ss ss; | |
36423 | + struct ss ssa[2]; | |
36424 | + string x = make_string ("this is x"); | |
36425 | + zzz_type c = make_container ("container"); | |
36426 | + const struct string_repr cstring = { { "const string" } }; | |
36427 | + | |
36428 | + init_ss(&ss, 1, 2); | |
36429 | + init_ss(ssa+0, 3, 4); | |
36430 | + init_ss(ssa+1, 5, 6); | |
36431 | + | |
36432 | +#ifdef __cplusplus | |
36433 | + S cps; | |
36434 | + | |
36435 | + cps.zs = 7; | |
36436 | + init_s(&cps, 8); | |
36437 | + | |
36438 | + SS cpss; | |
36439 | + cpss.zss = 9; | |
36440 | + init_s(&cpss.s, 10); | |
36441 | + | |
36442 | + SS cpssa[2]; | |
36443 | + cpssa[0].zss = 11; | |
36444 | + init_s(&cpssa[0].s, 12); | |
36445 | + cpssa[1].zss = 13; | |
36446 | + init_s(&cpssa[1].s, 14); | |
36447 | + | |
36448 | + SSS sss(15, cps); | |
36449 | + | |
36450 | + SSS& ref (sss); | |
36451 | +#endif | |
36452 | + | |
36453 | + add_item (&c, 23); /* MI breakpoint here */ | |
36454 | + add_item (&c, 72); | |
36455 | + | |
36456 | +#ifdef MI | |
36457 | + do_nothing (); | |
36458 | +#endif | |
36459 | + | |
36460 | + return 0; /* break to inspect struct and union */ | |
36461 | +} | |
36462 | diff --git a/gdb/testsuite/gdb.python/python-prettyprint.exp b/gdb/testsuite/gdb.python/python-prettyprint.exp | |
36463 | new file mode 100644 | |
36464 | index 0000000..b2ccb2b | |
36465 | --- /dev/null | |
36466 | +++ b/gdb/testsuite/gdb.python/python-prettyprint.exp | |
36467 | @@ -0,0 +1,90 @@ | |
36468 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
36469 | + | |
36470 | +# This program is free software; you can redistribute it and/or modify | |
36471 | +# it under the terms of the GNU General Public License as published by | |
36472 | +# the Free Software Foundation; either version 3 of the License, or | |
36473 | +# (at your option) any later version. | |
36474 | +# | |
36475 | +# This program is distributed in the hope that it will be useful, | |
36476 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36477 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
36478 | +# GNU General Public License for more details. | |
36479 | +# | |
36480 | +# You should have received a copy of the GNU General Public License | |
36481 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
36482 | + | |
36483 | +# This file is part of the GDB testsuite. It tests Python-based | |
36484 | +# pretty-printing for the CLI. | |
36485 | + | |
36486 | +if $tracelevel then { | |
36487 | + strace $tracelevel | |
36488 | +} | |
36489 | + | |
36490 | +set testfile "python-prettyprint" | |
36491 | +set srcfile ${testfile}.c | |
36492 | +set binfile ${objdir}/${subdir}/${testfile} | |
36493 | + | |
36494 | +# Start with a fresh gdb. | |
36495 | +gdb_exit | |
36496 | +gdb_start | |
36497 | +gdb_test_multiple "python print 'hello, world!'" "verify python support" { | |
36498 | + -re "not supported.*$gdb_prompt $" { | |
36499 | + unsupported "python support is disabled" | |
36500 | + return -1 | |
36501 | + } | |
36502 | + -re "$gdb_prompt $" {} | |
36503 | +} | |
36504 | + | |
36505 | +proc run_lang_tests {lang} { | |
36506 | + global srcdir subdir srcfile binfile testfile hex | |
36507 | + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug $lang"] != "" } { | |
36508 | + untested "Couldn't compile ${srcfile} in $lang mode" | |
36509 | + return -1 | |
36510 | + } | |
36511 | + | |
36512 | + set nl "\[\r\n\]+" | |
36513 | + | |
36514 | + # Start with a fresh gdb. | |
36515 | + gdb_exit | |
36516 | + gdb_start | |
36517 | + gdb_reinitialize_dir $srcdir/$subdir | |
36518 | + gdb_load ${binfile} | |
36519 | + | |
36520 | + | |
36521 | + if ![runto_main ] then { | |
36522 | + perror "couldn't run to breakpoint" | |
36523 | + return | |
36524 | + } | |
36525 | + | |
36526 | + gdb_test "set print pretty on" "" | |
36527 | + | |
36528 | + gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \ | |
36529 | + ".*Breakpoint.*" | |
36530 | + gdb_test "continue" ".*Breakpoint.*" | |
36531 | + | |
36532 | + gdb_test "python execfile ('${srcdir}/${subdir}/${testfile}.py')" "" | |
36533 | + | |
36534 | + gdb_test "print ss" " = a=< a=<1> b=<$hex>> b=< a=<2> b=<$hex>>" | |
36535 | + gdb_test "print ssa\[1\]" " = a=< a=<5> b=<$hex>> b=< a=<6> b=<$hex>>" | |
36536 | + gdb_test "print ssa" " = {a=< a=<3> b=<$hex>> b=< a=<4> b=<$hex>>, a=< a=<5> b=<$hex>> b=< a=<6> b=<$hex>>}" | |
36537 | + | |
36538 | + if {$lang == "c++"} { | |
36539 | + gdb_test "print cps" "= a=<8> b=<$hex>" | |
36540 | + gdb_test "print cpss" " = {$nl *zss = 9, *$nl *s = a=<10> b=<$hex>$nl}" | |
36541 | + gdb_test "print cpssa\[0\]" " = {$nl *zss = 11, *$nl *s = a=<12> b=<$hex>$nl}" | |
36542 | + gdb_test "print cpssa\[1\]" " = {$nl *zss = 13, *$nl *s = a=<14> b=<$hex>$nl}" | |
36543 | + gdb_test "print cpssa" " = {{$nl *zss = 11, *$nl *s = a=<12> b=<$hex>$nl *}, {$nl *zss = 13, *$nl *s = a=<14> b=<$hex>$nl *}}" | |
36544 | + gdb_test "print sss" "= a=<15> b=< a=<8> b=<$hex>>" | |
36545 | + gdb_test "print ref" "= a=<15> b=< a=<8> b=<$hex>>" | |
36546 | + } | |
36547 | + | |
36548 | + gdb_test "print x" " = $hex \"this is x\"" | |
36549 | + gdb_test "print cstring" " = $hex \"const string\"" | |
36550 | + | |
36551 | + gdb_test "print c" " = container $hex \"container\" with 2 elements = {$nl *.0. = 23,$nl *.1. = 72$nl}" | |
36552 | + | |
36553 | + gdb_test "continue" "Program exited normally\." | |
36554 | +} | |
36555 | + | |
36556 | +run_lang_tests "c" | |
36557 | +run_lang_tests "c++" | |
36558 | diff --git a/gdb/testsuite/gdb.python/python-prettyprint.py b/gdb/testsuite/gdb.python/python-prettyprint.py | |
36559 | new file mode 100644 | |
36560 | index 0000000..0d9cb87 | |
36561 | --- /dev/null | |
36562 | +++ b/gdb/testsuite/gdb.python/python-prettyprint.py | |
36563 | @@ -0,0 +1,134 @@ | |
36564 | +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. | |
36565 | + | |
36566 | +# This program is free software; you can redistribute it and/or modify | |
36567 | +# it under the terms of the GNU General Public License as published by | |
36568 | +# the Free Software Foundation; either version 3 of the License, or | |
36569 | +# (at your option) any later version. | |
36570 | +# | |
36571 | +# This program is distributed in the hope that it will be useful, | |
36572 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36573 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
36574 | +# GNU General Public License for more details. | |
36575 | +# | |
36576 | +# You should have received a copy of the GNU General Public License | |
36577 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
36578 | + | |
36579 | +# This file is part of the GDB testsuite. It tests python pretty | |
36580 | +# printers. | |
36581 | + | |
36582 | +import re | |
36583 | + | |
36584 | +# Test returning a Value from a printer. | |
36585 | +class string_print: | |
36586 | + def __init__(self, val): | |
36587 | + self.val = val | |
36588 | + | |
36589 | + def to_string(self): | |
36590 | + return self.val['whybother']['contents'] | |
36591 | + | |
36592 | +# Test a class-based printer. | |
36593 | +class ContainerPrinter: | |
36594 | + class _iterator: | |
36595 | + def __init__ (self, pointer, len): | |
36596 | + self.start = pointer | |
36597 | + self.pointer = pointer | |
36598 | + self.end = pointer + len | |
36599 | + | |
36600 | + def __iter__(self): | |
36601 | + return self | |
36602 | + | |
36603 | + def next(self): | |
36604 | + if self.pointer == self.end: | |
36605 | + raise StopIteration | |
36606 | + result = self.pointer | |
36607 | + self.pointer = self.pointer + 1 | |
36608 | + return ('[%d]' % int (result - self.start), result.dereference()) | |
36609 | + | |
36610 | + def __init__(self, val): | |
36611 | + self.val = val | |
36612 | + | |
36613 | + def to_string(self): | |
36614 | + return 'container %s with %d elements' % (self.val['name'], self.val['len']) | |
36615 | + | |
36616 | + def children(self): | |
36617 | + return self._iterator(self.val['elements'], self.val['len']) | |
36618 | + | |
36619 | +class pp_s: | |
36620 | + def __init__(self, val): | |
36621 | + self.val = val | |
36622 | + | |
36623 | + def to_string(self): | |
36624 | + a = self.val["a"] | |
36625 | + b = self.val["b"] | |
36626 | + if a.address() != b: | |
36627 | + raise Exception("&a(%s) != b(%s)" % (str(a.address()), str(b))) | |
36628 | + return " a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">" | |
36629 | + | |
36630 | +class pp_ss: | |
36631 | + def __init__(self, val): | |
36632 | + self.val = val | |
36633 | + | |
36634 | + def to_string(self): | |
36635 | + return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">" | |
36636 | + | |
36637 | +class pp_sss: | |
36638 | + def __init__(self, val): | |
36639 | + self.val = val | |
36640 | + | |
36641 | + def to_string(self): | |
36642 | + return "a=<" + str(self.val['a']) + "> b=<" + str(self.val["b"]) + ">" | |
36643 | + | |
36644 | +def lookup_function (val): | |
36645 | + "Look-up and return a pretty-printer that can print val." | |
36646 | + | |
36647 | + # Get the type. | |
36648 | + type = val.type (); | |
36649 | + | |
36650 | + # If it points to a reference, get the reference. | |
36651 | + if type.code () == gdb.TYPE_CODE_REF: | |
36652 | + type = type.target () | |
36653 | + | |
36654 | + # Get the unqualified type, stripped of typedefs. | |
36655 | + type = type.unqualified ().strip_typedefs () | |
36656 | + | |
36657 | + # Get the type name. | |
36658 | + typename = type.tag () | |
36659 | + | |
36660 | + if typename == None: | |
36661 | + return None | |
36662 | + | |
36663 | + # Iterate over local dictionary of types to determine | |
36664 | + # if a printer is registered for that type. Return an | |
36665 | + # instantiation of the printer if found. | |
36666 | + for function in pretty_printers_dict: | |
36667 | + if function.match (typename): | |
36668 | + return pretty_printers_dict[function] (val) | |
36669 | + | |
36670 | + # Cannot find a pretty printer. Return None. | |
36671 | + | |
36672 | + return None | |
36673 | + | |
36674 | + | |
36675 | +def register_pretty_printers (): | |
36676 | + pretty_printers_dict[re.compile ('^struct s$')] = pp_s | |
36677 | + pretty_printers_dict[re.compile ('^s$')] = pp_s | |
36678 | + pretty_printers_dict[re.compile ('^S$')] = pp_s | |
36679 | + | |
36680 | + pretty_printers_dict[re.compile ('^struct ss$')] = pp_ss | |
36681 | + pretty_printers_dict[re.compile ('^ss$')] = pp_ss | |
36682 | + pretty_printers_dict[re.compile ('^const S &$')] = pp_s | |
36683 | + pretty_printers_dict[re.compile ('^SSS$')] = pp_sss | |
36684 | + | |
36685 | + # Note that we purposely omit the typedef names here. | |
36686 | + # Printer lookup is based on canonical name. | |
36687 | + # However, we do need both tagged and untagged variants, to handle | |
36688 | + # both the C and C++ cases. | |
36689 | + pretty_printers_dict[re.compile ('^struct string_repr$')] = string_print | |
36690 | + pretty_printers_dict[re.compile ('^struct container$')] = ContainerPrinter | |
36691 | + pretty_printers_dict[re.compile ('^string_repr$')] = string_print | |
36692 | + pretty_printers_dict[re.compile ('^container$')] = ContainerPrinter | |
36693 | + | |
36694 | +pretty_printers_dict = {} | |
36695 | + | |
36696 | +register_pretty_printers () | |
36697 | +gdb.pretty_printers.append (lookup_function) | |
36698 | diff --git a/gdb/testsuite/gdb.python/python-template.cc b/gdb/testsuite/gdb.python/python-template.cc | |
36699 | new file mode 100644 | |
36700 | index 0000000..bd6a212 | |
36701 | --- /dev/null | |
36702 | +++ b/gdb/testsuite/gdb.python/python-template.cc | |
36703 | @@ -0,0 +1,30 @@ | |
36704 | +/* This testcase is part of GDB, the GNU debugger. | |
36705 | + | |
36706 | + Copyright 2008 Free Software Foundation, Inc. | |
36707 | + | |
36708 | + This program is free software; you can redistribute it and/or modify | |
36709 | + it under the terms of the GNU General Public License as published by | |
36710 | + the Free Software Foundation; either version 3 of the License, or | |
36711 | + (at your option) any later version. | |
36712 | + | |
36713 | + This program is distributed in the hope that it will be useful, | |
36714 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36715 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
36716 | + GNU General Public License for more details. | |
36717 | + | |
36718 | + You should have received a copy of the GNU General Public License | |
36719 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
36720 | + | |
36721 | +template <typename T> | |
36722 | +struct Foo { | |
36723 | +}; | |
36724 | + | |
36725 | +#ifndef TYPE | |
36726 | +#define TYPE int | |
36727 | +#endif | |
36728 | + | |
36729 | +int main() | |
36730 | +{ | |
36731 | + Foo<TYPE> foo; | |
36732 | + return 0; // break here | |
36733 | +} | |
36734 | diff --git a/gdb/testsuite/gdb.python/python-template.exp b/gdb/testsuite/gdb.python/python-template.exp | |
36735 | new file mode 100644 | |
36736 | index 0000000..561ff73 | |
36737 | --- /dev/null | |
36738 | +++ b/gdb/testsuite/gdb.python/python-template.exp | |
36739 | @@ -0,0 +1,75 @@ | |
36740 | +# Copyright (C) 2008 Free Software Foundation, Inc. | |
36741 | + | |
36742 | +# This program is free software; you can redistribute it and/or modify | |
36743 | +# it under the terms of the GNU General Public License as published by | |
36744 | +# the Free Software Foundation; either version 3 of the License, or | |
36745 | +# (at your option) any later version. | |
36746 | +# | |
36747 | +# This program is distributed in the hope that it will be useful, | |
36748 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36749 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
36750 | +# GNU General Public License for more details. | |
36751 | +# | |
36752 | +# You should have received a copy of the GNU General Public License | |
36753 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
36754 | + | |
36755 | +# This file is part of the GDB testsuite. It tests the mechanism | |
36756 | +# exposing values to Python. | |
36757 | + | |
36758 | +if $tracelevel then { | |
36759 | + strace $tracelevel | |
36760 | +} | |
36761 | + | |
36762 | +set testfile "python-template" | |
36763 | +set srcfile ${testfile}.cc | |
36764 | +set binfile ${objdir}/${subdir}/${testfile} | |
36765 | +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ | |
36766 | + {debug c++}] != "" } { | |
36767 | + untested "Couldn't compile ${srcfile}" | |
36768 | + return -1 | |
36769 | +} | |
36770 | + | |
36771 | +# Start with a fresh gdb. | |
36772 | + | |
36773 | +gdb_exit | |
36774 | +gdb_start | |
36775 | +gdb_reinitialize_dir $srcdir/$subdir | |
36776 | + | |
36777 | +gdb_test_multiple "python print 23" "verify python support" { | |
36778 | + -re "not supported.*$gdb_prompt $" { | |
36779 | + unsupported "python support is disabled" | |
36780 | + return -1 | |
36781 | + } | |
36782 | + -re "$gdb_prompt $" {} | |
36783 | +} | |
36784 | + | |
36785 | +proc test_template_arg {type} { | |
36786 | + global testfile srcdir subdir srcfile binfile | |
36787 | + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ | |
36788 | + executable \ | |
36789 | + [list debug c++ additional_flags="-DTYPE=$type"]] != "" } { | |
36790 | + untested $type | |
36791 | + return -1 | |
36792 | + } | |
36793 | + gdb_load ${binfile} | |
36794 | + if ![runto_main ] then { | |
36795 | + perror "couldn't run to breakpoint" | |
36796 | + return | |
36797 | + } | |
36798 | + # There is no executable code in main(), so we are where we want to be | |
36799 | + gdb_test "print foo" "" | |
36800 | + gdb_test "python foo = gdb.history(0)" "" | |
36801 | + | |
36802 | + # Replace '*' with '\*' in regex. | |
36803 | + regsub -all {\*} $type {\*} t | |
36804 | + gdb_test "python print foo.type().template_argument(0)" $t $type | |
36805 | +} | |
36806 | + | |
36807 | +test_template_arg "const int" | |
36808 | +test_template_arg "volatile int" | |
36809 | +test_template_arg "const int &" | |
36810 | +test_template_arg "volatile int &" | |
36811 | +test_template_arg "volatile int * const" | |
36812 | +test_template_arg "volatile int * const *" | |
36813 | +test_template_arg "const int * volatile" | |
36814 | +test_template_arg "const int * volatile * const * volatile *" | |
36815 | diff --git a/gdb/testsuite/gdb.python/python-value.c b/gdb/testsuite/gdb.python/python-value.c | |
36816 | index 17e5c62..9637fe9 100644 | |
36817 | --- a/gdb/testsuite/gdb.python/python-value.c | |
36818 | +++ b/gdb/testsuite/gdb.python/python-value.c | |
36819 | @@ -33,13 +33,17 @@ enum e | |
36820 | TWO = 2 | |
36821 | }; | |
36822 | ||
36823 | +typedef struct s *PTR; | |
36824 | + | |
36825 | enum e evalue = TWO; | |
36826 | ||
36827 | int | |
36828 | main (int argc, char *argv[]) | |
36829 | { | |
36830 | + char *cp = argv[0]; /* Prevent gcc from optimizing argv[] out. */ | |
36831 | struct s s; | |
36832 | union u u; | |
36833 | + PTR x = &s; | |
36834 | ||
36835 | s.a = 3; | |
36836 | s.b = 5; | |
36837 | diff --git a/gdb/testsuite/gdb.python/python-value.exp b/gdb/testsuite/gdb.python/python-value.exp | |
36838 | index 8f5e0ab..9ca9593 100644 | |
36839 | --- a/gdb/testsuite/gdb.python/python-value.exp | |
36840 | +++ b/gdb/testsuite/gdb.python/python-value.exp | |
36841 | @@ -227,6 +227,37 @@ proc test_value_in_inferior {} { | |
36842 | gdb_test "python print arg0" "0x.*$testfile\"" "verify dereferenced value" | |
36843 | } | |
36844 | ||
36845 | +proc test_value_after_death {} { | |
36846 | + # Construct a type while the inferior is still running. | |
36847 | + gdb_py_test_silent_cmd "python ptrtype = gdb.Type('PTR')" \ | |
36848 | + "create PTR type" 1 | |
36849 | + | |
36850 | + # Check the type has the expected name. | |
36851 | + gdb_test "python print ptrtype" "PTR" \ | |
36852 | + "check initial PTR type" | |
36853 | + | |
36854 | + # Kill the inferior and remove the symbols. | |
36855 | + gdb_test "kill" "" "kill the inferior" \ | |
36856 | + "Kill the program being debugged. .y or n. $" \ | |
36857 | + "y" | |
36858 | + gdb_test "file" "" "Discard the symbols" \ | |
36859 | + "Discard symbol table from.*y or n. $" \ | |
36860 | + "y" | |
36861 | + | |
36862 | + # Now create a value using that type. Relies on arg0, created by | |
36863 | + # test_value_in_inferior. | |
36864 | + gdb_py_test_silent_cmd "python castval = arg0.cast(ptrtype.pointer())" \ | |
36865 | + "cast arg0 to PTR" 1 | |
36866 | + | |
36867 | + # Make sure the type is deleted. | |
36868 | + gdb_py_test_silent_cmd "python ptrtype = None" \ | |
36869 | + "delete PTR type" 1 | |
36870 | + | |
36871 | + # Now see if the value's type is still valid. | |
36872 | + gdb_test "python print castval.type()" "PTR \\*" \ | |
36873 | + "print value's type" | |
36874 | +} | |
36875 | + | |
36876 | ||
36877 | # Start with a fresh gdb. | |
36878 | ||
36879 | @@ -256,3 +287,4 @@ if ![runto_main] then { | |
36880 | } | |
36881 | ||
36882 | test_value_in_inferior | |
36883 | +test_value_after_death | |
36884 | diff --git a/gdb/testsuite/lib/cp-support.exp b/gdb/testsuite/lib/cp-support.exp | |
36885 | index dbd2f59..44e1b51 100644 | |
36886 | --- a/gdb/testsuite/lib/cp-support.exp | |
36887 | +++ b/gdb/testsuite/lib/cp-support.exp | |
36888 | @@ -222,7 +222,7 @@ proc cp_test_ptype_class { in_command in_testname in_key in_tag in_class_table { | |
36889 | ||
36890 | set parse_okay 0 | |
36891 | gdb_test_multiple "$in_command" "$in_testname // parse failed" { | |
36892 | - -re "type = (struct|class)${wsopt}(\[A-Za-z0-9_\]*)${wsopt}((:\[^\{\]*)?)${wsopt}\{(.*)\}${wsopt}(\[^\r\n\]*)\[\r\n\]+$gdb_prompt $" { | |
36893 | + -re "type = (struct|class)${wsopt}(\[A-Za-z0-9_:\]*)${wsopt}((:\[^\{\]*)?)${wsopt}\{(.*)\}${wsopt}(\[^\r\n\]*)\[\r\n\]+$gdb_prompt $" { | |
36894 | set parse_okay 1 | |
36895 | set actual_key $expect_out(1,string) | |
36896 | set actual_tag $expect_out(2,string) | |
36897 | @@ -231,6 +231,7 @@ proc cp_test_ptype_class { in_command in_testname in_key in_tag in_class_table { | |
36898 | set actual_tail $expect_out(6,string) | |
36899 | } | |
36900 | } | |
36901 | + | |
36902 | if { ! $parse_okay } then { return } | |
36903 | ||
36904 | # Check the actual key. It would be nice to require that it match | |
36905 | diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp | |
36906 | index 820ab20..8b8e7c6 100644 | |
36907 | --- a/gdb/testsuite/lib/gdb.exp | |
36908 | +++ b/gdb/testsuite/lib/gdb.exp | |
36909 | @@ -1162,9 +1162,12 @@ proc default_gdb_start { } { | |
36910 | global gdb_prompt | |
36911 | global timeout | |
36912 | global gdb_spawn_id; | |
36913 | + global env | |
36914 | ||
36915 | gdb_stop_suppressing_tests; | |
36916 | ||
36917 | + set env(LC_CTYPE) C | |
36918 | + | |
36919 | verbose "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS" | |
36920 | ||
36921 | if [info exists gdb_spawn_id] { | |
36922 | diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp | |
36923 | index f62c240..bda7ea1 100644 | |
36924 | --- a/gdb/testsuite/lib/mi-support.exp | |
36925 | +++ b/gdb/testsuite/lib/mi-support.exp | |
36926 | @@ -1237,6 +1237,21 @@ proc mi_varobj_update_with_type_change { name new_type new_children testname } { | |
36927 | mi_gdb_test "-var-update $name" $er $testname | |
36928 | } | |
36929 | ||
36930 | +# Update a dynamic varobj named NAME. CHILDREN is a list of children, | |
36931 | +# in the same form as mi_list_varobj_children. TESTNAME is the name | |
36932 | +# of the test. | |
36933 | +proc mi_varobj_update_dynamic {name children testname} { | |
36934 | + set children_exp_j [mi_child_regexp $children 0] | |
36935 | + | |
36936 | + set er "\\^done,changelist=\\\[" | |
36937 | + | |
36938 | + append er "{name=\"$name\",in_scope=\"true\",type_changed=\"false\"" | |
36939 | + append er ",children=\\\[$children_exp_j.*\\\]}\\\]" | |
36940 | + | |
36941 | + verbose -log "Expecting: $er" | |
36942 | + mi_gdb_test "-var-update $name" $er $testname | |
36943 | +} | |
36944 | + | |
36945 | proc mi_check_varobj_value { name value testname } { | |
36946 | ||
36947 | mi_gdb_test "-var-evaluate-expression $name" \ | |
36948 | @@ -1244,6 +1259,42 @@ proc mi_check_varobj_value { name value testname } { | |
36949 | $testname | |
36950 | } | |
36951 | ||
36952 | +# Helper proc which constructs a child regexp for | |
36953 | +# mi_list_varobj_children and mi_varobj_update_dynamic. | |
36954 | +proc mi_child_regexp {children add_child} { | |
36955 | + set children_exp {} | |
36956 | + set whatever "\"\[^\"\]+\"" | |
36957 | + | |
36958 | + if {$add_child} { | |
36959 | + set pre "child=" | |
36960 | + } else { | |
36961 | + set pre "" | |
36962 | + } | |
36963 | + | |
36964 | + foreach item $children { | |
36965 | + | |
36966 | + set name [lindex $item 0] | |
36967 | + set exp [lindex $item 1] | |
36968 | + set numchild [lindex $item 2] | |
36969 | + if {[llength $item] == 5} { | |
36970 | + set type [lindex $item 3] | |
36971 | + set value [lindex $item 4] | |
36972 | + | |
36973 | + lappend children_exp\ | |
36974 | + "$pre{name=\"$name\",exp=\"$exp\",numchild=\"$numchild\",value=\"$value\",type=\"$type\"\(,thread-id=\"\[0-9\]+\")?}" | |
36975 | + } elseif {[llength $item] == 4} { | |
36976 | + set type [lindex $item 3] | |
36977 | + | |
36978 | + lappend children_exp\ | |
36979 | + "$pre{name=\"$name\",exp=\"$exp\",numchild=\"$numchild\",type=\"$type\"\(,thread-id=\"\[0-9\]+\")?}" | |
36980 | + } else { | |
36981 | + lappend children_exp\ | |
36982 | + "$pre{name=\"$name\",exp=\"$exp\",numchild=\"$numchild\"(,thread-id=\"\[0-9\]+\")?}" | |
36983 | + } | |
36984 | + } | |
36985 | + return [join $children_exp ","] | |
36986 | +} | |
36987 | + | |
36988 | # Check the results of the: | |
36989 | # | |
36990 | # -var-list-children VARNAME | |
36991 | @@ -1265,39 +1316,23 @@ proc mi_check_varobj_value { name value testname } { | |
36992 | # have no value. | |
36993 | # | |
36994 | proc mi_list_varobj_children { varname children testname } { | |
36995 | + mi_list_varobj_children_range $varname [llength $children] $children \ | |
36996 | + $testname | |
36997 | +} | |
36998 | ||
36999 | +# Like mi_list_varobj_children, but assumes that a subrange has been | |
37000 | +# selected with -var-set-child-range. NUMCHILDREN is the total number | |
37001 | +# of children. | |
37002 | +proc mi_list_varobj_children_range {varname numchildren children testname} { | |
37003 | set options "" | |
37004 | if {[llength $varname] == 2} { | |
37005 | set options [lindex $varname 1] | |
37006 | set varname [lindex $varname 0] | |
37007 | } | |
37008 | ||
37009 | - set numchildren [llength $children] | |
37010 | - set children_exp {} | |
37011 | set whatever "\"\[^\"\]+\"" | |
37012 | ||
37013 | - foreach item $children { | |
37014 | - | |
37015 | - set name [lindex $item 0] | |
37016 | - set exp [lindex $item 1] | |
37017 | - set numchild [lindex $item 2] | |
37018 | - if {[llength $item] == 5} { | |
37019 | - set type [lindex $item 3] | |
37020 | - set value [lindex $item 4] | |
37021 | - | |
37022 | - lappend children_exp\ | |
37023 | - "child={name=\"$name\",exp=\"$exp\",numchild=\"$numchild\",value=\"$value\",type=\"$type\"\(,thread-id=\"\[0-9\]+\")?}" | |
37024 | - } elseif {[llength $item] == 4} { | |
37025 | - set type [lindex $item 3] | |
37026 | - | |
37027 | - lappend children_exp\ | |
37028 | - "child={name=\"$name\",exp=\"$exp\",numchild=\"$numchild\",type=\"$type\"\(,thread-id=\"\[0-9\]+\")?}" | |
37029 | - } else { | |
37030 | - lappend children_exp\ | |
37031 | - "child={name=\"$name\",exp=\"$exp\",numchild=\"$numchild\"(,thread-id=\"\[0-9\]+\")?}" | |
37032 | - } | |
37033 | - } | |
37034 | - set children_exp_j [join $children_exp ","] | |
37035 | + set children_exp_j [mi_child_regexp $children 1] | |
37036 | if {$numchildren} { | |
37037 | set expected "\\^done,numchild=\".*\",children=\\\[$children_exp_j.*\\\]" | |
37038 | } { | |
37039 | @@ -1770,3 +1805,25 @@ proc mi_check_thread_states { xstates test } { | |
37040 | verbose -log "expecting: $pattern" | |
37041 | mi_gdb_test "-thread-info" $pattern $test | |
37042 | } | |
37043 | + | |
37044 | +# Return a list of MI features supported by this gdb. | |
37045 | +proc mi_get_features {} { | |
37046 | + global expect_out mi_gdb_prompt | |
37047 | + | |
37048 | + send_gdb "-list-features\n" | |
37049 | + | |
37050 | + gdb_expect { | |
37051 | + -re "\\^done,features=\\\[(.*)\\\]\r\n$mi_gdb_prompt$" { | |
37052 | + regsub -all -- \" $expect_out(1,string) "" features | |
37053 | + return [split $features ,] | |
37054 | + } | |
37055 | + -re ".*\r\n$mi_gdb_prompt$" { | |
37056 | + verbose -log "got $expect_out(buffer)" | |
37057 | + return "" | |
37058 | + } | |
37059 | + timeout { | |
37060 | + verbose -log "timeout in mi_gdb_prompt" | |
37061 | + return "" | |
37062 | + } | |
37063 | + } | |
37064 | +} | |
37065 | diff --git a/gdb/thread.c b/gdb/thread.c | |
37066 | index 9dea7c2..326e44e 100644 | |
37067 | --- a/gdb/thread.c | |
37068 | +++ b/gdb/thread.c | |
37069 | @@ -61,7 +61,6 @@ static int thread_alive (struct thread_info *); | |
37070 | static void info_threads_command (char *, int); | |
37071 | static void thread_apply_command (char *, int); | |
37072 | static void restore_current_thread (ptid_t); | |
37073 | -static void prune_threads (void); | |
37074 | ||
37075 | /* Frontend view of the thread state. Possible extensions: stepping, | |
37076 | finishing, until(ling),... */ | |
37077 | @@ -459,16 +458,23 @@ thread_alive (struct thread_info *tp) | |
37078 | return 1; | |
37079 | } | |
37080 | ||
37081 | -static void | |
37082 | +void | |
37083 | prune_threads (void) | |
37084 | { | |
37085 | - struct thread_info *tp, *next; | |
37086 | + struct thread_info *tp; | |
37087 | + struct thread_info **prevp = &thread_list; | |
37088 | ||
37089 | - for (tp = thread_list; tp; tp = next) | |
37090 | + for (tp = *prevp; tp; tp = *prevp) | |
37091 | { | |
37092 | - next = tp->next; | |
37093 | + /* If the thread has died, free it and unlink it from the list. | |
37094 | + Otherwise, advance to the next thread. */ | |
37095 | if (!thread_alive (tp)) | |
37096 | - delete_thread (tp->ptid); | |
37097 | + { | |
37098 | + *prevp = tp->next; | |
37099 | + free_thread (tp); | |
37100 | + } | |
37101 | + else | |
37102 | + prevp = &tp->next; | |
37103 | } | |
37104 | } | |
37105 | ||
37106 | diff --git a/gdb/top.c b/gdb/top.c | |
37107 | index d676f02..d6b17f0 100644 | |
37108 | --- a/gdb/top.c | |
37109 | +++ b/gdb/top.c | |
37110 | @@ -377,6 +377,7 @@ execute_command (char *p, int from_tty) | |
37111 | } | |
37112 | ||
37113 | free_all_values (); | |
37114 | + free_all_types (); | |
37115 | ||
37116 | /* Force cleanup of any alloca areas if using C alloca instead of | |
37117 | a builtin alloca. */ | |
37118 | @@ -1246,7 +1247,8 @@ quit_target (void *arg) | |
37119 | struct qt_args *qt = (struct qt_args *)arg; | |
37120 | ||
37121 | /* Kill or detach all inferiors. */ | |
37122 | - iterate_over_inferiors (kill_or_detach, qt); | |
37123 | + if (target_has_execution) | |
37124 | + iterate_over_inferiors (kill_or_detach, qt); | |
37125 | ||
37126 | /* Give all pushed targets a chance to do minimal cleanup, and pop | |
37127 | them all out. */ | |
37128 | diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c | |
37129 | index 83df64e..003ef3a 100644 | |
37130 | --- a/gdb/tracepoint.c | |
37131 | +++ b/gdb/tracepoint.c | |
37132 | @@ -1587,7 +1587,7 @@ encode_actions (struct tracepoint *t, char ***tdp_actions, | |
37133 | case UNOP_MEMVAL: | |
37134 | /* safe because we know it's a simple expression */ | |
37135 | tempval = evaluate_expression (exp); | |
37136 | - addr = VALUE_ADDRESS (tempval) + value_offset (tempval); | |
37137 | + addr = value_address (tempval); | |
37138 | len = TYPE_LENGTH (check_typedef (exp->elts[1].type)); | |
37139 | add_memrange (collect, memrange_absolute, addr, len); | |
37140 | break; | |
37141 | diff --git a/gdb/typeprint.c b/gdb/typeprint.c | |
37142 | index 1f824fa..4a92a13 100644 | |
37143 | --- a/gdb/typeprint.c | |
37144 | +++ b/gdb/typeprint.c | |
37145 | @@ -35,6 +35,7 @@ | |
37146 | #include "gdb_string.h" | |
37147 | #include "exceptions.h" | |
37148 | #include "valprint.h" | |
37149 | +#include "dwarf2loc.h" | |
37150 | #include <errno.h> | |
37151 | ||
37152 | extern void _initialize_typeprint (void); | |
37153 | @@ -76,6 +77,9 @@ void | |
37154 | type_print (struct type *type, char *varstring, struct ui_file *stream, | |
37155 | int show) | |
37156 | { | |
37157 | + if (show >= 0) | |
37158 | + type = check_typedef (type); | |
37159 | + | |
37160 | LA_PRINT_TYPE (type, varstring, stream, show, 0); | |
37161 | } | |
37162 | ||
37163 | @@ -115,7 +119,8 @@ whatis_exp (char *exp, int show) | |
37164 | { | |
37165 | struct expression *expr; | |
37166 | struct value *val; | |
37167 | - struct cleanup *old_chain = NULL; | |
37168 | + /* Required at least for the object_address_set call. */ | |
37169 | + struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); | |
37170 | struct type *real_type = NULL; | |
37171 | struct type *type; | |
37172 | int full = 0; | |
37173 | @@ -126,12 +131,13 @@ whatis_exp (char *exp, int show) | |
37174 | if (exp) | |
37175 | { | |
37176 | expr = parse_expression (exp); | |
37177 | - old_chain = make_cleanup (free_current_contents, &expr); | |
37178 | + make_cleanup (free_current_contents, &expr); | |
37179 | val = evaluate_type (expr); | |
37180 | } | |
37181 | else | |
37182 | val = access_value_history (0); | |
37183 | ||
37184 | + object_address_set (VALUE_ADDRESS (val)); | |
37185 | type = value_type (val); | |
37186 | ||
37187 | get_user_print_options (&opts); | |
37188 | @@ -168,8 +174,7 @@ whatis_exp (char *exp, int show) | |
37189 | type_print (type, "", gdb_stdout, show); | |
37190 | printf_filtered ("\n"); | |
37191 | ||
37192 | - if (exp) | |
37193 | - do_cleanups (old_chain); | |
37194 | + do_cleanups (old_chain); | |
37195 | } | |
37196 | ||
37197 | static void | |
37198 | @@ -236,7 +241,7 @@ print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream) | |
37199 | break; | |
37200 | ||
37201 | case TYPE_CODE_CHAR: | |
37202 | - LA_PRINT_CHAR ((unsigned char) val, stream); | |
37203 | + LA_PRINT_CHAR ((unsigned char) val, type, stream); | |
37204 | break; | |
37205 | ||
37206 | case TYPE_CODE_BOOL: | |
37207 | diff --git a/gdb/typeprint.h b/gdb/typeprint.h | |
37208 | index f561310..b39fd17 100644 | |
37209 | --- a/gdb/typeprint.h | |
37210 | +++ b/gdb/typeprint.h | |
37211 | @@ -26,4 +26,6 @@ void print_type_scalar (struct type * type, LONGEST, struct ui_file *); | |
37212 | ||
37213 | void c_type_print_varspec_suffix (struct type *, struct ui_file *, int, | |
37214 | int, int); | |
37215 | + | |
37216 | +void c_type_print_args (struct type *, struct ui_file *, int); | |
37217 | #endif | |
37218 | diff --git a/gdb/ui-file.c b/gdb/ui-file.c | |
37219 | index 02a0314..5c8c96e 100644 | |
37220 | --- a/gdb/ui-file.c | |
37221 | +++ b/gdb/ui-file.c | |
37222 | @@ -22,6 +22,7 @@ | |
37223 | ||
37224 | #include "defs.h" | |
37225 | #include "ui-file.h" | |
37226 | +#include "gdb_obstack.h" | |
37227 | #include "gdb_string.h" | |
37228 | ||
37229 | #include <errno.h> | |
37230 | @@ -263,7 +264,7 @@ set_ui_file_data (struct ui_file *file, void *data, | |
37231 | } | |
37232 | ||
37233 | /* ui_file utility function for converting a ``struct ui_file'' into | |
37234 | - a memory buffer''. */ | |
37235 | + a memory buffer. */ | |
37236 | ||
37237 | struct accumulated_ui_file | |
37238 | { | |
37239 | @@ -297,6 +298,23 @@ ui_file_xstrdup (struct ui_file *file, | |
37240 | *length = acc.length; | |
37241 | return acc.buffer; | |
37242 | } | |
37243 | + | |
37244 | +static void | |
37245 | +do_ui_file_obsavestring (void *context, const char *buffer, long length) | |
37246 | +{ | |
37247 | + struct obstack *obstack = (struct obstack *) context; | |
37248 | + obstack_grow (obstack, buffer, length); | |
37249 | +} | |
37250 | + | |
37251 | +char * | |
37252 | +ui_file_obsavestring (struct ui_file *file, struct obstack *obstack, | |
37253 | + long *length) | |
37254 | +{ | |
37255 | + ui_file_put (file, do_ui_file_obsavestring, obstack); | |
37256 | + *length = obstack_object_size (obstack); | |
37257 | + obstack_1grow (obstack, '\0'); | |
37258 | + return obstack_finish (obstack); | |
37259 | +} | |
37260 | \f | |
37261 | /* A pure memory based ``struct ui_file'' that can be used an output | |
37262 | buffer. The buffers accumulated contents are available via | |
37263 | diff --git a/gdb/ui-file.h b/gdb/ui-file.h | |
37264 | index 1562d5a..d86a7eb 100644 | |
37265 | --- a/gdb/ui-file.h | |
37266 | +++ b/gdb/ui-file.h | |
37267 | @@ -19,6 +19,7 @@ | |
37268 | #ifndef UI_FILE_H | |
37269 | #define UI_FILE_H | |
37270 | ||
37271 | +struct obstack; | |
37272 | struct ui_file; | |
37273 | ||
37274 | /* Create a generic ui_file object with null methods. */ | |
37275 | @@ -77,7 +78,10 @@ extern void ui_file_put (struct ui_file *src, ui_file_put_method_ftype *write, v | |
37276 | appended NUL. */ | |
37277 | extern char *ui_file_xstrdup (struct ui_file *file, long *length); | |
37278 | ||
37279 | - | |
37280 | +/* Similar to ui_file_xstrdup, but return a new string allocated on | |
37281 | + OBSTACK. */ | |
37282 | +extern char *ui_file_obsavestring (struct ui_file *file, | |
37283 | + struct obstack *obstack, long *length); | |
37284 | ||
37285 | extern long ui_file_read (struct ui_file *file, char *buf, long length_buf); | |
37286 | ||
37287 | diff --git a/gdb/utils.c b/gdb/utils.c | |
37288 | index 9224839..88a9a39 100644 | |
37289 | --- a/gdb/utils.c | |
37290 | +++ b/gdb/utils.c | |
37291 | @@ -272,6 +272,19 @@ make_cleanup_fclose (FILE *file) | |
37292 | } | |
37293 | ||
37294 | static void | |
37295 | +do_obstack_free (void *arg) | |
37296 | +{ | |
37297 | + struct obstack *ob = arg; | |
37298 | + obstack_free (ob, NULL); | |
37299 | +} | |
37300 | + | |
37301 | +struct cleanup * | |
37302 | +make_cleanup_obstack_free (struct obstack *obstack) | |
37303 | +{ | |
37304 | + return make_cleanup (do_obstack_free, obstack); | |
37305 | +} | |
37306 | + | |
37307 | +static void | |
37308 | do_ui_file_delete (void *arg) | |
37309 | { | |
37310 | ui_file_delete (arg); | |
37311 | @@ -1554,21 +1567,33 @@ query (const char *ctlstr, ...) | |
37312 | va_end (args); | |
37313 | } | |
37314 | ||
37315 | -/* Print an error message saying that we couldn't make sense of a | |
37316 | - \^mumble sequence in a string or character constant. START and END | |
37317 | - indicate a substring of some larger string that contains the | |
37318 | - erroneous backslash sequence, missing the initial backslash. */ | |
37319 | -static NORETURN int | |
37320 | -no_control_char_error (const char *start, const char *end) | |
37321 | +/* A helper for parse_escape that converts a host character to a | |
37322 | + target character. C is the host character. If conversion is | |
37323 | + possible, then the target character is stored in *TARGET_C and the | |
37324 | + function returns 1. Otherwise, the function returns 0. */ | |
37325 | + | |
37326 | +static int | |
37327 | +host_char_to_target (int c, int *target_c) | |
37328 | { | |
37329 | - int len = end - start; | |
37330 | - char *copy = alloca (end - start + 1); | |
37331 | + struct obstack host_data; | |
37332 | + char the_char = c; | |
37333 | + struct cleanup *cleanups; | |
37334 | + int result = 0; | |
37335 | + | |
37336 | + obstack_init (&host_data); | |
37337 | + cleanups = make_cleanup_obstack_free (&host_data); | |
37338 | + | |
37339 | + convert_between_encodings (target_charset (), host_charset (), | |
37340 | + &the_char, 1, 1, &host_data, translit_none); | |
37341 | ||
37342 | - memcpy (copy, start, len); | |
37343 | - copy[len] = '\0'; | |
37344 | + if (obstack_object_size (&host_data) == 1) | |
37345 | + { | |
37346 | + result = 1; | |
37347 | + *target_c = *(char *) obstack_base (&host_data); | |
37348 | + } | |
37349 | ||
37350 | - error (_("There is no control character `\\%s' in the `%s' character set."), | |
37351 | - copy, target_charset ()); | |
37352 | + do_cleanups (cleanups); | |
37353 | + return result; | |
37354 | } | |
37355 | ||
37356 | /* Parse a C escape sequence. STRING_PTR points to a variable | |
37357 | @@ -1591,53 +1616,13 @@ parse_escape (char **string_ptr) | |
37358 | { | |
37359 | int target_char; | |
37360 | int c = *(*string_ptr)++; | |
37361 | - if (c_parse_backslash (c, &target_char)) | |
37362 | - return target_char; | |
37363 | - else | |
37364 | - switch (c) | |
37365 | - { | |
37366 | + switch (c) | |
37367 | + { | |
37368 | case '\n': | |
37369 | return -2; | |
37370 | case 0: | |
37371 | (*string_ptr)--; | |
37372 | return 0; | |
37373 | - case '^': | |
37374 | - { | |
37375 | - /* Remember where this escape sequence started, for reporting | |
37376 | - errors. */ | |
37377 | - char *sequence_start_pos = *string_ptr - 1; | |
37378 | - | |
37379 | - c = *(*string_ptr)++; | |
37380 | - | |
37381 | - if (c == '?') | |
37382 | - { | |
37383 | - /* XXXCHARSET: What is `delete' in the host character set? */ | |
37384 | - c = 0177; | |
37385 | - | |
37386 | - if (!host_char_to_target (c, &target_char)) | |
37387 | - error (_("There is no character corresponding to `Delete' " | |
37388 | - "in the target character set `%s'."), host_charset ()); | |
37389 | - | |
37390 | - return target_char; | |
37391 | - } | |
37392 | - else if (c == '\\') | |
37393 | - target_char = parse_escape (string_ptr); | |
37394 | - else | |
37395 | - { | |
37396 | - if (!host_char_to_target (c, &target_char)) | |
37397 | - no_control_char_error (sequence_start_pos, *string_ptr); | |
37398 | - } | |
37399 | - | |
37400 | - /* Now target_char is something like `c', and we want to find | |
37401 | - its control-character equivalent. */ | |
37402 | - if (!target_char_to_control_char (target_char, &target_char)) | |
37403 | - no_control_char_error (sequence_start_pos, *string_ptr); | |
37404 | - | |
37405 | - return target_char; | |
37406 | - } | |
37407 | - | |
37408 | - /* XXXCHARSET: we need to use isdigit and value-of-digit | |
37409 | - methods of the host character set here. */ | |
37410 | ||
37411 | case '0': | |
37412 | case '1': | |
37413 | @@ -1648,16 +1633,16 @@ parse_escape (char **string_ptr) | |
37414 | case '6': | |
37415 | case '7': | |
37416 | { | |
37417 | - int i = c - '0'; | |
37418 | + int i = host_hex_value (c); | |
37419 | int count = 0; | |
37420 | while (++count < 3) | |
37421 | { | |
37422 | c = (**string_ptr); | |
37423 | - if (c >= '0' && c <= '7') | |
37424 | + if (isdigit (c) && c != '8' && c != '9') | |
37425 | { | |
37426 | (*string_ptr)++; | |
37427 | i *= 8; | |
37428 | - i += c - '0'; | |
37429 | + i += host_hex_value (c); | |
37430 | } | |
37431 | else | |
37432 | { | |
37433 | @@ -1666,14 +1651,39 @@ parse_escape (char **string_ptr) | |
37434 | } | |
37435 | return i; | |
37436 | } | |
37437 | - default: | |
37438 | - if (!host_char_to_target (c, &target_char)) | |
37439 | - error | |
37440 | - ("The escape sequence `\%c' is equivalent to plain `%c', which" | |
37441 | - " has no equivalent\n" "in the `%s' character set.", c, c, | |
37442 | - target_charset ()); | |
37443 | - return target_char; | |
37444 | - } | |
37445 | + | |
37446 | + case 'a': | |
37447 | + c = '\a'; | |
37448 | + break; | |
37449 | + case 'b': | |
37450 | + c = '\b'; | |
37451 | + break; | |
37452 | + case 'f': | |
37453 | + c = '\f'; | |
37454 | + break; | |
37455 | + case 'n': | |
37456 | + c = '\n'; | |
37457 | + break; | |
37458 | + case 'r': | |
37459 | + c = '\r'; | |
37460 | + break; | |
37461 | + case 't': | |
37462 | + c = '\t'; | |
37463 | + break; | |
37464 | + case 'v': | |
37465 | + c = '\v'; | |
37466 | + break; | |
37467 | + | |
37468 | + default: | |
37469 | + break; | |
37470 | + } | |
37471 | + | |
37472 | + if (!host_char_to_target (c, &target_char)) | |
37473 | + error | |
37474 | + ("The escape sequence `\%c' is equivalent to plain `%c', which" | |
37475 | + " has no equivalent\n" "in the `%s' character set.", c, c, | |
37476 | + target_charset ()); | |
37477 | + return target_char; | |
37478 | } | |
37479 | \f | |
37480 | /* Print the character C on STREAM as part of the contents of a literal | |
37481 | diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c | |
37482 | index 9850de4..285fe3f 100644 | |
37483 | --- a/gdb/v850-tdep.c | |
37484 | +++ b/gdb/v850-tdep.c | |
37485 | @@ -705,7 +705,7 @@ v850_push_dummy_call (struct gdbarch *gdbarch, | |
37486 | if (!v850_type_is_scalar (value_type (*args)) | |
37487 | && TYPE_LENGTH (value_type (*args)) > E_MAX_RETTYPE_SIZE_IN_REGS) | |
37488 | { | |
37489 | - store_unsigned_integer (valbuf, 4, VALUE_ADDRESS (*args)); | |
37490 | + store_unsigned_integer (valbuf, 4, value_address (*args)); | |
37491 | len = 4; | |
37492 | val = valbuf; | |
37493 | } | |
37494 | diff --git a/gdb/valarith.c b/gdb/valarith.c | |
37495 | index f38cdb8..8e103cf 100644 | |
37496 | --- a/gdb/valarith.c | |
37497 | +++ b/gdb/valarith.c | |
37498 | @@ -164,9 +164,9 @@ an integer nor a pointer of the same type.")); | |
37499 | struct value * | |
37500 | value_subscript (struct value *array, struct value *idx) | |
37501 | { | |
37502 | - struct value *bound; | |
37503 | int c_style = current_language->c_style_arrays; | |
37504 | struct type *tarray; | |
37505 | + LONGEST index = value_as_long (idx); | |
37506 | ||
37507 | array = coerce_ref (array); | |
37508 | tarray = check_typedef (value_type (array)); | |
37509 | @@ -179,13 +179,26 @@ value_subscript (struct value *array, struct value *idx) | |
37510 | get_discrete_bounds (range_type, &lowerbound, &upperbound); | |
37511 | ||
37512 | if (VALUE_LVAL (array) != lval_memory) | |
37513 | - return value_subscripted_rvalue (array, idx, lowerbound); | |
37514 | + { | |
37515 | + if (index >= lowerbound && index <= upperbound) | |
37516 | + { | |
37517 | + CORE_ADDR element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tarray)); | |
37518 | + CORE_ADDR offset = (index - lowerbound) * element_size; | |
37519 | + | |
37520 | + return value_subscripted_rvalue (array, offset); | |
37521 | + } | |
37522 | + error (_("array or string index out of range")); | |
37523 | + } | |
37524 | ||
37525 | if (c_style == 0) | |
37526 | { | |
37527 | - LONGEST index = value_as_long (idx); | |
37528 | if (index >= lowerbound && index <= upperbound) | |
37529 | - return value_subscripted_rvalue (array, idx, lowerbound); | |
37530 | + { | |
37531 | + CORE_ADDR element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tarray)); | |
37532 | + CORE_ADDR offset = (index - lowerbound) * element_size; | |
37533 | + | |
37534 | + return value_subscripted_rvalue (array, offset); | |
37535 | + } | |
37536 | /* Emit warning unless we have an array of unknown size. | |
37537 | An array of unknown size has lowerbound 0 and upperbound -1. */ | |
37538 | if (upperbound > -1) | |
37539 | @@ -194,49 +207,52 @@ value_subscript (struct value *array, struct value *idx) | |
37540 | c_style = 1; | |
37541 | } | |
37542 | ||
37543 | - if (lowerbound != 0) | |
37544 | - { | |
37545 | - bound = value_from_longest (value_type (idx), (LONGEST) lowerbound); | |
37546 | - idx = value_binop (idx, bound, BINOP_SUB); | |
37547 | - } | |
37548 | - | |
37549 | + index -= lowerbound; | |
37550 | array = value_coerce_array (array); | |
37551 | } | |
37552 | ||
37553 | if (c_style) | |
37554 | - return value_ind (value_ptradd (array, idx)); | |
37555 | + { | |
37556 | + struct value *idx; | |
37557 | + | |
37558 | + idx = value_from_longest (builtin_type_int32, index); | |
37559 | + return value_ind (value_ptradd (array, idx)); | |
37560 | + } | |
37561 | else | |
37562 | error (_("not an array or string")); | |
37563 | } | |
37564 | ||
37565 | -/* Return the value of EXPR[IDX], expr an aggregate rvalue | |
37566 | - (eg, a vector register). This routine used to promote floats | |
37567 | - to doubles, but no longer does. */ | |
37568 | +/* Return the value of *((void *) ARRAY + ELEMENT), ARRAY an aggregate rvalue | |
37569 | + (eg, a vector register). This routine used to promote floats to doubles, | |
37570 | + but no longer does. OFFSET is zero-based with 0 for the lowermost existing | |
37571 | + element, it must be expressed in bytes (therefore multiplied by | |
37572 | + check_typedef (TYPE_TARGET_TYPE (array_type)). */ | |
37573 | ||
37574 | struct value * | |
37575 | -value_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound) | |
37576 | +value_subscripted_rvalue (struct value *array, CORE_ADDR offset) | |
37577 | { | |
37578 | struct type *array_type = check_typedef (value_type (array)); | |
37579 | struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type)); | |
37580 | - unsigned int elt_size = TYPE_LENGTH (elt_type); | |
37581 | - LONGEST index = value_as_long (idx); | |
37582 | - unsigned int elt_offs = elt_size * longest_to_int (index - lowerbound); | |
37583 | struct value *v; | |
37584 | ||
37585 | - if (index < lowerbound || elt_offs >= TYPE_LENGTH (array_type)) | |
37586 | - error (_("no such vector element")); | |
37587 | + /* Do not check TYPE_LENGTH (array_type) as we may have been given the | |
37588 | + innermost dimension of a multi-dimensional Fortran array where its length | |
37589 | + is shorter than the possibly accessed element offset. */ | |
37590 | ||
37591 | v = allocate_value (elt_type); | |
37592 | if (VALUE_LVAL (array) == lval_memory && value_lazy (array)) | |
37593 | set_value_lazy (v, 1); | |
37594 | else | |
37595 | - memcpy (value_contents_writeable (v), | |
37596 | - value_contents (array) + elt_offs, elt_size); | |
37597 | + { | |
37598 | + unsigned int elt_size = TYPE_LENGTH (elt_type); | |
37599 | + memcpy (value_contents_writeable (v), | |
37600 | + value_contents (array) + offset, elt_size); | |
37601 | + } | |
37602 | ||
37603 | set_value_component_location (v, array); | |
37604 | VALUE_REGNUM (v) = VALUE_REGNUM (array); | |
37605 | VALUE_FRAME_ID (v) = VALUE_FRAME_ID (array); | |
37606 | - set_value_offset (v, value_offset (array) + elt_offs); | |
37607 | + set_value_offset (v, value_offset (array) + offset); | |
37608 | return v; | |
37609 | } | |
37610 | ||
37611 | diff --git a/gdb/valops.c b/gdb/valops.c | |
37612 | index 9810f2b..14c562e 100644 | |
37613 | --- a/gdb/valops.c | |
37614 | +++ b/gdb/valops.c | |
37615 | @@ -38,6 +38,7 @@ | |
37616 | #include "cp-support.h" | |
37617 | #include "dfp.h" | |
37618 | #include "user-regs.h" | |
37619 | +#include "dwarf2loc.h" | |
37620 | ||
37621 | #include <errno.h> | |
37622 | #include "gdb_string.h" | |
37623 | @@ -254,9 +255,8 @@ value_cast_structs (struct type *type, struct value *v2) | |
37624 | if (v) | |
37625 | { | |
37626 | /* Downcasting is possible (t1 is superclass of v2). */ | |
37627 | - CORE_ADDR addr2 = VALUE_ADDRESS (v2); | |
37628 | - addr2 -= (VALUE_ADDRESS (v) | |
37629 | - + value_offset (v) | |
37630 | + CORE_ADDR addr2 = value_address (v2); | |
37631 | + addr2 -= (value_address (v) | |
37632 | + value_embedded_offset (v)); | |
37633 | return value_at (type, addr2); | |
37634 | } | |
37635 | @@ -371,8 +371,6 @@ value_cast (struct type *type, struct value *arg2) | |
37636 | new_length = val_length / element_length; | |
37637 | if (val_length % element_length != 0) | |
37638 | warning (_("array element type size does not divide object size in cast")); | |
37639 | - /* FIXME-type-allocation: need a way to free this type when | |
37640 | - we are done with it. */ | |
37641 | range_type = create_range_type ((struct type *) NULL, | |
37642 | TYPE_TARGET_TYPE (range_type), | |
37643 | low_bound, | |
37644 | @@ -511,7 +509,7 @@ value_cast (struct type *type, struct value *arg2) | |
37645 | } | |
37646 | else if (VALUE_LVAL (arg2) == lval_memory) | |
37647 | return value_at_lazy (type, | |
37648 | - VALUE_ADDRESS (arg2) + value_offset (arg2)); | |
37649 | + value_address (arg2)); | |
37650 | else if (code1 == TYPE_CODE_VOID) | |
37651 | { | |
37652 | return value_zero (builtin_type_void, not_lval); | |
37653 | @@ -568,6 +566,64 @@ value_one (struct type *type, enum lval_type lv) | |
37654 | return val; | |
37655 | } | |
37656 | ||
37657 | +/* object_address_set must be already called before this function. */ | |
37658 | + | |
37659 | +const char * | |
37660 | +object_address_data_not_valid (struct type *type) | |
37661 | +{ | |
37662 | + /* Attributes are present only at the target type of a typedef. Make the | |
37663 | + call conditional as it would otherwise loop through type_length_get. */ | |
37664 | + if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) | |
37665 | + CHECK_TYPEDEF (type); | |
37666 | + | |
37667 | + /* DW_AT_associated has a preference over DW_AT_allocated. */ | |
37668 | + if (TYPE_NOT_ASSOCIATED (type) | |
37669 | + || (TYPE_ASSOCIATED (type) != NULL | |
37670 | + && 0 == dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (type)))) | |
37671 | + return N_("object is not associated"); | |
37672 | + | |
37673 | + if (TYPE_NOT_ALLOCATED (type) | |
37674 | + || (TYPE_ALLOCATED (type) != NULL | |
37675 | + && 0 == dwarf_locexpr_baton_eval (TYPE_ALLOCATED (type)))) | |
37676 | + return N_("object is not allocated"); | |
37677 | + | |
37678 | + return NULL; | |
37679 | +} | |
37680 | + | |
37681 | +/* Return non-zero if the variable is valid. If it is valid the function | |
37682 | + may store the data address (DW_AT_DATA_LOCATION) of TYPE at *ADDRESS_RETURN. | |
37683 | + You must set *ADDRESS_RETURN as VALUE_ADDRESS (VAL) before calling this | |
37684 | + function. If no DW_AT_DATA_LOCATION is present for TYPE the address at | |
37685 | + *ADDRESS_RETURN is left unchanged. ADDRESS_RETURN must not be NULL, use | |
37686 | + object_address_data_not_valid () for just the data validity check. */ | |
37687 | + | |
37688 | +int | |
37689 | +object_address_get_data (struct type *type, CORE_ADDR *address_return) | |
37690 | +{ | |
37691 | + gdb_assert (address_return != NULL); | |
37692 | + | |
37693 | + object_address_set (*address_return); | |
37694 | + | |
37695 | + /* TYPE_DATA_LOCATION_DWARF_BLOCK / TYPE_DATA_LOCATION_ADDR are present only | |
37696 | + at the target type of a typedef. */ | |
37697 | + CHECK_TYPEDEF (type); | |
37698 | + | |
37699 | + if (object_address_data_not_valid (type) != NULL) | |
37700 | + { | |
37701 | + /* Do not try to evaluate DW_AT_data_location as it may even crash | |
37702 | + (it would just return the value zero in the gfortran case). */ | |
37703 | + return 0; | |
37704 | + } | |
37705 | + | |
37706 | + if (TYPE_DATA_LOCATION_IS_ADDR (type)) | |
37707 | + *address_return = TYPE_DATA_LOCATION_ADDR (type); | |
37708 | + else if (TYPE_DATA_LOCATION_DWARF_BLOCK (type) != NULL) | |
37709 | + *address_return | |
37710 | + = dwarf_locexpr_baton_eval (TYPE_DATA_LOCATION_DWARF_BLOCK (type)); | |
37711 | + | |
37712 | + return 1; | |
37713 | +} | |
37714 | + | |
37715 | /* Return a value with type TYPE located at ADDR. | |
37716 | ||
37717 | Call value_at only if the data needs to be fetched immediately; | |
37718 | @@ -593,7 +649,7 @@ value_at (struct type *type, CORE_ADDR addr) | |
37719 | read_memory (addr, value_contents_all_raw (val), TYPE_LENGTH (type)); | |
37720 | ||
37721 | VALUE_LVAL (val) = lval_memory; | |
37722 | - VALUE_ADDRESS (val) = addr; | |
37723 | + set_value_address (val, addr); | |
37724 | ||
37725 | return val; | |
37726 | } | |
37727 | @@ -611,7 +667,7 @@ value_at_lazy (struct type *type, CORE_ADDR addr) | |
37728 | val = allocate_value_lazy (type); | |
37729 | ||
37730 | VALUE_LVAL (val) = lval_memory; | |
37731 | - VALUE_ADDRESS (val) = addr; | |
37732 | + set_value_address (val, addr); | |
37733 | ||
37734 | return val; | |
37735 | } | |
37736 | @@ -637,11 +693,19 @@ value_fetch_lazy (struct value *val) | |
37737 | allocate_value_contents (val); | |
37738 | if (VALUE_LVAL (val) == lval_memory) | |
37739 | { | |
37740 | - CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val); | |
37741 | - int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val))); | |
37742 | + CORE_ADDR addr = VALUE_ADDRESS (val); | |
37743 | + | |
37744 | + if (object_address_get_data (value_type (val), &addr)) | |
37745 | + { | |
37746 | + struct type *type = value_enclosing_type (val); | |
37747 | + int length = TYPE_LENGTH (check_typedef (type)); | |
37748 | ||
37749 | - if (length) | |
37750 | - read_memory (addr, value_contents_all_raw (val), length); | |
37751 | + if (length) | |
37752 | + { | |
37753 | + addr += value_offset (val); | |
37754 | + read_memory (addr, value_contents_all_raw (val), length); | |
37755 | + } | |
37756 | + } | |
37757 | } | |
37758 | else if (VALUE_LVAL (val) == lval_register) | |
37759 | { | |
37760 | @@ -709,7 +773,7 @@ value_fetch_lazy (struct value *val) | |
37761 | VALUE_REGNUM (new_val)); | |
37762 | else if (VALUE_LVAL (new_val) == lval_memory) | |
37763 | fprintf_unfiltered (gdb_stdlog, " address=0x%s", | |
37764 | - paddr_nz (VALUE_ADDRESS (new_val))); | |
37765 | + paddr_nz (value_address (new_val))); | |
37766 | else | |
37767 | fprintf_unfiltered (gdb_stdlog, " computed"); | |
37768 | ||
37769 | @@ -813,16 +877,15 @@ value_assign (struct value *toval, struct value *fromval) | |
37770 | error (_("Can't handle bitfields which don't fit in a %d bit word."), | |
37771 | (int) sizeof (LONGEST) * HOST_CHAR_BIT); | |
37772 | ||
37773 | - read_memory (VALUE_ADDRESS (toval) + value_offset (toval), | |
37774 | - buffer, changed_len); | |
37775 | + read_memory (value_address (toval), buffer, changed_len); | |
37776 | modify_field (buffer, value_as_long (fromval), | |
37777 | value_bitpos (toval), value_bitsize (toval)); | |
37778 | - changed_addr = VALUE_ADDRESS (toval) + value_offset (toval); | |
37779 | + changed_addr = value_address (toval); | |
37780 | dest_buffer = buffer; | |
37781 | } | |
37782 | else | |
37783 | { | |
37784 | - changed_addr = VALUE_ADDRESS (toval) + value_offset (toval); | |
37785 | + changed_addr = value_address (toval); | |
37786 | changed_len = TYPE_LENGTH (type); | |
37787 | dest_buffer = value_contents (fromval); | |
37788 | } | |
37789 | @@ -985,11 +1048,11 @@ value_repeat (struct value *arg1, int count) | |
37790 | ||
37791 | val = allocate_repeat_value (value_enclosing_type (arg1), count); | |
37792 | ||
37793 | - read_memory (VALUE_ADDRESS (arg1) + value_offset (arg1), | |
37794 | + read_memory (value_address (arg1), | |
37795 | value_contents_all_raw (val), | |
37796 | TYPE_LENGTH (value_enclosing_type (val))); | |
37797 | VALUE_LVAL (val) = lval_memory; | |
37798 | - VALUE_ADDRESS (val) = VALUE_ADDRESS (arg1) + value_offset (arg1); | |
37799 | + set_value_address (val, value_address (arg1)); | |
37800 | ||
37801 | return val; | |
37802 | } | |
37803 | @@ -1036,10 +1099,11 @@ address_of_variable (struct symbol *var, struct block *b) | |
37804 | ||
37805 | val = value_of_variable (var, b); | |
37806 | ||
37807 | - if ((VALUE_LVAL (val) == lval_memory && value_lazy (val)) | |
37808 | + if ((VALUE_LVAL (val) == lval_memory && value_lazy (val) | |
37809 | + && object_address_get_data (type, &VALUE_ADDRESS (val))) | |
37810 | || TYPE_CODE (type) == TYPE_CODE_FUNC) | |
37811 | { | |
37812 | - CORE_ADDR addr = VALUE_ADDRESS (val); | |
37813 | + CORE_ADDR addr = value_address (val); | |
37814 | return value_from_pointer (lookup_pointer_type (type), addr); | |
37815 | } | |
37816 | ||
37817 | @@ -1145,6 +1209,7 @@ struct value * | |
37818 | value_coerce_array (struct value *arg1) | |
37819 | { | |
37820 | struct type *type = check_typedef (value_type (arg1)); | |
37821 | + CORE_ADDR address; | |
37822 | ||
37823 | /* If the user tries to do something requiring a pointer with an | |
37824 | array that has not yet been pushed to the target, then this would | |
37825 | @@ -1154,8 +1219,12 @@ value_coerce_array (struct value *arg1) | |
37826 | if (VALUE_LVAL (arg1) != lval_memory) | |
37827 | error (_("Attempt to take address of value not located in memory.")); | |
37828 | ||
37829 | + address = VALUE_ADDRESS (arg1); | |
37830 | + if (!object_address_get_data (type, &address)) | |
37831 | + error (_("Attempt to take address of non-valid value.")); | |
37832 | + | |
37833 | return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)), | |
37834 | - (VALUE_ADDRESS (arg1) + value_offset (arg1))); | |
37835 | + address + value_offset (arg1)); | |
37836 | } | |
37837 | ||
37838 | /* Given a value which is a function, return a value which is a pointer | |
37839 | @@ -1170,7 +1239,7 @@ value_coerce_function (struct value *arg1) | |
37840 | error (_("Attempt to take address of value not located in memory.")); | |
37841 | ||
37842 | retval = value_from_pointer (lookup_pointer_type (value_type (arg1)), | |
37843 | - (VALUE_ADDRESS (arg1) + value_offset (arg1))); | |
37844 | + (value_address (arg1))); | |
37845 | return retval; | |
37846 | } | |
37847 | ||
37848 | @@ -1205,8 +1274,7 @@ value_addr (struct value *arg1) | |
37849 | ||
37850 | /* Get target memory address */ | |
37851 | arg2 = value_from_pointer (lookup_pointer_type (value_type (arg1)), | |
37852 | - (VALUE_ADDRESS (arg1) | |
37853 | - + value_offset (arg1) | |
37854 | + (value_address (arg1) | |
37855 | + value_embedded_offset (arg1))); | |
37856 | ||
37857 | /* This may be a pointer to a base subobject; so remember the | |
37858 | @@ -1352,6 +1420,24 @@ value_array (int lowbound, int highbound, struct value **elemvec) | |
37859 | return val; | |
37860 | } | |
37861 | ||
37862 | +struct value * | |
37863 | +value_typed_string (char *ptr, int len, struct type *char_type) | |
37864 | +{ | |
37865 | + struct value *val; | |
37866 | + int lowbound = current_language->string_lower_bound; | |
37867 | + int highbound = len / TYPE_LENGTH (char_type); | |
37868 | + struct type *rangetype = create_range_type ((struct type *) NULL, | |
37869 | + builtin_type_int32, | |
37870 | + lowbound, | |
37871 | + highbound + lowbound - 1); | |
37872 | + struct type *stringtype | |
37873 | + = create_array_type ((struct type *) NULL, char_type, rangetype); | |
37874 | + | |
37875 | + val = allocate_value (stringtype); | |
37876 | + memcpy (value_contents_raw (val), ptr, len); | |
37877 | + return val; | |
37878 | +} | |
37879 | + | |
37880 | /* Create a value for a string constant by allocating space in the | |
37881 | inferior, copying the data into that space, and returning the | |
37882 | address with type TYPE_CODE_STRING. PTR points to the string | |
37883 | @@ -1600,8 +1686,7 @@ search_struct_field (char *name, struct value *arg1, int offset, | |
37884 | ||
37885 | boffset = baseclass_offset (type, i, | |
37886 | value_contents (arg1) + offset, | |
37887 | - VALUE_ADDRESS (arg1) | |
37888 | - + value_offset (arg1) + offset); | |
37889 | + value_address (arg1) + offset); | |
37890 | if (boffset == -1) | |
37891 | error (_("virtual baseclass botch")); | |
37892 | ||
37893 | @@ -1616,13 +1701,13 @@ search_struct_field (char *name, struct value *arg1, int offset, | |
37894 | ||
37895 | v2 = allocate_value (basetype); | |
37896 | base_addr = | |
37897 | - VALUE_ADDRESS (arg1) + value_offset (arg1) + boffset; | |
37898 | + value_address (arg1) + boffset; | |
37899 | if (target_read_memory (base_addr, | |
37900 | value_contents_raw (v2), | |
37901 | TYPE_LENGTH (basetype)) != 0) | |
37902 | error (_("virtual baseclass botch")); | |
37903 | VALUE_LVAL (v2) = lval_memory; | |
37904 | - VALUE_ADDRESS (v2) = base_addr; | |
37905 | + set_value_address (v2, base_addr); | |
37906 | } | |
37907 | else | |
37908 | { | |
37909 | @@ -1745,8 +1830,7 @@ search_struct_method (char *name, struct value **arg1p, | |
37910 | if (offset < 0 || offset >= TYPE_LENGTH (type)) | |
37911 | { | |
37912 | gdb_byte *tmp = alloca (TYPE_LENGTH (baseclass)); | |
37913 | - if (target_read_memory (VALUE_ADDRESS (*arg1p) | |
37914 | - + value_offset (*arg1p) + offset, | |
37915 | + if (target_read_memory (value_address (*arg1p) + offset, | |
37916 | tmp, TYPE_LENGTH (baseclass)) != 0) | |
37917 | error (_("virtual baseclass botch")); | |
37918 | base_valaddr = tmp; | |
37919 | @@ -1755,8 +1839,7 @@ search_struct_method (char *name, struct value **arg1p, | |
37920 | base_valaddr = value_contents (*arg1p) + offset; | |
37921 | ||
37922 | base_offset = baseclass_offset (type, i, base_valaddr, | |
37923 | - VALUE_ADDRESS (*arg1p) | |
37924 | - + value_offset (*arg1p) + offset); | |
37925 | + value_address (*arg1p) + offset); | |
37926 | if (base_offset == -1) | |
37927 | error (_("virtual baseclass botch")); | |
37928 | } | |
37929 | @@ -1965,7 +2048,7 @@ find_method_list (struct value **argp, char *method, | |
37930 | base_offset = value_offset (*argp) + offset; | |
37931 | base_offset = baseclass_offset (type, i, | |
37932 | value_contents (*argp) + base_offset, | |
37933 | - VALUE_ADDRESS (*argp) + base_offset); | |
37934 | + value_address (*argp) + base_offset); | |
37935 | if (base_offset == -1) | |
37936 | error (_("virtual baseclass botch")); | |
37937 | } | |
37938 | @@ -2083,12 +2166,25 @@ find_overload_match (struct type **arg_types, int nargs, | |
37939 | if (method) | |
37940 | { | |
37941 | gdb_assert (obj); | |
37942 | + | |
37943 | + /* OBJ may be a pointer value rather than the object itself. */ | |
37944 | + obj = coerce_ref (obj); | |
37945 | + while (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_PTR) | |
37946 | + obj = coerce_ref (value_ind (obj)); | |
37947 | obj_type_name = TYPE_NAME (value_type (obj)); | |
37948 | - /* Hack: evaluate_subexp_standard often passes in a pointer | |
37949 | - value rather than the object itself, so try again. */ | |
37950 | - if ((!obj_type_name || !*obj_type_name) | |
37951 | - && (TYPE_CODE (value_type (obj)) == TYPE_CODE_PTR)) | |
37952 | - obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (value_type (obj))); | |
37953 | + | |
37954 | + /* First check whether this is a data member, e.g. a pointer to | |
37955 | + a function. */ | |
37956 | + if (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_STRUCT) | |
37957 | + { | |
37958 | + *valp = search_struct_field (name, obj, 0, | |
37959 | + check_typedef (value_type (obj)), 0); | |
37960 | + if (*valp) | |
37961 | + { | |
37962 | + *staticp = 1; | |
37963 | + return 0; | |
37964 | + } | |
37965 | + } | |
37966 | ||
37967 | fns_ptr = value_find_oload_method_list (&temp, name, | |
37968 | 0, &num_fns, | |
37969 | @@ -2108,16 +2204,29 @@ find_overload_match (struct type **arg_types, int nargs, | |
37970 | } | |
37971 | else | |
37972 | { | |
37973 | - const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym); | |
37974 | + const char *qualified_name = SYMBOL_NATURAL_NAME (fsym); | |
37975 | ||
37976 | - /* If we have a C++ name, try to extract just the function | |
37977 | - part. */ | |
37978 | - if (qualified_name) | |
37979 | - func_name = cp_func_name (qualified_name); | |
37980 | + /* If we have a function with a C++ name, try to extract just | |
37981 | + the function part. Do not try this for non-functions (e.g. | |
37982 | + function pointers). */ | |
37983 | + if (qualified_name | |
37984 | + && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC) | |
37985 | + { | |
37986 | + func_name = cp_func_name (qualified_name); | |
37987 | + | |
37988 | + /* If cp_func_name did not remove anything, the name of the | |
37989 | + symbol did not include scope or argument types - it was | |
37990 | + probably a C-style function. */ | |
37991 | + if (func_name && strcmp (func_name, qualified_name) == 0) | |
37992 | + { | |
37993 | + xfree (func_name); | |
37994 | + func_name = NULL; | |
37995 | + } | |
37996 | + } | |
37997 | ||
37998 | - /* If there was no C++ name, this must be a C-style function. | |
37999 | - Just return the same symbol. Do the same if cp_func_name | |
38000 | - fails for some reason. */ | |
38001 | + /* If there was no C++ name, this must be a C-style function or | |
38002 | + not a function at all. Just return the same symbol. Do the | |
38003 | + same if cp_func_name fails for some reason. */ | |
38004 | if (func_name == NULL) | |
38005 | { | |
38006 | *symp = fsym; | |
38007 | @@ -2558,8 +2667,8 @@ check_field (struct type *type, const char *name) | |
38008 | the comment before value_struct_elt_for_reference. */ | |
38009 | ||
38010 | struct value * | |
38011 | -value_aggregate_elt (struct type *curtype, | |
38012 | - char *name, int want_address, | |
38013 | +value_aggregate_elt (struct type *curtype, char *name, | |
38014 | + struct type *expect_type, int want_address, | |
38015 | enum noside noside) | |
38016 | { | |
38017 | switch (TYPE_CODE (curtype)) | |
38018 | @@ -2567,7 +2676,7 @@ value_aggregate_elt (struct type *curtype, | |
38019 | case TYPE_CODE_STRUCT: | |
38020 | case TYPE_CODE_UNION: | |
38021 | return value_struct_elt_for_reference (curtype, 0, curtype, | |
38022 | - name, NULL, | |
38023 | + name, expect_type, | |
38024 | want_address, noside); | |
38025 | case TYPE_CODE_NAMESPACE: | |
38026 | return value_namespace_elt (curtype, name, | |
38027 | @@ -2671,7 +2780,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, | |
38028 | if (intype) | |
38029 | { | |
38030 | while (j--) | |
38031 | - if (TYPE_FN_FIELD_TYPE (f, j) == intype) | |
38032 | + if (compare_parameters (TYPE_FN_FIELD_TYPE (f, j), intype)) | |
38033 | break; | |
38034 | if (j < 0) | |
38035 | error (_("no member function matches that type instantiation")); | |
38036 | @@ -2725,7 +2834,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, | |
38037 | result = allocate_value (lookup_methodptr_type (TYPE_FN_FIELD_TYPE (f, j))); | |
38038 | cplus_make_method_ptr (value_type (result), | |
38039 | value_contents_writeable (result), | |
38040 | - VALUE_ADDRESS (v), 0); | |
38041 | + value_address (v), 0); | |
38042 | } | |
38043 | } | |
38044 | return result; | |
38045 | @@ -2791,7 +2900,7 @@ value_maybe_namespace_elt (const struct type *curtype, | |
38046 | struct symbol *sym; | |
38047 | struct value *result; | |
38048 | ||
38049 | - sym = cp_lookup_symbol_namespace (namespace_name, name, NULL, | |
38050 | + sym = cp_lookup_symbol_namespace_incremental (namespace_name, name, NULL, | |
38051 | get_selected_block (0), | |
38052 | VAR_DOMAIN); | |
38053 | ||
38054 | @@ -2884,7 +2993,7 @@ value_full_object (struct value *argp, | |
38055 | /* Go back by the computed top_offset from the beginning of the | |
38056 | object, adjusting for the embedded offset of argp if that's what | |
38057 | value_rtti_type used for its computation. */ | |
38058 | - new_val = value_at_lazy (real_type, VALUE_ADDRESS (argp) - top + | |
38059 | + new_val = value_at_lazy (real_type, value_address (argp) - top + | |
38060 | (using_enc ? 0 : value_embedded_offset (argp))); | |
38061 | deprecated_set_value_type (new_val, value_type (argp)); | |
38062 | set_value_embedded_offset (new_val, (using_enc | |
38063 | @@ -2989,8 +3098,6 @@ value_slice (struct value *array, int lowbound, int length) | |
38064 | || lowbound + length - 1 > upperbound) | |
38065 | error (_("slice out of range")); | |
38066 | ||
38067 | - /* FIXME-type-allocation: need a way to free this type when we are | |
38068 | - done with it. */ | |
38069 | slice_range_type = create_range_type ((struct type *) NULL, | |
38070 | TYPE_TARGET_TYPE (range_type), | |
38071 | lowbound, | |
38072 | diff --git a/gdb/valprint.c b/gdb/valprint.c | |
38073 | index b02e9df..a9e8227 100644 | |
38074 | --- a/gdb/valprint.c | |
38075 | +++ b/gdb/valprint.c | |
38076 | @@ -34,6 +34,7 @@ | |
38077 | #include "doublest.h" | |
38078 | #include "exceptions.h" | |
38079 | #include "dfp.h" | |
38080 | +#include "python/python.h" | |
38081 | ||
38082 | #include <errno.h> | |
38083 | ||
38084 | @@ -80,7 +81,9 @@ struct value_print_options user_print_options = | |
38085 | 0, /* print_array_indexes */ | |
38086 | 0, /* deref_ref */ | |
38087 | 1, /* static_field_print */ | |
38088 | - 1 /* pascal_static_field_print */ | |
38089 | + 1, /* pascal_static_field_print */ | |
38090 | + 0, /* raw */ | |
38091 | + 0 /* summary */ | |
38092 | }; | |
38093 | ||
38094 | /* Initialize *OPTS to be a copy of the user print options. */ | |
38095 | @@ -257,6 +260,15 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, | |
38096 | return (0); | |
38097 | } | |
38098 | ||
38099 | + if (!options->raw) | |
38100 | + { | |
38101 | + ret = apply_val_pretty_printer (type, valaddr, embedded_offset, | |
38102 | + address, stream, recurse, options, | |
38103 | + language); | |
38104 | + if (ret) | |
38105 | + return ret; | |
38106 | + } | |
38107 | + | |
38108 | TRY_CATCH (except, RETURN_MASK_ERROR) | |
38109 | { | |
38110 | ret = language->la_val_print (type, valaddr, embedded_offset, address, | |
38111 | @@ -287,6 +299,13 @@ value_check_printable (struct value *val, struct ui_file *stream) | |
38112 | return 0; | |
38113 | } | |
38114 | ||
38115 | + if (TYPE_CODE (value_type (val)) == TYPE_CODE_INTERNAL_FUNCTION) | |
38116 | + { | |
38117 | + fprintf_filtered (stream, _("<internal function %s>"), | |
38118 | + value_internal_function_name (val)); | |
38119 | + return 0; | |
38120 | + } | |
38121 | + | |
38122 | return 1; | |
38123 | } | |
38124 | ||
38125 | @@ -308,7 +327,7 @@ common_val_print (struct value *val, struct ui_file *stream, int recurse, | |
38126 | return 0; | |
38127 | ||
38128 | return val_print (value_type (val), value_contents_all (val), | |
38129 | - value_embedded_offset (val), VALUE_ADDRESS (val), | |
38130 | + value_embedded_offset (val), value_address (val), | |
38131 | stream, recurse, options, language); | |
38132 | } | |
38133 | ||
38134 | @@ -324,6 +343,18 @@ value_print (struct value *val, struct ui_file *stream, | |
38135 | if (!value_check_printable (val, stream)) | |
38136 | return 0; | |
38137 | ||
38138 | + if (!options->raw) | |
38139 | + { | |
38140 | + int r = apply_val_pretty_printer (value_type (val), | |
38141 | + value_contents_all (val), | |
38142 | + value_embedded_offset (val), | |
38143 | + value_address (val), | |
38144 | + stream, 0, options, | |
38145 | + current_language); | |
38146 | + if (r) | |
38147 | + return r; | |
38148 | + } | |
38149 | + | |
38150 | return LA_VALUE_PRINT (val, stream, options); | |
38151 | } | |
38152 | ||
38153 | @@ -919,7 +950,8 @@ print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr, | |
38154 | Omit any leading zero chars. */ | |
38155 | ||
38156 | void | |
38157 | -print_char_chars (struct ui_file *stream, const gdb_byte *valaddr, | |
38158 | +print_char_chars (struct ui_file *stream, struct type *type, | |
38159 | + const gdb_byte *valaddr, | |
38160 | unsigned len, enum bfd_endian byte_order) | |
38161 | { | |
38162 | const gdb_byte *p; | |
38163 | @@ -932,7 +964,7 @@ print_char_chars (struct ui_file *stream, const gdb_byte *valaddr, | |
38164 | ||
38165 | while (p < valaddr + len) | |
38166 | { | |
38167 | - LA_EMIT_CHAR (*p, stream, '\''); | |
38168 | + LA_EMIT_CHAR (*p, type, stream, '\''); | |
38169 | ++p; | |
38170 | } | |
38171 | } | |
38172 | @@ -944,7 +976,7 @@ print_char_chars (struct ui_file *stream, const gdb_byte *valaddr, | |
38173 | ||
38174 | while (p >= valaddr) | |
38175 | { | |
38176 | - LA_EMIT_CHAR (*p, stream, '\''); | |
38177 | + LA_EMIT_CHAR (*p, type, stream, '\''); | |
38178 | --p; | |
38179 | } | |
38180 | } | |
38181 | @@ -1085,6 +1117,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr, | |
38182 | ||
38183 | for (; i < len && things_printed < options->print_max; i++) | |
38184 | { | |
38185 | + size_t elt_offset = i * eltlen; | |
38186 | if (i != 0) | |
38187 | { | |
38188 | if (options->prettyprint_arrays) | |
38189 | @@ -1104,7 +1137,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr, | |
38190 | rep1 = i + 1; | |
38191 | reps = 1; | |
38192 | while ((rep1 < len) && | |
38193 | - !memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen)) | |
38194 | + !memcmp (valaddr + elt_offset, valaddr + rep1 * eltlen, eltlen)) | |
38195 | { | |
38196 | ++reps; | |
38197 | ++rep1; | |
38198 | @@ -1112,7 +1145,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr, | |
38199 | ||
38200 | if (reps > options->repeat_count_threshold) | |
38201 | { | |
38202 | - val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen, | |
38203 | + val_print (elttype, valaddr + elt_offset, 0, address + elt_offset, | |
38204 | stream, recurse + 1, options, current_language); | |
38205 | annotate_elt_rep (reps); | |
38206 | fprintf_filtered (stream, " <repeats %u times>", reps); | |
38207 | @@ -1123,7 +1156,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr, | |
38208 | } | |
38209 | else | |
38210 | { | |
38211 | - val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen, | |
38212 | + val_print (elttype, valaddr + elt_offset, 0, address + elt_offset, | |
38213 | stream, recurse + 1, options, current_language); | |
38214 | annotate_elt (); | |
38215 | things_printed++; | |
38216 | @@ -1315,7 +1348,8 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, | |
38217 | whichever is smaller. */ | |
38218 | ||
38219 | int | |
38220 | -val_print_string (CORE_ADDR addr, int len, int width, struct ui_file *stream, | |
38221 | +val_print_string (struct type *elttype, CORE_ADDR addr, int len, | |
38222 | + struct ui_file *stream, | |
38223 | const struct value_print_options *options) | |
38224 | { | |
38225 | int force_ellipsis = 0; /* Force ellipsis to be printed if nonzero. */ | |
38226 | @@ -1325,6 +1359,7 @@ val_print_string (CORE_ADDR addr, int len, int width, struct ui_file *stream, | |
38227 | int bytes_read; | |
38228 | gdb_byte *buffer = NULL; /* Dynamically growable fetch buffer. */ | |
38229 | struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */ | |
38230 | + int width = TYPE_LENGTH (elttype); | |
38231 | ||
38232 | /* First we need to figure out the limit on the number of characters we are | |
38233 | going to attempt to fetch and print. This is actually pretty simple. If | |
38234 | @@ -1378,7 +1413,7 @@ val_print_string (CORE_ADDR addr, int len, int width, struct ui_file *stream, | |
38235 | { | |
38236 | fputs_filtered (" ", stream); | |
38237 | } | |
38238 | - LA_PRINT_STRING (stream, buffer, bytes_read / width, width, force_ellipsis, options); | |
38239 | + LA_PRINT_STRING (stream, elttype, buffer, bytes_read / width, force_ellipsis, options); | |
38240 | } | |
38241 | ||
38242 | if (errcode != 0) | |
38243 | diff --git a/gdb/valprint.h b/gdb/valprint.h | |
38244 | index 8b65af6..4f63fa6 100644 | |
38245 | --- a/gdb/valprint.h | |
38246 | +++ b/gdb/valprint.h | |
38247 | @@ -84,6 +84,12 @@ struct value_print_options | |
38248 | /* If nonzero, print static fields for Pascal. FIXME: C++ and Java | |
38249 | share one flag, why not Pascal too? */ | |
38250 | int pascal_static_field_print; | |
38251 | + | |
38252 | + /* Controls Python pretty-printing. */ | |
38253 | + int raw; | |
38254 | + | |
38255 | + /* If nonzero, print the value in "summary" form. */ | |
38256 | + int summary; | |
38257 | }; | |
38258 | ||
38259 | /* The global print options set by the user. In general this should | |
38260 | @@ -134,9 +140,10 @@ extern void print_decimal_chars (struct ui_file *, const gdb_byte *, | |
38261 | extern void print_hex_chars (struct ui_file *, const gdb_byte *, | |
38262 | unsigned int, enum bfd_endian); | |
38263 | ||
38264 | -extern void print_char_chars (struct ui_file *, const gdb_byte *, | |
38265 | - unsigned int, enum bfd_endian); | |
38266 | +extern void print_char_chars (struct ui_file *, struct type *, | |
38267 | + const gdb_byte *, unsigned int, enum bfd_endian); | |
38268 | ||
38269 | int read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, | |
38270 | gdb_byte **buffer, int *bytes_read); | |
38271 | + | |
38272 | #endif | |
38273 | diff --git a/gdb/value.c b/gdb/value.c | |
38274 | index 4d4329e..5c81d83 100644 | |
38275 | --- a/gdb/value.c | |
38276 | +++ b/gdb/value.c | |
38277 | @@ -36,6 +36,7 @@ | |
38278 | #include "block.h" | |
38279 | #include "dfp.h" | |
38280 | #include "objfiles.h" | |
38281 | +#include "cli/cli-decode.h" | |
38282 | #include "valprint.h" | |
38283 | ||
38284 | #include "python/python.h" | |
38285 | @@ -44,6 +45,23 @@ | |
38286 | ||
38287 | void _initialize_values (void); | |
38288 | ||
38289 | +/* Definition of a user function. */ | |
38290 | +struct internal_function | |
38291 | +{ | |
38292 | + /* The name of the function. It is a bit odd to have this in the | |
38293 | + function itself -- the user might use a differently-named | |
38294 | + convenience variable to hold the function. */ | |
38295 | + char *name; | |
38296 | + | |
38297 | + /* The handler. */ | |
38298 | + internal_function_fn handler; | |
38299 | + | |
38300 | + /* User data for the handler. */ | |
38301 | + void *cookie; | |
38302 | +}; | |
38303 | + | |
38304 | +static struct cmd_list_element *functionlist; | |
38305 | + | |
38306 | struct value | |
38307 | { | |
38308 | /* Type of value; either not an lval, or one of the various | |
38309 | @@ -203,6 +221,10 @@ struct value_history_chunk | |
38310 | static struct value_history_chunk *value_history_chain; | |
38311 | ||
38312 | static int value_history_count; /* Abs number of last entry stored */ | |
38313 | + | |
38314 | +/* The type of internal functions. */ | |
38315 | + | |
38316 | +static struct type *internal_fn_type; | |
38317 | \f | |
38318 | /* List of all value objects currently allocated | |
38319 | (except for those released by calls to release_value) | |
38320 | @@ -225,9 +247,11 @@ allocate_value_lazy (struct type *type) | |
38321 | val->next = all_values; | |
38322 | all_values = val; | |
38323 | val->type = type; | |
38324 | + type_incref (type); | |
38325 | val->enclosing_type = type; | |
38326 | + type_incref (type); | |
38327 | VALUE_LVAL (val) = not_lval; | |
38328 | - VALUE_ADDRESS (val) = 0; | |
38329 | + val->location.address = 0; | |
38330 | VALUE_FRAME_ID (val) = null_frame_id; | |
38331 | val->offset = 0; | |
38332 | val->bitpos = 0; | |
38333 | @@ -269,13 +293,9 @@ struct value * | |
38334 | allocate_repeat_value (struct type *type, int count) | |
38335 | { | |
38336 | int low_bound = current_language->string_lower_bound; /* ??? */ | |
38337 | - /* FIXME-type-allocation: need a way to free this type when we are | |
38338 | - done with it. */ | |
38339 | struct type *range_type | |
38340 | = create_range_type ((struct type *) NULL, builtin_type_int32, | |
38341 | low_bound, count + low_bound - 1); | |
38342 | - /* FIXME-type-allocation: need a way to free this type when we are | |
38343 | - done with it. */ | |
38344 | return allocate_value (create_array_type ((struct type *) NULL, | |
38345 | type, range_type)); | |
38346 | } | |
38347 | @@ -335,6 +355,8 @@ value_type (struct value *value) | |
38348 | void | |
38349 | deprecated_set_value_type (struct value *value, struct type *type) | |
38350 | { | |
38351 | + type_incref (type); | |
38352 | + type_decref (value->type); | |
38353 | value->type = type; | |
38354 | } | |
38355 | ||
38356 | @@ -509,6 +531,32 @@ deprecated_value_address_hack (struct value *value) | |
38357 | return &value->location.address; | |
38358 | } | |
38359 | ||
38360 | +CORE_ADDR | |
38361 | +value_address (struct value *value) | |
38362 | +{ | |
38363 | + if (value->lval == lval_internalvar | |
38364 | + || value->lval == lval_internalvar_component) | |
38365 | + return 0; | |
38366 | + return value->location.address + value->offset; | |
38367 | +} | |
38368 | + | |
38369 | +CORE_ADDR | |
38370 | +value_raw_address (struct value *value) | |
38371 | +{ | |
38372 | + if (value->lval == lval_internalvar | |
38373 | + || value->lval == lval_internalvar_component) | |
38374 | + return 0; | |
38375 | + return value->location.address; | |
38376 | +} | |
38377 | + | |
38378 | +void | |
38379 | +set_value_address (struct value *value, CORE_ADDR addr) | |
38380 | +{ | |
38381 | + gdb_assert (value->lval != lval_internalvar | |
38382 | + && value->lval != lval_internalvar_component); | |
38383 | + value->location.address = addr; | |
38384 | +} | |
38385 | + | |
38386 | struct internalvar ** | |
38387 | deprecated_value_internalvar_hack (struct value *value) | |
38388 | { | |
38389 | @@ -547,11 +595,16 @@ value_mark (void) | |
38390 | return all_values; | |
38391 | } | |
38392 | ||
38393 | +/* Deallocate a value and run destructors if needed. */ | |
38394 | + | |
38395 | void | |
38396 | value_free (struct value *val) | |
38397 | { | |
38398 | if (val) | |
38399 | { | |
38400 | + type_decref (val->type); | |
38401 | + type_decref (val->enclosing_type); | |
38402 | + | |
38403 | if (VALUE_LVAL (val) == lval_computed) | |
38404 | { | |
38405 | struct lval_funcs *funcs = val->location.computed.funcs; | |
38406 | @@ -655,6 +708,8 @@ value_copy (struct value *arg) | |
38407 | val = allocate_value_lazy (encl_type); | |
38408 | else | |
38409 | val = allocate_value (encl_type); | |
38410 | + type_incref (arg->type); | |
38411 | + type_decref (val->type); | |
38412 | val->type = arg->type; | |
38413 | VALUE_LVAL (val) = VALUE_LVAL (arg); | |
38414 | val->location = arg->location; | |
38415 | @@ -693,6 +748,7 @@ set_value_component_location (struct value *component, struct value *whole) | |
38416 | VALUE_LVAL (component) = VALUE_LVAL (whole); | |
38417 | ||
38418 | component->location = whole->location; | |
38419 | + | |
38420 | if (VALUE_LVAL (whole) == lval_computed) | |
38421 | { | |
38422 | struct lval_funcs *funcs = whole->location.computed.funcs; | |
38423 | @@ -700,6 +756,8 @@ set_value_component_location (struct value *component, struct value *whole) | |
38424 | if (funcs->copy_closure) | |
38425 | component->location.computed.closure = funcs->copy_closure (whole); | |
38426 | } | |
38427 | + | |
38428 | + object_address_get_data (value_type (whole), &VALUE_ADDRESS (component)); | |
38429 | } | |
38430 | ||
38431 | \f | |
38432 | @@ -830,6 +888,25 @@ show_values (char *num_exp, int from_tty) | |
38433 | num_exp[1] = '\0'; | |
38434 | } | |
38435 | } | |
38436 | + | |
38437 | +/* Sanity check for memory leaks and proper types reference counting. */ | |
38438 | + | |
38439 | +static void | |
38440 | +value_history_cleanup (void *unused) | |
38441 | +{ | |
38442 | + while (value_history_chain) | |
38443 | + { | |
38444 | + struct value_history_chunk *chunk = value_history_chain; | |
38445 | + int i; | |
38446 | + | |
38447 | + for (i = 0; i < ARRAY_SIZE (chunk->values); i++) | |
38448 | + value_free (chunk->values[i]); | |
38449 | + | |
38450 | + value_history_chain = chunk->next; | |
38451 | + xfree (chunk); | |
38452 | + } | |
38453 | + value_history_count = 0; | |
38454 | +} | |
38455 | \f | |
38456 | /* Internal variables. These are variables within the debugger | |
38457 | that hold values assigned by debugger commands. | |
38458 | @@ -878,7 +955,7 @@ init_if_undefined_command (char* args, int from_tty) | |
38459 | the return value is NULL. */ | |
38460 | ||
38461 | struct internalvar * | |
38462 | -lookup_only_internalvar (char *name) | |
38463 | +lookup_only_internalvar (const char *name) | |
38464 | { | |
38465 | struct internalvar *var; | |
38466 | ||
38467 | @@ -894,7 +971,7 @@ lookup_only_internalvar (char *name) | |
38468 | NAME should not normally include a dollar sign. */ | |
38469 | ||
38470 | struct internalvar * | |
38471 | -create_internalvar (char *name) | |
38472 | +create_internalvar (const char *name) | |
38473 | { | |
38474 | struct internalvar *var; | |
38475 | var = (struct internalvar *) xmalloc (sizeof (struct internalvar)); | |
38476 | @@ -902,6 +979,7 @@ create_internalvar (char *name) | |
38477 | var->value = allocate_value (builtin_type_void); | |
38478 | var->endian = gdbarch_byte_order (current_gdbarch); | |
38479 | var->make_value = NULL; | |
38480 | + var->canonical = 0; | |
38481 | release_value (var->value); | |
38482 | var->next = internalvars; | |
38483 | internalvars = var; | |
38484 | @@ -934,7 +1012,7 @@ create_internalvar_type_lazy (char *name, internalvar_make_value fun) | |
38485 | one is created, with a void value. */ | |
38486 | ||
38487 | struct internalvar * | |
38488 | -lookup_internalvar (char *name) | |
38489 | +lookup_internalvar (const char *name) | |
38490 | { | |
38491 | struct internalvar *var; | |
38492 | ||
38493 | @@ -1031,6 +1109,9 @@ set_internalvar (struct internalvar *var, struct value *val) | |
38494 | { | |
38495 | struct value *newval; | |
38496 | ||
38497 | + if (var->canonical) | |
38498 | + error (_("Cannot overwrite convenience function %s"), var->name); | |
38499 | + | |
38500 | newval = value_copy (val); | |
38501 | newval->modifiable = 1; | |
38502 | ||
38503 | @@ -1042,7 +1123,7 @@ set_internalvar (struct internalvar *var, struct value *val) | |
38504 | ||
38505 | /* Begin code which must not call error(). If var->value points to | |
38506 | something free'd, an error() obviously leaves a dangling pointer. | |
38507 | - But we also get a danling pointer if var->value points to | |
38508 | + But we also get a dangling pointer if var->value points to | |
38509 | something in the value chain (i.e., before release_value is | |
38510 | called), because after the error free_all_values will get called before | |
38511 | long. */ | |
38512 | @@ -1059,6 +1140,76 @@ internalvar_name (struct internalvar *var) | |
38513 | return var->name; | |
38514 | } | |
38515 | ||
38516 | +static struct value * | |
38517 | +value_create_internal_function (const char *name, | |
38518 | + internal_function_fn handler, | |
38519 | + void *cookie) | |
38520 | +{ | |
38521 | + struct value *result = allocate_value (internal_fn_type); | |
38522 | + gdb_byte *addr = value_contents_writeable (result); | |
38523 | + struct internal_function **fnp = (struct internal_function **) addr; | |
38524 | + struct internal_function *ifn = XNEW (struct internal_function); | |
38525 | + ifn->name = xstrdup (name); | |
38526 | + ifn->handler = handler; | |
38527 | + ifn->cookie = cookie; | |
38528 | + *fnp = ifn; | |
38529 | + return result; | |
38530 | +} | |
38531 | + | |
38532 | +char * | |
38533 | +value_internal_function_name (struct value *val) | |
38534 | +{ | |
38535 | + gdb_byte *addr = value_contents_writeable (val); | |
38536 | + struct internal_function *ifn = * (struct internal_function **) addr; | |
38537 | + return ifn->name; | |
38538 | +} | |
38539 | + | |
38540 | +struct value * | |
38541 | +call_internal_function (struct value *func, int argc, struct value **argv) | |
38542 | +{ | |
38543 | + gdb_byte *addr = value_contents_writeable (func); | |
38544 | + struct internal_function *ifn = * (struct internal_function **) addr; | |
38545 | + return (*ifn->handler) (ifn->cookie, argc, argv); | |
38546 | +} | |
38547 | + | |
38548 | +/* The 'function' command. This does nothing -- it is just a | |
38549 | + placeholder to let "help function NAME" work. This is also used as | |
38550 | + the implementation of the sub-command that is created when | |
38551 | + registering an internal function. */ | |
38552 | +static void | |
38553 | +function_command (char *command, int from_tty) | |
38554 | +{ | |
38555 | + /* Do nothing. */ | |
38556 | +} | |
38557 | + | |
38558 | +/* Clean up if an internal function's command is destroyed. */ | |
38559 | +static void | |
38560 | +function_destroyer (struct cmd_list_element *self, void *ignore) | |
38561 | +{ | |
38562 | + xfree (self->name); | |
38563 | + xfree (self->doc); | |
38564 | +} | |
38565 | + | |
38566 | +/* Add a new internal function. NAME is the name of the function; DOC | |
38567 | + is a documentation string describing the function. HANDLER is | |
38568 | + called when the function is invoked. COOKIE is an arbitrary | |
38569 | + pointer which is passed to HANDLER and is intended for "user | |
38570 | + data". */ | |
38571 | +void | |
38572 | +add_internal_function (const char *name, const char *doc, | |
38573 | + internal_function_fn handler, void *cookie) | |
38574 | +{ | |
38575 | + struct cmd_list_element *cmd; | |
38576 | + struct internalvar *var = lookup_internalvar (name); | |
38577 | + struct value *fnval = value_create_internal_function (name, handler, cookie); | |
38578 | + set_internalvar (var, fnval); | |
38579 | + var->canonical = 1; | |
38580 | + | |
38581 | + cmd = add_cmd (xstrdup (name), no_class, function_command, (char *) doc, | |
38582 | + &functionlist); | |
38583 | + cmd->destroyer = function_destroyer; | |
38584 | +} | |
38585 | + | |
38586 | /* Update VALUE before discarding OBJFILE. COPIED_TYPES is used to | |
38587 | prevent cycles / duplicates. */ | |
38588 | ||
38589 | @@ -1067,12 +1218,21 @@ preserve_one_value (struct value *value, struct objfile *objfile, | |
38590 | htab_t copied_types) | |
38591 | { | |
38592 | if (TYPE_OBJFILE (value->type) == objfile) | |
38593 | - value->type = copy_type_recursive (objfile, value->type, copied_types); | |
38594 | + { | |
38595 | + /* No need to decref the old type here, since we know it has no | |
38596 | + reference count. */ | |
38597 | + value->type = copy_type_recursive (value->type, copied_types); | |
38598 | + type_incref (value->type); | |
38599 | + } | |
38600 | ||
38601 | if (TYPE_OBJFILE (value->enclosing_type) == objfile) | |
38602 | - value->enclosing_type = copy_type_recursive (objfile, | |
38603 | - value->enclosing_type, | |
38604 | - copied_types); | |
38605 | + { | |
38606 | + /* No need to decref the old type here, since we know it has no | |
38607 | + reference count. */ | |
38608 | + value->enclosing_type = copy_type_recursive (value->enclosing_type, | |
38609 | + copied_types); | |
38610 | + type_incref (value->enclosing_type); | |
38611 | + } | |
38612 | } | |
38613 | ||
38614 | /* Update the internal variables and value history when OBJFILE is | |
38615 | @@ -1196,7 +1356,7 @@ value_as_address (struct value *val) | |
38616 | ||
38617 | Upon entry to this function, if VAL is a value of type `function' | |
38618 | (that is, TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC), then | |
38619 | - VALUE_ADDRESS (val) is the address of the function. This is what | |
38620 | + value_address (val) is the address of the function. This is what | |
38621 | you'll get if you evaluate an expression like `main'. The call | |
38622 | to COERCE_ARRAY below actually does all the usual unary | |
38623 | conversions, which includes converting values of type `function' | |
38624 | @@ -1216,7 +1376,7 @@ value_as_address (struct value *val) | |
38625 | function, just return its address directly. */ | |
38626 | if (TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC | |
38627 | || TYPE_CODE (value_type (val)) == TYPE_CODE_METHOD) | |
38628 | - return VALUE_ADDRESS (val); | |
38629 | + return value_address (val); | |
38630 | ||
38631 | val = coerce_array (val); | |
38632 | ||
38633 | @@ -1447,7 +1607,7 @@ value_static_field (struct type *type, int fieldno) | |
38634 | } | |
38635 | if (retval && VALUE_LVAL (retval) == lval_memory) | |
38636 | SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno), | |
38637 | - VALUE_ADDRESS (retval)); | |
38638 | + value_address (retval)); | |
38639 | } | |
38640 | return retval; | |
38641 | } | |
38642 | @@ -1465,6 +1625,8 @@ value_change_enclosing_type (struct value *val, struct type *new_encl_type) | |
38643 | val->contents = | |
38644 | (gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type)); | |
38645 | ||
38646 | + type_incref (new_encl_type); | |
38647 | + type_decref (val->enclosing_type); | |
38648 | val->enclosing_type = new_encl_type; | |
38649 | return val; | |
38650 | } | |
38651 | @@ -1516,6 +1678,8 @@ value_primitive_field (struct value *arg1, int offset, | |
38652 | memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1), | |
38653 | TYPE_LENGTH (value_enclosing_type (arg1))); | |
38654 | } | |
38655 | + type_incref (type); | |
38656 | + type_decref (v->type); | |
38657 | v->type = type; | |
38658 | v->offset = value_offset (arg1); | |
38659 | v->embedded_offset = (offset + value_embedded_offset (arg1) | |
38660 | @@ -1592,7 +1756,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty | |
38661 | v = allocate_value (ftype); | |
38662 | if (sym) | |
38663 | { | |
38664 | - VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); | |
38665 | + set_value_address (v, BLOCK_START (SYMBOL_BLOCK_VALUE (sym))); | |
38666 | } | |
38667 | else | |
38668 | { | |
38669 | @@ -1601,9 +1765,9 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty | |
38670 | struct objfile *objfile = msymbol_objfile (msym); | |
38671 | struct gdbarch *gdbarch = get_objfile_arch (objfile); | |
38672 | ||
38673 | - VALUE_ADDRESS (v) | |
38674 | - = gdbarch_convert_from_func_ptr_addr | |
38675 | - (gdbarch, SYMBOL_VALUE_ADDRESS (msym), ¤t_target); | |
38676 | + set_value_address (v, | |
38677 | + gdbarch_convert_from_func_ptr_addr | |
38678 | + (gdbarch, SYMBOL_VALUE_ADDRESS (msym), ¤t_target)); | |
38679 | } | |
38680 | ||
38681 | if (arg1p) | |
38682 | @@ -1750,6 +1914,41 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num) | |
38683 | } | |
38684 | ||
38685 | ||
38686 | +/* Pack NUM into BUF using a target format of TYPE. */ | |
38687 | + | |
38688 | +void | |
38689 | +pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num) | |
38690 | +{ | |
38691 | + int len; | |
38692 | + | |
38693 | + type = check_typedef (type); | |
38694 | + len = TYPE_LENGTH (type); | |
38695 | + | |
38696 | + switch (TYPE_CODE (type)) | |
38697 | + { | |
38698 | + case TYPE_CODE_INT: | |
38699 | + case TYPE_CODE_CHAR: | |
38700 | + case TYPE_CODE_ENUM: | |
38701 | + case TYPE_CODE_FLAGS: | |
38702 | + case TYPE_CODE_BOOL: | |
38703 | + case TYPE_CODE_RANGE: | |
38704 | + case TYPE_CODE_MEMBERPTR: | |
38705 | + store_unsigned_integer (buf, len, num); | |
38706 | + break; | |
38707 | + | |
38708 | + case TYPE_CODE_REF: | |
38709 | + case TYPE_CODE_PTR: | |
38710 | + store_typed_address (buf, type, (CORE_ADDR) num); | |
38711 | + break; | |
38712 | + | |
38713 | + default: | |
38714 | + error (_("\ | |
38715 | +Unexpected type (%d) encountered for unsigned integer constant."), | |
38716 | + TYPE_CODE (type)); | |
38717 | + } | |
38718 | +} | |
38719 | + | |
38720 | + | |
38721 | /* Convert C numbers into newly allocated values. */ | |
38722 | ||
38723 | struct value * | |
38724 | @@ -1763,6 +1962,19 @@ value_from_longest (struct type *type, LONGEST num) | |
38725 | } | |
38726 | ||
38727 | ||
38728 | +/* Convert C unsigned numbers into newly allocated values. */ | |
38729 | + | |
38730 | +struct value * | |
38731 | +value_from_ulongest (struct type *type, ULONGEST num) | |
38732 | +{ | |
38733 | + struct value *val = allocate_value (type); | |
38734 | + | |
38735 | + pack_unsigned_long (value_contents_raw (val), type, num); | |
38736 | + | |
38737 | + return val; | |
38738 | +} | |
38739 | + | |
38740 | + | |
38741 | /* Create a value representing a pointer of type TYPE to the address | |
38742 | ADDR. */ | |
38743 | struct value * | |
38744 | @@ -1816,8 +2028,9 @@ value_from_contents_and_address (struct type *type, | |
38745 | set_value_lazy (v, 1); | |
38746 | else | |
38747 | memcpy (value_contents_raw (v), valaddr, TYPE_LENGTH (type)); | |
38748 | - VALUE_ADDRESS (v) = address; | |
38749 | - VALUE_LVAL (v) = lval_memory; | |
38750 | + set_value_address (v, address); | |
38751 | + if (address != 0) | |
38752 | + VALUE_LVAL (v) = lval_memory; | |
38753 | return v; | |
38754 | } | |
38755 | ||
38756 | @@ -1944,4 +2157,15 @@ init-if-undefined VARIABLE = EXPRESSION\n\ | |
38757 | Set an internal VARIABLE to the result of the EXPRESSION if it does not\n\ | |
38758 | exist or does not contain a value. The EXPRESSION is not evaluated if the\n\ | |
38759 | VARIABLE is already initialized.")); | |
38760 | + | |
38761 | + add_prefix_cmd ("function", no_class, function_command, _("\ | |
38762 | +Placeholder command for showing help on convenience functions."), | |
38763 | + &functionlist, "function ", 0, &cmdlist); | |
38764 | + | |
38765 | + internal_fn_type = alloc_type (OBJFILE_INTERNAL, NULL); | |
38766 | + TYPE_CODE (internal_fn_type) = TYPE_CODE_INTERNAL_FUNCTION; | |
38767 | + TYPE_LENGTH (internal_fn_type) = sizeof (struct internal_function *); | |
38768 | + TYPE_NAME (internal_fn_type) = "<internal function>"; | |
38769 | + | |
38770 | + make_final_cleanup (value_history_cleanup, NULL); | |
38771 | } | |
38772 | diff --git a/gdb/value.h b/gdb/value.h | |
38773 | index aa43365..1ad3c75 100644 | |
38774 | --- a/gdb/value.h | |
38775 | +++ b/gdb/value.h | |
38776 | @@ -272,12 +272,23 @@ extern void set_value_component_location (struct value *component, | |
38777 | extern enum lval_type *deprecated_value_lval_hack (struct value *); | |
38778 | #define VALUE_LVAL(val) (*deprecated_value_lval_hack (val)) | |
38779 | ||
38780 | -/* If lval == lval_memory, this is the address in the inferior. If | |
38781 | - lval == lval_register, this is the byte offset into the registers | |
38782 | - structure. */ | |
38783 | +/* Backward compatibility for the Fedora merge branch. */ | |
38784 | extern CORE_ADDR *deprecated_value_address_hack (struct value *); | |
38785 | #define VALUE_ADDRESS(val) (*deprecated_value_address_hack (val)) | |
38786 | ||
38787 | +/* If lval == lval_memory, return the address in the inferior. If | |
38788 | + lval == lval_register, return the byte offset into the registers | |
38789 | + structure. Otherwise, return 0. The returned address | |
38790 | + includes the offset, if any. */ | |
38791 | +extern CORE_ADDR value_address (struct value *); | |
38792 | + | |
38793 | +/* Like value_address, except the result does not include value's | |
38794 | + offset. */ | |
38795 | +extern CORE_ADDR value_raw_address (struct value *); | |
38796 | + | |
38797 | +/* Set the address of a value. */ | |
38798 | +extern void set_value_address (struct value *, CORE_ADDR); | |
38799 | + | |
38800 | /* Pointer to internal variable. */ | |
38801 | extern struct internalvar **deprecated_value_internalvar_hack (struct value *); | |
38802 | #define VALUE_INTERNALVAR(val) (*deprecated_value_internalvar_hack (val)) | |
38803 | @@ -314,6 +325,9 @@ struct internalvar | |
38804 | struct value *value; | |
38805 | internalvar_make_value make_value; | |
38806 | int endian; | |
38807 | + /* True if this internalvar is the canonical name for a convenience | |
38808 | + function. */ | |
38809 | + int canonical; | |
38810 | }; | |
38811 | ||
38812 | \f | |
38813 | @@ -342,12 +356,17 @@ extern LONGEST unpack_field_as_long (struct type *type, | |
38814 | extern void pack_long (gdb_byte *buf, struct type *type, LONGEST num); | |
38815 | ||
38816 | extern struct value *value_from_longest (struct type *type, LONGEST num); | |
38817 | +extern struct value *value_from_ulongest (struct type *type, ULONGEST num); | |
38818 | extern struct value *value_from_pointer (struct type *type, CORE_ADDR addr); | |
38819 | extern struct value *value_from_double (struct type *type, DOUBLEST num); | |
38820 | extern struct value *value_from_decfloat (struct type *type, | |
38821 | const gdb_byte *decbytes); | |
38822 | extern struct value *value_from_string (char *string); | |
38823 | ||
38824 | +extern const char *object_address_data_not_valid (struct type *type); | |
38825 | +extern int object_address_get_data (struct type *type, | |
38826 | + CORE_ADDR *address_return); | |
38827 | + | |
38828 | extern struct value *value_at (struct type *type, CORE_ADDR addr); | |
38829 | extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr); | |
38830 | ||
38831 | @@ -388,6 +407,8 @@ extern struct value *value_mark (void); | |
38832 | ||
38833 | extern void value_free_to_mark (struct value *mark); | |
38834 | ||
38835 | +extern struct value *value_typed_string (char *ptr, int len, | |
38836 | + struct type *char_type); | |
38837 | extern struct value *value_string (char *ptr, int len); | |
38838 | extern struct value *value_bitstring (char *ptr, int len); | |
38839 | ||
38840 | @@ -435,6 +456,7 @@ extern struct value *value_struct_elt (struct value **argp, | |
38841 | ||
38842 | extern struct value *value_aggregate_elt (struct type *curtype, | |
38843 | char *name, | |
38844 | + struct type *expect_type, | |
38845 | int want_address, | |
38846 | enum noside noside); | |
38847 | ||
38848 | @@ -533,14 +555,14 @@ extern void set_internalvar_component (struct internalvar *var, | |
38849 | int bitpos, int bitsize, | |
38850 | struct value *newvalue); | |
38851 | ||
38852 | -extern struct internalvar *lookup_only_internalvar (char *name); | |
38853 | +extern struct internalvar *lookup_only_internalvar (const char *name); | |
38854 | ||
38855 | -extern struct internalvar *create_internalvar (char *name); | |
38856 | +extern struct internalvar *create_internalvar (const char *name); | |
38857 | ||
38858 | extern struct internalvar * | |
38859 | create_internalvar_type_lazy (char *name, internalvar_make_value fun); | |
38860 | ||
38861 | -extern struct internalvar *lookup_internalvar (char *name); | |
38862 | +extern struct internalvar *lookup_internalvar (const char *name); | |
38863 | ||
38864 | extern int value_equal (struct value *arg1, struct value *arg2); | |
38865 | ||
38866 | @@ -619,7 +641,7 @@ extern int common_val_print (struct value *val, | |
38867 | const struct value_print_options *options, | |
38868 | const struct language_defn *language); | |
38869 | ||
38870 | -extern int val_print_string (CORE_ADDR addr, int len, int width, | |
38871 | +extern int val_print_string (struct type *elttype, CORE_ADDR addr, int len, | |
38872 | struct ui_file *stream, | |
38873 | const struct value_print_options *options); | |
38874 | ||
38875 | @@ -658,5 +680,22 @@ extern struct value *value_allocate_space_in_inferior (int); | |
38876 | ||
38877 | extern struct value *value_of_local (const char *name, int complain); | |
38878 | ||
38879 | -extern struct value * value_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound); | |
38880 | +extern struct value *value_subscripted_rvalue (struct value *array, | |
38881 | + CORE_ADDR offset); | |
38882 | + | |
38883 | +/* User function handler. */ | |
38884 | + | |
38885 | +typedef struct value *(*internal_function_fn) (void *cookie, | |
38886 | + int argc, | |
38887 | + struct value **argv); | |
38888 | + | |
38889 | +void add_internal_function (const char *name, const char *doc, | |
38890 | + internal_function_fn handler, | |
38891 | + void *cookie); | |
38892 | + | |
38893 | +struct value *call_internal_function (struct value *function, | |
38894 | + int argc, struct value **argv); | |
38895 | + | |
38896 | +char *value_internal_function_name (struct value *); | |
38897 | + | |
38898 | #endif /* !defined (VALUE_H) */ | |
38899 | diff --git a/gdb/varobj.c b/gdb/varobj.c | |
38900 | index 2ec6d90..1237c96 100644 | |
38901 | --- a/gdb/varobj.c | |
38902 | +++ b/gdb/varobj.c | |
38903 | @@ -29,11 +29,20 @@ | |
38904 | ||
38905 | #include "gdb_assert.h" | |
38906 | #include "gdb_string.h" | |
38907 | +#include "gdb_regex.h" | |
38908 | ||
38909 | #include "varobj.h" | |
38910 | #include "vec.h" | |
38911 | #include "gdbthread.h" | |
38912 | #include "inferior.h" | |
38913 | +#include "valprint.h" | |
38914 | + | |
38915 | +#if HAVE_PYTHON | |
38916 | +#include "python/python.h" | |
38917 | +#include "python/python-internal.h" | |
38918 | +#else | |
38919 | +typedef int PyObject; | |
38920 | +#endif | |
38921 | ||
38922 | /* Non-zero if we want to see trace of varobj level stuff. */ | |
38923 | ||
38924 | @@ -138,6 +147,12 @@ struct varobj | |
38925 | /* Children of this object. */ | |
38926 | VEC (varobj_p) *children; | |
38927 | ||
38928 | + /* Whether the children of this varobj were requested. This field is | |
38929 | + used to decide if dynamic varobj should recompute their children. | |
38930 | + In the event that the frontend never asked for the children, we | |
38931 | + can avoid that. */ | |
38932 | + int children_requested; | |
38933 | + | |
38934 | /* Description of the root variable. Points to root variable for children. */ | |
38935 | struct varobj_root *root; | |
38936 | ||
38937 | @@ -159,6 +174,16 @@ struct varobj | |
38938 | not fetched if either the variable is frozen, or any parents is | |
38939 | frozen. */ | |
38940 | int not_fetched; | |
38941 | + | |
38942 | + /* Sub-range of children which the MI consumer has requested. If | |
38943 | + FROM < 0 or TO < 0, means that all children have been | |
38944 | + requested. */ | |
38945 | + int from; | |
38946 | + int to; | |
38947 | + | |
38948 | + /* The pretty-printer that has been constructed. If NULL, then a | |
38949 | + new printer object is needed, and one will be constructed. */ | |
38950 | + PyObject *pretty_printer; | |
38951 | }; | |
38952 | ||
38953 | struct cpstack | |
38954 | @@ -190,6 +215,10 @@ static void uninstall_variable (struct varobj *); | |
38955 | ||
38956 | static struct varobj *create_child (struct varobj *, int, char *); | |
38957 | ||
38958 | +static struct varobj * | |
38959 | +create_child_with_value (struct varobj *parent, int index, const char *name, | |
38960 | + struct value *value); | |
38961 | + | |
38962 | /* Utility routines */ | |
38963 | ||
38964 | static struct varobj *new_variable (void); | |
38965 | @@ -200,6 +229,8 @@ static void free_variable (struct varobj *var); | |
38966 | ||
38967 | static struct cleanup *make_cleanup_free_variable (struct varobj *var); | |
38968 | ||
38969 | +static struct cleanup *make_cleanup_uninstall_variable (struct varobj *var); | |
38970 | + | |
38971 | static struct type *get_type (struct varobj *var); | |
38972 | ||
38973 | static struct type *get_value_type (struct varobj *var); | |
38974 | @@ -215,6 +246,8 @@ static char *cppop (struct cpstack **pstack); | |
38975 | static int install_new_value (struct varobj *var, struct value *value, | |
38976 | int initial); | |
38977 | ||
38978 | +static void install_default_visualizer (struct varobj *var); | |
38979 | + | |
38980 | /* Language-specific routines. */ | |
38981 | ||
38982 | static enum varobj_languages variable_language (struct varobj *var); | |
38983 | @@ -232,13 +265,17 @@ static struct value *value_of_child (struct varobj *parent, int index); | |
38984 | static char *my_value_of_variable (struct varobj *var, | |
38985 | enum varobj_display_formats format); | |
38986 | ||
38987 | -static char *value_get_print_value (struct value *value, | |
38988 | - enum varobj_display_formats format); | |
38989 | +char *value_get_print_value (struct value *value, | |
38990 | + enum varobj_display_formats format, | |
38991 | + PyObject *value_formatter); | |
38992 | ||
38993 | static int varobj_value_is_changeable_p (struct varobj *var); | |
38994 | ||
38995 | static int is_root_p (struct varobj *var); | |
38996 | ||
38997 | +static struct varobj * | |
38998 | +varobj_add_child (struct varobj *var, const char *name, struct value *value); | |
38999 | + | |
39000 | /* C implementation */ | |
39001 | ||
39002 | static int c_number_of_children (struct varobj *var); | |
39003 | @@ -570,8 +607,10 @@ varobj_create (char *objname, | |
39004 | do_cleanups (old_chain); | |
39005 | return NULL; | |
39006 | } | |
39007 | + make_cleanup_uninstall_variable (var); | |
39008 | } | |
39009 | ||
39010 | + install_default_visualizer (var); | |
39011 | discard_cleanups (old_chain); | |
39012 | return var; | |
39013 | } | |
39014 | @@ -678,6 +717,33 @@ varobj_delete (struct varobj *var, char ***dellist, int only_children) | |
39015 | return delcount; | |
39016 | } | |
39017 | ||
39018 | +/* Convenience function for varobj_set_visualizer. Instantiate a | |
39019 | + pretty-printer for a given value. */ | |
39020 | +static PyObject * | |
39021 | +instantiate_pretty_printer (PyObject *constructor, struct value *value) | |
39022 | +{ | |
39023 | +#if HAVE_PYTHON | |
39024 | + PyObject *val_obj = NULL; | |
39025 | + PyObject *printer; | |
39026 | + volatile struct gdb_exception except; | |
39027 | + | |
39028 | + TRY_CATCH (except, RETURN_MASK_ALL) | |
39029 | + { | |
39030 | + value = value_copy (value); | |
39031 | + } | |
39032 | + GDB_PY_HANDLE_EXCEPTION (except); | |
39033 | + val_obj = value_to_value_object (value); | |
39034 | + | |
39035 | + if (! val_obj) | |
39036 | + return NULL; | |
39037 | + | |
39038 | + printer = gdbpy_instantiate_printer (constructor, val_obj); | |
39039 | + Py_DECREF (val_obj); | |
39040 | + return printer; | |
39041 | +#endif | |
39042 | + return NULL; | |
39043 | +} | |
39044 | + | |
39045 | /* Set/Get variable object display format */ | |
39046 | ||
39047 | enum varobj_display_formats | |
39048 | @@ -702,7 +768,8 @@ varobj_set_display_format (struct varobj *var, | |
39049 | && var->value && !value_lazy (var->value)) | |
39050 | { | |
39051 | xfree (var->print_value); | |
39052 | - var->print_value = value_get_print_value (var->value, var->format); | |
39053 | + var->print_value = value_get_print_value (var->value, var->format, | |
39054 | + var->pretty_printer); | |
39055 | } | |
39056 | ||
39057 | return var->format; | |
39058 | @@ -714,6 +781,21 @@ varobj_get_display_format (struct varobj *var) | |
39059 | return var->format; | |
39060 | } | |
39061 | ||
39062 | +char * | |
39063 | +varobj_get_display_hint (struct varobj *var) | |
39064 | +{ | |
39065 | + char *result = NULL; | |
39066 | + | |
39067 | +#if HAVE_PYTHON | |
39068 | + PyGILState_STATE state = PyGILState_Ensure (); | |
39069 | + if (var->pretty_printer) | |
39070 | + result = gdbpy_get_display_hint (var->pretty_printer); | |
39071 | + PyGILState_Release (state); | |
39072 | +#endif | |
39073 | + | |
39074 | + return result; | |
39075 | +} | |
39076 | + | |
39077 | /* If the variable object is bound to a specific thread, that | |
39078 | is its evaluation can always be done in context of a frame | |
39079 | inside that thread, returns GDB id of the thread -- which | |
39080 | @@ -746,12 +828,141 @@ varobj_get_frozen (struct varobj *var) | |
39081 | return var->frozen; | |
39082 | } | |
39083 | ||
39084 | +static int | |
39085 | +update_dynamic_varobj_children (struct varobj *var, | |
39086 | + VEC (varobj_p) **changed, | |
39087 | + VEC (varobj_p) **new_and_unchanged, | |
39088 | + int *cchanged) | |
39089 | + | |
39090 | +{ | |
39091 | +#if HAVE_PYTHON | |
39092 | + /* FIXME: we *might* want to provide this functionality as | |
39093 | + a standalone function, so that other interested parties | |
39094 | + than varobj code can benefit for this. */ | |
39095 | + struct cleanup *back_to; | |
39096 | + PyObject *children; | |
39097 | + PyObject *iterator; | |
39098 | + int i; | |
39099 | + int children_changed = 0; | |
39100 | + PyObject *printer = var->pretty_printer; | |
39101 | + PyGILState_STATE state; | |
39102 | + | |
39103 | + state = PyGILState_Ensure (); | |
39104 | + back_to = make_cleanup_py_restore_gil (&state); | |
39105 | + | |
39106 | + *cchanged = 0; | |
39107 | + if (!PyObject_HasAttr (printer, gdbpy_children_cst)) | |
39108 | + { | |
39109 | + do_cleanups (back_to); | |
39110 | + return 0; | |
39111 | + } | |
39112 | + | |
39113 | + children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst, | |
39114 | + NULL); | |
39115 | + | |
39116 | + if (!children) | |
39117 | + { | |
39118 | + gdbpy_print_stack (); | |
39119 | + error ("Null value returned for children"); | |
39120 | + } | |
39121 | + | |
39122 | + make_cleanup_py_decref (children); | |
39123 | + | |
39124 | + if (!PyIter_Check (children)) | |
39125 | + error ("Returned value is not iterable"); | |
39126 | + | |
39127 | + iterator = PyObject_GetIter (children); | |
39128 | + if (!iterator) | |
39129 | + { | |
39130 | + gdbpy_print_stack (); | |
39131 | + error ("Could not get children iterator"); | |
39132 | + } | |
39133 | + make_cleanup_py_decref (iterator); | |
39134 | + | |
39135 | + for (i = 0; ; ++i) | |
39136 | + { | |
39137 | + PyObject *item = PyIter_Next (iterator); | |
39138 | + PyObject *py_v; | |
39139 | + struct value *v; | |
39140 | + char *name; | |
39141 | + struct cleanup *inner; | |
39142 | + | |
39143 | + if (!item) | |
39144 | + break; | |
39145 | + inner = make_cleanup_py_decref (item); | |
39146 | + | |
39147 | + if (!PyArg_ParseTuple (item, "sO", &name, &py_v)) | |
39148 | + error ("Invalid item from the child list"); | |
39149 | + | |
39150 | + if (PyObject_TypeCheck (py_v, &value_object_type)) | |
39151 | + { | |
39152 | + /* If we just call convert_value_from_python for this type, | |
39153 | + we won't know who owns the result. For this one case we | |
39154 | + need to copy the resulting value. */ | |
39155 | + v = value_object_to_value (py_v); | |
39156 | + v = value_copy (v); | |
39157 | + } | |
39158 | + else | |
39159 | + v = convert_value_from_python (py_v); | |
39160 | + | |
39161 | + /* TODO: This assume the name of the i-th child never changes. */ | |
39162 | + | |
39163 | + /* Now see what to do here. */ | |
39164 | + if (VEC_length (varobj_p, var->children) < i + 1) | |
39165 | + { | |
39166 | + /* There's no child yet. */ | |
39167 | + struct varobj *child = varobj_add_child (var, name, v); | |
39168 | + if (new_and_unchanged) | |
39169 | + VEC_safe_push (varobj_p, *new_and_unchanged, child); | |
39170 | + children_changed = 1; | |
39171 | + } | |
39172 | + else | |
39173 | + { | |
39174 | + varobj_p existing = VEC_index (varobj_p, var->children, i); | |
39175 | + if (install_new_value (existing, v, 0) && changed) | |
39176 | + { | |
39177 | + if (changed) | |
39178 | + VEC_safe_push (varobj_p, *changed, existing); | |
39179 | + } | |
39180 | + else | |
39181 | + { | |
39182 | + if (new_and_unchanged) | |
39183 | + VEC_safe_push (varobj_p, *new_and_unchanged, existing); | |
39184 | + } | |
39185 | + } | |
39186 | + | |
39187 | + do_cleanups (inner); | |
39188 | + } | |
39189 | + | |
39190 | + if (i < VEC_length (varobj_p, var->children)) | |
39191 | + { | |
39192 | + int i; | |
39193 | + children_changed = 1; | |
39194 | + for (i = 0; i < VEC_length (varobj_p, var->children); ++i) | |
39195 | + varobj_delete (VEC_index (varobj_p, var->children, i), NULL, 0); | |
39196 | + } | |
39197 | + VEC_truncate (varobj_p, var->children, i); | |
39198 | + var->num_children = VEC_length (varobj_p, var->children); | |
39199 | + | |
39200 | + do_cleanups (back_to); | |
39201 | + | |
39202 | + *cchanged = children_changed; | |
39203 | + return 1; | |
39204 | +#else | |
39205 | + gdb_assert (0 && "should never be called if Python is not enabled"); | |
39206 | +#endif | |
39207 | +} | |
39208 | ||
39209 | int | |
39210 | varobj_get_num_children (struct varobj *var) | |
39211 | { | |
39212 | if (var->num_children == -1) | |
39213 | - var->num_children = number_of_children (var); | |
39214 | + { | |
39215 | + int changed; | |
39216 | + if (!var->pretty_printer | |
39217 | + || !update_dynamic_varobj_children (var, NULL, NULL, &changed)) | |
39218 | + var->num_children = number_of_children (var); | |
39219 | + } | |
39220 | ||
39221 | return var->num_children; | |
39222 | } | |
39223 | @@ -764,7 +975,16 @@ varobj_list_children (struct varobj *var) | |
39224 | { | |
39225 | struct varobj *child; | |
39226 | char *name; | |
39227 | - int i; | |
39228 | + int i, children_changed; | |
39229 | + | |
39230 | + var->children_requested = 1; | |
39231 | + | |
39232 | + if (var->pretty_printer | |
39233 | + /* This, in theory, can result in the number of children changing without | |
39234 | + frontend noticing. But well, calling -var-list-children on the same | |
39235 | + varobj twice is not something a sane frontend would do. */ | |
39236 | + && update_dynamic_varobj_children (var, NULL, NULL, &children_changed)) | |
39237 | + return var->children; | |
39238 | ||
39239 | if (var->num_children == -1) | |
39240 | var->num_children = number_of_children (var); | |
39241 | @@ -790,12 +1010,24 @@ varobj_list_children (struct varobj *var) | |
39242 | name = name_of_child (var, i); | |
39243 | existing = create_child (var, i, name); | |
39244 | VEC_replace (varobj_p, var->children, i, existing); | |
39245 | + install_default_visualizer (existing); | |
39246 | } | |
39247 | } | |
39248 | ||
39249 | return var->children; | |
39250 | } | |
39251 | ||
39252 | +static struct varobj * | |
39253 | +varobj_add_child (struct varobj *var, const char *name, struct value *value) | |
39254 | +{ | |
39255 | + varobj_p v = create_child_with_value (var, | |
39256 | + VEC_length (varobj_p, var->children), | |
39257 | + name, value); | |
39258 | + VEC_safe_push (varobj_p, var->children, v); | |
39259 | + install_default_visualizer (v); | |
39260 | + return v; | |
39261 | +} | |
39262 | + | |
39263 | /* Obtain the type of an object Variable as a string similar to the one gdb | |
39264 | prints on the console */ | |
39265 | ||
39266 | @@ -1002,6 +1234,13 @@ install_new_value (struct varobj *var, struct value *value, int initial) | |
39267 | a type. */ | |
39268 | gdb_assert (var->type || CPLUS_FAKE_CHILD (var)); | |
39269 | changeable = varobj_value_is_changeable_p (var); | |
39270 | + | |
39271 | + /* If the type has custom visualizer, we consider it to be always | |
39272 | + changeable. FIXME: need to make sure this behaviour will not | |
39273 | + mess up read-sensitive values. */ | |
39274 | + if (var->pretty_printer) | |
39275 | + changeable = 1; | |
39276 | + | |
39277 | need_to_fetch = changeable; | |
39278 | ||
39279 | /* We are not interested in the address of references, and given | |
39280 | @@ -1053,12 +1292,14 @@ install_new_value (struct varobj *var, struct value *value, int initial) | |
39281 | } | |
39282 | } | |
39283 | ||
39284 | + | |
39285 | /* Below, we'll be comparing string rendering of old and new | |
39286 | values. Don't get string rendering if the value is | |
39287 | lazy -- if it is, the code above has decided that the value | |
39288 | should not be fetched. */ | |
39289 | if (value && !value_lazy (value)) | |
39290 | - print_value = value_get_print_value (value, var->format); | |
39291 | + print_value = value_get_print_value (value, var->format, | |
39292 | + var->pretty_printer); | |
39293 | ||
39294 | /* If the type is changeable, compare the old and the new values. | |
39295 | If this is the initial assignment, we don't have any old value | |
39296 | @@ -1123,6 +1364,150 @@ install_new_value (struct varobj *var, struct value *value, int initial) | |
39297 | return changed; | |
39298 | } | |
39299 | ||
39300 | +/* Return the effective requested range for a varobj. VAR is the | |
39301 | + varobj. CHILDREN is the computed list of children. FROM and TO | |
39302 | + are out parameters. If VAR has no bounds selected, *FROM and *TO | |
39303 | + will be set to the full range of CHILDREN. Otherwise, *FROM and | |
39304 | + *TO will be set to the selected sub-range of VAR, clipped to be in | |
39305 | + range of CHILDREN. */ | |
39306 | +void | |
39307 | +varobj_get_child_range (struct varobj *var, VEC (varobj_p) *children, | |
39308 | + int *from, int *to) | |
39309 | +{ | |
39310 | + if (var->from < 0 || var->to < 0) | |
39311 | + { | |
39312 | + *from = 0; | |
39313 | + *to = VEC_length (varobj_p, children); | |
39314 | + } | |
39315 | + else | |
39316 | + { | |
39317 | + *from = var->from; | |
39318 | + if (*from > VEC_length (varobj_p, children)) | |
39319 | + *from = VEC_length (varobj_p, children); | |
39320 | + *to = var->to; | |
39321 | + if (*to > VEC_length (varobj_p, children)) | |
39322 | + *to = VEC_length (varobj_p, children); | |
39323 | + } | |
39324 | +} | |
39325 | + | |
39326 | +/* Set the selected sub-range of children of VAR to start at index | |
39327 | + FROM and end at index TO. If either FROM or TO is less than zero, | |
39328 | + this is interpreted as a request for all children. */ | |
39329 | +void | |
39330 | +varobj_set_child_range (struct varobj *var, int from, int to) | |
39331 | +{ | |
39332 | + var->from = from; | |
39333 | + var->to = to; | |
39334 | +} | |
39335 | + | |
39336 | +static void | |
39337 | +install_visualizer (struct varobj *var, PyObject *visualizer) | |
39338 | +{ | |
39339 | +#if HAVE_PYTHON | |
39340 | + /* If there are any children now, wipe them. */ | |
39341 | + varobj_delete (var, NULL, 1 /* children only */); | |
39342 | + var->num_children = -1; | |
39343 | + | |
39344 | + Py_XDECREF (var->pretty_printer); | |
39345 | + var->pretty_printer = visualizer; | |
39346 | + | |
39347 | + install_new_value (var, var->value, 1); | |
39348 | + | |
39349 | + /* If we removed the visualizer, and the user ever requested the | |
39350 | + object's children, then we must compute the list of children. | |
39351 | + Note that we needn't do this when installing a visualizer, | |
39352 | + because updating will recompute dynamic children. */ | |
39353 | + if (!visualizer && var->children_requested) | |
39354 | + varobj_list_children (var); | |
39355 | +#else | |
39356 | + error ("Python support required"); | |
39357 | +#endif | |
39358 | +} | |
39359 | + | |
39360 | +static void | |
39361 | +install_default_visualizer (struct varobj *var) | |
39362 | +{ | |
39363 | +#if HAVE_PYTHON | |
39364 | + struct cleanup *cleanup; | |
39365 | + PyGILState_STATE state; | |
39366 | + PyObject *pretty_printer = NULL; | |
39367 | + | |
39368 | + state = PyGILState_Ensure (); | |
39369 | + cleanup = make_cleanup_py_restore_gil (&state); | |
39370 | + | |
39371 | + if (var->value) | |
39372 | + { | |
39373 | + pretty_printer = gdbpy_get_varobj_pretty_printer (var->value); | |
39374 | + if (! pretty_printer) | |
39375 | + { | |
39376 | + gdbpy_print_stack (); | |
39377 | + error (_("Cannot instantiate printer for default visualizer")); | |
39378 | + } | |
39379 | + } | |
39380 | + | |
39381 | + if (pretty_printer == Py_None) | |
39382 | + { | |
39383 | + Py_DECREF (pretty_printer); | |
39384 | + pretty_printer = NULL; | |
39385 | + } | |
39386 | + | |
39387 | + install_visualizer (var, pretty_printer); | |
39388 | + do_cleanups (cleanup); | |
39389 | +#else | |
39390 | + /* No error is right as this function is inserted just as a hook. */ | |
39391 | +#endif | |
39392 | +} | |
39393 | + | |
39394 | +void | |
39395 | +varobj_set_visualizer (struct varobj *var, const char *visualizer) | |
39396 | +{ | |
39397 | +#if HAVE_PYTHON | |
39398 | + PyObject *mainmod, *globals, *pretty_printer, *constructor; | |
39399 | + struct cleanup *back_to, *value; | |
39400 | + PyGILState_STATE state; | |
39401 | + | |
39402 | + | |
39403 | + state = PyGILState_Ensure (); | |
39404 | + back_to = make_cleanup_py_restore_gil (&state); | |
39405 | + | |
39406 | + mainmod = PyImport_AddModule ("__main__"); | |
39407 | + globals = PyModule_GetDict (mainmod); | |
39408 | + Py_INCREF (globals); | |
39409 | + make_cleanup_py_decref (globals); | |
39410 | + | |
39411 | + constructor = PyRun_String (visualizer, Py_eval_input, globals, globals); | |
39412 | + | |
39413 | + /* Do not instantiate NoneType. */ | |
39414 | + if (constructor == Py_None) | |
39415 | + { | |
39416 | + pretty_printer = Py_None; | |
39417 | + Py_INCREF (pretty_printer); | |
39418 | + } | |
39419 | + else | |
39420 | + pretty_printer = instantiate_pretty_printer (constructor, var->value); | |
39421 | + | |
39422 | + Py_XDECREF (constructor); | |
39423 | + | |
39424 | + if (! pretty_printer) | |
39425 | + { | |
39426 | + gdbpy_print_stack (); | |
39427 | + error ("Could not evaluate visualizer expression: %s", visualizer); | |
39428 | + } | |
39429 | + | |
39430 | + if (pretty_printer == Py_None) | |
39431 | + { | |
39432 | + Py_DECREF (pretty_printer); | |
39433 | + pretty_printer = NULL; | |
39434 | + } | |
39435 | + | |
39436 | + install_visualizer (var, pretty_printer); | |
39437 | + | |
39438 | + do_cleanups (back_to); | |
39439 | +#else | |
39440 | + error ("Python support required"); | |
39441 | +#endif | |
39442 | +} | |
39443 | + | |
39444 | /* Update the values for a variable and its children. This is a | |
39445 | two-pronged attack. First, re-parse the value for the root's | |
39446 | expression to see if it's changed. Then go all the way | |
39447 | @@ -1148,7 +1533,7 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) | |
39448 | struct varobj **cv; | |
39449 | struct varobj **templist = NULL; | |
39450 | struct value *new; | |
39451 | - VEC (varobj_p) *stack = NULL; | |
39452 | + VEC (varobj_update_result) *stack = NULL; | |
39453 | VEC (varobj_update_result) *result = NULL; | |
39454 | struct frame_info *fi; | |
39455 | ||
39456 | @@ -1187,20 +1572,85 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) | |
39457 | ||
39458 | if (new == NULL) | |
39459 | r.status = VAROBJ_NOT_IN_SCOPE; | |
39460 | - | |
39461 | - if (r.type_changed || r.changed) | |
39462 | - VEC_safe_push (varobj_update_result, result, &r); | |
39463 | + r.value_installed = 1; | |
39464 | ||
39465 | if (r.status == VAROBJ_NOT_IN_SCOPE) | |
39466 | - return result; | |
39467 | + { | |
39468 | + VEC_safe_push (varobj_update_result, result, &r); | |
39469 | + return result; | |
39470 | + } | |
39471 | + | |
39472 | + VEC_safe_push (varobj_update_result, stack, &r); | |
39473 | + } | |
39474 | + else | |
39475 | + { | |
39476 | + varobj_update_result r = {*varp}; | |
39477 | + VEC_safe_push (varobj_update_result, stack, &r); | |
39478 | } | |
39479 | - | |
39480 | - VEC_safe_push (varobj_p, stack, *varp); | |
39481 | ||
39482 | /* Walk through the children, reconstructing them all. */ | |
39483 | - while (!VEC_empty (varobj_p, stack)) | |
39484 | + while (!VEC_empty (varobj_update_result, stack)) | |
39485 | { | |
39486 | - v = VEC_pop (varobj_p, stack); | |
39487 | + varobj_update_result r = *(VEC_last (varobj_update_result, stack)); | |
39488 | + struct varobj *v = r.varobj; | |
39489 | + | |
39490 | + VEC_pop (varobj_update_result, stack); | |
39491 | + | |
39492 | + /* Update this variable, unless it's a root, which is already | |
39493 | + updated. */ | |
39494 | + if (!r.value_installed) | |
39495 | + { | |
39496 | + new = value_of_child (v->parent, v->index); | |
39497 | + if (install_new_value (v, new, 0 /* type not changed */)) | |
39498 | + { | |
39499 | + r.changed = 1; | |
39500 | + v->updated = 0; | |
39501 | + } | |
39502 | + } | |
39503 | + | |
39504 | + /* We probably should not get children of a varobj that has a | |
39505 | + pretty-printer, but for which -var-list-children was never | |
39506 | + invoked. Presumably, such varobj is not yet expanded in the | |
39507 | + UI, so we need not bother getting it. */ | |
39508 | + if (v->pretty_printer) | |
39509 | + { | |
39510 | + VEC (varobj_p) *changed = 0, *new_and_unchanged = 0; | |
39511 | + int i, children_changed; | |
39512 | + varobj_p tmp; | |
39513 | + | |
39514 | + if (!v->children_requested) | |
39515 | + continue; | |
39516 | + | |
39517 | + if (v->frozen) | |
39518 | + continue; | |
39519 | + | |
39520 | + /* If update_dynamic_varobj_children returns 0, then we have | |
39521 | + a non-conforming pretty-printer, so we skip it. */ | |
39522 | + if (update_dynamic_varobj_children (v, &changed, &new_and_unchanged, | |
39523 | + &children_changed)) | |
39524 | + { | |
39525 | + if (children_changed) | |
39526 | + r.children_changed = 1; | |
39527 | + for (i = 0; VEC_iterate (varobj_p, changed, i, tmp); ++i) | |
39528 | + { | |
39529 | + varobj_update_result r = {tmp}; | |
39530 | + r.changed = 1; | |
39531 | + r.value_installed = 1; | |
39532 | + VEC_safe_push (varobj_update_result, stack, &r); | |
39533 | + } | |
39534 | + for (i = 0; | |
39535 | + VEC_iterate (varobj_p, new_and_unchanged, i, tmp); | |
39536 | + ++i) | |
39537 | + { | |
39538 | + varobj_update_result r = {tmp}; | |
39539 | + r.value_installed = 1; | |
39540 | + VEC_safe_push (varobj_update_result, stack, &r); | |
39541 | + } | |
39542 | + if (r.changed || r.children_changed) | |
39543 | + VEC_safe_push (varobj_update_result, result, &r); | |
39544 | + continue; | |
39545 | + } | |
39546 | + } | |
39547 | ||
39548 | /* Push any children. Use reverse order so that the first | |
39549 | child is popped from the work stack first, and so | |
39550 | @@ -1211,26 +1661,18 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) | |
39551 | varobj_p c = VEC_index (varobj_p, v->children, i); | |
39552 | /* Child may be NULL if explicitly deleted by -var-delete. */ | |
39553 | if (c != NULL && !c->frozen) | |
39554 | - VEC_safe_push (varobj_p, stack, c); | |
39555 | - } | |
39556 | - | |
39557 | - /* Update this variable, unless it's a root, which is already | |
39558 | - updated. */ | |
39559 | - if (v->root->rootvar != v) | |
39560 | - { | |
39561 | - new = value_of_child (v->parent, v->index); | |
39562 | - if (install_new_value (v, new, 0 /* type not changed */)) | |
39563 | { | |
39564 | - /* Note that it's changed */ | |
39565 | - varobj_update_result r = {v}; | |
39566 | - r.changed = 1; | |
39567 | - VEC_safe_push (varobj_update_result, result, &r); | |
39568 | - v->updated = 0; | |
39569 | + varobj_update_result r = {c}; | |
39570 | + VEC_safe_push (varobj_update_result, stack, &r); | |
39571 | } | |
39572 | } | |
39573 | + | |
39574 | + if (r.changed || r.type_changed) | |
39575 | + VEC_safe_push (varobj_update_result, result, &r); | |
39576 | } | |
39577 | ||
39578 | - VEC_free (varobj_p, stack); | |
39579 | + VEC_free (varobj_update_result, stack); | |
39580 | + | |
39581 | return result; | |
39582 | } | |
39583 | \f | |
39584 | @@ -1429,16 +1871,23 @@ uninstall_variable (struct varobj *var) | |
39585 | static struct varobj * | |
39586 | create_child (struct varobj *parent, int index, char *name) | |
39587 | { | |
39588 | + return create_child_with_value (parent, index, name, | |
39589 | + value_of_child (parent, index)); | |
39590 | +} | |
39591 | + | |
39592 | +static struct varobj * | |
39593 | +create_child_with_value (struct varobj *parent, int index, const char *name, | |
39594 | + struct value *value) | |
39595 | +{ | |
39596 | struct varobj *child; | |
39597 | char *childs_name; | |
39598 | - struct value *value; | |
39599 | ||
39600 | child = new_variable (); | |
39601 | ||
39602 | /* name is allocated by name_of_child */ | |
39603 | - child->name = name; | |
39604 | + /* FIXME: xstrdup should not be here. */ | |
39605 | + child->name = xstrdup (name); | |
39606 | child->index = index; | |
39607 | - value = value_of_child (parent, index); | |
39608 | child->parent = parent; | |
39609 | child->root = parent->root; | |
39610 | childs_name = xstrprintf ("%s.%s", parent->obj_name, name); | |
39611 | @@ -1487,6 +1936,10 @@ new_variable (void) | |
39612 | var->print_value = NULL; | |
39613 | var->frozen = 0; | |
39614 | var->not_fetched = 0; | |
39615 | + var->children_requested = 0; | |
39616 | + var->from = -1; | |
39617 | + var->to = -1; | |
39618 | + var->pretty_printer = 0; | |
39619 | ||
39620 | return var; | |
39621 | } | |
39622 | @@ -1519,6 +1972,14 @@ free_variable (struct varobj *var) | |
39623 | xfree (var->root); | |
39624 | } | |
39625 | ||
39626 | +#if HAVE_PYTHON | |
39627 | + { | |
39628 | + PyGILState_STATE state = PyGILState_Ensure (); | |
39629 | + Py_XDECREF (var->pretty_printer); | |
39630 | + PyGILState_Release (state); | |
39631 | + } | |
39632 | +#endif | |
39633 | + | |
39634 | xfree (var->name); | |
39635 | xfree (var->obj_name); | |
39636 | xfree (var->print_value); | |
39637 | @@ -1538,6 +1999,18 @@ make_cleanup_free_variable (struct varobj *var) | |
39638 | return make_cleanup (do_free_variable_cleanup, var); | |
39639 | } | |
39640 | ||
39641 | +static void | |
39642 | +do_uninstall_variable_cleanup (void *var) | |
39643 | +{ | |
39644 | + uninstall_variable (var); | |
39645 | +} | |
39646 | + | |
39647 | +static struct cleanup * | |
39648 | +make_cleanup_uninstall_variable (struct varobj *var) | |
39649 | +{ | |
39650 | + return make_cleanup (do_uninstall_variable_cleanup, var); | |
39651 | +} | |
39652 | + | |
39653 | /* This returns the type of the variable. It also skips past typedefs | |
39654 | to return the real type of the variable. | |
39655 | ||
39656 | @@ -1792,24 +2265,71 @@ my_value_of_variable (struct varobj *var, enum varobj_display_formats format) | |
39657 | return NULL; | |
39658 | } | |
39659 | ||
39660 | -static char * | |
39661 | -value_get_print_value (struct value *value, enum varobj_display_formats format) | |
39662 | +char * | |
39663 | +value_get_print_value (struct value *value, enum varobj_display_formats format, | |
39664 | + PyObject *value_formatter) | |
39665 | { | |
39666 | long dummy; | |
39667 | struct ui_file *stb; | |
39668 | struct cleanup *old_chain; | |
39669 | - char *thevalue; | |
39670 | + char *thevalue = NULL; | |
39671 | struct value_print_options opts; | |
39672 | ||
39673 | if (value == NULL) | |
39674 | return NULL; | |
39675 | ||
39676 | +#if HAVE_PYTHON | |
39677 | + { | |
39678 | + PyGILState_STATE state = PyGILState_Ensure (); | |
39679 | + if (value_formatter && PyObject_HasAttr (value_formatter, | |
39680 | + gdbpy_to_string_cst)) | |
39681 | + { | |
39682 | + char *hint; | |
39683 | + struct value *replacement; | |
39684 | + int string_print = 0; | |
39685 | + | |
39686 | + hint = gdbpy_get_display_hint (value_formatter); | |
39687 | + if (hint) | |
39688 | + { | |
39689 | + if (!strcmp (hint, "string")) | |
39690 | + string_print = 1; | |
39691 | + xfree (hint); | |
39692 | + } | |
39693 | + | |
39694 | + thevalue = apply_varobj_pretty_printer (value_formatter, | |
39695 | + &replacement); | |
39696 | + if (thevalue && !string_print) | |
39697 | + { | |
39698 | + PyGILState_Release (state); | |
39699 | + return thevalue; | |
39700 | + } | |
39701 | + if (replacement) | |
39702 | + value = replacement; | |
39703 | + } | |
39704 | + PyGILState_Release (state); | |
39705 | + } | |
39706 | +#endif | |
39707 | + | |
39708 | stb = mem_fileopen (); | |
39709 | old_chain = make_cleanup_ui_file_delete (stb); | |
39710 | ||
39711 | get_formatted_print_options (&opts, format_code[(int) format]); | |
39712 | opts.deref_ref = 0; | |
39713 | - common_val_print (value, stb, 0, &opts, current_language); | |
39714 | + opts.raw = 1; | |
39715 | + if (thevalue) | |
39716 | + { | |
39717 | + struct type *string_char_type; | |
39718 | + | |
39719 | + make_cleanup (xfree, thevalue); | |
39720 | + | |
39721 | + /* OUTPUT is already in the hosts's charset. */ | |
39722 | + string_char_type = language_string_char_type (current_language, | |
39723 | + current_gdbarch); | |
39724 | + LA_PRINT_STRING (stb, string_char_type, (gdb_byte *) thevalue, | |
39725 | + strlen (thevalue), 0, &opts); | |
39726 | + } | |
39727 | + else | |
39728 | + common_val_print (value, stb, 0, &opts, current_language); | |
39729 | thevalue = ui_file_xstrdup (stb, &dummy); | |
39730 | ||
39731 | do_cleanups (old_chain); | |
39732 | @@ -1900,7 +2420,7 @@ varobj_floating_p (struct varobj *var) | |
39733 | value is not known. | |
39734 | ||
39735 | If WAS_PTR is not NULL, set *WAS_PTR to 0 or 1 | |
39736 | - depending on whether pointer was deferenced | |
39737 | + depending on whether pointer was dereferenced | |
39738 | in this function. */ | |
39739 | static void | |
39740 | adjust_value_for_child_access (struct value **value, | |
39741 | @@ -2269,6 +2789,11 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format) | |
39742 | catch that case explicitly. */ | |
39743 | struct type *type = get_type (var); | |
39744 | ||
39745 | + /* If we have a custom formatter, return whatever string it has | |
39746 | + produced. */ | |
39747 | + if (var->pretty_printer && var->print_value) | |
39748 | + return xstrdup (var->print_value); | |
39749 | + | |
39750 | /* Strip top-level references. */ | |
39751 | while (TYPE_CODE (type) == TYPE_CODE_REF) | |
39752 | type = check_typedef (TYPE_TARGET_TYPE (type)); | |
39753 | @@ -2313,7 +2838,8 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format) | |
39754 | if (format == var->format) | |
39755 | return xstrdup (var->print_value); | |
39756 | else | |
39757 | - return value_get_print_value (var->value, format); | |
39758 | + return value_get_print_value (var->value, format, | |
39759 | + var->pretty_printer); | |
39760 | } | |
39761 | } | |
39762 | } | |
39763 | diff --git a/gdb/varobj.h b/gdb/varobj.h | |
39764 | index f2cdcf8..10758d6 100644 | |
39765 | --- a/gdb/varobj.h | |
39766 | +++ b/gdb/varobj.h | |
39767 | @@ -72,7 +72,12 @@ typedef struct varobj_update_result_t | |
39768 | struct varobj *varobj; | |
39769 | int type_changed; | |
39770 | int changed; | |
39771 | + int children_changed; | |
39772 | enum varobj_scope_status status; | |
39773 | + /* This variable is used internally by varobj_update to indicate if the | |
39774 | + new value of varobj is already computed and installed, or has to | |
39775 | + be yet installed. Don't use this outside varobj.c */ | |
39776 | + int value_installed; | |
39777 | } varobj_update_result; | |
39778 | ||
39779 | DEF_VEC_O (varobj_update_result); | |
39780 | @@ -107,6 +112,14 @@ extern void varobj_set_frozen (struct varobj *var, int frozen); | |
39781 | ||
39782 | extern int varobj_get_frozen (struct varobj *var); | |
39783 | ||
39784 | +extern void varobj_get_child_range (struct varobj *var, | |
39785 | + VEC (varobj_p) *children, | |
39786 | + int *from, int *to); | |
39787 | + | |
39788 | +extern void varobj_set_child_range (struct varobj *var, int from, int to); | |
39789 | + | |
39790 | +extern char *varobj_get_display_hint (struct varobj *var); | |
39791 | + | |
39792 | extern int varobj_get_num_children (struct varobj *var); | |
39793 | ||
39794 | /* Return the list of children of VAR. The returned vector | |
39795 | @@ -141,4 +154,13 @@ extern int varobj_editable_p (struct varobj *var); | |
39796 | ||
39797 | extern int varobj_floating_p (struct varobj *var); | |
39798 | ||
39799 | +extern void | |
39800 | +varobj_set_visualizer (struct varobj *var, const char *visualizer); | |
39801 | + | |
39802 | +extern void | |
39803 | +varobj_clear_type_visualizers (); | |
39804 | + | |
39805 | +extern void | |
39806 | +varobj_set_visualizer (struct varobj *var, const char *visualizer); | |
39807 | + | |
39808 | #endif /* VAROBJ_H */ | |
39809 | diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c | |
39810 | index aab3e48..d41738b 100644 | |
39811 | --- a/gdb/xcoffread.c | |
39812 | +++ b/gdb/xcoffread.c | |
39813 | @@ -3021,6 +3021,7 @@ static struct sym_fns xcoff_sym_fns = | |
39814 | xcoff_new_init, /* sym_new_init: init anything gbl to entire symtab */ | |
39815 | xcoff_symfile_init, /* sym_init: read initial info, setup for sym_read() */ | |
39816 | xcoff_initial_scan, /* sym_read: read a symbol file into symtab */ | |
39817 | + NULL, /* sym_read_psymbols */ | |
39818 | xcoff_symfile_finish, /* sym_finish: finished with file, cleanup */ | |
39819 | xcoff_symfile_offsets, /* sym_offsets: xlate offsets ext->int form */ | |
39820 | default_symfile_segments, /* sym_segments: Get segment information from | |
39821 | diff --git a/gdb/xml-syscall.c b/gdb/xml-syscall.c | |
39822 | new file mode 100644 | |
39823 | index 0000000..498f58a | |
39824 | --- /dev/null | |
39825 | +++ b/gdb/xml-syscall.c | |
39826 | @@ -0,0 +1,423 @@ | |
39827 | +/* Functions that provide the mechanism to parse a syscall XML file | |
39828 | + and get its values. | |
39829 | + | |
39830 | + Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, | |
39831 | + 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008 | |
39832 | + Free Software Foundation, Inc. | |
39833 | + | |
39834 | + This file is part of GDB. | |
39835 | + | |
39836 | + This program is free software; you can redistribute it and/or modify | |
39837 | + it under the terms of the GNU General Public License as published by | |
39838 | + the Free Software Foundation; either version 3 of the License, or | |
39839 | + (at your option) any later version. | |
39840 | + | |
39841 | + This program is distributed in the hope that it will be useful, | |
39842 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
39843 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
39844 | + GNU General Public License for more details. | |
39845 | + | |
39846 | + You should have received a copy of the GNU General Public License | |
39847 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
39848 | + | |
39849 | +#include "defs.h" | |
39850 | +#include "gdbtypes.h" | |
39851 | +#include "xml-support.h" | |
39852 | +#include "xml-syscall.h" | |
39853 | + | |
39854 | +#include "filenames.h" | |
39855 | + | |
39856 | +#include "gdb_assert.h" | |
39857 | + | |
39858 | +#ifndef HAVE_LIBEXPAT | |
39859 | + | |
39860 | +/* Dummy functions to indicate that there's no support for fetching | |
39861 | + syscalls information. */ | |
39862 | + | |
39863 | +static void | |
39864 | +syscall_warn_user (void) | |
39865 | +{ | |
39866 | + static int have_warned = 0; | |
39867 | + if (!have_warned) | |
39868 | + { | |
39869 | + have_warned = 1; | |
39870 | + warning (_("Can not parse XML syscalls information; XML support was " | |
39871 | + "disabled at compile time")); | |
39872 | + } | |
39873 | +} | |
39874 | + | |
39875 | +const struct syscalls_info * | |
39876 | +xml_init_syscalls_info (const char *filename) | |
39877 | +{ | |
39878 | + syscall_warn_user (); | |
39879 | + return NULL; | |
39880 | +} | |
39881 | + | |
39882 | +int | |
39883 | +xml_get_syscall_number (const struct syscalls_info *sysinfo, | |
39884 | + const char *syscall_name) | |
39885 | +{ | |
39886 | + syscall_warn_user (); | |
39887 | + return UNKNOWN_SYSCALL; | |
39888 | +} | |
39889 | + | |
39890 | +const char * | |
39891 | +xml_get_syscall_name (const struct syscalls_info *sysinfo, | |
39892 | + int syscall_number) | |
39893 | +{ | |
39894 | + syscall_warn_user (); | |
39895 | + return NULL; | |
39896 | +} | |
39897 | + | |
39898 | +int | |
39899 | +xml_number_of_syscalls (const struct syscalls_info *sysinfo) | |
39900 | +{ | |
39901 | + syscall_warn_user (); | |
39902 | + return 0; | |
39903 | +} | |
39904 | + | |
39905 | +const char ** | |
39906 | +xml_list_of_syscalls (const struct syscalls_info *sysinfo) | |
39907 | +{ | |
39908 | + syscall_warn_user (); | |
39909 | + return NULL; | |
39910 | +} | |
39911 | + | |
39912 | +#else | |
39913 | + | |
39914 | +/* Structure which describes a syscall. */ | |
39915 | + | |
39916 | +typedef struct syscall_desc | |
39917 | +{ | |
39918 | + /* The syscall number. */ | |
39919 | + | |
39920 | + int number; | |
39921 | + | |
39922 | + /* The syscall name. */ | |
39923 | + | |
39924 | + char *name; | |
39925 | +} *syscall_desc_p; | |
39926 | +DEF_VEC_P(syscall_desc_p); | |
39927 | + | |
39928 | +/* Structure that represents syscalls information. */ | |
39929 | + | |
39930 | +struct syscalls_info | |
39931 | +{ | |
39932 | + /* The syscalls. */ | |
39933 | + | |
39934 | + VEC(syscall_desc_p) *syscalls; | |
39935 | +}; | |
39936 | + | |
39937 | +/* Callback data for syscall information parsing. */ | |
39938 | + | |
39939 | +struct syscall_parsing_data | |
39940 | +{ | |
39941 | + /* The syscalls_info we are building. */ | |
39942 | + | |
39943 | + struct syscalls_info *sysinfo; | |
39944 | +}; | |
39945 | + | |
39946 | + | |
39947 | +static struct syscalls_info * | |
39948 | +allocate_syscalls_info (void) | |
39949 | +{ | |
39950 | + return XZALLOC (struct syscalls_info); | |
39951 | +} | |
39952 | + | |
39953 | +static void | |
39954 | +sysinfo_free_syscalls_desc (struct syscall_desc *sd) | |
39955 | +{ | |
39956 | + xfree (sd->name); | |
39957 | +} | |
39958 | + | |
39959 | +static void | |
39960 | +free_syscalls_info (void *arg) | |
39961 | +{ | |
39962 | + struct syscalls_info *sysinfo = arg; | |
39963 | + struct syscall_desc *sysdesc; | |
39964 | + int i; | |
39965 | + | |
39966 | + for (i = 0; | |
39967 | + VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc); | |
39968 | + i++) | |
39969 | + sysinfo_free_syscalls_desc (sysdesc); | |
39970 | + VEC_free (syscall_desc_p, sysinfo->syscalls); | |
39971 | + | |
39972 | + xfree (sysinfo); | |
39973 | +} | |
39974 | + | |
39975 | +struct cleanup * | |
39976 | +make_cleanup_free_syscalls_info (struct syscalls_info *sysinfo) | |
39977 | +{ | |
39978 | + return make_cleanup (free_syscalls_info, sysinfo); | |
39979 | +} | |
39980 | + | |
39981 | +/* Open FILENAME, read all its text into memory, close it, and return | |
39982 | + the text. If something goes wrong, return NULL and warn. */ | |
39983 | + | |
39984 | +static char * | |
39985 | +fetch_xml_from_file (const char *filename, void *baton) | |
39986 | +{ | |
39987 | + const char *dirname = baton; | |
39988 | + FILE *file; | |
39989 | + struct cleanup *back_to; | |
39990 | + char *text; | |
39991 | + size_t len, offset; | |
39992 | + | |
39993 | + if (dirname && *dirname) | |
39994 | + { | |
39995 | + char *fullname = concat (dirname, "/", filename, (char *) NULL); | |
39996 | + if (fullname == NULL) | |
39997 | + nomem (0); | |
39998 | + file = fopen (fullname, FOPEN_RT); | |
39999 | + xfree (fullname); | |
40000 | + } | |
40001 | + else | |
40002 | + file = fopen (filename, FOPEN_RT); | |
40003 | + | |
40004 | + if (file == NULL) | |
40005 | + return NULL; | |
40006 | + | |
40007 | + back_to = make_cleanup_fclose (file); | |
40008 | + | |
40009 | + /* Read in the whole file, one chunk at a time. */ | |
40010 | + len = 4096; | |
40011 | + offset = 0; | |
40012 | + text = xmalloc (len); | |
40013 | + make_cleanup (free_current_contents, &text); | |
40014 | + while (1) | |
40015 | + { | |
40016 | + size_t bytes_read; | |
40017 | + | |
40018 | + /* Continue reading where the last read left off. Leave at least | |
40019 | + one byte so that we can NUL-terminate the result. */ | |
40020 | + bytes_read = fread (text + offset, 1, len - offset - 1, file); | |
40021 | + if (ferror (file)) | |
40022 | + { | |
40023 | + warning (_("Read error from \"%s\""), filename); | |
40024 | + do_cleanups (back_to); | |
40025 | + return NULL; | |
40026 | + } | |
40027 | + | |
40028 | + offset += bytes_read; | |
40029 | + | |
40030 | + if (feof (file)) | |
40031 | + break; | |
40032 | + | |
40033 | + len = len * 2; | |
40034 | + text = xrealloc (text, len); | |
40035 | + } | |
40036 | + | |
40037 | + fclose (file); | |
40038 | + discard_cleanups (back_to); | |
40039 | + | |
40040 | + text[offset] = '\0'; | |
40041 | + return text; | |
40042 | +} | |
40043 | + | |
40044 | +static void | |
40045 | +syscall_create_syscall_desc (struct syscalls_info *sysinfo, | |
40046 | + const char *name, int number) | |
40047 | +{ | |
40048 | + struct syscall_desc *sysdesc = XZALLOC (struct syscall_desc); | |
40049 | + | |
40050 | + sysdesc->name = xstrdup (name); | |
40051 | + sysdesc->number = number; | |
40052 | + | |
40053 | + VEC_safe_push (syscall_desc_p, sysinfo->syscalls, sysdesc); | |
40054 | +} | |
40055 | + | |
40056 | +/* Handle the start of a <syscalls_info> element. */ | |
40057 | + | |
40058 | +static void | |
40059 | +syscall_start_syscalls_info (struct gdb_xml_parser *parser, | |
40060 | + const struct gdb_xml_element *element, | |
40061 | + void *user_data, | |
40062 | + VEC(gdb_xml_value_s) *attributes) | |
40063 | +{ | |
40064 | + struct syscall_parsing_data *data = user_data; | |
40065 | + struct syscalls_info *sysinfo = data->sysinfo; | |
40066 | +} | |
40067 | + | |
40068 | +/* Handle the start of a <syscall> element. */ | |
40069 | + | |
40070 | +static void | |
40071 | +syscall_start_syscall (struct gdb_xml_parser *parser, | |
40072 | + const struct gdb_xml_element *element, | |
40073 | + void *user_data, VEC(gdb_xml_value_s) *attributes) | |
40074 | +{ | |
40075 | + struct syscall_parsing_data *data = user_data; | |
40076 | + struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes); | |
40077 | + int len, i; | |
40078 | + /* syscall info. */ | |
40079 | + char *name = NULL; | |
40080 | + int number = 0; | |
40081 | + | |
40082 | + len = VEC_length (gdb_xml_value_s, attributes); | |
40083 | + | |
40084 | + for (i = 0; i < len; i++) | |
40085 | + { | |
40086 | + if (strcmp (attrs[i].name, "name") == 0) | |
40087 | + name = attrs[i].value; | |
40088 | + else if (strcmp (attrs[i].name, "number") == 0) | |
40089 | + number = * (ULONGEST *) attrs[i].value; | |
40090 | + else | |
40091 | + internal_error (__FILE__, __LINE__, | |
40092 | + _("Unknown attribute name '%s'."), attrs[i].name); | |
40093 | + } | |
40094 | + | |
40095 | + syscall_create_syscall_desc (data->sysinfo, name, number); | |
40096 | +} | |
40097 | + | |
40098 | + | |
40099 | +/* The elements and attributes of an XML syscall document. */ | |
40100 | + | |
40101 | +static const struct gdb_xml_attribute syscall_attr[] = { | |
40102 | + { "number", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, | |
40103 | + { "name", GDB_XML_AF_NONE, NULL, NULL }, | |
40104 | + { NULL, GDB_XML_AF_NONE, NULL, NULL } | |
40105 | +}; | |
40106 | + | |
40107 | +static const struct gdb_xml_element syscalls_info_children[] = { | |
40108 | + { "syscall", syscall_attr, NULL, | |
40109 | + GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, | |
40110 | + syscall_start_syscall, NULL }, | |
40111 | + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } | |
40112 | +}; | |
40113 | + | |
40114 | +static const struct gdb_xml_element syselements[] = { | |
40115 | + { "syscalls_info", NULL, syscalls_info_children, | |
40116 | + GDB_XML_EF_NONE, syscall_start_syscalls_info, NULL }, | |
40117 | + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } | |
40118 | +}; | |
40119 | + | |
40120 | +static struct syscalls_info * | |
40121 | +syscall_parse_xml (const char *document, xml_fetch_another fetcher, | |
40122 | + void *fetcher_baton) | |
40123 | +{ | |
40124 | + struct cleanup *result_cleanup; | |
40125 | + struct gdb_xml_parser *parser; | |
40126 | + struct syscall_parsing_data data; | |
40127 | + char *expanded_text; | |
40128 | + int i; | |
40129 | + | |
40130 | + parser = gdb_xml_create_parser_and_cleanup (_("syscalls info"), | |
40131 | + syselements, &data); | |
40132 | + | |
40133 | + memset (&data, 0, sizeof (struct syscall_parsing_data)); | |
40134 | + data.sysinfo = allocate_syscalls_info (); | |
40135 | + result_cleanup = make_cleanup_free_syscalls_info (data.sysinfo); | |
40136 | + | |
40137 | + if (gdb_xml_parse (parser, document) == 0) | |
40138 | + { | |
40139 | + /* Parsed successfully. */ | |
40140 | + discard_cleanups (result_cleanup); | |
40141 | + return data.sysinfo; | |
40142 | + } | |
40143 | + else | |
40144 | + { | |
40145 | + warning (_("Could not load XML syscalls info; ignoring")); | |
40146 | + do_cleanups (result_cleanup); | |
40147 | + return NULL; | |
40148 | + } | |
40149 | +} | |
40150 | + | |
40151 | +const struct syscalls_info * | |
40152 | +xml_init_syscalls_info (const char *filename) | |
40153 | +{ | |
40154 | + char *full_file; | |
40155 | + char *dirname; | |
40156 | + struct syscalls_info *sysinfo; | |
40157 | + struct cleanup *back_to; | |
40158 | + | |
40159 | + full_file = fetch_xml_from_file (filename, gdb_datadir); | |
40160 | + if (full_file == NULL) | |
40161 | + { | |
40162 | + warning (_("Could not open \"%s\""), filename); | |
40163 | + return NULL; | |
40164 | + } | |
40165 | + | |
40166 | + back_to = make_cleanup (xfree, full_file); | |
40167 | + | |
40168 | + dirname = ldirname (filename); | |
40169 | + if (dirname != NULL) | |
40170 | + make_cleanup (xfree, dirname); | |
40171 | + | |
40172 | + sysinfo = syscall_parse_xml (full_file, fetch_xml_from_file, dirname); | |
40173 | + do_cleanups (back_to); | |
40174 | + | |
40175 | + return sysinfo; | |
40176 | +} | |
40177 | + | |
40178 | +int | |
40179 | +xml_get_syscall_number (const struct syscalls_info *sysinfo, | |
40180 | + const char *syscall_name) | |
40181 | +{ | |
40182 | + struct syscall_desc *sysdesc; | |
40183 | + int i; | |
40184 | + | |
40185 | + if (sysinfo == NULL | |
40186 | + || syscall_name == NULL) | |
40187 | + return UNKNOWN_SYSCALL; | |
40188 | + | |
40189 | + for (i = 0; | |
40190 | + VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc); | |
40191 | + i++) | |
40192 | + if (strcmp (sysdesc->name, syscall_name) == 0) | |
40193 | + return sysdesc->number; | |
40194 | + | |
40195 | + return UNKNOWN_SYSCALL; | |
40196 | +} | |
40197 | + | |
40198 | +const char * | |
40199 | +xml_get_syscall_name (const struct syscalls_info *sysinfo, | |
40200 | + int syscall_number) | |
40201 | +{ | |
40202 | + struct syscall_desc *sysdesc; | |
40203 | + int i; | |
40204 | + | |
40205 | + if (sysinfo == NULL | |
40206 | + || syscall_number < 0) | |
40207 | + return NULL; | |
40208 | + | |
40209 | + for (i = 0; | |
40210 | + VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc); | |
40211 | + i++) | |
40212 | + if (sysdesc->number == syscall_number) | |
40213 | + return sysdesc->name; | |
40214 | + | |
40215 | + return NULL; | |
40216 | +} | |
40217 | + | |
40218 | +int | |
40219 | +xml_number_of_syscalls (const struct syscalls_info *sysinfo) | |
40220 | +{ | |
40221 | + return (sysinfo == NULL ? 0 : VEC_length(syscall_desc_p, | |
40222 | + sysinfo->syscalls)); | |
40223 | +} | |
40224 | + | |
40225 | +const char ** | |
40226 | +xml_list_of_syscalls (const struct syscalls_info *sysinfo) | |
40227 | +{ | |
40228 | + struct syscall_desc *sysdesc; | |
40229 | + const char **names = NULL; | |
40230 | + int nsyscalls; | |
40231 | + int i; | |
40232 | + | |
40233 | + if (sysinfo == NULL) | |
40234 | + return NULL; | |
40235 | + | |
40236 | + nsyscalls = VEC_length (syscall_desc_p, sysinfo->syscalls); | |
40237 | + names = xmalloc ((nsyscalls + 1) * sizeof (char *)); | |
40238 | + | |
40239 | + for (i = 0; | |
40240 | + VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc); | |
40241 | + i++) | |
40242 | + names[i] = sysdesc->name; | |
40243 | + | |
40244 | + names[i] = NULL; | |
40245 | + | |
40246 | + return names; | |
40247 | +} | |
40248 | + | |
40249 | +#endif /* HAVE_LIBEXPAT */ | |
40250 | diff --git a/gdb/xml-syscall.h b/gdb/xml-syscall.h | |
40251 | new file mode 100644 | |
40252 | index 0000000..ff11f20 | |
40253 | --- /dev/null | |
40254 | +++ b/gdb/xml-syscall.h | |
40255 | @@ -0,0 +1,64 @@ | |
40256 | +/* Functions that provide the mechanism to parse a syscall XML file | |
40257 | + and get its values. | |
40258 | + | |
40259 | + Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, | |
40260 | + 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008 | |
40261 | + Free Software Foundation, Inc. | |
40262 | + | |
40263 | + This file is part of GDB. | |
40264 | + | |
40265 | + This program is free software; you can redistribute it and/or modify | |
40266 | + it under the terms of the GNU General Public License as published by | |
40267 | + the Free Software Foundation; either version 3 of the License, or | |
40268 | + (at your option) any later version. | |
40269 | + | |
40270 | + This program is distributed in the hope that it will be useful, | |
40271 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
40272 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
40273 | + GNU General Public License for more details. | |
40274 | + | |
40275 | + You should have received a copy of the GNU General Public License | |
40276 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
40277 | + | |
40278 | +#ifndef XML_SYSCALL_H | |
40279 | +#define XML_SYSCALL_H 1 | |
40280 | + | |
40281 | +/* Structure that stores information about the system's | |
40282 | + syscalls. */ | |
40283 | + | |
40284 | +struct syscalls_info; | |
40285 | + | |
40286 | + | |
40287 | +/* Function responsible for initializing the information | |
40288 | + about the syscalls. It reads the XML file and fills the | |
40289 | + struct syscalls_info with the values. | |
40290 | + | |
40291 | + Returns the struct syscalls_info if the file is valid, NULL otherwise. */ | |
40292 | + | |
40293 | +const struct syscalls_info *xml_init_syscalls_info (const char *); | |
40294 | + | |
40295 | +/* Function that retrieves the syscall number corresponding to the given | |
40296 | + name. | |
40297 | + | |
40298 | + Returns the syscall number if found, or otherwise. */ | |
40299 | + | |
40300 | +int xml_get_syscall_number (const struct syscalls_info *, const char *); | |
40301 | + | |
40302 | +/* Function that retrieves the syscall name corresponding to the given | |
40303 | + number. | |
40304 | + | |
40305 | + Returns the syscall name if found, NULL otherwise. */ | |
40306 | +const char *xml_get_syscall_name (const struct syscalls_info *, int); | |
40307 | + | |
40308 | +/* Function that returns the number of syscalls defined in the system. | |
40309 | + | |
40310 | + Returns the number of syscalls, or zero otherwise. */ | |
40311 | +int xml_number_of_syscalls (const struct syscalls_info *); | |
40312 | + | |
40313 | +/* Function used to retrieve the list of syscalls in the system. This list | |
40314 | + is returned as an array of strings. | |
40315 | + | |
40316 | + Returns the list of syscalls in the system, or NULL otherwise. */ | |
40317 | +const char **xml_list_of_syscalls (const struct syscalls_info *sysinfo); | |
40318 | + | |
40319 | +#endif /* XML_SYSCALL_H */ | |
40320 | diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c | |
40321 | index c872db5..5e70395 100644 | |
40322 | --- a/opcodes/ppc-opc.c | |
40323 | +++ b/opcodes/ppc-opc.c | |
40324 | @@ -4560,8 +4560,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { | |
40325 | ||
40326 | {"lhbrx", X(31,790), X_MASK, COM, PPCNONE, {RT, RA0, RB}}, | |
40327 | ||
40328 | -{"lfqx", X(31,791), X_MASK, POWER2, PPCNONE, {FRT, RA, RB}}, | |
40329 | {"lfdpx", X(31,791), X_MASK, POWER6, POWER7, {FRT, RA, RB}}, | |
40330 | +{"lfqx", X(31,791), X_MASK, POWER2, PPCNONE, {FRT, RA, RB}}, | |
40331 | ||
40332 | {"sraw", XRC(31,792,0), X_MASK, PPCCOM, PPCNONE, {RA, RS, RB}}, | |
40333 | {"sra", XRC(31,792,0), X_MASK, PWRCOM, PPCNONE, {RA, RS, RB}}, | |
40334 | @@ -4638,8 +4638,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { | |
40335 | ||
40336 | {"sthbrx", X(31,918), X_MASK, COM, PPCNONE, {RS, RA0, RB}}, | |
40337 | ||
40338 | -{"stfqx", X(31,919), X_MASK, POWER2, PPCNONE, {FRS, RA, RB}}, | |
40339 | {"stfdpx", X(31,919), X_MASK, POWER6, PPCNONE, {FRS, RA, RB}}, | |
40340 | +{"stfqx", X(31,919), X_MASK, POWER2, PPCNONE, {FRS, RA, RB}}, | |
40341 | ||
40342 | {"sraq", XRC(31,920,0), X_MASK, M601, PPCNONE, {RA, RS, RB}}, | |
40343 | {"sraq.", XRC(31,920,1), X_MASK, M601, PPCNONE, {RA, RS, RB}}, | |
40344 | @@ -4801,12 +4801,12 @@ const struct powerpc_opcode powerpc_opcodes[] = { | |
40345 | ||
40346 | {"psq_l", OP(56), OP_MASK, PPCPS, PPCNONE, {FRT,PSD,RA,PSW,PSQ}}, | |
40347 | ||
40348 | +{"lfdp", OP(57), OP_MASK, POWER6, POWER7, {FRT, D, RA0}}, | |
40349 | + | |
40350 | {"lfqu", OP(57), OP_MASK, POWER2, PPCNONE, {FRT, D, RA0}}, | |
40351 | ||
40352 | {"psq_lu", OP(57), OP_MASK, PPCPS, PPCNONE, {FRT,PSD,RA,PSW,PSQ}}, | |
40353 | ||
40354 | -{"lfdp", OP(57), OP_MASK, POWER6, POWER7, {FRT, D, RA0}}, | |
40355 | - | |
40356 | {"ld", DSO(58,0), DS_MASK, PPC64, PPCNONE, {RT, DS, RA0}}, | |
40357 | {"ldu", DSO(58,1), DS_MASK, PPC64, PPCNONE, {RT, DS, RAL}}, | |
40358 | {"lwa", DSO(58,2), DS_MASK, PPC64, PPCNONE, {RT, DS, RA0}}, | |
40359 | @@ -4921,10 +4921,6 @@ const struct powerpc_opcode powerpc_opcodes[] = { | |
40360 | {"fcfidus", XRC(59,974,0), XRA_MASK, POWER7, PPCNONE, {FRT, FRB}}, | |
40361 | {"fcfidus.", XRC(59,974,1), XRA_MASK, POWER7, PPCNONE, {FRT, FRB}}, | |
40362 | ||
40363 | -{"stfq", OP(60), OP_MASK, POWER2, PPCNONE, {FRS, D, RA}}, | |
40364 | - | |
40365 | -{"psq_st", OP(60), OP_MASK, PPCPS, PPCNONE, {FRS,PSD,RA,PSW,PSQ}}, | |
40366 | - | |
40367 | {"xxsldwi", XX3(60,2), XX3SHW_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6, SHW}}, | |
40368 | {"xxsel", XX4(60,3), XX4_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6, XC6}}, | |
40369 | {"xxspltd", XX3(60,10), XX3DM_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6S, DMEX}}, | |
40370 | @@ -5067,12 +5063,16 @@ const struct powerpc_opcode powerpc_opcodes[] = { | |
40371 | {"xvcvsxddp", XX2(60,504), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}}, | |
40372 | {"xvnegdp", XX2(60,505), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}}, | |
40373 | ||
40374 | -{"psq_stu", OP(61), OP_MASK, PPCPS, PPCNONE, {FRS,PSD,RA,PSW,PSQ}}, | |
40375 | +{"stfq", OP(60), OP_MASK, POWER2, PPCNONE, {FRS, D, RA}}, | |
40376 | ||
40377 | -{"stfqu", OP(61), OP_MASK, POWER2, PPCNONE, {FRS, D, RA}}, | |
40378 | +{"psq_st", OP(60), OP_MASK, PPCPS, PPCNONE, {FRS,PSD,RA,PSW,PSQ}}, | |
40379 | ||
40380 | {"stfdp", OP(61), OP_MASK, POWER6, PPCNONE, {FRT, D, RA0}}, | |
40381 | ||
40382 | +{"stfqu", OP(61), OP_MASK, POWER2, PPCNONE, {FRS, D, RA}}, | |
40383 | + | |
40384 | +{"psq_stu", OP(61), OP_MASK, PPCPS, PPCNONE, {FRS,PSD,RA,PSW,PSQ}}, | |
40385 | + | |
40386 | {"std", DSO(62,0), DS_MASK, PPC64, PPCNONE, {RS, DS, RA0}}, | |
40387 | {"stdu", DSO(62,1), DS_MASK, PPC64, PPCNONE, {RS, DS, RAS}}, | |
40388 | {"stq", DSO(62,2), DS_MASK, POWER4, PPCNONE, {RSQ, DS, RA0}}, |