diff --git a/gdb/ChangeLog b/gdb/ChangeLog index af0c40dea9c..ed00ee19d47 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,277 @@ +1999-11-01 Michael Snyder + Tom Tromey + + * tracepoint.h (get_tracepoint_by_number): Updated declaration. + * tracepoint.c (get_tracepoint_by_number): Added `multi_p' + argument. Now uses get_number_or_range and get_number. + (trace_pass_command): Allow a tracepoint range. + * breakpoint.h (get_number, get_number_or_range): Declare. + * breakpoint.c (get_number_trailer): New function. + (get_number): Rewrote to use get_number_trailer. + (get_number_or_range): New function. + (condition_command): Check `get_number' return value. + (commands_command): Likewise. + (ignore_command): Likewise. + (map_breakpoint_numbers): Use get_number_or_range. + +1999-11-01 Fernando Nasser + + * remote-rdi.c (_initialize_remote_rdi): Make log commands + subcommands of maintenance. Remove improper identation from + command documentation. + +1999-11-01 Fernando Nasser + + From Grant Edwards : + * rdi-share/etherdrv.c (fetch_ports): Print out additional TCP/IP + port information in ethernet driver if the DEBUG flag is set. + * rdi-share/hostchan.c (Adp_addToQueue): Changed #if statement in + hostchan.c to avoid compiler complaint when DEBUG macro was + undefined. + * rdi-share/unixcomm.c (Unix_ReadSerial): Print system error code + if read() system call fails. + +1999-11-01 Fernando Nasser + + * rdi-share/bytesex.h: Deleted. Conflicts with a system header file + on some systems like Linux Red Hat 5.2. + * rdi-share/angel_bytesex.h: New file. Replaces the above. + * rdi-share/bytesex.c: Deleted. Name changed to match the header + mentioned above (this is the implementation file). + * rdi-share/angel_bytesex.c: New file. Replaces the above. + * rdi-share/Makefile.am: Reflect above changes. + * rdi-share/Makefile.in: Reflect above changes. + +1999-11-01 Jimmy Guo + + * annotate.c (breakpoints_changed, annotate_ignore_count_change, + annotate_stopped): Provide annotation for breakpoint ignore_count + changes but only provide once at annotate_stopped time for + sucessive ignore_count triggered breakpoint changes, to make GUIs + happy yet lazy. + * annotate.h (annotate_ignore_count_change): Declare. + * breakpoint.c (bpstat_stop_status): Call + annotate_ignore_count_change when ignore_count changes. + +1999-11-01 Fernando Nasser + + From Grant Edwards : + * rdi-share/ardi.c (HandleStoppedMessage): Changed code that + handles the "stop" message so that unrecognized errors are + returned as "Error" rather than "NoError". The old code resulted + in some error conditions not being reported to the user. + +1999-11-01 Fernando Nasser + + From Grant Edwards : + * remote-rdi.c (arm_rdi_open): Added a call to Adp_CloseDevice() + before attempting to open a connection. This allows the user to + issue the "target rdi" command multiple times (in case the user + needs to change options or re-initialize the link). + +1999-11-01 Fernando Nasser + + From Grant Edwards : + * rdi-share/endian.h: Deleted. Name clash with + /usr/include/endian.h. This was causing the wrong byte order to + be used by htons() in the RDI Ethernet driver. + * rdi-share/angel_endian.h: New file. Replaces the above. + * rdi-share/ardi.c: Replace include to reflect the above change. + * rdi-share/etherdrv.c: Ditto. + * rdi-share/hsys.c: Ditto. + * rdi-share/msgbuild.c: Ditto. + * rdi-share/params.c: Ditto. + * rdi-share/rx.c: Ditto. + * rdi-share/tx.c: Ditto. + * rdi-share/Makefile.am: Reflect above changes. + * rdi-share/Makefile.in: Reflect above changes. + +1999-11-01 Fernando Nasser + + From Grant Edwards : + * remote-rdi.c (_initialize_remote_rdi): Added command + rdilogenable. Allows the user to log ADP packets that are + exchanged between gdb and the target. Both the raw packets are + shown and some minimal decoding is attempted. Default state is + disabled. + (_initialize_remote_rdi): Added command rdilogfile. Allows the + user to specify the filename to which the ADP packet log is to be + written. Default state is "rdi.log". + (rdilogenable_command): New function. Related to rdilogenable. + (rdilogfile_command): New function. Related to rdilogfile. + * rdi-share/devsw.c (openLogFile, closeLogFile, + DevSW_SetLogEnable, DevSW_SetLogfile, dumpPacket): New + functions. Implement logging. + (DevSW_Read): Log if requested. + (DevSW_Write): Log if requested. + * rdi-share/devsw.h: Add prototypes for DevSW_SetLogfile and + DevSW_SetLogEnable. + * rdi-share/hostchan.c (Adp_SetLogEnable, Adp_SetLogfile): New + functions. Related to rdilogenable and rdilogfile. + * rdi-share/hostchan.h: Add prototypes for the above functions. + +1999-11-01 Fernando Nasser + + From Grant Edwards : + * remote-rdi.c (arm_rdi_open): Added code to split the arguments + to the 'target rdi' command at the first space. The first word is + passed to Adp_OpenDevice as the device name, the tail is passed as + the "arguments" parameter. This allows user specified baud rates + -- among other things that still need to be documented [e.g. (gdb) + target rdi /dev/ttyS1 19200]. NB: With very limited testing, the + ARM Embedded-ICE seems to run at 19.2K (though it is reported to + be unreliable above 9600), and the EPI Jeeni seems to run at + 38.4K. + +1999-11-01 Fernando Nasser + + From Grant Edwards : + * remote-rdi.c (_initialize_remote_rdi): Added the boolean + set/show variable rdiromatzero. Should be set to true if the + target has ROM at address 0. If true, then gdb will not tell the + target to trap fetches to interrupt vectors (which are located at + address 0). Using the Angel monitor, attempting to set + breakpoints in ROM is an error. Using JTAG debugging of the + ARM7TDMI, attempting to set more than two breakpoints in ROM is an + error. Default state is false (vectors will be trapped) -- used to + be hardwired false. + +1999-11-01 Fernando Nasser + + From Grant Edwards : + * remote-rdi.c (_initialize_remote_rdi): Added the boolean + set/show variable rdiheartbeat. This enables or disables ADP + link-check "heartbeat" packets sent by the host to the target. + Heartbeat packets can cause both the ARM Embedded-ICE and the EPI + Jeeni to malfunction: If a heartbeat packet is received by the + target while it is sending a packet, that packet will be aborted, + and the ADP protocol engine then gets very confused. Default state + is off -- used to hardwired on. + +1999-10-29 Kevin Buettner + + * i386-linux-nat.c (dummy_sse_values): Also define for systems + without PTRACE_GETXFPREGS. + +1999-10-29 Jim Blandy + + Hardware watchpoint fix from Eli Zaretskii : + + * breakpoint.c (insert_breakpoints): Fetch the value of the + expression we need to watch. If it's a lazy memory lvalue, then + we need to fetch it now, before we start the inferior again. + (insert_breakpoints, remove_breakpoint, bpstat_stop_status, + can_use_hardware_watchpoint): Only those values representing + memory we actually fetched need to be watched. + +1999-10-29 Elena Zannoni + + * breakpoint.h (bpstat_print): Return 'enum print_stop_action', + not 'int'. + +1999-10-29 Jim Blandy + + * acconfig.h: Fix entries for HAVE_STRUCT_SAVE_STATE_T, + HAVE_STRUCT_MEMBER_SS_WIDE, and HAVE_PTRACE_GETXFPREGS. + * config.h.in: Regenerated. + +1999-10-28 Jim Blandy + + Fixes for warnings from Andreas Jaeger . + * linux-thread.c (linuxthreads_sig_restart, + linuxthreads_sig_cancel, linuxthreads_sig_debug): Add missing + initializers to avoid gcc warnings. + (resume_thread): Add braces as recommended by gcc -Wparentheses. + (stop_thread): Likewise. + (linuxthreads_wait): Likewise. + (linuxthreads_find_trap): Likewise. + +1999-10-28 Elena Zannoni + + * infcmd.c: Fix typo. + +1999-10-28 Jim Blandy + + * gdbtypes.c (init_simd_type): The upper bound to + create_range_type is inclusive, not exclusive. + + * 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. + * config/i386/tm-linux.h (HAVE_SSE_REGS): #define, iff the + configure script #defined HAVE_PTRACE_GETXFPREGS. + (REGISTER_VIRTUAL_TYPE): Provide the proper types for the pointer + registers and the SSE registers. + * i386-linux-nat.c (GETREGS_SUPPLIES, GETFPREGS_SUPPLIES, + GETXFPREGS_SUPPLIES): New macros. + (have_ptrace_getxfpregs): New variable. + (FPREGSET_T_FPREG_ADDR): Renamed from FPREGSET_T_FPREG_OFFSET. + (supply_fpregset, convert_to_fpregset): Callers changed. + (supply_xfpregset, convert_to_xfpregset, fetch_xfpregs, + store_xfpregs, dummy_sse_values): New functions. + (fetch_inferior_registers, store_inferior_registers): Use the + *_SUPPLIES macros to decide how to fetch a given register. Use + {fetch,store}_xfpregs and dummy_sse_values to provide access to + the SSE registers, on systems where they are present. + +1999-10-28 Kevin Buettner + + * gdbserver/gdbreplay.c (config.h, errno.h): Include. + (perror_with_name): Don't declare sys_nerr, sys_errlist, or errno + when STDC_HEADERS is defined. + * gdbserver/utils.c (STDC_HEADERS): Likewise. + + * gdbserver/low-hppabsd.c, gdbserver/low-linux.c, + gdbserver/low-lynx.c, gdbserver/low-sim.c, gdbserver/low-sparc.c, + gdbserver/low-sun3.c (my_registers): Declare. + (registers): Changed from array type to pointer type in order + to match declaration in inferior.h in main gdb sources. + * gdbserver/server.h (registers): Likewise. + * gdbserver/remote-utils.c (outreg): Removed declaration of + registers[]. + + * gdbserver/low-linux.c (fetch_register): Changed PTRACE_PEEKUSR to + PTRACE_PEEKUSER. [Note the missing 'E'.] + (store_inferior_registers): Likewise for PTRACE_POKEUSER. + + * gdbserver/low-linux.c (sys/ptrace.h): Move include to + avoid conflict with #defines coming from . + (sys/reg.h): Only include when HAVE_SYS_REG_H is defined. + (PTRACE_XFER_TYPE): Provide a default type in case + the target doesn't define it. + (fetch_register, read_inferior_memory, write_inferior_memory): + Use PTRACE_XFER_TYPE instead of int for ptrace() transfers. + (I386_GNULINUX_TARGET): Use #ifdef with this symbol instead + of assuming it's an x86 target when it's not a m68k target. + (i386_register_raw_size, i386_register_byte): Define these arrays + to match other changes that've been occuring to the x86 target + in the main gdb sources. + (initialize_arch): New (static) function for doing target arch + specific initializations. + + * gdbserver/server.h (MAXBUFBYTES, PBUFSIZ): New defines + [actually stolen from remote.c]. + * gdbserver/remote-utils.c (putpkt): Use PBUFSIZ to make + sure that buffer is big enough. + * gdbserver/server.c (main): Ditto. + + * gdbserver/remote-utils.c (outreg): Allow register numbers + bigger than 255. + (prepare_resume_reply): Provide alternate mechanism, + GDBSERVER_RESUME_REGS, for defining list of registers to send + to gdb. + * gdbserver/Makefile.in (INTERNAL_CFLAGS): Swapped order of + INCLUDE_CFLAGS and BFD_CFLAGS to ensure that gdb's config.h + gets found before bfd's config.h. Also added -DGDBSERVER + switch. + (INCLUDE_CFLAGS): Added -I.. . + +1999-10-27 Nick Clifton + + * arm-tdep.c (THUMB_BE_BREAKPOINT): Change to 0xbebe. + (THUMB_LE_BREAKPOINT): Change to 0xbebe. + Mon Oct 25 18:22:06 1999 Andrew Cagney * remote.c: Document future of compare_sections_command. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index edb38eed087..a24ca7954f0 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 = 19991025 +VERSION = 19991101 DIST=gdb LINT=/usr/5bin/lint diff --git a/gdb/acconfig.h b/gdb/acconfig.h index bf52c4f375b..d2d72fea0ac 100644 --- a/gdb/acconfig.h +++ b/gdb/acconfig.h @@ -78,7 +78,10 @@ #undef WITH_SIM /* Set to true if the save_state_t structure is present */ -#define HAVE_STRUCT_SAVE_STATE_T 0 +#undef HAVE_STRUCT_SAVE_STATE_T /* Set to true if the save_state_t structure has the ss_wide member */ -#define HAVE_STRUCT_MEMBER_SS_WIDE 0 +#undef HAVE_STRUCT_MEMBER_SS_WIDE + +/* Define if defines the PTRACE_GETXFPREGS request. */ +#undef HAVE_PTRACE_GETXFPREGS diff --git a/gdb/annotate.c b/gdb/annotate.c index 1c235a568e5..4508ad8cf06 100644 --- a/gdb/annotate.c +++ b/gdb/annotate.c @@ -40,6 +40,8 @@ void (*annotate_signalled_hook) PARAMS ((void)); void (*annotate_signal_hook) PARAMS ((void)); void (*annotate_exited_hook) PARAMS ((void)); +static int ignore_count_changed = 0; + static void print_value_flags (t) struct type *t; @@ -57,9 +59,24 @@ breakpoints_changed () { target_terminal_ours (); printf_unfiltered ("\n\032\032breakpoints-invalid\n"); + if (ignore_count_changed) + ignore_count_changed = 0; /* Avoid multiple break annotations. */ } } +/* The GUI needs to be informed of ignore_count changes, but we don't + want to provide successive multiple breakpoints-invalid messages + that are all caused by the fact that the ignore count is changing + (which could keep the GUI very busy). One is enough, after the + target actually "stops". */ + +void +annotate_ignore_count_change (void) +{ + if (annotation_level > 1) + ignore_count_changed = 1; +} + void annotate_breakpoint (num) int num; @@ -109,6 +126,11 @@ annotate_stopped () if (annotation_level > 1) printf_filtered ("\n\032\032stopped\n"); } + if (annotation_level > 1 && ignore_count_changed) + { + ignore_count_changed = 0; + breakpoints_changed (); + } } void diff --git a/gdb/annotate.h b/gdb/annotate.h index e80313a36eb..0521896f23d 100644 --- a/gdb/annotate.h +++ b/gdb/annotate.h @@ -23,6 +23,7 @@ extern void breakpoints_changed PARAMS ((void)); +extern void annotate_ignore_count_change (void); extern void annotate_breakpoint PARAMS ((int)); extern void annotate_catchpoint PARAMS ((int)); extern void annotate_watchpoint PARAMS ((int)); diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index b3ad0245468..99139ac115b 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -1698,8 +1698,8 @@ gdb_print_insn_arm (memaddr, info) /* Sequence of bytes for breakpoint instruction. */ #define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7} /* Recognized illegal opcodes */ #define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE} -#define THUMB_LE_BREAKPOINT {0xfe,0xdf} -#define THUMB_BE_BREAKPOINT {0xdf,0xfe} +#define THUMB_LE_BREAKPOINT {0xbe,0xbe} +#define THUMB_BE_BREAKPOINT {0xbe,0xbe} /* The following has been superseded by BREAKPOINT_FOR_PC, but is defined merely to keep mem-break.c happy. */ diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 82085b0b120..2f75e605eb1 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -137,7 +137,7 @@ static void condition_command PARAMS ((char *, int)); static int -get_number PARAMS ((char **)); +get_number_trailer PARAMS ((char **, int)); void set_breakpoint_count PARAMS ((int)); @@ -271,12 +271,12 @@ static int executing_breakpoint_commands; ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current breakpoint. */ -#define ALL_BREAKPOINTS(b) for (b = breakpoint_chain; b; b = b->next) +#define ALL_BREAKPOINTS(B) for (B = breakpoint_chain; B; B = B->next) -#define ALL_BREAKPOINTS_SAFE(b,tmp) \ - for (b = breakpoint_chain; \ - b? (tmp=b->next, 1): 0; \ - b = tmp) +#define ALL_BREAKPOINTS_SAFE(B,TMP) \ + for (B = breakpoint_chain; \ + B ? (TMP=B->next, 1): 0; \ + B = TMP) /* True if SHIFT_INST_REGS defined, false otherwise. */ @@ -403,12 +403,16 @@ int default_breakpoint_line; Currently the string can either be a number or "$" followed by the name of a convenience variable. Making it an expression wouldn't work well - for map_breakpoint_numbers (e.g. "4 + 5 + 6"). */ + for map_breakpoint_numbers (e.g. "4 + 5 + 6"). + + TRAILER is a character which can be found after the number; most + commonly this is `-'. If you don't want a trailer, use \0. */ static int -get_number (pp) +get_number_trailer (pp, trailer) char **pp; + int trailer; { - int retval; + int retval = 0; /* default */ char *p = *pp; if (p == NULL) @@ -428,11 +432,13 @@ get_number (pp) strncpy (varname, start, p - start); varname[p - start] = '\0'; val = value_of_internalvar (lookup_internalvar (varname)); - if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_INT) - error ( - "Convenience variables used to specify breakpoints must have integer values." - ); - retval = (int) value_as_long (val); + if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT) + retval = (int) value_as_long (val); + else + { + printf_filtered ("Convenience variable must have integer value.\n"); + retval = 0; + } } else { @@ -442,16 +448,115 @@ get_number (pp) ++p; if (p == *pp) /* There is no number here. (e.g. "cond a == b"). */ - error_no_arg ("breakpoint number"); - retval = atoi (*pp); + { + /* Skip non-numeric token */ + while (*p && !isspace((int) *p)) + ++p; + /* Return zero, which caller must interpret as error. */ + retval = 0; + } + else + retval = atoi (*pp); + } + if (!(isspace (*p) || *p == '\0' || *p == trailer)) + { + /* Trailing junk: return 0 and let caller print error msg. */ + while (!(isspace (*p) || *p == '\0' || *p == trailer)) + ++p; + retval = 0; } - if (!(isspace (*p) || *p == '\0')) - error ("breakpoint number expected"); while (isspace (*p)) p++; *pp = p; return retval; } + +/* Like get_number_trailer, but don't allow a trailer. */ +int +get_number (pp) + char **pp; +{ + return get_number_trailer (pp, '\0'); +} + +/* Parse a number or a range. + * A number will be of the form handled by get_number. + * A range will be of the form - , and + * will represent all the integers between number1 and number2, + * inclusive. + * + * While processing a range, this fuction is called iteratively; + * At each call it will return the next value in the range. + * + * At the beginning of parsing a range, the char pointer PP will + * be advanced past and left pointing at the '-' token. + * Subsequent calls will not advance the pointer until the range + * is completed. The call that completes the range will advance + * pointer PP past . + */ + +int +get_number_or_range (pp) + char **pp; +{ + static int last_retval, end_value; + static char *end_ptr; + static int in_range = 0; + + if (**pp != '-') + { + /* Default case: pp is pointing either to a solo number, + or to the first number of a range. */ + last_retval = get_number_trailer (pp, '-'); + if (**pp == '-') + { + char **temp; + + /* This is the start of a range ( - ). + Skip the '-', parse and remember the second number, + and also remember the end of the final token. */ + + temp = &end_ptr; + end_ptr = *pp + 1; + while (isspace ((int) *end_ptr)) + end_ptr++; /* skip white space */ + end_value = get_number (temp); + if (end_value < last_retval) + { + error ("inverted range"); + } + else if (end_value == last_retval) + { + /* degenerate range (number1 == number2). Advance the + token pointer so that the range will be treated as a + single number. */ + *pp = end_ptr; + } + else + in_range = 1; + } + } + else if (! in_range) + error ("negative value"); + else + { + /* pp points to the '-' that betokens a range. All + number-parsing has already been done. Return the next + integer value (one greater than the saved previous value). + Do not advance the token pointer 'pp' until the end of range + is reached. */ + + if (++last_retval == end_value) + { + /* End of range reached; advance token pointer. */ + *pp = end_ptr; + in_range = 0; + } + } + return last_retval; +} + + /* condition N EXP -- set break condition of breakpoint N to EXP. */ @@ -469,6 +574,8 @@ condition_command (arg, from_tty) p = arg; bnum = get_number (&p); + if (bnum == 0) + error ("Bad breakpoint argument: '%s'", arg); ALL_BREAKPOINTS (b) if (b->number == bnum) @@ -525,6 +632,9 @@ commands_command (arg, from_tty) p = arg; bnum = get_number (&p); + if (bnum == 0) + error ("bad breakpoint number: '%s'", arg); + if (p && *p) error ("Unexpected extra arguments following breakpoint number."); @@ -842,8 +952,13 @@ insert_breakpoints () if (within_current_scope) { /* Evaluate the expression and cut the chain of values - produced off from the value chain. */ + produced off from the value chain. + + Make sure the value returned isn't lazy; we use + laziness to determine what memory GDB actually needed + in order to compute the value of the expression. */ v = evaluate_expression (b->exp); + VALUE_CONTENTS(v); value_release_to_mark (mark); b->val_chain = v; @@ -852,8 +967,11 @@ insert_breakpoints () /* Look at each value on the value chain. */ for (; v; v = v->next) { - /* If it's a memory location, then we must watch it. */ - if (v->lval == lval_memory) + /* If it's a memory location, and GDB actually needed + its contents to evaluate the expression, then we + must watch it. */ + if (VALUE_LVAL (v) == lval_memory + && ! VALUE_LAZY (v)) { CORE_ADDR addr; int len, type; @@ -1198,7 +1316,8 @@ remove_breakpoint (b, is) { /* For each memory reference remove the watchpoint at that address. */ - if (v->lval == lval_memory) + if (VALUE_LVAL (v) == lval_memory + && ! VALUE_LAZY (v)) { CORE_ADDR addr; int len, type; @@ -2333,7 +2452,8 @@ bpstat_stop_status (pc, not_a_breakpoint) continue; for (v = b->val_chain; v; v = v->next) { - if (v->lval == lval_memory) + if (VALUE_LVAL (v) == lval_memory + && ! VALUE_LAZY (v)) { CORE_ADDR vaddr; @@ -2420,6 +2540,7 @@ bpstat_stop_status (pc, not_a_breakpoint) else if (b->ignore_count > 0) { b->ignore_count--; + annotate_ignore_count_change (); bs->stop = 0; } else @@ -4694,21 +4815,46 @@ can_use_hardware_watchpoint (v) if (!can_use_hw_watchpoints) return 0; - /* Make sure all the intermediate values are in memory. Also make sure - we found at least one memory expression. Guards against watch 0x12345, - which is meaningless, but could cause errors if one tries to insert a - hardware watchpoint for the constant expression. */ + /* Make sure that the value of the expression depends only upon + memory contents, and values computed from them within GDB. If we + find any register references or function calls, we can't use a + hardware watchpoint. + + The idea here is that evaluating an expression generates a series + of values, one holding the value of every subexpression. (The + expression a*b+c has five subexpressions: a, b, a*b, c, and + a*b+c.) GDB's values hold almost enough information to establish + the criteria given above --- they identify memory lvalues, + register lvalues, computed values, etcetera. So we can evaluate + the expression, and then scan the chain of values that leaves + behind to decide whether we can detect any possible change to the + expression's final value using only hardware watchpoints. + + However, I don't think that the values returned by inferior + function calls are special in any way. So this function may not + notice that an expression involving an inferior function call + can't be watched with hardware watchpoints. FIXME. */ for (; v; v = v->next) { - if (v->lval == lval_memory) + if (VALUE_LVAL (v) == lval_memory) { - CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); - int len = TYPE_LENGTH (VALUE_TYPE (v)); - - if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len)) - return 0; + if (VALUE_LAZY (v)) + /* A lazy memory lvalue is one that GDB never needed to fetch; + we either just used its address (e.g., `a' in `a.b') or + we never needed it at all (e.g., `a' in `a,b'). */ + ; else - found_memory_cnt++; + { + /* Ahh, memory we actually used! Check if we can cover + it with hardware watchpoints. */ + CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); + int len = TYPE_LENGTH (VALUE_TYPE (v)); + + if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len)) + return 0; + else + found_memory_cnt++; + } } else if (v->lval != not_lval && v->modifiable == 0) return 0; /* ??? What does this represent? */ @@ -6440,7 +6586,8 @@ ignore_command (args, from_tty) error_no_arg ("a breakpoint number"); num = get_number (&p); - + if (num == 0) + error ("bad breakpoint number: '%s'", args); if (*p == 0) error ("Second argument (specified ignore-count) is missing."); @@ -6462,7 +6609,7 @@ map_breakpoint_numbers (args, function) register char *p = args; char *p1; register int num; - register struct breakpoint *b; + register struct breakpoint *b, *tmp; if (p == 0) error_no_arg ("one or more breakpoint numbers"); @@ -6471,19 +6618,25 @@ map_breakpoint_numbers (args, function) { p1 = p; - num = get_number (&p1); - - ALL_BREAKPOINTS (b) - if (b->number == num) + num = get_number_or_range (&p1); + if (num == 0) { - struct breakpoint *related_breakpoint = b->related_breakpoint; - function (b); - if (related_breakpoint) - function (related_breakpoint); - goto win; + warning ("bad breakpoint number at or near '%s'", p); + } + else + { + ALL_BREAKPOINTS_SAFE (b, tmp) + if (b->number == num) + { + struct breakpoint *related_breakpoint = b->related_breakpoint; + function (b); + if (related_breakpoint) + function (related_breakpoint); + goto win; + } + printf_unfiltered ("No breakpoint number %d.\n", num); + win: } - printf_unfiltered ("No breakpoint number %d.\n", num); - win: p = p1; } } diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index a59708490b9..94492dd3bda 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -375,6 +375,16 @@ struct bpstat_what int call_dummy; }; +/* The possible return values for print_bpstat, print_it_normal, + print_it_done, print_it_noop. */ +enum print_stop_action + { + PRINT_UNKNOWN = -1, + PRINT_SRC_AND_LOC, + PRINT_SRC_ONLY, + PRINT_NOTHING + }; + /* Tell what to do about this bpstat. */ struct bpstat_what bpstat_what PARAMS ((bpstat)); @@ -410,7 +420,7 @@ extern int bpstat_have_active_hw_watchpoints PARAMS ((void)); /* Print a message indicating what happened. Returns nonzero to say that only the source line should be printed after this (zero return means print the frame as well as the source line). */ -extern int bpstat_print PARAMS ((bpstat)); +extern enum print_stop_action bpstat_print PARAMS ((bpstat)); /* Return the breakpoint number of the first breakpoint we are stopped at. *BSP upon return is a bpstat which points to the remaining @@ -488,16 +498,6 @@ enum breakpoint_here ordinary_breakpoint_here, permanent_breakpoint_here }; - -/* The possible return values for print_bpstat, print_it_normal, - print_it_done, print_it_noop. */ -enum print_stop_action - { - PRINT_UNKNOWN = -1, - PRINT_SRC_AND_LOC, - PRINT_SRC_ONLY, - PRINT_NOTHING - }; /* Prototypes for breakpoint-related functions. */ @@ -618,6 +618,10 @@ enable_watchpoints_after_interactive_call_stop PARAMS ((void)); extern void clear_breakpoint_hit_counts PARAMS ((void)); +extern int get_number PARAMS ((char **)); + +extern int get_number_or_range PARAMS ((char **)); + /* The following are for displays, which aren't really breakpoints, but here is as good a place as any for them. */ diff --git a/gdb/config.in b/gdb/config.in index b0f5ae872ad..5660f45b129 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -112,10 +112,13 @@ #undef WITH_SIM /* Set to true if the save_state_t structure is present */ -#define HAVE_STRUCT_SAVE_STATE_T 0 +#undef HAVE_STRUCT_SAVE_STATE_T /* Set to true if the save_state_t structure has the ss_wide member */ -#define HAVE_STRUCT_MEMBER_SS_WIDE 0 +#undef HAVE_STRUCT_MEMBER_SS_WIDE + +/* Define if defines the PTRACE_GETXFPREGS request. */ +#undef HAVE_PTRACE_GETXFPREGS /* Define if you have the __argz_count function. */ #undef HAVE___ARGZ_COUNT diff --git a/gdb/config/i386/tm-linux.h b/gdb/config/i386/tm-linux.h index 5faa6ff6264..42daaeae5bf 100644 --- a/gdb/config/i386/tm-linux.h +++ b/gdb/config/i386/tm-linux.h @@ -23,6 +23,9 @@ #define I386_GNULINUX_TARGET #define HAVE_I387_REGS +#ifdef HAVE_PTRACE_GETXFPREGS +#define HAVE_SSE_REGS +#endif #include "i386/tm-i386.h" @@ -90,8 +93,12 @@ extern int i387_store_floating (PTR addr, int len, long double val); /* Return the GDB type object for the "standard" data type of data in register N. */ #undef REGISTER_VIRTUAL_TYPE -#define REGISTER_VIRTUAL_TYPE(N) \ - (IS_FP_REGNUM (N) ? builtin_type_long_double : builtin_type_int) +#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) #endif diff --git a/gdb/configure b/gdb/configure index 5f649626a02..9306516db85 100755 --- a/gdb/configure +++ b/gdb/configure @@ -3691,8 +3691,41 @@ EOF fi +echo $ac_n "checking for PTRACE_GETXFPREGS""... $ac_c" 1>&6 +echo "configure:3696: checking for PTRACE_GETXFPREGS" >&5 +if eval "test \"`echo '$''{'gdb_cv_have_ptrace_getxfpregs'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { +PTRACE_GETXFPREGS; +; return 0; } +EOF +if { (eval echo configure:3708: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + gdb_cv_have_ptrace_getxfpregs=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + gdb_cv_have_ptrace_getxfpregs=no +fi +rm -f conftest* +fi + +echo "$ac_t""$gdb_cv_have_ptrace_getxfpregs" 1>&6 +if test $gdb_cv_have_ptrace_getxfpregs = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_PTRACE_GETXFPREGS 1 +EOF + +fi + echo $ac_n "checking for socketpair in -lsocket""... $ac_c" 1>&6 -echo "configure:3696: checking for socketpair in -lsocket" >&5 +echo "configure:3729: checking for socketpair in -lsocket" >&5 ac_lib_var=`echo socket'_'socketpair | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3700,7 +3733,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3741,12 +3774,12 @@ fi for ac_func in socketpair do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3745: checking for $ac_func" >&5 +echo "configure:3778: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3806: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3796,12 +3829,12 @@ done echo $ac_n "checking whether malloc must be declared""... $ac_c" 1>&6 -echo "configure:3800: checking whether malloc must be declared" >&5 +echo "configure:3833: checking whether malloc must be declared" >&5 if eval "test \"`echo '$''{'bfd_cv_decl_needed_malloc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3822,7 +3855,7 @@ int main() { char *(*pfn) = (char *(*)) malloc ; return 0; } EOF -if { (eval echo configure:3826: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3859: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_decl_needed_malloc=no else @@ -3843,12 +3876,12 @@ EOF fi echo $ac_n "checking whether realloc must be declared""... $ac_c" 1>&6 -echo "configure:3847: checking whether realloc must be declared" >&5 +echo "configure:3880: checking whether realloc must be declared" >&5 if eval "test \"`echo '$''{'bfd_cv_decl_needed_realloc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3869,7 +3902,7 @@ int main() { char *(*pfn) = (char *(*)) realloc ; return 0; } EOF -if { (eval echo configure:3873: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3906: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_decl_needed_realloc=no else @@ -3890,12 +3923,12 @@ EOF fi echo $ac_n "checking whether free must be declared""... $ac_c" 1>&6 -echo "configure:3894: checking whether free must be declared" >&5 +echo "configure:3927: checking whether free must be declared" >&5 if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3916,7 +3949,7 @@ int main() { char *(*pfn) = (char *(*)) free ; return 0; } EOF -if { (eval echo configure:3920: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3953: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_decl_needed_free=no else @@ -3937,12 +3970,12 @@ EOF fi echo $ac_n "checking whether strerror must be declared""... $ac_c" 1>&6 -echo "configure:3941: checking whether strerror must be declared" >&5 +echo "configure:3974: checking whether strerror must be declared" >&5 if eval "test \"`echo '$''{'bfd_cv_decl_needed_strerror'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3963,7 +3996,7 @@ int main() { char *(*pfn) = (char *(*)) strerror ; return 0; } EOF -if { (eval echo configure:3967: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4000: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_decl_needed_strerror=no else @@ -3984,12 +4017,12 @@ EOF fi echo $ac_n "checking whether strdup must be declared""... $ac_c" 1>&6 -echo "configure:3988: checking whether strdup must be declared" >&5 +echo "configure:4021: checking whether strdup must be declared" >&5 if eval "test \"`echo '$''{'bfd_cv_decl_needed_strdup'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -4010,7 +4043,7 @@ int main() { char *(*pfn) = (char *(*)) strdup ; return 0; } EOF -if { (eval echo configure:4014: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4047: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_decl_needed_strdup=no else @@ -4031,12 +4064,12 @@ EOF fi echo $ac_n "checking whether strstr must be declared""... $ac_c" 1>&6 -echo "configure:4035: checking whether strstr must be declared" >&5 +echo "configure:4068: checking whether strstr must be declared" >&5 if eval "test \"`echo '$''{'bfd_cv_decl_needed_strstr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -4057,7 +4090,7 @@ int main() { char *(*pfn) = (char *(*)) strstr ; return 0; } EOF -if { (eval echo configure:4061: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4094: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_decl_needed_strstr=no else @@ -4084,9 +4117,9 @@ fi # could be expunged. --jsm 1999-03-22 echo $ac_n "checking for HPUX save_state structure""... $ac_c" 1>&6 -echo "configure:4088: checking for HPUX save_state structure" >&5 +echo "configure:4121: checking for HPUX save_state structure" >&5 cat > conftest.$ac_ext < EOF @@ -4101,7 +4134,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < EOF @@ -4153,7 +4186,7 @@ EOF gdb_cv_hostos_is_solaris=yes ;; esac echo $ac_n "checking for directory proc entries""... $ac_c" 1>&6 -echo "configure:4157: checking for directory proc entries" >&5 +echo "configure:4190: checking for directory proc entries" >&5 # The [gdb_host != sun4sol2] hack is because Solaris does provide the # multiple procfs files as of Solaris 2.6, but GDB can't use it right now. if test "$ac_cv_header_sys_procfs_h" = yes -a \ @@ -4175,19 +4208,19 @@ fi if test "$ac_cv_header_sys_procfs_h" = yes; then echo $ac_n "checking for pstatus_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:4179: checking for pstatus_t in sys/procfs.h" >&5 +echo "configure:4212: checking for pstatus_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pstatus_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { pstatus_t avar ; return 0; } EOF -if { (eval echo configure:4191: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4224: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_pstatus_t=yes else @@ -4209,19 +4242,19 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_pstatus_t" 1>&6 echo $ac_n "checking for prrun_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:4213: checking for prrun_t in sys/procfs.h" >&5 +echo "configure:4246: checking for prrun_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prrun_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { prrun_t avar ; return 0; } EOF -if { (eval echo configure:4225: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4258: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_prrun_t=yes else @@ -4243,19 +4276,19 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_prrun_t" 1>&6 echo $ac_n "checking for gregset_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:4247: checking for gregset_t in sys/procfs.h" >&5 +echo "configure:4280: checking for gregset_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_gregset_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { gregset_t avar ; return 0; } EOF -if { (eval echo configure:4259: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4292: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_gregset_t=yes else @@ -4277,19 +4310,19 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_gregset_t" 1>&6 echo $ac_n "checking for fpregset_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:4281: checking for fpregset_t in sys/procfs.h" >&5 +echo "configure:4314: checking for fpregset_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_fpregset_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { fpregset_t avar ; return 0; } EOF -if { (eval echo configure:4293: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4326: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_fpregset_t=yes else @@ -4313,12 +4346,12 @@ EOF echo $ac_n "checking for PIOCSET ioctl entry in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:4317: checking for PIOCSET ioctl entry in sys/procfs.h" >&5 +echo "configure:4350: checking for PIOCSET ioctl entry in sys/procfs.h" >&5 if eval "test \"`echo '$''{'gdb_cv_have_procfs_piocset'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -4331,7 +4364,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:4335: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4368: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* gdb_cv_have_procfs_piocset=yes else @@ -4353,7 +4386,7 @@ EOF fi echo $ac_n "checking for main in -lm""... $ac_c" 1>&6 -echo "configure:4357: checking for main in -lm" >&5 +echo "configure:4390: checking for main in -lm" >&5 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4361,14 +4394,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4397,7 +4430,7 @@ fi echo $ac_n "checking for wctype in -lc""... $ac_c" 1>&6 -echo "configure:4401: checking for wctype in -lc" >&5 +echo "configure:4434: checking for wctype in -lc" >&5 ac_lib_var=`echo c'_'wctype | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4405,7 +4438,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4453: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4435,7 +4468,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for wctype in -lw""... $ac_c" 1>&6 -echo "configure:4439: checking for wctype in -lw" >&5 +echo "configure:4472: checking for wctype in -lw" >&5 ac_lib_var=`echo w'_'wctype | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4443,7 +4476,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lw $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4486,12 +4519,12 @@ fi echo $ac_n "checking for long long support in compiler""... $ac_c" 1>&6 -echo "configure:4490: checking for long long support in compiler" >&5 +echo "configure:4523: checking for long long support in compiler" >&5 if eval "test \"`echo '$''{'gdb_cv_c_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4538: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* gdb_cv_c_long_long=yes else @@ -4523,7 +4556,7 @@ fi echo $ac_n "checking for long long support in printf""... $ac_c" 1>&6 -echo "configure:4527: checking for long long support in printf" >&5 +echo "configure:4560: checking for long long support in printf" >&5 if eval "test \"`echo '$''{'gdb_cv_printf_has_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4531,7 +4564,7 @@ else gdb_cv_printf_has_long_long=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4582: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then gdb_cv_printf_has_long_long=yes else @@ -4569,19 +4602,19 @@ echo "$ac_t""$gdb_cv_printf_has_long_long" 1>&6 echo $ac_n "checking for long double support in compiler""... $ac_c" 1>&6 -echo "configure:4573: checking for long double support in compiler" >&5 +echo "configure:4606: checking for long double support in compiler" >&5 if eval "test \"`echo '$''{'ac_cv_c_long_double'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4618: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_long_double=yes else @@ -4603,7 +4636,7 @@ fi echo $ac_n "checking for long double support in printf""... $ac_c" 1>&6 -echo "configure:4607: checking for long double support in printf" >&5 +echo "configure:4640: checking for long double support in printf" >&5 if eval "test \"`echo '$''{'gdb_cv_printf_has_long_double'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4611,7 +4644,7 @@ else gdb_cv_printf_has_long_double=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then gdb_cv_printf_has_long_double=yes else @@ -4645,7 +4678,7 @@ echo "$ac_t""$gdb_cv_printf_has_long_double" 1>&6 echo $ac_n "checking for long double support in scanf""... $ac_c" 1>&6 -echo "configure:4649: checking for long double support in scanf" >&5 +echo "configure:4682: checking for long double support in scanf" >&5 if eval "test \"`echo '$''{'gdb_cv_scanf_has_long_double'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4653,7 +4686,7 @@ else gdb_cv_scanf_has_long_double=no else cat > conftest.$ac_ext < 3.14159 && f < 3.14160); } EOF -if { (eval echo configure:4667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4700: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then gdb_cv_scanf_has_long_double=yes else @@ -4689,17 +4722,17 @@ for ac_hdr in unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4693: checking for $ac_hdr" >&5 +echo "configure:4726: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4703: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4736: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4728,12 +4761,12 @@ done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4732: checking for $ac_func" >&5 +echo "configure:4765: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4793: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4781,7 +4814,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:4785: checking for working mmap" >&5 +echo "configure:4818: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4789,7 +4822,7 @@ else ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:4966: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else @@ -4958,7 +4991,7 @@ if test ${build} = ${host} -a ${host} = ${target} ; then case ${host_os} in hpux*) echo $ac_n "checking for HPUX/OSF thread support""... $ac_c" 1>&6 -echo "configure:4962: checking for HPUX/OSF thread support" >&5 +echo "configure:4995: checking for HPUX/OSF thread support" >&5 if test -f /usr/include/dce/cma_config.h ; then if test "$GCC" = "yes" ; then echo "$ac_t""yes" 1>&6 @@ -4977,7 +5010,7 @@ EOF ;; solaris*) echo $ac_n "checking for Solaris thread debugging library""... $ac_c" 1>&6 -echo "configure:4981: checking for Solaris thread debugging library" >&5 +echo "configure:5014: checking for Solaris thread debugging library" >&5 if test -f /usr/lib/libthread_db.so.1 ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF @@ -4987,7 +5020,7 @@ EOF CONFIG_OBS="${CONFIG_OBS} sol-thread.o" CONFIG_SRCS="${CONFIG_SRCS} sol-thread.c" echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:4991: checking for dlopen in -ldl" >&5 +echo "configure:5024: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4995,7 +5028,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5038,17 +5071,17 @@ fi # all symbols visible in the dynamic symbol table. hold_ldflags=$LDFLAGS echo $ac_n "checking for the ld -export-dynamic flag""... $ac_c" 1>&6 -echo "configure:5042: checking for the ld -export-dynamic flag" >&5 +echo "configure:5075: checking for the ld -export-dynamic flag" >&5 LDFLAGS="${LDFLAGS} -Wl,-export-dynamic" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* found=yes else @@ -5067,13 +5100,13 @@ rm -f conftest* # Sun randomly tweaked the prototypes in # at one point. echo $ac_n "checking if is old""... $ac_c" 1>&6 -echo "configure:5071: checking if is old" >&5 +echo "configure:5104: checking if is old" >&5 if eval "test \"`echo '$''{'gdb_cv_proc_service_is_old'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -5084,7 +5117,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:5088: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5121: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* gdb_cv_proc_service_is_old=no else @@ -5230,12 +5263,12 @@ fi # In the Cygwin environment, we need some additional flags. echo $ac_n "checking for cygwin""... $ac_c" 1>&6 -echo "configure:5357: checking for cygwin" >&5 +echo "configure:5390: checking for cygwin" >&5 if eval "test \"`echo '$''{'gdb_cv_os_cygwin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 -echo "configure:5396: checking for tgetent in -lncurses" >&5 +echo "configure:5429: checking for tgetent in -lncurses" >&5 ac_lib_var=`echo ncurses'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5277,7 +5310,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lncurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5307,7 +5340,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -lHcurses""... $ac_c" 1>&6 -echo "configure:5434: checking for tgetent in -lHcurses" >&5 +echo "configure:5467: checking for tgetent in -lHcurses" >&5 ac_lib_var=`echo Hcurses'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5315,7 +5348,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lHcurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5486: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5345,7 +5378,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -ltermlib""... $ac_c" 1>&6 -echo "configure:5472: checking for tgetent in -ltermlib" >&5 +echo "configure:5505: checking for tgetent in -ltermlib" >&5 ac_lib_var=`echo termlib'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5353,7 +5386,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ltermlib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5524: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5383,7 +5416,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6 -echo "configure:5510: checking for tgetent in -ltermcap" >&5 +echo "configure:5543: checking for tgetent in -ltermcap" >&5 ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5391,7 +5424,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ltermcap $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5562: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5421,7 +5454,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -lcurses""... $ac_c" 1>&6 -echo "configure:5548: checking for tgetent in -lcurses" >&5 +echo "configure:5581: checking for tgetent in -lcurses" >&5 ac_lib_var=`echo curses'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5429,7 +5462,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5600: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5459,7 +5492,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -lterminfo""... $ac_c" 1>&6 -echo "configure:5586: checking for tgetent in -lterminfo" >&5 +echo "configure:5619: checking for tgetent in -lterminfo" >&5 ac_lib_var=`echo terminfo'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5467,7 +5500,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lterminfo $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5638: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5530,7 +5563,7 @@ fi # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 -echo "configure:6741: checking for X" >&5 +echo "configure:6774: checking for X" >&5 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then @@ -5592,12 +5625,12 @@ if test "$ac_x_includes" = NO; then # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6808: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6841: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5666,14 +5699,14 @@ if test "$ac_x_libraries" = NO; then ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. @@ -5953,12 +5986,12 @@ fi echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 -echo "configure:7235: checking for Cygwin environment" >&5 +echo "configure:7268: checking for Cygwin environment" >&5 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7284: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cygwin=yes else @@ -5986,19 +6019,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6 CYGWIN= test "$ac_cv_cygwin" = yes && CYGWIN=yes echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 -echo "configure:7268: checking for mingw32 environment" >&5 +echo "configure:7301: checking for mingw32 environment" >&5 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7313: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_mingw32=yes else @@ -6017,7 +6050,7 @@ test "$ac_cv_mingw32" = yes && MINGW32=yes echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:7299: checking for executable suffix" >&5 +echo "configure:7332: checking for executable suffix" >&5 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6027,7 +6060,7 @@ else rm -f conftest* echo 'int main () { return 0; }' > conftest.$ac_ext ac_cv_exeext= - if { (eval echo configure:7309: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + if { (eval echo configure:7342: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then for file in conftest.*; do case $file in *.c | *.o | *.obj | *.ilk | *.pdb) ;; diff --git a/gdb/configure.in b/gdb/configure.in index 55ded716bf5..8435420a91a 100644 --- a/gdb/configure.in +++ b/gdb/configure.in @@ -92,6 +92,24 @@ AC_C_CONST AC_CHECK_FUNCS(setpgid sbrk sigaction isascii bzero bcopy btowc poll sigprocmask) AC_FUNC_ALLOCA +dnl See if ptrace.h provides the PTRACE_GETXFPREGS request. +dnl PTRACE_GETXFPREGS is a Cygnus invention, since we wrote our own +dnl Linux kernel patch for SSE support. That patch may or may not +dnl actually make it into the official distribution. If you find that +dnl years have gone by since this configure test was added, and Linux +dnl isn't using PTRACE_GETXFPREGS, that means that our patch didn't +dnl make it, and you can delete this code. +AC_MSG_CHECKING(for PTRACE_GETXFPREGS) +AC_CACHE_VAL(gdb_cv_have_ptrace_getxfpregs, +[AC_TRY_COMPILE([#include ], + [PTRACE_GETXFPREGS;], + [gdb_cv_have_ptrace_getxfpregs=yes], + [gdb_cv_have_ptrace_getxfpregs=no])]) +AC_MSG_RESULT($gdb_cv_have_ptrace_getxfpregs) +if test $gdb_cv_have_ptrace_getxfpregs = yes; then + AC_DEFINE(HAVE_PTRACE_GETXFPREGS) +fi + AC_CHECK_LIB(socket, socketpair) AC_CHECK_FUNCS(socketpair) diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index d55050ff2d4..e714e325177 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -89,9 +89,10 @@ READLINE_DEP = $$(READLINE_DIR) # All the includes used for CFLAGS and for lint. # -I. for config files. +# -I.. for gdb's config files (especially config.h) # -I${srcdir} possibly for regex.h also. # -I${srcdir}/config for more generic config files. -INCLUDE_CFLAGS = -I. -I${srcdir} -I${srcdir}/.. -I${srcdir}/../config -I$(INCLUDE_DIR) +INCLUDE_CFLAGS = -I. -I.. -I${srcdir} -I${srcdir}/.. -I${srcdir}/../config -I$(INCLUDE_DIR) # M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS # from the config/ directory. @@ -103,7 +104,7 @@ GLOBAL_CFLAGS = ${MT_CFLAGS} ${MH_CFLAGS} CFLAGS = -g # INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros. INTERNAL_CFLAGS = ${CFLAGS} ${GLOBAL_CFLAGS} ${PROFILE_CFLAGS} \ - ${BFD_CFLAGS} ${INCLUDE_CFLAGS} + ${INCLUDE_CFLAGS} ${BFD_CFLAGS} -DGDBSERVER # LDFLAGS is specifically reserved for setting from the command line # when running make. diff --git a/gdb/gdbserver/gdbreplay.c b/gdb/gdbserver/gdbreplay.c index 577396222f7..9e88a75659e 100644 --- a/gdb/gdbserver/gdbreplay.c +++ b/gdb/gdbserver/gdbreplay.c @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "config.h" #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include /* Sort of a hack... */ #define EOL (EOF - 1) @@ -42,10 +44,12 @@ void perror_with_name (string) char *string; { +#ifndef STDC_HEADERS extern int sys_nerr; extern char *sys_errlist[]; extern int errno; - char *err; +#endif + const char *err; char *combined; err = (errno < sys_nerr) ? sys_errlist[errno] : "unknown error"; diff --git a/gdb/gdbserver/low-hppabsd.c b/gdb/gdbserver/low-hppabsd.c index 3c28a3895d3..7c1b6603d69 100644 --- a/gdb/gdbserver/low-hppabsd.c +++ b/gdb/gdbserver/low-hppabsd.c @@ -34,7 +34,8 @@ /***************Begin MY defs*********************/ int quit_flag = 0; -char registers[REGISTER_BYTES]; +static char my_registers[REGISTER_BYTES]; +char *registers = my_registers; /* Index within `registers' of the first byte of the space for register N. */ diff --git a/gdb/gdbserver/low-linux.c b/gdb/gdbserver/low-linux.c index 32f10a13f13..b17e7558e42 100644 --- a/gdb/gdbserver/low-linux.c +++ b/gdb/gdbserver/low-linux.c @@ -26,17 +26,16 @@ #include #include #include +#include #include #include #include -#if 0 -#include -#endif #include /***************Begin MY defs*********************/ int quit_flag = 0; -char registers[REGISTER_BYTES]; +static char my_registers[REGISTER_BYTES]; +char *registers = my_registers; /* Index within `registers' of the first byte of the space for register N. */ @@ -45,12 +44,15 @@ char registers[REGISTER_BYTES]; char buf2[MAX_REGISTER_RAW_SIZE]; /***************End MY defs*********************/ -#include - -#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) +#ifdef HAVE_SYS_REG_H #include #endif +/* Default the type of the ptrace transfer to int. */ +#ifndef PTRACE_XFER_TYPE +#define PTRACE_XFER_TYPE int +#endif + extern char **environ; extern int errno; extern int inferior_pid; @@ -167,7 +169,42 @@ myresume (step, signal) - KERNEL_U_ADDR #endif -#ifndef TARGET_M68K +#ifdef I386_GNULINUX_TARGET +/* i386_register_raw_size[i] is the number of bytes of storage in the + actual machine representation for register i. */ +int i386_register_raw_size[MAX_NUM_REGS] = { + 4, 4, 4, 4, + 4, 4, 4, 4, + 4, 4, 4, 4, + 4, 4, 4, 4, + 10, 10, 10, 10, + 10, 10, 10, 10, + 4, 4, 4, 4, + 4, 4, 4, 4, + 16, 16, 16, 16, + 16, 16, 16, 16, + 4 +}; + +int i386_register_byte[MAX_NUM_REGS]; + +static void +initialize_arch() +{ + /* Initialize the table saying where each register starts in the + register file. */ + { + int i, offset; + + offset = 0; + for (i = 0; i < MAX_NUM_REGS; i++) + { + i386_register_byte[i] = offset; + offset += i386_register_raw_size[i]; + } + } +} + /* this table must line up with REGISTER_NAMES in tm-i386v.h */ /* symbols like 'EAX' come from */ static int regmap[] = @@ -201,7 +238,13 @@ i386_register_u_addr (blockend, regnum) return (blockend + 4 * regmap[regnum]); } -#else /* TARGET_M68K */ +#elif defined(TARGET_M68K) +static void +initialize_arch() +{ + return; +} + /* This table must line up with REGISTER_NAMES in tm-m68k.h */ static int regmap[] = { @@ -231,6 +274,256 @@ m68k_linux_register_u_addr (blockend, regnum) { return (blockend + 4 * regmap[regnum]); } +/* start-sanitize-ia64 */ +#elif defined(IA64_GNULINUX_TARGET) +#undef NUM_FREGS +#define NUM_FREGS 0 + +#include + +static int u_offsets[] = + { + /* general registers */ + -1, /* gr0 not available; i.e, it's always zero */ + PT_R1, + PT_R2, + PT_R3, + PT_R4, + PT_R5, + PT_R6, + PT_R7, + PT_R8, + PT_R9, + PT_R10, + PT_R11, + PT_R12, + PT_R13, + PT_R14, + PT_R15, + PT_R16, + PT_R17, + PT_R18, + PT_R19, + PT_R20, + PT_R21, + PT_R22, + PT_R23, + PT_R24, + PT_R25, + PT_R26, + PT_R27, + PT_R28, + PT_R29, + PT_R30, + PT_R31, + /* gr32 through gr127 not directly available via the ptrace interface */ + -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, + -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, + /* Floating point registers */ + -1, -1, /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0) */ + PT_F2, + PT_F3, + PT_F4, + PT_F5, + PT_F6, + PT_F7, + PT_F8, + PT_F9, + PT_F10, + PT_F11, + PT_F12, + PT_F13, + PT_F14, + PT_F15, + PT_F16, + PT_F17, + PT_F18, + PT_F19, + PT_F20, + PT_F21, + PT_F22, + PT_F23, + PT_F24, + PT_F25, + PT_F26, + PT_F27, + PT_F28, + PT_F29, + PT_F30, + PT_F31, + PT_F32, + PT_F33, + PT_F34, + PT_F35, + PT_F36, + PT_F37, + PT_F38, + PT_F39, + PT_F40, + PT_F41, + PT_F42, + PT_F43, + PT_F44, + PT_F45, + PT_F46, + PT_F47, + PT_F48, + PT_F49, + PT_F50, + PT_F51, + PT_F52, + PT_F53, + PT_F54, + PT_F55, + PT_F56, + PT_F57, + PT_F58, + PT_F59, + PT_F60, + PT_F61, + PT_F62, + PT_F63, + PT_F64, + PT_F65, + PT_F66, + PT_F67, + PT_F68, + PT_F69, + PT_F70, + PT_F71, + PT_F72, + PT_F73, + PT_F74, + PT_F75, + PT_F76, + PT_F77, + PT_F78, + PT_F79, + PT_F80, + PT_F81, + PT_F82, + PT_F83, + PT_F84, + PT_F85, + PT_F86, + PT_F87, + PT_F88, + PT_F89, + PT_F90, + PT_F91, + PT_F92, + PT_F93, + PT_F94, + PT_F95, + PT_F96, + PT_F97, + PT_F98, + PT_F99, + PT_F100, + PT_F101, + PT_F102, + PT_F103, + PT_F104, + PT_F105, + PT_F106, + PT_F107, + PT_F108, + PT_F109, + PT_F110, + PT_F111, + PT_F112, + PT_F113, + PT_F114, + PT_F115, + PT_F116, + PT_F117, + PT_F118, + PT_F119, + PT_F120, + PT_F121, + PT_F122, + PT_F123, + PT_F124, + PT_F125, + PT_F126, + PT_F127, + /* branch registers */ + PT_B0, + PT_B1, + PT_B2, + PT_B3, + PT_B4, + PT_B5, + PT_B6, + PT_B7, + /* other registers */ + PT_PR, + PT_CR_IIP, + PT_CR_IPSR, + /* kernel registers not visible via ptrace interface (?) */ + -1, -1, -1, -1, -1, -1, -1, -1, + /* hole */ + -1, -1, -1, -1, -1, -1, -1, -1, + PT_AR_RSC, + PT_AR_BSP, + PT_AR_BSPSTORE, + PT_AR_RNAT, + -1, + -1, /* Not available: FCR, IA32 floating control register */ + -1, -1, + -1, /* Not available: EFLAG */ + -1, /* Not available: CSD */ + -1, /* Not available: SSD */ + -1, /* Not available: CFLG */ + -1, /* Not available: FSR */ + -1, /* Not available: FIR */ + -1, /* Not available: FDR */ + -1, + PT_AR_CCV, + -1, -1, -1, + PT_AR_UNAT, + -1, -1, -1, + PT_AR_FPSR, + -1, -1, -1, + -1, /* Not available: ITC */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, + PT_AR_PFS, + PT_AR_LC, + -1, /* Not available: EC, the Epilog Count register */ + -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, + }; + +int +ia64_register_u_addr (int blockend, int regnum) +{ + int addr; + + if (regnum < 0 || regnum >= NUM_REGS) + error ("Invalid register number %d.", regnum); + + addr = u_offsets[regnum]; + if (addr == -1) + addr = 0; + + return addr; +} + +initialize_arch() +{ + return; +} +/* end-sanitize-ia64 */ #endif CORE_ADDR @@ -254,7 +547,7 @@ static void fetch_register (regno) int regno; { - register unsigned int regaddr; + CORE_ADDR regaddr; register int i; /* Offset of registers within the u area. */ @@ -263,12 +556,12 @@ fetch_register (regno) offset = U_REGS_OFFSET; regaddr = register_addr (regno, offset); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) { errno = 0; - *(int *) ®isters[regno * 4 + i] = ptrace (PTRACE_PEEKUSR, inferior_pid, - (PTRACE_ARG3_TYPE) regaddr, 0); - regaddr += sizeof (int); + *(PTRACE_XFER_TYPE *) ®isters[REGISTER_BYTE (regno) + i] = + ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0); + regaddr += sizeof (PTRACE_XFER_TYPE); if (errno != 0) { /* Warning, not error, in case we are attached; sometimes the @@ -304,8 +597,8 @@ void store_inferior_registers (regno) int regno; { - register unsigned int regaddr; - register int i; + CORE_ADDR regaddr; + int i; unsigned int offset = U_REGS_OFFSET; if (regno >= 0) @@ -335,7 +628,7 @@ store_inferior_registers (regno) for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) { errno = 0; - ptrace (PTRACE_POKEUSR, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, + ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, *(int *) ®isters[REGISTER_BYTE (regno) + i]); if (errno != 0) { @@ -373,21 +666,23 @@ read_inferior_memory (memaddr, myaddr, len) { register int i; /* Round starting address down to longword boundary. */ - register CORE_ADDR addr = memaddr & -sizeof (int); + register CORE_ADDR addr = memaddr & -sizeof (PTRACE_XFER_TYPE); /* Round ending address up; get number of longwords that makes. */ - register int count - = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); + register int count + = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) + / sizeof (PTRACE_XFER_TYPE); /* Allocate buffer of that many longwords. */ - register int *buffer = (int *) alloca (count * sizeof (int)); + register PTRACE_XFER_TYPE *buffer + = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); /* Read all the longwords */ - for (i = 0; i < count; i++, addr += sizeof (int)) + for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0); } /* Copy appropriate bytes out of the buffer. */ - memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len); + memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len); } /* Copy LEN bytes of data from debugger memory at MYADDR @@ -403,12 +698,12 @@ write_inferior_memory (memaddr, myaddr, len) { register int i; /* Round starting address down to longword boundary. */ - register CORE_ADDR addr = memaddr & -sizeof (int); + register CORE_ADDR addr = memaddr & -sizeof (PTRACE_XFER_TYPE); /* Round ending address up; get number of longwords that makes. */ register int count - = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); + = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE); /* Allocate buffer of that many longwords. */ - register int *buffer = (int *) alloca (count * sizeof (int)); + register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); extern int errno; /* Fill start and end extra bytes of buffer with existing memory data. */ @@ -419,16 +714,16 @@ write_inferior_memory (memaddr, myaddr, len) { buffer[count - 1] = ptrace (PTRACE_PEEKTEXT, inferior_pid, - addr + (count - 1) * sizeof (int), 0); + addr + (count - 1) * sizeof (PTRACE_XFER_TYPE), 0); } /* Copy data to be written over corresponding part of buffer */ - memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); + memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len); /* Write the entire buffer. */ - for (i = 0; i < count; i++, addr += sizeof (int)) + for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { errno = 0; ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]); @@ -443,6 +738,7 @@ void initialize () { inferior_pid = 0; + initialize_arch(); } int diff --git a/gdb/gdbserver/low-lynx.c b/gdb/gdbserver/low-lynx.c index ecc331811c9..75e11ba050a 100644 --- a/gdb/gdbserver/low-lynx.c +++ b/gdb/gdbserver/low-lynx.c @@ -44,7 +44,8 @@ #include #include -char registers[REGISTER_BYTES]; +static char my_registers[REGISTER_BYTES]; +char *registers = my_registers; #include diff --git a/gdb/gdbserver/low-sim.c b/gdb/gdbserver/low-sim.c index ebd5f7d21e7..3f9dea26ee9 100644 --- a/gdb/gdbserver/low-sim.c +++ b/gdb/gdbserver/low-sim.c @@ -28,7 +28,8 @@ extern int remote_debug; extern host_callback default_callback; /* in sim/common/callback.c */ -char registers[REGISTER_BYTES] __attribute__ ((aligned)); +static char my_registers[REGISTER_BYTES] __attribute__ ((aligned)); +char * registers = my_registers; int target_byte_order; /* used by simulator */ diff --git a/gdb/gdbserver/low-sparc.c b/gdb/gdbserver/low-sparc.c index 9dd70a25079..e0e635e5bd0 100644 --- a/gdb/gdbserver/low-sparc.c +++ b/gdb/gdbserver/low-sparc.c @@ -37,7 +37,8 @@ /***************Begin MY defs*********************/ int quit_flag = 0; -char registers[REGISTER_BYTES]; +static char my_registers[REGISTER_BYTES]; +char *registers = my_registers; /* Index within `registers' of the first byte of the space for register N. */ diff --git a/gdb/gdbserver/low-sun3.c b/gdb/gdbserver/low-sun3.c index 11f1d8ac238..786770b9a55 100644 --- a/gdb/gdbserver/low-sun3.c +++ b/gdb/gdbserver/low-sun3.c @@ -34,7 +34,8 @@ /***************Begin MY defs*********************/ int quit_flag = 0; -char registers[REGISTER_BYTES]; +static char my_registers[REGISTER_BYTES]; +char *registers = my_registers; /* Index within `registers' of the first byte of the space for register N. */ diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index 4dab2abb8d5..cd078ccddc9 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -201,7 +201,7 @@ putpkt (buf) { int i; unsigned char csum = 0; - char buf2[2000]; + char buf2[PBUFSIZ]; char buf3[1]; int cnt = strlen (buf); char *p; @@ -435,10 +435,13 @@ outreg (regno, buf) int regno; char *buf; { - extern char registers[]; int regsize = REGISTER_RAW_SIZE (regno); - *buf++ = tohex (regno >> 4); + if ((regno >> 12) != 0) + *buf++ = tohex ((regno >> 12) & 0xf); + if ((regno >> 8) != 0) + *buf++ = tohex ((regno >> 8) & 0xf); + *buf++ = tohex ((regno >> 4) & 0xf); *buf++ = tohex (regno & 0xf); *buf++ = ':'; convert_int_to_ascii (®isters[REGISTER_BYTE (regno)], buf, regsize); @@ -469,6 +472,18 @@ prepare_resume_reply (buf, status, signo) if (status == 'T') { +#ifdef GDBSERVER_RESUME_REGS + static int gdbserver_resume_regs[] = GDBSERVER_RESUME_REGS ; + int i; + for (i = 0; + i < sizeof (gdbserver_resume_regs) + / sizeof (gdbserver_resume_regs[0]); + i++) + { + int regnum = gdbserver_resume_regs[i]; + buf = outreg (regnum, buf); + } +#else /* !defined(GDBSERVER_RESUME_REGS) */ buf = outreg (PC_REGNUM, buf); buf = outreg (FP_REGNUM, buf); buf = outreg (SP_REGNUM, buf); @@ -478,6 +493,7 @@ prepare_resume_reply (buf, status, signo) #ifdef O7_REGNUM buf = outreg (O7_REGNUM, buf); #endif +#endif /* GDBSERVER_RESUME_REGS */ /* If the debugger hasn't used any thread features, don't burden it with threads. If we didn't check this, GDB 4.13 and older would choke. */ diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 66afb888efd..8b18f533836 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -47,7 +47,7 @@ main (argc, argv) int argc; char *argv[]; { - char ch, status, own_buf[2000], mem_buf[2000]; + char ch, status, own_buf[PBUFSIZ], mem_buf[2000]; int i = 0; unsigned char signal; unsigned int len; diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index bfc89c7bbb7..c42a65c6c8f 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -36,7 +36,7 @@ int create_inferior (); /* Target-specific variables */ -extern char registers[]; +extern char *registers; /* Public variables in server.c */ @@ -71,3 +71,14 @@ void decode_M_packet PARAMS ((char *from, CORE_ADDR * mem_addr_ptr, /* Functions from utils.c */ void perror_with_name PARAMS ((char *string)); + + +/* Maximum number of bytes to read/write at once. The value here + is chosen to fill up a packet (the headers account for the 32). */ +#define MAXBUFBYTES(N) (((N)-32)/2) + +/* Buffer sizes for transferring memory, registers, etc. Round up PBUFSIZ to + hold all the registers, at least. */ +#define PBUFSIZ ((REGISTER_BYTES > MAXBUFBYTES (2000)) \ + ? (REGISTER_BYTES * 2 + 32) \ + : 2000) diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c index ecff057ac48..2603beb3ef7 100644 --- a/gdb/gdbserver/utils.c +++ b/gdb/gdbserver/utils.c @@ -32,10 +32,12 @@ void perror_with_name (string) char *string; { +#ifndef STDC_HEADERS extern int sys_nerr; extern char *sys_errlist[]; extern int errno; - char *err; +#endif + const char *err; char *combined; if (errno < sys_nerr) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index ffed1e6e2e8..e8917d06855 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -658,7 +658,8 @@ init_simd_type (char *name, memset (f, 0, sizeof (*f)); f->loc.bitpos = 0; f->type = create_array_type (0, elt_type, - create_range_type (0, builtin_type_int, 0, n)); + create_range_type (0, builtin_type_int, + 0, n-1)); f->name = elt_name; /* Build a struct type with that field. */ diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c index 12fbe3e280c..65731533271 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -45,6 +45,35 @@ static int regmap[] = }; +/* Which ptrace request retrieves which registers? + These apply to the corresponding SET requests as well. */ +#define GETREGS_SUPPLIES(regno) \ + (0 <= (regno) && (regno) <= 15) +#define GETFPREGS_SUPPLIES(regno) \ + (FP0_REGNUM <= (regno) && (regno) <= LAST_FPU_CTRL_REGNUM) +#define GETXFPREGS_SUPPLIES(regno) \ + (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM) + +/* Does the current host support the GETXFPREGS request? The header + file may or may not define it, and even if it is defined, the + kernel will return EIO if it's running on a pre-SSE processor. + + My instinct is to attach this to some architecture- or + target-specific data structure, but really, a particular GDB + process can only run on top of one kernel at a time. So it's okay + for this to be a simple variable. */ +int have_ptrace_getxfpregs = +#ifdef HAVE_PTRACE_GETXFPREGS + 1 +#else + 0 +#endif +; + + + +/* Transfering the general registers between GDB, inferiors and core files. */ + /* Given a pointer to a general register set in struct user format (gregset_t *), unpack the register contents and supply them as gdb's idea of the current register values. */ @@ -61,6 +90,7 @@ supply_gregset (gregsetp) } } + /* Fill in a gregset_t object with selected data from a gdb-format register file. - GREGSETP points to the gregset_t object to be filled. @@ -82,6 +112,9 @@ convert_to_gregset (gregset_t *gregsetp, *(regp + regmap[regi]) = * (int *) ®isters[REGISTER_BYTE (regi)]; } + +/* Store GDB's value for REGNO in *GREGSETP. If REGNO is -1, do all + of them. */ void fill_gregset (gregset_t *gregsetp, int regno) @@ -98,8 +131,56 @@ fill_gregset (gregset_t *gregsetp, } -/* Where does st(N) start in the fpregset_t structure F? */ -#define FPREGSET_T_FPREG_OFFSET(f, n) \ +/* Read the general registers from the process, and store them + in registers[]. */ +static void +fetch_regs () +{ + int ret, regno; + gregset_t buf; + + ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int) &buf); + if (ret < 0) + { + warning ("Couldn't get registers"); + return; + } + + supply_gregset (&buf); +} + + +/* Set the inferior's general registers to the values in registers[] + --- but only those registers marked as valid. */ +static void +store_regs () +{ + int ret, regno; + gregset_t buf; + + ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int) &buf); + if (ret < 0) + { + warning ("Couldn't get registers"); + return; + } + + convert_to_gregset (&buf, registers, register_valid); + + ret = ptrace (PTRACE_SETREGS, inferior_pid, 0, (int)buf); + if (ret < 0) + { + warning ("Couldn't write registers"); + return; + } +} + + + +/* Transfering floating-point registers between GDB, inferiors and cores. */ + +/* What is the address of st(N) within the fpregset_t structure F? */ +#define FPREGSET_T_FPREG_ADDR(f, n) \ ((char *) &(f)->st_space + (n) * 10) /* Fill GDB's register file with the floating-point register values in @@ -111,7 +192,7 @@ supply_fpregset (fpregset_t *fpregsetp) /* Supply the floating-point registers. */ for (i = 0; i < 8; i++) - supply_register (FP0_REGNUM + i, FPREGSET_T_FPREG_OFFSET (fpregsetp, i)); + supply_register (FP0_REGNUM + i, FPREGSET_T_FPREG_ADDR (fpregsetp, i)); supply_register (FCTRL_REGNUM, (char *) &fpregsetp->cwd); supply_register (FSTAT_REGNUM, (char *) &fpregsetp->swd); @@ -151,7 +232,7 @@ convert_to_fpregset (fpregset_t *fpregsetp, /* Fill in the floating-point registers. */ for (i = 0; i < 8; i++) if (!valid || valid[i]) - memcpy (FPREGSET_T_FPREG_OFFSET (fpregsetp, i), + memcpy (FPREGSET_T_FPREG_ADDR (fpregsetp, i), ®isters[REGISTER_BYTE (FP0_REGNUM + i)], REGISTER_RAW_SIZE(FP0_REGNUM + i)); @@ -240,52 +321,191 @@ store_fpregs () } } + +/* Transfering floating-point and SSE registers to and from GDB. */ -/* Read the general registers from the process, and store them - in registers[]. */ + +#ifdef HAVE_PTRACE_GETXFPREGS static void -fetch_regs () +supply_xfpregset (struct user_xfpregs_struct *xfpregs) { - int ret, regno; - gregset_t buf; + int reg; - ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int) &buf); - if (ret < 0) + /* Supply the floating-point registers. */ + for (reg = 0; reg < 8; reg++) + supply_register (FP0_REGNUM + reg, (char *) &xfpregs->st_space[reg]); + + { + supply_register (FCTRL_REGNUM, (char *) &xfpregs->cwd); + supply_register (FSTAT_REGNUM, (char *) &xfpregs->swd); + supply_register (FTAG_REGNUM, (char *) &xfpregs->twd); + supply_register (FCOFF_REGNUM, (char *) &xfpregs->fip); + supply_register (FDS_REGNUM, (char *) &xfpregs->fos); + supply_register (FDOFF_REGNUM, (char *) &xfpregs->foo); + + /* Extract the code segment and opcode from the "fcs" member. */ { - warning ("Couldn't get registers"); - return; - } + long l; + + l = xfpregs->fcs & 0xffff; + supply_register (FCS_REGNUM, (char *) &l); - supply_gregset (&buf); + l = (xfpregs->fcs >> 16) & ((1 << 11) - 1); + supply_register (FOP_REGNUM, (char *) &l); + } + } + + /* Supply the SSE registers. */ + for (reg = 0; reg < 8; reg++) + supply_register (XMM0_REGNUM + reg, (char *) &xfpregs->xmm_space[reg]); + supply_register (MXCSR_REGNUM, (char *) &xfpregs->mxcsr); } -/* Set the inferior's general registers to the values in registers[] - --- but only those registers marked as valid. */ static void -store_regs () +convert_to_xfpregset (struct user_xfpregs_struct *xfpregs, + char *gdb_regs, + signed char *valid) { - int ret, regno; - gregset_t buf; + int reg; - ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int) &buf); - if (ret < 0) - { - warning ("Couldn't get registers"); - return; - } + /* Fill in the floating-point registers. */ + for (reg = 0; reg < 8; reg++) + if (!valid || valid[reg]) + memcpy (&xfpregs->st_space[reg], + ®isters[REGISTER_BYTE (FP0_REGNUM + reg)], + REGISTER_RAW_SIZE(FP0_REGNUM + reg)); - convert_to_gregset (&buf, registers, register_valid); +#define fill(MEMBER, REGNO) \ + if (! valid || valid[(REGNO)]) \ + memcpy (&xfpregs->MEMBER, ®isters[REGISTER_BYTE (REGNO)], \ + sizeof (xfpregs->MEMBER)) - ret = ptrace (PTRACE_SETREGS, inferior_pid, 0, (int)buf); - if (ret < 0) - { - warning ("Couldn't write registers"); - return; - } + fill (cwd, FCTRL_REGNUM); + fill (swd, FSTAT_REGNUM); + fill (twd, FTAG_REGNUM); + fill (fip, FCOFF_REGNUM); + fill (foo, FDOFF_REGNUM); + fill (fos, FDS_REGNUM); + +#undef fill + + if (! valid || valid[FCS_REGNUM]) + xfpregs->fcs + = ((xfpregs->fcs & ~0xffff) + | (* (int *) ®isters[REGISTER_BYTE (FCS_REGNUM)] & 0xffff)); + + if (! valid || valid[FOP_REGNUM]) + xfpregs->fcs + = ((xfpregs->fcs & 0xffff) + | ((*(int *) ®isters[REGISTER_BYTE (FOP_REGNUM)] & ((1 << 11) - 1)) + << 16)); + + /* Fill in the XMM registers. */ + for (reg = 0; reg < 8; reg++) + if (! valid || valid[reg]) + memcpy (&xfpregs->xmm_space[reg], + ®isters[REGISTER_BYTE (XMM0_REGNUM + reg)], + REGISTER_RAW_SIZE (XMM0_REGNUM + reg)); } +/* Make a PTRACE_GETXFPREGS request, and supply all the register + values that yields to GDB. */ +static int +fetch_xfpregs () +{ + int ret; + struct user_xfpregs_struct xfpregs; + + if (! have_ptrace_getxfpregs) + return 0; + + ret = ptrace (PTRACE_GETXFPREGS, inferior_pid, 0, &xfpregs); + if (ret == -1) + { + if (errno == EIO) + { + have_ptrace_getxfpregs = 0; + return 0; + } + + warning ("couldn't read floating-point and SSE registers."); + return 0; + } + + supply_xfpregset (&xfpregs); + return 1; +} + + +/* Send all the valid register values in GDB's register file covered + by the PTRACE_SETXFPREGS request to the inferior. */ +static int +store_xfpregs () +{ + int ret; + struct user_xfpregs_struct xfpregs; + + if (! have_ptrace_getxfpregs) + return 0; + + ret = ptrace (PTRACE_GETXFPREGS, inferior_pid, 0, &xfpregs); + if (ret == -1) + { + if (errno == EIO) + { + have_ptrace_getxfpregs = 0; + return 0; + } + + warning ("couldn't read floating-point and SSE registers."); + return 0; + } + + convert_to_xfpregset (&xfpregs, registers, register_valid); + + if (ptrace (PTRACE_SETXFPREGS, inferior_pid, 0, &xfpregs) < 0) + { + warning ("Couldn't write floating-point and SSE registers."); + return 0; + } + + return 1; +} + + +/* Fill the XMM registers in the register file with dummy values. For + cases where we don't have access to the XMM registers. I think + this is cleaner than printing a warning. For a cleaner solution, + we should gdbarchify the i386 family. */ +static void +dummy_sse_values () +{ + /* C doesn't have a syntax for NaN's, so write it out as an array of + longs. */ + static long dummy[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + static long mxcsr = 0x1f80; + int reg; + + for (reg = 0; reg < 8; reg++) + supply_register (XMM0_REGNUM + reg, (char *) dummy); + supply_register (MXCSR_REGNUM, (char *) &mxcsr); +} + +#else + +/* Stub versions of the above routines, for systems that don't have + PTRACE_GETXFPREGS. */ +static int store_xfpregs () { return 0; } +static int fetch_xfpregs () { return 0; } +static void dummy_sse_values () {} + +#endif + + +/* Transferring arbitrary registers between GDB and inferior. */ + /* Fetch registers from the child process. Fetch all if regno == -1, otherwise fetch all ordinary registers or all floating point registers depending @@ -294,11 +514,42 @@ store_regs () void fetch_inferior_registers (int regno) { - if (regno < NUM_GREGS || regno == -1) - fetch_regs (); + /* Use the xfpregs requests whenever possible, since they transfer + more registers in one system call, and we'll cache the results. + But remember that fetch_xfpregs can fail, and return zero. */ + if (regno == -1) + { + fetch_regs (); + if (fetch_xfpregs ()) + return; + fetch_fpregs (); + return; + } - if (regno >= NUM_GREGS || regno == -1) - fetch_fpregs (); + if (GETREGS_SUPPLIES (regno)) + { + fetch_regs (); + return; + } + + if (GETXFPREGS_SUPPLIES (regno)) + { + if (fetch_xfpregs ()) + return; + + /* Either our processor or our kernel doesn't support the SSE + registers, so read the FP registers in the traditional way, + and fill the SSE registers with dummy values. It would be + more graceful to handle differences in the register set using + gdbarch. Until then, this will at least make things work + plausibly. */ + fetch_fpregs (); + dummy_sse_values (); + return; + } + + internal_error ("i386-linux-nat.c (fetch_inferior_registers): " + "got request for bad register number %d", regno); } @@ -312,14 +563,43 @@ void store_inferior_registers (regno) int regno; { - if (regno < NUM_GREGS || regno == -1) - store_regs (); + /* Use the xfpregs requests whenever possible, since they transfer + more registers in one system call. But remember that + fetch_xfpregs can fail, and return zero. */ + if (regno == -1) + { + store_regs (); + if (store_xfpregs ()) + return; + store_fpregs (); + return; + } - if (regno >= NUM_GREGS || regno == -1) - store_fpregs (); + if (GETREGS_SUPPLIES (regno)) + { + store_regs (); + return; + } + + if (GETXFPREGS_SUPPLIES (regno)) + { + if (store_xfpregs ()) + return; + + /* Either our processor or our kernel doesn't support the SSE + registers, so just write the FP registers in the traditional way. */ + store_fpregs (); + return; + } + + internal_error ("i386-linux-nat.c (store_inferior_registers): " + "got request to store bad register number %d", regno); } + +/* Calling functions in shared libraries. */ + /* Find the minimal symbol named NAME, and return both the minsym struct and its objfile. This probably ought to be in minsym.c, but everything there is trying to deal with things like C++ and diff --git a/gdb/linux-thread.c b/gdb/linux-thread.c index 9f0a80713b4..26e45e04693 100644 --- a/gdb/linux-thread.c +++ b/gdb/linux-thread.c @@ -161,13 +161,13 @@ struct linuxthreads_signal { }; struct linuxthreads_signal linuxthreads_sig_restart = { - "__pthread_sig_restart", 1, 0, 0, 0 + "__pthread_sig_restart", 1, 0, 0, 0, 0 }; struct linuxthreads_signal linuxthreads_sig_cancel = { - "__pthread_sig_cancel", 1, 0, 0, 0 + "__pthread_sig_cancel", 1, 0, 0, 0, 0 }; struct linuxthreads_signal linuxthreads_sig_debug = { - "__pthread_sig_debug", 0, 0, 0, 0 + "__pthread_sig_debug", 0, 0, 0, 0, 0 }; /* A table of breakpoint locations, one per PID. */ @@ -336,10 +336,12 @@ linuxthreads_find_trap (pid, stop) else if (WSTOPSIG(status) != SIGSTOP) wstatus[last++] = status; else if (stop) - if (found_trap) - break; - else - found_stop = 1; + { + if (found_trap) + break; + else + found_stop = 1; + } } /* Resend any other signals we noticed to the thread, to be received @@ -651,10 +653,12 @@ resume_thread (pid) if (pid != inferior_pid && in_thread_list (pid) && linuxthreads_thread_alive (pid)) - if (pid == linuxthreads_step_pid) - child_resume (pid, 1, linuxthreads_step_signo); - else - child_resume (pid, 0, TARGET_SIGNAL_0); + { + if (pid == linuxthreads_step_pid) + child_resume (pid, 1, linuxthreads_step_signo); + else + child_resume (pid, 0, TARGET_SIGNAL_0); + } } /* Detach a thread */ @@ -679,21 +683,23 @@ stop_thread (pid) int pid; { if (pid != inferior_pid) - if (in_thread_list (pid)) - kill (pid, SIGSTOP); - else if (ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0) == 0) - { - if (!linuxthreads_attach_pending) - printf_unfiltered ("[New %s]\n", target_pid_to_str (pid)); - add_thread (pid); - if (linuxthreads_sig_debug.signal) - /* After a new thread in glibc 2.1 signals gdb its existence, - it suspends itself and wait for linuxthreads_sig_restart, - now we can wake up it. */ - kill (pid, linuxthreads_sig_restart.signal); - } - else - perror_with_name ("ptrace in stop_thread"); + { + if (in_thread_list (pid)) + kill (pid, SIGSTOP); + else if (ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0) == 0) + { + if (!linuxthreads_attach_pending) + printf_unfiltered ("[New %s]\n", target_pid_to_str (pid)); + add_thread (pid); + if (linuxthreads_sig_debug.signal) + /* After a new thread in glibc 2.1 signals gdb its existence, + it suspends itself and wait for linuxthreads_sig_restart, + now we can wake up it. */ + kill (pid, linuxthreads_sig_restart.signal); + } + else + perror_with_name ("ptrace in stop_thread"); + } } /* Wait for a thread */ @@ -1284,10 +1290,12 @@ linuxthreads_wait (pid, ourstatus) if (rpid > 0) break; if (rpid < 0) - if (errno == EINTR) - continue; - else if (save_errno != 0) - break; + { + if (errno == EINTR) + continue; + else if (save_errno != 0) + break; + } sigsuspend(&omask); } @@ -1364,10 +1372,12 @@ linuxthreads_wait (pid, ourstatus) { /* Skip SIGSTOP signals. */ if (!linuxthreads_pending_status (rpid)) - if (linuxthreads_step_pid == rpid) - child_resume (rpid, 1, linuxthreads_step_signo); - else - child_resume (rpid, 0, TARGET_SIGNAL_0); + { + if (linuxthreads_step_pid == rpid) + child_resume (rpid, 1, linuxthreads_step_signo); + else + child_resume (rpid, 0, TARGET_SIGNAL_0); + } continue; } diff --git a/gdb/objfiles.h b/gdb/objfiles.h index f2c217822c8..98d45751e78 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -361,7 +361,7 @@ struct objfile int num_sections; /* These pointers are used to locate the section table, which - among other thigs, is used to map pc addresses into sections. + among other things, is used to map pc addresses into sections. SECTIONS points to the first entry in the table, and SECTIONS_END points to the first location past the last entry in the table. Currently the table is stored on the diff --git a/gdb/rdi-share/Makefile.am b/gdb/rdi-share/Makefile.am index 9d63d1c6486..4dd71d89d0d 100644 --- a/gdb/rdi-share/Makefile.am +++ b/gdb/rdi-share/Makefile.am @@ -4,15 +4,15 @@ AUTOMAKE_OPTIONS = cygnus noinst_LIBRARIES = libangsd.a -libangsd_a_SOURCES = ardi.c bytesex.c crc.c devsw.c drivers.c etherdrv.c \ - hostchan.c hsys.c logging.c msgbuild.c params.c rx.c \ - serdrv.c serpardr.c tx.c unixcomm.c +libangsd_a_SOURCES = ardi.c angel_bytesex.c crc.c devsw.c drivers.c etherdrv.c \ + hostchan.c hsys.c logging.c msgbuild.c params.c rx.c \ + serdrv.c serpardr.c tx.c unixcomm.c -noinst_HEADERS = adp.h adperr.h angel.h ardi.h armdbg.h buffers.h bytesex.h \ +noinst_HEADERS = adp.h adperr.h angel.h ardi.h armdbg.h buffers.h \ chandefs.h channels.h chanpriv.h crc.h dbg_conf.h dbg_cp.h \ dbg_hif.h dbg_rdi.h devclnt.h devices.h devsw.h drivers.h \ - endian.h ethernet.h host.h hostchan.h hsys.h logging.h \ - msgbuild.h params.h rxtx.h sys.h unixcomm.h + angel_endian.h ethernet.h host.h hostchan.h hsys.h logging.h \ + msgbuild.h params.h rxtx.h sys.h unixcomm.h angel_bytesex.h EXTRA_DIST = README.CYGNUS diff --git a/gdb/rdi-share/Makefile.in b/gdb/rdi-share/Makefile.in index 33274dac7a7..a24e1afb9bb 100644 --- a/gdb/rdi-share/Makefile.in +++ b/gdb/rdi-share/Makefile.in @@ -70,15 +70,15 @@ AUTOMAKE_OPTIONS = cygnus noinst_LIBRARIES = libangsd.a -libangsd_a_SOURCES = ardi.c bytesex.c crc.c devsw.c drivers.c etherdrv.c \ - hostchan.c hsys.c logging.c msgbuild.c params.c rx.c \ - serdrv.c serpardr.c tx.c unixcomm.c +libangsd_a_SOURCES = ardi.c angel_bytesex.c crc.c devsw.c drivers.c etherdrv.c \ + hostchan.c hsys.c logging.c msgbuild.c params.c rx.c \ + serdrv.c serpardr.c tx.c unixcomm.c -noinst_HEADERS = adp.h adperr.h angel.h ardi.h armdbg.h buffers.h bytesex.h \ +noinst_HEADERS = adp.h adperr.h angel.h ardi.h armdbg.h buffers.h \ chandefs.h channels.h chanpriv.h crc.h dbg_conf.h dbg_cp.h \ dbg_hif.h dbg_rdi.h devclnt.h devices.h devsw.h drivers.h \ - endian.h ethernet.h host.h hostchan.h hsys.h logging.h \ - msgbuild.h params.h rxtx.h sys.h unixcomm.h + angel_endian.h ethernet.h host.h hostchan.h hsys.h logging.h \ + msgbuild.h params.h rxtx.h sys.h unixcomm.h angel_bytesex.h EXTRA_DIST = README.CYGNUS diff --git a/gdb/rdi-share/angel_bytesex.c b/gdb/rdi-share/angel_bytesex.c new file mode 100644 index 00000000000..054f9607ce1 --- /dev/null +++ b/gdb/rdi-share/angel_bytesex.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved. + * + * This software may be freely used, copied, modified, and distributed + * provided that the above copyright notice is preserved in all copies of the + * software. + */ + +/* + * angel_bytesex.c - Code to support byte-sex independence + * Copyright: (C) 1991, Advanced RISC Machines Ltd., Cambridge, England. + */ + +/* + * RCS $Revision$ + * Checkin $Date$ + */ + +#include "angel_bytesex.h" + +static int reversing_bytes = 0; + +void bytesex_reverse(yes_or_no) +int yes_or_no; +{ reversing_bytes = yes_or_no; +} + +int bytesex_reversing() +{ + return reversing_bytes; +} + +int32 bytesex_hostval(v) +int32 v; +{ /* Return v with the same endian-ness as the host */ + /* This mess generates better ARM code than the more obvious mess */ + /* and may eventually peephole to optimal code... */ + if (reversing_bytes) + { unsigned32 t; + /* t = v ^ (v ror 16) */ + t = v ^ ((v << 16) | (((unsigned32)v) >> 16)); + t &= ~0xff0000; + /* v = v ror 8 */ + v = (v << 24) | (((unsigned32)v) >> 8); + v = v ^ (t >> 8); + } + return v; +} + +int32 bytesex_hostval_16(v) +int32 v; +{ + if (reversing_bytes) { + v = ((v >> 8) & 0xff) | ((v << 8) & 0xff00); + } + return v; +} diff --git a/gdb/rdi-share/angel_bytesex.h b/gdb/rdi-share/angel_bytesex.h new file mode 100644 index 00000000000..cb86af4fdc5 --- /dev/null +++ b/gdb/rdi-share/angel_bytesex.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved. + * + * This software may be freely used, copied, modified, and distributed + * provided that the above copyright notice is preserved in all copies of the + * software. + */ + +/* + Title: Code to support byte-sex independence + Copyright: (C) 1991, Advanced RISC Machines Ltd., Cambridge, England. +*/ +/* + * RCS $Revision$ + * Checkin $Date$ + */ + +#ifndef angel_bytesex_h +#define angel_bytesex_h + +#include "host.h" + +void bytesex_reverse(int yes_or_no); +/* + * Turn sex-reversal on or off - 0 means off, non-0 means on. + */ + +int bytesex_reversing(void); +/* + * Return non-0 if reversing the byte sex, else 0. + */ + +int32 bytesex_hostval(int32 v); +/* + * Return v or byte-reversed v, according to whether sex-reversval + * is on or off. + */ + +int32 bytesex_hostval_16(int32 v); +/* Return v or byte-reversed v for a 16 bit value */ + +#endif diff --git a/gdb/rdi-share/angel_endian.h b/gdb/rdi-share/angel_endian.h new file mode 100644 index 00000000000..4e40dcb7a9e --- /dev/null +++ b/gdb/rdi-share/angel_endian.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved. + * + * This software may be freely used, copied, modified, and distributed + * provided that the above copyright notice is preserved in all copies of the + * software. + */ + +/* -*-C-*- + * + * $Revision$ + * $Date$ + * + * + * angel_endian.h - target endianness independent read/write primitives. + */ + +#ifndef angel_endian_h +#define angel_endian_h + +/* + * The endianness of the data being processed needs to be known, but + * the host endianness is not required (since the data is constructed + * using bytes). At the moment these are provided as macros. This + * gives the compiler freedom in optimising individual calls. However, + * if space is at a premium then functions should be provided. + * + * NOTE: These macros assume that the data has been packed in the same format + * as the packing on the build host. If this is not the case then + * the wrong addresses could be used when dealing with structures. + * + */ + +/* + * For all the following routines the target endianness is defined by the + * following boolean definitions. + */ +#define BE (1 == 1) /* TRUE : big-endian */ +#define LE (1 == 0) /* FALSE : little-endian */ + +/* + * The following type definitions are used by the endianness converting + * macros. + */ +typedef unsigned char U8; +typedef U8 *P_U8; +typedef const U8 *CP_U8; + +typedef unsigned short U16; +typedef U16 *P_U16; + +typedef unsigned int U32; +typedef U32 *P_U32; + +/* + * If the endianness of the host and target are known (fixed) and the same + * then the following macro definitions can be used. These just directly copy + * the data. + * + * #define READ(e,a) (a) + * #define WRITE(e,a,v) ((a) = (v)) + * #define PREAD(e,a) (a) + * #define PWRITE(e,a,v) (*(a) = (v)) + */ + +/* + * These macros assume that a byte (char) is 8bits in size, and that the + * endianness is not important when reading or writing bytes. + */ +#define PUT8(a,v) (*((P_U8)(a)) = (U8)(v)) +#define PUT16LE(a,v) (PUT8(a,((v) & 0xFF)), \ + PUT8((((P_U8)(a)) + sizeof(char)),((v) >> 8))) +#define PUT16BE(a,v) (PUT8(a,((v) >> 8)), \ + PUT8((((P_U8)(a)) + sizeof(char)),((v) & 0xFF))) +#define PUT32LE(a,v) (PUT16LE(a,v), \ + PUT16LE((((P_U8)(a)) + sizeof(short)),((v) >> 16))) +#define PUT32BE(a,v) (PUT16BE(a,((v) >> 16)), \ + PUT16BE((((P_U8)(a)) + sizeof(short)),v)) + +#define GET8(a) (*((CP_U8)(a))) +#define GET16LE(a) (GET8(a) | (((U16)GET8(((CP_U8)(a)) + sizeof(char))) << 8)) +#define GET16BE(a) ((((U16)GET8(a)) << 8) | GET8(((CP_U8)(a)) + sizeof(char))) +#define GET32LE(a) (GET16LE(a) | \ + (((U32)GET16LE(((CP_U8)(a)) + sizeof(short))) << 16)) +#define GET32BE(a) ((((U32)GET16BE(a)) << 16) | \ + GET16BE(((CP_U8)(a)) + sizeof(short))) + +/* + * These macros simplify the code in respect to reading and writing the + * correct size data when dealing with endianness. "e" is TRUE if we are + * dealing with big-endian data, FALSE if we are dealing with little-endian. + */ + +/* void WRITE(int endianness, void *address, unsigned value); */ + +#define WRITE16(e,a,v) ((e) ? PUT16BE(&(a),v) : PUT16LE(&(a),v)) +#define WRITE32(e,a,v) ((e) ? PUT32BE(&(a),v) : PUT32LE(&(a),v)) +#define WRITE(e,a,v) ((sizeof(v) == sizeof(char)) ? \ + PUT8(&(a),v) : ((sizeof(v) == sizeof(short)) ? \ + WRITE16(e,a,v) : WRITE32(e,a,v))) + +/* unsigned READ(int endianness, void *address) */ +#define READ16(e,a) ((e) ? GET16BE(&(a)) : GET16LE(&(a))) +#define READ32(e,a) ((e) ? GET32BE(&(a)) : GET32LE(&(a))) +#define READ(e,a) ((sizeof(a) == sizeof(char)) ? \ + GET8((CP_U8)&(a)) : ((sizeof(a) == sizeof(short)) ? \ + READ16(e,a) : READ32(e,a))) + +/* void PWRITE(int endianness, void *address, unsigned value); */ +#define PWRITE16(e,a,v) ((e) ? PUT16BE(a,v) : PUT16LE(a,v)) +#define PWRITE32(e,a,v) ((e) ? PUT32BE(a,v) : PUT32LE(a,v)) +#define PWRITE(e,a,v) ((sizeof(v) == sizeof(char)) ? \ + PUT8(a,v) : ((sizeof(v) == sizeof(short)) ? \ + PWRITE16(e,a,v) : PWRITE32(e,a,v))) + +/* unsigned PREAD(int endianness, void *address) */ +#define PREAD16(e,a) ((e) ? GET16BE(a) : GET16LE(a)) +#define PREAD32(e,a) ((e) ? GET32BE(a) : GET32LE(a)) +#define PREAD(e,a) ((sizeof(*(a)) == sizeof(char)) ? \ + GET8((CP_U8)a) : ((sizeof(*(a)) == sizeof(short)) ? \ + PREAD16(e,a) : PREAD32(e,a))) + +#endif /* !defined(angel_endian_h) */ + +/* EOF angel_endian.h */ diff --git a/gdb/rdi-share/ardi.c b/gdb/rdi-share/ardi.c index f61f7242f73..f7a391e52a1 100644 --- a/gdb/rdi-share/ardi.c +++ b/gdb/rdi-share/ardi.c @@ -27,13 +27,13 @@ #undef uint -#include "endian.h" +#include "angel_endian.h" #include "ardi.h" #include "buffers.h" #include "channels.h" #include "hostchan.h" #include "host.h" -#include "bytesex.h" +#include "angel_bytesex.h" #include "dbg_cp.h" #include "adp.h" #include "hsys.h" @@ -1300,7 +1300,7 @@ static int HandleStoppedMessage(Packet *packet, void *stateptr) { stopped_info->stopped_status = RDIError_NoError; break; default: - stopped_info->stopped_status = RDIError_NoError; + stopped_info->stopped_status = RDIError_Error; break; } return RDIError_NoError; diff --git a/gdb/rdi-share/devsw.c b/gdb/rdi-share/devsw.c index 7fa142b4722..51ac29e9c98 100644 --- a/gdb/rdi-share/devsw.c +++ b/gdb/rdi-share/devsw.c @@ -14,6 +14,7 @@ */ #include #include +#include #include "adp.h" #include "hsys.h" @@ -26,6 +27,172 @@ #include "hostchan.h" #include "logging.h" +static char *angelDebugFilename = NULL; +static FILE *angelDebugLogFile = NULL; +static int angelDebugLogEnable = 0; + +static void openLogFile () +{ + time_t t; + struct tm lt; + + if (angelDebugFilename == NULL || *angelDebugFilename =='\0') + return; + + angelDebugLogFile = fopen (angelDebugFilename,"a"); + + if (!angelDebugLogFile) + { + fprintf (stderr,"Error opening log file '%s'\n",angelDebugFilename); + perror ("fopen"); + } + else + setlinebuf (angelDebugLogFile); + + time (&t); + fprintf (angelDebugLogFile,"ADP log file opened at %s\n",asctime(localtime(&t))); +} + + +static void closeLogFile (void) +{ + time_t t; + struct tm lt; + + if (!angelDebugLogFile) + return; + + time (&t); + fprintf (angelDebugLogFile,"ADP log file closed at %s\n",asctime(localtime(&t))); + + fclose (angelDebugLogFile); + angelDebugLogFile = NULL; +} + +void DevSW_SetLogEnable (int logEnableFlag) +{ + if (logEnableFlag && !angelDebugLogFile) + openLogFile (); + else if (!logEnableFlag && angelDebugLogFile) + closeLogFile (); + + angelDebugLogEnable = logEnableFlag; +} + + +void DevSW_SetLogfile (const char *filename) +{ + closeLogFile (); + + if (angelDebugFilename) + { + free (angelDebugFilename); + angelDebugFilename = NULL; + } + + if (filename && *filename) + { + angelDebugFilename = strdup (filename); + if (angelDebugLogEnable) + openLogFile (); + } +} + + +#define WordAt(p) ((unsigned long) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24))) + +static void dumpPacket(FILE *fp, char *label, struct data_packet *p) +{ + unsigned r; + int i; + + if (!fp) + return; + + fprintf(fp,"%s [T=%d L=%d] ",label,p->type,p->len); + for (i=0; ilen; ++i) + fprintf(fp,"%02x ",p->data[i]); + fprintf(fp,"\n"); + + r = WordAt(p->data+4); + + fprintf(fp,"R=%08x ",r); + fprintf(fp,"%s ", r&0x80000000 ? "H<-T" : "H->T"); + + switch ((r>>16) & 0xff) + { + case CI_PRIVATE: fprintf(fp,"CI_PRIVATE: "); break; + case CI_HADP: fprintf(fp,"CI_HADP: "); break; + case CI_TADP: fprintf(fp,"CI_TADP: "); break; + case CI_HBOOT: fprintf(fp,"CI_HBOOT: "); break; + case CI_TBOOT: fprintf(fp,"CI_TBOOT: "); break; + case CI_CLIB: fprintf(fp,"CI_CLIB: "); break; + case CI_HUDBG: fprintf(fp,"CI_HUDBG: "); break; + case CI_TUDBG: fprintf(fp,"CI_TUDBG: "); break; + case CI_HTDCC: fprintf(fp,"CI_HTDCC: "); break; + case CI_TTDCC: fprintf(fp,"CI_TTDCC: "); break; + case CI_TLOG: fprintf(fp,"CI_TLOG: "); break; + default: fprintf(fp,"BadChan: "); break; + } + + switch (r & 0xffffff) + { + case ADP_Booted: fprintf(fp," ADP_Booted "); break; +#if defined(ADP_TargetResetIndication) + case ADP_TargetResetIndication: fprintf(fp," ADP_TargetResetIndication "); break; +#endif + case ADP_Reboot: fprintf(fp," ADP_Reboot "); break; + case ADP_Reset: fprintf(fp," ADP_Reset "); break; +#if defined(ADP_HostResetIndication) + case ADP_HostResetIndication: fprintf(fp," ADP_HostResetIndication "); break; +#endif + case ADP_ParamNegotiate: fprintf(fp," ADP_ParamNegotiate "); break; + case ADP_LinkCheck: fprintf(fp," ADP_LinkCheck "); break; + case ADP_HADPUnrecognised: fprintf(fp," ADP_HADPUnrecognised "); break; + case ADP_Info: fprintf(fp," ADP_Info "); break; + case ADP_Control: fprintf(fp," ADP_Control "); break; + case ADP_Read: fprintf(fp," ADP_Read "); break; + case ADP_Write: fprintf(fp," ADP_Write "); break; + case ADP_CPUread: fprintf(fp," ADP_CPUread "); break; + case ADP_CPUwrite: fprintf(fp," ADP_CPUwrite "); break; + case ADP_CPread: fprintf(fp," ADP_CPread "); break; + case ADP_CPwrite: fprintf(fp," ADP_CPwrite "); break; + case ADP_SetBreak: fprintf(fp," ADP_SetBreak "); break; + case ADP_ClearBreak: fprintf(fp," ADP_ClearBreak "); break; + case ADP_SetWatch: fprintf(fp," ADP_SetWatch "); break; + case ADP_ClearWatch: fprintf(fp," ADP_ClearWatch "); break; + case ADP_Execute: fprintf(fp," ADP_Execute "); break; + case ADP_Step: fprintf(fp," ADP_Step "); break; + case ADP_InterruptRequest: fprintf(fp," ADP_InterruptRequest "); break; + case ADP_HW_Emulation: fprintf(fp," ADP_HW_Emulation "); break; + case ADP_ICEbreakerHADP: fprintf(fp," ADP_ICEbreakerHADP "); break; + case ADP_ICEman: fprintf(fp," ADP_ICEman "); break; + case ADP_Profile: fprintf(fp," ADP_Profile "); break; + case ADP_InitialiseApplication: fprintf(fp," ADP_InitialiseApplication "); break; + case ADP_End: fprintf(fp," ADP_End "); break; + case ADP_TADPUnrecognised: fprintf(fp," ADP_TADPUnrecognised "); break; + case ADP_Stopped: fprintf(fp," ADP_Stopped "); break; + case ADP_TDCC_ToHost: fprintf(fp," ADP_TDCC_ToHost "); break; + case ADP_TDCC_FromHost: fprintf(fp," ADP_TDCC_FromHost "); break; + default: fprintf(fp," BadReason "); break; + } + + i = 20; + + if (((r & 0xffffff) == ADP_CPUread || + (r & 0xffffff) == ADP_CPUwrite) && (r&0x80000000)==0) + { + fprintf(fp,"%02x ", p->data[i]); + ++i; + } + + for (; ilen; i+=4) + fprintf(fp,"%08x ",WordAt(p->data+i)); + + fprintf(fp,"\n"); +} + + /* * TODO: this should be adjustable - it could be done by defining * a reason code for DevSW_Ioctl. It could even be a @@ -309,6 +476,10 @@ AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type, #ifdef RET_DEBUG printf("got a complete packet\n"); #endif + + if (angelDebugLogEnable) + dumpPacket(angelDebugLogFile,"rx:",&ds->ds_activeread.dc_packet); + enqueue_packet(ds); *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]); return adp_ok; @@ -380,6 +551,10 @@ AdpErrs DevSW_Write(const DeviceDescr *device, Packet *packet, DevChanID type) * we can take this packet - set things up, then try to get rid of it */ initialise_write(dc, packet, type); + + if (angelDebugLogEnable) + dumpPacket(angelDebugLogFile,"tx:",&dc->dc_packet); + flush_packet(device, dc); return adp_ok; diff --git a/gdb/rdi-share/devsw.h b/gdb/rdi-share/devsw.h index f561768fd9d..749e7e64ff8 100644 --- a/gdb/rdi-share/devsw.h +++ b/gdb/rdi-share/devsw.h @@ -259,6 +259,13 @@ AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args); */ bool DevSW_WriteFinished(const DeviceDescr *device); + +/* + * set filename and enable/disable logginf of ADP packets + */ +void DevSW_SetLogfile(const char *filename); +void DevSW_SetLogEnable(int logEnableFlag); + #ifdef __cplusplus } #endif diff --git a/gdb/rdi-share/etherdrv.c b/gdb/rdi-share/etherdrv.c index 58462d44768..d9c5c0fa2cd 100644 --- a/gdb/rdi-share/etherdrv.c +++ b/gdb/rdi-share/etherdrv.c @@ -71,7 +71,7 @@ #include "hsys.h" #include "devices.h" -#include "endian.h" +#include "angel_endian.h" #include "buffers.h" #include "hostchan.h" #include "params.h" @@ -282,6 +282,10 @@ static void fetch_ports(void) * port on the remote target */ ia->sin_port = htons(CTRL_PORT); +#ifdef DEBUG + printf("CTLR_PORT=0x%04x sin_port=0x%04x\n"); +#endif + if (sendto(sock, ctrlpacket, sizeof(ctrlpacket), 0, (struct sockaddr *)ia, sizeof(*ia)) < 0) { diff --git a/gdb/rdi-share/hostchan.c b/gdb/rdi-share/hostchan.c index 8e41da49860..3114c52d2f7 100644 --- a/gdb/rdi-share/hostchan.c +++ b/gdb/rdi-share/hostchan.c @@ -230,7 +230,7 @@ void Adp_addToQueue(Packet **head, Packet *newpkt) */ ASSERT(&(((Packet *)0)->pk_next) == 0, "bad struct Packet layout"); -#if DEBUG && 0 +#if defined(DEBUG) && 0 printf("Adp_addToQueue(%p, %p)\n", head, newpkt); #endif @@ -265,6 +265,16 @@ Packet *Adp_removeFromQueue(Packet **head) return pk; } +void Adp_SetLogEnable(int logEnableFlag) +{ + DevSW_SetLogEnable(logEnableFlag); +} + +void Adp_SetLogfile(const char *filename) +{ + DevSW_SetLogfile(filename); +} + AdpErrs Adp_OpenDevice(const char *name, const char *arg, unsigned int heartbeat_on) { diff --git a/gdb/rdi-share/hostchan.h b/gdb/rdi-share/hostchan.h index 44563a6112a..b9acb77919d 100644 --- a/gdb/rdi-share/hostchan.h +++ b/gdb/rdi-share/hostchan.h @@ -91,6 +91,13 @@ extern void Adp_addToQueue(Packet **head, Packet *newpkt); extern Packet *Adp_removeFromQueue(Packet **head); +/* + * Set log file and Enable/disable logging of ADP packets to file. + */ + +void Adp_SetLogfile(const char *filename); +void Adp_SetLogEnable(int logEnableFlag); + /* * Function: Adp_OpenDevice * Purpose: Open a device to use for channels communication. This is a diff --git a/gdb/rdi-share/hsys.c b/gdb/rdi-share/hsys.c index ef42a309b94..39137566247 100644 --- a/gdb/rdi-share/hsys.c +++ b/gdb/rdi-share/hsys.c @@ -29,7 +29,7 @@ #include "ardi.h" #include "buffers.h" #include "channels.h" /* Channel interface. */ -#include "endian.h" +#include "angel_endian.h" #include "logging.h" /* Angel support functions. */ #include "msgbuild.h" #include "sys.h" diff --git a/gdb/rdi-share/msgbuild.c b/gdb/rdi-share/msgbuild.c index e2db2cc0576..63263e75676 100644 --- a/gdb/rdi-share/msgbuild.c +++ b/gdb/rdi-share/msgbuild.c @@ -28,7 +28,7 @@ #include "channels.h" #include "buffers.h" -#include "endian.h" /* Endianness support macros */ +#include "angel_endian.h" /* Endianness support macros */ #include "msgbuild.h" /* Header file for this source code */ #ifndef UNUSED diff --git a/gdb/rdi-share/params.c b/gdb/rdi-share/params.c index 2c781887c19..55d9eb210ef 100644 --- a/gdb/rdi-share/params.c +++ b/gdb/rdi-share/params.c @@ -19,7 +19,7 @@ #include "params.h" -#include "endian.h" +#include "angel_endian.h" #include "logging.h" diff --git a/gdb/rdi-share/rx.c b/gdb/rdi-share/rx.c index 4f434f0cbd6..caf833ad24b 100644 --- a/gdb/rdi-share/rx.c +++ b/gdb/rdi-share/rx.c @@ -19,7 +19,7 @@ #include /* ANSI varargs support */ #include "angel.h" /* Angel system definitions */ -#include "endian.h" /* Endian independant memory access macros */ +#include "angel_endian.h" /* Endian independant memory access macros */ #include "crc.h" /* crc generation definitions and headers */ #include "rxtx.h" #include "channels.h" diff --git a/gdb/rdi-share/tx.c b/gdb/rdi-share/tx.c index a52286c12b5..7d8d154e484 100644 --- a/gdb/rdi-share/tx.c +++ b/gdb/rdi-share/tx.c @@ -18,7 +18,7 @@ #include /* ANSI varargs support */ #include "angel.h" /* Angel system definitions */ -#include "endian.h" /* Endian independant memory access macros */ +#include "angel_endian.h" /* Endian independant memory access macros */ #include "crc.h" /* crc generation definitions and headers */ #include "rxtx.h" #include "channels.h" diff --git a/gdb/rdi-share/unixcomm.c b/gdb/rdi-share/unixcomm.c index 61d84e33be1..86bffc045e2 100644 --- a/gdb/rdi-share/unixcomm.c +++ b/gdb/rdi-share/unixcomm.c @@ -287,7 +287,14 @@ extern int Unix_ReadSerial(unsigned char *buf, int n, bool block) return -1; } else if (err > 0 && FD_ISSET(serpfd, &fdset)) - return read(serpfd, buf, n); + { + int s; + + s = read(serpfd, buf, n); + if (s < 0) + perror("read:"); + return s; + } else /* err == 0 || FD_CLR(serpfd, &fdset) */ { errno = ERRNO_FOR_BLOCKED_IO; diff --git a/gdb/remote-rdi.c b/gdb/remote-rdi.c index ef996081bf5..69addf6ed35 100644 --- a/gdb/remote-rdi.c +++ b/gdb/remote-rdi.c @@ -107,6 +107,18 @@ static int max_load_size; static int execute_status; +/* Send heatbeat packets? */ +static int rdi_heartbeat = 0; + +/* Target has ROM at address 0. */ +static int rom_at_zero = 0; + +/* Enable logging? */ +static int log_enable = 0; + +/* Name of the log file. Default is "rdi.log". */ +static char *log_filename; + /* A little list of breakpoints that have been set. */ static struct local_bp_list_entry @@ -214,14 +226,33 @@ arm_rdi_open (name, from_tty) { int rslt, i; unsigned long arg1, arg2; + char *openArgs = NULL; + char *devName = NULL; + char *p; if (name == NULL) error ("To open an RDI connection, you need to specify what serial\n\ 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,' '); + if (p) + { + *p = '\0'; + ++p; + + while (*p == ' ') + ++p; + + openArgs = p; + } + /* Make the basic low-level connection. */ - rslt = Adp_OpenDevice (name, NULL, 1); + Adp_CloseDevice (); + rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat); if (rslt != adp_ok) error ("Could not open device \"%s\"", name); @@ -295,7 +326,8 @@ device is attached to the remote system (e.g. /dev/ttya)."); printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); } - arg1 = 0x13b; + arg1 = rom_at_zero ? 0x0 : 0x13b; + rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2); if (rslt) { @@ -967,11 +999,96 @@ 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) +{ + 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) +{ + 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); + else + printf_filtered ("rdilogenable: unrecognized argument '%s'\n" + " try y or n\n",args); +} + void _initialize_remote_rdi () { init_rdi_ops (); add_target (&arm_rdi_ops); + + log_filename = strdup("rdi.log"); + Adp_SetLogfile(log_filename); + Adp_SetLogEnable(log_enable); + + add_cmd ("rdilogfile", class_maintenance, + rdilogfile_command, + "Set filename for ADP packet log.\n\ +This file is used to log Angel Debugger Protocol packets.\n\ +With a single argument, sets the logfile name to that value.\n\ +Without an argument, shows the current logfile name.\n\ +See also: rdilogenable\n", + &maintenancelist); + + 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\ +rdi target device.\n\ +An argument of 1,t,true,y,yes will enable.\n\ +An argument of 0,f,false,n,no will disabled.\n\ +Withough an argument, it will display current state.\n", + &maintenancelist); + + add_show_from_set + (add_set_cmd ("rdiromatzero", no_class, + var_boolean, (char *) &rom_at_zero, + "Set target has ROM at addr 0.\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); + + add_show_from_set + (add_set_cmd ("rdiheartbeat", no_class, + var_boolean, (char *) &rdi_heartbeat, + "Set enable for ADP heartbeat packets.\n\ +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); } /* A little dummy to make linking with the library succeed. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 06e699f25f2..28b724cd153 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,14 @@ +1999-11-01 Stan Shebs + + From Jimmy Guo : + * gdb.base/annota1.exp: Add tests for annotate ignore count change. + * gdb.base/annota1.c: Add code for tests to work with. + +1999-10-26 Frank Ch. Eigler + + * gdb.base/remote.exp: New test for remote downloading settings. + * gdb.base/remote.c: New file with large .data. + 1999-10-18 Jim Blandy * gdb.threads/linux-dp.c, gdb.threads/linux-dp.exp: New test suite diff --git a/gdb/testsuite/gdb.base/annota1.c b/gdb/testsuite/gdb.base/annota1.c index 7d423e0960c..6a13ee9d53d 100644 --- a/gdb/testsuite/gdb.base/annota1.c +++ b/gdb/testsuite/gdb.base/annota1.c @@ -39,6 +39,12 @@ main () printf ("value is %d\n", value); printf ("my_array[2] is %d\n", my_array[2]); + + { + int i; + for (i = 0; i < 5; i++) + value++; + } return 0; } diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp index 5ecdcb37b84..9b4fce6f6fe 100644 --- a/gdb/testsuite/gdb.base/annota1.exp +++ b/gdb/testsuite/gdb.base/annota1.exp @@ -359,6 +359,54 @@ gdb_expect { timeout { fail "re-run (timeout)" } } +# +# Test that breakpoints-invalid is issued once and only once for +# breakpoint ignore count changes, after annotation stopped. +# +send_gdb "break 46\n" +gdb_expect { + -re "Breakpoint 5 at $hex: file .*$srcfile, line 46.*$gdb_prompt$" { + pass "break at 46" + } + -re ".*$gdb_prompt$" { fail "break at 46" } + timeout { fail "break at 46 (timeout)" } +} + +send_gdb "ignore 5 4\n" +gdb_expect { + -re "Will ignore next 4 crossings of breakpoint 5.*$gdb_prompt$" { + pass "ignore 5 4" + } + -re ".*$gdb_prompt$" { fail "ignore 5 4" } + timeout { fail "ignore 5 4 (timeout)" } +} + +send_gdb "continue\n" +gdb_expect { + -re ".*$srcfile:46:.*\032\032stopped\r\n\r\n\032\032breakpoints-invalid\r\n$gdb_prompt$" { + pass "annotate ignore count change" + } + -re ".*$gdb_prompt$" { fail "annotate ignore count change" } + timeout { fail "annotate ignore count change (timeout)" } +} + +# check that ignore command is working, or the above can provide +# misleading assurance ... + +send_gdb "next\n" +gdb_expect { + -re "$gdb_prompt$" {} + timeout { fail "next to exit loop" } +} + +send_gdb "next\n" +gdb_expect { + -re ".*$srcfile:49:.*$gdb_prompt$" { + pass "breakpoint ignore count" + } + -re ".*$gdb_prompt$" { fail "breakpoint ignore count" } + timeout { fail "breakpoint ignore count (timeout)" } +} # # Send a signal that is not handled; test: diff --git a/gdb/testsuite/gdb.base/remote.c b/gdb/testsuite/gdb.base/remote.c new file mode 100644 index 00000000000..b297e5e86d1 --- /dev/null +++ b/gdb/testsuite/gdb.base/remote.c @@ -0,0 +1,26 @@ +#include +#include + +/************************************************************************** + * TESTS : + * -- downloading of a rather large executable + ***************************************************************************/ + + +/* A large array in .data. If RLE compression becomes available during + downloads, this would have to become a bunch of real random data. + Here's a quick way of generating such a bunch: + +yes | awk '{printf ("%4d,", rand()*1000);}' | fold -w80 -s | head -4096 + +*/ + +unsigned long random_data[65536] = { 1 }; + +int +main() +{ + printf ("%lu\n", random_data [rand() % + (sizeof (random_data) / + sizeof (random_data [0]))]); +} diff --git a/gdb/testsuite/gdb.base/remote.exp b/gdb/testsuite/gdb.base/remote.exp new file mode 100644 index 00000000000..4c8b415452e --- /dev/null +++ b/gdb/testsuite/gdb.base/remote.exp @@ -0,0 +1,83 @@ +# Copyright (C) 1999 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +if $tracelevel then { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + + +# test only on a remote target board +if {! [is_remote target]} { + return +} + + +set testfile "remote" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + + +proc gdb_load_timed {executable writesize} { + global test gdb_prompt + set test "timed download `[file tail $executable]' ($writesize)" + + if {$writesize != ""} then { + send_gdb "set remotewritesize $writesize\n" + gdb_expect 5 { + -re ".*$gdb_prompt $" { } + timeout { fail "$test - setting remotewritesize" ; return } + } + } + + set load_begin_time [clock clicks] + set result [gdb_load $executable] + set load_end_time [clock clicks] + if {$result < 0} then { fail "$test - loading executable"; return } + verbose "$test - time [expr ($load_end_time - $load_begin_time) / 1000] ms" + pass $test +} + + + +# tests + +gdb_start + +set result [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] +if {$result != "" } then { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +gdb_load_timed $binfile {} +gdb_load_timed $binfile 50 +gdb_load_timed $binfile 100 +gdb_load_timed $binfile 200 +gdb_load_timed $binfile 400 + +# extra tests for capable targets +if {[target_info gdb,big_rx_buffers] != ""} then { + gdb_load_timed $binfile 800 + gdb_load_timed $binfile 8000 + gdb_load_timed $binfile 80000 +} + +gdb_exit diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 6b0be604273..5b03a6c24a1 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -556,6 +556,9 @@ tracepoint_operation (t, from_tty, opcode) { struct tracepoint *t2; + if (t == NULL) /* no tracepoint operand */ + return; + switch (opcode) { case enable_op: @@ -595,51 +598,36 @@ tracepoint_operation (t, from_tty, opcode) } } -/* Utility: parse a tracepoint number and look it up in the list. */ +/* Utility: parse a tracepoint number and look it up in the list. + If MULTI_P is true, there might be a range of tracepoints in ARG. */ struct tracepoint * -get_tracepoint_by_number (arg) +get_tracepoint_by_number (arg, multi_p) char **arg; + int multi_p; { struct tracepoint *t; - char *end, *copy; - value_ptr val; + char *instring = *arg; int tpnum; - if (arg == 0) - error ("Bad tracepoint argument"); + if (arg == NULL) + error_no_arg ("tracepoint number"); - if (*arg == 0 || **arg == 0) /* empty arg means refer to last tp */ - tpnum = tracepoint_count; - else if (**arg == '$') /* handle convenience variable */ + tpnum = multi_p ? get_number_or_range (arg) : get_number (arg); + if (tpnum <= 0) { - /* Make a copy of the name, so we can null-terminate it - to pass to lookup_internalvar(). */ - end = *arg + 1; - while (isalnum ((int) *end) || *end == '_') - end++; - copy = (char *) alloca (end - *arg); - strncpy (copy, *arg + 1, (end - *arg - 1)); - copy[end - *arg - 1] = '\0'; - *arg = end; + printf_filtered ("bad tracepoint number at or near '%s'\n", instring); + return NULL; + } - val = value_of_internalvar (lookup_internalvar (copy)); - if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_INT) - error ("Convenience variable must have integral type."); - tpnum = (int) value_as_long (val); - } - else - /* handle tracepoint number */ - { - tpnum = strtol (*arg, arg, 0); - if (tpnum == 0) /* possible strtol failure */ - while (**arg && !isspace ((int) **arg)) - (*arg)++; /* advance to next white space, if any */ - } ALL_TRACEPOINTS (t) if (t->number == tpnum) { return t; } + + /* FIXME: if we are in the middle of a range we don't want to give + a message. The current interface to get_number_or_range doesn't + allow us to discover this. */ printf_unfiltered ("No tracepoint number %d.\n", tpnum); return NULL; } @@ -660,9 +648,8 @@ map_args_over_tracepoints (args, from_tty, opcode) while (*args) { QUIT; /* give user option to bail out with ^C */ - t = get_tracepoint_by_number (&args); - if (t) - tracepoint_operation (t, from_tty, opcode); + t = get_tracepoint_by_number (&args, 1); + tracepoint_operation (t, from_tty, opcode); while (*args == ' ' || *args == '\t') args++; } @@ -717,6 +704,7 @@ trace_pass_command (args, from_tty) { struct tracepoint *t1 = (struct tracepoint *) -1, *t2; unsigned int count; + int all = 0; if (args == 0 || *args == 0) error ("PASS command requires an argument (count + optional TP num)"); @@ -727,26 +715,34 @@ trace_pass_command (args, from_tty) args++; if (*args && strncasecmp (args, "all", 3) == 0) - args += 3; /* skip special argument "all" */ - else - t1 = get_tracepoint_by_number (&args); - - if (*args) - error ("Junk at end of arguments."); - - if (t1 == NULL) - return; /* error, bad tracepoint number */ - - ALL_TRACEPOINTS (t2) - if (t1 == (struct tracepoint *) -1 || t1 == t2) { - t2->pass_count = count; - if (modify_tracepoint_hook) - modify_tracepoint_hook (t2); - if (from_tty) - printf_filtered ("Setting tracepoint %d's passcount to %d\n", - t2->number, count); + args += 3; /* skip special argument "all" */ + all = 1; + if (*args) + error ("Junk at end of arguments."); } + else + t1 = get_tracepoint_by_number (&args, 1); + + do + { + if (t1) + { + ALL_TRACEPOINTS (t2) + if (t1 == (struct tracepoint *) -1 || t1 == t2) + { + t2->pass_count = count; + if (modify_tracepoint_hook) + modify_tracepoint_hook (t2); + if (from_tty) + printf_filtered ("Setting tracepoint %d's passcount to %d\n", + t2->number, count); + } + } + if (! all) + t1 = get_tracepoint_by_number (&args, 1); + } + while (*args); } /* ACTIONS functions: */ @@ -797,7 +793,7 @@ trace_actions_command (args, from_tty) char tmpbuf[128]; char *end_msg = "End with a line saying just \"end\"."; - t = get_tracepoint_by_number (&args); + t = get_tracepoint_by_number (&args, 0); if (t) { sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.", @@ -817,10 +813,9 @@ trace_actions_command (args, from_tty) if (readline_end_hook) (*readline_end_hook) (); - /* tracepoints_changed () */ } - /* else error, just return; */ + /* else just return */ } /* worker function */ diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h index 3f338170319..d61ab40abb4 100644 --- a/gdb/tracepoint.h +++ b/gdb/tracepoint.h @@ -1,5 +1,5 @@ /* Data structures associated with tracepoints in GDB. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 1999 Free Software Foundation, Inc. This file is part of GDB. @@ -121,7 +121,7 @@ void (*modify_tracepoint_hook) PARAMS ((struct tracepoint *)); void (*trace_find_hook) PARAMS ((char *arg, int from_tty)); void (*trace_start_stop_hook) PARAMS ((int start, int from_tty)); -struct tracepoint *get_tracepoint_by_number PARAMS ((char **)); +struct tracepoint *get_tracepoint_by_number PARAMS ((char **, int)); int get_traceframe_number PARAMS ((void)); void free_actions PARAMS ((struct tracepoint *)); enum actionline_type validate_actionline PARAMS ((char **, diff --git a/sim/arm/ChangeLog b/sim/arm/ChangeLog index 44b15238546..eb432557bd5 100644 --- a/sim/arm/ChangeLog +++ b/sim/arm/ChangeLog @@ -1,3 +1,8 @@ +1999-10-27 Nick Clifton + + * thumbemu.c (ARMul_ThumbDecode): Accept 0xbebe as a thumb + breakpoint. + 1999-10-08 Ulrich Drepper * armos.c (SWIopen): Always pass third parameter with 0666 since diff --git a/sim/arm/thumbemu.c b/sim/arm/thumbemu.c index c610b97c55b..9a9fe03120b 100644 --- a/sim/arm/thumbemu.c +++ b/sim/arm/thumbemu.c @@ -325,6 +325,8 @@ ARMul_ThumbDecode (state,pc,tinstr,ainstr) : 0xE28DDF00) /* ADD */ | (tinstr & 0x007F); /* off7 */ } + else if ((tinstr & 0x0F00) == 0x0e00) + * ainstr = 0xEF000000 | SWI_Breakpoint; else { /* Format 14 */ diff --git a/sim/d10v/ChangeLog b/sim/d10v/ChangeLog index 6fa21b1de4f..0be82fa979e 100644 --- a/sim/d10v/ChangeLog +++ b/sim/d10v/ChangeLog @@ -1,3 +1,8 @@ +Mon Oct 18 18:03:24 MDT 1999 Diego Novillo + + * simops.c (OP_3220): Fix trace output for illegal accumulator + message. + 1999-09-14 Nick Clifton * simops.c: Disable setting of DM bit in PSW. diff --git a/sim/d10v/simops.c b/sim/d10v/simops.c index 9d779438b9e..5f19ebd9a13 100644 --- a/sim/d10v/simops.c +++ b/sim/d10v/simops.c @@ -2360,7 +2360,7 @@ OP_3220 () trace_input ("slae", OP_ACCUM, OP_REG, OP_VOID); - reg = SEXT16( GPR (OP[1])); + reg = SEXT16 (GPR (OP[1])); if (reg >= 17 || reg <= -17) { @@ -2373,7 +2373,7 @@ OP_3220 () if (PSW_ST && (tmp < SEXT40 (MIN32) || tmp > SEXT40 (MAX32))) { - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: value to shift 0x%x out of range.\n", tmp); + (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: accumulator value 0x%.2x%.8lx out of range\n", ((int)(tmp >> 32) & 0xff), ((unsigned long) tmp) & 0xffffffff); State.exception = SIGILL; return; }