diff options
author | Andrew Cagney <cagney@redhat.com> | 2002-07-03 18:43:59 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2002-07-03 18:43:59 +0000 |
commit | a3f41504c1a26f5066953d0ce9b17dd1ff1e9017 (patch) | |
tree | 00b030fb9ebc6cf4e183710ddb6c8b3a03a1da81 | |
parent | f830f91903e28389b666b6477045d9e28c9cb5e3 (diff) | |
download | fsf-binutils-gdb-a3f41504c1a26f5066953d0ce9b17dd1ff1e9017.zip fsf-binutils-gdb-a3f41504c1a26f5066953d0ce9b17dd1ff1e9017.tar.gz fsf-binutils-gdb-a3f41504c1a26f5066953d0ce9b17dd1ff1e9017.tar.bz2 |
merge with trunk.
-rw-r--r-- | gdb/MAINTAINERS | 1 | ||||
-rw-r--r-- | gdb/Makefile.in | 2 | ||||
-rw-r--r-- | gdb/blockframe.c | 36 | ||||
-rw-r--r-- | gdb/cli/cli-decode.c | 20 | ||||
-rw-r--r-- | gdb/command.h | 6 | ||||
-rw-r--r-- | gdb/configure.tgt | 4 | ||||
-rw-r--r-- | gdb/frame.h | 2 | ||||
-rw-r--r-- | gdb/i386-linux-tdep.c | 111 | ||||
-rw-r--r-- | gdb/i386-sol2-tdep.c | 8 | ||||
-rw-r--r-- | gdb/i386-tdep.c | 145 | ||||
-rw-r--r-- | gdb/i386-tdep.h | 11 | ||||
-rw-r--r-- | gdb/i386bsd-nat.c | 22 | ||||
-rw-r--r-- | gdb/i386bsd-tdep.c | 65 | ||||
-rw-r--r-- | gdb/i386nbsd-tdep.c | 4 | ||||
-rw-r--r-- | gdb/m68k-tdep.c | 99 | ||||
-rw-r--r-- | gdb/macrotab.h | 4 | ||||
-rw-r--r-- | gdb/mcore-tdep.c | 129 | ||||
-rw-r--r-- | gdb/rs6000-tdep.c | 4 | ||||
-rw-r--r-- | gdb/solib-osf.c | 9 | ||||
-rw-r--r-- | gdb/top.c | 4 | ||||
-rw-r--r-- | gdb/valops.c | 57 | ||||
-rw-r--r-- | gdb/version.in | 2 |
22 files changed, 494 insertions, 251 deletions
diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS index 3478121..1501c83 100644 --- a/gdb/MAINTAINERS +++ b/gdb/MAINTAINERS @@ -424,6 +424,7 @@ Alexandre Oliva aoliva@redhat.com Tom Rix trix@redhat.com Theodore A. Roth troth@verinet.com Ian Roxborough irox@redhat.com +Grace Sainsbury graces@redhat.com Mark Salter msalter@redhat.com Peter Schauer Peter.Schauer@regent Andreas Schwab schwab@suse.de diff --git a/gdb/Makefile.in b/gdb/Makefile.in index ef35ccc..d62c4f8 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -637,7 +637,7 @@ inferior_h = inferior.h $(breakpoint_h) language_h = language.h linespec_h = linespec.h macroexp_h = macroexp.h -macrotab_h = macrotab.h $(obstack_h) $(bcache_h) +macrotab_h = macrotab.h macroscope_h = macroscope.h $(macrotab_h) $(symtab_h) memattr_h = memattr.h monitor_h = monitor.h diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 9971e5d..8f95a89 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -528,6 +528,26 @@ get_frame_pc (struct frame_info *frame) return frame->pc; } +/* return the address of the PC for the given FRAME, ie the current PC value + if FRAME is the innermost frame, or the address adjusted to point to the + call instruction if not. */ + +CORE_ADDR +frame_address_in_block (struct frame_info *frame) +{ + CORE_ADDR pc = frame->pc; + + /* If we are not in the innermost frame, and we are not interrupted + by a signal, frame->pc points to the instruction following the + call. As a consequence, we need to get the address of the previous + instruction. Unfortunately, this is not straightforward to do, so + we just use the address minus one, which is a good enough + approximation. */ + if (frame->next != 0 && frame->next->signal_handler_caller == 0) + --pc; + + return pc; +} #ifdef FRAME_FIND_SAVED_REGS /* XXX - deprecated. This is a compatibility function for targets @@ -576,17 +596,7 @@ get_frame_saved_regs (struct frame_info *frame, struct block * get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block) { - CORE_ADDR pc; - - pc = frame->pc; - if (frame->next != 0 && frame->next->signal_handler_caller == 0) - /* We are not in the innermost frame and we were not interrupted - by a signal. We need to subtract one to get the correct block, - in case the call instruction was the last instruction of the block. - If there are any machines on which the saved pc does not point to - after the call insn, we probably want to make frame->pc point after - the call insn anyway. */ - --pc; + const CORE_ADDR pc = frame_address_in_block (frame); if (addr_in_block) *addr_in_block = pc; @@ -970,6 +980,7 @@ block_innermost_frame (struct block *block) struct frame_info *frame; register CORE_ADDR start; register CORE_ADDR end; + CORE_ADDR calling_pc; if (block == NULL) return NULL; @@ -983,7 +994,8 @@ block_innermost_frame (struct block *block) frame = get_prev_frame (frame); if (frame == NULL) return NULL; - if (frame->pc >= start && frame->pc < end) + calling_pc = frame_address_in_block (frame); + if (calling_pc >= start && calling_pc < end) return frame; } } diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c index 098c13a..84e445e 100644 --- a/gdb/cli/cli-decode.c +++ b/gdb/cli/cli-decode.c @@ -1505,3 +1505,23 @@ complete_on_enum (const char *enumlist[], return matchlist; } + +/* check function pointer */ +int +cmd_func_p (struct cmd_list_element *cmd) +{ + return (cmd->func != NULL); +} + + +/* call the command function */ +void +cmd_func (struct cmd_list_element *cmd, char *args, int from_tty) +{ + if (cmd_func_p (cmd)) + (*cmd->func) (cmd, args, from_tty); + else + error ("Invalid command"); +} + + diff --git a/gdb/command.h b/gdb/command.h index 9aceef6..96c99ab 100644 --- a/gdb/command.h +++ b/gdb/command.h @@ -280,4 +280,10 @@ extern void dont_repeat (void); extern void not_just_help_class_command (char *, int); +/* check function pointer */ +extern int cmd_func_p (struct cmd_list_element *cmd); + +/* call the command function */ +extern void cmd_func (struct cmd_list_element *cmd, char *args, int from_tty); + #endif /* !defined (COMMAND_H) */ diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 02c6581..8e3cf6d 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -94,12 +94,12 @@ i[3456]86-*-aix*) gdb_target=i386aix ;; i[3456]86-*-bsd*) gdb_target=i386bsd ;; i[3456]86-*-freebsd*) gdb_target=fbsd ;; i[3456]86-*-netbsdelf*) gdb_target=nbsdelf ;; -i[3456]86-*-netbsd*) gdb_target=nbsdaout ;; +i[3456]86-*-netbsd* | i[3456]86-*-openbsd*) + gdb_target=nbsdaout ;; i[3456]86-*-os9k) gdb_target=i386os9k ;; i[3456]86-*-go32*) gdb_target=i386aout ;; i[3456]86-*-msdosdjgpp*) gdb_target=go32 ;; i[3456]86-*-lynxos*) gdb_target=i386lynx ;; -i[3456]86-*-openbsd*) gdb_target=obsd ;; i[3456]86-*-solaris*) gdb_target=i386sol2 ;; i[3456]86-*-sysv4.2*) gdb_target=i386v42mp ;; i[3456]86-*-sysv4*) gdb_target=i386v4 ;; diff --git a/gdb/frame.h b/gdb/frame.h index d3bd2ab..20ffff0 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -250,6 +250,8 @@ extern struct symbol *get_frame_function (struct frame_info *); extern CORE_ADDR get_frame_pc (struct frame_info *); +extern CORE_ADDR frame_address_in_block (struct frame_info *); + extern CORE_ADDR get_pc_function_start (CORE_ADDR); extern struct block *block_for_pc (CORE_ADDR); diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 8fa9261..394699f 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -240,7 +240,7 @@ i386_linux_pc_in_sigtramp (CORE_ADDR pc, char *name) /* Assuming FRAME is for a GNU/Linux sigtramp routine, return the address of the associated sigcontext structure. */ -CORE_ADDR +static CORE_ADDR i386_linux_sigcontext_addr (struct frame_info *frame) { CORE_ADDR pc; @@ -286,100 +286,6 @@ i386_linux_sigcontext_addr (struct frame_info *frame) return 0; } -/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>. */ -#define LINUX_SIGCONTEXT_PC_OFFSET (56) - -/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the - saved program counter. */ - -static CORE_ADDR -i386_linux_sigtramp_saved_pc (struct frame_info *frame) -{ - CORE_ADDR addr; - addr = i386_linux_sigcontext_addr (frame); - return read_memory_integer (addr + LINUX_SIGCONTEXT_PC_OFFSET, 4); -} - -/* Offset to saved SP in sigcontext, from <asm/sigcontext.h>. */ -#define LINUX_SIGCONTEXT_SP_OFFSET (28) - -/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the - saved stack pointer. */ - -static CORE_ADDR -i386_linux_sigtramp_saved_sp (struct frame_info *frame) -{ - CORE_ADDR addr; - addr = i386_linux_sigcontext_addr (frame); - return read_memory_integer (addr + LINUX_SIGCONTEXT_SP_OFFSET, 4); -} - -/* Signal trampolines don't have a meaningful frame. As in - "i386/tm-i386.h", the frame pointer value we use is actually the - frame pointer of the calling frame -- that is, the frame which was - in progress when the signal trampoline was entered. GDB mostly - treats this frame pointer value as a magic cookie. We detect the - case of a signal trampoline by looking at the SIGNAL_HANDLER_CALLER - field, which is set based on PC_IN_SIGTRAMP. - - When a signal trampoline is invoked from a frameless function, we - essentially have two frameless functions in a row. In this case, - we use the same magic cookie for three frames in a row. We detect - this case by seeing whether the next frame has - SIGNAL_HANDLER_CALLER set, and, if it does, checking whether the - current frame is actually frameless. In this case, we need to get - the PC by looking at the SP register value stored in the signal - context. - - This should work in most cases except in horrible situations where - a signal occurs just as we enter a function but before the frame - has been set up. */ - -#define FRAMELESS_SIGNAL(frame) \ - ((frame)->next != NULL \ - && (frame)->next->signal_handler_caller \ - && frameless_look_for_prologue (frame)) - -CORE_ADDR -i386_linux_frame_chain (struct frame_info *frame) -{ - if (frame->signal_handler_caller || FRAMELESS_SIGNAL (frame)) - return frame->frame; - - if (! inside_entry_file (frame->pc)) - return read_memory_unsigned_integer (frame->frame, 4); - - return 0; -} - -/* Return the saved program counter for FRAME. */ - -CORE_ADDR -i386_linux_frame_saved_pc (struct frame_info *frame) -{ - if (frame->signal_handler_caller) - return i386_linux_sigtramp_saved_pc (frame); - - if (FRAMELESS_SIGNAL (frame)) - { - CORE_ADDR sp = i386_linux_sigtramp_saved_sp (frame->next); - return read_memory_unsigned_integer (sp, 4); - } - - return read_memory_unsigned_integer (frame->frame + 4, 4); -} - -/* Immediately after a function call, return the saved pc. */ - -CORE_ADDR -i386_linux_saved_pc_after_call (struct frame_info *frame) -{ - if (frame->signal_handler_caller) - return i386_linux_sigtramp_saved_pc (frame); - - return read_memory_unsigned_integer (read_register (SP_REGNUM), 4); -} - /* Set the program counter for process PTID to PC. */ static void @@ -557,16 +463,15 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->jb_pc_offset = 20; /* From <bits/setjmp.h>. */ - /* When the i386 Linux kernel calls a signal handler, the return - address points to a bit of code on the stack. These definitions - are used to identify this bit of code as a signal trampoline in - order to support backtracing through calls to signal handlers. */ + tdep->sigcontext_addr = i386_linux_sigcontext_addr; + tdep->sc_pc_offset = 14 * 4; /* From <asm/sigcontext.h>. */ + tdep->sc_sp_offset = 7 * 4; + /* When the i386 Linux kernel calls a signal handler, the return + address points to a bit of code on the stack. This function is + used to identify this bit of code as a signal trampoline in order + to support backtracing through calls to signal handlers. */ set_gdbarch_pc_in_sigtramp (gdbarch, i386_linux_pc_in_sigtramp); - set_gdbarch_frame_chain (gdbarch, i386_linux_frame_chain); - set_gdbarch_frame_saved_pc (gdbarch, i386_linux_frame_saved_pc); - set_gdbarch_saved_pc_after_call (gdbarch, i386_linux_saved_pc_after_call); - tdep->sigtramp_saved_pc = i386_linux_sigtramp_saved_pc; set_solib_svr4_fetch_link_map_offsets (gdbarch, i386_linux_svr4_fetch_link_map_offsets); diff --git a/gdb/i386-sol2-tdep.c b/gdb/i386-sol2-tdep.c index 206e85c..023e446 100644 --- a/gdb/i386-sol2-tdep.c +++ b/gdb/i386-sol2-tdep.c @@ -19,6 +19,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "value.h" #include "i386-tdep.h" @@ -43,8 +44,13 @@ i386_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Signal trampolines are different from SVR4, in fact they're rather similar to BSD. */ set_gdbarch_pc_in_sigtramp (gdbarch, i386_sol2_pc_in_sigtramp); - tdep->sigtramp_saved_pc = i386bsd_sigtramp_saved_pc; + tdep->sigcontext_addr = i386bsd_sigcontext_addr; tdep->sc_pc_offset = 36 + 14 * 4; + tdep->sc_sp_offset = 36 + 7 * 4; + + /* Assume that the prototype flag can be trusted. */ + set_gdbarch_coerce_float_to_double (gdbarch, + standard_coerce_float_to_double); } diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 1a838f2..8efba94 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -452,6 +452,38 @@ i386_get_frame_setup (CORE_ADDR pc) return (-1); } +/* Signal trampolines don't have a meaningful frame. The frame + pointer value we use is actually the frame pointer of the calling + frame -- that is, the frame which was in progress when the signal + trampoline was entered. GDB mostly treats this frame pointer value + as a magic cookie. We detect the case of a signal trampoline by + looking at the SIGNAL_HANDLER_CALLER field, which is set based on + PC_IN_SIGTRAMP. + + When a signal trampoline is invoked from a frameless function, we + essentially have two frameless functions in a row. In this case, + we use the same magic cookie for three frames in a row. We detect + this case by seeing whether the next frame has + SIGNAL_HANDLER_CALLER set, and, if it does, checking whether the + current frame is actually frameless. In this case, we need to get + the PC by looking at the SP register value stored in the signal + context. + + This should work in most cases except in horrible situations where + a signal occurs just as we enter a function but before the frame + has been set up. */ + +/* Return non-zero if we're dealing with a frameless signal, that is, + a signal trampoline invoked from a frameless function. */ + +static int +i386_frameless_signal_p (struct frame_info *frame) +{ + return (frame->next + && frame->next->signal_handler_caller + && frameless_look_for_prologue (frame)); +} + /* Return the chain-pointer for FRAME. In the case of the i386, the frame's nominal address is the address of a 4-byte word containing the calling frame's address. */ @@ -459,7 +491,8 @@ i386_get_frame_setup (CORE_ADDR pc) static CORE_ADDR i386_frame_chain (struct frame_info *frame) { - if (frame->signal_handler_caller) + if (frame->signal_handler_caller + || i386_frameless_signal_p (frame)) return frame->frame; if (! inside_entry_file (frame->pc)) @@ -472,7 +505,7 @@ i386_frame_chain (struct frame_info *frame) not have a from on the stack associated with it. If it does not, return non-zero, otherwise return zero. */ -int +static int i386_frameless_function_invocation (struct frame_info *frame) { if (frame->signal_handler_caller) @@ -481,18 +514,44 @@ i386_frameless_function_invocation (struct frame_info *frame) return frameless_look_for_prologue (frame); } +/* Assuming FRAME is for a sigtramp routine, return the saved program + counter. */ + +static CORE_ADDR +i386_sigtramp_saved_pc (struct frame_info *frame) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + CORE_ADDR addr; + + addr = tdep->sigcontext_addr (frame); + return read_memory_unsigned_integer (addr + tdep->sc_pc_offset, 4); +} + +/* Assuming FRAME is for a sigtramp routine, return the saved stack + pointer. */ + +static CORE_ADDR +i386_sigtramp_saved_sp (struct frame_info *frame) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + CORE_ADDR addr; + + addr = tdep->sigcontext_addr (frame); + return read_memory_unsigned_integer (addr + tdep->sc_sp_offset, 4); +} + /* Return the saved program counter for FRAME. */ static CORE_ADDR i386_frame_saved_pc (struct frame_info *frame) { if (frame->signal_handler_caller) - { - CORE_ADDR (*sigtramp_saved_pc) (struct frame_info *); - sigtramp_saved_pc = gdbarch_tdep (current_gdbarch)->sigtramp_saved_pc; + return i386_sigtramp_saved_pc (frame); - gdb_assert (sigtramp_saved_pc != NULL); - return sigtramp_saved_pc (frame); + if (i386_frameless_signal_p (frame)) + { + CORE_ADDR sp = i386_sigtramp_saved_sp (frame->next); + return read_memory_unsigned_integer (sp, 4); } return read_memory_unsigned_integer (frame->frame + 4, 4); @@ -503,13 +562,16 @@ i386_frame_saved_pc (struct frame_info *frame) static CORE_ADDR i386_saved_pc_after_call (struct frame_info *frame) { + if (frame->signal_handler_caller) + return i386_sigtramp_saved_pc (frame); + return read_memory_unsigned_integer (read_register (SP_REGNUM), 4); } /* Return number of args passed to a frame. Can return -1, meaning no way to tell. */ -int +static int i386_frame_num_args (struct frame_info *fi) { #if 1 @@ -606,7 +668,7 @@ i386_frame_num_args (struct frame_info *fi) If the setup sequence is at the end of the function, then the next instruction will be a branch back to the start. */ -void +static void i386_frame_init_saved_regs (struct frame_info *fip) { long locals = -1; @@ -666,7 +728,7 @@ i386_frame_init_saved_regs (struct frame_info *fip) /* Return PC of first real instruction. */ -CORE_ADDR +static CORE_ADDR i386_skip_prologue (CORE_ADDR pc) { unsigned char op; @@ -767,7 +829,7 @@ i386_breakpoint_from_pc (CORE_ADDR *pc, int *len) return break_insn; } -void +static void i386_push_dummy_frame (void) { CORE_ADDR sp = read_register (SP_REGNUM); @@ -803,7 +865,7 @@ static LONGEST i386_call_dummy_words[] = /* Insert the (relative) function address into the call sequence stored at DYMMY. */ -void +static void i386_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p) { @@ -820,7 +882,7 @@ i386_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, *((char *)(dummy) + 4) = ((delta >> 24) & 0xff); } -void +static void i386_pop_frame (void) { struct frame_info *frame = get_current_frame (); @@ -880,7 +942,7 @@ i386_get_longjmp_target (CORE_ADDR *pc) } -CORE_ADDR +static CORE_ADDR i386_push_arguments (int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { @@ -898,7 +960,7 @@ i386_push_arguments (int nargs, struct value **args, CORE_ADDR sp, return sp; } -void +static void i386_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) { /* Do nothing. Everything was already done by i386_push_arguments. */ @@ -914,7 +976,7 @@ i386_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) function return value of TYPE, and copy that, in virtual format, into VALBUF. */ -void +static void i386_extract_return_value (struct type *type, char *regbuf, char *valbuf) { int len = TYPE_LENGTH (type); @@ -965,7 +1027,7 @@ i386_extract_return_value (struct type *type, char *regbuf, char *valbuf) /* Write into the appropriate registers a function return value stored in VALBUF of type TYPE, given in virtual format. */ -void +static void i386_store_return_value (struct type *type, char *valbuf) { int len = TYPE_LENGTH (type); @@ -1037,7 +1099,7 @@ i386_store_return_value (struct type *type, char *valbuf) the address in which a function should return its structure value, as a CORE_ADDR. */ -CORE_ADDR +static CORE_ADDR i386_extract_struct_value_address (char *regbuf) { return extract_address (®buf[REGISTER_BYTE (LOW_RETURN_REGNUM)], @@ -1080,7 +1142,7 @@ i386_use_struct_convention (int gcc_p, struct type *type) register REGNUM. Perhaps %esi and %edi should go here, but potentially they could be used for things other than address. */ -struct type * +static struct type * i386_register_virtual_type (int regnum) { if (regnum == PC_REGNUM || regnum == FP_REGNUM || regnum == SP_REGNUM) @@ -1101,7 +1163,7 @@ i386_register_virtual_type (int regnum) registers need conversion. Even if we can't find a counterexample, this is still sloppy. */ -int +static int i386_register_convertible (int regnum) { return IS_FP_REGNUM (regnum); @@ -1110,7 +1172,7 @@ i386_register_convertible (int regnum) /* Convert data from raw format for register REGNUM in buffer FROM to virtual format with type TYPE in buffer TO. */ -void +static void i386_register_convert_to_virtual (int regnum, struct type *type, char *from, char *to) { @@ -1133,7 +1195,7 @@ i386_register_convert_to_virtual (int regnum, struct type *type, /* Convert data from virtual format with type TYPE in buffer FROM to raw format for register REGNUM in buffer TO. */ -void +static void i386_register_convert_to_raw (struct type *type, int regnum, char *from, char *to) { @@ -1244,29 +1306,31 @@ i386_svr4_pc_in_sigtramp (CORE_ADDR pc, char *name) || strcmp ("sigvechandler", name) == 0)); } -/* Get saved user PC for sigtramp from the pushed ucontext on the - stack for all three variants of SVR4 sigtramps. */ +/* Get address of the pushed ucontext (sigcontext) on the stack for + all three variants of SVR4 sigtramps. */ -CORE_ADDR -i386_svr4_sigtramp_saved_pc (struct frame_info *frame) +static CORE_ADDR +i386_svr4_sigcontext_addr (struct frame_info *frame) { - CORE_ADDR saved_pc_offset = 4; + int sigcontext_offset = -1; char *name = NULL; find_pc_partial_function (frame->pc, &name, NULL, NULL); if (name) { if (strcmp (name, "_sigreturn") == 0) - saved_pc_offset = 132 + 14 * 4; + sigcontext_offset = 132; else if (strcmp (name, "_sigacthandler") == 0) - saved_pc_offset = 80 + 14 * 4; + sigcontext_offset = 80; else if (strcmp (name, "sigvechandler") == 0) - saved_pc_offset = 120 + 14 * 4; + sigcontext_offset = 120; } + gdb_assert (sigcontext_offset != -1); + if (frame->next) - return read_memory_integer (frame->next->frame + saved_pc_offset, 4); - return read_memory_integer (read_register (SP_REGNUM) + saved_pc_offset, 4); + return frame->next->frame + sigcontext_offset; + return read_register (SP_REGNUM) + sigcontext_offset; } @@ -1303,14 +1367,16 @@ i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid); set_gdbarch_pc_in_sigtramp (gdbarch, i386_svr4_pc_in_sigtramp); - tdep->sigtramp_saved_pc = i386_svr4_sigtramp_saved_pc; + tdep->sigcontext_addr = i386_svr4_sigcontext_addr; + tdep->sc_pc_offset = 14 * 4; + tdep->sc_sp_offset = 7 * 4; tdep->jb_pc_offset = 20; } /* DJGPP. */ -void +static void i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -1322,7 +1388,7 @@ i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* NetWare. */ -void +static void i386_nw_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -1334,7 +1400,7 @@ i386_nw_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) } -struct gdbarch * +static struct gdbarch * i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch_tdep *tdep; @@ -1369,17 +1435,18 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->jb_pc_offset = -1; tdep->struct_return = pcc_struct_return; - tdep->sigtramp_saved_pc = NULL; tdep->sigtramp_start = 0; tdep->sigtramp_end = 0; + tdep->sigcontext_addr = NULL; tdep->sc_pc_offset = -1; + tdep->sc_sp_offset = -1; /* The format used for `long double' on almost all i386 targets is the i387 extended floating-point format. In fact, of all targets in the GCC 2.95 tree, only OSF/1 does it different, and insists on having a `long double' that's not `long' at all. */ set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext); - + /* Although the i386 extended floating-point has only 80 significant bits, a `long double' actually takes up 96, probably to enforce alignment. */ @@ -1388,7 +1455,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* NOTE: tm-i386aix.h, tm-i386bsd.h, tm-i386os9k.h, tm-ptx.h, tm-symmetry.h currently override this. Sigh. */ set_gdbarch_num_regs (gdbarch, I386_NUM_GREGS + I386_NUM_FREGS); - + set_gdbarch_sp_regnum (gdbarch, 4); set_gdbarch_fp_regnum (gdbarch, 5); set_gdbarch_pc_regnum (gdbarch, 8); diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index 61a8178..d255c40 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -65,15 +65,16 @@ struct gdbarch_tdep /* Convention for returning structures. */ enum struct_return struct_return; - /* Get saved PC for sigtramp. */ - CORE_ADDR (*sigtramp_saved_pc) (struct frame_info *); - /* Address range where sigtramp lives. */ CORE_ADDR sigtramp_start; CORE_ADDR sigtramp_end; - /* Offset of saved PC in `struct sigcontext'. */ + /* Get address of sigcontext for sigtramp. */ + CORE_ADDR (*sigcontext_addr) (struct frame_info *); + + /* Offset of saved PC and SP in `struct sigcontext'. */ int sc_pc_offset; + int sc_sp_offset; }; /* Floating-point registers. */ @@ -175,6 +176,6 @@ extern void i386_svr4_init_abi (struct gdbarch_info, struct gdbarch *); /* Functions exported from i386bsd-tdep.c. */ -extern CORE_ADDR i386bsd_sigtramp_saved_pc (struct frame_info *frame); +extern CORE_ADDR i386bsd_sigcontext_addr (struct frame_info *frame); #endif /* i386-tdep.h */ diff --git a/gdb/i386bsd-nat.c b/gdb/i386bsd-nat.c index 3ab22a9..8a3acd4 100644 --- a/gdb/i386bsd-nat.c +++ b/gdb/i386bsd-nat.c @@ -387,6 +387,7 @@ void _initialize_i386bsd_nat (void) { int sc_pc_offset; + int sc_sp_offset; /* To support the recognition of signal handlers, i386bsd-tdep.c hardcodes some constants. Inclusion of this file means that we @@ -396,13 +397,19 @@ _initialize_i386bsd_nat (void) #if defined (__FreeBSD_version) && __FreeBSD_version >= 400011 extern int i386fbsd4_sc_pc_offset; + extern int i386fbsd4_sc_sp_offset; #define SC_PC_OFFSET i386fbsd4_sc_pc_offset -#elif defined (NetBSD) || defined (__NetBSD_Version__) +#define SC_SP_OFFSET i386fbsd4_sc_sp_offset +#elif defined (NetBSD) || defined (__NetBSD_Version__) || defined (OpenBSD) extern int i386nbsd_sc_pc_offset; + extern int i386nbsd_sc_sp_offset; #define SC_PC_OFFSET i386nbsd_sc_pc_offset +#define SC_SP_OFFSET i386nbsd_sc_sp_offset #else extern int i386bsd_sc_pc_offset; + extern int i386bsd_sc_sp_offset; #define SC_PC_OFFSET i386bsd_sc_pc_offset +#define SC_SP_OFFSET i386bsd_sc_sp_offset #endif /* Override the default value for the offset of the program counter @@ -418,4 +425,17 @@ Please report this to <bug-gdb@gnu.org>.", } SC_PC_OFFSET = sc_pc_offset; + + /* Likewise for the stack pointer. */ + sc_sp_offset = offsetof (struct sigcontext, sc_sp); + + if (SC_SP_OFFSET != sc_sp_offset) + { + warning ("\ +offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\ +Please report this to <bug-gdb@gnu.org>.", + sc_sp_offset, SC_SP_OFFSET); + } + + SC_SP_OFFSET = sc_sp_offset; } diff --git a/gdb/i386bsd-tdep.c b/gdb/i386bsd-tdep.c index e6427b3..61213ff 100644 --- a/gdb/i386bsd-tdep.c +++ b/gdb/i386bsd-tdep.c @@ -19,6 +19,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "arch-utils.h" #include "frame.h" #include "gdbcore.h" #include "regcache.h" @@ -38,9 +39,12 @@ i386bsd_pc_in_sigtramp (CORE_ADDR pc, char *name) } /* Assuming FRAME is for a BSD sigtramp routine, return the address of - the associated sigcontext structure. */ + the associated sigcontext structure. -static CORE_ADDR + Note: This function is used for Solaris 2 too, so don't make it + static. */ + +CORE_ADDR i386bsd_sigcontext_addr (struct frame_info *frame) { if (frame->next) @@ -54,33 +58,6 @@ i386bsd_sigcontext_addr (struct frame_info *frame) return read_memory_unsigned_integer (read_register (SP_REGNUM) + 8, 4); } -/* Assuming FRAME is for a BSD sigtramp routine, return the saved - program counter. - - Note: This function is used for Solaris 2 too, so don't make it - static. */ - -CORE_ADDR -i386bsd_sigtramp_saved_pc (struct frame_info *frame) -{ - int sc_pc_offset = gdbarch_tdep (current_gdbarch)->sc_pc_offset; - CORE_ADDR addr; - - addr = i386bsd_sigcontext_addr (frame); - return read_memory_unsigned_integer (addr + sc_pc_offset, 4); -} - -/* Return the saved program counter for FRAME. */ - -static CORE_ADDR -i386bsd_frame_saved_pc (struct frame_info *frame) -{ - if (frame->signal_handler_caller) - return i386bsd_sigtramp_saved_pc (frame); - - return read_memory_unsigned_integer (frame->frame + 4, 4); -} - /* Return the start address of the sigtramp routine. */ CORE_ADDR @@ -98,10 +75,21 @@ i386bsd_sigtramp_end (CORE_ADDR pc) } +/* Support for shared libraries. */ + +/* Return non-zero if we are in a shared library trampoline code stub. */ + +int +i386bsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name) +{ + return (name && !strcmp (name, "_DYNAMIC")); +} + /* Traditional BSD (4.3 BSD, still used for BSDI and 386BSD). */ /* From <machine/signal.h>. */ int i386bsd_sc_pc_offset = 20; +int i386bsd_sc_sp_offset = 8; static void i386bsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) @@ -110,18 +98,24 @@ i386bsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_pc_in_sigtramp (gdbarch, i386bsd_pc_in_sigtramp); + /* Assume SunOS-style shared libraries. */ + set_gdbarch_in_solib_call_trampoline (gdbarch, + i386bsd_aout_in_solib_call_trampoline); + tdep->jb_pc_offset = 0; - tdep->sigtramp_saved_pc = i386bsd_sigtramp_saved_pc; tdep->sigtramp_start = 0xfdbfdfc0; tdep->sigtramp_end = 0xfdbfe000; + tdep->sigcontext_addr = i386bsd_sigcontext_addr; tdep->sc_pc_offset = i386bsd_sc_pc_offset; + tdep->sc_sp_offset = i386bsd_sc_sp_offset; } /* NetBSD 1.0 or later. */ /* From <machine/signal.h>. */ int i386nbsd_sc_pc_offset = 44; +int i386nbsd_sc_sp_offset = 56; static void i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) @@ -141,6 +135,7 @@ i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* NetBSD has a `struct sigcontext' that's different from the origional 4.3 BSD. */ tdep->sc_pc_offset = i386nbsd_sc_pc_offset; + tdep->sc_sp_offset = i386nbsd_sc_sp_offset; } /* NetBSD ELF. */ @@ -155,6 +150,10 @@ i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* But ELF-based. */ i386_elf_init_abi (info, gdbarch); + /* NetBSD ELF uses SVR4-style shared libraries. */ + set_gdbarch_in_solib_call_trampoline (gdbarch, + generic_in_solib_call_trampoline); + /* NetBSD ELF uses -fpcc-struct-return by default. */ tdep->struct_return = pcc_struct_return; @@ -193,12 +192,17 @@ i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Except that it uses ELF. */ i386_elf_init_abi (info, gdbarch); + + /* FreeBSD ELF uses SVR4-style shared libraries. */ + set_gdbarch_in_solib_call_trampoline (gdbarch, + generic_in_solib_call_trampoline); } /* FreeBSD 4.0-RELEASE or later. */ /* From <machine/signal.h>. */ int i386fbsd4_sc_pc_offset = 76; +int i386fbsd4_sc_sp_offset = 88; static void i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) @@ -211,6 +215,7 @@ i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* FreeBSD 4.0 introduced a new `struct sigcontext'. */ tdep->sc_pc_offset = i386fbsd4_sc_pc_offset; + tdep->sc_sp_offset = i386fbsd4_sc_sp_offset; } diff --git a/gdb/i386nbsd-tdep.c b/gdb/i386nbsd-tdep.c index c327d42..634101a 100644 --- a/gdb/i386nbsd-tdep.c +++ b/gdb/i386nbsd-tdep.c @@ -86,8 +86,8 @@ fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, } static void -fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which, - CORE_ADDR ignore) +fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, + int which, CORE_ADDR ignore) { switch (which) { diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index d1ab13f..a39fa94 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -42,17 +42,83 @@ #define P_FMOVM 0xf237 #define P_TRAP 0x4e40 + +/* Register numbers of various important registers. + Note that some of these values are "real" register numbers, + and correspond to the general registers of the machine, + and some are "phony" register numbers which are too large + to be actual register numbers as far as the user is concerned + but do serve to get the desired values when passed to read_register. */ + +/* Note: Since they are used in files other than this (monitor files), + D0_REGNUM and A0_REGNUM are currently defined in tm-m68k.h. */ + enum { + E_A1_REGNUM = 9, E_FP_REGNUM = 14, /* Contains address of executing stack frame */ E_SP_REGNUM = 15, /* Contains address of top of stack */ E_PS_REGNUM = 16, /* Contains processor status */ E_PC_REGNUM = 17, /* Contains program counter */ - E_FP0_REGNUM = 18 /* Floating point register 0 */ + E_FP0_REGNUM = 18, /* Floating point register 0 */ + E_FPC_REGNUM = 26, /* 68881 control register */ + E_FPS_REGNUM = 27, /* 68881 status register */ + E_FPI_REGNUM = 28 }; +#define REGISTER_BYTES_FP (16*4 + 8 + 8*12 + 3*4) +#define REGISTER_BYTES_NOFP (16*4 + 8) + +#define NUM_FREGS (NUM_REGS-24) + +/* Offset from SP to first arg on stack at first instruction of a function */ + +#define SP_ARG0 (1 * 4) + +/* This was determined by experimentation on hp300 BSD 4.3. Perhaps + it corresponds to some offset in /usr/include/sys/user.h or + something like that. Using some system include file would + have the advantage of probably being more robust in the face + of OS upgrades, but the disadvantage of being wrong for + cross-debugging. */ + +#define SIG_PC_FP_OFFSET 530 + +#define TARGET_M68K + + +#if !defined (BPT_VECTOR) +#define BPT_VECTOR 0xf +#endif + +#if !defined (REMOTE_BPT_VECTOR) +#define REMOTE_BPT_VECTOR 1 +#endif + + void m68k_frame_init_saved_regs (struct frame_info *frame_info); + +/* gdbarch_breakpoint_from_pc is set to m68k_local_breakpoint_from_pc + so m68k_remote_breakpoint_from_pc is currently not used. */ + +const static unsigned char * +m68k_remote_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) +{ + static unsigned char break_insn[] = {0x4e, (0x40 | REMOTE_BPT_VECTOR)}; + *lenptr = sizeof (break_insn); + return break_insn; +} + +const static unsigned char * +m68k_local_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) +{ + static unsigned char break_insn[] = {0x4e, (0x40 | BPT_VECTOR)}; + *lenptr = sizeof (break_insn); + return break_insn; +} + + static int m68k_register_bytes_ok (numbytes) { @@ -92,7 +158,7 @@ m68k_register_virtual_size (int regnum) static struct type * m68k_register_virtual_type (int regnum) { - if ((unsigned) regnum >= FPC_REGNUM) + if ((unsigned) regnum >= E_FPC_REGNUM) return lookup_pointer_type (builtin_type_void); else if ((unsigned) regnum >= FP0_REGNUM) return builtin_type_long_double; @@ -138,8 +204,8 @@ m68k_stack_align (CORE_ADDR addr) static int m68k_register_byte (int regnum) { - if (regnum >= FPC_REGNUM) - return (((regnum - FPC_REGNUM) * 4) + 168); + if (regnum >= E_FPC_REGNUM) + return (((regnum - E_FPC_REGNUM) * 4) + 168); else if (regnum >= FP0_REGNUM) return (((regnum - FP0_REGNUM) * 12) + 72); else @@ -152,7 +218,7 @@ m68k_register_byte (int regnum) static void m68k_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) { - write_register (A1_REGNUM, addr); + write_register (E_A1_REGNUM, addr); } /* Extract from an array regbuf containing the (raw) register state @@ -795,14 +861,14 @@ supply_fpregset (fpregset_t *fpregsetp) register int regi; char *from; - for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++) + for (regi = FP0_REGNUM; regi < E_FPC_REGNUM; regi++) { from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]); supply_register (regi, from); } - supply_register (FPC_REGNUM, (char *) &(fpregsetp->f_pcr)); - supply_register (FPS_REGNUM, (char *) &(fpregsetp->f_psr)); - supply_register (FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr)); + supply_register (E_FPC_REGNUM, (char *) &(fpregsetp->f_pcr)); + supply_register (E_FPS_REGNUM, (char *) &(fpregsetp->f_psr)); + supply_register (E_FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr)); } /* Given a pointer to a floating point register set in /proc format @@ -817,7 +883,7 @@ fill_fpregset (fpregset_t *fpregsetp, int regno) char *to; char *from; - for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++) + for (regi = FP0_REGNUM; regi < E_FPC_REGNUM; regi++) { if ((regno == -1) || (regno == regi)) { @@ -826,17 +892,17 @@ fill_fpregset (fpregset_t *fpregsetp, int regno) memcpy (to, from, REGISTER_RAW_SIZE (regi)); } } - if ((regno == -1) || (regno == FPC_REGNUM)) + if ((regno == -1) || (regno == E_FPC_REGNUM)) { - fpregsetp->f_pcr = *(int *) ®isters[REGISTER_BYTE (FPC_REGNUM)]; + fpregsetp->f_pcr = *(int *) ®isters[REGISTER_BYTE (E_FPC_REGNUM)]; } - if ((regno == -1) || (regno == FPS_REGNUM)) + if ((regno == -1) || (regno == E_FPS_REGNUM)) { - fpregsetp->f_psr = *(int *) ®isters[REGISTER_BYTE (FPS_REGNUM)]; + fpregsetp->f_psr = *(int *) ®isters[REGISTER_BYTE (E_FPS_REGNUM)]; } - if ((regno == -1) || (regno == FPI_REGNUM)) + if ((regno == -1) || (regno == E_FPI_REGNUM)) { - fpregsetp->f_fpiaddr = *(int *) ®isters[REGISTER_BYTE (FPI_REGNUM)]; + fpregsetp->f_fpiaddr = *(int *) ®isters[REGISTER_BYTE (E_FPI_REGNUM)]; } } @@ -936,6 +1002,7 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_skip_prologue (gdbarch, m68k_skip_prologue); set_gdbarch_saved_pc_after_call (gdbarch, m68k_saved_pc_after_call); + set_gdbarch_breakpoint_from_pc (gdbarch, m68k_local_breakpoint_from_pc); /* Stack grows down. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); diff --git a/gdb/macrotab.h b/gdb/macrotab.h index cbc6d1b..df32977 100644 --- a/gdb/macrotab.h +++ b/gdb/macrotab.h @@ -22,8 +22,8 @@ #ifndef MACROTAB_H #define MACROTAB_H -#include "obstack.h" -#include "bcache.h" +struct obstack; +struct bcache; /* How do we represent a source location? I mean, how should we represent them within GDB; the user wants to use all sorts of diff --git a/gdb/mcore-tdep.c b/gdb/mcore-tdep.c index 0e6ffc8..f16f6635 100644 --- a/gdb/mcore-tdep.c +++ b/gdb/mcore-tdep.c @@ -76,22 +76,12 @@ void mcore_extract_return_value (struct type *type, char *regbuf, char *valbuf); int mcore_debug = 0; #endif -/* The registers of the Motorola MCore processors */ -/* *INDENT-OFF* */ -char *mcore_register_names[] = -{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "ar0", "ar1", "ar2", "ar3", "ar4", "ar5", "ar6", "ar7", - "ar8", "ar9", "ar10", "ar11", "ar12", "ar13", "ar14", "ar15", - "psr", "vbr", "epsr", "fpsr", "epc", "fpc", "ss0", "ss1", - "ss2", "ss3", "ss4", "gcr", "gsr", "cr13", "cr14", "cr15", - "cr16", "cr17", "cr18", "cr19", "cr20", "cr21", "cr22", "cr23", - "cr24", "cr25", "cr26", "cr27", "cr28", "cr29", "cr30", "cr31", - "pc" }; -/* *INDENT-ON* */ - +/* All registers are 4 bytes long. */ +#define MCORE_REG_SIZE 4 +#define MCORE_NUM_REGS 65 + /* Additional info that we use for managing frames */ struct frame_extra_info { @@ -175,6 +165,68 @@ mcore_dump_insn (char *commnt, CORE_ADDR pc, int insn) #define mcore_insn_debug(args) {} #endif + +static struct type * +mcore_register_virtual_type (int regnum) +{ + if (regnum < 0 || regnum >= MCORE_NUM_REGS) + internal_error (__FILE__, __LINE__, + "mcore_register_virtual_type: illegal register number %d", + regnum); + else + return builtin_type_int; +} + +static int +mcore_register_byte (int regnum) +{ + if (regnum < 0 || regnum >= MCORE_NUM_REGS) + internal_error (__FILE__, __LINE__, + "mcore_register_byte: illegal register number %d", + regnum); + else + return (regnum * MCORE_REG_SIZE); +} + +static int +mcore_register_size (int regnum) +{ + + if (regnum < 0 || regnum >= MCORE_NUM_REGS) + internal_error (__FILE__, __LINE__, + "mcore_register_size: illegal register number %d", + regnum); + else + return MCORE_REG_SIZE; +} + +/* The registers of the Motorola MCore processors */ + +static const char * +mcore_register_name (int regnum) +{ + + static char *register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "ar0", "ar1", "ar2", "ar3", "ar4", "ar5", "ar6", "ar7", + "ar8", "ar9", "ar10", "ar11", "ar12", "ar13", "ar14", "ar15", + "psr", "vbr", "epsr", "fpsr", "epc", "fpc", "ss0", "ss1", + "ss2", "ss3", "ss4", "gcr", "gsr", "cr13", "cr14", "cr15", + "cr16", "cr17", "cr18", "cr19", "cr20", "cr21", "cr22", "cr23", + "cr24", "cr25", "cr26", "cr27", "cr28", "cr29", "cr30", "cr31", + "pc" + }; + + if (regnum < 0 || + regnum >= sizeof (register_names) / sizeof (register_names[0])) + internal_error (__FILE__, __LINE__, + "mcore_register_name: illegal register number %d", + regnum); + else + return register_names[regnum]; +} + /* Given the address at which to insert a breakpoint (BP_ADDR), what will that breakpoint be? @@ -981,10 +1033,59 @@ get_insn (CORE_ADDR pc) return extract_unsigned_integer (buf, 2); } +static struct gdbarch * +mcore_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) +{ + static LONGEST call_dummy_words[7] = { }; + struct gdbarch_tdep *tdep = NULL; + struct gdbarch *gdbarch; + + /* find a candidate among the list of pre-declared architectures. */ + arches = gdbarch_list_lookup_by_info (arches, &info); + if (arches != NULL) + return (arches->gdbarch); + + gdbarch = gdbarch_alloc (&info, 0); + + /* All registers are 32 bits */ + set_gdbarch_register_size (gdbarch, MCORE_REG_SIZE); + set_gdbarch_max_register_raw_size (gdbarch, MCORE_REG_SIZE); + set_gdbarch_max_register_virtual_size (gdbarch, MCORE_REG_SIZE); + + set_gdbarch_register_name (gdbarch, mcore_register_name); + set_gdbarch_register_virtual_type (gdbarch, mcore_register_virtual_type); + set_gdbarch_register_virtual_size (gdbarch, mcore_register_size); + set_gdbarch_register_raw_size (gdbarch, mcore_register_size); + set_gdbarch_register_byte (gdbarch, mcore_register_byte); + + set_gdbarch_call_dummy_p (gdbarch, 1); + set_gdbarch_use_generic_dummy_frames (gdbarch, 1); + set_gdbarch_call_dummy_words (gdbarch, call_dummy_words); + set_gdbarch_sizeof_call_dummy_words (gdbarch, 0); + set_gdbarch_call_dummy_start_offset (gdbarch, 0); + set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); + set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0); + set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT); + set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy); + set_gdbarch_call_dummy_address (gdbarch, entry_point_address); + set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); + set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy); + set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0); + + return gdbarch; +} + +static void +mcore_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) +{ + +} + void _initialize_mcore_tdep (void) { extern int print_insn_mcore (bfd_vma, disassemble_info *); + gdbarch_register (bfd_arch_mcore, mcore_gdbarch_init, mcore_dump_tdep); tm_print_insn = print_insn_mcore; #ifdef MCORE_DEBUG diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 2372d25a..b387510 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -2619,7 +2619,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_convert_to_raw (gdbarch, rs6000_register_convert_to_raw); set_gdbarch_stab_reg_to_regnum (gdbarch, rs6000_stab_reg_to_regnum); - set_gdbarch_deprecated_extract_return_value (gdbarch, rs6000_extract_return_value); + set_gdbarch_extract_return_value (gdbarch, rs6000_extract_return_value); /* Note: kevinb/2002-04-12: I'm not convinced that rs6000_push_arguments() is correct for the SysV ABI when the wordsize is 8, but I'm also @@ -2635,7 +2635,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_store_struct_return (gdbarch, rs6000_store_struct_return); set_gdbarch_store_return_value (gdbarch, rs6000_store_return_value); - set_gdbarch_deprecated_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address); + set_gdbarch_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address); set_gdbarch_pop_frame (gdbarch, rs6000_pop_frame); set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue); diff --git a/gdb/solib-osf.c b/gdb/solib-osf.c index a00e488..6f43a8f 100644 --- a/gdb/solib-osf.c +++ b/gdb/solib-osf.c @@ -359,7 +359,14 @@ static int open_map (struct read_map_ctxt *ctxt) { #ifdef USE_LDR_ROUTINES - ctxt->proc = ldr_my_process (); + /* Note: As originally written, ldr_my_process() was used to obtain + the value for ctxt->proc. This is incorrect, however, since + ldr_my_process() retrieves the "unique identifier" associated + with the current process (i.e. GDB) and not the one being + debugged. Presumably, the pid of the process being debugged is + compatible with the "unique identifier" used by the ldr_ + routines, so we use that. */ + ctxt->proc = ptid_get_pid (inferior_ptid); if (ldr_xattach (ctxt->proc) != 0) return 0; ctxt->next = LDR_NULL_MODULE; @@ -703,12 +703,12 @@ execute_command (char *p, int from_tty) execute_user_command (c, arg); else if (c->type == set_cmd || c->type == show_cmd) do_setshow_command (arg, from_tty & caution, c); - else if (c->func == NULL) + else if (!cmd_func_p (c)) error ("That is not a command, just a help topic."); else if (call_command_hook) call_command_hook (c, arg, from_tty & caution); else - (*c->func) (c, arg, from_tty & caution); + cmd_func (c, arg, from_tty & caution); /* If this command has been post-hooked, run the hook last. */ execute_cmd_post_hook (c); diff --git a/gdb/valops.c b/gdb/valops.c index 22c744d..3e72e94 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1316,8 +1316,10 @@ hand_function_call (struct value *function, int nargs, struct value **args) struct type *value_type; unsigned char struct_return; CORE_ADDR struct_addr = 0; + char *retbuf; + struct cleanup *retbuf_cleanup; struct inferior_status *inf_status; - struct cleanup *old_chain; + struct cleanup *inf_status_cleanup; CORE_ADDR funaddr; int using_gcc; /* Set to version of gcc in use, or zero if not gcc */ CORE_ADDR real_pc; @@ -1333,8 +1335,18 @@ hand_function_call (struct value *function, int nargs, struct value **args) if (!target_has_execution) noprocess (); + /* Create a cleanup chain that contains the retbuf (buffer + containing the register values). This chain is create BEFORE the + inf_status chain so that the inferior status can cleaned up + (restored or discarded) without having the retbuf freed. */ + retbuf = xmalloc (REGISTER_BYTES); + retbuf_cleanup = make_cleanup (xfree, retbuf); + + /* A cleanup for the inferior status. Create this AFTER the retbuf + so that this can be discarded or applied without interfering with + the regbuf. */ inf_status = save_inferior_status (1); - old_chain = make_cleanup_restore_inferior_status (inf_status); + inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status); /* PUSH_DUMMY_FRAME is responsible for saving the inferior registers (and POP_FRAME for restoring them). (At least on most machines) @@ -1656,7 +1668,6 @@ You must use a pointer to function type variable. Command ignored.", arg_name); SAVE_DUMMY_FRAME_TOS (sp); { - struct regcache *retbuf = NULL; char *name; struct symbol *symbol; @@ -1688,7 +1699,7 @@ You must use a pointer to function type variable. Command ignored.", arg_name); /* Execute the stack dummy routine, calling FUNCTION. When it is done, discard the empty frame after storing the contents of all regs into retbuf. */ - rc = run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, &retbuf); + rc = run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf); if (rc == 1) { @@ -1715,11 +1726,12 @@ Evaluation of the expression containing the function (%s) will be abandoned.", { /* The user wants to stay in the frame where we stopped (default).*/ - /* If we did the cleanups, we would print a spurious error - message (Unable to restore previously selected frame), - would write the registers from the inf_status (which is - wrong), and would do other wrong things. */ - discard_cleanups (old_chain); + /* If we restored the inferior status (via the cleanup), + we would print a spurious error message (Unable to + restore previously selected frame), would write the + registers from the inf_status (which is wrong), and + would do other wrong things. */ + discard_cleanups (inf_status_cleanup); discard_inferior_status (inf_status); /* FIXME: Insert a bunch of wrap_here; name can be very long if it's @@ -1737,11 +1749,12 @@ Evaluation of the expression containing the function (%s) will be abandoned.", { /* We hit a breakpoint inside the FUNCTION. */ - /* If we did the cleanups, we would print a spurious error - message (Unable to restore previously selected frame), - would write the registers from the inf_status (which is - wrong), and would do other wrong things. */ - discard_cleanups (old_chain); + /* If we restored the inferior status (via the cleanup), we + would print a spurious error message (Unable to restore + previously selected frame), would write the registers from + the inf_status (which is wrong), and would do other wrong + things. */ + discard_cleanups (inf_status_cleanup); discard_inferior_status (inf_status); /* The following error message used to say "The expression @@ -1761,7 +1774,10 @@ the function call).", name); } /* If we get here the called FUNCTION run to completion. */ - do_cleanups (old_chain); + + /* Restore the inferior status, via its cleanup. At this stage, + leave the RETBUF alone. */ + do_cleanups (inf_status_cleanup); /* Figure out the value returned by the function. */ /* elz: I defined this new macro for the hppa architecture only. @@ -1774,10 +1790,17 @@ the function call).", name); #ifdef VALUE_RETURNED_FROM_STACK if (struct_return) - return (struct value *) VALUE_RETURNED_FROM_STACK (value_type, struct_addr); + { + do_cleanups (retbuf_cleanup); + return VALUE_RETURNED_FROM_STACK (value_type, struct_addr); + } #endif - return value_being_returned (value_type, retbuf, struct_return); + { + struct value *retval = value_being_returned (value_type, retbuf, struct_return); + do_cleanups (retbuf_cleanup); + return retval; + } } } diff --git a/gdb/version.in b/gdb/version.in index b605542..4068d0c 100644 --- a/gdb/version.in +++ b/gdb/version.in @@ -1 +1 @@ -2002-06-28-cvs +2002-07-03-cvs |