From 4ce44c668ddc0a909c3f081d98c68bea90a93af9 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Wed, 17 Nov 1999 02:31:06 +0000 Subject: [PATCH] import gdb-1999-11-16 snapshot --- gdb/ChangeLog | 201 ++++++- gdb/Makefile.in | 5 +- gdb/breakpoint.c | 9 + gdb/config/d10v/tm-d10v.h | 289 +-------- gdb/config/i386/tm-go32.h | 182 +----- gdb/config/i386/tm-i386.h | 10 +- gdb/corefile.c | 4 +- gdb/d10v-tdep.c | 427 ++++++++------ gdb/defs.h | 32 +- gdb/exec.c | 2 +- gdb/gdbserver/low-hppabsd.c | 9 +- gdb/gdbserver/low-linux.c | 20 +- gdb/gdbserver/low-lynx.c | 5 + gdb/gdbserver/low-sim.c | 11 +- gdb/gdbserver/low-sparc.c | 9 +- gdb/gdbserver/low-sun3.c | 9 +- gdb/gdbserver/server.c | 2 + gdb/gdbserver/server.h | 1 + gdb/go32-nat.c | 11 +- gdb/hppa-tdep.c | 2 +- gdb/irix5-nat.c | 2 +- gdb/monitor.c | 1 + gdb/osfsolib.c | 2 +- gdb/pa64solib.c | 2 +- gdb/remote-rdi.c | 64 +- gdb/remote-sim.c | 15 +- gdb/sol-thread.c | 25 +- gdb/solib.c | 2 +- gdb/somsolib.c | 2 +- gdb/stabsread.c | 18 +- gdb/testsuite/ChangeLog | 22 + gdb/testsuite/gdb.base/commands.exp | 2 +- gdb/testsuite/gdb.c++/derivation.exp | 15 - gdb/testsuite/lib/compiler.c | 31 + gdb/testsuite/lib/compiler.cc | 34 ++ gdb/testsuite/lib/gdb.exp | 33 +- gdb/utils.c | 181 ++++-- sim/d10v/ChangeLog | 83 ++- sim/d10v/d10v_sim.h | 63 +- sim/d10v/interp.c | 845 ++++++++++++++++++--------- sim/d10v/simops.c | 28 +- sim/mips/ChangeLog | 5 + sim/mips/interp.c | 9 +- sim/testsuite/d10v-elf/ChangeLog | 9 + sim/testsuite/d10v-elf/t-mvtc.s | 56 +- 45 files changed, 1627 insertions(+), 1162 deletions(-) create mode 100644 gdb/testsuite/lib/compiler.c create mode 100644 gdb/testsuite/lib/compiler.cc diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f75ce8d9ca0..6881a3ce439 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,199 @@ +1999-11-16 Mark Salter + + * monitor.c (monitor_supply_register): Initialize value to zero. + +1999-11-15 Eli Zaretskii + + (Patches applied by Jim Blandy ) + + Change DJGPP target use the common register layout in + config/i386/tm-i386.h. + * config/i386/tm-go32.h: #include "i386/tm-i386.h", not + "i386/tm-i386v.h". + (HAVE_I387_REGS): Define. + (HAVE_SSE_REGS): Undefine. + (NUM_FREGS, NUM_REGS, REGISTER_NAMES, FP_REGNUM, SP_REGNUM, + PS_REGNUM, PC_REGNUM, FP0_REGNUM, FPC_REGNUM, FPCWD_REGNUM, + FPSWD_REGNUM, FPTWD_REGNUM, FPIPO_REGNUM, FPIPS_REGNUM, + FPOOS_REGNUM, FPOPS_REGNUM, REGISTER_BYTES, REGISTER_BYTE, + REGBYTE_0, REGBYTE_10 REGBYTE_16, REGBYTE_24, REGBYTE_29, + REGISTER_RAW_SIZE, REGISTER_VIRTUAL_SIZE, MAX_REGISTER_RAW_SIZE, + MAX_REGISTER_VIRTUAL_SIZE, REGISTER_CONVERTIBLE): Definitions + deleted. + (i387_to_double, double_to_i387): Declarations deleted. + (REGISTER_CONVERT_TO_VIRTUAL, REGISTER_CONVERT_TO_RAW, + REGISTER_VIRTUAL_TYPE): Use definitions from + config/i386/tm-i386.h, unless LD_I387 is #defined. + + * go32-nat.c (go32_fetch_registers, store_register) + (go32_create_inferior, init_go32_ops): Replace fatal with + internal_error. + (sig_map): Map exception 7 to TARGET_SIGNAL_EMT. + + * utils.c (notice_quit): Doc fixes. + +1999-11-15 Kevin Buettner + + * gdbserver/server.h (initialize_low): Declare this target + specific function. + * gdbserver/server.c (main): Call initialize_low. + * gdbserver/low-hppabsd.c, gdbserver/low-linux.c, + gdbserver/low-sim.c, gdbserver/low-sparc.c, gdbserver/low-sun3.c + (initialize_low): Renamed from initialize. Also removed + initialization of inferior_pid. + (have_inferior_p): Removed. + * gdbserver/low-lynx.c (initialize_low): New function. + +1999-11-12 Fernando Nasser + + * remote-rdi.c: Fix indentation accordingly to GNU standards. + +Thu Oct 28 00:28:51 1999 Andrew Cagney + + * d10v-tdep.c (d10v_gdbarch_init): Make the d10v:ts3 the default. + +Tue Oct 26 09:57:29 1999 Andrew Cagney + + * gdbarch.sh: Re-sync with Cagney's earlier const change. + +Sun Oct 24 20:07:31 1999 Andrew Cagney + + * d10v-tdep.c (struct gdbarch_tdep): Replace nr_a_regs, + imap0_regnum, nr_imap_regs, dmap0_regnum, with dmap_register and + imap_register. + (R0_REGNUM, LR_REGNUM, PSW_REGNUM, NR_IMAP_REGS, NR_A_REGS): + Convert to enums. + (TS2_NR_A_REGS, TS2_NR_IMAP_REGS, TS3_NR_IMAP_REGS, + TS3_NR_A_REGS): Delete. + (d10v_ts2_dmap_register, d10v_ts3_dmap_register, + d10v_ts2_imap_register, d10v_ts3_imap_register): New functions. + (d10v_dmap_register, d10v_imap_register, + d10v_ts2_register_sim_regno, d10v_ts3_register_sim_regno, + show_regs): Update. + (remote_d10v_translate_xfer_address): Rewrite. Use + sim_d10v_translate_addr to translate addresses. + (d10v_gdbarch_init): Initialize tdep members dmap_register and + imap_register. + +Sun Oct 24 00:12:44 1999 Andrew Cagney + + * d10v-tdep.c (struct gdbarch_tdep): Declare. + (NR_IMAP_REGS, NR_DMAP_REGS, A0_REGNUM, NR_A_REGS): Redefine using + value in gdbarch_tdep. + (d10v_dmap_register, d10v_imap_register): Ditto. + (d10v_ts2_register_name, d10v_ts2_register_sim_regno): Rename + d10v_register_name and d10v_register_sim_regno + (enum ts3_regnums, d10v_ts3_register_name, + d10v_ts3_register_sim_regno, d10v_register_sim_regno): New. + (d10v_gdbarch_init): Configure registers and G packet according to + d10v/ts2 and d10v/ts3. + +Sat Oct 23 21:28:02 1999 Andrew Cagney + + * config/d10v/tm-d10v.h (IMAP0_REGNUM, IMAP1_REGNUM, DMAP_REGNUM): + Delete macro. + (R0_REGNUM, LR_REGNUM, PSW_REGNUM, A0_REGNUM): Move from here. + * d10v-tdep.c: To here. + + * d10v-tdep.c: (NR_DMAP_REGS, NR_IMAP_REGS, NR_A_REGS): Define. + (d10v_dmap_register, d10v_imap_register): New functions. + (remote_d10v_translate_xfer_address): Make static. + (d10v_register_virtual_size): Use TYPE_LENGTH of + REGISTER_VIRTUAL_TYPE. + (d10v_register_byte, do_d10v_pop_frame, + remote_d10v_translate_xfer_address, show_regs, + d10v_register_raw_size): Ditto. + (d10v_register_virtual_type): Ditto. Use explicitly sized builtin + types. + +Sat Oct 23 19:08:39 1999 Andrew Cagney + + * d10v-tdep.c: Include "sim-d10v.h". + (enum ts2_regnums): Declare. + (d10v_register_sim_regno): New function. + + * config/d10v/tm-d10v.h: Delete pre multi-arch code. + (REGISTER_SIM_REGNO): Define. + (d10v_register_sim_regno): Declare. + +Sat Oct 23 16:39:34 1999 Andrew Cagney + + * gdbarch.c (initialize_current_architecture): Make ``choice'' + const. + +Wed Nov 10 16:10:22 1999 Jeffrey A Law (law@cygnus.com) + + * hppa-tdep.c (hppa_fix_call_dummy): Fix typo in error message. + +Wed Nov 10 16:47:06 1999 Andrew Cagney + + * utils.c (error_last_message): Use gdb_file_xstrdup. + + * defs.h (verror, internal_verror): Declare. + + * utils.c (verror, internal_error): New functions. + (error, internal_error): Use verror / internal_verror. + (error_stream): Use gdb_file_xstrdup. Correctly handle %s in + error message body. + (error_init): Use mem_fileopen. + + * corefile.c (memory_error): Use mem_fileopen instead of + tui_sfileopen. Don't call error_begin. + * remote-sim.c (gdb_os_error): Rewrite using verror. Don't call + error_begin. + +Wed Nov 10 14:21:43 1999 Andrew Cagney + + * defs.h (gdb_file_xstrdup): New function. + * utils.c (gdb_file_xstrdup, do_gdb_file_xstrdup): Implement. + +1999-11-09 Stan Shebs + + * exec.c (exec_file_attach), irix5-nat.c, osfsolib.c, solib.c + (info_sharedlibrary_command), pa64solib.c + (pa64_sharedlibrary_info_command), somsolib.c + (som_sharedlibrary_info_command): Replace "exec file" with + "executable file" in messages. + +1999-11-09 Jim Blandy + + Finish the job attempted by the previous change. + * stabsread.c (read_range_type): Make n2 and n3 LONGEST. Adjust + the various tests that check for maximum values, bit counts, etc. + In the long run, it might have been simpler just to give GDB bignums. + +Tue Nov 9 18:34:13 1999 Andrew Cagney + + * defs.h (gdb_file_put): Add parameter write. + (gdb_file_put_method_ftype): New typedef. + * utils.c (gdb_file_put, mem_file_put, tui_file_put, + null_file_put): Update. + + * utils.c (struct gdb_file): Add field magic. + (gdb_file_new): Initialize. + (gdb_file_data): Verify. + + * utils.c (mem_file_fputs): Delete. Replaced by. + (mem_file_write): New function. Rewrite mem_file. + (mem_file_new): Update. + +Tue Nov 9 17:51:12 1999 Andrew Cagney + + * remote-sim.c (gdb_os_write_stdout): Use gdb_file_write. + (gdb_os_flush_stdout): Flush gdb_stdtarg instead of gdb_stdout. + +Tue Nov 9 15:33:43 1999 Andrew Cagney + + * Makefile.in (procfs.o): Don't compile with -Werror for moment. + * sol-thread.c (info_cb): Move assignments to outside of if + statement. + (info_cb): Use paddr when printing addresses. + +1999-11-08 Jim Blandy + + * defs.h (ULONGEST_MAX, LONGEST_MAX): New definitions. + * stabsread.c (read_huge_number): Parse and return LONGEST values. + 1999-11-08 Mark Salter * utils.c (floatformat_to_doublest): Fix conversion of denormals. @@ -423,7 +619,10 @@ Thu Nov 4 17:36:27 1999 Andrew Cagney * gdbtypes.c (init_simd_type): The upper bound to create_range_type is inclusive, not exclusive. - * configure.in: Check for PTRACE_GETXFPREGS, and #define + Add preliminary support for the Pentium-III's Streaming SIMD + Extensions --- specifically, the ability to read the XMM + registers. + * Configure.in: Check for PTRACE_GETXFPREGS, and #define HAVE_PTRACE_GETXFPREGS if we have it. * acconfig.h: Add entry for HAVE_PTRACE_GETXFPREGS. * configure, config.in: Regenerated. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 8686020c56b..acffdb02f89 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -229,7 +229,7 @@ CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \ ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES) ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES) -VERSION = 19991108 +VERSION = 19991116 DIST=gdb LINT=/usr/5bin/lint @@ -1407,8 +1407,11 @@ printcmd.o: printcmd.c $(breakpoint_h) $(defs_h) $(expression_h) \ $(gdbcmd_h) $(gdbcore_h) $(gdbtypes_h) language.h objfiles.h \ symfile.h $(symtab_h) target.h gdb_string.h +# FIXME: Procfs.o gets -Wformat errors because things like pid_t don't +# match output format strings. procfs.o: procfs.c $(command_h) $(defs_h) $(gdbcore_h) $(inferior_h) \ target.h gdb_string.h + $(CC) -c $(INTERNAL_WARN_CFLAGS) $(NO_WERROR_CFLAGS) $< sol-thread.o: sol-thread.c $(defs_h) gdbthread.h target.h $(inferior_h) \ $(gdbcmd_h) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index ca7bb08cdf4..62dcb27b0c8 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -2066,6 +2066,7 @@ print_it_typical (bs) printf_filtered ("\n"); return PRINT_UNKNOWN; break; + /* Fall through, we don't deal with these types of breakpoints here. */ @@ -2271,9 +2272,14 @@ watchpoint_check (p) So we can't even detect the first assignment to it and watch after that (since the garbage may or may not equal the first value assigned). */ + /* We print all the stop information in print_it_typical(), but + in this case, by the time we call print_it_typical() this bp + will be deleted already. So we have no choice but print the + information here. */ printf_filtered ("\ Watchpoint %d deleted because the program has left the block in\n\ which its expression is valid.\n", bs->breakpoint_at->number); + if (b->related_breakpoint) b->related_breakpoint->disposition = del_at_next_stop; b->disposition = del_at_next_stop; @@ -2408,6 +2414,9 @@ bpstat_stop_status (pc, not_a_breakpoint) { case WP_DELETED: /* We've already printed what needs to be printed. */ + /* Actually this is superfluous, because by the time we + call print_it_typical() the wp will be already deleted, + and the function will return immediately. */ bs->print_it = print_it_done; /* Stop. */ break; diff --git a/gdb/config/d10v/tm-d10v.h b/gdb/config/d10v/tm-d10v.h index 1983f690ac6..e2fe383d28f 100644 --- a/gdb/config/d10v/tm-d10v.h +++ b/gdb/config/d10v/tm-d10v.h @@ -22,290 +22,5 @@ #define GDB_MULTI_ARCH 1 -/* #define GDB_TARGET_IS_D10V - moved to gdbarch.h */ - -/* Define the bit, byte, and word ordering of the machine. */ - -#if !GDB_MULTI_ARCH - -#define TARGET_BYTE_ORDER BIG_ENDIAN - -/* Offset from address of function to start of its code. - Zero on most machines. */ - -#define FUNCTION_START_OFFSET 0 - -/* Advance PC across any function entry prologue instructions - to reach some "real" code. */ - -extern CORE_ADDR d10v_skip_prologue (); -#define SKIP_PROLOGUE(ip) (d10v_skip_prologue (ip)) - -/* Stack grows downward. */ -#define INNER_THAN(lhs,rhs) (core_addr_lessthan ((lhs), (rhs))) - -/* for a breakpoint, use "dbt || nop" */ -extern breakpoint_from_pc_fn d10v_breakpoint_from_pc; -#define BREAKPOINT_FROM_PC(PCPTR,LENPTR) (d10v_breakpoint_from_pc ((PCPTR), (LENPTR))) - -/* If your kernel resets the pc after the trap happens you may need to - define this before including this file. */ -#define DECR_PC_AFTER_BREAK 4 - -extern char *d10v_register_name PARAMS ((int reg_nr)); -#define REGISTER_NAME(NR) (d10v_register_name (NR)) - -#define NUM_REGS 37 - -#endif /* GDB_MULTI_ARCH */ - -/* Register numbers of various important registers. - Note that some of these values are "real" register numbers, - and correspond to the general registers of the machine, - and some are "phony" register numbers which are too large - to be actual register numbers as far as the user is concerned - but do serve to get the desired values when passed to read_register. */ - -/* Used by both d10v-tdep.c and remote-d10v.c */ - -#define R0_REGNUM 0 -#define LR_REGNUM 13 -#if !GDB_MULTI_ARCH -#define SP_REGNUM 15 -#define FP_REGNUM 11 -#define PC_REGNUM 18 -#endif -#define PSW_REGNUM 16 -#define IMAP0_REGNUM 32 -#define IMAP1_REGNUM 33 -#define DMAP_REGNUM 34 -#define A0_REGNUM 35 - -#if !GDB_MULTI_ARCH - -/* ??? */ -#define REGISTER_SIZE 2 - -/* Say how much memory is needed to store a copy of the register set */ -#define REGISTER_BYTES ((37/*NUM_REGS*/-2)*2+16) - -/* Index within `registers' of the first byte of the space for - register N. */ -extern int d10v_register_byte PARAMS ((int reg_nr)); -#define REGISTER_BYTE(N) (d10v_register_byte (N)) - -/* Number of bytes of storage in the actual machine representation - for register N. */ -extern int d10v_register_raw_size PARAMS ((int reg_nr)); -#define REGISTER_RAW_SIZE(N) (d10v_register_raw_size (N)) - -/* Number of bytes of storage in the program's representation - for register N. */ -extern int d10v_register_virtual_size PARAMS ((int reg_nr)); -#define REGISTER_VIRTUAL_SIZE(N) (d10v_register_virtual_size (N)) - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#define MAX_REGISTER_RAW_SIZE 8 - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ - -#define MAX_REGISTER_VIRTUAL_SIZE 8 - -/* Return the GDB type object for the "standard" data type - of data in register N. */ - -extern struct type *d10v_register_virtual_type PARAMS ((int reg_nr)); -#define REGISTER_VIRTUAL_TYPE(N) (d10v_register_virtual_type (N)) - -/* convert $pc and $sp to/from virtual addresses */ -extern int d10v_register_convertible PARAMS ((int nr)); -extern void d10v_register_convert_to_virtual PARAMS ((int regnum, struct type * type, char *from, char *to)); -extern void d10v_register_convert_to_raw PARAMS ((struct type * type, int regnum, char *from, char *to)); -#define REGISTER_CONVERTIBLE(N) (d10v_register_convertible ((N))) -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ - d10v_register_convert_to_virtual ((REGNUM), (TYPE), (FROM), (TO)) -#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ - d10v_register_convert_to_raw ((TYPE), (REGNUM), (FROM), (TO)) - -extern CORE_ADDR d10v_make_daddr PARAMS ((CORE_ADDR x)); -#define D10V_MAKE_DADDR(x) (d10v_make_daddr (x)) -extern CORE_ADDR d10v_make_iaddr PARAMS ((CORE_ADDR x)); -#define D10V_MAKE_IADDR(x) (d10v_make_iaddr (x)) - -extern int d10v_daddr_p PARAMS ((CORE_ADDR x)); -#define D10V_DADDR_P(X) (d10v_daddr_p (X)) -extern int d10v_iaddr_p PARAMS ((CORE_ADDR x)); -#define D10V_IADDR_P(X) (d10v_iaddr_p (X)) - -extern CORE_ADDR d10v_convert_daddr_to_raw PARAMS ((CORE_ADDR x)); -#define D10V_CONVERT_DADDR_TO_RAW(X) (d10v_convert_daddr_to_raw (X)) -extern CORE_ADDR d10v_convert_iaddr_to_raw PARAMS ((CORE_ADDR x)); -#define D10V_CONVERT_IADDR_TO_RAW(X) (d10v_convert_iaddr_to_raw (X)) - -/* Store the address of the place in which to copy the structure the - subroutine will return. This is called from call_function. - - We store structs through a pointer passed in the first Argument - register. */ - -extern void d10v_store_struct_return PARAMS ((CORE_ADDR addr, CORE_ADDR sp)); -#define STORE_STRUCT_RETURN(ADDR, SP) d10v_store_struct_return ((ADDR), (SP)) - - -/* Write into appropriate registers a function return value - of type TYPE, given in virtual format. - - Things always get returned in RET1_REGNUM, RET2_REGNUM, ... */ - -extern void d10v_store_return_value PARAMS ((struct type * type, char *valbuf)); -#define STORE_RETURN_VALUE(TYPE,VALBUF) d10v_store_return_value ((TYPE), (VALBUF)) - - -/* Extract from an array REGBUF containing the (raw) register state - the address in which a function should return its structure value, - as a CORE_ADDR (or an expression that can be used as one). */ - -extern CORE_ADDR d10v_extract_struct_value_address PARAMS ((char *regbuf)); -#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (d10v_extract_struct_value_address ((REGBUF))) - -/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of - EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc - and TYPE is the type (which is known to be struct, union or array). - - The d10v returns anything less than 8 bytes in size in - registers. */ - -extern use_struct_convention_fn d10v_use_struct_convention; -#define USE_STRUCT_CONVENTION(gcc_p, type) d10v_use_struct_convention (gcc_p, type) - - -/* Define other aspects of the stack frame. - we keep a copy of the worked out return pc lying around, since it - is a useful bit of info */ - -extern void d10v_init_extra_frame_info PARAMS ((int fromleaf, struct frame_info * fi)); -#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \ - d10v_init_extra_frame_info(fromleaf, fi) - -/* A macro that tells us whether the function invocation represented - by FI does not have a frame on the stack associated with it. If it - does not, FRAMELESS is set to 1, else 0. */ - -#define FRAMELESS_FUNCTION_INVOCATION(FI) \ - (frameless_look_for_prologue (FI)) - -extern CORE_ADDR d10v_frame_chain PARAMS ((struct frame_info * frame)); -#define FRAME_CHAIN(FRAME) d10v_frame_chain(FRAME) -extern int d10v_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *)); -#define FRAME_CHAIN_VALID(chain, thisframe) d10v_frame_chain_valid (chain, thisframe) -extern CORE_ADDR d10v_frame_saved_pc PARAMS ((struct frame_info * fi)); -#define FRAME_SAVED_PC(fi) (d10v_frame_saved_pc ((fi))) -extern CORE_ADDR d10v_frame_args_address PARAMS ((struct frame_info * fi)); -#define FRAME_ARGS_ADDRESS(fi) (d10v_frame_args_address ((fi))) -extern CORE_ADDR d10v_frame_locals_address PARAMS ((struct frame_info * fi)); -#define FRAME_LOCALS_ADDRESS(fi) (d10v_frame_locals_address ((fi))) - -/* Immediately after a function call, return the saved pc. We can't */ -/* use frame->return_pc beause that is determined by reading R13 off the */ -/*stack and that may not be written yet. */ - -extern CORE_ADDR d10v_saved_pc_after_call PARAMS ((struct frame_info * frame)); -#define SAVED_PC_AFTER_CALL(frame) (d10v_saved_pc_after_call ((frame))) - -/* Set VAL to the number of args passed to frame described by FI. - Can set VAL to -1, meaning no way to tell. */ -/* We can't tell how many args there are */ - -#define FRAME_NUM_ARGS(fi) (-1) - -/* Return number of bytes at start of arglist that are not really args. */ - -#define FRAME_ARGS_SKIP 0 - -/* Put here the code to store, into frame_info->saved_regs, the - addresses of the saved registers of frame described by FRAME_INFO. - This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: the address we - return for it IS the sp for the next frame. */ - -extern void d10v_frame_init_saved_regs PARAMS ((struct frame_info *)); -#define FRAME_INIT_SAVED_REGS(frame_info) \ - d10v_frame_init_saved_regs(frame_info) - -/* DUMMY FRAMES. Need these to support inferior function calls. They - work like this on D10V: First we set a breakpoint at 0 or __start. - Then we push all the registers onto the stack. Then put the - function arguments in the proper registers and set r13 to our - breakpoint address. Finally, the PC is set to the start of the - function being called (no JSR/BSR insn). When it hits the - breakpoint, clear the break point and pop the old register contents - off the stack. */ - -extern void d10v_pop_frame PARAMS ((void)); -#define POP_FRAME d10v_pop_frame () - -#define USE_GENERIC_DUMMY_FRAMES 1 -#define CALL_DUMMY {0} -#define CALL_DUMMY_START_OFFSET (0) -#define CALL_DUMMY_BREAKPOINT_OFFSET (0) -#define CALL_DUMMY_LOCATION AT_ENTRY_POINT -#define FIX_CALL_DUMMY(DUMMY, START, FUNADDR, NARGS, ARGS, TYPE, GCCP) -#define CALL_DUMMY_ADDRESS() entry_point_address () -extern CORE_ADDR d10v_push_return_address PARAMS ((CORE_ADDR pc, CORE_ADDR sp)); -#define PUSH_RETURN_ADDRESS(PC, SP) d10v_push_return_address (PC, SP) - -#define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP) -/* #define PC_IN_CALL_DUMMY(pc, sp, frame_address) ( pc == IMEM_START + 4 ) */ - -#define PUSH_DUMMY_FRAME generic_push_dummy_frame () - -/* override the default get_saved_register function with one that - takes account of generic CALL_DUMMY frames */ -#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \ - generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) - -#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \ - (d10v_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr))) -extern CORE_ADDR d10v_push_arguments PARAMS ((int, struct value **, CORE_ADDR, int, CORE_ADDR)); - - -/* Extract from an array REGBUF containing the (raw) register state - a function return value of type TYPE, and copy that, in virtual format, - into VALBUF. */ - -#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ -d10v_extract_return_value(TYPE, REGBUF, VALBUF) -extern void d10v_extract_return_value PARAMS ((struct type *, char *, char *)); - - -void d10v_write_pc PARAMS ((CORE_ADDR val, int pid)); -CORE_ADDR d10v_read_pc PARAMS ((int pid)); -void d10v_write_sp PARAMS ((CORE_ADDR val)); -CORE_ADDR d10v_read_sp PARAMS ((void)); -void d10v_write_fp PARAMS ((CORE_ADDR val)); -CORE_ADDR d10v_read_fp PARAMS ((void)); - -#define TARGET_READ_PC(pid) d10v_read_pc (pid) -#define TARGET_WRITE_PC(val,pid) d10v_write_pc (val, pid) -#define TARGET_READ_FP() d10v_read_fp () -#define TARGET_WRITE_FP(val) d10v_write_fp (val) -#define TARGET_READ_SP() d10v_read_sp () -#define TARGET_WRITE_SP(val) d10v_write_sp (val) - -/* Number of bits in the appropriate type */ -#define TARGET_INT_BIT (2 * TARGET_CHAR_BIT) -#define TARGET_PTR_BIT (4 * TARGET_CHAR_BIT) -#define TARGET_DOUBLE_BIT (4 * TARGET_CHAR_BIT) -#define TARGET_LONG_DOUBLE_BIT (8 * TARGET_CHAR_BIT) - - -/* For the d10v when talking to the remote d10v board, GDB addresses - need to be translated into a format that the d10v rom monitor - understands. */ - -extern void remote_d10v_translate_xfer_address PARAMS ((CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR * rem_addr, int *rem_len)); -#define REMOTE_TRANSLATE_XFER_ADDRESS(GDB_ADDR, GDB_LEN, REM_ADDR, REM_LEN) \ - remote_d10v_translate_xfer_address ((GDB_ADDR), (GDB_LEN), (REM_ADDR), (REM_LEN)) - -#endif +extern int d10v_register_sim_regno (int reg); +#define REGISTER_SIM_REGNO(NR) d10v_register_sim_regno((NR)) diff --git a/gdb/config/i386/tm-go32.h b/gdb/config/i386/tm-go32.h index 579355252ae..3db97f9f0c7 100644 --- a/gdb/config/i386/tm-go32.h +++ b/gdb/config/i386/tm-go32.h @@ -18,108 +18,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "i386/tm-i386v.h" - -/* Number of machine registers. */ - -#undef NUM_FREGS -#define NUM_FREGS 15 -#undef NUM_REGS -#define NUM_REGS (16+NUM_FREGS) - -/* Initializer for an array of names of registers. There should be - NUM_REGS strings in this initializer. */ - -/* The order of the first 8 registers must match the compiler's - numbering scheme (which is the same as the 386 scheme). */ - -#undef REGISTER_NAMES -#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \ - "esp", "ebp", "esi", "edi", \ - "eip", "eflags","cs", "ss", \ - "ds", "es", "fs", "gs", \ - "st0", "st1", "st2", "st3", \ - "st4", "st5", "st6", "st7", \ - "fctrl","fstat", "ftag", "fcs", \ - "fopsel","fip", "fopoff" } - -#undef FP_REGNUM -#define FP_REGNUM 5 /* (ebp) Contains addr of stack frame */ -#undef SP_REGNUM -#define SP_REGNUM 4 /* (usp) Contains address of top of stack */ -#undef PS_REGNUM -#define PS_REGNUM 9 /* (ps) Contains processor status */ -#undef PC_REGNUM -#define PC_REGNUM 8 /* (eip) Contains program counter */ -#undef FP0_REGNUM -#define FP0_REGNUM 16 /* Floating point register 0 */ -#undef FPC_REGNUM -#define FPC_REGNUM 24 /* 80387 control register */ -#undef FPCWD_REGNUM -#define FPCWD_REGNUM FPC_REGNUM -#undef FPSWD_REGNUM -#define FPSWD_REGNUM 25 /* 80387 status register */ -#undef FPTWD_REGNUM -#define FPTWD_REGNUM 26 /* 80387 tag register */ -#undef FPIPO_REGNUM -#define FPIPO_REGNUM 29 /* 80387 instruction pointer offset reg */ -#undef FPIPS_REGNUM -#define FPIPS_REGNUM 27 /* 80387 instruction pointer selector reg */ -#undef FPOOS_REGNUM -#define FPOOS_REGNUM 30 /* 80387 operand pointer offset reg */ -#undef FPOPS_REGNUM -#define FPOPS_REGNUM 28 /* 80387 operand pointer selector reg */ - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. */ - -#undef REGISTER_BYTES -#define REGISTER_BYTES (10*4 + 6*2 + 8*10 + 5*2 + 2*4) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#undef REGISTER_BYTE -#define REGBYTE_0 0 -#define REGBYTE_10 (REGBYTE_0+10*4) -#define REGBYTE_16 (REGBYTE_10+6*2) -#define REGBYTE_24 (REGBYTE_16+8*10) -#define REGBYTE_29 (REGBYTE_24+5*2) -#define REGISTER_BYTE(N) (((N) < 10) ? (N) * 4 : \ - (N) < 16 ? REGBYTE_10 +((N) - 10) * 2 : \ - (N) < 24 ? REGBYTE_16 +((N) - 16) * 10 : \ - (N) < 29 ? REGBYTE_24 +((N) - 24) * 2 : \ - REGBYTE_29 + ((N) - 29) * 4) - -/* Number of bytes of storage in the actual machine representation - for register N. */ - -#undef REGISTER_RAW_SIZE -#define REGISTER_RAW_SIZE(N) ((N) < 10 ? 4 : (N) < 16 ? 2 : (N) < 24 ? 10 : \ - (N) < 29 ? 2 : 4) - -/* Number of bytes of storage in the program's representation - for register N. */ - -#undef REGISTER_VIRTUAL_SIZE -#define REGISTER_VIRTUAL_SIZE(N) REGISTER_RAW_SIZE(N) - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#undef MAX_REGISTER_RAW_SIZE -#define MAX_REGISTER_RAW_SIZE 10 - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ - -#undef MAX_REGISTER_VIRTUAL_SIZE -#define MAX_REGISTER_VIRTUAL_SIZE 10 - -/* Nonzero if register N requires conversion - from raw format to virtual format. */ - -#undef REGISTER_CONVERTIBLE -#define REGISTER_CONVERTIBLE(N) ((N) < FP0_REGNUM ? 0 :\ - (N) < FPC_REGNUM ? 1 : 0) +#undef HAVE_SSE_REGS /* FIXME! go32-nat.c needs to support XMMi registers */ +#define HAVE_I387_REGS + +#include "i386/tm-i386.h" /* The host and target are i386 machines and the compiler supports long doubles. Long doubles on the host therefore have the same @@ -142,70 +44,34 @@ extern int i387_hex_long_double_input (char *p, long double *putithere); +#ifdef LD_I387 /* otherwise, definitions from tm-i386.h are good enough */ + #undef REGISTER_CONVERT_TO_VIRTUAL -#ifdef LD_I387 -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ -{ \ - if (TYPE == REGISTER_VIRTUAL_TYPE (REGNUM)) \ - { \ - memcpy (TO, FROM, TYPE_LENGTH (TYPE)); \ - } \ - else \ - { \ - long double val = *((long double *)FROM); \ - store_floating ((TO), TYPE_LENGTH (TYPE), val); \ - } \ +#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ +{ \ + long double val = *((long double *)(FROM)); \ + store_floating ((TO), TYPE_LENGTH (TYPE), val); \ } -#else -/* Convert data from raw format for register REGNUM in buffer FROM to - virtual format with type TYPE in buffer TO. */ -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ -{ \ - double val; \ - i387_to_double ((FROM), (char *)&val); \ - store_floating ((TO), TYPE_LENGTH (TYPE), val); \ -} -#endif - -extern void i387_to_double PARAMS ((char *, char *)); #undef REGISTER_CONVERT_TO_RAW -#ifdef LD_I387 -#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ -{ \ - if (TYPE == REGISTER_VIRTUAL_TYPE (REGNUM)) \ - { \ - memcpy (TO, FROM, TYPE_LENGTH (TYPE)); \ - } \ - else \ - { \ - long double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ - *((long double *)TO) = val; \ - } \ -} -#else -#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ -{ \ - double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ - double_to_i387((char *)&val, (TO)); \ +#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ +{ \ + long double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ + *((long double *)(TO)) = val; \ } -#endif -extern void double_to_i387 PARAMS ((char *, char *)); +/* Return the GDB type object for the "standard" data type of data in + register N. Perhaps si and di should go here, but potentially they + could be used for things other than address. */ -/* Return the GDB type object for the "standard" data type of data in - register N. */ +#define REGISTER_VIRTUAL_TYPE(N) \ + (((N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM) \ + ? lookup_pointer_type (builtin_type_void) \ + : IS_FP_REGNUM(N) ? builtin_type_long_double \ + : IS_SSE_REGNUM(N) ? builtin_type_v4sf \ + : builtin_type_int) -#undef REGISTER_VIRTUAL_TYPE -#ifdef LD_I387 -#define REGISTER_VIRTUAL_TYPE(N) \ - ((N < FP0_REGNUM) ? builtin_type_int : \ - (N < FPC_REGNUM) ? builtin_type_long_double : builtin_type_int) -#else -#define REGISTER_VIRTUAL_TYPE(N) \ - ((N < FP0_REGNUM) ? builtin_type_int : \ - (N < FPC_REGNUM) ? builtin_type_double : builtin_type_int) -#endif +#endif /* LD_I387 */ #undef TARGET_LONG_DOUBLE_BIT #define TARGET_LONG_DOUBLE_BIT 96 diff --git a/gdb/config/i386/tm-i386.h b/gdb/config/i386/tm-i386.h index 9f4aaed621c..efc3f417491 100644 --- a/gdb/config/i386/tm-i386.h +++ b/gdb/config/i386/tm-i386.h @@ -148,11 +148,11 @@ extern int i386_skip_prologue PARAMS ((int)); #define FP0_REGNUM 16 /* first FPU floating-point register */ #define FP7_REGNUM 23 /* last FPU floating-point register */ -/* All of these control registers are sixteen bits long (at most) in - the FPU, but are zero-extended to thirty-two bits in GDB's register - file. This makes it easier to compute the size of the control - register file, and somewhat easier to convert to and from the FSAVE - instruction's 32-bit format. */ +/* All of these control registers (except for FCOFF and FDOFF) are + sixteen bits long (at most) in the FPU, but are zero-extended to + thirty-two bits in GDB's register file. This makes it easier to + compute the size of the control register file, and somewhat easier + to convert to and from the FSAVE instruction's 32-bit format. */ #define FIRST_FPU_CTRL_REGNUM 24 #define FCTRL_REGNUM 24 /* FPU control word */ #define FPC_REGNUM 24 /* old name for FCTRL_REGNUM */ diff --git a/gdb/corefile.c b/gdb/corefile.c index 3a5ef9aa340..f41cc55b66e 100644 --- a/gdb/corefile.c +++ b/gdb/corefile.c @@ -236,11 +236,9 @@ memory_error (status, memaddr) int status; CORE_ADDR memaddr; { - GDB_FILE *tmp_stream = tui_sfileopen (130); + struct gdb_file *tmp_stream = mem_fileopen (); make_cleanup_gdb_file_delete (tmp_stream); - error_begin (); - if (status == EIO) { /* Actually, address between memaddr and memaddr + len diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index aecbea5edc5..93e3c6e05a3 100644 --- a/gdb/d10v-tdep.c +++ b/gdb/d10v-tdep.c @@ -35,6 +35,11 @@ #include "objfiles.h" #include "language.h" +#include "sim-d10v.h" + +#undef XMALLOC +#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE))) + struct frame_extra_info { CORE_ADDR return_pc; @@ -42,14 +47,36 @@ struct frame_extra_info int size; }; -/* these are the addresses the D10V-EVA board maps data */ -/* and instruction memory to. */ +struct gdbarch_tdep + { + int a0_regnum; + int nr_dmap_regs; + unsigned long (*dmap_register) (int nr); + unsigned long (*imap_register) (int nr); + int (*register_sim_regno) (int nr); + }; + +/* These are the addresses the D10V-EVA board maps data and + instruction memory to. */ #define DMEM_START 0x2000000 #define IMEM_START 0x1000000 #define STACK_START 0x0007ffe -/* d10v register naming conventions */ +/* d10v register names. */ + +enum + { + R0_REGNUM = 0, + LR_REGNUM = 13, + PSW_REGNUM = 16, + NR_IMAP_REGS = 2, + NR_A_REGS = 2 + }; +#define NR_DMAP_REGS (gdbarch_tdep (current_gdbarch)->nr_dmap_regs) +#define A0_REGNUM (gdbarch_tdep (current_gdbarch)->a0_regnum) + +/* d10v calling convention. */ #define ARG1_REGNUM R0_REGNUM #define ARGN_REGNUM 3 @@ -69,9 +96,6 @@ extern void d10v_frame_init_saved_regs PARAMS ((struct frame_info *)); static void do_d10v_pop_frame PARAMS ((struct frame_info * fi)); -/* FIXME */ -extern void remote_d10v_translate_xfer_address PARAMS ((CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR * rem_addr, int *rem_len)); - int d10v_frame_chain_valid (chain, frame) CORE_ADDR chain; @@ -108,9 +132,19 @@ d10v_breakpoint_from_pc (pcptr, lenptr) return breakpoint; } -char * -d10v_register_name (reg_nr) - int reg_nr; +/* Map the REG_NR onto an ascii name. Return NULL or an empty string + when the reg_nr isn't valid. */ + +enum ts2_regnums + { + TS2_IMAP0_REGNUM = 32, + TS2_DMAP_REGNUM = 34, + TS2_NR_DMAP_REGS = 1, + TS2_A0_REGNUM = 35 + }; + +static char * +d10v_ts2_register_name (int reg_nr) { static char *register_names[] = { @@ -127,6 +161,120 @@ d10v_register_name (reg_nr) return register_names[reg_nr]; } +enum ts3_regnums + { + TS3_IMAP0_REGNUM = 36, + TS3_DMAP0_REGNUM = 38, + TS3_NR_DMAP_REGS = 4, + TS3_A0_REGNUM = 32 + }; + +static char * +d10v_ts3_register_name (int reg_nr) +{ + static char *register_names[] = + { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "psw", "bpsw", "pc", "bpc", "cr4", "cr5", "cr6", "rpt_c", + "rpt_s", "rpt_e", "mod_s", "mod_e", "cr12", "cr13", "iba", "cr15", + "a0", "a1", + "spi", "spu", + "imap0", "imap1", + "dmap0", "dmap1", "dmap2", "dmap3" + }; + if (reg_nr < 0) + return NULL; + if (reg_nr >= (sizeof (register_names) / sizeof (*register_names))) + return NULL; + return register_names[reg_nr]; +} + +/* Access the DMAP/IMAP registers in a target independant way. */ + +static unsigned long +d10v_ts2_dmap_register (int reg_nr) +{ + switch (reg_nr) + { + case 0: + case 1: + return 0x2000; + case 2: + return read_register (TS2_DMAP_REGNUM); + default: + return 0; + } +} + +static unsigned long +d10v_ts3_dmap_register (int reg_nr) +{ + return read_register (TS3_DMAP0_REGNUM + reg_nr); +} + +static unsigned long +d10v_dmap_register (int reg_nr) +{ + return gdbarch_tdep (current_gdbarch)->dmap_register (reg_nr); +} + +static unsigned long +d10v_ts2_imap_register (int reg_nr) +{ + return read_register (TS2_IMAP0_REGNUM + reg_nr); +} + +static unsigned long +d10v_ts3_imap_register (int reg_nr) +{ + return read_register (TS3_IMAP0_REGNUM + reg_nr); +} + +static unsigned long +d10v_imap_register (int reg_nr) +{ + return gdbarch_tdep (current_gdbarch)->imap_register (reg_nr); +} + +/* MAP GDB's internal register numbering (determined by the layout fo + the REGISTER_BYTE array) onto the simulator's register + numbering. */ + +static int +d10v_ts2_register_sim_regno (int nr) +{ + if (nr >= TS2_IMAP0_REGNUM + && nr < TS2_IMAP0_REGNUM + NR_IMAP_REGS) + return nr - TS2_IMAP0_REGNUM + SIM_D10V_IMAP0_REGNUM; + if (nr == TS2_DMAP_REGNUM) + return nr - TS2_DMAP_REGNUM + SIM_D10V_TS2_DMAP_REGNUM; + if (nr >= TS2_A0_REGNUM + && nr < TS2_A0_REGNUM + NR_A_REGS) + return nr - TS2_A0_REGNUM + SIM_D10V_A0_REGNUM; + return nr; +} + +static int +d10v_ts3_register_sim_regno (int nr) +{ + if (nr >= TS3_IMAP0_REGNUM + && nr < TS3_IMAP0_REGNUM + NR_IMAP_REGS) + return nr - TS3_IMAP0_REGNUM + SIM_D10V_IMAP0_REGNUM; + if (nr >= TS3_DMAP0_REGNUM + && nr < TS3_DMAP0_REGNUM + TS3_NR_DMAP_REGS) + return nr - TS3_DMAP0_REGNUM + SIM_D10V_DMAP0_REGNUM; + if (nr >= TS3_A0_REGNUM + && nr < TS3_A0_REGNUM + NR_A_REGS) + return nr - TS3_A0_REGNUM + SIM_D10V_A0_REGNUM; + return nr; +} + +int +d10v_register_sim_regno (int nr) +{ + return gdbarch_tdep (current_gdbarch)->register_sim_regno (nr); +} /* Index within `registers' of the first byte of the space for register REG_NR. */ @@ -135,10 +283,15 @@ int d10v_register_byte (reg_nr) int reg_nr; { - if (reg_nr > A0_REGNUM) - return ((reg_nr - A0_REGNUM) * 8 + (A0_REGNUM * 2)); - else + if (reg_nr < A0_REGNUM) return (reg_nr * 2); + else if (reg_nr < (A0_REGNUM + NR_A_REGS)) + return (A0_REGNUM * 2 + + (reg_nr - A0_REGNUM) * 8); + else + return (A0_REGNUM * 2 + + NR_A_REGS * 8 + + (reg_nr - A0_REGNUM - NR_A_REGS) * 2); } /* Number of bytes of storage in the actual machine representation for @@ -148,7 +301,9 @@ int d10v_register_raw_size (reg_nr) int reg_nr; { - if (reg_nr >= A0_REGNUM) + if (reg_nr < A0_REGNUM) + return 2; + else if (reg_nr < (A0_REGNUM + NR_A_REGS)) return 8; else return 2; @@ -161,12 +316,7 @@ int d10v_register_virtual_size (reg_nr) int reg_nr; { - if (reg_nr >= A0_REGNUM) - return 8; - else if (reg_nr == PC_REGNUM || reg_nr == SP_REGNUM) - return 4; - else - return 2; + return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (reg_nr)); } /* Return the GDB type object for the "standard" data type @@ -176,12 +326,14 @@ struct type * d10v_register_virtual_type (reg_nr) int reg_nr; { - if (reg_nr >= A0_REGNUM) - return builtin_type_long_long; - else if (reg_nr == PC_REGNUM || reg_nr == SP_REGNUM) - return builtin_type_long; + if (reg_nr >= A0_REGNUM + && reg_nr < (A0_REGNUM + NR_A_REGS)) + return builtin_type_int64; + else if (reg_nr == PC_REGNUM + || reg_nr == SP_REGNUM) + return builtin_type_int32; else - return builtin_type_short; + return builtin_type_int16; } /* convert $pc and $sp to/from virtual addresses */ @@ -363,7 +515,7 @@ do_d10v_pop_frame (fi) d10v_frame_init_saved_regs (fi); /* now update the current registers with the old values */ - for (regnum = A0_REGNUM; regnum < A0_REGNUM + 2; regnum++) + for (regnum = A0_REGNUM; regnum < A0_REGNUM + NR_A_REGS; regnum++) { if (fi->saved_regs[regnum]) { @@ -754,12 +906,24 @@ show_regs (args, from_tty) (long) read_register (13), (long) read_register (14), (long) read_register (15)); - printf_filtered ("IMAP0 %04lx IMAP1 %04lx DMAP %04lx\n", - (long) read_register (IMAP0_REGNUM), - (long) read_register (IMAP1_REGNUM), - (long) read_register (DMAP_REGNUM)); - printf_filtered ("A0-A1"); - for (a = A0_REGNUM; a <= A0_REGNUM + 1; a++) + for (a = 0; a < NR_IMAP_REGS; a++) + { + if (a > 0) + printf_filtered (" "); + printf_filtered ("IMAP%d %04lx", a, d10v_imap_register (a)); + } + if (NR_DMAP_REGS == 1) + printf_filtered (" DMAP %04lx\n", d10v_dmap_register (2)); + else + { + for (a = 0; a < NR_DMAP_REGS; a++) + { + printf_filtered (" DMAP%d %04lx", a, d10v_dmap_register (a)); + } + printf_filtered ("\n"); + } + printf_filtered ("A0-A%d", NR_A_REGS - 1); + for (a = A0_REGNUM; a < A0_REGNUM + NR_A_REGS; a++) { char num[MAX_REGISTER_RAW_SIZE]; int i; @@ -1032,163 +1196,25 @@ d10v_extract_return_value (type, regbuf, valbuf) /* Translate a GDB virtual ADDR/LEN into a format the remote target understands. Returns number of bytes that can be transfered - starting at taddr, ZERO if no bytes can be transfered. */ + starting at TARG_ADDR. Return ZERO if no bytes can be transfered + (segmentation fault). Since the simulator knows all about how the + VM system works, we just call that to do the translation. */ -void +static void remote_d10v_translate_xfer_address (CORE_ADDR memaddr, int nr_bytes, CORE_ADDR *targ_addr, int *targ_len) { - CORE_ADDR phys; - CORE_ADDR seg; - CORE_ADDR off; - char *from = "unknown"; - char *to = "unknown"; - - /* GDB interprets addresses as: - - 0x00xxxxxx: Physical unified memory segment (Unified memory) - 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory) - 0x02xxxxxx: Physical data memory segment (On-chip data memory) - 0x10xxxxxx: Logical data address segment (DMAP translated memory) - 0x11xxxxxx: Logical instruction address segment (IMAP translated memory) - - The remote d10v board interprets addresses as: - - 0x00xxxxxx: Physical unified memory segment (Unified memory) - 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory) - 0x02xxxxxx: Physical data memory segment (On-chip data memory) - - Translate according to current IMAP/dmap registers */ - - enum - { - targ_unified = 0x00000000, - targ_insn = 0x01000000, - targ_data = 0x02000000, - }; - - seg = (memaddr >> 24); - off = (memaddr & 0xffffffL); - - switch (seg) - { - case 0x00: /* Physical unified memory */ - from = "phys-unified"; - phys = targ_unified | off; - to = "unified"; - break; - - case 0x01: /* Physical instruction memory */ - from = "phys-insn"; - phys = targ_insn | off; - to = "chip-insn"; - break; - - case 0x02: /* Physical data memory segment */ - from = "phys-data"; - phys = targ_data | off; - to = "chip-data"; - break; - - case 0x10: /* in logical data address segment */ - { - from = "logical-data"; - if (off <= 0x7fffL) - { - /* On chip data */ - phys = targ_data + off; - if (off + nr_bytes > 0x7fffL) - /* don't cross VM boundary */ - nr_bytes = 0x7fffL - off + 1; - to = "chip-data"; - } - else if (off <= 0xbfffL) - { - unsigned short dmap = read_register (DMAP_REGNUM); - short map = dmap; - - if (map & 0x1000) - { - /* Instruction memory */ - phys = targ_insn | ((map & 0xf) << 14) | (off & 0x3fff); - to = "chip-insn"; - } - else - { - /* Unified memory */ - phys = targ_unified | ((map & 0x3ff) << 14) | (off & 0x3fff); - to = "unified"; - } - if (off + nr_bytes > 0xbfffL) - /* don't cross VM boundary */ - nr_bytes = (0xbfffL - off + 1); - } - else - { - /* Logical address out side of data segments, not supported */ - *targ_len = 0; - return; - } - break; - } - - case 0x11: /* in logical instruction address segment */ - { - short map; - unsigned short imap0 = read_register (IMAP0_REGNUM); - unsigned short imap1 = read_register (IMAP1_REGNUM); - - from = "logical-insn"; - if (off <= 0x1ffffL) - { - map = imap0; - } - else if (off <= 0x3ffffL) - { - map = imap1; - } - else - { - /* Logical address outside of IMAP[01] segment, not - supported */ - *targ_len = 0; - return; - } - if ((off & 0x1ffff) + nr_bytes > 0x1ffffL) - { - /* don't cross VM boundary */ - nr_bytes = 0x1ffffL - (off & 0x1ffffL) + 1; - } - if (map & 0x1000) - /* Instruction memory */ - { - phys = targ_insn | off; - to = "chip-insn"; - } - else - { - phys = ((map & 0x7fL) << 17) + (off & 0x1ffffL); - if (phys > 0xffffffL) - { - /* Address outside of unified address segment */ - *targ_len = 0; - return; - } - phys |= targ_unified; - to = "unified"; - } - break; - } - - default: - *targ_len = 0; - return; - } - - *targ_addr = phys; - *targ_len = nr_bytes; + long out_addr; + long out_len; + out_len = sim_d10v_translate_addr (memaddr, nr_bytes, + &out_addr, + d10v_dmap_register, + d10v_imap_register); + *targ_addr = out_addr; + *targ_len = out_len; } + /* The following code implements access to, and display of, the D10V's instruction trace buffer. The buffer consists of 64K or more 4-byte words of data, of which each words includes an 8-bit count, @@ -1490,6 +1516,7 @@ display_trace (low, high) static gdbarch_init_ftype d10v_gdbarch_init; + static struct gdbarch * d10v_gdbarch_init (info, arches) struct gdbarch_info info; @@ -1498,12 +1525,42 @@ d10v_gdbarch_init (info, arches) static LONGEST d10v_call_dummy_words[] = {0}; struct gdbarch *gdbarch; - int d10v_num_regs = 37; + int d10v_num_regs; + struct gdbarch_tdep *tdep; + gdbarch_register_name_ftype *d10v_register_name; - /* there is only one d10v architecture */ + /* Find a candidate among the list of pre-declared architectures. */ + arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; - gdbarch = gdbarch_alloc (&info, NULL); + + /* None found, create a new architecture from the information + provided. */ + tdep = XMALLOC (struct gdbarch_tdep); + gdbarch = gdbarch_alloc (&info, tdep); + + switch (info.bfd_arch_info->mach) + { + case bfd_mach_d10v_ts2: + d10v_num_regs = 37; + d10v_register_name = d10v_ts2_register_name; + tdep->a0_regnum = TS2_A0_REGNUM; + tdep->nr_dmap_regs = TS2_NR_DMAP_REGS; + tdep->register_sim_regno = d10v_ts2_register_sim_regno; + tdep->dmap_register = d10v_ts2_dmap_register; + tdep->imap_register = d10v_ts2_imap_register; + break; + default: + case bfd_mach_d10v_ts3: + d10v_num_regs = 42; + d10v_register_name = d10v_ts3_register_name; + tdep->a0_regnum = TS3_A0_REGNUM; + tdep->nr_dmap_regs = TS3_NR_DMAP_REGS; + tdep->register_sim_regno = d10v_ts3_register_sim_regno; + tdep->dmap_register = d10v_ts3_dmap_register; + tdep->imap_register = d10v_ts3_imap_register; + break; + } set_gdbarch_read_pc (gdbarch, d10v_read_pc); set_gdbarch_write_pc (gdbarch, d10v_write_pc); diff --git a/gdb/defs.h b/gdb/defs.h index 39142bb463b..3d8f83007b2 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -409,7 +409,8 @@ extern void set_gdb_file_isatty (struct gdb_file *stream, gdb_file_isatty_ftype typedef void (gdb_file_rewind_ftype) (struct gdb_file * stream); extern void set_gdb_file_rewind (struct gdb_file *stream, gdb_file_rewind_ftype * rewind); -typedef void (gdb_file_put_ftype) (struct gdb_file * stream, struct gdb_file * dest); +typedef void (gdb_file_put_method_ftype) (void *object, const char *buffer, long length_buffer); +typedef void (gdb_file_put_ftype) (struct gdb_file *stream, gdb_file_put_method_ftype * method, void *context); extern void set_gdb_file_put (struct gdb_file *stream, gdb_file_put_ftype * put); typedef void (gdb_file_delete_ftype) (struct gdb_file * stream); @@ -439,7 +440,13 @@ extern int gdb_file_isatty (GDB_FILE *); extern void gdb_file_write (struct gdb_file *file, const char *buf, long length_buf); /* NOTE: copies left to right */ -extern void gdb_file_put (struct gdb_file *src, struct gdb_file *dest); +extern void gdb_file_put (struct gdb_file *src, gdb_file_put_method_ftype *write, void *dest); + +/* Returns a freshly allocated buffer containing the entire contents + of FILE (as determined by gdb_file_put()) with a NUL character + appended. LENGTH is set to the size of the buffer minus that + appended NUL. */ +extern char *gdb_file_xstrdup (struct gdb_file *file, long *length); /* More generic printf like operations */ @@ -782,6 +789,14 @@ enum val_prettyprint #define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF for 32-bits */ #endif +#if !defined (ULONGEST_MAX) +#define ULONGEST_MAX (~(ULONGEST)0) /* 0xFFFFFFFFFFFFFFFF for 32-bits */ +#endif + +#if !defined (LONGEST_MAX) /* 0x7FFFFFFFFFFFFFFF for 32-bits */ +#define LONGEST_MAX ((LONGEST)(ULONGEST_MAX >> 1)) +#endif + /* Convert a LONGEST to an int. This is used in contexts (e.g. number of arguments to a function, number in a value history, register number, etc.) where the value must not be larger than can fit in an int. */ @@ -823,16 +838,23 @@ extern char *quit_pre_print; extern char *warning_pre_print; -extern NORETURN void error (const char *, ...) ATTR_NORETURN; +extern NORETURN void verror (const char *fmt, va_list ap) ATTR_NORETURN; -extern void error_begin (void); +extern NORETURN void error (const char *fmt, ...) ATTR_NORETURN; -extern NORETURN void internal_error (char *, ...) ATTR_NORETURN; +/* DEPRECATED: Use error(), verror() or error_stream(). */ +extern NORETURN void error_begin (void); extern NORETURN void error_stream (GDB_FILE *) ATTR_NORETURN; +/* Returns a freshly allocate buffer containing the last error + message. */ extern char *error_last_message (void); +extern NORETURN void internal_verror (const char *, va_list ap) ATTR_NORETURN; + +extern NORETURN void internal_error (char *, ...) ATTR_NORETURN; + extern NORETURN void nomem (long) ATTR_NORETURN; /* Reasons for calling return_to_top_level. */ diff --git a/gdb/exec.c b/gdb/exec.c index 2ff76e87eea..8a7da9df88a 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -198,7 +198,7 @@ exec_file_attach (args, from_tty) {; } if (*argv == NULL) - error ("no exec file name was specified"); + error ("No executable file name was specified"); filename = tilde_expand (*argv); make_cleanup (free, filename); diff --git a/gdb/gdbserver/low-hppabsd.c b/gdb/gdbserver/low-hppabsd.c index 7c1b6603d69..de78ad51a0a 100644 --- a/gdb/gdbserver/low-hppabsd.c +++ b/gdb/gdbserver/low-hppabsd.c @@ -369,13 +369,6 @@ write_inferior_memory (memaddr, myaddr, len) } void -initialize () +initialize_low () { - inferior_pid = 0; -} - -int -have_inferior_p () -{ - return inferior_pid != 0; } diff --git a/gdb/gdbserver/low-linux.c b/gdb/gdbserver/low-linux.c index b9573b34e14..3b3e2871466 100644 --- a/gdb/gdbserver/low-linux.c +++ b/gdb/gdbserver/low-linux.c @@ -451,6 +451,15 @@ static int u_offsets[] = PT_F125, PT_F126, PT_F127, + /* predicate registers - we don't fetch these individually */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, /* branch registers */ PT_B0, PT_B1, @@ -460,6 +469,8 @@ static int u_offsets[] = PT_B5, PT_B6, PT_B7, + /* virtual frame pointer and virtual return address pointer */ + -1, -1, /* other registers */ PT_PR, PT_CR_IIP, @@ -735,14 +746,7 @@ write_inferior_memory (memaddr, myaddr, len) } void -initialize () +initialize_low () { - inferior_pid = 0; initialize_arch(); } - -int -have_inferior_p () -{ - return inferior_pid != 0; -} diff --git a/gdb/gdbserver/low-lynx.c b/gdb/gdbserver/low-lynx.c index 75e11ba050a..666956506cf 100644 --- a/gdb/gdbserver/low-lynx.c +++ b/gdb/gdbserver/low-lynx.c @@ -746,3 +746,8 @@ ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n", return 0; } + +void +initialize_low () +{ +} diff --git a/gdb/gdbserver/low-sim.c b/gdb/gdbserver/low-sim.c index 3f9dea26ee9..8d7c2e6c767 100644 --- a/gdb/gdbserver/low-sim.c +++ b/gdb/gdbserver/low-sim.c @@ -276,16 +276,7 @@ write_inferior_memory (memaddr, myaddr, len) return 0; } -#if 0 void -initialize () -{ - inferior_pid = 0; -} - -int -have_inferior_p () +initialize_low () { - return inferior_pid != 0; } -#endif diff --git a/gdb/gdbserver/low-sparc.c b/gdb/gdbserver/low-sparc.c index e0e635e5bd0..178afc79ab0 100644 --- a/gdb/gdbserver/low-sparc.c +++ b/gdb/gdbserver/low-sparc.c @@ -324,13 +324,6 @@ write_inferior_memory (memaddr, myaddr, len) } void -initialize () +initialize_low () { - inferior_pid = 0; -} - -int -have_inferior_p () -{ - return inferior_pid != 0; } diff --git a/gdb/gdbserver/low-sun3.c b/gdb/gdbserver/low-sun3.c index 786770b9a55..71a151e1faf 100644 --- a/gdb/gdbserver/low-sun3.c +++ b/gdb/gdbserver/low-sun3.c @@ -303,13 +303,6 @@ write_inferior_memory (memaddr, myaddr, len) } void -initialize () +initialize_low () { - inferior_pid = 0; -} - -int -have_inferior_p () -{ - return inferior_pid != 0; } diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 8b18f533836..48a7e0f597a 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -62,6 +62,8 @@ main (argc, argv) if (argc < 3) error ("Usage: gdbserver tty prog [args ...]"); + initialize_low (); + /* Wait till we are at first instruction in program. */ signal = start_inferior (&argv[2], &status); diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index c42a65c6c8f..21e4d68b7b5 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -33,6 +33,7 @@ unsigned char mywait PARAMS ((char *status)); void read_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len)); int write_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len)); int create_inferior (); +void initialize_low (); /* Target-specific variables */ diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c index b24312411d0..dae43439988 100644 --- a/gdb/go32-nat.c +++ b/gdb/go32-nat.c @@ -345,7 +345,7 @@ sig_map[] = 4, TARGET_SIGNAL_FPE, 5, TARGET_SIGNAL_SEGV, 6, TARGET_SIGNAL_ILL, - 7, TARGET_SIGNAL_FPE, + 7, TARGET_SIGNAL_EMT, /* no-coprocessor exception */ 8, TARGET_SIGNAL_SEGV, 9, TARGET_SIGNAL_SEGV, 10, TARGET_SIGNAL_BUS, @@ -570,7 +570,8 @@ go32_fetch_registers (int regno) supply_register (regno, (char *) &npx + regno_mapping[regno].tss_ofs); else - fatal ("Invalid register no. %d in go32_fetch_register.", regno); + internal_error ("Invalid register no. %d in go32_fetch_register.", + regno); } } @@ -587,7 +588,7 @@ store_register (int regno) else if (regno < 31) rp = (char *) &npx + regno_mapping[regno].tss_ofs; else - fatal ("Invalid register no. %d in store_register.", regno); + internal_error ("Invalid register no. %d in store_register.", regno); memcpy (rp, v, regno_mapping[regno].size); } @@ -680,7 +681,7 @@ go32_create_inferior (char *exec_file, char *args, char **env) resume_is_step = 0; /* Init command line storage. */ if (redir_debug_init (&child_cmd) == -1) - fatal ("Cannot allocate redirection storage: not enough memory.\n"); + internal_error ("Cannot allocate redirection storage: not enough memory.\n"); /* Parse the command line and create redirections. */ if (strpbrk (args, "<>")) @@ -1311,7 +1312,7 @@ init_go32_ops (void) /* Initialize child's command line storage. */ if (redir_debug_init (&child_cmd) == -1) - fatal ("Cannot allocate redirection storage: not enough memory.\n"); + internal_error ("Cannot allocate redirection storage: not enough memory.\n"); } void diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index 8b1d87fc1c4..1477df2527f 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -2230,7 +2230,7 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p) funsymbol = lookup_minimal_symbol_by_pc (fun); if (!funsymbol) - error ("Unable to find minimal symbol for target fucntion.\n"); + error ("Unable to find minimal symbol for target function.\n"); /* Search all the object files for an import symbol with the right name. */ diff --git a/gdb/irix5-nat.c b/gdb/irix5-nat.c index 7ff0c441c85..eb6208cf15f 100644 --- a/gdb/irix5-nat.c +++ b/gdb/irix5-nat.c @@ -983,7 +983,7 @@ info_sharedlibrary_command (ignore, from_tty) if (exec_bfd == NULL) { - printf_unfiltered ("No exec file.\n"); + printf_unfiltered ("No executable file.\n"); return; } while ((so = find_solib (so)) != NULL) diff --git a/gdb/monitor.c b/gdb/monitor.c index c9c6d5a47cc..3a50c9887aa 100644 --- a/gdb/monitor.c +++ b/gdb/monitor.c @@ -912,6 +912,7 @@ monitor_supply_register (regno, valstr) unsigned char regbuf[MAX_REGISTER_RAW_SIZE]; char *p; + val = 0; p = valstr; while (p && *p != '\0') { diff --git a/gdb/osfsolib.c b/gdb/osfsolib.c index 2c4980455b5..1294072f8ed 100644 --- a/gdb/osfsolib.c +++ b/gdb/osfsolib.c @@ -732,7 +732,7 @@ info_sharedlibrary_command (ignore, from_tty) if (exec_bfd == NULL) { - printf_unfiltered ("No exec file.\n"); + printf_unfiltered ("No executable file.\n"); return; } while ((so = find_solib (so)) != NULL) diff --git a/gdb/pa64solib.c b/gdb/pa64solib.c index e281e6a7216..271efc2367b 100644 --- a/gdb/pa64solib.c +++ b/gdb/pa64solib.c @@ -794,7 +794,7 @@ pa64_sharedlibrary_info_command (ignore, from_tty) if (exec_bfd == NULL) { - printf_unfiltered ("no exec file.\n"); + printf_unfiltered ("No executable file.\n"); return; } diff --git a/gdb/remote-rdi.c b/gdb/remote-rdi.c index 69addf6ed35..73327628ece 100644 --- a/gdb/remote-rdi.c +++ b/gdb/remote-rdi.c @@ -108,13 +108,13 @@ static int max_load_size; static int execute_status; /* Send heatbeat packets? */ -static int rdi_heartbeat = 0; +static int rdi_heartbeat = 0; /* Target has ROM at address 0. */ static int rom_at_zero = 0; /* Enable logging? */ -static int log_enable = 0; +static int log_enable = 0; /* Name of the log file. Default is "rdi.log". */ static char *log_filename; @@ -236,8 +236,8 @@ device is attached to the remote system (e.g. /dev/ttya)."); /* split name after whitespace, pass tail as arg to open command */ - devName = strdup(name); - p = strchr(devName,' '); + devName = strdup (name); + p = strchr (devName, ' '); if (p) { *p = '\0'; @@ -280,7 +280,7 @@ device is attached to the remote system (e.g. /dev/ttya)."); { printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); Adp_CloseDevice (); - error("RID_open failed\n"); + error ("RID_open failed\n"); } rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2); @@ -999,47 +999,49 @@ Specify the serial device it is connected to (e.g. /dev/ttya)."; arm_rdi_ops.to_magic = OPS_MAGIC; } -static void rdilogfile_command (char *arg, int from_tty) +static void +rdilogfile_command (char *arg, int from_tty) { if (!arg || strlen (arg) == 0) { printf_filtered ("rdi log file is '%s'\n", log_filename); return; } - + if (log_filename) free (log_filename); - + log_filename = strdup (arg); Adp_SetLogfile (log_filename); } -static void rdilogenable_command (char *args, int from_tty) +static void +rdilogenable_command (char *args, int from_tty) { if (!args || strlen (args) == 0) { printf_filtered ("rdi log is %s\n", log_enable ? "enabled" : "disabled"); return; } - - if (!strcasecmp (args,"1") || - !strcasecmp (args,"y") || - !strcasecmp (args,"yes") || - !strcasecmp (args,"on") || - !strcasecmp (args,"t") || - !strcasecmp (args,"true")) - Adp_SetLogEnable (log_enable=1); - else if (!strcasecmp (args,"0") || - !strcasecmp (args,"n") || - !strcasecmp (args,"no") || - !strcasecmp (args,"off") || - !strcasecmp (args,"f") || - !strcasecmp (args,"false")) - Adp_SetLogEnable (log_enable=0); + + if (!strcasecmp (args, "1") || + !strcasecmp (args, "y") || + !strcasecmp (args, "yes") || + !strcasecmp (args, "on") || + !strcasecmp (args, "t") || + !strcasecmp (args, "true")) + Adp_SetLogEnable (log_enable = 1); + else if (!strcasecmp (args, "0") || + !strcasecmp (args, "n") || + !strcasecmp (args, "no") || + !strcasecmp (args, "off") || + !strcasecmp (args, "f") || + !strcasecmp (args, "false")) + Adp_SetLogEnable (log_enable = 0); else printf_filtered ("rdilogenable: unrecognized argument '%s'\n" - " try y or n\n",args); + " try y or n\n", args); } void @@ -1048,9 +1050,9 @@ _initialize_remote_rdi () init_rdi_ops (); add_target (&arm_rdi_ops); - log_filename = strdup("rdi.log"); - Adp_SetLogfile(log_filename); - Adp_SetLogEnable(log_enable); + log_filename = strdup ("rdi.log"); + Adp_SetLogfile (log_filename); + Adp_SetLogEnable (log_enable); add_cmd ("rdilogfile", class_maintenance, rdilogfile_command, @@ -1061,7 +1063,7 @@ Without an argument, shows the current logfile name.\n\ See also: rdilogenable\n", &maintenancelist); - add_cmd("rdilogenable", class_maintenance, + add_cmd ("rdilogenable", class_maintenance, rdilogenable_command, "Set enable logging of ADP packets.\n\ This will log ADP packets exchanged between gdb and the\n\ @@ -1078,7 +1080,7 @@ Withough an argument, it will display current state.\n", A true value disables vector catching, false enables vector catching.\n\ This is evaluated at the time the 'target rdi' command is executed\n", &setlist), - &showlist); + &showlist); add_show_from_set (add_set_cmd ("rdiheartbeat", no_class, @@ -1088,7 +1090,7 @@ I don't know why you would want this. If you enable them,\n\ it will confuse ARM and EPI JTAG interface boxes as well\n\ as the Angel Monitor.\n", &setlist), - &showlist); + &showlist); } /* A little dummy to make linking with the library succeed. */ diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c index 0c9d6761f32..74728376dc1 100644 --- a/gdb/remote-sim.c +++ b/gdb/remote-sim.c @@ -194,12 +194,7 @@ gdb_os_write_stdout (p, buf, len) int i; char b[2]; - for (i = 0; i < len; i++) - { - b[0] = buf[i]; - b[1] = 0; - fputs_unfiltered (b, gdb_stdtarg); - } + gdb_file_write (gdb_stdtarg, buf, len); return len; } @@ -209,7 +204,7 @@ static void gdb_os_flush_stdout (p) host_callback *p; { - gdb_flush (gdb_stdout); + gdb_flush (gdb_stdtarg); } /* GDB version of os_write_stderr callback. */ @@ -281,12 +276,8 @@ gdb_os_error (host_callback * p, const char *format,...) { va_list args; va_start (args, format); - - error_begin (); - vfprintf_filtered (gdb_stderr, format, args); - fprintf_filtered (gdb_stderr, "\n"); + verror (format, args); va_end (args); - return_to_top_level (RETURN_ERROR); } } diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c index 218ab38f34c..2ab04b3890b 100644 --- a/gdb/sol-thread.c +++ b/gdb/sol-thread.c @@ -1493,7 +1493,6 @@ info_cb (th, s) { td_err_e ret; td_thrinfo_t ti; - struct minimal_symbol *msym; if ((ret = p_td_thr_get_info (th, &ti)) == TD_OK) { @@ -1527,17 +1526,25 @@ info_cb (th, s) } /* Print thr_create start function: */ if (ti.ti_startfunc != 0) - if (msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc)) - printf_filtered (" startfunc: %s\n", SYMBOL_NAME (msym)); - else - printf_filtered (" startfunc: 0x%08x\n", ti.ti_startfunc); + { + struct minimal_symbol *msym; + msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc); + if (msym) + printf_filtered (" startfunc: %s\n", SYMBOL_NAME (msym)); + else + printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc)); + } /* If thread is asleep, print function that went to sleep: */ if (ti.ti_state == TD_THR_SLEEP) - if (msym = lookup_minimal_symbol_by_pc (ti.ti_pc)) - printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym)); - else - printf_filtered (" - Sleep func: 0x%08x\n", ti.ti_startfunc); + { + struct minimal_symbol *msym; + msym = lookup_minimal_symbol_by_pc (ti.ti_pc); + if (msym) + printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym)); + else + printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc)); + } /* Wrap up line, if necessary */ if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0) diff --git a/gdb/solib.c b/gdb/solib.c index bd490deef29..93eb06611c1 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -1277,7 +1277,7 @@ info_sharedlibrary_command (ignore, from_tty) if (exec_bfd == NULL) { - printf_unfiltered ("No exec file.\n"); + printf_unfiltered ("No executable file.\n"); return; } diff --git a/gdb/somsolib.c b/gdb/somsolib.c index 81a36506d71..cde7f91d286 100644 --- a/gdb/somsolib.c +++ b/gdb/somsolib.c @@ -1445,7 +1445,7 @@ som_sharedlibrary_info_command (ignore, from_tty) if (exec_bfd == NULL) { - printf_unfiltered ("no exec file.\n"); + printf_unfiltered ("No executable file.\n"); return; } diff --git a/gdb/stabsread.c b/gdb/stabsread.c index 464fce1701d..c62a136b64a 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -91,7 +91,7 @@ static char * static struct type * dbx_alloc_type PARAMS ((int[2], struct objfile *)); -static long read_huge_number PARAMS ((char **, int, int *)); +static LONGEST read_huge_number PARAMS ((char **, int, int *)); static struct type *error_type PARAMS ((char **, struct objfile *)); @@ -4480,7 +4480,7 @@ read_sun_floating_type (pp, typenums, objfile) If encounter garbage, set *BITS to -1 and return 0. */ -static long +static LONGEST read_huge_number (pp, end, bits) char **pp; int end; @@ -4488,12 +4488,12 @@ read_huge_number (pp, end, bits) { char *p = *pp; int sign = 1; - long n = 0; + LONGEST n = 0; int radix = 10; char overflow = 0; int nbits = 0; int c; - long upper_limit; + LONGEST upper_limit; if (*p == '-') { @@ -4510,9 +4510,9 @@ read_huge_number (pp, end, bits) } if (os9k_stabs) - upper_limit = ULONG_MAX / radix; + upper_limit = ULONGEST_MAX / radix; else - upper_limit = LONG_MAX / radix; + upper_limit = LONGEST_MAX / radix; while ((c = *p++) >= '0' && c < ('0' + radix)) { @@ -4593,7 +4593,7 @@ read_range_type (pp, typenums, objfile) { char *orig_pp = *pp; int rangenums[2]; - long n2, n3; + LONGEST n2, n3; int n2bits, n3bits; int self_subrange; struct type *result_type; @@ -4646,8 +4646,8 @@ read_range_type (pp, typenums, objfile) fit in a long but -1 does. */ else if ((n2bits != 0 && n3bits != 0 && n2bits == n3bits + 1) || (n2bits != 0 && n3bits == 0 - && (n2bits == sizeof (long) * HOST_CHAR_BIT) - && n3 == LONG_MAX)) + && (n2bits == sizeof (LONGEST) * HOST_CHAR_BIT) + && n3 == LONGEST_MAX)) { got_signed = 1; nbits = n2bits; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ea2809835a2..872aa7b9c31 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,25 @@ +1999-11-12 Stan Shebs + + * gdb.base/dollar.exp: Remove, now in gdb.hp. + +1999-11-10 Jimmy Guo + + * gdb.exp (get_compiler_info): pick up compiler.c and compiler.cc + from $srcdir/lib/. + * lib/compiler.c, lib/compiler.cc: New files, moved from gdb.base/ + and gdb.c++/. + + * gdb.c++/derivation.exp: remove redundant get compiler info code. + + * gdb.base/commands.exp: add '$gdb_prompt $' anchor to + 'continue with watch' test point. + +1999-11-08 Jim Blandy + + Merged from p2linux-990323-branch: + + * lib/gdb.exp (gdb_continue_to_breakpoint): New function. + Mon Nov 8 23:07:09 1999 Andrew Cagney * gdb.base/remote.exp: Test ``set remote memory-write-packet-sized diff --git a/gdb/testsuite/gdb.base/commands.exp b/gdb/testsuite/gdb.base/commands.exp index c9cea084d70..71491dbb3b0 100644 --- a/gdb/testsuite/gdb.base/commands.exp +++ b/gdb/testsuite/gdb.base/commands.exp @@ -320,7 +320,7 @@ proc watchpoint_command_test {} { } send_gdb "continue\n" gdb_expect { - -re "Continuing.*\[Ww\]atchpoint $wp_id deleted because the program has left the block in.*which its expression is valid.*run.c:57.*"\ + -re "Continuing.*\[Ww\]atchpoint $wp_id deleted because the program has left the block in.*which its expression is valid.*run.c:57.*$gdb_prompt $"\ {pass "continue with watch"} -re "$gdb_prompt $"\ {fail "continue with watch"} diff --git a/gdb/testsuite/gdb.c++/derivation.exp b/gdb/testsuite/gdb.c++/derivation.exp index 031985a496b..3a4a3076707 100644 --- a/gdb/testsuite/gdb.c++/derivation.exp +++ b/gdb/testsuite/gdb.c++/derivation.exp @@ -60,21 +60,6 @@ gdb_exit gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} -remote_file build delete ${binfile}.ci - if {![istarget "hppa*-*-hpux*"]} { - if { [gdb_compile "${srcdir}/${subdir}/compiler.cc" "${binfile}.ci" preprocess ""] != "" -} { - gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will auto -matically fail." - } - } else { - if { [gdb_preprocess "${srcdir}/${subdir}/compiler.cc" "${binfile}.ci" "c++"] != "" } { - perror "Couldn't make ${binfile}.ci file" - return 1; - } - } - -source ${binfile}.ci # # set it up at a breakpoint so we can play with the variable values diff --git a/gdb/testsuite/lib/compiler.c b/gdb/testsuite/lib/compiler.c new file mode 100644 index 00000000000..8eb0d47dd19 --- /dev/null +++ b/gdb/testsuite/lib/compiler.c @@ -0,0 +1,31 @@ +/* Often the behavior of any particular test depends upon what compiler was + used to compile the test. As each test is compiled, this file is + preprocessed by the same compiler used to compile that specific test + (different tests might be compiled by different compilers, particularly + if compiled at different times), and used to generate a *.ci (compiler + info) file for that test. + + I.E., when callfuncs is compiled, a callfuncs.ci file will be generated, + which can then be sourced by callfuncs.exp to give callfuncs.exp access + to information about the compilation environment. + + TODO: It might be a good idea to add expect code that tests each + definition made with 'set" to see if one already exists, and if so + warn about conflicts if it is being set to something else. */ + +/* This needs to be kept in sync with whatis.c and gdb.exp(get_compiler_info). + If this ends up being hairy, we could use a common header file. */ + +#if defined (__STDC__) || defined (_AIX) +set signed_keyword_not_used 0 +#else +set signed_keyword_not_used 1 +#endif + +#if defined (__GNUC__) +set gcc_compiled __GNUC__ +#else +set gcc_compiled 0 +#endif + +return 0 diff --git a/gdb/testsuite/lib/compiler.cc b/gdb/testsuite/lib/compiler.cc new file mode 100644 index 00000000000..aa35c7510ff --- /dev/null +++ b/gdb/testsuite/lib/compiler.cc @@ -0,0 +1,34 @@ +/* Often the behavior of any particular test depends upon what compiler was + used to compile the test. As each test is compiled, this file is + preprocessed by the same compiler used to compile that specific test + (different tests might be compiled by different compilers, particularly + if compiled at different times), and used to generate a *.ci (compiler + info) file for that test. + + I.E., when callfuncs is compiled, a callfuncs.ci file will be generated, + which can then be sourced by callfuncs.exp to give callfuncs.exp access + to information about the compilation environment. + + TODO: It might be a good idea to add expect code that tests each + definition made with 'set" to see if one already exists, and if so + warn about conflicts if it is being set to something else. */ + +#if defined(__GNUC__) && __GNUC__ >= 2 && __GNUC_MINOR__ >= 6 +set supports_template_debugging 1 +#else +set supports_template_debugging 0 +#endif + +#if defined(__cplusplus) +set supports_template_debugging 1 +#else +set supports_template_debugging 0 +#endif + +#if defined (__GNUC__) +set gcc_compiled __GNUC__ +#else +set gcc_compiled 0 +#endif + +return 0 diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 64ccaa9362b..a1a839a0baa 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -335,6 +335,31 @@ proc runto_main { } { } +### Continue, and expect to hit a breakpoint. +### Report a pass or fail, depending on whether it seems to have +### worked. Use NAME as part of the test name; each call to +### continue_to_breakpoint should use a NAME which is unique within +### that test file. +proc gdb_continue_to_breakpoint {name} { + global gdb_prompt + set full_name "continue to breakpoint: $name" + + send_gdb "continue\n" + gdb_expect { + -re "Breakpoint .* at .*\r\n$gdb_prompt $" { + pass $full_name + } + -re ".*$gdb_prompt $" { + fail $full_name + } + timeout { + fail "$full_name (timeout)" + } + } +} + + + # gdb_test COMMAND PATTERN MESSAGE -- send a command to gdb; test the result. # # COMMAND is the command to execute, send to GDB with send_gdb. If @@ -901,13 +926,13 @@ proc get_compiler_info {binfile args} { if {![istarget "hppa*-*-hpux*"]} { if { [llength $args] > 0 } { if {$args == "c++"} { - if { [gdb_compile "${srcdir}/${subdir}/compiler.cc" "${binfile}.ci" preprocess {}] != "" } { + if { [gdb_compile "${srcdir}/lib/compiler.cc" "${binfile}.ci" preprocess {}] != "" } { perror "Couldn't make ${binfile}.ci file" return 1; } } } else { - if { [gdb_compile "${srcdir}/${subdir}/compiler.c" "${binfile}.ci" preprocess {}] != "" } { + if { [gdb_compile "${srcdir}/lib/compiler.c" "${binfile}.ci" preprocess {}] != "" } { perror "Couldn't make ${binfile}.ci file" return 1; } @@ -916,7 +941,7 @@ proc get_compiler_info {binfile args} { if { [llength $args] > 0 } { if {$args == "c++"} { if { [eval gdb_preprocess \ - [list "${srcdir}/${subdir}/compiler.cc" "${binfile}.ci"] \ + [list "${srcdir}/lib/compiler.cc" "${binfile}.ci"] \ $args] != "" } { perror "Couldn't make ${binfile}.ci file" return 1; @@ -924,7 +949,7 @@ proc get_compiler_info {binfile args} { } } elseif { $args != "f77" } { if { [eval gdb_preprocess \ - [list "${srcdir}/${subdir}/compiler.c" "${binfile}.ci"] \ + [list "${srcdir}/lib/compiler.c" "${binfile}.ci"] \ $args] != "" } { perror "Couldn't make ${binfile}.ci file" return 1; diff --git a/gdb/utils.c b/gdb/utils.c index 339b26a31b0..9760cab4756 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -522,32 +522,39 @@ error_begin () The first argument STRING is the error message, used as a fprintf string, and the remaining args are passed as arguments to it. */ +NORETURN void +verror (const char *string, va_list args) +{ + /* FIXME: cagney/1999-11-10: All error calls should come here. + Unfortunatly some code uses the sequence: error_begin(); print + error message; return_to_top_level. That code should be + flushed. */ + error_begin (); + vfprintf_filtered (gdb_stderr, string, args); + fprintf_filtered (gdb_stderr, "\n"); + /* Save it as the last error as well (no newline) */ + gdb_file_rewind (gdb_lasterr); + vfprintf_filtered (gdb_lasterr, string, args); + va_end (args); + return_to_top_level (RETURN_ERROR); +} + NORETURN void error (const char *string,...) { va_list args; va_start (args, string); - if (error_hook) - (*error_hook) (); - else - { - error_begin (); - vfprintf_filtered (gdb_stderr, string, args); - fprintf_filtered (gdb_stderr, "\n"); - /* Save it as the last error as well (no newline) */ - gdb_file_rewind (gdb_lasterr); - vfprintf_filtered (gdb_lasterr, string, args); - va_end (args); - return_to_top_level (RETURN_ERROR); - } + verror (string, args); + va_end (args); } -/* Allows the error message to be passed on a stream buffer */ - NORETURN void error_stream (GDB_FILE *stream) { - error (tui_file_get_strbuf (stream)); + long size; + char *msg = gdb_file_xstrdup (stream, &size); + make_cleanup (free, msg); + error ("%s", msg); } /* Get the last error message issued by gdb */ @@ -555,26 +562,26 @@ error_stream (GDB_FILE *stream) char * error_last_message (void) { - return (tui_file_get_strbuf (gdb_lasterr)); + long len; + return gdb_file_xstrdup (gdb_lasterr, &len); } - + /* This is to be called by main() at the very beginning */ void error_init (void) { - gdb_lasterr = tui_sfileopen (132); + gdb_lasterr = mem_fileopen (); } /* Print a message reporting an internal error. Ask the user if they want to continue, dump core, or just exit. */ NORETURN void -internal_error (char *string, ...) +internal_verror (const char *fmt, va_list ap) { static char msg[] = "Internal GDB error: recursive internal error.\n"; static int dejavu = 0; - va_list args; int continue_p; int dump_core_p; @@ -596,9 +603,7 @@ internal_error (char *string, ...) /* Try to get the message out */ fputs_unfiltered ("gdb-internal-error: ", gdb_stderr); - va_start (args, string); - vfprintf_unfiltered (gdb_stderr, string, args); - va_end (args); + vfprintf_unfiltered (gdb_stderr, fmt, ap); fputs_unfiltered ("\n", gdb_stderr); /* Default (no case) is to quit GDB. When in batch mode this @@ -632,6 +637,15 @@ Create a core file containing the current state of GDB? "); return_to_top_level (RETURN_ERROR); } +NORETURN void +internal_error (char *string, ...) +{ + va_list ap; + va_start (ap, string); + internal_verror (string, ap); + va_end (ap); +} + /* The strerror() function can return NULL for errno values that are out of range. Provide a "safe" version that always returns a printable string. */ @@ -787,7 +801,7 @@ notice_quit () immediate_quit = 1; } -#else /* !defined(__GO32__) && !defined(_MSC_VER) */ +#else /* !defined(_MSC_VER) */ void notice_quit () @@ -795,7 +809,7 @@ notice_quit () /* Done by signals */ } -#endif /* !defined(__GO32__) && !defined(_MSC_VER) */ +#endif /* !defined(_MSC_VER) */ /* Control C comes here */ void @@ -1754,19 +1768,20 @@ stdio_fileopen (file) /* A pure memory based ``struct gdb_file'' that can be used an output - collector. It's input is available through gdb_file_put(). */ + buffer. The buffers accumulated contents are available via + gdb_file_put(). */ struct mem_file { int *magic; char *buffer; int sizeof_buffer; - int strlen_buffer; + int length_buffer; }; -extern gdb_file_fputs_ftype mem_file_fputs; static gdb_file_rewind_ftype mem_file_rewind; static gdb_file_put_ftype mem_file_put; +static gdb_file_write_ftype mem_file_write; static gdb_file_delete_ftype mem_file_delete; static struct gdb_file *mem_file_new PARAMS ((void)); static int mem_file_magic; @@ -1777,12 +1792,13 @@ mem_file_new (void) struct mem_file *stream = XMALLOC (struct mem_file); struct gdb_file *file = gdb_file_new (); set_gdb_file_data (file, stream, mem_file_delete); - set_gdb_file_fputs (file, mem_file_fputs); set_gdb_file_rewind (file, mem_file_rewind); set_gdb_file_put (file, mem_file_put); + set_gdb_file_write (file, mem_file_write); stream->magic = &mem_file_magic; stream->buffer = NULL; stream->sizeof_buffer = 0; + stream->length_buffer = 0; return file; } @@ -1809,52 +1825,49 @@ mem_file_rewind (struct gdb_file *file) struct mem_file *stream = gdb_file_data (file); if (stream->magic != &mem_file_magic) internal_error ("mem_file_rewind: bad magic number"); - if (stream->buffer != NULL) - { - stream->buffer[0] = '\0'; - stream->strlen_buffer = 0; - } + stream->length_buffer = 0; } static void -mem_file_put (struct gdb_file *file, struct gdb_file *dest) +mem_file_put (struct gdb_file *file, + gdb_file_put_method_ftype *write, + void *dest) { struct mem_file *stream = gdb_file_data (file); if (stream->magic != &mem_file_magic) internal_error ("mem_file_put: bad magic number"); - if (stream->buffer != NULL) - fputs_unfiltered (stream->buffer, dest); + if (stream->length_buffer > 0) + write (dest, stream->buffer, stream->length_buffer); } void -mem_file_fputs (const char *linebuffer, struct gdb_file *file) +mem_file_write (struct gdb_file *file, + const char *buffer, + long length_buffer) { struct mem_file *stream = gdb_file_data (file); if (stream->magic != &mem_file_magic) - internal_error ("mem_file_fputs: bad magic number"); + internal_error ("mem_file_write: bad magic number"); if (stream->buffer == NULL) { - stream->strlen_buffer = strlen (linebuffer); - stream->sizeof_buffer = stream->strlen_buffer + 1; + stream->length_buffer = length_buffer; + stream->sizeof_buffer = length_buffer; stream->buffer = xmalloc (stream->sizeof_buffer); - strcpy (stream->buffer, linebuffer); + memcpy (stream->buffer, buffer, length_buffer); } else { - int len = strlen (linebuffer); - int new_strlen = stream->strlen_buffer + len; - int new_sizeof = new_strlen + 1; - if (new_sizeof >= stream->sizeof_buffer) + int new_length = stream->length_buffer + length_buffer; + if (new_length >= stream->sizeof_buffer) { - stream->sizeof_buffer = new_sizeof; + stream->sizeof_buffer = new_length; stream->buffer = xrealloc (stream->buffer, stream->sizeof_buffer); } - strcpy (stream->buffer + stream->strlen_buffer, linebuffer); - stream->strlen_buffer = new_strlen; + memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer); + stream->length_buffer = new_length; } } - /* A ``struct gdb_file'' that is compatible with all the legacy code. */ @@ -1972,17 +1985,15 @@ tui_file_rewind (file) } static void -tui_file_put (file, dest) - struct gdb_file *file; - struct gdb_file *dest; +tui_file_put (struct gdb_file *file, + gdb_file_put_method_ftype *write, + void *dest) { struct tui_stream *stream = gdb_file_data (file); if (stream->ts_magic != &tui_file_magic) internal_error ("tui_file_put: bad magic number"); if (stream->ts_streamtype == astring) - { - fputs_unfiltered (stream->ts_strbuf, dest); - } + write (dest, stream->ts_strbuf, strlen (stream->ts_strbuf)); } /* All TUI I/O sent to the *_filtered and *_unfiltered functions @@ -2149,6 +2160,7 @@ static gdb_file_put_ftype null_file_put; struct gdb_file { + int *magic; gdb_file_flush_ftype *to_flush; gdb_file_write_ftype *to_write; gdb_file_fputs_ftype *to_fputs; @@ -2158,11 +2170,13 @@ struct gdb_file gdb_file_put_ftype *to_put; void *to_data; }; +int gdb_file_magic; struct gdb_file * gdb_file_new () { struct gdb_file *file = xmalloc (sizeof (struct gdb_file)); + file->magic = &gdb_file_magic; set_gdb_file_data (file, NULL, null_file_delete); set_gdb_file_flush (file, null_file_flush); set_gdb_file_write (file, null_file_write); @@ -2196,9 +2210,9 @@ null_file_rewind (file) } static void -null_file_put (file, src) - struct gdb_file *file; - struct gdb_file *src; +null_file_put (struct gdb_file *file, + gdb_file_put_method_ftype *write, + void *dest) { return; } @@ -2265,6 +2279,8 @@ void * gdb_file_data (file) struct gdb_file *file; { + if (file->magic != &gdb_file_magic) + internal_error ("gdb_file_data: bad magic number"); return file->to_data; } @@ -2290,11 +2306,11 @@ gdb_file_rewind (file) } void -gdb_file_put (file, dest) - struct gdb_file *file; - struct gdb_file *dest; +gdb_file_put (struct gdb_file *file, + gdb_file_put_method_ftype *write, + void *dest) { - file->to_put (file, dest); + file->to_put (file, write, dest); } void @@ -2370,6 +2386,43 @@ set_gdb_file_data (file, data, delete) file->to_delete = delete; } +/* gdb_file utility function for converting a ``struct gdb_file'' into + a memory buffer''. */ + +struct accumulated_gdb_file +{ + char *buffer; + long length; +}; + +static void +do_gdb_file_xstrdup (void *context, const char *buffer, long length) +{ + struct accumulated_gdb_file *acc = context; + if (acc->buffer == NULL) + acc->buffer = xmalloc (length + 1); + else + acc->buffer = xrealloc (acc->buffer, acc->length + length + 1); + memcpy (acc->buffer + acc->length, buffer, length); + acc->length += length; + acc->buffer[acc->length] = '\0'; +} + +char * +gdb_file_xstrdup (struct gdb_file *file, + long *length) +{ + struct accumulated_gdb_file acc; + acc.buffer = NULL; + acc.length = 0; + gdb_file_put (file, do_gdb_file_xstrdup, &acc); + if (acc.buffer == NULL) + acc.buffer = xstrdup (""); + *length = acc.length; + return acc.buffer; +} + + /* Like fputs but if FILTER is true, pause after every screenful. Regardless of FILTER can wrap at points other than the final diff --git a/sim/d10v/ChangeLog b/sim/d10v/ChangeLog index 0be82fa979e..449e256085f 100644 --- a/sim/d10v/ChangeLog +++ b/sim/d10v/ChangeLog @@ -1,7 +1,88 @@ +Fri Oct 29 18:34:28 1999 Andrew Cagney + + * simops.c (move_to_cr): Don't allow user to set PSW.DM in either + DPSW and BPSW. + +Thu Oct 28 01:26:18 1999 Andrew Cagney + + * simops.c (OP_5F20): Use SET_HW_PSW when updating PSW. + (PSW_HW_MASK): Declare. + + * d10v_sim.h (move_to_cr): Add ``psw_hw_p'' parameter. + (SET_CREG, SET_PSW_BIT): Update. + (SET_HW_CREG, SET_HW_PSW): Define. + +Sun Oct 24 21:38:04 1999 Andrew Cagney + + * interp.c (sim_d10v_translate_dmap_addr): Fix extraction of IOSP + for DMAP3. + +Sun Oct 24 16:04:16 1999 Andrew Cagney + + * interp.c (sim_d10v_translate_addr): New function. + (xfer_mem): Rewrite. Use sim_d10v_translate_addr. + (map_memory): Make INLINE. + +Sun Oct 24 13:45:19 1999 Andrew Cagney + + * interp.c (sim_d10v_translate_dmap_addr): New function. + (dmem_addr): Rewrite. Use sim_d10v_translate_dmap_addr. Change + offset parameter to type uint16. + * d10v_sim.h (dmem_addr): Update declaration. + +Sun Oct 24 13:07:31 1999 Andrew Cagney + + * interp.c (imap_register, set_imap_register, dmap_register, + set_imap_register): Use map_memory. + (DMAP): Update. + (sim_create_inferior): Initialize all DMAP registers. NOTE that + DMAP2, in internal memory mode, is set to 0x0000 and NOT + 0x2000. This is consistent with the older d10v boards. + +Sun Oct 24 11:22:12 1999 Andrew Cagney + + * interp.c (sim_d10v_translate_imap_addr): New function. + (imem_addr): Rewrite. Use sim_d10v_translate_imap_addr. + (last_from, last_to): Declare. + +Sun Oct 24 01:21:56 1999 Andrew Cagney + + * d10v_sim.h (struct d10v_memory): Define. Support very long + memories. + (struct _state): Replace imem, dmem and umem by mem. + (IMAP_BLOCK_SIZE, DMAP_BLOCK_SIZE, SEGMENT_SIZE, IMEM_SEGMENTS, + DMEM_SEGMENTS, UMEM_SEGMENTS): Define. + + * interp.c (map_memory): New function. + (sim_size, xfer_memory, imem_addr, dmem_addr): Update. + (UMEM_SEGMENTS): Moveed to "d10v_sim.h". + (IMEM_SIZEDMEM_SIZE): Delete. + +Sat Oct 23 20:06:58 1999 Andrew Cagney + + * interp.c: Include "sim-d10v.h". + (imap_register, set_imap_register, dmap_register, + set_dmap_register, spi_register, spu_register, set_spi_register, + set_spu_register): New functions. + (sim_create_inferior): Update. + (sim_fetch_register, sim_store_register): Rewrite. Use enums + defined in sim-d10v.h. + + * d10v_sim.h (DEBUG_MEMORY): Define. + (IMAP0, IMAP1, DMAP, SET_IMAP0, SET_IMAP1, SET_DMAP): Delete. + +Sat Oct 23 18:41:18 1999 Andrew Cagney + + * interp.c (sim_open): Allow a debug value to be passed to the -t + option. + (lookup_hash): Don't exit on an illegal instruction. + (do_long, do_2_short, do_parallel): Check for failed instruction + lookup. + Mon Oct 18 18:03:24 MDT 1999 Diego Novillo * simops.c (OP_3220): Fix trace output for illegal accumulator - message. + message. 1999-09-14 Nick Clifton diff --git a/sim/d10v/d10v_sim.h b/sim/d10v/d10v_sim.h index ca7e02ec9c5..130aed95c1a 100644 --- a/sim/d10v/d10v_sim.h +++ b/sim/d10v/d10v_sim.h @@ -13,6 +13,7 @@ #define DEBUG_MEMSIZE 0x00000008 #define DEBUG_INSTRUCTION 0x00000010 #define DEBUG_TRAP 0x00000020 +#define DEBUG_MEMORY 0x00000040 #ifndef DEBUG #define DEBUG (DEBUG_TRACE | DEBUG_VALUES | DEBUG_LINE_NUMBER) @@ -197,6 +198,37 @@ enum { } \ while (0) +/* d10v memory: There are three separate d10v memory regions IMEM, + UMEM and DMEM. The IMEM and DMEM are further broken down into + blocks (very like VM pages). */ + +enum +{ + IMAP_BLOCK_SIZE = 0x20000, + DMAP_BLOCK_SIZE = 0x4000, +}; + +/* Implement the three memory regions using sparse arrays. Allocate + memory using ``segments''. A segment must be at least as large as + a BLOCK - ensures that an access that doesn't cross a block + boundary can't cross a segment boundary */ + +enum +{ + SEGMENT_SIZE = 0x20000, /* 128KB - MAX(IMAP_BLOCK_SIZE,DMAP_BLOCK_SIZE) */ + IMEM_SEGMENTS = 8, /* 1MB */ + DMEM_SEGMENTS = 8, /* 1MB */ + UMEM_SEGMENTS = 128 /* 16MB */ +}; + +struct d10v_memory +{ + uint8 *insn[IMEM_SEGMENTS]; + uint8 *data[DMEM_SEGMENTS]; + uint8 *unif[UMEM_SEGMENTS]; + uint8 fault[16]; +}; + struct _state { reg_t regs[16]; /* general-purpose registers */ @@ -209,7 +241,8 @@ struct _state reg_t cregs[16]; /* control registers */ #define CREG(N) (State.cregs[(N)] + 0) -#define SET_CREG(N,VAL) move_to_cr ((N), 0, (VAL)) +#define SET_CREG(N,VAL) move_to_cr ((N), 0, (VAL), 0) +#define SET_HW_CREG(N,VAL) move_to_cr ((N), 0, (VAL), 1) reg_t sp[2]; /* holding area for SPI(0)/SPU(1) */ #define HELD_SP(N) (State.sp[(N)] + 0) @@ -232,10 +265,11 @@ struct _state int exception; int pc_changed; - /* NOTE: everything below this line is not reset by sim_create_inferior() */ - uint8 *imem; - uint8 *dmem; - uint8 *umem[128]; + /* NOTE: everything below this line is not reset by + sim_create_inferior() */ + + struct d10v_memory mem; + enum _ins_type ins_type; } State; @@ -283,7 +317,8 @@ enum #define PSW CREG (PSW_CR) #define SET_PSW(VAL) SET_CREG (PSW_CR, (VAL)) -#define SET_PSW_BIT(MASK,VAL) move_to_cr (PSW_CR, ~(MASK), (VAL) ? (MASK) : 0) +#define SET_HW_PSW(VAL) SET_HW_CREG (PSW_CR, (VAL)) +#define SET_PSW_BIT(MASK,VAL) move_to_cr (PSW_CR, ~(MASK), (VAL) ? (MASK) : 0, 1) #define PSW_SM ((PSW & PSW_SM_BIT) != 0) #define SET_PSW_SM(VAL) SET_PSW_BIT (PSW_SM_BIT, (VAL)) @@ -404,7 +439,7 @@ do \ } \ while (0) -extern uint8 *dmem_addr PARAMS ((uint32)); +extern uint8 *dmem_addr (uint16 offset); extern uint8 *imem_addr PARAMS ((uint32)); extern bfd_vma decode_pc PARAMS ((void)); @@ -434,13 +469,6 @@ extern void write_longlong PARAMS ((uint8 *addr, int64 data)); #define READ_64(x) get_longlong(x) #define WRITE_64(addr,data) write_longlong(addr,data) -#define IMAP0 RW(0xff00) -#define IMAP1 RW(0xff02) -#define DMAP RW(0xff04) -#define SET_IMAP0(x) SW(0xff00,x) -#define SET_IMAP1(x) SW(0xff02,x) -#define SET_DMAP(x) SW(0xff04,x) - #define JMP(x) do { SET_PC (x); State.pc_changed = 1; } while (0) #define RIE_VECTOR_START 0xffc2 @@ -449,4 +477,9 @@ extern void write_longlong PARAMS ((uint8 *addr, int64 data)); #define DBT_VECTOR_START 0xffd4 #define SDBT_VECTOR_START 0xffd5 -extern reg_t move_to_cr PARAMS ((int cr, reg_t mask, reg_t val)); +/* Scedule a store of VAL into cr[CR]. MASK indicates the bits in + cr[CR] that should not be modified (i.e. cr[CR] = (cr[CR] & MASK) | + (VAL & ~MASK)). In addition, unless PSW_HW_P, a VAL intended for + PSW is masked for zero bits. */ + +extern reg_t move_to_cr (int cr, reg_t mask, reg_t val, int psw_hw_p); diff --git a/sim/d10v/interp.c b/sim/d10v/interp.c index bd1639147fe..2a9ae043c66 100644 --- a/sim/d10v/interp.c +++ b/sim/d10v/interp.c @@ -5,11 +5,7 @@ #include "remote-sim.h" #include "d10v_sim.h" - -#define IMEM_SIZE 18 /* D10V instruction memory size is 18 bits */ -#define DMEM_SIZE 16 /* Data memory is 64K (but only 32K internal RAM) */ -#define UMEM_SIZE 17 /* Each unified memory segment is 17 bits */ -#define UMEM_SEGMENTS 128 /* Number of segments in unified memory region */ +#include "sim-d10v.h" enum _leftright { LEFT_FIRST, RIGHT_FIRST }; @@ -43,6 +39,7 @@ static void do_parallel PARAMS ((uint16 ins1, uint16 ins2)); static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value)); extern void sim_set_profile PARAMS ((int n)); extern void sim_set_profile_size PARAMS ((int n)); +static INLINE uint8 *map_memory (unsigned phys_addr); #ifdef NEED_UI_LOOP_HOOK /* How often to run the ui_loop update, when in use */ @@ -102,8 +99,10 @@ lookup_hash (ins, size) { if (h->next == NULL) { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR looking up hash for %x at PC %x\n",ins, PC); - exit (1); + (*d10v_callback->printf_filtered) + (d10v_callback, "ERROR: Illegal instruction %x at PC %x\n", ins, PC); + State.exception = SIGILL; + return NULL; } h = h->next; } @@ -158,6 +157,8 @@ do_long (ins) (*d10v_callback->printf_filtered) (d10v_callback, "do_long 0x%x\n", ins); #endif h = lookup_hash (ins, 1); + if (h == NULL) + return; get_operands (h->ops, ins); State.ins_type = INS_LONG; ins_type_counters[ (int)State.ins_type ]++; @@ -193,6 +194,8 @@ do_2_short (ins1, ins2, leftright) /* Issue the first instruction */ h = lookup_hash (ins1, 0); + if (h == NULL) + return; get_operands (h->ops, ins1); State.ins_type = first; ins_type_counters[ (int)State.ins_type ]++; @@ -204,6 +207,8 @@ do_2_short (ins1, ins2, leftright) /* finish any existing instructions */ SLOT_FLUSH (); h = lookup_hash (ins2, 0); + if (h == NULL) + return; get_operands (h->ops, ins2); State.ins_type = second; ins_type_counters[ (int)State.ins_type ]++; @@ -225,7 +230,11 @@ do_parallel (ins1, ins2) #endif ins_type_counters[ (int)INS_PARALLEL ]++; h1 = lookup_hash (ins1, 0); + if (h1 == NULL) + return; h2 = lookup_hash (ins2, 0); + if (h2 == NULL) + return; if (h1->ops->exec_type == PARONLY) { @@ -306,252 +315,446 @@ sim_size (power) { int i; - - if (State.imem) + for (i = 0; i < IMEM_SEGMENTS; i++) { - for (i=0;iprintf_filtered) (d10v_callback, "Memory allocation failed.\n"); - exit(1); + if (State.mem.data[i]) + free (State.mem.data[i]); } - + for (i = 0; i < UMEM_SEGMENTS; i++) + { + if (State.mem.unif[i]) + free (State.mem.unif[i]); + } + /* Always allocate dmem segment 0. This contains the IMAP and DMAP + registers. */ + State.mem.data[0] = calloc (1, SEGMENT_SIZE); +} + +/* For tracing - leave info on last access around. */ +static char *last_segname = "invalid"; +static char *last_from = "invalid"; +static char *last_to = "invalid"; + +enum + { + IMAP0_OFFSET = 0xff00, + DMAP0_OFFSET = 0xff08, + DMAP2_SHADDOW = 0xff04, + DMAP2_OFFSET = 0xff0c + }; + +static void +set_dmap_register (int reg_nr, unsigned long value) +{ + uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA + + DMAP0_OFFSET + 2 * reg_nr); + WRITE_16 (raw, value); #ifdef DEBUG - if ((d10v_debug & DEBUG_MEMSIZE) != 0) + if ((d10v_debug & DEBUG_MEMORY)) { - char buffer[20]; - (*d10v_callback->printf_filtered) (d10v_callback, - "Allocated %s bytes instruction memory and\n", - add_commas (buffer, sizeof (buffer), (1UL<printf_filtered) + (d10v_callback, "mem: dmap%d=0x%04lx\n", reg_nr, value); + } +#endif +} - (*d10v_callback->printf_filtered) (d10v_callback, " %s bytes data memory.\n", - add_commas (buffer, sizeof (buffer), (1UL<printf_filtered) + (d10v_callback, "mem: imap%d=0x%04lx\n", reg_nr, value); } #endif } -/* Transfer data to/from simulated memory. Since a bug in either the - simulated program or in gdb or the simulator itself may cause a - bogus address to be passed in, we need to do some sanity checking - on addresses to make sure they are within bounds. When an address - fails the bounds check, treat it as a zero length read/write rather - than aborting the entire run. */ +static unsigned long +imap_register (int reg_nr) +{ + uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA + + IMAP0_OFFSET + 2 * reg_nr); + return READ_16 (raw); +} -static int -xfer_mem (SIM_ADDR addr, - unsigned char *buffer, - int size, - int write_p) +enum + { + HELD_SPI_IDX = 0, + HELD_SPU_IDX = 1 + }; + +static unsigned long +spu_register (void) { - unsigned char *memory; - int segment = ((addr >> 24) & 0xff); - addr = (addr & 0x00ffffff); + if (PSW_SM) + return GPR (SP_IDX); + else + return HELD_SP (HELD_SPU_IDX); +} -#ifdef DEBUG - if ((d10v_debug & DEBUG_INSTRUCTION) != 0) +static unsigned long +spi_register (void) +{ + if (!PSW_SM) + return GPR (SP_IDX); + else + return HELD_SP (HELD_SPI_IDX); +} + +static void +set_spi_register (unsigned long value) +{ + if (!PSW_SM) + SET_GPR (SP_IDX, value); + SET_HELD_SP (HELD_SPI_IDX, value); +} + +static void +set_spu_register (unsigned long value) +{ + if (PSW_SM) + SET_GPR (SP_IDX, value); + SET_HELD_SP (HELD_SPU_IDX, value); +} + +/* Given a virtual address in the DMAP address space, translate it + into a physical address. */ + +unsigned long +sim_d10v_translate_dmap_addr (unsigned long offset, + int nr_bytes, + unsigned long *phys, + unsigned long (*dmap_register) (int reg_nr)) +{ + short map; + int regno; + last_from = "logical-data"; + if (offset >= DMAP_BLOCK_SIZE * SIM_D10V_NR_DMAP_REGS) { - if (write_p) - { - (*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%02x:%06x\n", size, segment, addr); - } - else + /* Logical address out side of data segments, not supported */ + return 0; + } + regno = (offset / DMAP_BLOCK_SIZE); + offset = (offset % DMAP_BLOCK_SIZE); + if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE) + { + /* Don't cross a BLOCK boundary */ + nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE); + } + map = dmap_register (regno); + if (regno == 3) + { + /* Always maps to data memory */ + int iospi = (offset / 0x1000) % 4; + int iosp = (map >> (4 * (3 - iospi))) % 0x10; + last_to = "io-space"; + *phys = (SIM_D10V_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset); + } + else + { + int sp = ((map & 0x3000) >> 12); + int segno = (map & 0x3ff); + switch (sp) { - (*d10v_callback->printf_filtered) (d10v_callback, "sim_read %d bytes from 0x%2x:%6x\n", size, segment, addr); + case 0: /* 00: Unified memory */ + *phys = SIM_D10V_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset; + last_to = "unified"; + break; + case 1: /* 01: Instruction Memory */ + *phys = SIM_D10V_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset; + last_to = "chip-insn"; + break; + case 2: /* 10: Internal data memory */ + *phys = SIM_D10V_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset; + last_to = "chip-data"; + break; + case 3: /* 11: Reserved */ + return 0; } } -#endif + return nr_bytes; +} - /* To access data, we use the following mappings: +/* Given a virtual address in the IMAP address space, translate it + into a physical address. */ - 0x00xxxxxx: Physical unified memory segment (Unified memory) - 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory) - 0x02xxxxxx: Physical data memory segment (On-chip data memory) - 0x10xxxxxx: Logical data address segment (DMAP translated memory) - 0x11xxxxxx: Logical instruction address segment (IMAP translated memory) +unsigned long +sim_d10v_translate_imap_addr (unsigned long offset, + int nr_bytes, + unsigned long *phys, + unsigned long (*imap_register) (int reg_nr)) +{ + short map; + int regno; + int sp; + int segno; + last_from = "logical-insn"; + if (offset >= (IMAP_BLOCK_SIZE * SIM_D10V_NR_IMAP_REGS)) + { + /* Logical address outside of IMAP segments, not supported */ + return 0; + } + regno = (offset / IMAP_BLOCK_SIZE); + offset = (offset % IMAP_BLOCK_SIZE); + if (offset + nr_bytes > IMAP_BLOCK_SIZE) + { + /* Don't cross a BLOCK boundary */ + nr_bytes = IMAP_BLOCK_SIZE - offset; + } + map = imap_register (regno); + sp = (map & 0x3000) >> 12; + segno = (map & 0x007f); + switch (sp) + { + case 0: /* 00: unified memory */ + *phys = SIM_D10V_MEMORY_UNIFIED + (segno << 17) + offset; + last_to = "unified"; + break; + case 1: /* 01: instruction memory */ + *phys = SIM_D10V_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset; + last_to = "chip-insn"; + break; + case 2: /*10*/ + /* Reserved. */ + return 0; + case 3: /* 11: for testing - instruction memory */ + offset = (offset % 0x800); + *phys = SIM_D10V_MEMORY_INSN + offset; + if (offset + nr_bytes > 0x800) + /* don't cross VM boundary */ + nr_bytes = 0x800 - offset; + last_to = "test-insn"; + break; + } + return nr_bytes; +} - Alternatively, the "old segment mapping" is still available by setting - old_segment_mapping to 1. It looks like this: +unsigned long +sim_d10v_translate_addr (unsigned long memaddr, + int nr_bytes, + unsigned long *targ_addr, + unsigned long (*dmap_register) (int reg_nr), + unsigned long (*imap_register) (int reg_nr)) +{ + unsigned long phys; + unsigned long seg; + unsigned long off; - 0x00xxxxxx: Logical data address segment (DMAP translated memory) - 0x01xxxxxx: Logical instruction address segment (IMAP translated memory) - 0x10xxxxxx: Physical data memory segment (On-chip data memory) - 0x11xxxxxx: Physical instruction memory segment (On-chip insn memory) - 0x12xxxxxx: Physical unified memory segment (Unified memory) + last_from = "unknown"; + last_to = "unknown"; - */ + seg = (memaddr >> 24); + off = (memaddr & 0xffffffL); /* However, if we've asked to use the previous generation of segment mapping, rearrange the segments as follows. */ if (old_segment_mapping) { - switch (segment) + switch (seg) { case 0x00: /* DMAP translated memory */ - segment = 0x10; + seg = 0x10; break; case 0x01: /* IMAP translated memory */ - segment = 0x11; + seg = 0x11; break; case 0x10: /* On-chip data memory */ - segment = 0x02; + seg = 0x02; break; case 0x11: /* On-chip insn memory */ - segment = 0x01; + seg = 0x01; break; case 0x12: /* Unified memory */ - segment = 0x00; + seg = 0x00; break; } } - switch (segment) + switch (seg) { - case 0x10: /* DMAP translated memory */ - { - int byte; - for (byte = 0; byte < size; byte++) - { - uint8 *mem = dmem_addr (addr + byte); - if (mem == NULL) - return byte; - else if (write_p) - *mem = buffer[byte]; - else - buffer[byte] = *mem; - } - return byte; - } + case 0x00: /* Physical unified memory */ + last_from = "phys-unified"; + last_to = "unified"; + phys = SIM_D10V_MEMORY_UNIFIED + off; + if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) + nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); + break; - case 0x11: /* IMAP translated memory */ - { - int byte; - for (byte = 0; byte < size; byte++) - { - uint8 *mem = imem_addr (addr + byte); - if (mem == NULL) - return byte; - else if (write_p) - *mem = buffer[byte]; - else - buffer[byte] = *mem; - } - return byte; - } + case 0x01: /* Physical instruction memory */ + last_from = "phys-insn"; + last_to = "chip-insn"; + phys = SIM_D10V_MEMORY_INSN + off; + if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) + nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); + break; - case 0x02: /* On-chip data memory */ + case 0x02: /* Physical data memory segment */ + last_from = "phys-data"; + last_to = "chip-data"; + phys = SIM_D10V_MEMORY_DATA + off; + if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) + nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); + break; + + case 0x10: /* in logical data address segment */ + nr_bytes = sim_d10v_translate_dmap_addr (off, nr_bytes, &phys, + dmap_register); + break; + + case 0x11: /* in logical instruction address segment */ + nr_bytes = sim_d10v_translate_imap_addr (off, nr_bytes, &phys, + imap_register); + break; + + default: + return 0; + } + + *targ_addr = phys; + return nr_bytes; +} + +/* Return a pointer into the raw buffer designated by phys_addr. It + is assumed that the client has already ensured that the access + isn't going to cross a segment boundary. */ + +uint8 * +map_memory (unsigned phys_addr) +{ + uint8 **memory; + uint8 *raw; + unsigned offset; + int segment = ((phys_addr >> 24) & 0xff); + + switch (segment) + { + + case 0x00: /* Unified memory */ { - addr &= ((1 << DMEM_SIZE) - 1); - if ((addr + size) > (1 << DMEM_SIZE)) - { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: data address 0x%x is outside range 0-0x%x.\n", - addr + size - 1, (1 << DMEM_SIZE) - 1); - return (0); - } - memory = State.dmem + addr; + memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS]; + last_segname = "umem"; break; } - + case 0x01: /* On-chip insn memory */ { - addr &= ((1 << IMEM_SIZE) - 1); - if ((addr + size) > (1 << IMEM_SIZE)) - { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: instruction address 0x%x is outside range 0-0x%x.\n", - addr + size - 1, (1 << IMEM_SIZE) - 1); - return (0); - } - memory = State.imem + addr; + memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS]; + last_segname = "imem"; break; } - - case 0x00: /* Unified memory */ + + case 0x02: /* On-chip data memory */ { - int startsegment, startoffset; /* Segment and offset within segment where xfer starts */ - int endsegment, endoffset; /* Segment and offset within segment where xfer ends */ - - startsegment = addr >> UMEM_SIZE; - startoffset = addr & ((1 << UMEM_SIZE) - 1); - endsegment = (addr + size) >> UMEM_SIZE; - endoffset = (addr + size) & ((1 << UMEM_SIZE) - 1); - - /* FIXME: We do not currently implement xfers across segments, - so detect this case and fail gracefully. */ - - if ((startsegment != endsegment) && !((endsegment == (startsegment + 1)) && endoffset == 0)) - { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: Unimplemented support for transfers across unified memory segment boundaries\n"); - return (0); - } - if (!State.umem[startsegment]) + if ((phys_addr & 0xff00) == 0xff00) { -#ifdef DEBUG - if ((d10v_debug & DEBUG_MEMSIZE) != 0) + phys_addr = (phys_addr & 0xffff); + if (phys_addr == DMAP2_SHADDOW) { - (*d10v_callback->printf_filtered) (d10v_callback,"Allocating %s bytes unified memory to region %d\n", - add_commas (buffer, sizeof (buffer), (1UL<printf_filtered) (d10v_callback, "ERROR: Memory allocation of 0x%x bytes failed.\n", 1<printf_filtered) (d10v_callback, "ERROR: address 0x%lx is not in valid range\n", (long) addr); - if (old_segment_mapping) - { - (*d10v_callback->printf_filtered) (d10v_callback, "0x00xxxxxx: Logical data address segment (DMAP translated memory)\n"); - (*d10v_callback->printf_filtered) (d10v_callback, "0x01xxxxxx: Logical instruction address segment (IMAP translated memory)\n"); - (*d10v_callback->printf_filtered) (d10v_callback, "0x10xxxxxx: Physical data memory segment (On-chip data memory)\n"); - (*d10v_callback->printf_filtered) (d10v_callback, "0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)\n"); - (*d10v_callback->printf_filtered) (d10v_callback, "0x12xxxxxx: Phisical unified memory segment (Unified memory)\n"); - } - else - { - (*d10v_callback->printf_filtered) (d10v_callback, "0x00xxxxxx: Physical unified memory segment (Unified memory)\n"); - (*d10v_callback->printf_filtered) (d10v_callback, "0x01xxxxxx: Physical instruction memory segment (On-chip insn memory)\n"); - (*d10v_callback->printf_filtered) (d10v_callback, "0x02xxxxxx: Physical data memory segment (On-chip data memory)\n"); - (*d10v_callback->printf_filtered) (d10v_callback, "0x10xxxxxx: Logical data address segment (DMAP translated memory)\n"); - (*d10v_callback->printf_filtered) (d10v_callback, "0x11xxxxxx: Logical instruction address segment (IMAP translated memory)\n"); - } - return (0); - } + /* OOPS! */ + last_segname = "scrap"; + return State.mem.fault; } - - if (write_p) + + if (*memory == NULL) { - memcpy (memory, buffer, size); + *memory = calloc (1, SEGMENT_SIZE); + if (*memory == NULL) + { + (*d10v_callback->printf_filtered) (d10v_callback, "Malloc failed.\n"); + return State.mem.fault; + } } - else + + offset = (phys_addr % SEGMENT_SIZE); + raw = *memory + offset; + return raw; +} + +/* Transfer data to/from simulated memory. Since a bug in either the + simulated program or in gdb or the simulator itself may cause a + bogus address to be passed in, we need to do some sanity checking + on addresses to make sure they are within bounds. When an address + fails the bounds check, treat it as a zero length read/write rather + than aborting the entire run. */ + +static int +xfer_mem (SIM_ADDR virt, + unsigned char *buffer, + int size, + int write_p) +{ + int xfered = 0; + + while (xfered < size) { - memcpy (buffer, memory, size); + uint8 *memory; + unsigned long phys; + int phys_size; + phys_size = sim_d10v_translate_addr (virt, size, + &phys, + dmap_register, + imap_register); + if (phys_size == 0) + return xfered; + + memory = map_memory (phys); + +#ifdef DEBUG + if ((d10v_debug & DEBUG_INSTRUCTION) != 0) + { + (*d10v_callback->printf_filtered) + (d10v_callback, + "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n", + (write_p ? "write" : "read"), + phys_size, virt, last_from, + phys, last_to, + (long) memory, last_segname); + } +#endif + + if (write_p) + { + memcpy (memory, buffer, phys_size); + } + else + { + memcpy (buffer, memory, phys_size); + } + + virt += phys_size; + buffer += phys_size; + xfered += phys_size; } return size; @@ -598,6 +801,9 @@ sim_open (kind, callback, abfd, argv) myname = argv[0]; old_segment_mapping = 0; + /* NOTE: This argument parsing is only effective when this function + is called by GDB. Standalone argument parsing is handled by + sim/common/run.c. */ for (p = argv + 1; *p; ++p) { if (strcmp (*p, "-oldseg") == 0) @@ -605,6 +811,8 @@ sim_open (kind, callback, abfd, argv) #ifdef DEBUG else if (strcmp (*p, "-t") == 0) d10v_debug = DEBUG; + else if (strncmp (*p, "-t", 2) == 0) + d10v_debug = atoi (*p + 2); #endif else (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p); @@ -637,8 +845,8 @@ sim_open (kind, callback, abfd, argv) } /* reset the processor state */ - if (!State.imem) - sim_size(1); + if (!State.mem.data[0]) + sim_size (1); sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL); /* Fudge our descriptor. */ @@ -673,84 +881,64 @@ sim_set_profile_size (n) (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n); } - uint8 * -dmem_addr( addr ) - uint32 addr; +dmem_addr (uint16 offset) { - int seg; + unsigned long phys; + uint8 *mem; + int phys_size; - addr &= 0xffff; + /* Note: DMEM address range is 0..0x10000. Calling code can compute + things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type + is uint16 this is modulo'ed onto 0x0e5d. */ - if (addr > 0xbfff) + phys_size = sim_d10v_translate_dmap_addr (offset, 1, &phys, + dmap_register); + if (phys_size == 0) { - if ( (addr & 0xfff0) != 0xff00) - { - (*d10v_callback->printf_filtered) (d10v_callback, "Data address 0x%lx is in I/O space, pc = 0x%lx.\n", - (long)addr, (long)decode_pc ()); - State.exception = SIGBUS; - } - - return State.dmem + addr; + mem = State.mem.fault; } - - if (addr > 0x7fff) - { - if (DMAP & 0x1000) - { - /* instruction memory */ - return (DMAP & 0xf) * 0x4000 + State.imem + (addr - 0x8000); - } - else - { - /* unified memory */ - /* this is ugly because we allocate unified memory in 128K segments and */ - /* dmap addresses 16k segments */ - seg = (DMAP & 0x3ff) >> 3; - if (State.umem[seg] == NULL) - { + else + mem = map_memory (phys); #ifdef DEBUG - (*d10v_callback->printf_filtered) (d10v_callback,"Allocating %d bytes unified memory to region %d\n", 1<printf_filtered) (d10v_callback, - "ERROR: alloc failed. unified memory region %d unmapped, pc = 0x%lx\n", - seg, (long)decode_pc ()); - State.exception = SIGBUS; - } - } - return State.umem[seg] + (DMAP & 7) * 0x4000 + (addr - 0x8000); - } + if ((d10v_debug & DEBUG_MEMORY)) + { + (*d10v_callback->printf_filtered) + (d10v_callback, + "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n", + offset, last_from, + phys, phys_size, last_to, + (long) mem, last_segname); } - return State.dmem + addr; +#endif + return mem; } - uint8 * -imem_addr (uint32 pc) +imem_addr (uint32 offset) { - uint16 imap; - - if (pc & 0x20000) - imap = IMAP1; - else - imap = IMAP0; - - if (imap & 0x1000) - return State.imem + pc; - - if (State.umem[imap & 0xff] == NULL) - return 0; - - /* Discard upper bit(s) of PC in case IMAP1 selects unified memory. */ - pc &= (1 << UMEM_SIZE) - 1; - - return State.umem[imap & 0xff] + pc; + unsigned long phys; + uint8 *mem; + int phys_size = sim_d10v_translate_imap_addr (offset, 1, &phys, imap_register); + if (phys_size == 0) + { + return State.mem.fault; + } + mem = map_memory (phys); +#ifdef DEBUG + if ((d10v_debug & DEBUG_MEMORY)) + { + (*d10v_callback->printf_filtered) + (d10v_callback, + "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n", + offset, last_from, + phys, phys_size, last_to, + (long) mem, last_segname); + } +#endif + return mem; } - static int stop_simulator = 0; int @@ -779,7 +967,7 @@ sim_resume (sd, step, siggnal) do { iaddr = imem_addr ((uint32)PC << 2); - if (iaddr == NULL) + if (iaddr == State.mem.fault) { State.exception = SIGBUS; break; @@ -990,7 +1178,7 @@ sim_create_inferior (sd, abfd, argv, env) bfd_vma start_address; /* reset all state information */ - memset (&State.regs, 0, (int)&State.imem - (int)&State.regs[0]); + memset (&State.regs, 0, (int)&State.mem - (int)&State.regs); if (argv) { @@ -1022,19 +1210,28 @@ sim_create_inferior (sd, abfd, argv, env) #endif SET_CREG (PC_CR, start_address >> 2); - /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board */ - /* resets imap0 and imap1 to 0x1000. */ + /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board + initializes imap0 and imap1 to 0x1000 as part of its ROM + initialization. */ if (old_segment_mapping) { - SET_IMAP0 (0x0000); - SET_IMAP1 (0x007f); - SET_DMAP (0x0000); + /* External memory startup. This is the HARD reset state. */ + set_imap_register (0, 0x0000); + set_imap_register (1, 0x007f); + set_dmap_register (0, 0x2000); + set_dmap_register (1, 0x2000); + set_dmap_register (2, 0x0000); /* Old DMAP */ + set_dmap_register (3, 0x0000); } else { - SET_IMAP0 (0x1000); - SET_IMAP1 (0x1000); - SET_DMAP(0); + /* Internal memory startup. This is the ROM intialized state. */ + set_imap_register (0, 0x1000); + set_imap_register (1, 0x1000); + set_dmap_register (0, 0x2000); + set_dmap_register (1, 0x2000); + set_dmap_register (2, 0x0000); /* Old DMAP, Value is not 0x2000 */ + set_dmap_register (3, 0x0000); } SLOT_FLUSH (); @@ -1088,19 +1285,56 @@ sim_fetch_register (sd, rn, memory, length) unsigned char *memory; int length; { - if (rn > 34) - WRITE_64 (memory, ACC (rn-35)); - else if (rn == 32) - WRITE_16 (memory, IMAP0); - else if (rn == 33) - WRITE_16 (memory, IMAP1); - else if (rn == 34) - WRITE_16 (memory, DMAP); - else if (rn >= 16) - WRITE_16 (memory, CREG (rn - 16)); + int size; + if (rn < 0) + size = 0; + else if (rn >= SIM_D10V_R0_REGNUM + && rn < SIM_D10V_R0_REGNUM + SIM_D10V_NR_R_REGS) + { + WRITE_16 (memory, GPR (rn - SIM_D10V_R0_REGNUM)); + size = 2; + } + else if (rn >= SIM_D10V_CR0_REGNUM + && rn < SIM_D10V_CR0_REGNUM + SIM_D10V_NR_CR_REGS) + { + WRITE_16 (memory, CREG (rn - SIM_D10V_CR0_REGNUM)); + size = 2; + } + else if (rn >= SIM_D10V_A0_REGNUM + && rn < SIM_D10V_A0_REGNUM + SIM_D10V_NR_A_REGS) + { + WRITE_64 (memory, ACC (rn - SIM_D10V_A0_REGNUM)); + size = 8; + } + else if (rn == SIM_D10V_SPI_REGNUM) + { + /* PSW_SM indicates that the current SP is the USER + stack-pointer. */ + WRITE_16 (memory, spi_register ()); + size = 2; + } + else if (rn == SIM_D10V_SPU_REGNUM) + { + /* PSW_SM indicates that the current SP is the USER + stack-pointer. */ + WRITE_16 (memory, spu_register ()); + size = 2; + } + else if (rn >= SIM_D10V_IMAP0_REGNUM + && rn < SIM_D10V_IMAP0_REGNUM + SIM_D10V_NR_IMAP_REGS) + { + WRITE_16 (memory, imap_register (rn - SIM_D10V_IMAP0_REGNUM)); + size = 2; + } + else if (rn >= SIM_D10V_DMAP0_REGNUM + && rn < SIM_D10V_DMAP0_REGNUM + SIM_D10V_NR_DMAP_REGS) + { + WRITE_16 (memory, dmap_register (rn - SIM_D10V_DMAP0_REGNUM)); + size = 2; + } else - WRITE_16 (memory, GPR (rn)); - return -1; + size = 0; + return size; } int @@ -1110,20 +1344,55 @@ sim_store_register (sd, rn, memory, length) unsigned char *memory; int length; { - if (rn > 34) - SET_ACC (rn-35, READ_64 (memory) & MASK40); - else if (rn == 34) - SET_DMAP( READ_16(memory) ); - else if (rn == 33) - SET_IMAP1( READ_16(memory) ); - else if (rn == 32) - SET_IMAP0( READ_16(memory) ); - else if (rn >= 16) - SET_CREG (rn - 16, READ_16 (memory)); + int size; + if (rn < 0) + size = 0; + else if (rn >= SIM_D10V_R0_REGNUM + && rn < SIM_D10V_R0_REGNUM + SIM_D10V_NR_R_REGS) + { + SET_GPR (rn - SIM_D10V_R0_REGNUM, READ_16 (memory)); + size = 2; + } + else if (rn >= SIM_D10V_CR0_REGNUM + && rn < SIM_D10V_CR0_REGNUM + SIM_D10V_NR_CR_REGS) + { + SET_CREG (rn - SIM_D10V_CR0_REGNUM, READ_16 (memory)); + size = 2; + } + else if (rn >= SIM_D10V_A0_REGNUM + && rn < SIM_D10V_A0_REGNUM + SIM_D10V_NR_A_REGS) + { + SET_ACC (rn - SIM_D10V_A0_REGNUM, READ_64 (memory) & MASK40); + size = 8; + } + else if (rn == SIM_D10V_SPI_REGNUM) + { + /* PSW_SM indicates that the current SP is the USER + stack-pointer. */ + set_spi_register (READ_16 (memory)); + size = 2; + } + else if (rn == SIM_D10V_SPU_REGNUM) + { + set_spu_register (READ_16 (memory)); + size = 2; + } + else if (rn >= SIM_D10V_IMAP0_REGNUM + && rn < SIM_D10V_IMAP0_REGNUM + SIM_D10V_NR_IMAP_REGS) + { + set_imap_register (rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory)); + size = 2; + } + else if (rn >= SIM_D10V_DMAP0_REGNUM + && rn < SIM_D10V_DMAP0_REGNUM + SIM_D10V_NR_DMAP_REGS) + { + set_dmap_register (rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory)); + size = 2; + } else - SET_GPR (rn, READ_16 (memory)); + size = 0; SLOT_FLUSH (); - return -1; + return size; } diff --git a/sim/d10v/simops.c b/sim/d10v/simops.c index 5f19ebd9a13..d80c9238894 100644 --- a/sim/d10v/simops.c +++ b/sim/d10v/simops.c @@ -56,10 +56,13 @@ enum { | PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT), + /* The following bits in the PSW _can't_ be set by instructions such + as mvtc. */ + PSW_HW_MASK = (PSW_MASK | PSW_DM_BIT) }; reg_t -move_to_cr (int cr, reg_t mask, reg_t val) +move_to_cr (int cr, reg_t mask, reg_t val, int psw_hw_p) { /* A MASK bit is set when the corresponding bit in the CR should be left alone */ @@ -67,13 +70,18 @@ move_to_cr (int cr, reg_t mask, reg_t val) switch (cr) { case PSW_CR: - val &= PSW_MASK; + if (psw_hw_p) + val &= PSW_HW_MASK; + else + val &= PSW_MASK; if ((mask & PSW_SM_BIT) == 0) { - int new_sm = (val & PSW_SM_BIT) != 0; - SET_HELD_SP (PSW_SM, GPR (SP_IDX)); /* save old SP */ - if (PSW_SM != new_sm) - SET_GPR (SP_IDX, HELD_SP (new_sm)); /* restore new SP */ + int new_psw_sm = (val & PSW_SM_BIT) != 0; + /* save old SP */ + SET_HELD_SP (PSW_SM, GPR (SP_IDX)); + if (PSW_SM != new_psw_sm) + /* restore new SP */ + SET_GPR (SP_IDX, HELD_SP (new_psw_sm)); } if ((mask & (PSW_ST_BIT | PSW_FX_BIT)) == 0) { @@ -91,7 +99,11 @@ move_to_cr (int cr, reg_t mask, reg_t val) break; case BPSW_CR: case DPSW_CR: - val &= PSW_MASK; + /* Just like PSW, mask things like DM out. */ + if (psw_hw_p) + val &= PSW_HW_MASK; + else + val &= PSW_MASK; break; case MOD_S_CR: case MOD_E_CR: @@ -1096,7 +1108,7 @@ OP_5F20 () trace_input ("dbt", OP_VOID, OP_VOID, OP_VOID); SET_DPC (PC + 1); SET_DPSW (PSW); - SET_PSW (PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)); + SET_HW_PSW (PSW_DM_BIT | (PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT))); JMP (DBT_VECTOR_START); trace_output_void (); } diff --git a/sim/mips/ChangeLog b/sim/mips/ChangeLog index c12ec658e0d..6c8bc4a0dbb 100644 --- a/sim/mips/ChangeLog +++ b/sim/mips/ChangeLog @@ -1,3 +1,8 @@ +1999-11-11 Andrew Haley + + * interp.c (decode_coproc): Correctly handle DMFC0 and DMTC0 + instructions. + Thu Sep 9 15:12:08 1999 Geoffrey Keating * mips.igen (MULT): Correct previous mis-applied patch. diff --git a/sim/mips/interp.c b/sim/mips/interp.c index 68ffd27c5a7..9c53ff9081a 100644 --- a/sim/mips/interp.c +++ b/sim/mips/interp.c @@ -3124,9 +3124,14 @@ decode_coproc (SIM_DESC sd, CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii) ERET Exception return (VR4100 = 01000010000000000000000000011000) */ - if (((code == 0x00) || (code == 0x04)) && tail == 0) + if (((code == 0x00) || (code == 0x04) /* MFC0 / MTC0 */ + || (code == 0x01) || (code == 0x05)) /* DMFC0 / DMTC0 */ + && tail == 0) { - /* M[TF]C0 - 32 bit word */ + /* Clear double/single coprocessor move bit. */ + code &= ~1; + + /* M[TF]C0 (32 bits) | DM[TF]C0 (64 bits) */ switch (rd) /* NOTEs: Standard CP0 registers */ { diff --git a/sim/testsuite/d10v-elf/ChangeLog b/sim/testsuite/d10v-elf/ChangeLog index 723f88ae743..de4a22cc46c 100644 --- a/sim/testsuite/d10v-elf/ChangeLog +++ b/sim/testsuite/d10v-elf/ChangeLog @@ -1,3 +1,12 @@ +Fri Oct 29 18:36:34 1999 Andrew Cagney + + * t-mvtc.s: Check that the user can not modify the DM bit in the + BPSW or DPSW. + +Thu Oct 28 01:47:26 1999 Andrew Cagney + + * t-mvtc.s: Update. Check that user can not modify DM bit. + Wed Sep 8 19:34:55 MDT 1999 Diego Novillo * t-ld-st.s: New file. diff --git a/sim/testsuite/d10v-elf/t-mvtc.s b/sim/testsuite/d10v-elf/t-mvtc.s index cbf9308444a..2eed8331a40 100644 --- a/sim/testsuite/d10v-elf/t-mvtc.s +++ b/sim/testsuite/d10v-elf/t-mvtc.s @@ -17,7 +17,7 @@ checkpsw2 4 PSW_DB loadpsw2 PSW_DM - checkpsw2 5 PSW_DM + checkpsw2 5 0 ;; PSW_DM loadpsw2 PSW_IE checkpsw2 6 PSW_IE @@ -65,17 +65,65 @@ mvfc r7, cr11 check 18 r7 0xbeee -;;; Check that certain bits of the DPSW and BPSW are hardwired to zero +;;; Check that certain bits of the PSW, DPSW and BPSW are hardwired to zero +psw_ffff: + ldi r6, 0xffff + mvtc r6, psw + mvfc r7, psw + check 18 r7 0xb7cd + +bpsw_ffff: ldi r6, 0xffff mvtc r6, bpsw mvfc r7, bpsw - check 18 r7 0xbfcd + check 18 r7 0xb7cd +dpsw_ffff: ldi r6, 0xffff mvtc r6, dpsw mvfc r7, dpsw - check 18 r7 0xbfcd + check 18 r7 0xb7cd + +;;; Another check. Very similar + +psw_dfff: + ldi r6, 0xdfff + mvtc r6, psw + mvfc r7, psw + check 18 r7 0x97cd + +bpsw_dfff: + ldi r6, 0xdfff + mvtc r6, bpsw + mvfc r7, bpsw + check 18 r7 0x97cd + +dpsw_dfff: + ldi r6, 0xdfff + mvtc r6, dpsw + mvfc r7, dpsw + check 18 r7 0x97cd + +;;; And again. + +psw_8005: + ldi r6, 0x8005 + mvtc r6, psw + mvfc r7, psw + check 18 r7 0x8005 + +bpsw_8005: + ldi r6, 0x8005 + mvtc r6, bpsw + mvfc r7, bpsw + check 18 r7 0x8005 + +dpsw_8005: + ldi r6, 0x8005 + mvtc r6, dpsw + mvfc r7, dpsw + check 18 r7 0x8005 exit0 -- 2.39.2