diff options
author | Jason Molenda <jmolenda@apple.com> | 1999-12-14 01:06:04 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 1999-12-14 01:06:04 +0000 |
commit | c4093a6ab3c9ba5f830ca18d91d8b4db5b1d28ee (patch) | |
tree | 273969a6c8a28b0f0128edd803506abf025371b1 /gdb | |
parent | a3a8c91d411abe91720a2ac92b8140e1bdb41282 (diff) | |
download | gdb-c4093a6ab3c9ba5f830ca18d91d8b4db5b1d28ee.zip gdb-c4093a6ab3c9ba5f830ca18d91d8b4db5b1d28ee.tar.gz gdb-c4093a6ab3c9ba5f830ca18d91d8b4db5b1d28ee.tar.bz2 |
import gdb-1999-12-13 snapshot
Diffstat (limited to 'gdb')
60 files changed, 1143 insertions, 376 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 43a507c..efe4adb 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,200 @@ +1999-12-13 Michael Snyder <msnyder@cleaver.cygnus.com> + + * breakpoint.h (enum bptype): add new BP type bp_thread_event. + This will be used when a target needs to set an invisible + breakpoint to detect events such as thread creation. + * breakpoint.c (interlan_breakpoint_number): remove ifdefs. + (create_thread_event_breakpoint): new function. + (remove_thread_event_breakpoints): new function. + (bpstat_what): don't stop at invisible thread_event breakpoints. + (update_breakpoints_after_exec): if bp_thread_event breakpoins + still exist after an exec, delete them. They'll need to be + found and installed anew anyway. + (print_it_typical): don't announce bp_thread_event breakpoints. + (print_one_breakpoint): account for new breakpoint type. + (mention): don't mention invisible bp_thread_event breakpoints. + (delete_command): don't delete invisible bp_thread_event bp's. + (breakpoint_re_set_one): don't touch bp_thread_event bp's. + +Mon Dec 13 11:10:59 1999 Jimmy Guo <guo@cup.hp.com> + + * language.h (longest_raw_hex_string, longest_local_hex_string, + longest_local_hex_string_custom): Declare. + * language.c: New functions, and misc. fixes. + (longest_raw_hex_string, longest_local_hex_string, + longest_local_hex_string_custom): New functions. + + * c-typeprint.c + (c_type_print_varspec_prefix,c_type_print_varpsec_suffix): Add + TYPE_CODE_TEMPLATE case and default case. + (c_type_print_base): Revise how demangled_no_class is found; + print '}' before printing local file:line info. + * c-valprint.c (c_value_print): print reference type to class. + + * valarith.c (value_binop): Add support for exponentiation, + equal, not equal. + (my_strcmp): New function. + (value_equal,value_less): Add string equality comparison support. + + * m2-exp.y (lex): add default case statement to capture + unhandled token and call error(). + +1999-12-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * main.c (main): Remove unused variable. + + From Hubert VERSTRAETE (hubertV@bigfoot.com): + * main.c (captured_main): Disambiguate command line option '-d' by + preferring --directory over --dbx. + + * top.c (return_to_top_level): Do not do exec cleanups if the + target is executing. Those cleanups are supposed to be done when + the target has stopped. + +Mon Dec 13 20:52:37 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * breakpoint.c (do_captured_breakpoint_query, + gdb_breakpoint_query): New functions. Implement a breakpoint + query. + + * defs.h (enum gdb_rc): Declare. + (gdb_breakpoint_query): Declare. + +Mon Dec 13 14:18:06 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdb-events.h: Fix typo in description of breakpoint events. + * gdb-events.sh: Update. + +Mon Dec 13 13:57:26 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * breakpoint.c (ep_type_description_t): Delete. + (print_one_breakpoint): Add local declaration of struct + ep_type_description. + +Mon Dec 13 12:38:31 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * top.h: Delete #include <setjmp.h>. Moved to top.c. + (SIGJMP_BUF, SIGSETJMP, SIGLONGJMP, SIGJMP_BUF, SIGSETJMP, + SIGLONGJMP): Delete. Moved to top.c + (error_return, quit_return): Delete extern declarations. + + * top.c: #include <setjmp.h>. + (error_return, quit_return): Make static. + (SIGJMP_BUF, SIGSETJMP, SIGLONGJMP, SIGJMP_BUF, SIGSETJMP, + SIGLONGJMP): Define. + +Mon Dec 13 11:54:12 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * tracepoint.c (trace_start_command, tracepoints_info): Print + step_count using %ld. + * Makefile.in (tracepoint.o): Compile tracepoint.o with -Werror. + +1999-12-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * target.h (enum target_waitkind): Add new enumeration value + TARGET_WAITKIND_IGNORE. For inferior events that we should do + nothing about. + + * remote.c (remote_async_wait): After each character of console + output from the inferior, return to the event loop with an event + kind of TARGET_WAITKIND_IGNORE instead of looping here. + + * infrun.c (handle_inferior_event): In case of + TARGET_WAITKIND_IGNORE, return immediately, and set things up so + that we are still waiting for the inferior. + +1999-12-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * event-loop.c (handle_timer_event): When calling the timer + procedure, use the saved_timer data, not the timer_ptr data, + because the latter has been already freed. + +Fri Dec 10 12:01:43 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * eval.c (evaluate_subexp): Only inline when GNUC and not STDC. + +Sat Dec 11 17:52:03 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * breakpoint.c (print_one_breakpoint): New function. Move + breakpoint print code to here. + (breakpoint_1): From here. + +Mon Dec 6 20:31:28 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbarch.sh: Replace field init_p with invalid_p. + (TARGET_BFD_VMA_BIT): New architecture vector method. Defaults to + architecture bits_per_address. + * gdbarch.h, gdbarch.c: Update. + * defs.h (TARGET_BFD_VMA_BIT): Provide default of TARGET_PTR_BIT + for non- multi-arch case. + + * gdbtypes.h (builtin_type_bfd_vma, builtin_type_ptr, + builtin_type_CORE_ADDR): New GDB specific address types. + * gdbtypes.c (_initialize_gdbtypes, build_gdbtypes): Initialize + new builtin types. + +Wed Dec 8 17:48:56 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * config/sparc/nm-nbsd.h (FETCH_INFERIOR_REGISTERS): Delete + definition. Already defined in config/nm-nbsd.h. Include the + more explicit config/nm-nbsd.h. + + * config/sparc/nbsd.mt (TDEPFILES): Move solib.o from here. + * config/sparc/nbsd.mh (NATDEPFILES): To here. + * config/xm-nbsd.h: #include <sys/param.h> to get definition of + NGROUPS needed by <limits.h> and missing on some systems. + * config/nm-nbsd.h: Only macro's that match NetBSD definitions + with what is expected by solib.c when not SVR4_SHARED_LIBS. + + * configure.host: Add patterns for sparc-*-netbsdaout* and + sparc-*-netbsdelf*. + * config/sparc/nm-nbsdelf.h: New file. + * config/sparc/nbsdelf.mh: New file. + +Wed Dec 8 19:56:48 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * frame.h, blockframe.c: Rename default_frame_chain_valid to + file_frame_chain_valid. Rename alternate_frame_chain_valid to + func_frame_chain_valid. + + * config/sparc/tm-sparclite.h, config/mips/tm-mipsv4.h, + config/m88k/tm-delta88v4.h, config/m68k/tm-m68kv4.h, + config/m68k/tm-monitor.h, config/i386/tm-i386nw.h, + config/i386/tm-i386v4.h, config/h8300/tm-h8300.h: Update. + * mips-tdep.c (mips_gdbarch_init): Update. + +Wed Dec 8 19:12:17 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * blockframe.c (generic_file_frame_chain_valid): Rename + generic_file_frame_chain_valid. + * frame.h: Update. + * config/fr30/tm-fr30.h, config/m32r/tm-m32r.h, + config/mn10200/tm-mn10200.h, config/mn10300/tm-mn10300.h, + config/sh/tm-sh.h, config/v850/tm-v850.h, config/mcore/tm-mcore.h: + Update. + + * blockframe.c (generic_func_frame_chain_valid): New function. + Implement dummy-frame equivalent of function based frame chain + valid. + * frame.h (generic_func_frame_chain_valid): Declare. + +Wed Dec 8 16:26:27 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * blockframe.c (alternate_frame_chain_valid, + default_frame_chain_valid): Swap implementations. The change Mon + Nov 30 11:18:48 1998 Andrew Cagney <cagney@chook> which converted + several macros to functions was backwards. + + * mips-tdep.c (mips_gdbarch_init): Update. Call + alternate_frame_chain_valid and not default_frame_chain_valid. + +Wed Dec 8 15:29:48 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * infptrace.c: Simplify handling of <sys/wait.h>. Always include + "wait.h" from the ../include/wait.h directory. #include + <sys/wait.h> was added as part of Mon Nov 29 12:14:10 1999 Andrew + Cagney <cagney@b1.cygnus.com> but the ChangeLog was omitted. + 1999-12-07 Jim Blandy <jimb@cygnus.com> Add support for SSE registers in core files. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index b7e548d..9fbb5e0 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 = 19991207 +VERSION = 19991213 DIST=gdb LINT=/usr/5bin/lint @@ -1158,12 +1158,9 @@ findvar.o: findvar.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h \ fork-child.o: fork-child.c $(wait_h) $(defs_h) $(gdbcore_h) \ $(inferior_h) target.h terminal.h gdbthread.h gdb_string.h -# Due to several ``enum enabled'' declaration clashes it is difficult -# to fix breakpoint.c's compiler warnings. tracepoint.o: tracepoint.c $(defs_h) $(symtab_h) $(frame_h) $(tracepoint_h) \ $(gdbtypes_h) $(expression_h) $(gdbcmd_h) $(value_h) target.h \ language.h gdb_string.h $(readline_headers) $(remote_h) - $(CC) -c $(INTERNAL_WARN_CFLAGS) $(NO_WERROR_CFLAGS) $< gdbarch.o: gdbarch.c $(defs_h) $(bfd_h) $(gdbcmd_h) diff --git a/gdb/blockframe.c b/gdb/blockframe.c index b4f42d2..6ce753e 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -41,13 +41,12 @@ void _initialize_blockframe (void); frame is the outermost one and has no caller. */ int -default_frame_chain_valid (chain, thisframe) +file_frame_chain_valid (chain, thisframe) CORE_ADDR chain; struct frame_info *thisframe; { return ((chain) != 0 - && !inside_main_func ((thisframe)->pc) - && !inside_entry_func ((thisframe)->pc)); + && !inside_entry_file (FRAME_SAVED_PC (thisframe))); } /* Use the alternate method of avoiding running up off the end of the @@ -55,12 +54,13 @@ default_frame_chain_valid (chain, thisframe) the comments in objfiles.h. */ int -alternate_frame_chain_valid (chain, thisframe) +func_frame_chain_valid (chain, thisframe) CORE_ADDR chain; struct frame_info *thisframe; { return ((chain) != 0 - && !inside_entry_file (FRAME_SAVED_PC (thisframe))); + && !inside_main_func ((thisframe)->pc) + && !inside_entry_func ((thisframe)->pc)); } /* A very simple method of determining a valid frame */ @@ -1104,7 +1104,7 @@ pc_in_call_dummy_at_entry_point (pc, sp, frame_address) * zero, and CALL_DUMMY_LOCATION to AT_ENTRY. Then you must remember * to define PUSH_RETURN_ADDRESS, because no call instruction will be * being executed by the target. Also FRAME_CHAIN_VALID as - * generic_frame_chain_valid and FIX_CALL_DUMMY as + * generic_{file,func}_frame_chain_valid and FIX_CALL_DUMMY as * generic_fix_call_dummy. */ /* Dummy frame. This saves the processor state just prior to setting @@ -1270,7 +1270,7 @@ generic_pop_dummy_frame () and false for the CRT0 start-up frame. Purpose is to terminate backtrace */ int -generic_frame_chain_valid (fp, fi) +generic_file_frame_chain_valid (fp, fi) CORE_ADDR fp; struct frame_info *fi; { @@ -1282,6 +1282,20 @@ generic_frame_chain_valid (fp, fi) && !inside_entry_file (FRAME_SAVED_PC (fi))); } +int +generic_func_frame_chain_valid (fp, fi) + CORE_ADDR fp; + struct frame_info *fi; +{ + if (PC_IN_CALL_DUMMY ((fi)->pc, fp, fp)) + return 1; /* don't prune CALL_DUMMY frames */ + else /* fall back to default algorithm (see frame.h) */ + return (fp != 0 + && (INNER_THAN (fi->frame, fp) || fi->frame == fp) + && !inside_main_func ((fi)->pc) + && !inside_entry_func ((fi)->pc)); +} + /* Function: fix_call_dummy Stub function. Generic dumy frames typically do not need to fix the frame being created */ diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 06d9471..1ffda2b 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -260,9 +260,7 @@ void set_breakpoint_count PARAMS ((int)); extern int addressprint; /* Print machine addresses? */ -#if defined (GET_LONGJMP_TARGET) || defined (SOLIB_ADD) static int internal_breakpoint_number = -1; -#endif /* Are we executing breakpoint commands? */ static int executing_breakpoint_commands; @@ -1128,6 +1126,13 @@ update_breakpoints_after_exec () continue; } + /* Thread event breakpoints must be set anew after an exec(). */ + if (b->type == bp_thread_event) + { + delete_breakpoint (b); + continue; + } + /* Step-resume breakpoints are meaningless after an exec(). */ if (b->type == bp_step_resume) { @@ -1907,6 +1912,13 @@ print_it_typical (bs) return PRINT_NOTHING; break; + case bp_thread_event: + /* Not sure how we will get here. + GDB should not stop for these breakpoints. */ + printf_filtered ("Thread Event Breakpoint: gdb should not stop!\n"); + return PRINT_NOTHING; + break; + case bp_catch_load: annotate_catchpoint (bs->breakpoint_at->number); printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number); @@ -2832,6 +2844,9 @@ bpstat_what (bs) case bp_shlib_event: bs_class = shlib_event; break; + case bp_thread_event: + bs_class = bp_nostop; + break; case bp_catch_load: case bp_catch_unload: /* Only if this catchpoint triggered should we cause the @@ -2975,28 +2990,19 @@ bpstat_get_triggered_catchpoints (ep_list, cp_list) *cp_list = bs; } -/* Print information on breakpoint number BNUM, or -1 if all. - If WATCHPOINTS is zero, process only breakpoints; if WATCHPOINTS - is nonzero, process only watchpoints. */ - -typedef struct -{ - enum bptype type; - char *description; -} -ep_type_description_t; - +/* Print B to gdb_stdout. */ static void -breakpoint_1 (bnum, allflag) - int bnum; - int allflag; +print_one_breakpoint (struct breakpoint *b, + CORE_ADDR *last_addr) { - register struct breakpoint *b; register struct command_line *l; register struct symbol *sym; - CORE_ADDR last_addr = (CORE_ADDR) -1; - int found_a_breakpoint = 0; - static ep_type_description_t bptypes[] = + struct ep_type_description + { + enum bptype type; + char *description; + }; + static struct ep_type_description bptypes[] = { {bp_none, "?deleted?"}, {bp_breakpoint, "breakpoint"}, @@ -3014,6 +3020,7 @@ breakpoint_1 (bnum, allflag) {bp_watchpoint_scope, "watchpoint scope"}, {bp_call_dummy, "call dummy"}, {bp_shlib_event, "shlib events"}, + {bp_thread_event, "thread events"}, {bp_catch_load, "catch load"}, {bp_catch_unload, "catch unload"}, {bp_catch_fork, "catch fork"}, @@ -3022,235 +3029,293 @@ breakpoint_1 (bnum, allflag) {bp_catch_catch, "catch catch"}, {bp_catch_throw, "catch throw"} }; - + static char *bpdisps[] = {"del", "dstp", "dis", "keep"}; static char bpenables[] = "nynny"; char wrap_indent[80]; - - - ALL_BREAKPOINTS (b) - if (bnum == -1 - || bnum == b->number) + annotate_record (); + + /* 1 */ + annotate_field (0); + printf_filtered ("%-3d ", b->number); + + /* 2 */ + annotate_field (1); + if (((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0]))) + || ((int) b->type != bptypes[(int) b->type].type)) + internal_error ("bptypes table does not describe type #%d.", + (int) b->type); + printf_filtered ("%-14s ", bptypes[(int) b->type].description); + + /* 3 */ + annotate_field (2); + printf_filtered ("%-4s ", bpdisps[(int) b->disposition]); + + /* 4 */ + annotate_field (3); + printf_filtered ("%-3c ", bpenables[(int) b->enable]); + + /* 5 and 6 */ + strcpy (wrap_indent, " "); + if (addressprint) + strcat (wrap_indent, " "); + switch (b->type) { -/* We only print out user settable breakpoints unless the allflag is set. */ - if (!allflag - && b->type != bp_breakpoint - && b->type != bp_catch_load - && b->type != bp_catch_unload - && b->type != bp_catch_fork - && b->type != bp_catch_vfork - && b->type != bp_catch_exec - && b->type != bp_catch_catch - && b->type != bp_catch_throw - && b->type != bp_hardware_breakpoint - && b->type != bp_watchpoint - && b->type != bp_read_watchpoint - && b->type != bp_access_watchpoint - && b->type != bp_hardware_watchpoint) - continue; + case bp_none: + internal_error ("print_one_breakpoint: bp_none encountered\n"); + break; - if (!found_a_breakpoint++) - { - annotate_breakpoints_headers (); - - annotate_field (0); - printf_filtered ("Num "); - annotate_field (1); - printf_filtered ("Type "); - annotate_field (2); - printf_filtered ("Disp "); - annotate_field (3); - printf_filtered ("Enb "); - if (addressprint) - { - annotate_field (4); - printf_filtered ("Address "); - } - annotate_field (5); - printf_filtered ("What\n"); + case bp_watchpoint: + case bp_hardware_watchpoint: + case bp_read_watchpoint: + case bp_access_watchpoint: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + annotate_field (5); + print_expression (b->exp, gdb_stdout); + break; + + case bp_catch_load: + case bp_catch_unload: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + annotate_field (5); + if (b->dll_pathname == NULL) + printf_filtered ("<any library> "); + else + printf_filtered ("library \"%s\" ", b->dll_pathname); + break; + + case bp_catch_fork: + case bp_catch_vfork: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + annotate_field (5); + if (b->forked_inferior_pid != 0) + printf_filtered ("process %d ", b->forked_inferior_pid); + break; + + case bp_catch_exec: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + annotate_field (5); + if (b->exec_pathname != NULL) + printf_filtered ("program \"%s\" ", b->exec_pathname); + break; - annotate_breakpoints_table (); - } + case bp_catch_catch: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + annotate_field (5); + printf_filtered ("exception catch "); + break; - annotate_record (); - annotate_field (0); - printf_filtered ("%-3d ", b->number); - annotate_field (1); - if ((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0]))) - error ("bptypes table does not describe type #%d.", (int) b->type); - if ((int) b->type != bptypes[(int) b->type].type) - error ("bptypes table does not describe type #%d?", (int) b->type); - printf_filtered ("%-14s ", bptypes[(int) b->type].description); - annotate_field (2); - printf_filtered ("%-4s ", bpdisps[(int) b->disposition]); - annotate_field (3); - printf_filtered ("%-3c ", bpenables[(int) b->enable]); - - strcpy (wrap_indent, " "); + case bp_catch_throw: + /* Field 4, the address, is omitted (which makes the columns + not line up too nicely with the headers, but the effect + is relatively readable). */ + annotate_field (5); + printf_filtered ("exception throw "); + break; + + case bp_breakpoint: + case bp_hardware_breakpoint: + case bp_until: + case bp_finish: + case bp_longjmp: + case bp_longjmp_resume: + case bp_step_resume: + case bp_through_sigtramp: + case bp_watchpoint_scope: + case bp_call_dummy: + case bp_shlib_event: + case bp_thread_event: if (addressprint) - strcat (wrap_indent, " "); - switch (b->type) { - case bp_watchpoint: - case bp_hardware_watchpoint: - case bp_read_watchpoint: - case bp_access_watchpoint: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - annotate_field (5); - print_expression (b->exp, gdb_stdout); - break; - - case bp_catch_load: - case bp_catch_unload: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - annotate_field (5); - if (b->dll_pathname == NULL) - printf_filtered ("<any library> "); - else - printf_filtered ("library \"%s\" ", b->dll_pathname); - break; - - case bp_catch_fork: - case bp_catch_vfork: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - annotate_field (5); - if (b->forked_inferior_pid != 0) - printf_filtered ("process %d ", b->forked_inferior_pid); - break; - - case bp_catch_exec: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - annotate_field (5); - if (b->exec_pathname != NULL) - printf_filtered ("program \"%s\" ", b->exec_pathname); - break; - case bp_catch_catch: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - annotate_field (5); - printf_filtered ("exception catch "); - break; - case bp_catch_throw: - /* Field 4, the address, is omitted (which makes the columns - not line up too nicely with the headers, but the effect - is relatively readable). */ - annotate_field (5); - printf_filtered ("exception throw "); - break; - - case bp_breakpoint: - case bp_hardware_breakpoint: - case bp_until: - case bp_finish: - case bp_longjmp: - case bp_longjmp_resume: - case bp_step_resume: - case bp_through_sigtramp: - case bp_watchpoint_scope: - case bp_call_dummy: - case bp_shlib_event: - if (addressprint) - { - annotate_field (4); - /* FIXME-32x64: need a print_address_numeric with - field width */ - printf_filtered - ("%s ", - local_hex_string_custom - ((unsigned long) b->address, "08l")); - } - - annotate_field (5); - - last_addr = b->address; - if (b->source_file) + annotate_field (4); + /* FIXME-32x64: need a print_address_numeric with + field width */ + printf_filtered + ("%s ", + local_hex_string_custom + ((unsigned long) b->address, "08l")); + } + annotate_field (5); + *last_addr = b->address; + if (b->source_file) + { + sym = find_pc_sect_function (b->address, b->section); + if (sym) { - sym = find_pc_sect_function (b->address, b->section); - if (sym) - { - fputs_filtered ("in ", gdb_stdout); - fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout); - wrap_here (wrap_indent); - fputs_filtered (" at ", gdb_stdout); - } - fputs_filtered (b->source_file, gdb_stdout); - printf_filtered (":%d", b->line_number); + fputs_filtered ("in ", gdb_stdout); + fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout); + wrap_here (wrap_indent); + fputs_filtered (" at ", gdb_stdout); } - else - print_address_symbolic (b->address, gdb_stdout, demangle, " "); - break; + fputs_filtered (b->source_file, gdb_stdout); + printf_filtered (":%d", b->line_number); } - - if (b->thread != -1) - printf_filtered (" thread %d", b->thread); - + else + print_address_symbolic (b->address, gdb_stdout, demangle, " "); + break; + } + + if (b->thread != -1) + { + printf_filtered (" thread %d", b->thread); + } + + printf_filtered ("\n"); + + if (b->frame) + { + annotate_field (6); + printf_filtered ("\tstop only in stack frame at "); + print_address_numeric (b->frame, 1, gdb_stdout); printf_filtered ("\n"); - - if (b->frame) - { - annotate_field (6); - - printf_filtered ("\tstop only in stack frame at "); - print_address_numeric (b->frame, 1, gdb_stdout); - printf_filtered ("\n"); - } - - if (b->cond) - { - annotate_field (7); - - printf_filtered ("\tstop only if "); - print_expression (b->cond, gdb_stdout); - printf_filtered ("\n"); - } - - if (b->thread != -1) + } + + if (b->cond) + { + annotate_field (7); + printf_filtered ("\tstop only if "); + print_expression (b->cond, gdb_stdout); + printf_filtered ("\n"); + } + + if (b->thread != -1) + { + /* FIXME should make an annotation for this */ + printf_filtered ("\tstop only in thread %d\n", b->thread); + } + + if (show_breakpoint_hit_counts && b->hit_count) + { + /* FIXME should make an annotation for this */ + if (ep_is_catchpoint (b)) + printf_filtered ("\tcatchpoint"); + else + printf_filtered ("\tbreakpoint"); + printf_filtered (" already hit %d time%s\n", + b->hit_count, (b->hit_count == 1 ? "" : "s")); + } + + if (b->ignore_count) + { + annotate_field (8); + printf_filtered ("\tignore next %d hits\n", b->ignore_count); + } + + if ((l = b->commands)) + { + annotate_field (9); + while (l) { - /* FIXME should make an annotation for this */ - printf_filtered ("\tstop only in thread %d\n", b->thread); + print_command_line (l, 4, gdb_stdout); + l = l->next; } + } +} - if (show_breakpoint_hit_counts && b->hit_count) - { - /* FIXME should make an annotation for this */ - if (ep_is_catchpoint (b)) - printf_filtered ("\tcatchpoint"); - else - printf_filtered ("\tbreakpoint"); - printf_filtered (" already hit %d time%s\n", - b->hit_count, (b->hit_count == 1 ? "" : "s")); - } +struct captured_breakpoint_query_args + { + int bnum; + }; - if (b->ignore_count) +static int +do_captured_breakpoint_query (void *data) +{ + struct captured_breakpoint_query_args *args = data; + register struct breakpoint *b; + CORE_ADDR dummy_addr = 0; + ALL_BREAKPOINTS (b) + { + if (args->bnum == b->number) { - annotate_field (8); - - printf_filtered ("\tignore next %d hits\n", b->ignore_count); + print_one_breakpoint (b, &dummy_addr); + return GDB_RC_OK; } + } + return GDB_RC_NONE; +} - if ((l = b->commands)) - { - annotate_field (9); +enum gdb_rc +gdb_breakpoint_query (/* output object, */ int bnum) +{ + struct captured_breakpoint_query_args args; + args.bnum = bnum; + /* For the moment we don't trust print_one_breakpoint() to not throw + an error. */ + return catch_errors (do_captured_breakpoint_query, &args, + NULL, RETURN_MASK_ALL); +} - while (l) - { - print_command_line (l, 4, gdb_stdout); - l = l->next; - } - } - } +/* Print information on breakpoint number BNUM, or -1 if all. + If WATCHPOINTS is zero, process only breakpoints; if WATCHPOINTS + is nonzero, process only watchpoints. */ +static void +breakpoint_1 (bnum, allflag) + int bnum; + int allflag; +{ + register struct breakpoint *b; + CORE_ADDR last_addr = (CORE_ADDR) -1; + int found_a_breakpoint = 0; + + ALL_BREAKPOINTS (b) + if (bnum == -1 + || bnum == b->number) + { + /* We only print out user settable breakpoints unless the + allflag is set. */ + if (!allflag + && b->type != bp_breakpoint + && b->type != bp_catch_load + && b->type != bp_catch_unload + && b->type != bp_catch_fork + && b->type != bp_catch_vfork + && b->type != bp_catch_exec + && b->type != bp_catch_catch + && b->type != bp_catch_throw + && b->type != bp_hardware_breakpoint + && b->type != bp_watchpoint + && b->type != bp_read_watchpoint + && b->type != bp_access_watchpoint + && b->type != bp_hardware_watchpoint) + continue; + + if (!found_a_breakpoint++) + { + annotate_breakpoints_headers (); + annotate_field (0); + printf_filtered ("Num "); + annotate_field (1); + printf_filtered ("Type "); + annotate_field (2); + printf_filtered ("Disp "); + annotate_field (3); + printf_filtered ("Enb "); + if (addressprint) + { + annotate_field (4); + printf_filtered ("Address "); + } + annotate_field (5); + printf_filtered ("What\n"); + annotate_breakpoints_table (); + } + + print_one_breakpoint (b, &last_addr); + } + if (!found_a_breakpoint) { if (bnum == -1) @@ -3259,11 +3324,15 @@ breakpoint_1 (bnum, allflag) printf_filtered ("No breakpoint or watchpoint number %d.\n", bnum); } else - /* Compare against (CORE_ADDR)-1 in case some compiler decides - that a comparison of an unsigned with -1 is always false. */ - if (last_addr != (CORE_ADDR) -1) - set_next_address (last_addr); + { + /* Compare against (CORE_ADDR)-1 in case some compiler decides + that a comparison of an unsigned with -1 is always false. */ + if (last_addr != (CORE_ADDR) -1) + set_next_address (last_addr); + } + /* FIXME? Should this be moved up so that it is only called when + there have been breakpoints? */ annotate_breakpoints_table_end (); } @@ -3556,6 +3625,42 @@ disable_longjmp_breakpoint () } } +struct breakpoint * +create_thread_event_breakpoint (address) + CORE_ADDR address; +{ + struct breakpoint *b; + struct symtab_and_line sal; + char addr_string[80]; /* Surely an addr can't be longer than that. */ + + INIT_SAL (&sal); /* initialize to zeroes */ + sal.pc = address; + sal.section = find_pc_overlay (sal.pc); + if ((b = set_raw_breakpoint (sal)) == NULL) + return NULL; + + b->number = internal_breakpoint_number--; + b->disposition = donttouch; + b->type = bp_thread_event; /* XXX: do we need a new type? + bp_thread_event */ + b->enable = enabled; + /* addr_string has to be used or breakpoint_re_set will delete me. */ + sprintf (addr_string, "*0x%s", paddr (b->address)); + b->addr_string = strsave (addr_string); + + return b; +} + +void +remove_thread_event_breakpoints (void) +{ + struct breakpoint *b, *temp; + + ALL_BREAKPOINTS_SAFE (b, temp) + if (b->type == bp_thread_event) + delete_breakpoint (b); +} + #ifdef SOLIB_ADD void remove_solib_event_breakpoints () @@ -4040,6 +4145,7 @@ mention (b) case bp_call_dummy: case bp_watchpoint_scope: case bp_shlib_event: + case bp_thread_event: break; } if (say_where) @@ -6280,6 +6386,7 @@ delete_command (arg, from_tty) { if (b->type != bp_call_dummy && b->type != bp_shlib_event && + b->type != bp_thread_event && b->number >= 0) breaks_to_delete = 1; } @@ -6292,6 +6399,7 @@ delete_command (arg, from_tty) { if (b->type != bp_call_dummy && b->type != bp_shlib_event && + b->type != bp_thread_event && b->number >= 0) delete_breakpoint (b); } @@ -6465,6 +6573,10 @@ breakpoint_re_set_one (bint) starts and we really don't want to touch it. */ case bp_shlib_event: + /* Like bp_shlib_event, this breakpoint type is special. + Once it is set up, we do not want to touch it. */ + case bp_thread_event: + /* Keep temporary breakpoints, which can be encountered when we step over a dlopen call and SOLIB_ADD is resetting the breakpoints. Otherwise these should have been blown away via the cleanup chain diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 94492dd..d0aa8bd 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -94,6 +94,16 @@ enum bptype dynamic libraries. */ bp_shlib_event, + /* Some multi-threaded systems can arrange for a location in the + inferior to be executed when certain thread-related events occur + (such as thread creation or thread death). + + By placing a breakpoint at one of these locations, GDB will get + control when these events occur. GDB can then update its thread + lists etc. */ + + bp_thread_event, + /* These breakpoints are used to implement the "catch load" command on platforms whose dynamic linkers support such functionality. */ bp_catch_load, @@ -641,8 +651,12 @@ extern void make_breakpoint_permanent PARAMS ((struct breakpoint *)); extern struct breakpoint *create_solib_event_breakpoint PARAMS ((CORE_ADDR)); +extern struct breakpoint *create_thread_event_breakpoint PARAMS ((CORE_ADDR)); + extern void remove_solib_event_breakpoints PARAMS ((void)); +extern void remove_thread_event_breakpoints PARAMS ((void)); + extern void disable_breakpoints_in_shlibs PARAMS ((int silent)); extern void re_enable_breakpoints_in_shlibs PARAMS ((void)); diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index d6eca30..90b626d 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -338,9 +338,13 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr) case TYPE_CODE_BITSTRING: case TYPE_CODE_COMPLEX: case TYPE_CODE_TYPEDEF: + case TYPE_CODE_TEMPLATE: /* These types need no prefix. They are listed here so that gcc -Wall will reveal any types that haven't been handled. */ break; + default: + error ("type not handled in c_type_print_varspec_prefix()"); + break; } } @@ -530,9 +534,13 @@ c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args) case TYPE_CODE_BITSTRING: case TYPE_CODE_COMPLEX: case TYPE_CODE_TYPEDEF: + case TYPE_CODE_TEMPLATE: /* These types do not need a suffix. They are listed so that gcc -Wall will report types that may not have been considered. */ break; + default: + error ("type not handled in c_type_print_varspec_suffix()"); + break; } } @@ -766,7 +774,6 @@ c_type_print_base (type, stream, show, level) if (TYPE_HAS_VTABLE (type) && (STREQN (TYPE_FIELD_NAME (type, i), "__vfp", 5))) continue; /* Other compilers */ - /* pai:: FIXME : check for has_vtable < 0 */ if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5) && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) continue; @@ -924,13 +931,13 @@ c_type_print_base (type, stream, show, level) else { char *p; - char *demangled_no_class = demangled_name; + char *demangled_no_class = strrchr (demangled_name, ':'); - while ((p = strchr (demangled_no_class, ':'))) - { - demangled_no_class = p; - if (*++demangled_no_class == ':') - ++demangled_no_class; + if (demangled_no_class == NULL) + demangled_no_class = demangled_name; + else + { + ++demangled_no_class; /* skip over last ':' */ } /* get rid of the static word appended by the demangler */ p = strstr (demangled_no_class, " static"); @@ -955,12 +962,12 @@ c_type_print_base (type, stream, show, level) } } + fprintfi_filtered (level, stream, "}"); + if (TYPE_LOCALTYPE_PTR (type) && show >= 0) fprintfi_filtered (level, stream, " (Local at %s:%d)\n", TYPE_LOCALTYPE_FILE (type), TYPE_LOCALTYPE_LINE (type)); - - fprintfi_filtered (level, stream, "}"); } if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE) goto go_back; diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index f888262..bc3666a 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -483,20 +483,24 @@ c_value_print (val, stream, format, pretty) { /* Pointer to class, check real type of object */ fprintf_filtered (stream, "("); - type = value_rtti_target_type (val, &full, &top, &using_enc); - if (type) + real_type = value_rtti_target_type (val, &full, &top, &using_enc); + if (real_type) { /* RTTI entry found */ - type = lookup_pointer_type (type); - type_print (type, "", stream, -1); - } - else - { - /* No RTTI fields, do whatever we can */ - type = VALUE_ENCLOSING_TYPE (val); - type_print (type, "", stream, -1); - fprintf_filtered (stream, " ?"); - } + if (TYPE_CODE (type) == TYPE_CODE_PTR) + { + /* create a pointer type pointing to the real type */ + type = lookup_pointer_type (real_type); + } + else + { + /* create a reference type referencing the real type */ + type = lookup_reference_type (real_type); + } + /* Note: When we look up RTTI entries, we don't get any + information on const or volatile attributes */ + } + type_print (type, "", stream, -1); fprintf_filtered (stream, ") "); } else @@ -521,6 +525,8 @@ c_value_print (val, stream, format, pretty) /* Print out object: enclosing type is same as real_type if full */ return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0, VALUE_ADDRESS (val), stream, format, 1, 0, pretty); + /* Note: When we look up RTTI entries, we don't get any information on + const or volatile attributes */ } else if (type != VALUE_ENCLOSING_TYPE (val)) { diff --git a/gdb/config/fr30/tm-fr30.h b/gdb/config/fr30/tm-fr30.h index 0bd5476..c530ad3 100644 --- a/gdb/config/fr30/tm-fr30.h +++ b/gdb/config/fr30/tm-fr30.h @@ -198,7 +198,7 @@ extern int fr30_frameless_function_invocation PARAMS ((struct frame_info * frame extern void fr30_init_extra_frame_info PARAMS ((struct frame_info * fi)); #define INIT_EXTRA_FRAME_INFO(fromleaf, fi) fr30_init_extra_frame_info (fi) -#define FRAME_CHAIN_VALID(FP, FI) generic_frame_chain_valid (FP, FI) +#define FRAME_CHAIN_VALID(FP, FI) generic_file_frame_chain_valid (FP, FI) extern CORE_ADDR fr30_push_arguments PARAMS ((int nargs, struct value ** args, CORE_ADDR sp, diff --git a/gdb/config/h8300/tm-h8300.h b/gdb/config/h8300/tm-h8300.h index e91f142..44b5e0d 100644 --- a/gdb/config/h8300/tm-h8300.h +++ b/gdb/config/h8300/tm-h8300.h @@ -205,7 +205,7 @@ CORE_ADDR h8300_frame_chain PARAMS ((struct frame_info *)); the frame chain or following frames back into the startup code. See the comments in objfile.h */ -#define FRAME_CHAIN_VALID(fp,fi) alternate_frame_chain_valid (fp, fi) +#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi) /* Define other aspects of the stack frame. */ diff --git a/gdb/config/i386/tm-i386nw.h b/gdb/config/i386/tm-i386nw.h index 1000b77..d61934a 100644 --- a/gdb/config/i386/tm-i386nw.h +++ b/gdb/config/i386/tm-i386nw.h @@ -25,7 +25,7 @@ /* Stop backtracing when we wander into main. */ -#define FRAME_CHAIN_VALID(fp,fi) alternate_frame_chain_valid (fp, fi) +#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi) /* Offsets (in target ints) into jmp_buf. Not defined in any system header diff --git a/gdb/config/i386/tm-i386v4.h b/gdb/config/i386/tm-i386v4.h index 7680a88..cdda76d 100644 --- a/gdb/config/i386/tm-i386v4.h +++ b/gdb/config/i386/tm-i386v4.h @@ -32,7 +32,7 @@ /* Use the alternate method of determining valid frame chains. */ -#define FRAME_CHAIN_VALID(fp,fi) alternate_frame_chain_valid (fp, fi) +#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi) /* Offsets (in target ints) into jmp_buf. Not defined in any system header file, so we have to step through setjmp/longjmp with a debugger and figure diff --git a/gdb/config/m32r/tm-m32r.h b/gdb/config/m32r/tm-m32r.h index 97f0880..7aad4c9 100644 --- a/gdb/config/m32r/tm-m32r.h +++ b/gdb/config/m32r/tm-m32r.h @@ -131,7 +131,7 @@ extern CORE_ADDR m32r_frame_chain PARAMS ((struct frame_info * fi)); /* mvs_check FRAME_CHAIN */ #define FRAME_CHAIN(fi) m32r_frame_chain (fi) -#define FRAME_CHAIN_VALID(fp, frame) generic_frame_chain_valid (fp, frame) +#define FRAME_CHAIN_VALID(fp, frame) generic_file_frame_chain_valid (fp, frame) extern CORE_ADDR m32r_find_callers_reg PARAMS ((struct frame_info * fi, int regnum)); diff --git a/gdb/config/m68k/tm-m68kv4.h b/gdb/config/m68k/tm-m68kv4.h index 9fd2460..84ebb0e 100644 --- a/gdb/config/m68k/tm-m68kv4.h +++ b/gdb/config/m68k/tm-m68kv4.h @@ -31,7 +31,7 @@ /* Use the alternate method of determining valid frame chains. */ -#define FRAME_CHAIN_VALID(fp,fi) alternate_frame_chain_valid (fp, fi) +#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi) #include "tm-sysv4.h" #include "m68k/tm-m68k.h" diff --git a/gdb/config/m68k/tm-monitor.h b/gdb/config/m68k/tm-monitor.h index 24c044d..914f825 100644 --- a/gdb/config/m68k/tm-monitor.h +++ b/gdb/config/m68k/tm-monitor.h @@ -40,6 +40,6 @@ /* Need to do this for ELF targets, where we can't figure out the boundaries of the entry file. This method stops the backtrace when we reach main. */ -#define FRAME_CHAIN_VALID(fp,fi) alternate_frame_chain_valid (fp, fi) +#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi) /* FIXME, should do GET_LONGJMP_TARGET for newlib. */ diff --git a/gdb/config/m88k/tm-delta88v4.h b/gdb/config/m88k/tm-delta88v4.h index 6804d98..f583ed6 100644 --- a/gdb/config/m88k/tm-delta88v4.h +++ b/gdb/config/m88k/tm-delta88v4.h @@ -24,7 +24,7 @@ #include "tm-sysv4.h" /* If we don't define this, backtraces go on forever. */ -#define FRAME_CHAIN_VALID(fp,fi) alternate_frame_chain_valid (fp, fi) +#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi) #define IN_SIGTRAMP(pc, name) ((name) && (STREQ ("signalhandler", (name)) \ || STREQ("sigacthandler", (name)))) diff --git a/gdb/config/mcore/tm-mcore.h b/gdb/config/mcore/tm-mcore.h index ddf5d90..cea17a0 100644 --- a/gdb/config/mcore/tm-mcore.h +++ b/gdb/config/mcore/tm-mcore.h @@ -81,7 +81,7 @@ extern void mcore_init_extra_frame_info (struct frame_info *fi); extern CORE_ADDR mcore_frame_chain (struct frame_info *fi); #define FRAME_CHAIN(FI) mcore_frame_chain ((FI)) -#define FRAME_CHAIN_VALID(FP, FI) generic_frame_chain_valid ((FP), (FI)) +#define FRAME_CHAIN_VALID(FP, FI) generic_file_frame_chain_valid ((FP), (FI)) extern CORE_ADDR mcore_frame_saved_pc (struct frame_info *); #define FRAME_SAVED_PC(FI) (mcore_frame_saved_pc ((FI))) diff --git a/gdb/config/mips/tm-mipsv4.h b/gdb/config/mips/tm-mipsv4.h index 02e188c..03fa499 100644 --- a/gdb/config/mips/tm-mipsv4.h +++ b/gdb/config/mips/tm-mipsv4.h @@ -40,7 +40,7 @@ #define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_BASE + 40 + 36 * 4) /* Use the alternate method of determining valid frame chains. */ -#define FRAME_CHAIN_VALID(fp,fi) alternate_frame_chain_valid (fp, fi) +#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi) /* Convert a DWARF register number to a gdb REGNUM. */ #define DWARF_REG_TO_REGNUM(num) ((num) < 32 ? (num) : (num)+FP0_REGNUM-32) diff --git a/gdb/config/mn10200/tm-mn10200.h b/gdb/config/mn10200/tm-mn10200.h index cb2a57f..f884361 100644 --- a/gdb/config/mn10200/tm-mn10200.h +++ b/gdb/config/mn10200/tm-mn10200.h @@ -109,7 +109,7 @@ extern void mn10200_frame_find_saved_regs PARAMS ((struct frame_info *, extern CORE_ADDR mn10200_frame_chain PARAMS ((struct frame_info *)); #define FRAME_CHAIN(fi) mn10200_frame_chain (fi) -#define FRAME_CHAIN_VALID(FP, FI) generic_frame_chain_valid (FP, FI) +#define FRAME_CHAIN_VALID(FP, FI) generic_file_frame_chain_valid (FP, FI) extern CORE_ADDR mn10200_find_callers_reg PARAMS ((struct frame_info *, int)); extern CORE_ADDR mn10200_frame_saved_pc PARAMS ((struct frame_info *)); diff --git a/gdb/config/mn10300/tm-mn10300.h b/gdb/config/mn10300/tm-mn10300.h index 4bc76fd..7969679 100644 --- a/gdb/config/mn10300/tm-mn10300.h +++ b/gdb/config/mn10300/tm-mn10300.h @@ -82,7 +82,7 @@ extern void mn10300_init_extra_frame_info PARAMS ((struct frame_info *)); extern CORE_ADDR mn10300_frame_chain PARAMS ((struct frame_info *)); #define FRAME_CHAIN(fi) mn10300_frame_chain (fi) -#define FRAME_CHAIN_VALID(FP, FI) generic_frame_chain_valid (FP, FI) +#define FRAME_CHAIN_VALID(FP, FI) generic_file_frame_chain_valid (FP, FI) extern CORE_ADDR mn10300_find_callers_reg PARAMS ((struct frame_info *, int)); extern CORE_ADDR mn10300_frame_saved_pc PARAMS ((struct frame_info *)); diff --git a/gdb/config/nm-nbsd.h b/gdb/config/nm-nbsd.h index c7c1fb5..2911288 100644 --- a/gdb/config/nm-nbsd.h +++ b/gdb/config/nm-nbsd.h @@ -1,5 +1,5 @@ /* Native-dependent definitions for NetBSD. - Copyright 1994, 1996 Free Software Foundation, Inc. + Copyright 1994, 1996, 1999 Free Software Foundation, Inc. This file is part of GDB. @@ -32,6 +32,11 @@ #define ATTACH_DETACH #include "solib.h" /* Support for shared libraries. */ +#if defined (SVR4_SHARED_LIBS) +#include "elf/common.h" /* Additional ELF shared library info. */ +#endif + +#if !defined (SVR4_SHARED_LIBS) /* make structure definitions match up with those expected in solib.c */ #define link_object sod @@ -85,3 +90,5 @@ #define ldd d_debug #define ld_un d_un #define ld_2 d_sdt + +#endif diff --git a/gdb/config/sh/tm-sh.h b/gdb/config/sh/tm-sh.h index 0c1c109..c6769e0 100644 --- a/gdb/config/sh/tm-sh.h +++ b/gdb/config/sh/tm-sh.h @@ -249,7 +249,7 @@ extern CORE_ADDR sh_push_return_address PARAMS ((CORE_ADDR, CORE_ADDR)); extern CORE_ADDR sh_frame_chain PARAMS ((struct frame_info *)); #define FRAME_CHAIN(FRAME) sh_frame_chain(FRAME) #define PUSH_DUMMY_FRAME generic_push_dummy_frame () -#define FRAME_CHAIN_VALID(FP, FRAME) generic_frame_chain_valid (FP, FRAME) +#define FRAME_CHAIN_VALID(FP, FRAME) generic_file_frame_chain_valid (FP, FRAME) #define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP) #define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \ (sh_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR)) diff --git a/gdb/config/sparc/nbsd.mh b/gdb/config/sparc/nbsd.mh index 310838d..292cc2b 100644 --- a/gdb/config/sparc/nbsd.mh +++ b/gdb/config/sparc/nbsd.mh @@ -2,5 +2,5 @@ XDEPFILES= ser-tcp.o XM_FILE= xm-nbsd.h NAT_FILE= nm-nbsd.h -NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o +NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o solib.o HOST_IPC=-DBSD_IPC diff --git a/gdb/config/sparc/nbsd.mt b/gdb/config/sparc/nbsd.mt index be8a348..5c89318 100644 --- a/gdb/config/sparc/nbsd.mt +++ b/gdb/config/sparc/nbsd.mt @@ -1,3 +1,3 @@ # Target: Sun 4 or Sparcstation, running NetBSD -TDEPFILES= sparc-tdep.o solib.o +TDEPFILES= sparc-tdep.o TM_FILE= tm-nbsd.h diff --git a/gdb/config/sparc/nbsdelf.mh b/gdb/config/sparc/nbsdelf.mh new file mode 100644 index 0000000..d76e7cb --- /dev/null +++ b/gdb/config/sparc/nbsdelf.mh @@ -0,0 +1,6 @@ +# Host: Sun 4 or Sparcstation, running NetBSD +XDEPFILES= ser-tcp.o +XM_FILE= xm-nbsd.h +NAT_FILE= nm-nbsdelf.h +NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o solib.o +HOST_IPC=-DBSD_IPC diff --git a/gdb/config/sparc/nm-nbsd.h b/gdb/config/sparc/nm-nbsd.h index 7668f9f..72f77b9 100644 --- a/gdb/config/sparc/nm-nbsd.h +++ b/gdb/config/sparc/nm-nbsd.h @@ -24,9 +24,7 @@ /* Get generic NetBSD native definitions. */ -#include "nm-nbsd.h" - -#define FETCH_INFERIOR_REGISTERS +#include "config/nm-nbsd.h" /* Before storing, we need to read all the registers. */ diff --git a/gdb/config/sparc/nm-nbsdelf.h b/gdb/config/sparc/nm-nbsdelf.h new file mode 100644 index 0000000..7f5e251 --- /dev/null +++ b/gdb/config/sparc/nm-nbsdelf.h @@ -0,0 +1,27 @@ +/* Native-dependent definitions for Sparc running NetBSD ELF, for GDB. + Copyright (C) 1999, Free Software Foundation, Inc. + + This file is part of GDB. + + 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. */ + +#ifndef NM_NBSDELF_H +#define NM_NBSDELF_H + +#define SVR4_SHARED_LIBS +#include "sparc/nm-nbsd.h" + +#endif diff --git a/gdb/config/sparc/tm-sparclite.h b/gdb/config/sparc/tm-sparclite.h index e419fe9..2e63418 100644 --- a/gdb/config/sparc/tm-sparclite.h +++ b/gdb/config/sparc/tm-sparclite.h @@ -39,7 +39,7 @@ #define DECR_PC_AFTER_HW_BREAK 4 -#define FRAME_CHAIN_VALID(fp,fi) alternate_frame_chain_valid (fp, fi) +#define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi) #undef NUM_REGS #define NUM_REGS 80 diff --git a/gdb/config/v850/tm-v850.h b/gdb/config/v850/tm-v850.h index 03efe94..256606a 100644 --- a/gdb/config/v850/tm-v850.h +++ b/gdb/config/v850/tm-v850.h @@ -108,7 +108,7 @@ extern void v850_frame_find_saved_regs PARAMS ((struct frame_info * fi, struct f extern CORE_ADDR v850_frame_chain PARAMS ((struct frame_info * fi)); #define FRAME_CHAIN(fi) v850_frame_chain (fi) -#define FRAME_CHAIN_VALID(FP, FI) generic_frame_chain_valid (FP, FI) +#define FRAME_CHAIN_VALID(FP, FI) generic_file_frame_chain_valid (FP, FI) extern CORE_ADDR v850_find_callers_reg PARAMS ((struct frame_info * fi, int regnum)); extern CORE_ADDR v850_frame_saved_pc PARAMS ((struct frame_info *)); diff --git a/gdb/config/xm-nbsd.h b/gdb/config/xm-nbsd.h index 18a668d..e9a00b5 100644 --- a/gdb/config/xm-nbsd.h +++ b/gdb/config/xm-nbsd.h @@ -1,5 +1,5 @@ /* Host-dependent definitions for any CPU running NetBSD. - Copyright 1993, 1994, 1996 Free Software Foundation, Inc. + Copyright 1993, 1994, 1996, 1999 Free Software Foundation, Inc. This file is part of GDB. @@ -18,6 +18,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* Include this to get things like NGROUPS which <limits.h> doesn't + define on some systems. */ +#include <sys/param.h> + /* We have to include these files now, so that GDB will not make competing definitions in defs.h. */ #include <limits.h> diff --git a/gdb/configure.host b/gdb/configure.host index a4acf1b..b116001 100644 --- a/gdb/configure.host +++ b/gdb/configure.host @@ -146,6 +146,8 @@ rs6000-*-*) gdb_host=rs6000 ;; sparc-*-linux*) gdb_host=linux ;; sparc-*-lynxos*) gdb_host=sparclynx ;; +sparc-*-netbsdelf*) gdb_host=nbsdelf ;; +sparc-*-netbsdaout*) gdb_host=nbsd ;; sparc-*-netbsd*) gdb_host=nbsd ;; sparc-*-solaris2*) gdb_host=sun4sol2 ;; sparc-*-sunos4*) gdb_host=sun4os4 ;; @@ -1052,6 +1052,11 @@ extern char *alloca (); #define TARGET_PTR_BIT TARGET_INT_BIT #endif +/* Number of bits in a BFD_VMA for the target object file format. */ +#if !defined (TARGET_BFD_VMA_BIT) +#define TARGET_BFD_VMA_BIT TARGET_PTR_BIT +#endif + /* If we picked up a copy of CHAR_BIT from a configuration file (which may get it by including <limits.h>) then use it to set the number of bits in a host char. If not, use the same size @@ -1306,4 +1311,32 @@ extern int use_windows; #define ISATTY(FP) (isatty (fileno (FP))) #endif + +/* FIXME: cagney/1999-12-13: The following will be moved to gdb.h / + libgdb.h or gdblib.h. */ + +/* Return-code (RC) from a gdb library call. (The abreviation RC is + taken from the sim/common directory.) */ + +enum gdb_rc { + /* The operation failed. The failure message can be fetched by + calling ``char *error_last_message(void)''. The value is + determined by the catch_errors() interface. */ + /* NOTE: Since ``defs.h:catch_errors()'' does not return an error / + internal / quit indication it is not possible to return that + here. */ + GDB_RC_FAIL = 0, + /* No error occured but nothing happened. Due to the catch_errors() + interface, this must be non-zero. */ + GDB_RC_NONE = 1, + /* The operation was successful. Due to the catch_errors() + interface, this must be non-zero. */ + GDB_RC_OK = 2 +}; + + +/* Print the specified breakpoint on GDB_STDOUT. (Eventually this + function will ``print'' the object on ``output''). */ +enum gdb_rc gdb_breakpoint_query (/* struct {ui,gdb}_out *output, */ int bnum); + #endif /* #ifndef DEFS_H */ diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 45e1cdb..f1150b8 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +Wed Dec 8 19:53:08 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbint.texinfo (FRAME_CHAIN_VALID): Add the generic frame-chain + valid functions. + 1999-11-05 Stan Shebs <shebs@andros.cygnus.com> * gdb.texinfo: Clarify regular expressions used in rbreak. diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo index 25666c3..21ec1e3 100644 --- a/gdb/doc/gdbint.texinfo +++ b/gdb/doc/gdbint.texinfo @@ -1381,13 +1381,17 @@ Presently only defined for HP PA. @item FRAME_CHAIN_VALID(chain,thisframe) Define this to be an expression that returns zero if the given frame is -an outermost frame, with no caller, and nonzero otherwise. Three common -definitions are available. @code{default_frame_chain_valid} (the -default) is nonzero if the chain pointer is nonzero and given frame's PC -is not inside the startup file (such as @file{crt0.o}). -@code{alternate_frame_chain_valid} is nonzero if the chain pointer is -nonzero and the given frame's PC is not in @code{main()} or a known -entry point function (such as @code{_start()}). +an outermost frame, with no caller, and nonzero otherwise. Several +common definitions are available. + +@code{file_frame_chain_valid} is nonzero if the chain pointer is nonzero +and given frame's PC is not inside the startup file (such as +@file{crt0.o}). @code{func_frame_chain_valid} is nonzero if the chain +pointer is nonzero and the given frame's PC is not in @code{main()} or a +known entry point function (such as @code{_start()}). +@code{generic_file_frame_chain_valid} and +@code{generic_func_frame_chain_valid} are equivalent implementations for +targets using generic dummy frames. @item FRAME_INIT_SAVED_REGS(frame) See @file{frame.h}. Determines the address of all registers in the @@ -59,7 +59,7 @@ static LONGEST init_array_element PARAMS ((value_ptr, value_ptr, struct expression *, int *, enum noside, LONGEST, LONGEST)); -#ifdef __GNUC__ +#if defined (__GNUC__) && !__STDC__ inline #endif static value_ptr diff --git a/gdb/event-loop.c b/gdb/event-loop.c index 7e3e02c..1915156 100644 --- a/gdb/event-loop.c +++ b/gdb/event-loop.c @@ -1082,7 +1082,7 @@ handle_timer_event (int dummy) saved_timer = timer_ptr; timer_ptr = timer_ptr->next; /* Call the procedure associated with that timer. */ - (*saved_timer->proc) (timer_ptr->client_data); + (*saved_timer->proc) (saved_timer->client_data); free (saved_timer); } diff --git a/gdb/frame.h b/gdb/frame.h index b7ab530..ad329c5 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -129,22 +129,24 @@ extern void frame_saved_regs_zalloc PARAMS ((struct frame_info *)); the definition here by providing one in the tm file. XXXX - both default and alternate frame_chain_valid functions are - deprecated. New code should use generic dummy frames. */ + deprecated. New code should use dummy frames and one of the + generic functions. */ -extern int default_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *)); -extern int alternate_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *)); +extern int file_frame_chain_valid (CORE_ADDR, struct frame_info *); +extern int func_frame_chain_valid (CORE_ADDR, struct frame_info *); extern int nonnull_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *)); -extern int generic_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *)); +extern int generic_file_frame_chain_valid (CORE_ADDR, struct frame_info *); +extern int generic_func_frame_chain_valid (CORE_ADDR, struct frame_info *); extern void generic_save_dummy_frame_tos PARAMS ((CORE_ADDR sp)); #if !defined (FRAME_CHAIN_VALID) #if !defined (FRAME_CHAIN_VALID_ALTERNATE) -#define FRAME_CHAIN_VALID(chain, thisframe) default_frame_chain_valid (chain, thisframe) +#define FRAME_CHAIN_VALID(chain, thisframe) file_frame_chain_valid (chain, thisframe) #else /* Use the alternate method of avoiding running up off the end of the frame chain or following frames back into the startup code. See the comments in objfiles.h. */ -#define FRAME_CHAIN_VALID(chain, thisframe) alternate_frame_chain_valid (chain,thisframe) +#define FRAME_CHAIN_VALID(chain, thisframe) func_frame_chain_valid (chain,thisframe) #endif /* FRAME_CHAIN_VALID_ALTERNATE */ #endif /* FRAME_CHAIN_VALID */ diff --git a/gdb/gdb-events.h b/gdb/gdb-events.h index ab60517..3985ffe 100644 --- a/gdb/gdb-events.h +++ b/gdb/gdb-events.h @@ -67,8 +67,8 @@ struct gdb_events /* Interface into events functions. - Where a *_p() predicate is present, it must called before calling - the hook proper. */ + Where a *_p() predicate is present, it must be called before + calling the hook proper. */ extern void breakpoint_create_event (int b); extern void breakpoint_delete_event (int b); extern void breakpoint_modify_event (int b); diff --git a/gdb/gdb-events.sh b/gdb/gdb-events.sh index 5854e84..620322d 100755 --- a/gdb/gdb-events.sh +++ b/gdb/gdb-events.sh @@ -213,8 +213,8 @@ echo "" echo "" cat <<EOF /* Interface into events functions. - Where a *_p() predicate is present, it must called before calling - the hook proper. */ + Where a *_p() predicate is present, it must be called before + calling the hook proper. */ EOF function_list | while eval read $read do diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index f7fbea4..49d7bf4 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -125,6 +125,7 @@ struct gdbarch */ + int bfd_vma_bit; int ptr_bit; int short_bit; int int_bit; @@ -224,6 +225,7 @@ struct gdbarch default_gdbarch = { 0, NULL, NULL, /* Multi-arch values */ 8 * sizeof (void*), + 8 * sizeof (void*), 8 * sizeof (short), 8 * sizeof (int), 8 * sizeof (long), @@ -325,6 +327,7 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->byte_order = info->byte_order; /* Force the explicit initialization of these. */ + gdbarch->bfd_vma_bit = TARGET_ARCHITECTURE->bits_per_address; gdbarch->num_regs = -1; gdbarch->sp_regnum = -1; gdbarch->fp_regnum = -1; @@ -366,6 +369,9 @@ verify_gdbarch (struct gdbarch *gdbarch) internal_error ("verify_gdbarch: bfd_arch_info unset"); /* Check those that need to be defined for the given multi-arch level. */ if ((GDB_MULTI_ARCH >= 1) + && (0)) + internal_error ("gdbarch: verify_gdbarch: bfd_vma_bit invalid"); + if ((GDB_MULTI_ARCH >= 1) && (gdbarch->ptr_bit == 0)) internal_error ("gdbarch: verify_gdbarch: ptr_bit invalid"); if ((GDB_MULTI_ARCH >= 1) @@ -612,6 +618,9 @@ gdbarch_dump (void) "gdbarch_update: TARGET_BYTE_ORDER = %ld\n", (long) TARGET_BYTE_ORDER); fprintf_unfiltered (gdb_stdlog, + "gdbarch_update: TARGET_BFD_VMA_BIT = %ld\n", + (long) TARGET_BFD_VMA_BIT); + fprintf_unfiltered (gdb_stdlog, "gdbarch_update: TARGET_PTR_BIT = %ld\n", (long) TARGET_PTR_BIT); fprintf_unfiltered (gdb_stdlog, @@ -940,6 +949,24 @@ gdbarch_byte_order (struct gdbarch *gdbarch) } int +gdbarch_bfd_vma_bit (struct gdbarch *gdbarch) +{ + if (0) + internal_error ("gdbarch: gdbarch_bfd_vma_bit invalid"); + if (gdbarch_debug >= 2) + /* FIXME: gdb_std??? */ + fprintf_unfiltered (gdb_stdlog, "gdbarch_bfd_vma_bit called\n"); + return gdbarch->bfd_vma_bit; +} + +void +set_gdbarch_bfd_vma_bit (struct gdbarch *gdbarch, + int bfd_vma_bit) +{ + gdbarch->bfd_vma_bit = bfd_vma_bit; +} + +int gdbarch_ptr_bit (struct gdbarch *gdbarch) { if (gdbarch->ptr_bit == 0) diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 34075c6..a1f7c76 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -99,6 +99,14 @@ extern int gdbarch_byte_order (struct gdbarch *gdbarch); /* The following are initialized by the target dependant code. */ +extern int gdbarch_bfd_vma_bit (struct gdbarch *gdbarch); +extern void set_gdbarch_bfd_vma_bit (struct gdbarch *gdbarch, int bfd_vma_bit); +#if GDB_MULTI_ARCH +#if (GDB_MULTI_ARCH > 1) || !defined (TARGET_BFD_VMA_BIT) +#define TARGET_BFD_VMA_BIT (gdbarch_bfd_vma_bit (current_gdbarch)) +#endif +#endif + extern int gdbarch_ptr_bit (struct gdbarch *gdbarch); extern void set_gdbarch_ptr_bit (struct gdbarch *gdbarch, int ptr_bit); #if GDB_MULTI_ARCH diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 92f3170..539f99a 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -19,7 +19,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -read="class level macro returntype function formal actual attrib default init init_p fmt print print_p description" +read="class level macro returntype function formal actual attrib default init invalid_p fmt print print_p description" # dump out/verify the doco for field in ${read} @@ -27,6 +27,7 @@ do case ${field} in class ) : ;; + # # -> line disable # f -> function # hiding a function @@ -39,7 +40,7 @@ do # See GDB_MULTI_ARCH description. Having GDB_MULTI_ARCH >= # LEVEL is a predicate on checking that a given method is - # initialized (using INIT_P). + # initialized (using INVALID_P). macro ) : ;; @@ -76,20 +77,21 @@ do default ) : ;; # To help with the GDB startup a default static gdbarch object - # is created. DEFAULT is the value to insert into that - # array. It defaults to ZERO. + # is created. DEFAULT is the value to insert into the static + # gdbarch object. If empty ZERO is used. init ) : ;; - # Any initial value to assign to the member after it is been - # MALLOCed. Defaults to zero. + # Any initial value to assign to a new gdbarch object after it + # as been malloc()ed. Zero is used by default. - init_p ) : ;; + invalid_p ) : ;; - # A predicate equation that tests to see if the code creating - # the new architecture has correctly updated this - # MEMBER. Default is to check that the value is no longer equal - # to INIT. + # A predicate equation that validates MEMBER. Non-zero is returned + # if the code creating the new architecture failed to initialize + # the MEMBER or initialized the member to something invalid. + # By default, a check that the value is no longer equal to INIT + # is performed. The equation ``0'' disables the invalid_p check. fmt ) : ;; @@ -129,6 +131,7 @@ i:2:TARGET_ARCHITECTURE:const struct bfd_arch_info *:bfd_arch_info::::&bfd_defau # i:2:TARGET_BYTE_ORDER:int:byte_order::::BIG_ENDIAN # +v:1:TARGET_BFD_VMA_BIT:int:bfd_vma_bit::::8 * sizeof (void*):TARGET_ARCHITECTURE->bits_per_address:0 v:1:TARGET_PTR_BIT:int:ptr_bit::::8 * sizeof (void*):0 #v:1:TARGET_CHAR_BIT:int:char_bit::::8 * sizeof (char):0 v:1:TARGET_SHORT_BIT:int:short_bit::::8 * sizeof (short):0 @@ -242,7 +245,7 @@ ${class} ${macro}(${actual}) level=${level} default=${default} init=${init} - init_p=${init_p} + invalid_p=${invalid_p} fmt=${fmt} print=${print} print_p=${print_p} @@ -968,10 +971,10 @@ function_list | while eval read $read do case "${class}" in "f" | "v" ) - if [ "${init_p}" ] + if [ "${invalid_p}" ] then echo " if ((GDB_MULTI_ARCH >= ${level})" - echo " && (${init_p}))" + echo " && (${invalid_p}))" echo " internal_error (\"gdbarch: verify_gdbarch: ${function} invalid\");" elif [ "${init}" ] then @@ -1084,9 +1087,9 @@ do echo "${returntype}" echo "gdbarch_${function} (struct gdbarch *gdbarch)" echo "{" - if [ "${init_p}" ] + if [ "${invalid_p}" ] then - echo " if (${init_p})" + echo " if (${invalid_p})" echo " internal_error (\"gdbarch: gdbarch_${function} invalid\");" elif [ "${init}" ] then diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 6a2fb1d..2016672 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -70,6 +70,9 @@ struct type *builtin_type_v4si; struct type *builtin_type_v8qi; struct type *builtin_type_v4hi; struct type *builtin_type_v2si; +struct type *builtin_type_ptr; +struct type *builtin_type_CORE_ADDR; +struct type *builtin_type_bfd_vma; int opaque_type_resolution = 1; @@ -2980,6 +2983,23 @@ build_gdbtypes () = init_simd_type ("__builtin_v4hi", builtin_type_int16, "f", 4); builtin_type_v2si = init_simd_type ("__builtin_v2si", builtin_type_int32, "f", 2); + + /* Pointer/Address types. */ + /* NOTE: At present there is no way of differentiating between at + target address and the target C language pointer type type even + though the two can be different (cf d10v) */ + builtin_type_ptr = + init_type (TYPE_CODE_INT, TARGET_PTR_BIT / 8, + TYPE_FLAG_UNSIGNED, + "__ptr", (struct objfile *) NULL); + builtin_type_CORE_ADDR = + init_type (TYPE_CODE_INT, TARGET_PTR_BIT / 8, + TYPE_FLAG_UNSIGNED, + "__CORE_ADDR", (struct objfile *) NULL); + builtin_type_bfd_vma = + init_type (TYPE_CODE_INT, TARGET_BFD_VMA_BIT / 8, + TYPE_FLAG_UNSIGNED, + "__bfd_vma", (struct objfile *) NULL); } @@ -3023,5 +3043,8 @@ _initialize_gdbtypes () register_gdbarch_swap (&builtin_type_v8qi, sizeof (struct type *), NULL); register_gdbarch_swap (&builtin_type_v4hi, sizeof (struct type *), NULL); register_gdbarch_swap (&builtin_type_v2si, sizeof (struct type *), NULL); + REGISTER_GDBARCH_SWAP (builtin_type_ptr); + REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR); + REGISTER_GDBARCH_SWAP (builtin_type_bfd_vma); register_gdbarch_swap (NULL, 0, build_gdbtypes); } diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 923b0b1..49ace6a 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -846,7 +846,18 @@ extern struct type *builtin_type_double_complex; extern struct type *builtin_type_string; extern struct type *builtin_type_bool; -/* Explicit sizes - see <intypes.h> for naming schema */ +/* Address/pointer types: */ +/* (C) Language pointer type. Some target platforms use an implicitly + {sign,zero} -extended 32 bit C language pointer on a 64 bit ISA. */ +extern struct type *builtin_type_ptr; +/* The target CPU's address type. This is the ISA address size. */ +extern struct type *builtin_type_CORE_ADDR; +/* The symbol table address type. Some object file formats have a 32 + bit address type even though the TARGET has a 64 bit pointer type + (cf MIPS). */ +extern struct type *builtin_type_bfd_vma; + +/* Explicit sizes - see C9X <intypes.h> for naming scheme */ extern struct type *builtin_type_int8; extern struct type *builtin_type_uint8; extern struct type *builtin_type_int16; diff --git a/gdb/infptrace.c b/gdb/infptrace.c index a21eaa1..8984b0c 100644 --- a/gdb/infptrace.c +++ b/gdb/infptrace.c @@ -24,13 +24,10 @@ #include "inferior.h" #include "target.h" #include "gdb_string.h" -#ifdef HAVE_WAIT_H -#include <wait.h> -#else #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif -#endif +#include "wait.h" /* NOTE: This is ../include/wait.h */ #include "command.h" #ifdef USG diff --git a/gdb/infrun.c b/gdb/infrun.c index 7e37228..591f819 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1755,6 +1755,17 @@ handle_inferior_event (struct execution_control_state *ecs) case TARGET_WAITKIND_STOPPED: stop_signal = ecs->ws.value.sig; break; + + /* We had an event in the inferior, but we are not interested + in handling it at this level. The lower layers have already + done what needs to be done, if anything. This case can + occur only when the target is async or extended-async. One + of the circumstamces for this to happen is when the + inferior produces output for the console. The inferior has + not stopped, and we are ignoring the event. */ + case TARGET_WAITKIND_IGNORE: + ecs->wait_some_more = 1; + return; } /* We may want to consider not doing a resume here in order to give diff --git a/gdb/language.c b/gdb/language.c index 1aeb237..be248ea 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -288,6 +288,10 @@ set_type_command (ignore, from_tty) did it in set_type_range. */ return; } + else + { + warning ("Unrecognized type check setting: \"%s\"", type); + } set_type_str (); show_type_command ((char *) NULL, from_tty); } @@ -334,6 +338,10 @@ set_range_command (ignore, from_tty) did it in set_type_range. */ return; } + else + { + warning ("Unrecognized range check setting: \"%s\"", range); + } set_range_str (); show_range_command ((char *) 0, from_tty); } @@ -398,7 +406,7 @@ set_lang_str () static void set_type_str () { - char *tmp, *prefix = ""; + char *tmp = NULL, *prefix = ""; free (type); if (type_mode == type_mode_auto) @@ -427,7 +435,6 @@ set_range_str () { char *tmp, *pref = ""; - free (range); if (range_mode == range_mode_auto) pref = "auto; currently "; @@ -446,6 +453,7 @@ set_range_str () error ("Unrecognized range check setting."); } + free (range); range = concat (pref, tmp, NULL); } @@ -539,6 +547,24 @@ local_hex_format_custom (pre) return form; } +/* Converts a number to hexadecimal (without leading "0x") and stores it in a + static string. Returns a pointer to this string. */ + +char * +longest_raw_hex_string (num) + LONGEST num; +{ + static char res_longest_raw_hex_string[50]; + long long ll = num; /* MERGEBUG ?? see below */ + res_longest_raw_hex_string[0] = 0; + /* MERGEBUG ?? As a quick fix I am replacing this with sprintf + strcat_address_numeric (num, 0, res_longest_raw_hex_string, 50); + */ + + sprintf (res_longest_raw_hex_string, "%llx", ll); + return res_longest_raw_hex_string; +} + /* Converts a number to hexadecimal and stores it in a static string. Returns a pointer to this string. */ char * @@ -551,6 +577,15 @@ local_hex_string (num) return res; } +/* Converts a LONGEST number to hexadecimal and stores it in a static + string. Returns a pointer to this string. */ +char * +longest_local_hex_string (num) + LONGEST num; +{ + return longest_local_hex_string_custom (num, "l"); +} + /* Converts a number to custom hexadecimal and stores it in a static string. Returns a pointer to this string. */ char * @@ -564,6 +599,107 @@ local_hex_string_custom (num, pre) return res; } +/* Converts a LONGEST number to custom hexadecimal and stores it in a static + string. Returns a pointer to this string. Note that the width parameter + should end with "l", e.g. "08l" as with calls to local_hex_string_custom */ + +char * +longest_local_hex_string_custom (num, width) + LONGEST num; + char *width; +{ +#define RESULT_BUF_LEN 50 + static char res2[RESULT_BUF_LEN]; + char format[RESULT_BUF_LEN]; +#if !defined (PRINTF_HAS_LONG_LONG) + int field_width; + int num_len; + int num_pad_chars; + char *pad_char; /* string with one character */ + int pad_on_left; + char *parse_ptr; + char temp_nbr_buf[RESULT_BUF_LEN]; +#endif + +#ifndef CC_HAS_LONG_LONG + /* If there is no long long, then LONGEST should be just long and we + can use local_hex_string_custom + */ + return local_hex_string_custom ((unsigned long) num, width); +#endif + +#if defined (PRINTF_HAS_LONG_LONG) + /* Just use printf. */ + strcpy (format, local_hex_format_prefix ()); /* 0x */ + strcat (format, "%"); + strcat (format, width); /* e.g. "08l" */ + strcat (format, "l"); /* need "ll" for long long */ + strcat (format, local_hex_format_specifier ()); /* "x" */ + strcat (format, local_hex_format_suffix ()); /* "" */ + sprintf (res2, format, num); + return res2; +#else /* !defined (PRINTF_HAS_LONG_LONG) */ + /* Use strcat_address_numeric to print the number into a string, then + build the result string from local_hex_format_prefix, padding and + the hex representation as indicated by "width". */ + + temp_nbr_buf[0] = 0; + /* With use_local == 0, we don't get the leading "0x" prefix. */ + /* MERGEBUG ?? As a quick fix I am replacing this call to + strcat_address_numeric with sprintf + strcat_address_numeric(num, 0, temp_nbr_buf, RESULT_BUF_LEN); + */ + + { + long long ll = num; + sprintf (temp_nbr_buf, "%llx", ll); + } + /* parse width */ + parse_ptr = width; + pad_on_left = 1; + pad_char = " "; + if (*parse_ptr == '-') + { + parse_ptr++; + pad_on_left = 0; + } + if (*parse_ptr == '0') + { + parse_ptr++; + if (pad_on_left) + pad_char = "0"; /* If padding is on the right, it is blank */ + } + field_width = atoi (parse_ptr); + num_len = strlen (temp_nbr_buf); + num_pad_chars = field_width - strlen (temp_nbr_buf); /* possibly negative */ + + if (strlen (local_hex_format_prefix ()) + num_len + num_pad_chars + < RESULT_BUF_LEN) /* paranoia */ + internal_error ("longest_local_hex_string_custom: insufficient space to store result"); + + strcpy (res2, local_hex_format_prefix ()); + if (pad_on_left) + { + while (num_pad_chars > 0) + { + strcat (res2, pad_char); + num_pad_chars--; + } + } + strcat (res2, temp_nbr_buf); + if (!pad_on_left) + { + while (num_pad_chars > 0) + { + strcat (res2, pad_char); + num_pad_chars--; + } + } + return res2; +#endif + +} /* longest_local_hex_string_custom */ + /* Returns the appropriate printf format for octal numbers. */ char * diff --git a/gdb/language.h b/gdb/language.h index 9484e0b..b730d9b 100644 --- a/gdb/language.h +++ b/gdb/language.h @@ -360,16 +360,28 @@ extern char * extern char * local_hex_format_custom PARAMS ((char *)); /* language.c */ +/* Return a string that contains the hex digits of the number. No preceeding + "0x" */ + +extern char * + longest_raw_hex_string PARAMS ((LONGEST)); + /* Return a string that contains a number formatted in one of the local (language-specific) formats. Result is static and is overwritten by - the next call. Takes printf options like "08" or "l". */ + the next call. Takes printf options like "08l" or "l". */ extern char * local_hex_string PARAMS ((unsigned long)); /* language.c */ extern char * + longest_local_hex_string PARAMS ((LONGEST)); /* language.c */ + +extern char * local_hex_string_custom PARAMS ((unsigned long, char *)); /* language.c */ +extern char * + longest_local_hex_string_custom PARAMS ((LONGEST, char *)); /* language.c */ + /* Type predicates */ extern int diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y index 507e5bc..94d1fe0 100644 --- a/gdb/m2-exp.y +++ b/gdb/m2-exp.y @@ -1050,6 +1050,10 @@ yylex () case LOC_LABEL: case LOC_UNRESOLVED: error("internal: Unforseen case in m2lex()"); + + default: + error ("unhandled token in m2lex()"); + break; } } else @@ -249,6 +249,7 @@ captured_main (void *data) {"version", no_argument, &print_version, 1}, {"x", required_argument, 0, 'x'}, {"directory", required_argument, 0, 'd'}, + {"d", required_argument, 0, 'd'}, {"cd", required_argument, 0, 11}, {"tty", required_argument, 0, 't'}, {"baud", required_argument, 0, 'b'}, @@ -693,7 +694,6 @@ captured_main (void *data) int main (int argc, char **argv) { - int top_level_val; struct captured_main_args args; args.argc = argc; args.argv = argv; diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 97076b4..13193df 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -3825,7 +3825,7 @@ mips_gdbarch_init (info, arches) set_gdbarch_push_arguments (gdbarch, mips_push_arguments); set_gdbarch_register_convertible (gdbarch, generic_register_convertible_not); - set_gdbarch_frame_chain_valid (gdbarch, default_frame_chain_valid); + set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid); set_gdbarch_get_saved_register (gdbarch, default_get_saved_register); if (gdbarch_debug) diff --git a/gdb/remote.c b/gdb/remote.c index d66ec50..402c95c 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -2886,7 +2886,10 @@ Packet Dropped"); goto got_status; case 'O': /* Console output */ remote_console_output (buf + 1); - continue; + /* Return immediately to the event loop. The event loop will + still be waiting on the inferior afterwards. */ + status->kind = TARGET_WAITKIND_IGNORE; + goto got_status; case '\0': if (last_sent_signal != TARGET_SIGNAL_0) { diff --git a/gdb/target.h b/gdb/target.h index 73b0739..4115eee 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -104,7 +104,18 @@ enum target_waitkind /* Nothing happened, but we stopped anyway. This perhaps should be handled within target_wait, but I'm not sure target_wait should be resuming the inferior. */ - TARGET_WAITKIND_SPURIOUS + TARGET_WAITKIND_SPURIOUS, + + /* This is used for target async and extended-async + only. Remote_async_wait() returns this when there is an event + on the inferior, but the rest of the world is not interested in + it. The inferior has not stopped, but has just sent some output + to the console, for instance. In this case, we want to go back + to the event loop and wait there for another event from the + inferior, rather than being stuck in the remote_async_wait() + function. This way the event loop is responsive to other events, + like for instance the user typing. */ + TARGET_WAITKIND_IGNORE }; /* The numbering of these signals is chosen to match traditional unix diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 30308c8..47d33a2 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,22 @@ +1999-12-13n Fernando Nasser <fnasser@totem.to.cygnus.com> + + * gdb.base/watchpoint.exp: Add missing "(timeout)" to test message. + +1999-12-13n Fernando Nasser <fnasser@totem.to.cygnus.com> + + * gdb.base/break.exp: Add missing anchor to reg exp on "finish from + outermost frame disallowed". + +1999-12-09 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * gdb.base/setvar.exp: New tests for setting the value of a struct + with a constant list. + +1999-12-08 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * gdb.base/setvar.exp: Remove pair os tests that expected gdb to + require the user to type a cast before setting the value of a struct. + 1999-12-06 Jim Blandy <jimb@cygnus.com> * gdb.base/default.exp: Expect the new 'info float' command on diff --git a/gdb/testsuite/gdb.base/break.exp b/gdb/testsuite/gdb.base/break.exp index a3d54ed..a076b53 100644 --- a/gdb/testsuite/gdb.base/break.exp +++ b/gdb/testsuite/gdb.base/break.exp @@ -619,7 +619,7 @@ send_gdb "finish\n" gdb_expect { -re "\"finish\" not meaningful in the outermost frame.\r\n$gdb_prompt $"\ {pass "finish from outermost frame disallowed"} - -re "Run till exit from.*" { + -re "Run till exit from.*\r\n$gdb_prompt $" { pass "finish from outermost frame disallowed" } -re "$gdb_prompt $"\ diff --git a/gdb/testsuite/gdb.base/setvar.exp b/gdb/testsuite/gdb.base/setvar.exp index 2c9b416..f321c9f 100644 --- a/gdb/testsuite/gdb.base/setvar.exp +++ b/gdb/testsuite/gdb.base/setvar.exp @@ -385,29 +385,33 @@ gdb_test "print v_struct1" \ v_long_member = 3,.*v_float_member = 4,.*v_double_member = 5.*\}" \ "set print structure #1" -# This should be an error. GCC extensions for structure constants require -# the type of the structure to be specified, as in +# Some believe that the following should be an error. GCC extensions for +# structure constants require the type of the structure to be specified, as in # v_struct1 = (struct t_struct) {32, 33, 34, 35, 36, 37} -# GDB should do the same if it wants to provide this feature. -# However, for HP's aCC this is OK, so we skip the tests for aCC -if {! $hp_aCC_compiler} { -if [target_info exists gdb,cannot_call_functions] { - setup_xfail "*-*-*" 2416 - fail "set variable v_struct1 = {32, 33, 34, 35, 36, 37}" - continue -} +# The argument is that GDB should do the same if it wants to provide this +# feature, i.e., require the cast. +# We decided that we don't want the debugger to be as picky as a +# compiler and make us type complex casts. + # We need to up this because this can be really slow on some boards. # (malloc() is called as part of the test). set timeout 60; -gdb_test "set variable v_struct1 = {32, 33, 34, 35, 36, 37}" "Invalid.*" -# And after the error the structure should be unchanged. -gdb_test "print v_struct1" \ +# Change the values +test_set "set variable v_struct1 = {32, 33, 34, 35, 36, 37}" \ + "print v_struct1" \ + ".*.\[0-9\]* = \{.*v_char_member = 32 \' \',.*v_short_member = 33,\ +.*v_int_member = 34,.*\ +v_long_member = 35,.*v_float_member = 36,.*v_double_member = 37.*\}" \ + "set print structure #2" + +# Change them back +test_set "set variable v_struct1 = {'h', 1, 2, 3, 4.0, 5.0}" \ + "print v_struct1" \ ".*.\[0-9\]* = \{.*v_char_member = 104 \'h\',.*v_short_member = 1,\ .*v_int_member = 2,.*\ v_long_member = 3,.*v_float_member = 4,.*v_double_member = 5.*\}" \ - "set print structure #2" -} + "set print structure #3" # Test printing of enumeration bitfields. # GNU C supports them, some other compilers don't. diff --git a/gdb/testsuite/gdb.base/watchpoint.exp b/gdb/testsuite/gdb.base/watchpoint.exp index 6be4e34..39c388e 100644 --- a/gdb/testsuite/gdb.base/watchpoint.exp +++ b/gdb/testsuite/gdb.base/watchpoint.exp @@ -420,7 +420,7 @@ proc test_stepping {} { -re ".*$gdb_prompt $" { fail "finish from marker1" } - default { fail "finish from marker1" ; return } + default { fail "finish from marker1 (timeout)" ; return } } gdb_test "next" "for \\(count = 0.*" "next to `for' in watchpoint.exp" @@ -448,7 +448,7 @@ proc test_stepping {} { -re ".*$gdb_prompt $" { fail "until out of loop" } - default { fail "until out of loop" ; return } + default { fail "until out of loop (timeout)" ; return } } gdb_test "step" "ival2 = count.*" "step to ival2 assignment" @@ -45,6 +45,7 @@ #include <sys/types.h> +#include <setjmp.h> #include "event-top.h" #include "gdb_string.h" @@ -464,10 +465,22 @@ NORETURN void (*error_hook) PARAMS ((void)) ATTR_NORETURN; +/* Generally one should use catch_errors rather than manipulating these + directly. The exception is main(). */ +#if defined(HAVE_SIGSETJMP) +#define SIGJMP_BUF sigjmp_buf +#define SIGSETJMP(buf) sigsetjmp(buf, 1) +#define SIGLONGJMP(buf,val) siglongjmp(buf,val) +#else +#define SIGJMP_BUF jmp_buf +#define SIGSETJMP(buf) setjmp(buf) +#define SIGLONGJMP(buf,val) longjmp(buf,val) +#endif + /* Where to go for return_to_top_level (RETURN_ERROR). */ - SIGJMP_BUF error_return; +static SIGJMP_BUF error_return; /* Where to go for return_to_top_level (RETURN_QUIT). */ - SIGJMP_BUF quit_return; +static SIGJMP_BUF quit_return; /* Return for reason REASON. This generally gets back to the command loop, but can be caught via catch_errors. */ @@ -485,7 +498,7 @@ return_to_top_level (reason) disable_current_display (); do_cleanups (ALL_CLEANUPS); - if (event_loop_p && target_can_async_p ()) + if (event_loop_p && target_can_async_p () && !target_executing) do_exec_cleanups (ALL_CLEANUPS); if (event_loop_p && sync_execution) do_exec_error_cleanups (ALL_CLEANUPS); @@ -19,8 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <setjmp.h> - /* From top.c. */ extern char *line; extern int linesize; @@ -30,21 +28,6 @@ extern int inhibit_gdbinit; extern int epoch_interface; extern char gdbinit[]; -/* Generally one should use catch_errors rather than manipulating these - directly. The exception is main(). */ -#if defined(HAVE_SIGSETJMP) -#define SIGJMP_BUF sigjmp_buf -#define SIGSETJMP(buf) sigsetjmp(buf, 1) -#define SIGLONGJMP(buf,val) siglongjmp(buf,val) -#else -#define SIGJMP_BUF jmp_buf -#define SIGSETJMP(buf) setjmp(buf) -#define SIGLONGJMP(buf,val) longjmp(buf,val) -#endif - -extern SIGJMP_BUF error_return; -extern SIGJMP_BUF quit_return; - extern void print_gdb_version PARAMS ((GDB_FILE *)); extern void source_command PARAMS ((char *, int)); diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 2c82e19..245f1d0 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -499,7 +499,7 @@ tracepoints_info (tpnum_exp, from_tty) printf_filtered ("%s ", local_hex_string_custom ((unsigned long) t->address, "08l")); - printf_filtered ("%-5d %-5d ", t->pass_count, t->step_count); + printf_filtered ("%-5d %-5ld ", t->pass_count, t->step_count); if (t->source_file) { @@ -1773,7 +1773,7 @@ trace_start_command (args, from_tty) char tmp[40]; sprintf_vma (tmp, t->address); - sprintf (buf, "QTDP:%x:%s:%c:%x:%x", t->number, tmp, /* address */ + sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number, tmp, /* address */ t->enabled == enabled ? 'E' : 'D', t->step_count, t->pass_count); diff --git a/gdb/valarith.c b/gdb/valarith.c index 1700716..97c3ca7 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -28,6 +28,7 @@ #include "language.h" #include "demangle.h" #include "gdb_string.h" +#include <math.h> /* Define whether or not the C operator '/' truncates towards zero for differently signed operands (truncation direction is undefined in C). */ @@ -573,7 +574,7 @@ value_ptr value_concat (arg1, arg2) value_ptr arg1, arg2; { - register value_ptr inval1, inval2, outval; + register value_ptr inval1, inval2, outval = NULL; int inval1len, inval2len; int count, idx; char *ptr; @@ -738,7 +739,7 @@ value_binop (arg1, arg2, op) /* FIXME-if-picky-about-floating-accuracy: Should be doing this in target format. real.c in GCC probably has the necessary code. */ - DOUBLEST v1, v2, v; + DOUBLEST v1, v2, v = 0; v1 = value_as_double (arg1); v2 = value_as_double (arg2); switch (op) @@ -759,6 +760,12 @@ value_binop (arg1, arg2, op) v = v1 / v2; break; + case BINOP_EXP: + v = pow (v1, v2); + if (errno) + error ("Cannot perform exponentiation: %s", strerror (errno)); + break; + default: error ("Integer-only operation on floating point number."); } @@ -779,7 +786,7 @@ value_binop (arg1, arg2, op) && TYPE_CODE (type2) == TYPE_CODE_BOOL) { - LONGEST v1, v2, v; + LONGEST v1, v2, v = 0; v1 = value_as_long (arg1); v2 = value_as_long (arg2); @@ -795,6 +802,14 @@ value_binop (arg1, arg2, op) case BINOP_BITWISE_XOR: v = v1 ^ v2; + break; + + case BINOP_EQUAL: + v = v1 == v2; + break; + + case BINOP_NOTEQUAL: + v = v1 != v2; break; default: @@ -855,7 +870,7 @@ value_binop (arg1, arg2, op) if (unsigned_operation) { - ULONGEST v1, v2, v; + ULONGEST v1, v2, v = 0; v1 = (ULONGEST) value_as_long (arg1); v2 = (ULONGEST) value_as_long (arg2); @@ -884,6 +899,12 @@ value_binop (arg1, arg2, op) v = v1 / v2; break; + case BINOP_EXP: + v = pow (v1, v2); + if (errno) + error ("Cannot perform exponentiation: %s", strerror (errno)); + break; + case BINOP_REM: v = v1 % v2; break; @@ -949,6 +970,10 @@ value_binop (arg1, arg2, op) v = v1 == v2; break; + case BINOP_NOTEQUAL: + v = v1 != v2; + break; + case BINOP_LESS: v = v1 < v2; break; @@ -976,7 +1001,7 @@ value_binop (arg1, arg2, op) } else { - LONGEST v1, v2, v; + LONGEST v1, v2, v = 0; v1 = value_as_long (arg1); v2 = value_as_long (arg2); @@ -996,6 +1021,12 @@ value_binop (arg1, arg2, op) case BINOP_DIV: v = v1 / v2; + break; + + case BINOP_EXP: + v = pow (v1, v2); + if (errno) + error ("Cannot perform exponentiation: %s", strerror (errno)); break; case BINOP_REM: @@ -1125,6 +1156,37 @@ value_logical_not (arg1) return len < 0; } +/* Perform a comparison on two string values (whose content are not + necessarily null terminated) based on their length */ + +static int +value_strcmp (arg1, arg2) + register value_ptr arg1, arg2; +{ + int len1 = TYPE_LENGTH (VALUE_TYPE (arg1)); + int len2 = TYPE_LENGTH (VALUE_TYPE (arg2)); + char *s1 = VALUE_CONTENTS (arg1); + char *s2 = VALUE_CONTENTS (arg2); + int i, len = len1 < len2 ? len1 : len2; + + for (i = 0; i < len; i++) + { + if (s1[i] < s2[i]) + return -1; + else if (s1[i] > s2[i]) + return 1; + else + continue; + } + + if (len1 < len2) + return -1; + else if (len1 > len2) + return 1; + else + return 0; +} + /* Simulate the C operator == by returning a 1 iff ARG1 and ARG2 have equal contents. */ @@ -1175,6 +1237,10 @@ value_equal (arg1, arg2) } return len < 0; } + else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING) + { + return value_strcmp (arg1, arg2) == 0; + } else { error ("Invalid type combination in equality test."); @@ -1217,7 +1283,8 @@ value_less (arg1, arg2) return value_as_pointer (arg1) < (CORE_ADDR) value_as_long (arg2); else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)) return (CORE_ADDR) value_as_long (arg1) < value_as_pointer (arg2); - + else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING) + return value_strcmp (arg1, arg2) < 0; else { error ("Invalid type combination in ordering comparison."); |