From: nobody <> Date: Sun, 14 May 2006 22:27:27 +0000 (+0000) Subject: This commit was manufactured by cvs2svn to create branch 'gdb_6_5-branch'. X-Git-Tag: gdb_6_5-2006-05-14-branchpoint X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=079230fc5086db703b49d21b2ac97350ca377a2f;p=thirdparty%2Fbinutils-gdb.git This commit was manufactured by cvs2svn to create branch 'gdb_6_5-branch'. Sprout from nickrob-async-20060513-branch 2006-05-12 01:45:11 UTC nobody 'This commit was manufactured by cvs2svn to create branch 'nickrob-' Cherrypick from master 2006-05-14 22:27:26 UTC Nick Roberts '(gdbmi-send): Correct regexp for repeat commands.': ChangeLog bfd/version.h config.guess config.sub gdb/ChangeLog gdb/MAINTAINERS gdb/Makefile.in gdb/config/powerpc/nbsd.mh gdb/config/powerpc/nbsd.mt gdb/doc/ChangeLog gdb/doc/gdb.texinfo gdb/dwarf2read.c gdb/m2-lang.h gdb/m2-typeprint.c gdb/m2-valprint.c gdb/mi/gdb-mi.el gdb/ppcnbsd-nat.c gdb/ppcnbsd-tdep.c gdb/ppcnbsd-tdep.h gdb/version.in libiberty/ChangeLog libiberty/cplus-dem.c opcodes/ChangeLog opcodes/mips16-opc.c --- diff --git a/ChangeLog b/ChangeLog index 08a35ec3832..aee54b1c491 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2006-05-14 Ben Elliston + + * config.sub, config.guess: Update from upstream sources. + 2006-05-12 Ben Elliston * config.sub, config.guess: Update from upstream sources. diff --git a/bfd/version.h b/bfd/version.h index 4f0f1d56280..18021474248 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -1,3 +1,3 @@ -#define BFD_VERSION_DATE 20060512 +#define BFD_VERSION_DATE 20060514 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_string@ diff --git a/config.guess b/config.guess index 7149b1bbbdd..c085f4f51a2 100755 --- a/config.guess +++ b/config.guess @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. -timestamp='2006-04-26' +timestamp='2006-05-13' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -989,7 +989,7 @@ EOF LIBC=gnulibc1 # endif #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun) + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout diff --git a/config.sub b/config.sub index 710f34846ac..4d936e23942 100755 --- a/config.sub +++ b/config.sub @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. -timestamp='2006-05-12' +timestamp='2006-05-13' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -1366,6 +1366,9 @@ else # system, and we'll never get to this point. case $basic_machine in + spu-*) + os=-elf + ;; *-acorn) os=-riscix1.2 ;; @@ -1375,9 +1378,9 @@ case $basic_machine in arm*-semi) os=-aout ;; - c4x-* | tic4x-*) - os=-coff - ;; + c4x-* | tic4x-*) + os=-coff + ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6842b6b7c3e..2bc3105bb33 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,93 @@ +2006-05-14 Nick Roberts + + * mi/gdb-mi.el (gdbmi-send): Correct regexp for repeat commands. + (gdbmi): Use new variable name gdb-pc-address. + (gdbmi-frame-handler): Use new variable name gdb-pc-address. + Check that a match has been found. + +2006-05-13 Gaius Mulley + + * m2-lang.h: Added function extern prototypes for + m2_is_long_set and get_long_set_bounds. + * m2-typeprint.c: Complete replacement. + (m2_print_type): Walk the Modula-2 type tree. + (m2_type_name): New function. + (m2_range): New function. + (m2_typedef): New function. + (m2_array): New function. + (m2_pointer): New function. + (m2_ref): New function. + (m2_unknown): New function. + (m2_union): New function. + (m2_procedure): New function. + (m2_print_bounds): New function. + (m2_short_set): New function. + (m2_is_long_set): New function. + (m2_get_discrete_bounds): New function. + (m2_is_long_set_of_type): New function. + (m2_long_set): New function. + (m2_record_fields): New function. + (m2_enum): New function. + * dwarf2read.c: Modified. + (read_set_type): New function. + (process_die): Call read_set_type. + (read_base_type): Modifed. + (set_cu_language): Added Modula-2 case clause. + * m2-valprint.c: Complete replacement. + (print_function_pointer_address): New function. + (get_long_set_bounds): New function. + (m2_print_long_set): New function. + (print_unpacked_pointer): New function. + (print_variable_at_address): New function. + (m2_val_print): Replaced. + * gdb/MAINTAINERS (Write After Approval): Added + Gaius Mulley + +2006-05-12 Mark Kettenis + + * ppcnbsd-tdep.h: Update copyright year. Include + (ppcnbsd_supply_reg, ppcnbsd_fill_reg, ppcnbsd_supply_fpreg) + (ppcnbsd_fill_fpreg): Remove prototypes. + (struct regset): Add forward declaration. + (ppcnbsd_gregset, ppcnbsd_fpregset): Extern declarations. + * ppcnbsd-tdep.c: Update copyright year. Include "gdbtypes.h", + "regset.h" and "gdb_string.h". Don't include "breakpoint.h", + "value.h", target.h and nbsd-tdep.h". Reorder includes. + (REG_FIXREG_OFFSET, REG_LR_OFFSET, REG_CR_OFFSET, REG_XER_OFFSET) + (REG_CTR_OFFSET, REG_PC_OFFSET, SIZEOF_STRUCT_REG) + (FPREG_FPR_OFFSET, FPREG_FPSCR_OFFSET, SIZEOF_STRUCT_FPREG): + Remove macros. + (ppcnbsd_supply_reg, ppcnbsd_fill_reg, ppcnbsd_supply_fpreg) + (ppcnbsd_fill_fpreg): Remove functions. + (fetch_core_registers, fetch_elfcore_registers): Remove functions. + (ppcnbsd_core_fns, ppcnbsd_elfcore_fns): Remove variables. + (ppcnbsd_reg_offsets): New variable. + (ppcnbsd_gregset, ppcnbsd_fpregset): New variables. + (ppcnbsd_sigtramp_cache_init): Deal with new signal trampoline + introduced in NetBSD 2.0. + (ppcnbsd_sigtramp): Provide complete signal trampoline. + (ppcnbsd2_sigtramp): New variable. + (ppcnbsd_init_abi): Set svr4_fetch_link_map_offsets to + svr4_ilp32_fetch_link_map_offsets. Set regset_from_core_section. + Add ppcnbs2_sigtramp unwinder. + (_initialize_ppcnbsd_tdep): Don't use deprecated_add_core_fns. + Initialize ppcnbsd_reg_offsets. + * ppcnbsd-nat.c: Update copyright year. Reorder includes. + (getregs_supplies): Use regnum instead of regno. + (getfpregs_supplies): Likewise. + (ppcnbsd_fetch_inferior_registers): Likewise. Call + ppc_supply_gregset and ppc_suppply_fpregset instead of + ppcnbsd_supply_reg and ppcnbsd_supply_fpreg + (ppcnbsd_store_inferior_registers): Likewise. Call + ppc_collect_gregset and ppc_collect_fpregset instead of + ppcnbsd_fill_reg and ppcnbsd_fill_fpreg. + (ppcnbsd_supply_pcb): Use `gdb_byte *' instead of `char *'. + (_initialize_ppcnbsd_nat): Add some whitespace. + * Makefile.in (ppcnbsd-nat.o, ppcnbsd-tdep.o): Update dependencies. + * config/powerpc/nbsd.mh (NATDEPFILES): Remove infptrace.o. + (NAT_FILE): Remove. + * config/powerpc/nbsd.mt (TDEPFILES): Remove nbsd-tdep.o. + 2006-05-11 Alfred M. Szmidt * gnu-nat.c (inf_validate_procs): Don't use lvalue in assignments. diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS index 4ed438a94c8..c143a43da7f 100644 --- a/gdb/MAINTAINERS +++ b/gdb/MAINTAINERS @@ -503,6 +503,7 @@ Marko Mlinar markom@opencores.org Alan Modra amodra@bigpond.net.au Jason Molenda jmolenda@apple.com Pierre Muller muller@sources.redhat.com +Gaius Mulley gaius@glam.ac.uk Joseph Myers joseph@codesourcery.com Fernando Nasser fnasser@redhat.com Nathanael Nerode neroden@gcc.gnu.org diff --git a/gdb/Makefile.in b/gdb/Makefile.in index a8b58a1e36a..e8cd87ada60 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -2416,13 +2416,13 @@ ppc-linux-tdep.o: ppc-linux-tdep.c $(defs_h) $(frame_h) $(inferior_h) \ ppcnbsd-nat.o: ppcnbsd-nat.c $(defs_h) $(inferior_h) $(gdb_assert_h) \ $(gdbcore_h) $(regcache_h) $(bsd_kvm_h) $(ppc_tdep_h) \ $(ppcnbsd_tdep_h) $(inf_ptrace_h) -ppcnbsd-tdep.o: ppcnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \ - $(target_h) $(breakpoint_h) $(value_h) $(osabi_h) $(ppc_tdep_h) \ - $(ppcnbsd_tdep_h) $(nbsd_tdep_h) $(tramp_frame_h) $(trad_frame_h) \ - $(gdb_assert_h) $(solib_svr4_h) +ppcnbsd-tdep.o: ppcnbsd-tdep.c $(defs_h) $(gdbcore_h) $(gdb_types_h) \ + $(osabi_h) $(regcache_h) $(regset_h) $(trad_frame_h) \ + $(tramp_frame_h) $(gdb_assert_h) $(gdb_string_h) \ + $(ppc_tdep_h) $(ppcnbsd_tdep_h) $(solib_svr4_h) ppcobsd-nat.o: ppcobsd-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) \ - $(regcache_h) $(ppc_tdep_h) $(ppcobsd_tdep_h) $(inf_ptrace_h) \ - $(bsd_kvm_h) + $(regcache_h) $(ppc_tdep_h) $(ppcobsd_tdep_h) $(bsd_kvm_h) \ + $(inf_ptrace_h) ppcobsd-tdep.o: ppcobsd-tdep.c $(defs_h) $(arch_utils_h) $(floatformat_h) \ $(frame_h) $(frame_unwind_h) $(osabi_h) $(regcache_h) $(regset_h) \ $(symtab_h) $(trad_frame_h) $(gdb_assert_h) $(gdb_string_h) \ diff --git a/gdb/config/powerpc/nbsd.mh b/gdb/config/powerpc/nbsd.mh index 5556886c3ff..db0390c8070 100644 --- a/gdb/config/powerpc/nbsd.mh +++ b/gdb/config/powerpc/nbsd.mh @@ -1,5 +1,4 @@ -# Host: PowerPC, running NetBSD -NATDEPFILES= fork-child.o inf-ptrace.o infptrace.o ppcnbsd-nat.o bsd-kvm.o -NAT_FILE= config/nm-nbsd.h +# Host: NetBSD/powerpc +NATDEPFILES= fork-child.o inf-ptrace.o ppcnbsd-nat.o bsd-kvm.o LOADLIBES= -lkvm diff --git a/gdb/config/powerpc/nbsd.mt b/gdb/config/powerpc/nbsd.mt index 2f50c21a1eb..8cdd39d817c 100644 --- a/gdb/config/powerpc/nbsd.mt +++ b/gdb/config/powerpc/nbsd.mt @@ -1,6 +1,6 @@ -# Target: PowerPC, running NetBSD -TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcnbsd-tdep.o nbsd-tdep.o corelow.o \ - solib.o solib-svr4.o +# Target: NetBSD/powerpc +TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcnbsd-tdep.o \ + corelow.o solib.o solib-svr4.o DEPRECATED_TM_FILE= tm-ppc-eabi.h SIM_OBS = remote-sim.o diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index f75912315a8..cdf4622c3e8 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,12 @@ +2006-05-14 Daniel Jacobowitz + + * gdb.texinfo (General Query Packets): Recommend not starting + new packets with qC and clarify. + +2006-05-13 Gaius Mulley + + * gdb.texinfo (M2 Types): New section. + 2006-05-10 Daniel Jacobowitz * agentexpr.texi: Add a copyright and license notice. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index e2b986a570e..422d63e8799 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -9471,6 +9471,7 @@ table. * M2 Operators:: Built-in operators * Built-In Func/Proc:: Built-in functions and procedures * M2 Constants:: Modula-2 constants +* M2 Types:: Modula-2 types * M2 Defaults:: Default settings for Modula-2 * Deviations:: Deviations from standard Modula-2 * M2 Checks:: Modula-2 type and range checks @@ -9595,7 +9596,7 @@ as @code{^}. @end table @quotation -@emph{Warning:} Sets and their operations are not yet supported, so @value{GDBN} +@emph{Warning:} Set expressions and their operations are not yet supported, so @value{GDBN} treats the use of the operator @code{IN}, or the use of operators @code{+}, @code{-}, @code{*}, @code{/}, @code{=}, , @code{<>}, @code{#}, @code{<=}, and @code{>=} on sets as an error. @@ -9764,6 +9765,170 @@ Pointer constants consist of integral values only. Set constants are not yet supported. @end itemize +@node M2 Types +@subsubsection Modula-2 Types +@cindex Modula-2 types + +Currently @value{GDBN} can print the following data types in Modula-2 +syntax: array types, record types, set types, pointer types, procedure +types, enumerated types, subrange types and base types. You can also +print the contents of variables declared using these type. +This section gives a number of simple source code examples together with +sample @value{GDBN} sessions. + +The first example contains the following section of code: + +@smallexample +VAR + s: SET OF CHAR ; + r: [20..40] ; +@end smallexample + +@noindent +and you can request @value{GDBN} to interrogate the type and value of +@code{r} and @code{s}. + +@smallexample +(@value{GDBP}) print s +@{'A'..'C', 'Z'@} +(@value{GDBP}) ptype s +SET OF CHAR +(@value{GDBP}) print r +21 +(@value{GDBP}) ptype r +[20..40] +@end smallexample + +@noindent +Likewise if your source code declares @code{s} as: + +@smallexample +VAR + s: SET ['A'..'Z'] ; +@end smallexample + +@noindent +then you may query the type of @code{s} by: + +@smallexample +(@value{GDBP}) ptype s +type = SET ['A'..'Z'] +@end smallexample + +@noindent +Note that at present you cannot interactively manipulate set +expressions using the debugger. + +The following example shows how you might declare an array in Modula-2 +and how you can interact with @value{GDBN} to print its type and contents: + +@smallexample +VAR + s: ARRAY [-10..10] OF CHAR ; +@end smallexample + +@smallexample +(@value{GDBP}) ptype s +ARRAY [-10..10] OF CHAR +@end smallexample + +Note that the array handling is not yet complete and although the type +is printed correctly, expression handling still assumes that all +arrays have a lower bound of zero and not @code{-10} as in the example +above. Unbounded arrays are also not yet recognized in @value{GDBN}. + +Here are some more type related Modula-2 examples: + +@smallexample +TYPE + colour = (blue, red, yellow, green) ; + t = [blue..yellow] ; +VAR + s: t ; +BEGIN + s := blue ; +@end smallexample + +@noindent +The @value{GDBN} interaction shows how you can query the data type +and value of a variable. + +@smallexample +(@value{GDBP}) print s +$1 = blue +(@value{GDBP}) ptype t +type = [blue..yellow] +@end smallexample + +@noindent +In this example a Modula-2 array is declared and its contents +displayed. Observe that the contents are written in the same way as +their @code{C} counterparts. + +@smallexample +VAR + s: ARRAY [1..5] OF CARDINAL ; +BEGIN + s[1] := 1 ; +@end smallexample + +@smallexample +(@value{GDBP}) print s +$1 = @{1, 0, 0, 0, 0@} +(@value{GDBP}) ptype s +type = ARRAY [1..5] OF CARDINAL +@end smallexample + +The Modula-2 language interface to @value{GDBN} also understands +pointer types as shown in this example: + +@smallexample +VAR + s: POINTER TO ARRAY [1..5] OF CARDINAL ; +BEGIN + NEW(s) ; + s^[1] := 1 ; +@end smallexample + +@noindent +and you can request that @value{GDBN} describes the type of @code{s}. + +@smallexample +(@value{GDBP}) ptype s +type = POINTER TO ARRAY [1..5] OF CARDINAL +@end smallexample + +@value{GDBN} handles compound types as we can see in this example. +Here we combine array types, record types, pointer types and subrange +types: + +@smallexample +TYPE + foo = RECORD + f1: CARDINAL ; + f2: CHAR ; + f3: myarray ; + END ; + + myarray = ARRAY myrange OF CARDINAL ; + myrange = [-2..2] ; +VAR + s: POINTER TO ARRAY myrange OF foo ; +@end smallexample + +@noindent +and you can ask @value{GDBN} to describe the type of @code{s} as shown +below. + +@smallexample +(@value{GDBP}) ptype s +type = POINTER TO ARRAY [-2..2] OF foo = RECORD + f1 : CARDINAL; + f2 : CHAR; + f3 : ARRAY [-2..2] OF CARDINAL; +END +@end smallexample + @node M2 Defaults @subsubsection Modula-2 defaults @cindex Modula-2 defaults @@ -23101,11 +23266,14 @@ foos) or @samp{Qacme.bar} (for setting bars). The name of a query or set packet should be separated from any parameters by a @samp{:}; the parameters themselves should be separated by @samp{,} or @samp{;}. Stubs must be careful to match the -full packet name, in case packet names have common prefixes. New -packets should not begin with @samp{qP} or @samp{qL}@footnote{The -@samp{qP} and @samp{qL} packets predate these conventions, and don't -have any terminator for the packet name; we suspect they are in -widespread use in places that are difficult to upgrade.}. +full packet name, and check for a separator or the end of the packet, +in case two packet names share a common prefix. New packets should not begin +with @samp{qC}, @samp{qP}, or @samp{qL}@footnote{The @samp{qP} and @samp{qL} +packets predate these conventions, and have arguments without any terminator +for the packet name; we suspect they are in widespread use in places that +are difficult to upgrade. The @samp{qC} packet has no arguments, but some +existing stubs (e.g.@: RedBoot) are known to not check for the end of the +packet.}. Like the descriptions of the other packets, each description here has a template showing the packet's overall syntax, followed by an diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 0881e3d1a1f..31b0ae0b65b 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1,7 +1,7 @@ /* DWARF 2 debugging format support for GDB. - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006 + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, @@ -1073,6 +1073,9 @@ static void dwarf2_mark (struct dwarf2_cu *); static void dwarf2_clear_marks (struct dwarf2_per_cu_data *); +static void read_set_type (struct die_info *, struct dwarf2_cu *); + + /* Try to locate the sections we need for DWARF 2 debugging information and return true if we have enough to do something. */ @@ -2662,6 +2665,9 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_subroutine_type: read_subroutine_type (die, cu); break; + case DW_TAG_set_type: + read_set_type (die, cu); + break; case DW_TAG_array_type: read_array_type (die, cu); break; @@ -4240,6 +4246,15 @@ read_array_order (struct die_info *die, struct dwarf2_cu *cu) }; } +/* Extract all information from a DW_TAG_set_type DIE and put it in + the DIE's type field. */ + +static void +read_set_type (struct die_info *die, struct dwarf2_cu *cu) +{ + if (die->type == NULL) + die->type = create_set_type ((struct type *) NULL, die_type (die, cu)); +} /* First cut: install each common block member as a global variable. */ @@ -4728,10 +4743,17 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) code = TYPE_CODE_FLT; break; case DW_ATE_signed: - case DW_ATE_signed_char: break; case DW_ATE_unsigned: - case DW_ATE_unsigned_char: + type_flags |= TYPE_FLAG_UNSIGNED; + break; + case DW_ATE_signed_char: + if (cu->language == language_m2) + code = TYPE_CODE_CHAR; + break; + case DW_ATE_unsigned_char: + if (cu->language == language_m2) + code = TYPE_CODE_CHAR; type_flags |= TYPE_FLAG_UNSIGNED; break; default: @@ -6168,10 +6190,12 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu) case DW_LANG_Ada95: cu->language = language_ada; break; + case DW_LANG_Modula2: + cu->language = language_m2; + break; case DW_LANG_Cobol74: case DW_LANG_Cobol85: case DW_LANG_Pascal83: - case DW_LANG_Modula2: default: cu->language = language_minimal; break; @@ -6961,6 +6985,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: + case DW_TAG_set_type: case DW_TAG_enumeration_type: SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; @@ -7290,6 +7315,9 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_array_type: read_array_type (die, cu); break; + case DW_TAG_set_type: + read_set_type (die, cu); + break; case DW_TAG_pointer_type: read_tag_pointer_type (die, cu); break; diff --git a/gdb/m2-lang.h b/gdb/m2-lang.h index a57cef066a7..294707a4340 100644 --- a/gdb/m2-lang.h +++ b/gdb/m2-lang.h @@ -27,6 +27,11 @@ extern void m2_error (char *); /* Defined in m2-exp.y */ extern void m2_print_type (struct type *, char *, struct ui_file *, int, int); +extern int m2_is_long_set (struct type *type); + extern int m2_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, int, int, enum val_prettyprint); + +extern int get_long_set_bounds (struct type *type, LONGEST *low, + LONGEST *high); diff --git a/gdb/m2-typeprint.c b/gdb/m2-typeprint.c index 7763d326d22..160305c7869 100644 --- a/gdb/m2-typeprint.c +++ b/gdb/m2-typeprint.c @@ -1,5 +1,6 @@ /* Support for printing Modula 2 types for GDB, the GNU debugger. - Copyright (C) 1986, 1988, 1989, 1991, 1992, 1995, 2000 + Copyright (C) 1986, 1988, 1989, 1991, 1992, 1995, 2000, 2001, + 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GDB. @@ -20,22 +21,554 @@ Boston, MA 02110-1301, USA. */ #include "defs.h" +#include "gdb_obstack.h" #include "bfd.h" /* Binary File Description */ #include "symtab.h" #include "gdbtypes.h" #include "expression.h" #include "value.h" #include "gdbcore.h" -#include "target.h" #include "m2-lang.h" +#include "target.h" +#include "language.h" +#include "demangle.h" +#include "c-lang.h" +#include "typeprint.h" +#include "cp-abi.h" + +#include "gdb_string.h" #include +static void m2_print_bounds (struct type *type, + struct ui_file *stream, int show, int level, + int print_high); + +static void m2_typedef (struct type *, struct ui_file *, int, int); +static void m2_array (struct type *, struct ui_file *, int, int); +static void m2_pointer (struct type *, struct ui_file *, int, int); +static void m2_ref (struct type *, struct ui_file *, int, int); +static void m2_procedure (struct type *, struct ui_file *, int, int); +static void m2_union (struct type *, struct ui_file *); +static void m2_enum (struct type *, struct ui_file *, int, int); +static void m2_range (struct type *, struct ui_file *, int, int); +static void m2_type_name (struct type *type, struct ui_file *stream); +static void m2_short_set (struct type *type, struct ui_file *stream, + int show, int level); +static int m2_long_set (struct type *type, struct ui_file *stream, + int show, int level); +static void m2_record_fields (struct type *type, struct ui_file *stream, + int show, int level); +static void m2_unknown (const char *s, struct type *type, + struct ui_file *stream, int show, int level); + +int m2_is_long_set (struct type *type); +int m2_is_long_set_of_type (struct type *type, struct type **of_type); + + void m2_print_type (struct type *type, char *varstring, struct ui_file *stream, int show, int level) { - extern void c_print_type (struct type *, char *, struct ui_file *, int, - int); + enum type_code code; + int demangled_args; + + CHECK_TYPEDEF (type); + code = TYPE_CODE (type); + + QUIT; + + wrap_here (" "); + if (type == NULL) + { + fputs_filtered (_(""), stream); + return; + } + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_SET: + m2_short_set(type, stream, show, level); + break; + + case TYPE_CODE_STRUCT: + if (m2_long_set (type, stream, show, level)) + break; + m2_record_fields (type, stream, show, level); + break; + + case TYPE_CODE_TYPEDEF: + m2_typedef (type, stream, show, level); + break; + + case TYPE_CODE_ARRAY: + m2_array (type, stream, show, level); + break; + + case TYPE_CODE_PTR: + m2_pointer (type, stream, show, level); + break; + + case TYPE_CODE_REF: + m2_ref (type, stream, show, level); + break; + + case TYPE_CODE_MEMBER: + m2_unknown (_("member"), type, stream, show, level); + break; + + case TYPE_CODE_METHOD: + m2_unknown (_("method"), type, stream, show, level); + break; + + case TYPE_CODE_FUNC: + m2_procedure (type, stream, show, level); + break; + + case TYPE_CODE_UNION: + m2_union (type, stream); + break; + + case TYPE_CODE_ENUM: + m2_enum (type, stream, show, level); + break; + + case TYPE_CODE_VOID: + break; + + case TYPE_CODE_UNDEF: + /* i18n: Do not translate the "struct" part! */ + m2_unknown (_("undef"), type, stream, show, level); + break; + + case TYPE_CODE_ERROR: + m2_unknown (_("error"), type, stream, show, level); + break; + + case TYPE_CODE_RANGE: + m2_range (type, stream, show, level); + break; + + case TYPE_CODE_TEMPLATE: + break; + + default: + m2_type_name (type, stream); + break; + } +} + +/* + * m2_type_name - if a, type, has a name then print it. + */ + +void +m2_type_name (struct type *type, struct ui_file *stream) +{ + if (TYPE_NAME (type) != NULL) + fputs_filtered (TYPE_NAME (type), stream); +} + +/* + * m2_range - displays a Modula-2 subrange type. + */ + +void +m2_range (struct type *type, struct ui_file *stream, int show, + int level) +{ + if (TYPE_HIGH_BOUND (type) == TYPE_LOW_BOUND (type)) + m2_print_type (TYPE_DOMAIN_TYPE (type), "", stream, show, level); + else + { + struct type *target = TYPE_TARGET_TYPE (type); + + fprintf_filtered (stream, "["); + print_type_scalar (target, TYPE_LOW_BOUND (type), stream); + fprintf_filtered (stream, ".."); + print_type_scalar (target, TYPE_HIGH_BOUND (type), stream); + fprintf_filtered (stream, "]"); + } +} + +static void +m2_typedef (struct type *type, struct ui_file *stream, int show, + int level) +{ + if (TYPE_NAME (type) != NULL) + { + fputs_filtered (TYPE_NAME (type), stream); + fputs_filtered (" = ", stream); + } + m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level); +} + +/* + * m2_array - prints out a Modula-2 ARRAY ... OF type + */ + +static void m2_array (struct type *type, struct ui_file *stream, + int show, int level) +{ + fprintf_filtered (stream, "ARRAY ["); + if (TYPE_LENGTH (type) >= 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0 + && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED) + { + if (TYPE_INDEX_TYPE (type) != 0) + { + m2_print_bounds (TYPE_INDEX_TYPE (type), stream, show, -1, 0); + fprintf_filtered (stream, ".."); + m2_print_bounds (TYPE_INDEX_TYPE (type), stream, show, -1, 1); + } + else + fprintf_filtered (stream, "%d", + (TYPE_LENGTH (type) + / TYPE_LENGTH (TYPE_TARGET_TYPE (type)))); + } + fprintf_filtered (stream, "] OF "); + m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level); +} + +static void +m2_pointer (struct type *type, struct ui_file *stream, int show, + int level) +{ + if (TYPE_CONST (type)) + fprintf_filtered (stream, "[...] : "); + else + fprintf_filtered (stream, "POINTER TO "); + + m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level); +} + +static void +m2_ref (struct type *type, struct ui_file *stream, int show, + int level) +{ + fprintf_filtered (stream, "VAR"); + m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level); +} + +static void +m2_unknown (const char *s, struct type *type, struct ui_file *stream, + int show, int level) +{ + fprintf_filtered (stream, "%s %s", s, _("is unknown")); +} + +static void m2_union (struct type *type, struct ui_file *stream) +{ + fprintf_filtered (stream, "union"); +} + +static void +m2_procedure (struct type *type, struct ui_file *stream, + int show, int level) +{ + fprintf_filtered (stream, "PROCEDURE "); + m2_type_name (type, stream); + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID) + { + int i, len = TYPE_NFIELDS (type); + + fprintf_filtered (stream, " ("); + for (i = 0; i < len; i++) + { + if (i > 0) + { + fputs_filtered (", ", stream); + wrap_here (" "); + } + m2_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); + } + if (TYPE_TARGET_TYPE (type) != NULL) + { + fprintf_filtered (stream, " : "); + m2_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0); + } + } +} + +static void +m2_print_bounds (struct type *type, + struct ui_file *stream, int show, int level, + int print_high) +{ + struct type *target = TYPE_TARGET_TYPE (type); + + if (target == NULL) + target = builtin_type_int; + + if (TYPE_NFIELDS(type) == 0) + return; + + if (print_high) + print_type_scalar (target, TYPE_HIGH_BOUND (type), stream); + else + print_type_scalar (target, TYPE_LOW_BOUND (type), stream); +} + +static void +m2_short_set (struct type *type, struct ui_file *stream, int show, int level) +{ + fprintf_filtered(stream, "SET ["); + m2_print_bounds (TYPE_INDEX_TYPE (type), stream, + show - 1, level, 0); + + fprintf_filtered(stream, ".."); + m2_print_bounds (TYPE_INDEX_TYPE (type), stream, + show - 1, level, 1); + fprintf_filtered(stream, "]"); +} + +int +m2_is_long_set (struct type *type) +{ + LONGEST previous_high = 0; /* unnecessary initialization + keeps gcc -Wall happy */ + int len, i; + struct type *range; + + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + { + + /* + * check if all fields of the RECORD are consecutive sets + */ + len = TYPE_NFIELDS (type); + for (i = TYPE_N_BASECLASSES (type); i < len; i++) + { + if (TYPE_FIELD_TYPE (type, i) == NULL) + return 0; + if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) != TYPE_CODE_SET) + return 0; + if (TYPE_FIELD_NAME (type, i) != NULL + && (strcmp (TYPE_FIELD_NAME (type, i), "") != 0)) + return 0; + range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i)); + if ((i > TYPE_N_BASECLASSES (type)) + && previous_high + 1 != TYPE_LOW_BOUND (range)) + return 0; + previous_high = TYPE_HIGH_BOUND (range); + } + return len>0; + } + return 0; +} + +/* + * m2_get_discrete_bounds - a wrapper for get_discrete_bounds which + * understands that CHARs might be signed. + * This should be integrated into gdbtypes.c + * inside get_discrete_bounds. + */ + +int +m2_get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp) +{ + CHECK_TYPEDEF (type); + switch (TYPE_CODE (type)) + { + case TYPE_CODE_CHAR: + if (TYPE_LENGTH (type) < sizeof (LONGEST)) + { + if (!TYPE_UNSIGNED (type)) + { + *lowp = -(1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1)); + *highp = -*lowp - 1; + return 0; + } + } + /* fall through */ + default: + return get_discrete_bounds (type, lowp, highp); + } +} + +/* + * m2_is_long_set_of_type - returns TRUE if the long set was declared as + * SET OF of_type is assigned to the + * subtype. + */ + +int +m2_is_long_set_of_type (struct type *type, struct type **of_type) +{ + int len, i; + struct type *range; + struct type *target; + LONGEST l1, l2; + LONGEST h1, h2; + + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + { + len = TYPE_NFIELDS (type); + i = TYPE_N_BASECLASSES (type); + if (len == 0) + return 0; + range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i)); + target = TYPE_TARGET_TYPE (range); + if (target == NULL) + target = builtin_type_int; + + l1 = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i))); + h1 = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, len-1))); + *of_type = target; + if (m2_get_discrete_bounds (target, &l2, &h2) >= 0) + return (l1 == l2 && h1 == h2); + error (_("long_set failed to find discrete bounds for its subtype")); + return 0; + } + error (_("expecting long_set")); + return 0; +} + +static int +m2_long_set (struct type *type, struct ui_file *stream, int show, int level) +{ + struct type *index_type; + struct type *range_type; + struct type *of_type; + int i; + int len = TYPE_NFIELDS (type); + LONGEST low; + LONGEST high; + + if (m2_is_long_set (type)) + { + if (TYPE_TAG_NAME (type) != NULL) + { + fputs_filtered (TYPE_TAG_NAME (type), stream); + if (show == 0) + return 1; + } + else if (TYPE_NAME (type) != NULL) + { + fputs_filtered (TYPE_NAME (type), stream); + if (show == 0) + return 1; + } + + if (TYPE_TAG_NAME (type) != NULL || TYPE_NAME (type) != NULL) + fputs_filtered (" = ", stream); + + if (get_long_set_bounds (type, &low, &high)) + { + fprintf_filtered(stream, "SET OF "); + i = TYPE_N_BASECLASSES (type); + if (m2_is_long_set_of_type (type, &of_type)) + m2_print_type (of_type, "", stream, show - 1, level); + else + { + fprintf_filtered(stream, "["); + m2_print_bounds (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i)), + stream, show - 1, level, 0); + + fprintf_filtered(stream, ".."); + + m2_print_bounds (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, len-1)), + stream, show - 1, level, 1); + fprintf_filtered(stream, "]"); + } + } + else + /* i18n: Do not translate the "SET OF" part! */ + fprintf_filtered(stream, _("SET OF ")); + + return 1; + } + return 0; +} + +void +m2_record_fields (struct type *type, struct ui_file *stream, int show, + int level) +{ + /* Print the tag if it exists. + */ + if (TYPE_TAG_NAME (type) != NULL) + { + if (strncmp (TYPE_TAG_NAME (type), "$$", 2) != 0) + { + fputs_filtered (TYPE_TAG_NAME (type), stream); + if (show > 0) + fprintf_filtered (stream, " = "); + } + } + wrap_here (" "); + if (show < 0) + { + if (TYPE_CODE (type) == DECLARED_TYPE_STRUCT) + fprintf_filtered (stream, "RECORD ... END "); + else if (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_UNION) + fprintf_filtered (stream, "CASE ... END "); + } + else if (show > 0) + { + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + fprintf_filtered (stream, "RECORD\n"); + else if (TYPE_CODE (type) == TYPE_CODE_UNION) + /* i18n: Do not translate "CASE" and "OF" */ + fprintf_filtered (stream, _("CASE OF\n")); + int i; + int len = TYPE_NFIELDS (type); + + for (i = TYPE_N_BASECLASSES (type); i < len; i++) + { + QUIT; + + print_spaces_filtered (level + 4, stream); + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + fputs_filtered (" : ", stream); + m2_print_type (TYPE_FIELD_TYPE (type, i), + "", + stream, 0, level + 4); + if (TYPE_FIELD_PACKED (type, i)) + { + /* It is a bitfield. This code does not attempt + to look at the bitpos and reconstruct filler, + unnamed fields. This would lead to misleading + results if the compiler does not put out fields + for such things (I don't know what it does). */ + fprintf_filtered (stream, " : %d", + TYPE_FIELD_BITSIZE (type, i)); + } + fprintf_filtered (stream, ";\n"); + } + + fprintfi_filtered (level, stream, "END "); + } +} + +void +m2_enum (struct type *type, struct ui_file *stream, int show, int level) +{ + int lastval, i, len; - c_print_type (type, varstring, stream, show, level); /* FIXME */ + if (show < 0) + { + /* If we just printed a tag name, no need to print anything else. */ + if (TYPE_TAG_NAME (type) == NULL) + fprintf_filtered (stream, "(...)"); + } + else if (show > 0 || TYPE_TAG_NAME (type) == NULL) + { + fprintf_filtered (stream, "("); + len = TYPE_NFIELDS (type); + lastval = 0; + for (i = 0; i < len; i++) + { + QUIT; + if (i > 0) + fprintf_filtered (stream, ", "); + wrap_here (" "); + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + if (lastval != TYPE_FIELD_BITPOS (type, i)) + { + fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i)); + lastval = TYPE_FIELD_BITPOS (type, i); + } + lastval++; + } + fprintf_filtered (stream, ")"); + } } diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c index 7b38dc95475..579ea8b8054 100644 --- a/gdb/m2-valprint.c +++ b/gdb/m2-valprint.c @@ -1,7 +1,8 @@ /* Support for printing Modula 2 values for GDB, the GNU debugger. - Copyright (C) 1986, 1988, 1989, 1991, 1992, 1996, 1998, 2000, 2005 Free - Software Foundation, Inc. + Copyright (C) 1986, 1988, 1989, 1991, 1992, 1996, 1998, + 2000, 2005, 2006 + Free Software Foundation, Inc. This file is part of GDB. @@ -23,14 +24,562 @@ #include "defs.h" #include "symtab.h" #include "gdbtypes.h" -#include "m2-lang.h" +#include "expression.h" +#include "value.h" +#include "valprint.h" +#include "language.h" +#include "typeprint.h" #include "c-lang.h" +#include "m2-lang.h" +#include "target.h" + +int print_unpacked_pointer (struct type *type, + CORE_ADDR address, CORE_ADDR addr, + int format, struct ui_file *stream); + + +/* Print function pointer with inferior address ADDRESS onto stdio + stream STREAM. */ + +static void +print_function_pointer_address (CORE_ADDR address, struct ui_file *stream) +{ + CORE_ADDR func_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, + address, + ¤t_target); + + /* If the function pointer is represented by a description, print the + address of the description. */ + if (addressprint && func_addr != address) + { + fputs_filtered ("@", stream); + fputs_filtered (paddress (address), stream); + fputs_filtered (": ", stream); + } + print_address_demangle (func_addr, stream, demangle); +} + +/* + * get_long_set_bounds - assigns the bounds of the long set to low and high. + */ + +int +get_long_set_bounds (struct type *type, LONGEST *low, LONGEST *high) +{ + int len, i; + + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + { + len = TYPE_NFIELDS (type); + i = TYPE_N_BASECLASSES (type); + if (len == 0) + return 0; + *low = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i))); + *high = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, + len-1))); + return 1; + } + error (_("expecting long_set")); + return 0; +} + +static void +m2_print_long_set (struct type *type, const gdb_byte *valaddr, + int embedded_offset, CORE_ADDR address, + struct ui_file *stream, int format, + enum val_prettyprint pretty) +{ + int empty_set = 1; + int element_seen = 0; + LONGEST previous_low = 0; + LONGEST previous_high= 0; + LONGEST i, low_bound, high_bound; + LONGEST field_low, field_high; + struct type *range; + int len, field; + struct type *target; + int bitval; + + CHECK_TYPEDEF (type); + + fprintf_filtered (stream, "{"); + len = TYPE_NFIELDS (type); + if (get_long_set_bounds (type, &low_bound, &high_bound)) + { + field = TYPE_N_BASECLASSES (type); + range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, field)); + } + else + { + fprintf_filtered (stream, " %s }", _("")); + return; + } + + target = TYPE_TARGET_TYPE (range); + if (target == NULL) + target = builtin_type_int; + + if (get_discrete_bounds (range, &field_low, &field_high) >= 0) + { + for (i = low_bound; i <= high_bound; i++) + { + bitval = value_bit_index (TYPE_FIELD_TYPE (type, field), + (TYPE_FIELD_BITPOS (type, field) / 8) + + valaddr + embedded_offset, i); + if (bitval < 0) + error (_("bit test is out of range")); + else if (bitval > 0) + { + previous_high = i; + if (! element_seen) + { + if (! empty_set) + fprintf_filtered (stream, ", "); + print_type_scalar (target, i, stream); + empty_set = 0; + element_seen = 1; + previous_low = i; + } + } + else + { + /* bit is not set */ + if (element_seen) + { + if (previous_low+1 < previous_high) + fprintf_filtered (stream, ".."); + if (previous_low+1 < previous_high) + print_type_scalar (target, previous_high, stream); + element_seen = 0; + } + } + if (i == field_high) + { + field++; + if (field == len) + break; + range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, field)); + if (get_discrete_bounds (range, &field_low, &field_high) < 0) + break; + target = TYPE_TARGET_TYPE (range); + if (target == NULL) + target = builtin_type_int; + } + } + if (element_seen) + { + if (previous_low+1 < previous_high) + { + fprintf_filtered (stream, ".."); + print_type_scalar (target, previous_high, stream); + } + element_seen = 0; + } + fprintf_filtered (stream, "}"); + } +} + +int +print_unpacked_pointer (struct type *type, + CORE_ADDR address, CORE_ADDR addr, + int format, struct ui_file *stream) +{ + struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type)); + + if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) + { + /* Try to print what function it points to. */ + print_function_pointer_address (addr, stream); + /* Return value is irrelevant except for string pointers. */ + return 0; + } + + if (addressprint && format != 's') + fputs_filtered (paddress (address), stream); + + /* For a pointer to char or unsigned char, also print the string + pointed to, unless pointer is null. */ + + if (TYPE_LENGTH (elttype) == 1 + && TYPE_CODE (elttype) == TYPE_CODE_INT + && (format == 0 || format == 's') + && addr != 0) + return val_print_string (addr, -1, TYPE_LENGTH (elttype), stream); + + return 0; +} + +static void +print_variable_at_address (struct type *type, const gdb_byte *valaddr, + struct ui_file *stream, int format, + int deref_ref, int recurse, + enum val_prettyprint pretty) +{ + CORE_ADDR addr = unpack_pointer (type, valaddr); + struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type)); + + fprintf_filtered (stream, "["); + fputs_filtered (paddress (addr), stream); + fprintf_filtered (stream, "] : "); + + if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) + { + struct value *deref_val = + value_at + (TYPE_TARGET_TYPE (type), + unpack_pointer (lookup_pointer_type (builtin_type_void), + valaddr)); + common_val_print (deref_val, stream, format, deref_ref, + recurse, pretty); + } + else + fputs_filtered ("???", stream); +} + +/* Print data of type TYPE located at VALADDR (within GDB), which came from + the inferior at address ADDRESS, onto stdio stream STREAM according to + FORMAT (a letter or 0 for natural format). The data at VALADDR is in + target byte order. + + If the data are a string pointer, returns the number of string characters + printed. + + If DEREF_REF is nonzero, then dereference references, otherwise just print + them like pointers. + + The PRETTY parameter controls prettyprinting. */ int m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { - return (c_val_print (type, valaddr, 0, address, stream, format, deref_ref, - recurse, pretty)); + unsigned int i = 0; /* Number of characters printed */ + unsigned len; + struct type *elttype; + unsigned eltlen; + int length_pos, length_size, string_pos; + int char_size; + LONGEST val; + CORE_ADDR addr; + + CHECK_TYPEDEF (type); + switch (TYPE_CODE (type)) + { + case TYPE_CODE_ARRAY: + if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) + { + elttype = check_typedef (TYPE_TARGET_TYPE (type)); + eltlen = TYPE_LENGTH (elttype); + len = TYPE_LENGTH (type) / eltlen; + if (prettyprint_arrays) + print_spaces_filtered (2 + 2 * recurse, stream); + /* For an array of chars, print with string syntax. */ + if (eltlen == 1 && + ((TYPE_CODE (elttype) == TYPE_CODE_INT) + || ((current_language->la_language == language_m2) + && (TYPE_CODE (elttype) == TYPE_CODE_CHAR))) + && (format == 0 || format == 's')) + { + /* If requested, look for the first null char and only print + elements up to it. */ + if (stop_print_at_null) + { + unsigned int temp_len; + + /* Look for a NULL char. */ + for (temp_len = 0; + (valaddr + embedded_offset)[temp_len] + && temp_len < len && temp_len < print_max; + temp_len++); + len = temp_len; + } + + LA_PRINT_STRING (stream, valaddr + embedded_offset, len, 1, 0); + i = len; + } + else + { + fprintf_filtered (stream, "{"); + val_print_array_elements (type, valaddr + embedded_offset, + address, stream, format, deref_ref, + recurse, pretty, 0); + fprintf_filtered (stream, "}"); + } + break; + } + /* Array of unspecified length: treat like pointer to first elt. */ + print_unpacked_pointer (type, address, address, format, stream); + break; + + case TYPE_CODE_PTR: + if (TYPE_CONST (type)) + print_variable_at_address (type, valaddr + embedded_offset, + stream, format, deref_ref, recurse, + pretty); + else if (format && format != 's') + print_scalar_formatted (valaddr + embedded_offset, type, format, + 0, stream); + else + { + addr = unpack_pointer (type, valaddr + embedded_offset); + print_unpacked_pointer (type, addr, address, format, stream); + } + break; + + case TYPE_CODE_MEMBER: + error (_("not implemented: member type in m2_val_print")); + break; + + case TYPE_CODE_REF: + elttype = check_typedef (TYPE_TARGET_TYPE (type)); + if (addressprint) + { + CORE_ADDR addr + = extract_typed_address (valaddr + embedded_offset, type); + fprintf_filtered (stream, "@"); + fputs_filtered (paddress (addr), stream); + if (deref_ref) + fputs_filtered (": ", stream); + } + /* De-reference the reference. */ + if (deref_ref) + { + if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) + { + struct value *deref_val = + value_at + (TYPE_TARGET_TYPE (type), + unpack_pointer (lookup_pointer_type (builtin_type_void), + valaddr + embedded_offset)); + common_val_print (deref_val, stream, format, deref_ref, + recurse, pretty); + } + else + fputs_filtered ("???", stream); + } + break; + + case TYPE_CODE_UNION: + if (recurse && !unionprint) + { + fprintf_filtered (stream, "{...}"); + break; + } + /* Fall through. */ + case TYPE_CODE_STRUCT: + if (m2_is_long_set (type)) + m2_print_long_set (type, valaddr, embedded_offset, address, + stream, format, pretty); + else + cp_print_value_fields (type, type, valaddr, embedded_offset, + address, stream, format, + recurse, pretty, NULL, 0); + break; + + case TYPE_CODE_ENUM: + if (format) + { + print_scalar_formatted (valaddr + embedded_offset, type, + format, 0, stream); + break; + } + len = TYPE_NFIELDS (type); + val = unpack_long (type, valaddr + embedded_offset); + for (i = 0; i < len; i++) + { + QUIT; + if (val == TYPE_FIELD_BITPOS (type, i)) + { + break; + } + } + if (i < len) + { + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + } + else + { + print_longest (stream, 'd', 0, val); + } + break; + + case TYPE_CODE_FUNC: + if (format) + { + print_scalar_formatted (valaddr + embedded_offset, type, + format, 0, stream); + break; + } + /* FIXME, we should consider, at least for ANSI C language, eliminating + the distinction made between FUNCs and POINTERs to FUNCs. */ + fprintf_filtered (stream, "{"); + type_print (type, "", stream, -1); + fprintf_filtered (stream, "} "); + /* Try to print what function it points to, and its address. */ + print_address_demangle (address, stream, demangle); + break; + + case TYPE_CODE_BOOL: + format = format ? format : output_format; + if (format) + print_scalar_formatted (valaddr + embedded_offset, type, + format, 0, stream); + else + { + val = unpack_long (type, valaddr + embedded_offset); + if (val == 0) + fputs_filtered ("FALSE", stream); + else if (val == 1) + fputs_filtered ("TRUE", stream); + else + fprintf_filtered (stream, "%ld)", (long int) val); + } + break; + + case TYPE_CODE_RANGE: + if (TYPE_LENGTH (type) == TYPE_LENGTH (TYPE_TARGET_TYPE (type))) + { + m2_val_print (TYPE_TARGET_TYPE (type), valaddr, embedded_offset, + address, stream, format, deref_ref, recurse, pretty); + break; + } + /* FIXME: create_range_type does not set the unsigned bit in a + range type (I think it probably should copy it from the target + type), so we won't print values which are too large to + fit in a signed integer correctly. */ + /* FIXME: Doesn't handle ranges of enums correctly. (Can't just + print with the target type, though, because the size of our type + and the target type might differ). */ + /* FALLTHROUGH */ + + case TYPE_CODE_INT: + format = format ? format : output_format; + if (format) + print_scalar_formatted (valaddr + embedded_offset, type, format, + 0, stream); + else + val_print_type_code_int (type, valaddr + embedded_offset, stream); + break; + + case TYPE_CODE_CHAR: + format = format ? format : output_format; + if (format) + print_scalar_formatted (valaddr + embedded_offset, type, + format, 0, stream); + else + { + val = unpack_long (type, valaddr + embedded_offset); + if (TYPE_UNSIGNED (type)) + fprintf_filtered (stream, "%u", (unsigned int) val); + else + fprintf_filtered (stream, "%d", (int) val); + fputs_filtered (" ", stream); + LA_PRINT_CHAR ((unsigned char) val, stream); + } + break; + + case TYPE_CODE_FLT: + if (format) + print_scalar_formatted (valaddr + embedded_offset, type, + format, 0, stream); + else + print_floating (valaddr + embedded_offset, type, stream); + break; + + case TYPE_CODE_METHOD: + break; + + case TYPE_CODE_BITSTRING: + case TYPE_CODE_SET: + elttype = TYPE_INDEX_TYPE (type); + CHECK_TYPEDEF (elttype); + if (TYPE_STUB (elttype)) + { + fprintf_filtered (stream, _("")); + gdb_flush (stream); + break; + } + else + { + struct type *range = elttype; + LONGEST low_bound, high_bound; + int i; + int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING; + int need_comma = 0; + + if (is_bitstring) + fputs_filtered ("B'", stream); + else + fputs_filtered ("{", stream); + + i = get_discrete_bounds (range, &low_bound, &high_bound); + maybe_bad_bstring: + if (i < 0) + { + fputs_filtered (_(""), stream); + goto done; + } + + for (i = low_bound; i <= high_bound; i++) + { + int element = value_bit_index (type, valaddr + embedded_offset, + i); + if (element < 0) + { + i = element; + goto maybe_bad_bstring; + } + if (is_bitstring) + fprintf_filtered (stream, "%d", element); + else if (element) + { + if (need_comma) + fputs_filtered (", ", stream); + print_type_scalar (range, i, stream); + need_comma = 1; + + if (i + 1 <= high_bound + && value_bit_index (type, valaddr + embedded_offset, + ++i)) + { + int j = i; + fputs_filtered ("..", stream); + while (i + 1 <= high_bound + && value_bit_index (type, + valaddr + embedded_offset, + ++i)) + j = i; + print_type_scalar (range, j, stream); + } + } + } + done: + if (is_bitstring) + fputs_filtered ("'", stream); + else + fputs_filtered ("}", stream); + } + break; + + case TYPE_CODE_VOID: + fprintf_filtered (stream, "void"); + break; + + case TYPE_CODE_ERROR: + fprintf_filtered (stream, _("")); + break; + + case TYPE_CODE_UNDEF: + /* This happens (without TYPE_FLAG_STUB set) on systems which don't use + dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" + and no complete type for struct foo in that file. */ + fprintf_filtered (stream, _("")); + break; + + default: + error (_("Invalid m2 type code %d in symbol table."), TYPE_CODE (type)); + } + gdb_flush (stream); + return (0); } diff --git a/gdb/mi/gdb-mi.el b/gdb/mi/gdb-mi.el index ed1d7b7669f..7a499d81f71 100644 --- a/gdb/mi/gdb-mi.el +++ b/gdb/mi/gdb-mi.el @@ -170,7 +170,7 @@ detailed description of this mode. (setq comint-input-sender 'gdbmi-send) ;; ;; (re-)initialise - (setq gdb-frame-address (if gdb-show-main "main" nil) + (setq gdb-pc-address (if gdb-show-main "main" nil) gdb-previous-frame-address nil gdb-memory-address "main" gdb-previous-frame nil @@ -225,7 +225,7 @@ detailed description of this mode. (setq gdb-output-sink 'user) (setq gdb-prompting nil) ;; mimic key to repeat previous command in GDB - (if (string-match "^\\S+$" string) + (if (not (string-match "^\\s+$" string)) (setq gdb-last-command string) (if gdb-last-command (setq string gdb-last-command))) (if gdb-enable-debug @@ -563,22 +563,23 @@ buffers, if required." (goto-char (point-min)) (when (re-search-forward gdb-stack-list-frames-regexp nil t) (setq gdb-frame-number (match-string 1)) - (setq gdb-frame-address (match-string 2)) + (setq gdb-pc-address (match-string 2)) (setq gdb-selected-frame (match-string 3)) - (setq gud-last-frame - (cons (match-string 4) (string-to-number (match-string 5)))) - (gud-display-frame) - (if gud-overlay-arrow-position - (let ((buffer (marker-buffer gud-overlay-arrow-position)) - (position (marker-position gud-overlay-arrow-position))) - (when buffer - (with-current-buffer buffer - (setq fringe-indicator-alist - (if (string-equal gdb-frame-number "0") - nil - '((overlay-arrow . hollow-right-triangle)))) - (setq gud-overlay-arrow-position (make-marker)) - (set-marker gud-overlay-arrow-position position))))) + (when (match-string 4) + (setq gud-last-frame + (cons (match-string 4) (string-to-number (match-string 5)))) + (gud-display-frame) + (if gud-overlay-arrow-position + (let ((buffer (marker-buffer gud-overlay-arrow-position)) + (position (marker-position gud-overlay-arrow-position))) + (when buffer + (with-current-buffer buffer + (setq fringe-indicator-alist + (if (string-equal gdb-frame-number "0") + nil + '((overlay-arrow . hollow-right-triangle)))) + (setq gud-overlay-arrow-position (make-marker)) + (set-marker gud-overlay-arrow-position position)))))) (if (gdb-get-buffer 'gdb-locals-buffer) (with-current-buffer (gdb-get-buffer 'gdb-locals-buffer) (setq mode-name (concat "Locals:" gdb-selected-frame)))) diff --git a/gdb/ppcnbsd-nat.c b/gdb/ppcnbsd-nat.c index ca19ca01f16..a200505cef8 100644 --- a/gdb/ppcnbsd-nat.c +++ b/gdb/ppcnbsd-nat.c @@ -1,5 +1,7 @@ -/* Native-dependent code for PowerPC's running NetBSD, for GDB. - Copyright (C) 2002, 2004 Free Software Foundation, Inc. +/* Native-dependent code for NetBSD/powerpc. + + Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. This file is part of GDB. @@ -26,35 +28,37 @@ #include #include "defs.h" -#include "inferior.h" -#include "gdb_assert.h" #include "gdbcore.h" +#include "inferior.h" #include "regcache.h" -#include "bsd-kvm.h" + +#include "gdb_assert.h" #include "ppc-tdep.h" #include "ppcnbsd-tdep.h" - +#include "bsd-kvm.h" #include "inf-ptrace.h" /* Returns true if PT_GETREGS fetches this register. */ + static int -getregs_supplies (int regno) +getregs_supplies (int regnum) { struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - return ((regno >= tdep->ppc_gp0_regnum - && regno < tdep->ppc_gp0_regnum + ppc_num_gprs) - || regno == tdep->ppc_lr_regnum - || regno == tdep->ppc_cr_regnum - || regno == tdep->ppc_xer_regnum - || regno == tdep->ppc_ctr_regnum - || regno == PC_REGNUM); + return ((regnum >= tdep->ppc_gp0_regnum + && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs) + || regnum == tdep->ppc_lr_regnum + || regnum == tdep->ppc_cr_regnum + || regnum == tdep->ppc_xer_regnum + || regnum == tdep->ppc_ctr_regnum + || regnum == PC_REGNUM); } /* Like above, but for PT_GETFPREGS. */ + static int -getfpregs_supplies (int regno) +getfpregs_supplies (int regnum) { struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); @@ -70,15 +74,15 @@ getfpregs_supplies (int regno) combination to the problem. */ gdb_assert (ppc_floating_point_unit_p (current_gdbarch)); - return ((regno >= tdep->ppc_fp0_regnum - && regno < tdep->ppc_fp0_regnum + ppc_num_fprs) - || regno == tdep->ppc_fpscr_regnum); + return ((regnum >= tdep->ppc_fp0_regnum + && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs) + || regnum == tdep->ppc_fpscr_regnum); } static void -ppcnbsd_fetch_inferior_registers (int regno) +ppcnbsd_fetch_inferior_registers (int regnum) { - if (regno == -1 || getregs_supplies (regno)) + if (regnum == -1 || getregs_supplies (regnum)) { struct reg regs; @@ -86,12 +90,11 @@ ppcnbsd_fetch_inferior_registers (int regno) (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); - ppcnbsd_supply_reg ((char *) ®s, regno); - if (regno != -1) - return; + ppc_supply_gregset (&ppcnbsd_gregset, current_regcache, + regnum, ®s, sizeof regs); } - if (regno == -1 || getfpregs_supplies (regno)) + if (regnum == -1 || getfpregs_supplies (regnum)) { struct fpreg fpregs; @@ -99,16 +102,15 @@ ppcnbsd_fetch_inferior_registers (int regno) (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't get FP registers")); - ppcnbsd_supply_fpreg ((char *) &fpregs, regno); - if (regno != -1) - return; + ppc_supply_fpregset (&ppcnbsd_fpregset, current_regcache, + regnum, &fpregs, sizeof fpregs); } } static void -ppcnbsd_store_inferior_registers (int regno) +ppcnbsd_store_inferior_registers (int regnum) { - if (regno == -1 || getregs_supplies (regno)) + if (regnum == -1 || getregs_supplies (regnum)) { struct reg regs; @@ -116,17 +118,15 @@ ppcnbsd_store_inferior_registers (int regno) (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); - ppcnbsd_fill_reg ((char *) ®s, regno); + ppc_collect_gregset (&ppcnbsd_gregset, current_regcache, + regnum, ®s, sizeof regs); if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't write registers")); - - if (regno != -1) - return; } - if (regno == -1 || getfpregs_supplies (regno)) + if (regnum == -1 || getfpregs_supplies (regnum)) { struct fpreg fpregs; @@ -134,8 +134,9 @@ ppcnbsd_store_inferior_registers (int regno) (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't get FP registers")); - ppcnbsd_fill_fpreg ((char *) &fpregs, regno); - + ppc_collect_fpregset (&ppcnbsd_fpregset, current_regcache, + regnum, &fpregs, sizeof fpregs); + if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't set FP registers")); @@ -154,19 +155,19 @@ ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) if (pcb->pcb_sp == 0) return 0; - read_memory (pcb->pcb_sp, (char *) &sf, sizeof sf); + read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf); regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2); for (i = 0 ; i < 19 ; i++) regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 13 + i, &sf.fixreg[i]); - read_memory(sf.sp, (char *)&cf, sizeof(cf)); + read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf)); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 1, &cf.sp); - read_memory(cf.sp, (char *)&cf, sizeof(cf)); + read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf)); regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &cf.lr); regcache_raw_supply (regcache, PC_REGNUM, &cf.lr); @@ -180,8 +181,10 @@ void _initialize_ppcnbsd_nat (void) { struct target_ops *t; + /* Support debugging kernel virtual memory images. */ bsd_kvm_add_target (ppcnbsd_supply_pcb); + /* Add in local overrides. */ t = inf_ptrace_target (); t->to_fetch_registers = ppcnbsd_fetch_inferior_registers; diff --git a/gdb/ppcnbsd-tdep.c b/gdb/ppcnbsd-tdep.c index 57ba742c85a..6bbdf4f6ad1 100644 --- a/gdb/ppcnbsd-tdep.c +++ b/gdb/ppcnbsd-tdep.c @@ -1,6 +1,6 @@ -/* Target-dependent code for PowerPC systems running NetBSD. +/* Target-dependent code for NetBSD/powerpc. - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Contributed by Wasabi Systems, Inc. @@ -22,225 +22,58 @@ Boston, MA 02110-1301, USA. */ #include "defs.h" -#include "gdbcore.h" -#include "regcache.h" -#include "target.h" -#include "breakpoint.h" -#include "value.h" +#include "gdbtypes.h" #include "osabi.h" +#include "regcache.h" +#include "regset.h" +#include "trad-frame.h" +#include "tramp-frame.h" + +#include "gdb_assert.h" +#include "gdb_string.h" #include "ppc-tdep.h" #include "ppcnbsd-tdep.h" -#include "nbsd-tdep.h" -#include "tramp-frame.h" -#include "trad-frame.h" -#include "gdb_assert.h" #include "solib-svr4.h" -#define REG_FIXREG_OFFSET(x) ((x) * 4) -#define REG_LR_OFFSET (32 * 4) -#define REG_CR_OFFSET (33 * 4) -#define REG_XER_OFFSET (34 * 4) -#define REG_CTR_OFFSET (35 * 4) -#define REG_PC_OFFSET (36 * 4) -#define SIZEOF_STRUCT_REG (37 * 4) - -#define FPREG_FPR_OFFSET(x) ((x) * 8) -#define FPREG_FPSCR_OFFSET (32 * 8) -#define SIZEOF_STRUCT_FPREG (33 * 8) - -void -ppcnbsd_supply_reg (char *regs, int regno) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - int i; - - for (i = 0; i < ppc_num_gprs; i++) - { - if (regno == tdep->ppc_gp0_regnum + i || regno == -1) - regcache_raw_supply (current_regcache, tdep->ppc_gp0_regnum + i, - regs + REG_FIXREG_OFFSET (i)); - } +/* Register offsets from . */ +struct ppc_reg_offsets ppcnbsd_reg_offsets; + - if (regno == tdep->ppc_lr_regnum || regno == -1) - regcache_raw_supply (current_regcache, tdep->ppc_lr_regnum, - regs + REG_LR_OFFSET); +/* Core file support. */ - if (regno == tdep->ppc_cr_regnum || regno == -1) - regcache_raw_supply (current_regcache, tdep->ppc_cr_regnum, - regs + REG_CR_OFFSET); +/* NetBSD/powerpc register set. */ - if (regno == tdep->ppc_xer_regnum || regno == -1) - regcache_raw_supply (current_regcache, tdep->ppc_xer_regnum, - regs + REG_XER_OFFSET); - - if (regno == tdep->ppc_ctr_regnum || regno == -1) - regcache_raw_supply (current_regcache, tdep->ppc_ctr_regnum, - regs + REG_CTR_OFFSET); - - if (regno == PC_REGNUM || regno == -1) - regcache_raw_supply (current_regcache, PC_REGNUM, - regs + REG_PC_OFFSET); -} - -void -ppcnbsd_fill_reg (char *regs, int regno) +struct regset ppcnbsd_gregset = { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - int i; - - for (i = 0; i < ppc_num_gprs; i++) - { - if (regno == tdep->ppc_gp0_regnum + i || regno == -1) - regcache_raw_collect (current_regcache, tdep->ppc_gp0_regnum + i, - regs + REG_FIXREG_OFFSET (i)); - } - - if (regno == tdep->ppc_lr_regnum || regno == -1) - regcache_raw_collect (current_regcache, tdep->ppc_lr_regnum, - regs + REG_LR_OFFSET); - - if (regno == tdep->ppc_cr_regnum || regno == -1) - regcache_raw_collect (current_regcache, tdep->ppc_cr_regnum, - regs + REG_CR_OFFSET); - - if (regno == tdep->ppc_xer_regnum || regno == -1) - regcache_raw_collect (current_regcache, tdep->ppc_xer_regnum, - regs + REG_XER_OFFSET); - - if (regno == tdep->ppc_ctr_regnum || regno == -1) - regcache_raw_collect (current_regcache, tdep->ppc_ctr_regnum, - regs + REG_CTR_OFFSET); - - if (regno == PC_REGNUM || regno == -1) - regcache_raw_collect (current_regcache, PC_REGNUM, regs + REG_PC_OFFSET); -} + &ppcnbsd_reg_offsets, + ppc_supply_gregset +}; -void -ppcnbsd_supply_fpreg (char *fpregs, int regno) +struct regset ppcnbsd_fpregset = { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - int i; - - /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating - point registers. Traditionally, GDB's register set has still - listed the floating point registers for such machines, so this - code is harmless. However, the new E500 port actually omits the - floating point registers entirely from the register set --- they - don't even have register numbers assigned to them. - - It's not clear to me how best to update this code, so this assert - will alert the first person to encounter the NetBSD/E500 - combination to the problem. */ - gdb_assert (ppc_floating_point_unit_p (current_gdbarch)); - - for (i = 0; i < ppc_num_fprs; i++) - { - if (regno == tdep->ppc_fp0_regnum + i || regno == -1) - regcache_raw_supply (current_regcache, tdep->ppc_fp0_regnum + i, - fpregs + FPREG_FPR_OFFSET (i)); - } - - if (regno == tdep->ppc_fpscr_regnum || regno == -1) - regcache_raw_supply (current_regcache, tdep->ppc_fpscr_regnum, - fpregs + FPREG_FPSCR_OFFSET); -} - -void -ppcnbsd_fill_fpreg (char *fpregs, int regno) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - int i; - - /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating - point registers. Traditionally, GDB's register set has still - listed the floating point registers for such machines, so this - code is harmless. However, the new E500 port actually omits the - floating point registers entirely from the register set --- they - don't even have register numbers assigned to them. - - It's not clear to me how best to update this code, so this assert - will alert the first person to encounter the NetBSD/E500 - combination to the problem. */ - gdb_assert (ppc_floating_point_unit_p (current_gdbarch)); - - for (i = 0; i < ppc_num_fprs; i++) - { - if (regno == tdep->ppc_fp0_regnum + i || regno == -1) - regcache_raw_collect (current_regcache, tdep->ppc_fp0_regnum + i, - fpregs + FPREG_FPR_OFFSET (i)); - } + &ppcnbsd_reg_offsets, + ppc_supply_fpregset +}; - if (regno == tdep->ppc_fpscr_regnum || regno == -1) - regcache_raw_collect (current_regcache, tdep->ppc_fpscr_regnum, - fpregs + FPREG_FPSCR_OFFSET); -} +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, - CORE_ADDR ignore) +static const struct regset * +ppcnbsd_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) { - char *regs, *fpregs; - - /* We get everything from one section. */ - if (which != 0) - return; + if (strcmp (sect_name, ".reg") == 0 && sect_size >= 148) + return &ppcnbsd_gregset; - regs = core_reg_sect; - fpregs = core_reg_sect + SIZEOF_STRUCT_REG; + if (strcmp (sect_name, ".reg2") == 0 && sect_size >= 264) + return &ppcnbsd_fpregset; - /* Integer registers. */ - ppcnbsd_supply_reg (regs, -1); - - /* Floating point registers. */ - ppcnbsd_supply_fpreg (fpregs, -1); + return NULL; } + -static void -fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which, - CORE_ADDR ignore) -{ - switch (which) - { - case 0: /* Integer registers. */ - if (core_reg_size != SIZEOF_STRUCT_REG) - warning (_("Wrong size register set in core file.")); - else - ppcnbsd_supply_reg (core_reg_sect, -1); - break; - - case 2: /* Floating point registers. */ - if (core_reg_size != SIZEOF_STRUCT_FPREG) - warning (_("Wrong size FP register set in core file.")); - else - ppcnbsd_supply_fpreg (core_reg_sect, -1); - break; - - default: - /* Don't know what kind of register request this is; just ignore it. */ - break; - } -} - -static struct core_fns ppcnbsd_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -static struct core_fns ppcnbsd_elfcore_fns = -{ - bfd_target_elf_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_elfcore_registers, /* core_read_registers */ - NULL /* next */ -}; - -/* NetBSD is confused. It appears that 1.5 was using the correct SVr4 +/* NetBSD is confused. It appears that 1.5 was using the correct SVR4 convention but, 1.6 switched to the below broken convention. For the moment use the broken convention. Ulgh!. */ @@ -249,6 +82,7 @@ ppcnbsd_return_value (struct gdbarch *gdbarch, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { +#if 0 if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT || TYPE_CODE (valtype) == TYPE_CODE_UNION) && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8) @@ -259,9 +93,15 @@ ppcnbsd_return_value (struct gdbarch *gdbarch, struct type *valtype, || TYPE_LENGTH (valtype) == 8)) return RETURN_VALUE_STRUCT_CONVENTION; else +#endif return ppc_sysv_abi_broken_return_value (gdbarch, valtype, regcache, readbuf, writebuf); } + + +/* Signal trampolines. */ + +static const struct tramp_frame ppcnbsd2_sigtramp; static void ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self, @@ -269,53 +109,72 @@ ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self, struct trad_frame_cache *this_cache, CORE_ADDR func) { - CORE_ADDR base; - CORE_ADDR offset; - int i; struct gdbarch *gdbarch = get_frame_arch (next_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + CORE_ADDR addr, base; + int i; base = frame_unwind_register_unsigned (next_frame, SP_REGNUM); - offset = base + 0x18 + 2 * tdep->wordsize; - for (i = 0; i < ppc_num_gprs; i++) + if (self == &ppcnbsd2_sigtramp) + addr = base + 0x10 + 2 * tdep->wordsize; + else + addr = base + 0x18 + 2 * tdep->wordsize; + for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize) { int regnum = i + tdep->ppc_gp0_regnum; - trad_frame_set_reg_addr (this_cache, regnum, offset); - offset += tdep->wordsize; + trad_frame_set_reg_addr (this_cache, regnum, addr); } - trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, offset); - offset += tdep->wordsize; - trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, offset); - offset += tdep->wordsize; - trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, offset); - offset += tdep->wordsize; - trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, offset); - offset += tdep->wordsize; - trad_frame_set_reg_addr (this_cache, PC_REGNUM, offset); /* SRR0? */ - offset += tdep->wordsize; + trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr); + addr += tdep->wordsize; + trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr); + addr += tdep->wordsize; + trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr); + addr += tdep->wordsize; + trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr); + addr += tdep->wordsize; + trad_frame_set_reg_addr (this_cache, PC_REGNUM, addr); /* SRR0? */ + addr += tdep->wordsize; /* Construct the frame ID using the function start. */ trad_frame_set_id (this_cache, frame_id_build (base, func)); } -/* Given the NEXT frame, examine the instructions at and around this - frame's resume address (aka PC) to see of they look like a signal - trampoline. Return the address of the trampolines first - instruction, or zero if it isn't a signal trampoline. */ +static const struct tramp_frame ppcnbsd_sigtramp = +{ + SIGTRAMP_FRAME, + 4, + { + { 0x3821fff0, -1 }, /* add r1,r1,-16 */ + { 0x4e800021, -1 }, /* blrl */ + { 0x38610018, -1 }, /* addi r3,r1,24 */ + { 0x38000127, -1 }, /* li r0,295 */ + { 0x44000002, -1 }, /* sc */ + { 0x38000001, -1 }, /* li r0,1 */ + { 0x44000002, -1 }, /* sc */ + { TRAMP_SENTINEL_INSN, -1 } + }, + ppcnbsd_sigtramp_cache_init +}; + +/* NetBSD 2.0 introduced a slightly different signal trampoline. */ -static const struct tramp_frame ppcnbsd_sigtramp = { +static const struct tramp_frame ppcnbsd2_sigtramp = +{ SIGTRAMP_FRAME, - 4, /* insn size */ - { /* insn */ - { 0x38610018, -1 }, /* addi r3,r1,24 */ - { 0x38000127, -1 }, /* li r0,295 */ - { 0x44000002, -1 }, /* sc */ - { 0x38000001, -1 }, /* li r0,1 */ - { 0x44000002, -1 }, /* sc */ + 4, + { + { 0x3821fff0, -1 }, /* add r1,r1,-16 */ + { 0x4e800021, -1 }, /* blrl */ + { 0x38610010, -1 }, /* addi r3,r1,16 */ + { 0x38000127, -1 }, /* li r0,295 */ + { 0x44000002, -1 }, /* sc */ + { 0x38000001, -1 }, /* li r0,1 */ + { 0x44000002, -1 }, /* sc */ { TRAMP_SENTINEL_INSN, -1 } }, ppcnbsd_sigtramp_cache_init }; + static void ppcnbsd_init_abi (struct gdbarch_info info, @@ -324,10 +183,21 @@ ppcnbsd_init_abi (struct gdbarch_info info, /* For NetBSD, this is an on again, off again thing. Some systems do use the broken struct convention, and some don't. */ set_gdbarch_return_value (gdbarch, ppcnbsd_return_value); - set_solib_svr4_fetch_link_map_offsets (gdbarch, - nbsd_ilp32_solib_svr4_fetch_link_map_offsets); + + /* NetBSD uses SVR4-style shared libraries. */ + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_ilp32_fetch_link_map_offsets); + + set_gdbarch_regset_from_core_section + (gdbarch, ppcnbsd_regset_from_core_section); + tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp); + tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp); } + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_ppcnbsd_tdep (void); void _initialize_ppcnbsd_tdep (void) @@ -335,6 +205,27 @@ _initialize_ppcnbsd_tdep (void) gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD_ELF, ppcnbsd_init_abi); - deprecated_add_core_fns (&ppcnbsd_core_fns); - deprecated_add_core_fns (&ppcnbsd_elfcore_fns); + /* Avoid initializing the register offsets again if they were + already initailized by ppcnbsd-nat.c. */ + if (ppcnbsd_reg_offsets.pc_offset == 0) + { + /* General-purpose registers. */ + ppcnbsd_reg_offsets.r0_offset = 0; + ppcnbsd_reg_offsets.lr_offset = 128; + ppcnbsd_reg_offsets.cr_offset = 132; + ppcnbsd_reg_offsets.xer_offset = 136; + ppcnbsd_reg_offsets.ctr_offset = 140; + ppcnbsd_reg_offsets.pc_offset = 144; + ppcnbsd_reg_offsets.ps_offset = -1; + ppcnbsd_reg_offsets.mq_offset = -1; + + /* Floating-point registers. */ + ppcnbsd_reg_offsets.f0_offset = 0; + ppcnbsd_reg_offsets.fpscr_offset = 256; + + /* AltiVec registers. */ + ppcnbsd_reg_offsets.vr0_offset = 0; + ppcnbsd_reg_offsets.vrsave_offset = 512; + ppcnbsd_reg_offsets.vscr_offset = 524; + } } diff --git a/gdb/ppcnbsd-tdep.h b/gdb/ppcnbsd-tdep.h index 968cf57d2cf..eee54497917 100644 --- a/gdb/ppcnbsd-tdep.h +++ b/gdb/ppcnbsd-tdep.h @@ -1,5 +1,6 @@ -/* Common target dependent code for GDB on PowerPC systems running NetBSD. - Copyright (C) 2002 Free Software Foundation, Inc. +/* Target-dependent code for NetBSD/powerpc. + + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GDB. @@ -21,10 +22,15 @@ #ifndef PPCNBSD_TDEP_H #define PPCNBSD_TDEP_H -void ppcnbsd_supply_reg (char *, int); -void ppcnbsd_fill_reg (char *, int); +#include + +struct regset; + +/* Register offsets for NetBSD/powerpc. */ +extern struct ppc_reg_offsets ppcnbsd_reg_offsets; -void ppcnbsd_supply_fpreg (char *, int); -void ppcnbsd_fill_fpreg (char *, int); +/* Register sets for NetBSD/powerpc. */ +extern struct regset ppcnbsd_gregset; +extern struct regset ppcnbsd_fpregset; -#endif /* PPCNBSD_TDEP_H */ +#endif /* ppcnbsd-tdep.h */ diff --git a/gdb/version.in b/gdb/version.in index 144b14dc1b5..0fbdab019b2 100644 --- a/gdb/version.in +++ b/gdb/version.in @@ -1 +1 @@ -6.4.50.20060512-cvs +6.4.50.20060514-cvs diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 76baa3c3ac2..ef48f8609bc 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,8 @@ +2006-05-12 Anton Blanchard + + * cplus-dem.c (demangle_fund_type): Ensure buf is large enough to + hold "int%u_t". + 2006-04-24 Julian Brown * floatformat.c (floatformat_to_double): Fix (biased) exponent=0 case. diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c index 8b60434a888..1f8b1fc31e4 100644 --- a/libiberty/cplus-dem.c +++ b/libiberty/cplus-dem.c @@ -3693,7 +3693,7 @@ demangle_fund_type (struct work_stuff *work, { int done = 0; int success = 1; - char buf[10]; + char buf[INTBUF_SIZE + 5 /* 'int%u_t' */]; unsigned int dec = 0; type_kind_t tk = tk_integral; diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index b3c5b6f16d4..37d19312d1d 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,9 @@ +2006-05-14 Thiemo Seufer + + * mips16-opc.c (I1, I32, I64): New shortcut defines. + (mips16_opcodes): Change membership of instructions to their + lowest baseline ISA. + 2006-05-09 H.J. Lu * i386-dis.c (grps): Update sgdt/sidt for 64bit. diff --git a/opcodes/mips16-opc.c b/opcodes/mips16-opc.c index 24b610788ae..8144986df79 100644 --- a/opcodes/mips16-opc.c +++ b/opcodes/mips16-opc.c @@ -58,59 +58,61 @@ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA #define TRAP INSN_TRAP +#define I1 INSN_ISA1 #define I3 INSN_ISA3 - -#define T3 INSN_3900 +#define I32 INSN_ISA32 +#define I64 INSN_ISA64 +#define T3 INSN_3900 const struct mips_opcode mips16_opcodes[] = { /* name, args, match, mask, pinfo, pinfo2, membership */ -{"nop", "", 0x6500, 0xffff, RD_Z, 0, 0 }, /* move $0,$Z */ -{"la", "x,A", 0x0800, 0xf800, WR_x|RD_PC, 0, 0 }, -{"abs", "x,w", 0, (int) M_ABS, INSN_MACRO, 0, 0 }, -{"addiu", "y,x,4", 0x4000, 0xf810, WR_y|RD_x, 0, 0 }, -{"addiu", "x,k", 0x4800, 0xf800, WR_x|RD_x, 0, 0 }, -{"addiu", "S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, 0 }, -{"addiu", "S,S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, 0 }, -{"addiu", "x,P,V", 0x0800, 0xf800, WR_x|RD_PC, 0, 0 }, -{"addiu", "x,S,V", 0x0000, 0xf800, WR_x|RD_SP, 0, 0 }, -{"addu", "z,v,y", 0xe001, 0xf803, WR_z|RD_x|RD_y, 0, 0 }, -{"addu", "y,x,4", 0x4000, 0xf810, WR_y|RD_x, 0, 0 }, -{"addu", "x,k", 0x4800, 0xf800, WR_x|RD_x, 0, 0 }, -{"addu", "S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, 0 }, -{"addu", "S,S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, 0 }, -{"addu", "x,P,V", 0x0800, 0xf800, WR_x|RD_PC, 0, 0 }, -{"addu", "x,S,V", 0x0000, 0xf800, WR_x|RD_SP, 0, 0 }, -{"and", "x,y", 0xe80c, 0xf81f, WR_x|RD_x|RD_y, 0, 0 }, -{"b", "q", 0x1000, 0xf800, BR, 0, 0 }, -{"beq", "x,y,p", 0, (int) M_BEQ, INSN_MACRO, 0, 0 }, -{"beq", "x,U,p", 0, (int) M_BEQ_I, INSN_MACRO, 0, 0 }, -{"beqz", "x,p", 0x2000, 0xf800, BR|RD_x, 0, 0 }, -{"bge", "x,y,p", 0, (int) M_BGE, INSN_MACRO, 0, 0 }, -{"bge", "x,8,p", 0, (int) M_BGE_I, INSN_MACRO, 0, 0 }, -{"bgeu", "x,y,p", 0, (int) M_BGEU, INSN_MACRO, 0, 0 }, -{"bgeu", "x,8,p", 0, (int) M_BGEU_I, INSN_MACRO, 0, 0 }, -{"bgt", "x,y,p", 0, (int) M_BGT, INSN_MACRO, 0, 0 }, -{"bgt", "x,8,p", 0, (int) M_BGT_I, INSN_MACRO, 0, 0 }, -{"bgtu", "x,y,p", 0, (int) M_BGTU, INSN_MACRO, 0, 0 }, -{"bgtu", "x,8,p", 0, (int) M_BGTU_I, INSN_MACRO, 0, 0 }, -{"ble", "x,y,p", 0, (int) M_BLE, INSN_MACRO, 0, 0 }, -{"ble", "x,8,p", 0, (int) M_BLE_I, INSN_MACRO, 0, 0 }, -{"bleu", "x,y,p", 0, (int) M_BLEU, INSN_MACRO, 0, 0 }, -{"bleu", "x,8,p", 0, (int) M_BLEU_I, INSN_MACRO, 0, 0 }, -{"blt", "x,y,p", 0, (int) M_BLT, INSN_MACRO, 0, 0 }, -{"blt", "x,8,p", 0, (int) M_BLT_I, INSN_MACRO, 0, 0 }, -{"bltu", "x,y,p", 0, (int) M_BLTU, INSN_MACRO, 0, 0 }, -{"bltu", "x,8,p", 0, (int) M_BLTU_I, INSN_MACRO, 0, 0 }, -{"bne", "x,y,p", 0, (int) M_BNE, INSN_MACRO, 0, 0 }, -{"bne", "x,U,p", 0, (int) M_BNE_I, INSN_MACRO, 0, 0 }, -{"bnez", "x,p", 0x2800, 0xf800, BR|RD_x, 0, 0 }, -{"break", "6", 0xe805, 0xf81f, TRAP, 0, 0 }, -{"bteqz", "p", 0x6000, 0xff00, BR|RD_T, 0, 0 }, -{"btnez", "p", 0x6100, 0xff00, BR|RD_T, 0, 0 }, -{"cmpi", "x,U", 0x7000, 0xf800, WR_T|RD_x, 0, 0 }, -{"cmp", "x,y", 0xe80a, 0xf81f, WR_T|RD_x|RD_y, 0, 0 }, -{"cmp", "x,U", 0x7000, 0xf800, WR_T|RD_x, 0, 0 }, +{"nop", "", 0x6500, 0xffff, RD_Z, 0, I1 }, /* move $0,$Z */ +{"la", "x,A", 0x0800, 0xf800, WR_x|RD_PC, 0, I1 }, +{"abs", "x,w", 0, (int) M_ABS, INSN_MACRO, 0, I1 }, +{"addiu", "y,x,4", 0x4000, 0xf810, WR_y|RD_x, 0, I1 }, +{"addiu", "x,k", 0x4800, 0xf800, WR_x|RD_x, 0, I1 }, +{"addiu", "S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, I1 }, +{"addiu", "S,S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, I1 }, +{"addiu", "x,P,V", 0x0800, 0xf800, WR_x|RD_PC, 0, I1 }, +{"addiu", "x,S,V", 0x0000, 0xf800, WR_x|RD_SP, 0, I1 }, +{"addu", "z,v,y", 0xe001, 0xf803, WR_z|RD_x|RD_y, 0, I1 }, +{"addu", "y,x,4", 0x4000, 0xf810, WR_y|RD_x, 0, I1 }, +{"addu", "x,k", 0x4800, 0xf800, WR_x|RD_x, 0, I1 }, +{"addu", "S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, I1 }, +{"addu", "S,S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, I1 }, +{"addu", "x,P,V", 0x0800, 0xf800, WR_x|RD_PC, 0, I1 }, +{"addu", "x,S,V", 0x0000, 0xf800, WR_x|RD_SP, 0, I1 }, +{"and", "x,y", 0xe80c, 0xf81f, WR_x|RD_x|RD_y, 0, I1 }, +{"b", "q", 0x1000, 0xf800, BR, 0, I1 }, +{"beq", "x,y,p", 0, (int) M_BEQ, INSN_MACRO, 0, I1 }, +{"beq", "x,U,p", 0, (int) M_BEQ_I, INSN_MACRO, 0, I1 }, +{"beqz", "x,p", 0x2000, 0xf800, BR|RD_x, 0, I1 }, +{"bge", "x,y,p", 0, (int) M_BGE, INSN_MACRO, 0, I1 }, +{"bge", "x,8,p", 0, (int) M_BGE_I, INSN_MACRO, 0, I1 }, +{"bgeu", "x,y,p", 0, (int) M_BGEU, INSN_MACRO, 0, I1 }, +{"bgeu", "x,8,p", 0, (int) M_BGEU_I, INSN_MACRO, 0, I1 }, +{"bgt", "x,y,p", 0, (int) M_BGT, INSN_MACRO, 0, I1 }, +{"bgt", "x,8,p", 0, (int) M_BGT_I, INSN_MACRO, 0, I1 }, +{"bgtu", "x,y,p", 0, (int) M_BGTU, INSN_MACRO, 0, I1 }, +{"bgtu", "x,8,p", 0, (int) M_BGTU_I, INSN_MACRO, 0, I1 }, +{"ble", "x,y,p", 0, (int) M_BLE, INSN_MACRO, 0, I1 }, +{"ble", "x,8,p", 0, (int) M_BLE_I, INSN_MACRO, 0, I1 }, +{"bleu", "x,y,p", 0, (int) M_BLEU, INSN_MACRO, 0, I1 }, +{"bleu", "x,8,p", 0, (int) M_BLEU_I, INSN_MACRO, 0, I1 }, +{"blt", "x,y,p", 0, (int) M_BLT, INSN_MACRO, 0, I1 }, +{"blt", "x,8,p", 0, (int) M_BLT_I, INSN_MACRO, 0, I1 }, +{"bltu", "x,y,p", 0, (int) M_BLTU, INSN_MACRO, 0, I1 }, +{"bltu", "x,8,p", 0, (int) M_BLTU_I, INSN_MACRO, 0, I1 }, +{"bne", "x,y,p", 0, (int) M_BNE, INSN_MACRO, 0, I1 }, +{"bne", "x,U,p", 0, (int) M_BNE_I, INSN_MACRO, 0, I1 }, +{"bnez", "x,p", 0x2800, 0xf800, BR|RD_x, 0, I1 }, +{"break", "6", 0xe805, 0xf81f, TRAP, 0, I1 }, +{"bteqz", "p", 0x6000, 0xff00, BR|RD_T, 0, I1 }, +{"btnez", "p", 0x6100, 0xff00, BR|RD_T, 0, I1 }, +{"cmpi", "x,U", 0x7000, 0xf800, WR_T|RD_x, 0, I1 }, +{"cmp", "x,y", 0xe80a, 0xf81f, WR_T|RD_x|RD_y, 0, I1 }, +{"cmp", "x,U", 0x7000, 0xf800, WR_T|RD_x, 0, I1 }, {"dla", "y,E", 0xfe00, 0xff00, WR_y|RD_PC, 0, I3 }, {"daddiu", "y,x,4", 0x4010, 0xf810, WR_y|RD_x, 0, I3 }, {"daddiu", "y,j", 0xfd00, 0xff00, WR_y|RD_y, 0, I3 }, @@ -126,20 +128,20 @@ const struct mips_opcode mips16_opcodes[] = {"daddu", "y,P,W", 0xfe00, 0xff00, WR_y|RD_PC, 0, I3 }, {"daddu", "y,S,W", 0xff00, 0xff00, WR_y|RD_SP, 0, I3 }, {"ddiv", "0,x,y", 0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, -{"ddiv", "z,v,y", 0, (int) M_DDIV_3, INSN_MACRO, 0, 0 }, +{"ddiv", "z,v,y", 0, (int) M_DDIV_3, INSN_MACRO, 0, I1 }, {"ddivu", "0,x,y", 0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, -{"ddivu", "z,v,y", 0, (int) M_DDIVU_3, INSN_MACRO, 0, 0 }, -{"div", "0,x,y", 0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, 0 }, -{"div", "z,v,y", 0, (int) M_DIV_3, INSN_MACRO, 0, 0 }, -{"divu", "0,x,y", 0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, 0 }, -{"divu", "z,v,y", 0, (int) M_DIVU_3, INSN_MACRO, 0, 0 }, +{"ddivu", "z,v,y", 0, (int) M_DDIVU_3, INSN_MACRO, 0, I1 }, +{"div", "0,x,y", 0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, +{"div", "z,v,y", 0, (int) M_DIV_3, INSN_MACRO, 0, I1 }, +{"divu", "0,x,y", 0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, +{"divu", "z,v,y", 0, (int) M_DIVU_3, INSN_MACRO, 0, I1 }, {"dmul", "z,v,y", 0, (int) M_DMUL, INSN_MACRO, 0, I3 }, {"dmult", "x,y", 0xe81c, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, {"dmultu", "x,y", 0xe81d, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, {"drem", "0,x,y", 0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, -{"drem", "z,v,y", 0, (int) M_DREM_3, INSN_MACRO, 0, 0 }, +{"drem", "z,v,y", 0, (int) M_DREM_3, INSN_MACRO, 0, I1 }, {"dremu", "0,x,y", 0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, -{"dremu", "z,v,y", 0, (int) M_DREMU_3, INSN_MACRO, 0, 0 }, +{"dremu", "z,v,y", 0, (int) M_DREMU_3, INSN_MACRO, 0, I1 }, {"dsllv", "y,x", 0xe814, 0xf81f, WR_y|RD_y|RD_x, 0, I3 }, {"dsll", "x,w,[", 0x3001, 0xf803, WR_x|RD_y, 0, I3 }, {"dsll", "y,x", 0xe814, 0xf81f, WR_y|RD_y|RD_x, 0, I3 }, @@ -150,92 +152,92 @@ const struct mips_opcode mips16_opcodes[] = {"dsrl", "y,]", 0xe808, 0xf81f, WR_y|RD_y, 0, I3 }, {"dsrl", "y,x", 0xe816, 0xf81f, WR_y|RD_y|RD_x, 0, I3 }, {"dsubu", "z,v,y", 0xe002, 0xf803, WR_z|RD_x|RD_y, 0, I3 }, -{"dsubu", "y,x,4", 0, (int) M_DSUBU_I, INSN_MACRO, 0, 0 }, -{"dsubu", "y,j", 0, (int) M_DSUBU_I_2, INSN_MACRO, 0, 0 }, -{"exit", "L", 0xed09, 0xff1f, TRAP, 0, 0 }, -{"exit", "L", 0xee09, 0xff1f, TRAP, 0, 0 }, -{"exit", "L", 0xef09, 0xff1f, TRAP, 0, 0 }, -{"entry", "l", 0xe809, 0xf81f, TRAP, 0, 0 }, -{"extend", "e", 0xf000, 0xf800, 0, 0, 0 }, -{"jalr", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, 0 }, -{"jalr", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, 0 }, -{"jal", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, 0 }, -{"jal", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, 0 }, -{"jal", "a", 0x1800, 0xfc00, UBD|WR_31, 0, 0 }, -{"jalx", "a", 0x1c00, 0xfc00, UBD|WR_31, 0, 0 }, -{"jr", "x", 0xe800, 0xf8ff, UBD|RD_x, 0, 0 }, -{"jr", "R", 0xe820, 0xffff, UBD|RD_31, 0, 0 }, -{"j", "x", 0xe800, 0xf8ff, UBD|RD_x, 0, 0 }, -{"j", "R", 0xe820, 0xffff, UBD|RD_31, 0, 0 }, -{"lb", "y,5(x)", 0x8000, 0xf800, WR_y|RD_x, 0, 0 }, -{"lbu", "y,5(x)", 0xa000, 0xf800, WR_y|RD_x, 0, 0 }, +{"dsubu", "y,x,4", 0, (int) M_DSUBU_I, INSN_MACRO, 0, I1 }, +{"dsubu", "y,j", 0, (int) M_DSUBU_I_2, INSN_MACRO, 0, I1 }, +{"exit", "L", 0xed09, 0xff1f, TRAP, 0, I1 }, +{"exit", "L", 0xee09, 0xff1f, TRAP, 0, I1 }, +{"exit", "L", 0xef09, 0xff1f, TRAP, 0, I1 }, +{"entry", "l", 0xe809, 0xf81f, TRAP, 0, I1 }, +{"extend", "e", 0xf000, 0xf800, 0, 0, I1 }, +{"jalr", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1 }, +{"jalr", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1 }, +{"jal", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1 }, +{"jal", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1 }, +{"jal", "a", 0x1800, 0xfc00, UBD|WR_31, 0, I1 }, +{"jalx", "a", 0x1c00, 0xfc00, UBD|WR_31, 0, I1 }, +{"jr", "x", 0xe800, 0xf8ff, UBD|RD_x, 0, I1 }, +{"jr", "R", 0xe820, 0xffff, UBD|RD_31, 0, I1 }, +{"j", "x", 0xe800, 0xf8ff, UBD|RD_x, 0, I1 }, +{"j", "R", 0xe820, 0xffff, UBD|RD_31, 0, I1 }, +{"lb", "y,5(x)", 0x8000, 0xf800, WR_y|RD_x, 0, I1 }, +{"lbu", "y,5(x)", 0xa000, 0xf800, WR_y|RD_x, 0, I1 }, {"ld", "y,D(x)", 0x3800, 0xf800, WR_y|RD_x, 0, I3 }, {"ld", "y,B", 0xfc00, 0xff00, WR_y|RD_PC, 0, I3 }, {"ld", "y,D(P)", 0xfc00, 0xff00, WR_y|RD_PC, 0, I3 }, {"ld", "y,D(S)", 0xf800, 0xff00, WR_y|RD_SP, 0, I3 }, -{"lh", "y,H(x)", 0x8800, 0xf800, WR_y|RD_x, 0, 0 }, -{"lhu", "y,H(x)", 0xa800, 0xf800, WR_y|RD_x, 0, 0 }, -{"li", "x,U", 0x6800, 0xf800, WR_x, 0, 0 }, -{"lw", "y,W(x)", 0x9800, 0xf800, WR_y|RD_x, 0, 0 }, -{"lw", "x,A", 0xb000, 0xf800, WR_x|RD_PC, 0, 0 }, -{"lw", "x,V(P)", 0xb000, 0xf800, WR_x|RD_PC, 0, 0 }, -{"lw", "x,V(S)", 0x9000, 0xf800, WR_x|RD_SP, 0, 0 }, +{"lh", "y,H(x)", 0x8800, 0xf800, WR_y|RD_x, 0, I1 }, +{"lhu", "y,H(x)", 0xa800, 0xf800, WR_y|RD_x, 0, I1 }, +{"li", "x,U", 0x6800, 0xf800, WR_x, 0, I1 }, +{"lw", "y,W(x)", 0x9800, 0xf800, WR_y|RD_x, 0, I1 }, +{"lw", "x,A", 0xb000, 0xf800, WR_x|RD_PC, 0, I1 }, +{"lw", "x,V(P)", 0xb000, 0xf800, WR_x|RD_PC, 0, I1 }, +{"lw", "x,V(S)", 0x9000, 0xf800, WR_x|RD_SP, 0, I1 }, {"lwu", "y,W(x)", 0xb800, 0xf800, WR_y|RD_x, 0, I3 }, -{"mfhi", "x", 0xe810, 0xf8ff, WR_x|RD_HI, 0, 0 }, -{"mflo", "x", 0xe812, 0xf8ff, WR_x|RD_LO, 0, 0 }, -{"move", "y,X", 0x6700, 0xff00, WR_y|RD_X, 0, 0 }, -{"move", "Y,Z", 0x6500, 0xff00, WR_Y|RD_Z, 0, 0 }, -{"mul", "z,v,y", 0, (int) M_MUL, INSN_MACRO, 0, 0 }, -{"mult", "x,y", 0xe818, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, 0 }, -{"multu", "x,y", 0xe819, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, 0 }, -{"neg", "x,w", 0xe80b, 0xf81f, WR_x|RD_y, 0, 0 }, -{"not", "x,w", 0xe80f, 0xf81f, WR_x|RD_y, 0, 0 }, -{"or", "x,y", 0xe80d, 0xf81f, WR_x|RD_x|RD_y, 0, 0 }, -{"rem", "0,x,y", 0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, 0 }, -{"rem", "z,v,y", 0, (int) M_REM_3, INSN_MACRO, 0, 0 }, -{"remu", "0,x,y", 0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, 0 }, -{"remu", "z,v,y", 0, (int) M_REMU_3, INSN_MACRO, 0, 0 }, -{"sb", "y,5(x)", 0xc000, 0xf800, RD_y|RD_x, 0, 0 }, +{"mfhi", "x", 0xe810, 0xf8ff, WR_x|RD_HI, 0, I1 }, +{"mflo", "x", 0xe812, 0xf8ff, WR_x|RD_LO, 0, I1 }, +{"move", "y,X", 0x6700, 0xff00, WR_y|RD_X, 0, I1 }, +{"move", "Y,Z", 0x6500, 0xff00, WR_Y|RD_Z, 0, I1 }, +{"mul", "z,v,y", 0, (int) M_MUL, INSN_MACRO, 0, I1 }, +{"mult", "x,y", 0xe818, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, +{"multu", "x,y", 0xe819, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, +{"neg", "x,w", 0xe80b, 0xf81f, WR_x|RD_y, 0, I1 }, +{"not", "x,w", 0xe80f, 0xf81f, WR_x|RD_y, 0, I1 }, +{"or", "x,y", 0xe80d, 0xf81f, WR_x|RD_x|RD_y, 0, I1 }, +{"rem", "0,x,y", 0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, +{"rem", "z,v,y", 0, (int) M_REM_3, INSN_MACRO, 0, I1 }, +{"remu", "0,x,y", 0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, +{"remu", "z,v,y", 0, (int) M_REMU_3, INSN_MACRO, 0, I1 }, +{"sb", "y,5(x)", 0xc000, 0xf800, RD_y|RD_x, 0, I1 }, {"sd", "y,D(x)", 0x7800, 0xf800, RD_y|RD_x, 0, I3 }, {"sd", "y,D(S)", 0xf900, 0xff00, RD_y|RD_PC, 0, I3 }, -{"sd", "R,C(S)", 0xfa00, 0xff00, RD_31|RD_PC, 0, 0 }, -{"sh", "y,H(x)", 0xc800, 0xf800, RD_y|RD_x, 0, 0 }, -{"sllv", "y,x", 0xe804, 0xf81f, WR_y|RD_y|RD_x, 0, 0 }, -{"sll", "x,w,<", 0x3000, 0xf803, WR_x|RD_y, 0, 0 }, -{"sll", "y,x", 0xe804, 0xf81f, WR_y|RD_y|RD_x, 0, 0 }, -{"slti", "x,8", 0x5000, 0xf800, WR_T|RD_x, 0, 0 }, -{"slt", "x,y", 0xe802, 0xf81f, WR_T|RD_x|RD_y, 0, 0 }, -{"slt", "x,8", 0x5000, 0xf800, WR_T|RD_x, 0, 0 }, -{"sltiu", "x,8", 0x5800, 0xf800, WR_T|RD_x, 0, 0 }, -{"sltu", "x,y", 0xe803, 0xf81f, WR_T|RD_x|RD_y, 0, 0 }, -{"sltu", "x,8", 0x5800, 0xf800, WR_T|RD_x, 0, 0 }, -{"srav", "y,x", 0xe807, 0xf81f, WR_y|RD_y|RD_x, 0, 0 }, -{"sra", "x,w,<", 0x3003, 0xf803, WR_x|RD_y, 0, 0 }, -{"sra", "y,x", 0xe807, 0xf81f, WR_y|RD_y|RD_x, 0, 0 }, -{"srlv", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x, 0, 0 }, -{"srl", "x,w,<", 0x3002, 0xf803, WR_x|RD_y, 0, 0 }, -{"srl", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x, 0, 0 }, -{"subu", "z,v,y", 0xe003, 0xf803, WR_z|RD_x|RD_y, 0, 0 }, -{"subu", "y,x,4", 0, (int) M_SUBU_I, INSN_MACRO, 0, 0 }, -{"subu", "x,k", 0, (int) M_SUBU_I_2, INSN_MACRO,0, 0 }, -{"sw", "y,W(x)", 0xd800, 0xf800, RD_y|RD_x, 0, 0 }, -{"sw", "x,V(S)", 0xd000, 0xf800, RD_x|RD_SP, 0, 0 }, -{"sw", "R,V(S)", 0x6200, 0xff00, RD_31|RD_SP, 0, 0 }, -{"xor", "x,y", 0xe80e, 0xf81f, WR_x|RD_x|RD_y, 0, 0 }, +{"sd", "R,C(S)", 0xfa00, 0xff00, RD_31|RD_PC, 0, I1 }, +{"sh", "y,H(x)", 0xc800, 0xf800, RD_y|RD_x, 0, I1 }, +{"sllv", "y,x", 0xe804, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, +{"sll", "x,w,<", 0x3000, 0xf803, WR_x|RD_y, 0, I1 }, +{"sll", "y,x", 0xe804, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, +{"slti", "x,8", 0x5000, 0xf800, WR_T|RD_x, 0, I1 }, +{"slt", "x,y", 0xe802, 0xf81f, WR_T|RD_x|RD_y, 0, I1 }, +{"slt", "x,8", 0x5000, 0xf800, WR_T|RD_x, 0, I1 }, +{"sltiu", "x,8", 0x5800, 0xf800, WR_T|RD_x, 0, I1 }, +{"sltu", "x,y", 0xe803, 0xf81f, WR_T|RD_x|RD_y, 0, I1 }, +{"sltu", "x,8", 0x5800, 0xf800, WR_T|RD_x, 0, I1 }, +{"srav", "y,x", 0xe807, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, +{"sra", "x,w,<", 0x3003, 0xf803, WR_x|RD_y, 0, I1 }, +{"sra", "y,x", 0xe807, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, +{"srlv", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, +{"srl", "x,w,<", 0x3002, 0xf803, WR_x|RD_y, 0, I1 }, +{"srl", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, +{"subu", "z,v,y", 0xe003, 0xf803, WR_z|RD_x|RD_y, 0, I1 }, +{"subu", "y,x,4", 0, (int) M_SUBU_I, INSN_MACRO, 0, I1 }, +{"subu", "x,k", 0, (int) M_SUBU_I_2, INSN_MACRO,0, I1 }, +{"sw", "y,W(x)", 0xd800, 0xf800, RD_y|RD_x, 0, I1 }, +{"sw", "x,V(S)", 0xd000, 0xf800, RD_x|RD_SP, 0, I1 }, +{"sw", "R,V(S)", 0x6200, 0xff00, RD_31|RD_SP, 0, I1 }, +{"xor", "x,y", 0xe80e, 0xf81f, WR_x|RD_x|RD_y, 0, I1 }, /* MIPS16e additions */ -{"jalrc", "x", 0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0, 0 }, -{"jalrc", "R,x", 0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0, 0 }, -{"jrc", "x", 0xe880, 0xf8ff, RD_x|TRAP, 0, 0 }, -{"jrc", "R", 0xe8a0, 0xffff, RD_31|TRAP, 0, 0 }, -{"restore", "M", 0x6400, 0xff80, WR_31|RD_SP|WR_SP|TRAP, 0, 0 }, -{"save", "m", 0x6480, 0xff80, RD_31|RD_SP|WR_SP|TRAP, 0, 0 }, -{"sdbbp", "6", 0xe801, 0xf81f, TRAP, 0, 0 }, -{"seb", "x", 0xe891, 0xf8ff, WR_x|RD_x, 0, 0 }, -{"seh", "x", 0xe8b1, 0xf8ff, WR_x|RD_x, 0, 0 }, -{"sew", "x", 0xe8d1, 0xf8ff, WR_x|RD_x, 0, I3 }, -{"zeb", "x", 0xe811, 0xf8ff, WR_x|RD_x, 0, 0 }, -{"zeh", "x", 0xe831, 0xf8ff, WR_x|RD_x, 0, 0 }, -{"zew", "x", 0xe851, 0xf8ff, WR_x|RD_x, 0, I3 }, +{"jalrc", "x", 0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0, I32 }, +{"jalrc", "R,x", 0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0, I32 }, +{"jrc", "x", 0xe880, 0xf8ff, RD_x|TRAP, 0, I32 }, +{"jrc", "R", 0xe8a0, 0xffff, RD_31|TRAP, 0, I32 }, +{"restore", "M", 0x6400, 0xff80, WR_31|RD_SP|WR_SP|TRAP, 0, I32 }, +{"save", "m", 0x6480, 0xff80, RD_31|RD_SP|WR_SP|TRAP, 0, I32 }, +{"sdbbp", "6", 0xe801, 0xf81f, TRAP, 0, I32 }, +{"seb", "x", 0xe891, 0xf8ff, WR_x|RD_x, 0, I32 }, +{"seh", "x", 0xe8b1, 0xf8ff, WR_x|RD_x, 0, I32 }, +{"sew", "x", 0xe8d1, 0xf8ff, WR_x|RD_x, 0, I64 }, +{"zeb", "x", 0xe811, 0xf8ff, WR_x|RD_x, 0, I32 }, +{"zeh", "x", 0xe831, 0xf8ff, WR_x|RD_x, 0, I32 }, +{"zew", "x", 0xe851, 0xf8ff, WR_x|RD_x, 0, I64 }, }; const int bfd_mips16_num_opcodes =