summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2004-06-20 19:47:29 +0000
committermarcel <marcel@FreeBSD.org>2004-06-20 19:47:29 +0000
commit78a152dbb18863b3be7de8f42ca4357818e653e0 (patch)
tree600408db2b676558a19981988d80b4303f78d112 /contrib
parent8bb422459538c6d19abef5bf32a64fd48d9e40d3 (diff)
downloadFreeBSD-src-78a152dbb18863b3be7de8f42ca4357818e653e0.zip
FreeBSD-src-78a152dbb18863b3be7de8f42ca4357818e653e0.tar.gz
Update to GDB 6.1.1. These files are identical to the vendor branch.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/gdb/gdb/alpha-tdep.c2406
-rw-r--r--contrib/gdb/gdb/coffread.c337
-rw-r--r--contrib/gdb/gdb/config/alpha/tm-alpha.h409
-rw-r--r--contrib/gdb/gdb/config/i386/tm-fbsd.h70
-rw-r--r--contrib/gdb/gdb/core-regset.c109
-rw-r--r--contrib/gdb/gdb/dbxread.c636
-rw-r--r--contrib/gdb/gdb/defs.h507
-rw-r--r--contrib/gdb/gdb/demangle.c41
-rw-r--r--contrib/gdb/gdb/doc/gdb.texinfo10918
-rw-r--r--contrib/gdb/gdb/doc/stabs.texinfo155
-rw-r--r--contrib/gdb/gdb/exec.c144
-rw-r--r--contrib/gdb/gdb/gdbserver/gdbreplay.c13
-rw-r--r--contrib/gdb/gdb/gdbserver/utils.c13
-rw-r--r--contrib/gdb/gdb/i386-tdep.c2339
-rw-r--r--contrib/gdb/gdb/i386bsd-nat.c102
-rw-r--r--contrib/gdb/gdb/infptrace.c56
-rw-r--r--contrib/gdb/gdb/main.c311
-rw-r--r--contrib/gdb/gdb/objfiles.c622
-rw-r--r--contrib/gdb/gdb/remote.c2076
-rw-r--r--contrib/gdb/gdb/ser-unix.c9
-rw-r--r--contrib/gdb/gdb/solib.c82
-rw-r--r--contrib/gdb/gdb/symfile.c1133
-rw-r--r--contrib/gdb/gdb/symtab.c2193
-rw-r--r--contrib/gdb/gdb/target.c1074
-rw-r--r--contrib/gdb/gdb/target.h523
-rw-r--r--contrib/gdb/gdb/thread.c109
-rw-r--r--contrib/gdb/gdb/top.c511
-rw-r--r--contrib/gdb/gdb/utils.c1404
-rw-r--r--contrib/gdb/gdb/version.in2
29 files changed, 17851 insertions, 10453 deletions
diff --git a/contrib/gdb/gdb/alpha-tdep.c b/contrib/gdb/gdb/alpha-tdep.c
index 4ca6bcc..1599eb2 100644
--- a/contrib/gdb/gdb/alpha-tdep.c
+++ b/contrib/gdb/gdb/alpha-tdep.c
@@ -1,5 +1,5 @@
/* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
This file is part of GDB.
@@ -20,7 +20,11 @@
Boston, MA 02111-1307, USA. */
#include "defs.h"
+#include "doublest.h"
#include "frame.h"
+#include "frame-unwind.h"
+#include "frame-base.h"
+#include "dwarf2-frame.h"
#include "inferior.h"
#include "symtab.h"
#include "value.h"
@@ -32,253 +36,20 @@
#include "gdb_string.h"
#include "linespec.h"
#include "regcache.h"
-#include "doublest.h"
-
-struct frame_extra_info
- {
- alpha_extra_func_info_t proc_desc;
- int localoff;
- int pc_reg;
- };
-
-/* FIXME: Some of this code should perhaps be merged with mips-tdep.c. */
-
-/* Prototypes for local functions. */
-
-static void alpha_find_saved_regs (struct frame_info *);
-
-static alpha_extra_func_info_t push_sigtramp_desc (CORE_ADDR low_addr);
-
-static CORE_ADDR read_next_frame_reg (struct frame_info *, int);
-
-static CORE_ADDR heuristic_proc_start (CORE_ADDR);
+#include "reggroups.h"
+#include "arch-utils.h"
+#include "osabi.h"
+#include "block.h"
-static alpha_extra_func_info_t heuristic_proc_desc (CORE_ADDR,
- CORE_ADDR,
- struct frame_info *);
+#include "elf-bfd.h"
-static alpha_extra_func_info_t find_proc_desc (CORE_ADDR,
- struct frame_info *);
+#include "alpha-tdep.h"
-#if 0
-static int alpha_in_lenient_prologue (CORE_ADDR, CORE_ADDR);
-#endif
-
-static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
-
-static CORE_ADDR after_prologue (CORE_ADDR pc,
- alpha_extra_func_info_t proc_desc);
-
-static int alpha_in_prologue (CORE_ADDR pc,
- alpha_extra_func_info_t proc_desc);
-
-static int alpha_about_to_return (CORE_ADDR pc);
-
-void _initialize_alpha_tdep (void);
-
-/* Heuristic_proc_start may hunt through the text section for a long
- time across a 2400 baud serial line. Allows the user to limit this
- search. */
-static unsigned int heuristic_fence_post = 0;
-/* *INDENT-OFF* */
-/* Layout of a stack frame on the alpha:
-
- | |
- pdr members: | 7th ... nth arg, |
- | `pushed' by caller. |
- | |
-----------------|-------------------------------|<-- old_sp == vfp
- ^ ^ ^ ^ | |
- | | | | | |
- | |localoff | Copies of 1st .. 6th |
- | | | | | argument if necessary. |
- | | | v | |
- | | | --- |-------------------------------|<-- FRAME_LOCALS_ADDRESS
- | | | | |
- | | | | Locals and temporaries. |
- | | | | |
- | | | |-------------------------------|
- | | | | |
- |-fregoffset | Saved float registers. |
- | | | | F9 |
- | | | | . |
- | | | | . |
- | | | | F2 |
- | | v | |
- | | -------|-------------------------------|
- | | | |
- | | | Saved registers. |
- | | | S6 |
- |-regoffset | . |
- | | | . |
- | | | S0 |
- | | | pdr.pcreg |
- | v | |
- | ----------|-------------------------------|
- | | |
- frameoffset | Argument build area, gets |
- | | 7th ... nth arg for any |
- | | called procedure. |
- v | |
- -------------|-------------------------------|<-- sp
- | |
-*/
-/* *INDENT-ON* */
-
-
-
-#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */
-/* These next two fields are kind of being hijacked. I wonder if
- iline is too small for the values it needs to hold, if GDB is
- running on a 32-bit host. */
-#define PROC_HIGH_ADDR(proc) ((proc)->pdr.iline) /* upper address bound */
-#define PROC_DUMMY_FRAME(proc) ((proc)->pdr.cbLineOffset) /*CALL_DUMMY frame */
-#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
-#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg)
-#define PROC_REG_MASK(proc) ((proc)->pdr.regmask)
-#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask)
-#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset)
-#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset)
-#define PROC_PC_REG(proc) ((proc)->pdr.pcreg)
-#define PROC_LOCALOFF(proc) ((proc)->pdr.localoff)
-#define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->pdr.isym)
-#define _PROC_MAGIC_ 0x0F0F0F0F
-#define PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym == _PROC_MAGIC_)
-#define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym = _PROC_MAGIC_)
-
-struct linked_proc_info
- {
- struct alpha_extra_func_info info;
- struct linked_proc_info *next;
- }
- *linked_proc_desc_table = NULL;
-int
-alpha_osf_in_sigtramp (CORE_ADDR pc, char *func_name)
-{
- return (func_name != NULL && STREQ ("__sigtramp", func_name));
-}
-
-/* Under GNU/Linux, signal handler invocations can be identified by the
- designated code sequence that is used to return from a signal
- handler. In particular, the return address of a signal handler
- points to the following sequence (the first instruction is quadword
- aligned):
-
- bis $30,$30,$16
- addq $31,0x67,$0
- call_pal callsys
-
- Each instruction has a unique encoding, so we simply attempt to
- match the instruction the pc is pointing to with any of the above
- instructions. If there is a hit, we know the offset to the start
- of the designated sequence and can then check whether we really are
- executing in a designated sequence. If not, -1 is returned,
- otherwise the offset from the start of the desingated sequence is
- returned.
-
- There is a slight chance of false hits: code could jump into the
- middle of the designated sequence, in which case there is no
- guarantee that we are in the middle of a sigreturn syscall. Don't
- think this will be a problem in praxis, though.
- */
-
-#ifndef TM_LINUXALPHA_H
-/* HACK: Provide a prototype when compiling this file for non
- linuxalpha targets. */
-long alpha_linux_sigtramp_offset (CORE_ADDR pc);
-#endif
-long
-alpha_linux_sigtramp_offset (CORE_ADDR pc)
-{
- unsigned int i[3], w;
- long off;
-
- if (read_memory_nobpt (pc, (char *) &w, 4) != 0)
- return -1;
-
- off = -1;
- switch (w)
- {
- case 0x47de0410:
- off = 0;
- break; /* bis $30,$30,$16 */
- case 0x43ecf400:
- off = 4;
- break; /* addq $31,0x67,$0 */
- case 0x00000083:
- off = 8;
- break; /* call_pal callsys */
- default:
- return -1;
- }
- pc -= off;
- if (pc & 0x7)
- {
- /* designated sequence is not quadword aligned */
- return -1;
- }
-
- if (read_memory_nobpt (pc, (char *) i, sizeof (i)) != 0)
- return -1;
-
- if (i[0] == 0x47de0410 && i[1] == 0x43ecf400 && i[2] == 0x00000083)
- return off;
-
- return -1;
-}
-
-
-/* Under OSF/1, the __sigtramp routine is frameless and has a frame
- size of zero, but we are able to backtrace through it. */
-CORE_ADDR
-alpha_osf_skip_sigtramp_frame (struct frame_info *frame, CORE_ADDR pc)
-{
- char *name;
- find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
- if (IN_SIGTRAMP (pc, name))
- return frame->frame;
- else
- return 0;
-}
-
-
-/* Dynamically create a signal-handler caller procedure descriptor for
- the signal-handler return code starting at address LOW_ADDR. The
- descriptor is added to the linked_proc_desc_table. */
-
-static alpha_extra_func_info_t
-push_sigtramp_desc (CORE_ADDR low_addr)
-{
- struct linked_proc_info *link;
- alpha_extra_func_info_t proc_desc;
-
- link = (struct linked_proc_info *)
- xmalloc (sizeof (struct linked_proc_info));
- link->next = linked_proc_desc_table;
- linked_proc_desc_table = link;
-
- proc_desc = &link->info;
-
- proc_desc->numargs = 0;
- PROC_LOW_ADDR (proc_desc) = low_addr;
- PROC_HIGH_ADDR (proc_desc) = low_addr + 3 * 4;
- PROC_DUMMY_FRAME (proc_desc) = 0;
- PROC_FRAME_OFFSET (proc_desc) = 0x298; /* sizeof(struct sigcontext_struct) */
- PROC_FRAME_REG (proc_desc) = SP_REGNUM;
- PROC_REG_MASK (proc_desc) = 0xffff;
- PROC_FREG_MASK (proc_desc) = 0xffff;
- PROC_PC_REG (proc_desc) = 26;
- PROC_LOCALOFF (proc_desc) = 0;
- SET_PROC_DESC_IS_DYN_SIGTRAMP (proc_desc);
- return (proc_desc);
-}
-
-
-char *
+static const char *
alpha_register_name (int regno)
{
- static char *register_names[] =
+ static const char * const register_names[] =
{
"v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
"t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
@@ -288,768 +59,242 @@ alpha_register_name (int regno)
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "fpcr",
- "pc", "vfp",
+ "pc", "", "unique"
};
if (regno < 0)
- return (NULL);
+ return NULL;
if (regno >= (sizeof(register_names) / sizeof(*register_names)))
- return (NULL);
- return (register_names[regno]);
+ return NULL;
+ return register_names[regno];
}
-int
+static int
alpha_cannot_fetch_register (int regno)
{
- return (regno == FP_REGNUM || regno == ZERO_REGNUM);
+ return regno == ALPHA_ZERO_REGNUM;
}
-int
+static int
alpha_cannot_store_register (int regno)
{
- return (regno == FP_REGNUM || regno == ZERO_REGNUM);
-}
-
-int
-alpha_register_convertible (int regno)
-{
- return (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31);
+ return regno == ALPHA_ZERO_REGNUM;
}
-struct type *
-alpha_register_virtual_type (int regno)
+static struct type *
+alpha_register_type (struct gdbarch *gdbarch, int regno)
{
- return ((regno >= FP0_REGNUM && regno < (FP0_REGNUM+31))
- ? builtin_type_double : builtin_type_long);
-}
-
-int
-alpha_register_byte (int regno)
-{
- return (regno * 8);
-}
+ if (regno == ALPHA_SP_REGNUM || regno == ALPHA_GP_REGNUM)
+ return builtin_type_void_data_ptr;
+ if (regno == ALPHA_PC_REGNUM)
+ return builtin_type_void_func_ptr;
-int
-alpha_register_raw_size (int regno)
-{
- return 8;
-}
+ /* Don't need to worry about little vs big endian until
+ some jerk tries to port to alpha-unicosmk. */
+ if (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31)
+ return builtin_type_ieee_double_little;
-int
-alpha_register_virtual_size (int regno)
-{
- return 8;
+ return builtin_type_int64;
}
-
-/* Guaranteed to set frame->saved_regs to some values (it never leaves it
- NULL). */
+/* Is REGNUM a member of REGGROUP? */
-static void
-alpha_find_saved_regs (struct frame_info *frame)
+static int
+alpha_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+ struct reggroup *group)
{
- int ireg;
- CORE_ADDR reg_position;
- unsigned long mask;
- alpha_extra_func_info_t proc_desc;
- int returnreg;
-
- frame_saved_regs_zalloc (frame);
-
- /* If it is the frame for __sigtramp, the saved registers are located
- in a sigcontext structure somewhere on the stack. __sigtramp
- passes a pointer to the sigcontext structure on the stack.
- If the stack layout for __sigtramp changes, or if sigcontext offsets
- change, we might have to update this code. */
-#ifndef SIGFRAME_PC_OFF
-#define SIGFRAME_PC_OFF (2 * 8)
-#define SIGFRAME_REGSAVE_OFF (4 * 8)
-#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_REGSAVE_OFF + 32 * 8 + 8)
-#endif
- if (frame->signal_handler_caller)
- {
- CORE_ADDR sigcontext_addr;
-
- sigcontext_addr = SIGCONTEXT_ADDR (frame);
- for (ireg = 0; ireg < 32; ireg++)
- {
- reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8;
- frame->saved_regs[ireg] = reg_position;
- }
- for (ireg = 0; ireg < 32; ireg++)
- {
- reg_position = sigcontext_addr + SIGFRAME_FPREGSAVE_OFF + ireg * 8;
- frame->saved_regs[FP0_REGNUM + ireg] = reg_position;
- }
- frame->saved_regs[PC_REGNUM] = sigcontext_addr + SIGFRAME_PC_OFF;
- return;
- }
-
- proc_desc = frame->extra_info->proc_desc;
- if (proc_desc == NULL)
- /* I'm not sure how/whether this can happen. Normally when we can't
- find a proc_desc, we "synthesize" one using heuristic_proc_desc
- and set the saved_regs right away. */
- return;
-
- /* Fill in the offsets for the registers which gen_mask says
- were saved. */
-
- reg_position = frame->frame + PROC_REG_OFFSET (proc_desc);
- mask = PROC_REG_MASK (proc_desc);
-
- returnreg = PROC_PC_REG (proc_desc);
+ /* Filter out any registers eliminated, but whose regnum is
+ reserved for backward compatibility, e.g. the vfp. */
+ if (REGISTER_NAME (regnum) == NULL || *REGISTER_NAME (regnum) == '\0')
+ return 0;
- /* Note that RA is always saved first, regardless of its actual
- register number. */
- if (mask & (1 << returnreg))
- {
- frame->saved_regs[returnreg] = reg_position;
- reg_position += 8;
- mask &= ~(1 << returnreg); /* Clear bit for RA so we
- don't save again later. */
- }
+ if (group == all_reggroup)
+ return 1;
- for (ireg = 0; ireg <= 31; ++ireg)
- if (mask & (1 << ireg))
- {
- frame->saved_regs[ireg] = reg_position;
- reg_position += 8;
- }
+ /* Zero should not be saved or restored. Technically it is a general
+ register (just as $f31 would be a float if we represented it), but
+ there's no point displaying it during "info regs", so leave it out
+ of all groups except for "all". */
+ if (regnum == ALPHA_ZERO_REGNUM)
+ return 0;
- /* Fill in the offsets for the registers which float_mask says
- were saved. */
+ /* All other registers are saved and restored. */
+ if (group == save_reggroup || group == restore_reggroup)
+ return 1;
- reg_position = frame->frame + PROC_FREG_OFFSET (proc_desc);
- mask = PROC_FREG_MASK (proc_desc);
+ /* All other groups are non-overlapping. */
- for (ireg = 0; ireg <= 31; ++ireg)
- if (mask & (1 << ireg))
- {
- frame->saved_regs[FP0_REGNUM + ireg] = reg_position;
- reg_position += 8;
- }
+ /* Since this is really a PALcode memory slot... */
+ if (regnum == ALPHA_UNIQUE_REGNUM)
+ return group == system_reggroup;
- frame->saved_regs[PC_REGNUM] = frame->saved_regs[returnreg];
-}
+ /* Force the FPCR to be considered part of the floating point state. */
+ if (regnum == ALPHA_FPCR_REGNUM)
+ return group == float_reggroup;
-void
-alpha_frame_init_saved_regs (struct frame_info *fi)
-{
- if (fi->saved_regs == NULL)
- alpha_find_saved_regs (fi);
- fi->saved_regs[SP_REGNUM] = fi->frame;
-}
-
-void
-alpha_init_frame_pc_first (int fromleaf, struct frame_info *prev)
-{
- prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) :
- prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ());
-}
-
-static CORE_ADDR
-read_next_frame_reg (struct frame_info *fi, int regno)
-{
- for (; fi; fi = fi->next)
- {
- /* We have to get the saved sp from the sigcontext
- if it is a signal handler frame. */
- if (regno == SP_REGNUM && !fi->signal_handler_caller)
- return fi->frame;
- else
- {
- if (fi->saved_regs == NULL)
- alpha_find_saved_regs (fi);
- if (fi->saved_regs[regno])
- return read_memory_integer (fi->saved_regs[regno], 8);
- }
- }
- return read_register (regno);
+ if (regnum >= ALPHA_FP0_REGNUM && regnum < ALPHA_FP0_REGNUM + 31)
+ return group == float_reggroup;
+ else
+ return group == general_reggroup;
}
-CORE_ADDR
-alpha_frame_saved_pc (struct frame_info *frame)
+static int
+alpha_register_byte (int regno)
{
- alpha_extra_func_info_t proc_desc = frame->extra_info->proc_desc;
- /* We have to get the saved pc from the sigcontext
- if it is a signal handler frame. */
- int pcreg = frame->signal_handler_caller ? PC_REGNUM
- : frame->extra_info->pc_reg;
-
- if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
- return read_memory_integer (frame->frame - 8, 8);
-
- return read_next_frame_reg (frame, pcreg);
+ return (regno * 8);
}
-CORE_ADDR
-alpha_saved_pc_after_call (struct frame_info *frame)
+static int
+alpha_register_raw_size (int regno)
{
- CORE_ADDR pc = frame->pc;
- CORE_ADDR tmp;
- alpha_extra_func_info_t proc_desc;
- int pcreg;
-
- /* Skip over shared library trampoline if necessary. */
- tmp = SKIP_TRAMPOLINE_CODE (pc);
- if (tmp != 0)
- pc = tmp;
-
- proc_desc = find_proc_desc (pc, frame->next);
- pcreg = proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM;
-
- if (frame->signal_handler_caller)
- return alpha_frame_saved_pc (frame);
- else
- return read_register (pcreg);
+ return 8;
}
-
-static struct alpha_extra_func_info temp_proc_desc;
-static CORE_ADDR temp_saved_regs[NUM_REGS];
-
-/* Nonzero if instruction at PC is a return instruction. "ret
- $zero,($ra),1" on alpha. */
-
static int
-alpha_about_to_return (CORE_ADDR pc)
+alpha_register_virtual_size (int regno)
{
- return read_memory_integer (pc, 4) == 0x6bfa8001;
+ return 8;
}
+/* The following represents exactly the conversion performed by
+ the LDS instruction. This applies to both single-precision
+ floating point and 32-bit integers. */
-
-/* This fencepost looks highly suspicious to me. Removing it also
- seems suspicious as it could affect remote debugging across serial
- lines. */
-
-static CORE_ADDR
-heuristic_proc_start (CORE_ADDR pc)
-{
- CORE_ADDR start_pc = pc;
- CORE_ADDR fence = start_pc - heuristic_fence_post;
-
- if (start_pc == 0)
- return 0;
-
- if (heuristic_fence_post == UINT_MAX
- || fence < VM_MIN_ADDRESS)
- fence = VM_MIN_ADDRESS;
-
- /* search back for previous return */
- for (start_pc -= 4;; start_pc -= 4)
- if (start_pc < fence)
- {
- /* It's not clear to me why we reach this point when
- stop_soon_quietly, but with this test, at least we
- don't print out warnings for every child forked (eg, on
- decstation). 22apr93 rich@cygnus.com. */
- if (!stop_soon_quietly)
- {
- static int blurb_printed = 0;
-
- if (fence == VM_MIN_ADDRESS)
- warning ("Hit beginning of text section without finding");
- else
- warning ("Hit heuristic-fence-post without finding");
-
- warning ("enclosing function for address 0x%s", paddr_nz (pc));
- if (!blurb_printed)
- {
- printf_filtered ("\
-This warning occurs if you are debugging a function without any symbols\n\
-(for example, in a stripped executable). In that case, you may wish to\n\
-increase the size of the search with the `set heuristic-fence-post' command.\n\
-\n\
-Otherwise, you told GDB there was a function where there isn't one, or\n\
-(more likely) you have encountered a bug in GDB.\n");
- blurb_printed = 1;
- }
- }
-
- return 0;
- }
- else if (alpha_about_to_return (start_pc))
- break;
-
- start_pc += 4; /* skip return */
- return start_pc;
-}
-
-static alpha_extra_func_info_t
-heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
- struct frame_info *next_frame)
+static void
+alpha_lds (void *out, const void *in)
{
- CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
- CORE_ADDR cur_pc;
- int frame_size;
- int has_frame_reg = 0;
- unsigned long reg_mask = 0;
- int pcreg = -1;
-
- if (start_pc == 0)
- return NULL;
- memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc));
- memset (&temp_saved_regs, '\0', SIZEOF_FRAME_SAVED_REGS);
- PROC_LOW_ADDR (&temp_proc_desc) = start_pc;
-
- if (start_pc + 200 < limit_pc)
- limit_pc = start_pc + 200;
- frame_size = 0;
- for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4)
+ ULONGEST mem = extract_unsigned_integer (in, 4);
+ ULONGEST frac = (mem >> 0) & 0x7fffff;
+ ULONGEST sign = (mem >> 31) & 1;
+ ULONGEST exp_msb = (mem >> 30) & 1;
+ ULONGEST exp_low = (mem >> 23) & 0x7f;
+ ULONGEST exp, reg;
+
+ exp = (exp_msb << 10) | exp_low;
+ if (exp_msb)
{
- char buf[4];
- unsigned long word;
- int status;
-
- status = read_memory_nobpt (cur_pc, buf, 4);
- if (status)
- memory_error (status, cur_pc);
- word = extract_unsigned_integer (buf, 4);
-
- if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */
- {
- if (word & 0x8000)
- frame_size += (-word) & 0xffff;
- else
- /* Exit loop if a positive stack adjustment is found, which
- usually means that the stack cleanup code in the function
- epilogue is reached. */
- break;
- }
- else if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */
- && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */
- {
- int reg = (word & 0x03e00000) >> 21;
- reg_mask |= 1 << reg;
- temp_saved_regs[reg] = sp + (short) word;
-
- /* Starting with OSF/1-3.2C, the system libraries are shipped
- without local symbols, but they still contain procedure
- descriptors without a symbol reference. GDB is currently
- unable to find these procedure descriptors and uses
- heuristic_proc_desc instead.
- As some low level compiler support routines (__div*, __add*)
- use a non-standard return address register, we have to
- add some heuristics to determine the return address register,
- or stepping over these routines will fail.
- Usually the return address register is the first register
- saved on the stack, but assembler optimization might
- rearrange the register saves.
- So we recognize only a few registers (t7, t9, ra) within
- the procedure prologue as valid return address registers.
- If we encounter a return instruction, we extract the
- the return address register from it.
-
- FIXME: Rewriting GDB to access the procedure descriptors,
- e.g. via the minimal symbol table, might obviate this hack. */
- if (pcreg == -1
- && cur_pc < (start_pc + 80)
- && (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM))
- pcreg = reg;
- }
- else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
- pcreg = (word >> 16) & 0x1f;
- else if (word == 0x47de040f) /* bis sp,sp fp */
- has_frame_reg = 1;
+ if (exp_low == 0x7f)
+ exp = 0x7ff;
}
- if (pcreg == -1)
+ else
{
- /* If we haven't found a valid return address register yet,
- keep searching in the procedure prologue. */
- while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80))
- {
- char buf[4];
- unsigned long word;
-
- if (read_memory_nobpt (cur_pc, buf, 4))
- break;
- cur_pc += 4;
- word = extract_unsigned_integer (buf, 4);
-
- if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */
- && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */
- {
- int reg = (word & 0x03e00000) >> 21;
- if (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM)
- {
- pcreg = reg;
- break;
- }
- }
- else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
- {
- pcreg = (word >> 16) & 0x1f;
- break;
- }
- }
+ if (exp_low != 0x00)
+ exp |= 0x380;
}
- if (has_frame_reg)
- PROC_FRAME_REG (&temp_proc_desc) = GCC_FP_REGNUM;
- else
- PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM;
- PROC_FRAME_OFFSET (&temp_proc_desc) = frame_size;
- PROC_REG_MASK (&temp_proc_desc) = reg_mask;
- PROC_PC_REG (&temp_proc_desc) = (pcreg == -1) ? RA_REGNUM : pcreg;
- PROC_LOCALOFF (&temp_proc_desc) = 0; /* XXX - bogus */
- return &temp_proc_desc;
+ reg = (sign << 63) | (exp << 52) | (frac << 29);
+ store_unsigned_integer (out, 8, reg);
}
-/* This returns the PC of the first inst after the prologue. If we can't
- find the prologue, then return 0. */
+/* Similarly, this represents exactly the conversion performed by
+ the STS instruction. */
-static CORE_ADDR
-after_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc)
+static void
+alpha_sts (void *out, const void *in)
{
- struct symtab_and_line sal;
- CORE_ADDR func_addr, func_end;
-
- if (!proc_desc)
- proc_desc = find_proc_desc (pc, NULL);
-
- if (proc_desc)
- {
- if (PROC_DESC_IS_DYN_SIGTRAMP (proc_desc))
- return PROC_LOW_ADDR (proc_desc); /* "prologue" is in kernel */
-
- /* If function is frameless, then we need to do it the hard way. I
- strongly suspect that frameless always means prologueless... */
- if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
- && PROC_FRAME_OFFSET (proc_desc) == 0)
- return 0;
- }
-
- if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
- return 0; /* Unknown */
-
- sal = find_pc_line (func_addr, 0);
-
- if (sal.end < func_end)
- return sal.end;
-
- /* The line after the prologue is after the end of the function. In this
- case, tell the caller to find the prologue the hard way. */
+ ULONGEST reg, mem;
- return 0;
+ reg = extract_unsigned_integer (in, 8);
+ mem = ((reg >> 32) & 0xc0000000) | ((reg >> 29) & 0x3fffffff);
+ store_unsigned_integer (out, 4, mem);
}
-/* Return non-zero if we *might* be in a function prologue. Return zero if we
- are definitively *not* in a function prologue. */
+/* The alpha needs a conversion between register and memory format if the
+ register is a floating point register and memory format is float, as the
+ register format must be double or memory format is an integer with 4
+ bytes or less, as the representation of integers in floating point
+ registers is different. */
static int
-alpha_in_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc)
+alpha_convert_register_p (int regno, struct type *type)
{
- CORE_ADDR after_prologue_pc;
-
- after_prologue_pc = after_prologue (pc, proc_desc);
-
- if (after_prologue_pc == 0
- || pc < after_prologue_pc)
- return 1;
- else
- return 0;
+ return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31);
}
-static alpha_extra_func_info_t
-find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame)
+static void
+alpha_register_to_value (struct frame_info *frame, int regnum,
+ struct type *valtype, void *out)
{
- alpha_extra_func_info_t proc_desc;
- struct block *b;
- struct symbol *sym;
- CORE_ADDR startaddr;
-
- /* Try to get the proc_desc from the linked call dummy proc_descs
- if the pc is in the call dummy.
- This is hairy. In the case of nested dummy calls we have to find the
- right proc_desc, but we might not yet know the frame for the dummy
- as it will be contained in the proc_desc we are searching for.
- So we have to find the proc_desc whose frame is closest to the current
- stack pointer. */
-
- if (PC_IN_CALL_DUMMY (pc, 0, 0))
- {
- struct linked_proc_info *link;
- CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
- alpha_extra_func_info_t found_proc_desc = NULL;
- long min_distance = LONG_MAX;
-
- for (link = linked_proc_desc_table; link; link = link->next)
- {
- long distance = (CORE_ADDR) PROC_DUMMY_FRAME (&link->info) - sp;
- if (distance > 0 && distance < min_distance)
- {
- min_distance = distance;
- found_proc_desc = &link->info;
- }
- }
- if (found_proc_desc != NULL)
- return found_proc_desc;
- }
-
- b = block_for_pc (pc);
-
- find_pc_partial_function (pc, NULL, &startaddr, NULL);
- if (b == NULL)
- sym = NULL;
- else
- {
- if (startaddr > BLOCK_START (b))
- /* This is the "pathological" case referred to in a comment in
- print_frame_info. It might be better to move this check into
- symbol reading. */
- sym = NULL;
- else
- sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE,
- 0, NULL);
- }
-
- /* If we never found a PDR for this function in symbol reading, then
- examine prologues to find the information. */
- if (sym && ((mips_extra_func_info_t) SYMBOL_VALUE (sym))->pdr.framereg == -1)
- sym = NULL;
-
- if (sym)
+ char in[MAX_REGISTER_SIZE];
+ frame_register_read (frame, regnum, in);
+ switch (TYPE_LENGTH (valtype))
{
- /* IF this is the topmost frame AND
- * (this proc does not have debugging information OR
- * the PC is in the procedure prologue)
- * THEN create a "heuristic" proc_desc (by analyzing
- * the actual code) to replace the "official" proc_desc.
- */
- proc_desc = (alpha_extra_func_info_t) SYMBOL_VALUE (sym);
- if (next_frame == NULL)
- {
- if (PROC_DESC_IS_DUMMY (proc_desc) || alpha_in_prologue (pc, proc_desc))
- {
- alpha_extra_func_info_t found_heuristic =
- heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
- pc, next_frame);
- if (found_heuristic)
- {
- PROC_LOCALOFF (found_heuristic) =
- PROC_LOCALOFF (proc_desc);
- PROC_PC_REG (found_heuristic) = PROC_PC_REG (proc_desc);
- proc_desc = found_heuristic;
- }
- }
- }
- }
- else
- {
- long offset;
-
- /* Is linked_proc_desc_table really necessary? It only seems to be used
- by procedure call dummys. However, the procedures being called ought
- to have their own proc_descs, and even if they don't,
- heuristic_proc_desc knows how to create them! */
-
- register struct linked_proc_info *link;
- for (link = linked_proc_desc_table; link; link = link->next)
- if (PROC_LOW_ADDR (&link->info) <= pc
- && PROC_HIGH_ADDR (&link->info) > pc)
- return &link->info;
-
- /* If PC is inside a dynamically generated sigtramp handler,
- create and push a procedure descriptor for that code: */
- offset = DYNAMIC_SIGTRAMP_OFFSET (pc);
- if (offset >= 0)
- return push_sigtramp_desc (pc - offset);
-
- /* If heuristic_fence_post is non-zero, determine the procedure
- start address by examining the instructions.
- This allows us to find the start address of static functions which
- have no symbolic information, as startaddr would have been set to
- the preceding global function start address by the
- find_pc_partial_function call above. */
- if (startaddr == 0 || heuristic_fence_post != 0)
- startaddr = heuristic_proc_start (pc);
-
- proc_desc =
- heuristic_proc_desc (startaddr, pc, next_frame);
+ case 4:
+ alpha_sts (out, in);
+ break;
+ case 8:
+ memcpy (out, in, 8);
+ break;
+ default:
+ error ("Cannot retrieve value from floating point register");
}
- return proc_desc;
-}
-
-alpha_extra_func_info_t cached_proc_desc;
-
-CORE_ADDR
-alpha_frame_chain (struct frame_info *frame)
-{
- alpha_extra_func_info_t proc_desc;
- CORE_ADDR saved_pc = FRAME_SAVED_PC (frame);
-
- if (saved_pc == 0 || inside_entry_file (saved_pc))
- return 0;
-
- proc_desc = find_proc_desc (saved_pc, frame);
- if (!proc_desc)
- return 0;
-
- cached_proc_desc = proc_desc;
-
- /* Fetch the frame pointer for a dummy frame from the procedure
- descriptor. */
- if (PROC_DESC_IS_DUMMY (proc_desc))
- return (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc);
-
- /* If no frame pointer and frame size is zero, we must be at end
- of stack (or otherwise hosed). If we don't check frame size,
- we loop forever if we see a zero size frame. */
- if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
- && PROC_FRAME_OFFSET (proc_desc) == 0
- /* The previous frame from a sigtramp frame might be frameless
- and have frame size zero. */
- && !frame->signal_handler_caller)
- return FRAME_PAST_SIGTRAMP_FRAME (frame, saved_pc);
- else
- return read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc))
- + PROC_FRAME_OFFSET (proc_desc);
}
-void
-alpha_print_extra_frame_info (struct frame_info *fi)
-{
- if (fi
- && fi->extra_info
- && fi->extra_info->proc_desc
- && fi->extra_info->proc_desc->pdr.framereg < NUM_REGS)
- printf_filtered (" frame pointer is at %s+%s\n",
- REGISTER_NAME (fi->extra_info->proc_desc->pdr.framereg),
- paddr_d (fi->extra_info->proc_desc->pdr.frameoffset));
-}
-
-void
-alpha_init_extra_frame_info (int fromleaf, struct frame_info *frame)
+static void
+alpha_value_to_register (struct frame_info *frame, int regnum,
+ struct type *valtype, const void *in)
{
- /* Use proc_desc calculated in frame_chain */
- alpha_extra_func_info_t proc_desc =
- frame->next ? cached_proc_desc : find_proc_desc (frame->pc, frame->next);
-
- frame->extra_info = (struct frame_extra_info *)
- frame_obstack_alloc (sizeof (struct frame_extra_info));
-
- frame->saved_regs = NULL;
- frame->extra_info->localoff = 0;
- frame->extra_info->pc_reg = RA_REGNUM;
- frame->extra_info->proc_desc = proc_desc == &temp_proc_desc ? 0 : proc_desc;
- if (proc_desc)
+ char out[MAX_REGISTER_SIZE];
+ switch (TYPE_LENGTH (valtype))
{
- /* Get the locals offset and the saved pc register from the
- procedure descriptor, they are valid even if we are in the
- middle of the prologue. */
- frame->extra_info->localoff = PROC_LOCALOFF (proc_desc);
- frame->extra_info->pc_reg = PROC_PC_REG (proc_desc);
-
- /* Fixup frame-pointer - only needed for top frame */
-
- /* Fetch the frame pointer for a dummy frame from the procedure
- descriptor. */
- if (PROC_DESC_IS_DUMMY (proc_desc))
- frame->frame = (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc);
-
- /* This may not be quite right, if proc has a real frame register.
- Get the value of the frame relative sp, procedure might have been
- interrupted by a signal at it's very start. */
- else if (frame->pc == PROC_LOW_ADDR (proc_desc)
- && !PROC_DESC_IS_DYN_SIGTRAMP (proc_desc))
- frame->frame = read_next_frame_reg (frame->next, SP_REGNUM);
- else
- frame->frame = read_next_frame_reg (frame->next, PROC_FRAME_REG (proc_desc))
- + PROC_FRAME_OFFSET (proc_desc);
-
- if (proc_desc == &temp_proc_desc)
- {
- char *name;
-
- /* Do not set the saved registers for a sigtramp frame,
- alpha_find_saved_registers will do that for us.
- We can't use frame->signal_handler_caller, it is not yet set. */
- find_pc_partial_function (frame->pc, &name,
- (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
- if (!IN_SIGTRAMP (frame->pc, name))
- {
- frame->saved_regs = (CORE_ADDR *)
- frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
- memcpy (frame->saved_regs, temp_saved_regs,
- SIZEOF_FRAME_SAVED_REGS);
- frame->saved_regs[PC_REGNUM]
- = frame->saved_regs[RA_REGNUM];
- }
- }
+ case 4:
+ alpha_lds (out, in);
+ break;
+ case 8:
+ memcpy (out, in, 8);
+ break;
+ default:
+ error ("Cannot store value in floating point register");
}
+ put_frame_register (frame, regnum, out);
}
-CORE_ADDR
-alpha_frame_locals_address (struct frame_info *fi)
-{
- return (fi->frame - fi->extra_info->localoff);
-}
-
-CORE_ADDR
-alpha_frame_args_address (struct frame_info *fi)
-{
- return (fi->frame - (ALPHA_NUM_ARG_REGS * 8));
-}
-
-/* ALPHA stack frames are almost impenetrable. When execution stops,
- we basically have to look at symbol information for the function
- that we stopped in, which tells us *which* register (if any) is
- the base of the frame pointer, and what offset from that register
- the frame itself is at.
-
- This presents a problem when trying to examine a stack in memory
- (that isn't executing at the moment), using the "frame" command. We
- don't have a PC, nor do we have any registers except SP.
-
- This routine takes two arguments, SP and PC, and tries to make the
- cached frames look as if these two arguments defined a frame on the
- cache. This allows the rest of info frame to extract the important
- arguments without difficulty. */
+
+/* The alpha passes the first six arguments in the registers, the rest on
+ the stack. The register arguments are stored in ARG_REG_BUFFER, and
+ then moved into the register file; this simplifies the passing of a
+ large struct which extends from the registers to the stack, plus avoids
+ three ptrace invocations per word.
-struct frame_info *
-setup_arbitrary_frame (int argc, CORE_ADDR *argv)
-{
- if (argc != 2)
- error ("ALPHA frame specifications require two arguments: sp and pc");
+ We don't bother tracking which register values should go in integer
+ regs or fp regs; we load the same values into both.
- return create_new_frame (argv[0], argv[1]);
-}
-
-/* The alpha passes the first six arguments in the registers, the rest on
- the stack. The register arguments are eventually transferred to the
- argument transfer area immediately below the stack by the called function
- anyway. So we `push' at least six arguments on the stack, `reload' the
- argument registers and then adjust the stack pointer to point past the
- sixth argument. This algorithm simplifies the passing of a large struct
- which extends from the registers to the stack.
If the called function is returning a structure, the address of the
structure to be returned is passed as a hidden first argument. */
-CORE_ADDR
-alpha_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
+static CORE_ADDR
+alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+ struct regcache *regcache, CORE_ADDR bp_addr,
+ int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
{
int i;
int accumulate_size = struct_return ? 8 : 0;
- int arg_regs_size = ALPHA_NUM_ARG_REGS * 8;
struct alpha_arg
{
char *contents;
int len;
int offset;
};
- struct alpha_arg *alpha_args =
- (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg));
- register struct alpha_arg *m_arg;
- char raw_buffer[sizeof (CORE_ADDR)];
+ struct alpha_arg *alpha_args
+ = (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg));
+ struct alpha_arg *m_arg;
+ char arg_reg_buffer[ALPHA_REGISTER_SIZE * ALPHA_NUM_ARG_REGS];
int required_arg_regs;
+ /* The ABI places the address of the called function in T12. */
+ regcache_cooked_write_signed (regcache, ALPHA_T12_REGNUM, func_addr);
+
+ /* Set the return address register to point to the entry point
+ of the program, where a breakpoint lies in wait. */
+ regcache_cooked_write_signed (regcache, ALPHA_RA_REGNUM, bp_addr);
+
+ /* Lay out the arguments in memory. */
for (i = 0, m_arg = alpha_args; i < nargs; i++, m_arg++)
{
struct value *arg = args[i];
struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+
/* Cast argument to long if necessary as the compiler does it too. */
switch (TYPE_CODE (arg_type))
{
@@ -1058,12 +303,66 @@ alpha_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
case TYPE_CODE_CHAR:
case TYPE_CODE_RANGE:
case TYPE_CODE_ENUM:
- if (TYPE_LENGTH (arg_type) < TYPE_LENGTH (builtin_type_long))
+ if (TYPE_LENGTH (arg_type) == 4)
+ {
+ /* 32-bit values must be sign-extended to 64 bits
+ even if the base data type is unsigned. */
+ arg_type = builtin_type_int32;
+ arg = value_cast (arg_type, arg);
+ }
+ if (TYPE_LENGTH (arg_type) < ALPHA_REGISTER_SIZE)
{
- arg_type = builtin_type_long;
+ arg_type = builtin_type_int64;
arg = value_cast (arg_type, arg);
}
break;
+
+ case TYPE_CODE_FLT:
+ /* "float" arguments loaded in registers must be passed in
+ register format, aka "double". */
+ if (accumulate_size < sizeof (arg_reg_buffer)
+ && TYPE_LENGTH (arg_type) == 4)
+ {
+ arg_type = builtin_type_ieee_double_little;
+ arg = value_cast (arg_type, arg);
+ }
+ /* Tru64 5.1 has a 128-bit long double, and passes this by
+ invisible reference. No one else uses this data type. */
+ else if (TYPE_LENGTH (arg_type) == 16)
+ {
+ /* Allocate aligned storage. */
+ sp = (sp & -16) - 16;
+
+ /* Write the real data into the stack. */
+ write_memory (sp, VALUE_CONTENTS (arg), 16);
+
+ /* Construct the indirection. */
+ arg_type = lookup_pointer_type (arg_type);
+ arg = value_from_pointer (arg_type, sp);
+ }
+ break;
+
+ case TYPE_CODE_COMPLEX:
+ /* ??? The ABI says that complex values are passed as two
+ separate scalar values. This distinction only matters
+ for complex float. However, GCC does not implement this. */
+
+ /* Tru64 5.1 has a 128-bit long double, and passes this by
+ invisible reference. */
+ if (TYPE_LENGTH (arg_type) == 32)
+ {
+ /* Allocate aligned storage. */
+ sp = (sp & -16) - 16;
+
+ /* Write the real data into the stack. */
+ write_memory (sp, VALUE_CONTENTS (arg), 32);
+
+ /* Construct the indirection. */
+ arg_type = lookup_pointer_type (arg_type);
+ arg = value_from_pointer (arg_type, sp);
+ }
+ break;
+
default:
break;
}
@@ -1080,246 +379,289 @@ alpha_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
required_arg_regs = ALPHA_NUM_ARG_REGS;
/* Make room for the arguments on the stack. */
- if (accumulate_size < arg_regs_size)
- accumulate_size = arg_regs_size;
+ if (accumulate_size < sizeof(arg_reg_buffer))
+ accumulate_size = 0;
+ else
+ accumulate_size -= sizeof(arg_reg_buffer);
sp -= accumulate_size;
- /* Keep sp aligned to a multiple of 16 as the compiler does it too. */
+ /* Keep sp aligned to a multiple of 16 as the ABI requires. */
sp &= ~15;
/* `Push' arguments on the stack. */
for (i = nargs; m_arg--, --i >= 0;)
- write_memory (sp + m_arg->offset, m_arg->contents, m_arg->len);
- if (struct_return)
{
- store_address (raw_buffer, sizeof (CORE_ADDR), struct_addr);
- write_memory (sp, raw_buffer, sizeof (CORE_ADDR));
+ char *contents = m_arg->contents;
+ int offset = m_arg->offset;
+ int len = m_arg->len;
+
+ /* Copy the bytes destined for registers into arg_reg_buffer. */
+ if (offset < sizeof(arg_reg_buffer))
+ {
+ if (offset + len <= sizeof(arg_reg_buffer))
+ {
+ memcpy (arg_reg_buffer + offset, contents, len);
+ continue;
+ }
+ else
+ {
+ int tlen = sizeof(arg_reg_buffer) - offset;
+ memcpy (arg_reg_buffer + offset, contents, tlen);
+ offset += tlen;
+ contents += tlen;
+ len -= tlen;
+ }
+ }
+
+ /* Everything else goes to the stack. */
+ write_memory (sp + offset - sizeof(arg_reg_buffer), contents, len);
}
+ if (struct_return)
+ store_unsigned_integer (arg_reg_buffer, ALPHA_REGISTER_SIZE, struct_addr);
/* Load the argument registers. */
for (i = 0; i < required_arg_regs; i++)
{
- LONGEST val;
-
- val = read_memory_integer (sp + i * 8, 8);
- write_register (A0_REGNUM + i, val);
- write_register (FPA0_REGNUM + i, val);
+ regcache_cooked_write (regcache, ALPHA_A0_REGNUM + i,
+ arg_reg_buffer + i*ALPHA_REGISTER_SIZE);
+ regcache_cooked_write (regcache, ALPHA_FPA0_REGNUM + i,
+ arg_reg_buffer + i*ALPHA_REGISTER_SIZE);
}
- return sp + arg_regs_size;
-}
+ /* Finally, update the stack pointer. */
+ regcache_cooked_write_signed (regcache, ALPHA_SP_REGNUM, sp);
-void
-alpha_push_dummy_frame (void)
-{
- int ireg;
- struct linked_proc_info *link;
- alpha_extra_func_info_t proc_desc;
- CORE_ADDR sp = read_register (SP_REGNUM);
- CORE_ADDR save_address;
- char raw_buffer[MAX_REGISTER_RAW_SIZE];
- unsigned long mask;
-
- link = (struct linked_proc_info *) xmalloc (sizeof (struct linked_proc_info));
- link->next = linked_proc_desc_table;
- linked_proc_desc_table = link;
-
- proc_desc = &link->info;
-
- /*
- * The registers we must save are all those not preserved across
- * procedure calls.
- * In addition, we must save the PC and RA.
- *
- * Dummy frame layout:
- * (high memory)
- * Saved PC
- * Saved F30
- * ...
- * Saved F0
- * Saved R29
- * ...
- * Saved R0
- * Saved R26 (RA)
- * Parameter build area
- * (low memory)
- */
-
-/* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<31. */
-#define MASK(i,j) ((((LONGEST)1 << ((j)+1)) - 1) ^ (((LONGEST)1 << (i)) - 1))
-#define GEN_REG_SAVE_MASK (MASK(0,8) | MASK(16,29))
-#define GEN_REG_SAVE_COUNT 24
-#define FLOAT_REG_SAVE_MASK (MASK(0,1) | MASK(10,30))
-#define FLOAT_REG_SAVE_COUNT 23
- /* The special register is the PC as we have no bit for it in the save masks.
- alpha_frame_saved_pc knows where the pc is saved in a dummy frame. */
-#define SPECIAL_REG_SAVE_COUNT 1
-
- PROC_REG_MASK (proc_desc) = GEN_REG_SAVE_MASK;
- PROC_FREG_MASK (proc_desc) = FLOAT_REG_SAVE_MASK;
- /* PROC_REG_OFFSET is the offset from the dummy frame to the saved RA,
- but keep SP aligned to a multiple of 16. */
- PROC_REG_OFFSET (proc_desc) =
- -((8 * (SPECIAL_REG_SAVE_COUNT
- + GEN_REG_SAVE_COUNT
- + FLOAT_REG_SAVE_COUNT)
- + 15) & ~15);
- PROC_FREG_OFFSET (proc_desc) =
- PROC_REG_OFFSET (proc_desc) + 8 * GEN_REG_SAVE_COUNT;
-
- /* Save general registers.
- The return address register is the first saved register, all other
- registers follow in ascending order.
- The PC is saved immediately below the SP. */
- save_address = sp + PROC_REG_OFFSET (proc_desc);
- store_address (raw_buffer, 8, read_register (RA_REGNUM));
- write_memory (save_address, raw_buffer, 8);
- save_address += 8;
- mask = PROC_REG_MASK (proc_desc) & 0xffffffffL;
- for (ireg = 0; mask; ireg++, mask >>= 1)
- if (mask & 1)
- {
- if (ireg == RA_REGNUM)
- continue;
- store_address (raw_buffer, 8, read_register (ireg));
- write_memory (save_address, raw_buffer, 8);
- save_address += 8;
- }
-
- store_address (raw_buffer, 8, read_register (PC_REGNUM));
- write_memory (sp - 8, raw_buffer, 8);
-
- /* Save floating point registers. */
- save_address = sp + PROC_FREG_OFFSET (proc_desc);
- mask = PROC_FREG_MASK (proc_desc) & 0xffffffffL;
- for (ireg = 0; mask; ireg++, mask >>= 1)
- if (mask & 1)
- {
- store_address (raw_buffer, 8, read_register (ireg + FP0_REGNUM));
- write_memory (save_address, raw_buffer, 8);
- save_address += 8;
- }
-
- /* Set and save the frame address for the dummy.
- This is tricky. The only registers that are suitable for a frame save
- are those that are preserved across procedure calls (s0-s6). But if
- a read system call is interrupted and then a dummy call is made
- (see testsuite/gdb.t17/interrupt.exp) the dummy call hangs till the read
- is satisfied. Then it returns with the s0-s6 registers set to the values
- on entry to the read system call and our dummy frame pointer would be
- destroyed. So we save the dummy frame in the proc_desc and handle the
- retrieval of the frame pointer of a dummy specifically. The frame register
- is set to the virtual frame (pseudo) register, it's value will always
- be read as zero and will help us to catch any errors in the dummy frame
- retrieval code. */
- PROC_DUMMY_FRAME (proc_desc) = sp;
- PROC_FRAME_REG (proc_desc) = FP_REGNUM;
- PROC_FRAME_OFFSET (proc_desc) = 0;
- sp += PROC_REG_OFFSET (proc_desc);
- write_register (SP_REGNUM, sp);
-
- PROC_LOW_ADDR (proc_desc) = CALL_DUMMY_ADDRESS ();
- PROC_HIGH_ADDR (proc_desc) = PROC_LOW_ADDR (proc_desc) + 4;
-
- SET_PROC_DESC_IS_DUMMY (proc_desc);
- PROC_PC_REG (proc_desc) = RA_REGNUM;
+ return sp;
}
-void
-alpha_pop_frame (void)
+/* Extract from REGCACHE the value about to be returned from a function
+ and copy it into VALBUF. */
+
+static void
+alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
+ void *valbuf)
{
- register int regnum;
- struct frame_info *frame = get_current_frame ();
- CORE_ADDR new_sp = frame->frame;
+ int length = TYPE_LENGTH (valtype);
+ char raw_buffer[ALPHA_REGISTER_SIZE];
+ ULONGEST l;
- alpha_extra_func_info_t proc_desc = frame->extra_info->proc_desc;
+ switch (TYPE_CODE (valtype))
+ {
+ case TYPE_CODE_FLT:
+ switch (length)
+ {
+ case 4:
+ regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, raw_buffer);
+ alpha_sts (valbuf, raw_buffer);
+ break;
- /* we need proc_desc to know how to restore the registers;
- if it is NULL, construct (a temporary) one */
- if (proc_desc == NULL)
- proc_desc = find_proc_desc (frame->pc, frame->next);
+ case 8:
+ regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
+ break;
- /* Question: should we copy this proc_desc and save it in
- frame->proc_desc? If we do, who will free it?
- For now, we don't save a copy... */
+ case 16:
+ regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &l);
+ read_memory (l, valbuf, 16);
+ break;
- write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
- if (frame->saved_regs == NULL)
- alpha_find_saved_regs (frame);
- if (proc_desc)
- {
- for (regnum = 32; --regnum >= 0;)
- if (PROC_REG_MASK (proc_desc) & (1 << regnum))
- write_register (regnum,
- read_memory_integer (frame->saved_regs[regnum],
- 8));
- for (regnum = 32; --regnum >= 0;)
- if (PROC_FREG_MASK (proc_desc) & (1 << regnum))
- write_register (regnum + FP0_REGNUM,
- read_memory_integer (frame->saved_regs[regnum + FP0_REGNUM], 8));
+ default:
+ internal_error (__FILE__, __LINE__, "unknown floating point width");
+ }
+ break;
+
+ case TYPE_CODE_COMPLEX:
+ switch (length)
+ {
+ case 8:
+ /* ??? This isn't correct wrt the ABI, but it's what GCC does. */
+ regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
+ break;
+
+ case 16:
+ regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
+ regcache_cooked_read (regcache, ALPHA_FP0_REGNUM+1,
+ (char *)valbuf + 8);
+ break;
+
+ case 32:
+ regcache_cooked_read_signed (regcache, ALPHA_V0_REGNUM, &l);
+ read_memory (l, valbuf, 32);
+ break;
+
+ default:
+ internal_error (__FILE__, __LINE__, "unknown floating point width");
+ }
+ break;
+
+ default:
+ /* Assume everything else degenerates to an integer. */
+ regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &l);
+ store_unsigned_integer (valbuf, length, l);
+ break;
}
- write_register (SP_REGNUM, new_sp);
- flush_cached_frames ();
+}
- if (proc_desc && (PROC_DESC_IS_DUMMY (proc_desc)
- || PROC_DESC_IS_DYN_SIGTRAMP (proc_desc)))
- {
- struct linked_proc_info *pi_ptr, *prev_ptr;
+/* Extract from REGCACHE the address of a structure about to be returned
+ from a function. */
- for (pi_ptr = linked_proc_desc_table, prev_ptr = NULL;
- pi_ptr != NULL;
- prev_ptr = pi_ptr, pi_ptr = pi_ptr->next)
+static CORE_ADDR
+alpha_extract_struct_value_address (struct regcache *regcache)
+{
+ ULONGEST addr;
+ regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &addr);
+ return addr;
+}
+
+/* Insert the given value into REGCACHE as if it was being
+ returned by a function. */
+
+static void
+alpha_store_return_value (struct type *valtype, struct regcache *regcache,
+ const void *valbuf)
+{
+ int length = TYPE_LENGTH (valtype);
+ char raw_buffer[ALPHA_REGISTER_SIZE];
+ ULONGEST l;
+
+ switch (TYPE_CODE (valtype))
+ {
+ case TYPE_CODE_FLT:
+ switch (length)
{
- if (&pi_ptr->info == proc_desc)
- break;
+ case 4:
+ alpha_lds (raw_buffer, valbuf);
+ regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, raw_buffer);
+ break;
+
+ case 8:
+ regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
+ break;
+
+ case 16:
+ /* FIXME: 128-bit long doubles are returned like structures:
+ by writing into indirect storage provided by the caller
+ as the first argument. */
+ error ("Cannot set a 128-bit long double return value.");
+
+ default:
+ internal_error (__FILE__, __LINE__, "unknown floating point width");
}
+ break;
- if (pi_ptr == NULL)
- error ("Can't locate dummy extra frame info\n");
+ case TYPE_CODE_COMPLEX:
+ switch (length)
+ {
+ case 8:
+ /* ??? This isn't correct wrt the ABI, but it's what GCC does. */
+ regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
+ break;
- if (prev_ptr != NULL)
- prev_ptr->next = pi_ptr->next;
- else
- linked_proc_desc_table = pi_ptr->next;
+ case 16:
+ regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
+ regcache_cooked_write (regcache, ALPHA_FP0_REGNUM+1,
+ (const char *)valbuf + 8);
+ break;
- xfree (pi_ptr);
+ case 32:
+ /* FIXME: 128-bit long doubles are returned like structures:
+ by writing into indirect storage provided by the caller
+ as the first argument. */
+ error ("Cannot set a 128-bit long double return value.");
+
+ default:
+ internal_error (__FILE__, __LINE__, "unknown floating point width");
+ }
+ break;
+
+ default:
+ /* Assume everything else degenerates to an integer. */
+ /* 32-bit values must be sign-extended to 64 bits
+ even if the base data type is unsigned. */
+ if (length == 4)
+ valtype = builtin_type_int32;
+ l = unpack_long (valtype, valbuf);
+ regcache_cooked_write_unsigned (regcache, ALPHA_V0_REGNUM, l);
+ break;
}
}
+
+static const unsigned char *
+alpha_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ static const unsigned char alpha_breakpoint[] =
+ { 0x80, 0, 0, 0 }; /* call_pal bpt */
+
+ *lenptr = sizeof(alpha_breakpoint);
+ return (alpha_breakpoint);
+}
+
+
+/* This returns the PC of the first insn after the prologue.
+ If we can't find the prologue, then return 0. */
+
+CORE_ADDR
+alpha_after_prologue (CORE_ADDR pc)
+{
+ struct symtab_and_line sal;
+ CORE_ADDR func_addr, func_end;
+
+ if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ return 0;
+
+ sal = find_pc_line (func_addr, 0);
+ if (sal.end < func_end)
+ return sal.end;
+
+ /* The line after the prologue is after the end of the function. In this
+ case, tell the caller to find the prologue the hard way. */
+ return 0;
+}
+
+/* Read an instruction from memory at PC, looking through breakpoints. */
+
+unsigned int
+alpha_read_insn (CORE_ADDR pc)
+{
+ char buf[4];
+ int status;
+
+ status = read_memory_nobpt (pc, buf, 4);
+ if (status)
+ memory_error (status, pc);
+ return extract_unsigned_integer (buf, 4);
+}
+
/* To skip prologues, I use this predicate. Returns either PC itself
if the code at PC does not look like a function prologue; otherwise
returns an address that (if we're lucky) follows the prologue. If
LENIENT, then we must skip everything which is involved in setting
up the frame (it's OK to skip more, just so long as we don't skip
- anything which might clobber the registers which are being saved.
- Currently we must not skip more on the alpha, but we might need the
- lenient stuff some day. */
+ anything which might clobber the registers which are being saved. */
static CORE_ADDR
-alpha_skip_prologue_internal (CORE_ADDR pc, int lenient)
+alpha_skip_prologue (CORE_ADDR pc)
{
unsigned long inst;
int offset;
CORE_ADDR post_prologue_pc;
char buf[4];
-#ifdef GDB_TARGET_HAS_SHARED_LIBS
/* Silently return the unaltered pc upon memory errors.
This could happen on OSF/1 if decode_line_1 tries to skip the
prologue for quickstarted shared library functions when the
shared library is not yet mapped in.
Reading target memory is slow over serial lines, so we perform
- this check only if the target has shared libraries. */
+ this check only if the target has shared libraries (which all
+ Alpha targets do). */
if (target_read_memory (pc, buf, 4))
return pc;
-#endif
/* See if we can determine the end of the prologue via the symbol table.
If so, then return either PC, or the PC after the prologue, whichever
is greater. */
- post_prologue_pc = after_prologue (pc, NULL);
-
+ post_prologue_pc = alpha_after_prologue (pc);
if (post_prologue_pc != 0)
return max (pc, post_prologue_pc);
@@ -1331,17 +673,7 @@ alpha_skip_prologue_internal (CORE_ADDR pc, int lenient)
or in the gcc frame. */
for (offset = 0; offset < 100; offset += 4)
{
- int status;
-
- status = read_memory_nobpt (pc + offset, buf, 4);
- if (status)
- memory_error (status, pc + offset);
- inst = extract_unsigned_integer (buf, 4);
-
- /* The alpha has no delay slots. But let's keep the lenient stuff,
- we might need it for something else in the future. */
- if (lenient && 0)
- continue;
+ inst = alpha_read_insn (pc + offset);
if ((inst & 0xffff0000) == 0x27bb0000) /* ldah $gp,n($t12) */
continue;
@@ -1352,15 +684,14 @@ alpha_skip_prologue_internal (CORE_ADDR pc, int lenient)
if ((inst & 0xffe01fff) == 0x43c0153e) /* subq $sp,n,$sp */
continue;
- if ((inst & 0xfc1f0000) == 0xb41e0000
- && (inst & 0xffff0000) != 0xb7fe0000)
- continue; /* stq reg,n($sp) */
- /* reg != $zero */
- if ((inst & 0xfc1f0000) == 0x9c1e0000
- && (inst & 0xffff0000) != 0x9ffe0000)
- continue; /* stt reg,n($sp) */
- /* reg != $zero */
- if (inst == 0x47de040f) /* bis sp,sp,fp */
+ if (((inst & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */
+ || (inst & 0xfc1f0000) == 0x9c1e0000) /* stt reg,n($sp) */
+ && (inst & 0x03e00000) != 0x03e00000) /* reg != $zero */
+ continue;
+
+ if (inst == 0x47de040f) /* bis sp,sp,fp */
+ continue;
+ if (inst == 0x47fe040f) /* bis zero,sp,fp */
continue;
break;
@@ -1368,124 +699,536 @@ alpha_skip_prologue_internal (CORE_ADDR pc, int lenient)
return pc + offset;
}
-CORE_ADDR
-alpha_skip_prologue (CORE_ADDR addr)
+
+/* Figure out where the longjmp will land.
+ We expect the first arg to be a pointer to the jmp_buf structure from
+ which we extract the PC (JB_PC) that we will land at. The PC is copied
+ into the "pc". This routine returns true on success. */
+
+static int
+alpha_get_longjmp_target (CORE_ADDR *pc)
{
- return (alpha_skip_prologue_internal (addr, 0));
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ CORE_ADDR jb_addr;
+ char raw_buffer[ALPHA_REGISTER_SIZE];
+
+ jb_addr = read_register (ALPHA_A0_REGNUM);
+
+ if (target_read_memory (jb_addr + (tdep->jb_pc * tdep->jb_elt_size),
+ raw_buffer, tdep->jb_elt_size))
+ return 0;
+
+ *pc = extract_unsigned_integer (raw_buffer, tdep->jb_elt_size);
+ return 1;
}
-#if 0
-/* Is address PC in the prologue (loosely defined) for function at
- STARTADDR? */
+
+/* Frame unwinder for signal trampolines. We use alpha tdep bits that
+ describe the location and shape of the sigcontext structure. After
+ that, all registers are in memory, so it's easy. */
+/* ??? Shouldn't we be able to do this generically, rather than with
+ OSABI data specific to Alpha? */
-static int
-alpha_in_lenient_prologue (CORE_ADDR startaddr, CORE_ADDR pc)
+struct alpha_sigtramp_unwind_cache
{
- CORE_ADDR end_prologue = alpha_skip_prologue_internal (startaddr, 1);
- return pc >= startaddr && pc < end_prologue;
+ CORE_ADDR sigcontext_addr;
+};
+
+static struct alpha_sigtramp_unwind_cache *
+alpha_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
+ void **this_prologue_cache)
+{
+ struct alpha_sigtramp_unwind_cache *info;
+ struct gdbarch_tdep *tdep;
+
+ if (*this_prologue_cache)
+ return *this_prologue_cache;
+
+ info = FRAME_OBSTACK_ZALLOC (struct alpha_sigtramp_unwind_cache);
+ *this_prologue_cache = info;
+
+ tdep = gdbarch_tdep (current_gdbarch);
+ info->sigcontext_addr = tdep->sigcontext_addr (next_frame);
+
+ return info;
}
-#endif
-
-/* The alpha needs a conversion between register and memory format if
- the register is a floating point register and
- memory format is float, as the register format must be double
- or
- memory format is an integer with 4 bytes or less, as the representation
- of integers in floating point registers is different. */
-void
-alpha_register_convert_to_virtual (int regnum, struct type *valtype,
- char *raw_buffer, char *virtual_buffer)
+
+/* Return the address of REGNUM in a sigtramp frame. Since this is
+ all arithmetic, it doesn't seem worthwhile to cache it. */
+
+static CORE_ADDR
+alpha_sigtramp_register_address (CORE_ADDR sigcontext_addr, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (regnum >= 0 && regnum < 32)
+ return sigcontext_addr + tdep->sc_regs_offset + regnum * 8;
+ else if (regnum >= ALPHA_FP0_REGNUM && regnum < ALPHA_FP0_REGNUM + 32)
+ return sigcontext_addr + tdep->sc_fpregs_offset + regnum * 8;
+ else if (regnum == ALPHA_PC_REGNUM)
+ return sigcontext_addr + tdep->sc_pc_offset;
+
+ return 0;
+}
+
+/* Given a GDB frame, determine the address of the calling function's
+ frame. This will be used to create a new GDB frame struct. */
+
+static void
+alpha_sigtramp_frame_this_id (struct frame_info *next_frame,
+ void **this_prologue_cache,
+ struct frame_id *this_id)
{
- if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum))
- {
- memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
- return;
- }
+ struct alpha_sigtramp_unwind_cache *info
+ = alpha_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
+ struct gdbarch_tdep *tdep;
+ CORE_ADDR stack_addr, code_addr;
- if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
- {
- double d = extract_floating (raw_buffer, REGISTER_RAW_SIZE (regnum));
- store_floating (virtual_buffer, TYPE_LENGTH (valtype), d);
- }
- else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
+ /* If the OSABI couldn't locate the sigcontext, give up. */
+ if (info->sigcontext_addr == 0)
+ return;
+
+ /* If we have dynamic signal trampolines, find their start.
+ If we do not, then we must assume there is a symbol record
+ that can provide the start address. */
+ tdep = gdbarch_tdep (current_gdbarch);
+ if (tdep->dynamic_sigtramp_offset)
{
- ULONGEST l;
- l = extract_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum));
- l = ((l >> 32) & 0xc0000000) | ((l >> 29) & 0x3fffffff);
- store_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype), l);
+ int offset;
+ code_addr = frame_pc_unwind (next_frame);
+ offset = tdep->dynamic_sigtramp_offset (code_addr);
+ if (offset >= 0)
+ code_addr -= offset;
+ else
+ code_addr = 0;
}
else
- error ("Cannot retrieve value from floating point register");
+ code_addr = frame_func_unwind (next_frame);
+
+ /* The stack address is trivially read from the sigcontext. */
+ stack_addr = alpha_sigtramp_register_address (info->sigcontext_addr,
+ ALPHA_SP_REGNUM);
+ stack_addr = get_frame_memory_unsigned (next_frame, stack_addr,
+ ALPHA_REGISTER_SIZE);
+
+ *this_id = frame_id_build (stack_addr, code_addr);
}
-void
-alpha_register_convert_to_raw (struct type *valtype, int regnum,
- char *virtual_buffer, char *raw_buffer)
+/* Retrieve the value of REGNUM in FRAME. Don't give up! */
+
+static void
+alpha_sigtramp_frame_prev_register (struct frame_info *next_frame,
+ void **this_prologue_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, void *bufferp)
{
- if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum))
+ struct alpha_sigtramp_unwind_cache *info
+ = alpha_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
+ CORE_ADDR addr;
+
+ if (info->sigcontext_addr != 0)
{
- memcpy (raw_buffer, virtual_buffer, REGISTER_RAW_SIZE (regnum));
- return;
+ /* All integer and fp registers are stored in memory. */
+ addr = alpha_sigtramp_register_address (info->sigcontext_addr, regnum);
+ if (addr != 0)
+ {
+ *optimizedp = 0;
+ *lvalp = lval_memory;
+ *addrp = addr;
+ *realnump = -1;
+ if (bufferp != NULL)
+ get_frame_memory (next_frame, addr, bufferp, ALPHA_REGISTER_SIZE);
+ return;
+ }
}
- if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+ /* This extra register may actually be in the sigcontext, but our
+ current description of it in alpha_sigtramp_frame_unwind_cache
+ doesn't include it. Too bad. Fall back on whatever's in the
+ outer frame. */
+ frame_register (next_frame, regnum, optimizedp, lvalp, addrp,
+ realnump, bufferp);
+}
+
+static const struct frame_unwind alpha_sigtramp_frame_unwind = {
+ SIGTRAMP_FRAME,
+ alpha_sigtramp_frame_this_id,
+ alpha_sigtramp_frame_prev_register
+};
+
+static const struct frame_unwind *
+alpha_sigtramp_frame_sniffer (struct frame_info *next_frame)
+{
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+ char *name;
+
+ /* We shouldn't even bother to try if the OSABI didn't register
+ a sigcontext_addr handler. */
+ if (!gdbarch_tdep (current_gdbarch)->sigcontext_addr)
+ return NULL;
+
+ /* Otherwise we should be in a signal frame. */
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (PC_IN_SIGTRAMP (pc, name))
+ return &alpha_sigtramp_frame_unwind;
+
+ return NULL;
+}
+
+/* Fallback alpha frame unwinder. Uses instruction scanning and knows
+ something about the traditional layout of alpha stack frames. */
+
+struct alpha_heuristic_unwind_cache
+{
+ CORE_ADDR *saved_regs;
+ CORE_ADDR vfp;
+ CORE_ADDR start_pc;
+ int return_reg;
+};
+
+/* Heuristic_proc_start may hunt through the text section for a long
+ time across a 2400 baud serial line. Allows the user to limit this
+ search. */
+static unsigned int heuristic_fence_post = 0;
+
+/* Attempt to locate the start of the function containing PC. We assume that
+ the previous function ends with an about_to_return insn. Not foolproof by
+ any means, since gcc is happy to put the epilogue in the middle of a
+ function. But we're guessing anyway... */
+
+static CORE_ADDR
+alpha_heuristic_proc_start (CORE_ADDR pc)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ CORE_ADDR last_non_nop = pc;
+ CORE_ADDR fence = pc - heuristic_fence_post;
+ CORE_ADDR orig_pc = pc;
+ CORE_ADDR func;
+
+ if (pc == 0)
+ return 0;
+
+ /* First see if we can find the start of the function from minimal
+ symbol information. This can succeed with a binary that doesn't
+ have debug info, but hasn't been stripped. */
+ func = get_pc_function_start (pc);
+ if (func)
+ return func;
+
+ if (heuristic_fence_post == UINT_MAX
+ || fence < tdep->vm_min_address)
+ fence = tdep->vm_min_address;
+
+ /* Search back for previous return; also stop at a 0, which might be
+ seen for instance before the start of a code section. Don't include
+ nops, since this usually indicates padding between functions. */
+ for (pc -= 4; pc >= fence; pc -= 4)
{
- double d = extract_floating (virtual_buffer, TYPE_LENGTH (valtype));
- store_floating (raw_buffer, REGISTER_RAW_SIZE (regnum), d);
+ unsigned int insn = alpha_read_insn (pc);
+ switch (insn)
+ {
+ case 0: /* invalid insn */
+ case 0x6bfa8001: /* ret $31,($26),1 */
+ return last_non_nop;
+
+ case 0x2ffe0000: /* unop: ldq_u $31,0($30) */
+ case 0x47ff041f: /* nop: bis $31,$31,$31 */
+ break;
+
+ default:
+ last_non_nop = pc;
+ break;
+ }
}
- else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
+
+ /* It's not clear to me why we reach this point when stopping quietly,
+ but with this test, at least we don't print out warnings for every
+ child forked (eg, on decstation). 22apr93 rich@cygnus.com. */
+ if (stop_soon == NO_STOP_QUIETLY)
{
- ULONGEST l;
- if (TYPE_UNSIGNED (valtype))
- l = extract_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype));
+ static int blurb_printed = 0;
+
+ if (fence == tdep->vm_min_address)
+ warning ("Hit beginning of text section without finding");
else
- l = extract_signed_integer (virtual_buffer, TYPE_LENGTH (valtype));
- l = ((l & 0xc0000000) << 32) | ((l & 0x3fffffff) << 29);
- store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), l);
+ warning ("Hit heuristic-fence-post without finding");
+ warning ("enclosing function for address 0x%s", paddr_nz (orig_pc));
+
+ if (!blurb_printed)
+ {
+ printf_filtered ("\
+This warning occurs if you are debugging a function without any symbols\n\
+(for example, in a stripped executable). In that case, you may wish to\n\
+increase the size of the search with the `set heuristic-fence-post' command.\n\
+\n\
+Otherwise, you told GDB there was a function where there isn't one, or\n\
+(more likely) you have encountered a bug in GDB.\n");
+ blurb_printed = 1;
+ }
}
- else
- error ("Cannot store value in floating point register");
+
+ return 0;
}
-/* Given a return value in `regbuf' with a type `valtype',
- extract and copy its value into `valbuf'. */
+static struct alpha_heuristic_unwind_cache *
+alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame,
+ void **this_prologue_cache,
+ CORE_ADDR start_pc)
+{
+ struct alpha_heuristic_unwind_cache *info;
+ ULONGEST val;
+ CORE_ADDR limit_pc, cur_pc;
+ int frame_reg, frame_size, return_reg, reg;
-void
-alpha_extract_return_value (struct type *valtype,
- char regbuf[REGISTER_BYTES], char *valbuf)
+ if (*this_prologue_cache)
+ return *this_prologue_cache;
+
+ info = FRAME_OBSTACK_ZALLOC (struct alpha_heuristic_unwind_cache);
+ *this_prologue_cache = info;
+ info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS);
+
+ limit_pc = frame_pc_unwind (next_frame);
+ if (start_pc == 0)
+ start_pc = alpha_heuristic_proc_start (limit_pc);
+ info->start_pc = start_pc;
+
+ frame_reg = ALPHA_SP_REGNUM;
+ frame_size = 0;
+ return_reg = -1;
+
+ /* If we've identified a likely place to start, do code scanning. */
+ if (start_pc != 0)
+ {
+ /* Limit the forward search to 50 instructions. */
+ if (start_pc + 200 < limit_pc)
+ limit_pc = start_pc + 200;
+
+ for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4)
+ {
+ unsigned int word = alpha_read_insn (cur_pc);
+
+ if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */
+ {
+ if (word & 0x8000)
+ {
+ /* Consider only the first stack allocation instruction
+ to contain the static size of the frame. */
+ if (frame_size == 0)
+ frame_size = (-word) & 0xffff;
+ }
+ else
+ {
+ /* Exit loop if a positive stack adjustment is found, which
+ usually means that the stack cleanup code in the function
+ epilogue is reached. */
+ break;
+ }
+ }
+ else if ((word & 0xfc1f0000) == 0xb41e0000) /* stq reg,n($sp) */
+ {
+ reg = (word & 0x03e00000) >> 21;
+
+ /* Ignore this instruction if we have already encountered
+ an instruction saving the same register earlier in the
+ function code. The current instruction does not tell
+ us where the original value upon function entry is saved.
+ All it says is that the function we are scanning reused
+ that register for some computation of its own, and is now
+ saving its result. */
+ if (info->saved_regs[reg])
+ continue;
+
+ if (reg == 31)
+ continue;
+
+ /* Do not compute the address where the register was saved yet,
+ because we don't know yet if the offset will need to be
+ relative to $sp or $fp (we can not compute the address
+ relative to $sp if $sp is updated during the execution of
+ the current subroutine, for instance when doing some alloca).
+ So just store the offset for the moment, and compute the
+ address later when we know whether this frame has a frame
+ pointer or not. */
+ /* Hack: temporarily add one, so that the offset is non-zero
+ and we can tell which registers have save offsets below. */
+ info->saved_regs[reg] = (word & 0xffff) + 1;
+
+ /* Starting with OSF/1-3.2C, the system libraries are shipped
+ without local symbols, but they still contain procedure
+ descriptors without a symbol reference. GDB is currently
+ unable to find these procedure descriptors and uses
+ heuristic_proc_desc instead.
+ As some low level compiler support routines (__div*, __add*)
+ use a non-standard return address register, we have to
+ add some heuristics to determine the return address register,
+ or stepping over these routines will fail.
+ Usually the return address register is the first register
+ saved on the stack, but assembler optimization might
+ rearrange the register saves.
+ So we recognize only a few registers (t7, t9, ra) within
+ the procedure prologue as valid return address registers.
+ If we encounter a return instruction, we extract the
+ the return address register from it.
+
+ FIXME: Rewriting GDB to access the procedure descriptors,
+ e.g. via the minimal symbol table, might obviate this hack. */
+ if (return_reg == -1
+ && cur_pc < (start_pc + 80)
+ && (reg == ALPHA_T7_REGNUM
+ || reg == ALPHA_T9_REGNUM
+ || reg == ALPHA_RA_REGNUM))
+ return_reg = reg;
+ }
+ else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
+ return_reg = (word >> 16) & 0x1f;
+ else if (word == 0x47de040f) /* bis sp,sp,fp */
+ frame_reg = ALPHA_GCC_FP_REGNUM;
+ else if (word == 0x47fe040f) /* bis zero,sp,fp */
+ frame_reg = ALPHA_GCC_FP_REGNUM;
+ }
+
+ /* If we haven't found a valid return address register yet, keep
+ searching in the procedure prologue. */
+ if (return_reg == -1)
+ {
+ while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80))
+ {
+ unsigned int word = alpha_read_insn (cur_pc);
+
+ if ((word & 0xfc1f0000) == 0xb41e0000) /* stq reg,n($sp) */
+ {
+ reg = (word & 0x03e00000) >> 21;
+ if (reg == ALPHA_T7_REGNUM
+ || reg == ALPHA_T9_REGNUM
+ || reg == ALPHA_RA_REGNUM)
+ {
+ return_reg = reg;
+ break;
+ }
+ }
+ else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
+ {
+ return_reg = (word >> 16) & 0x1f;
+ break;
+ }
+
+ cur_pc += 4;
+ }
+ }
+ }
+
+ /* Failing that, do default to the customary RA. */
+ if (return_reg == -1)
+ return_reg = ALPHA_RA_REGNUM;
+ info->return_reg = return_reg;
+
+ frame_unwind_unsigned_register (next_frame, frame_reg, &val);
+ info->vfp = val + frame_size;
+
+ /* Convert offsets to absolute addresses. See above about adding
+ one to the offsets to make all detected offsets non-zero. */
+ for (reg = 0; reg < ALPHA_NUM_REGS; ++reg)
+ if (info->saved_regs[reg])
+ info->saved_regs[reg] += val - 1;
+
+ return info;
+}
+
+/* Given a GDB frame, determine the address of the calling function's
+ frame. This will be used to create a new GDB frame struct. */
+
+static void
+alpha_heuristic_frame_this_id (struct frame_info *next_frame,
+ void **this_prologue_cache,
+ struct frame_id *this_id)
{
- if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
- alpha_register_convert_to_virtual (FP0_REGNUM, valtype,
- regbuf + REGISTER_BYTE (FP0_REGNUM),
- valbuf);
- else
- memcpy (valbuf, regbuf + REGISTER_BYTE (V0_REGNUM), TYPE_LENGTH (valtype));
+ struct alpha_heuristic_unwind_cache *info
+ = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0);
+
+ *this_id = frame_id_build (info->vfp, info->start_pc);
}
-/* Given a return value in `regbuf' with a type `valtype',
- write its value into the appropriate register. */
+/* Retrieve the value of REGNUM in FRAME. Don't give up! */
-void
-alpha_store_return_value (struct type *valtype, char *valbuf)
+static void
+alpha_heuristic_frame_prev_register (struct frame_info *next_frame,
+ void **this_prologue_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, void *bufferp)
{
- char raw_buffer[MAX_REGISTER_RAW_SIZE];
- int regnum = V0_REGNUM;
- int length = TYPE_LENGTH (valtype);
+ struct alpha_heuristic_unwind_cache *info
+ = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0);
+
+ /* The PC of the previous frame is stored in the link register of
+ the current frame. Frob regnum so that we pull the value from
+ the correct place. */
+ if (regnum == ALPHA_PC_REGNUM)
+ regnum = info->return_reg;
+
+ /* For all registers known to be saved in the current frame,
+ do the obvious and pull the value out. */
+ if (info->saved_regs[regnum])
+ {
+ *optimizedp = 0;
+ *lvalp = lval_memory;
+ *addrp = info->saved_regs[regnum];
+ *realnump = -1;
+ if (bufferp != NULL)
+ get_frame_memory (next_frame, *addrp, bufferp, ALPHA_REGISTER_SIZE);
+ return;
+ }
- if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+ /* The stack pointer of the previous frame is computed by popping
+ the current stack frame. */
+ if (regnum == ALPHA_SP_REGNUM)
{
- regnum = FP0_REGNUM;
- length = REGISTER_RAW_SIZE (regnum);
- alpha_register_convert_to_raw (valtype, regnum, valbuf, raw_buffer);
+ *optimizedp = 0;
+ *lvalp = not_lval;
+ *addrp = 0;
+ *realnump = -1;
+ if (bufferp != NULL)
+ store_unsigned_integer (bufferp, ALPHA_REGISTER_SIZE, info->vfp);
+ return;
}
- else
- memcpy (raw_buffer, valbuf, length);
- write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, length);
+ /* Otherwise assume the next frame has the same register value. */
+ frame_register (next_frame, regnum, optimizedp, lvalp, addrp,
+ realnump, bufferp);
}
+static const struct frame_unwind alpha_heuristic_frame_unwind = {
+ NORMAL_FRAME,
+ alpha_heuristic_frame_this_id,
+ alpha_heuristic_frame_prev_register
+};
+
+static const struct frame_unwind *
+alpha_heuristic_frame_sniffer (struct frame_info *next_frame)
+{
+ return &alpha_heuristic_frame_unwind;
+}
+
+static CORE_ADDR
+alpha_heuristic_frame_base_address (struct frame_info *next_frame,
+ void **this_prologue_cache)
+{
+ struct alpha_heuristic_unwind_cache *info
+ = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0);
+
+ return info->vfp;
+}
+
+static const struct frame_base alpha_heuristic_frame_base = {
+ &alpha_heuristic_frame_unwind,
+ alpha_heuristic_frame_base_address,
+ alpha_heuristic_frame_base_address,
+ alpha_heuristic_frame_base_address
+};
+
/* Just like reinit_frame_cache, but with the right arguments to be
- callable as an sfunc. */
+ callable as an sfunc. Used by the "set heuristic-fence-post" command. */
static void
reinit_frame_cache_sfunc (char *args, int from_tty, struct cmd_list_element *c)
@@ -1493,68 +1236,120 @@ reinit_frame_cache_sfunc (char *args, int from_tty, struct cmd_list_element *c)
reinit_frame_cache ();
}
-/* This is the definition of CALL_DUMMY_ADDRESS. It's a heuristic that is used
- to find a convenient place in the text segment to stick a breakpoint to
- detect the completion of a target function call (ala call_function_by_hand).
- */
+
+/* ALPHA stack frames are almost impenetrable. When execution stops,
+ we basically have to look at symbol information for the function
+ that we stopped in, which tells us *which* register (if any) is
+ the base of the frame pointer, and what offset from that register
+ the frame itself is at.
+
+ This presents a problem when trying to examine a stack in memory
+ (that isn't executing at the moment), using the "frame" command. We
+ don't have a PC, nor do we have any registers except SP.
-CORE_ADDR
-alpha_call_dummy_address (void)
+ This routine takes two arguments, SP and PC, and tries to make the
+ cached frames look as if these two arguments defined a frame on the
+ cache. This allows the rest of info frame to extract the important
+ arguments without difficulty. */
+
+struct frame_info *
+alpha_setup_arbitrary_frame (int argc, CORE_ADDR *argv)
{
- CORE_ADDR entry;
- struct minimal_symbol *sym;
+ if (argc != 2)
+ error ("ALPHA frame specifications require two arguments: sp and pc");
- entry = entry_point_address ();
+ return create_new_frame (argv[0], argv[1]);
+}
- if (entry != 0)
- return entry;
+/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
+ dummy frame. The frame ID's base needs to match the TOS value
+ saved by save_dummy_frame_tos(), and the PC match the dummy frame's
+ breakpoint. */
- sym = lookup_minimal_symbol ("_Prelude", NULL, symfile_objfile);
+static struct frame_id
+alpha_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ ULONGEST base;
+ frame_unwind_unsigned_register (next_frame, ALPHA_SP_REGNUM, &base);
+ return frame_id_build (base, frame_pc_unwind (next_frame));
+}
- if (!sym || MSYMBOL_TYPE (sym) != mst_text)
- return 0;
- else
- return SYMBOL_VALUE_ADDRESS (sym) + 4;
+static CORE_ADDR
+alpha_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ ULONGEST pc;
+ frame_unwind_unsigned_register (next_frame, ALPHA_PC_REGNUM, &pc);
+ return pc;
}
+
+/* Helper routines for alpha*-nat.c files to move register sets to and
+ from core files. The UNIQUE pointer is allowed to be NULL, as most
+ targets don't supply this value in their core files. */
+
void
-alpha_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
- struct value **args, struct type *type, int gcc_p)
+alpha_supply_int_regs (int regno, const void *r0_r30,
+ const void *pc, const void *unique)
{
- CORE_ADDR bp_address = CALL_DUMMY_ADDRESS ();
+ int i;
- if (bp_address == 0)
- error ("no place to put call");
- write_register (RA_REGNUM, bp_address);
- write_register (T12_REGNUM, fun);
-}
+ for (i = 0; i < 31; ++i)
+ if (regno == i || regno == -1)
+ supply_register (i, (const char *)r0_r30 + i*8);
+
+ if (regno == ALPHA_ZERO_REGNUM || regno == -1)
+ supply_register (ALPHA_ZERO_REGNUM, NULL);
-/* On the Alpha, the call dummy code is nevery copied to user space
- (see alpha_fix_call_dummy() above). The contents of this do not
- matter. */
-LONGEST alpha_call_dummy_words[] = { 0 };
+ if (regno == ALPHA_PC_REGNUM || regno == -1)
+ supply_register (ALPHA_PC_REGNUM, pc);
-int
-alpha_use_struct_convention (int gcc_p, struct type *type)
+ if (regno == ALPHA_UNIQUE_REGNUM || regno == -1)
+ supply_register (ALPHA_UNIQUE_REGNUM, unique);
+}
+
+void
+alpha_fill_int_regs (int regno, void *r0_r30, void *pc, void *unique)
{
- /* Structures are returned by ref in extra arg0. */
- return 1;
+ int i;
+
+ for (i = 0; i < 31; ++i)
+ if (regno == i || regno == -1)
+ regcache_collect (i, (char *)r0_r30 + i*8);
+
+ if (regno == ALPHA_PC_REGNUM || regno == -1)
+ regcache_collect (ALPHA_PC_REGNUM, pc);
+
+ if (unique && (regno == ALPHA_UNIQUE_REGNUM || regno == -1))
+ regcache_collect (ALPHA_UNIQUE_REGNUM, unique);
}
void
-alpha_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+alpha_supply_fp_regs (int regno, const void *f0_f30, const void *fpcr)
{
- /* Store the address of the place in which to copy the structure the
- subroutine will return. Handled by alpha_push_arguments. */
+ int i;
+
+ for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i)
+ if (regno == i || regno == -1)
+ supply_register (i, (const char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8);
+
+ if (regno == ALPHA_FPCR_REGNUM || regno == -1)
+ supply_register (ALPHA_FPCR_REGNUM, fpcr);
}
-CORE_ADDR
-alpha_extract_struct_value_address (char *regbuf)
+void
+alpha_fill_fp_regs (int regno, void *f0_f30, void *fpcr)
{
- return (extract_address (regbuf + REGISTER_BYTE (V0_REGNUM),
- REGISTER_RAW_SIZE (V0_REGNUM)));
+ int i;
+
+ for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i)
+ if (regno == i || regno == -1)
+ regcache_collect (i, (char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8);
+
+ if (regno == ALPHA_FPCR_REGNUM || regno == -1)
+ regcache_collect (ALPHA_FPCR_REGNUM, fpcr);
}
+
/* alpha_software_single_step() is called just before we want to resume
the inferior, if we want to single-step it but there is no hardware
or kernel single-step support (NetBSD on Alpha, for example). We find
@@ -1571,7 +1366,7 @@ alpha_next_pc (CORE_ADDR pc)
int offset;
LONGEST rav;
- insn = read_memory_unsigned_integer (pc, sizeof (insn));
+ insn = alpha_read_insn (pc);
/* Opcode is top 6 bits. */
op = (insn >> 26) & 0x3f;
@@ -1634,6 +1429,8 @@ alpha_next_pc (CORE_ADDR pc)
if (rav >= 0)
goto branch_taken;
break;
+
+ /* ??? Missing floating-point branches. */
}
}
@@ -1664,12 +1461,139 @@ alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
}
}
+
+/* Initialize the current architecture based on INFO. If possible, re-use an
+ architecture from ARCHES, which is a list of architectures already created
+ during this debugging session.
+
+ Called e.g. at program startup, when reading a core file, and when reading
+ a binary file. */
+
+static struct gdbarch *
+alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ struct gdbarch_tdep *tdep;
+ struct gdbarch *gdbarch;
+
+ /* Try to determine the ABI of the object we are loading. */
+ if (info.abfd != NULL && info.osabi == GDB_OSABI_UNKNOWN)
+ {
+ /* If it's an ECOFF file, assume it's OSF/1. */
+ if (bfd_get_flavour (info.abfd) == bfd_target_ecoff_flavour)
+ info.osabi = GDB_OSABI_OSF1;
+ }
+
+ /* Find a candidate among extant architectures. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
+
+ tdep = xmalloc (sizeof (struct gdbarch_tdep));
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ /* Lowest text address. This is used by heuristic_proc_start()
+ to decide when to stop looking. */
+ tdep->vm_min_address = (CORE_ADDR) 0x120000000;
+
+ tdep->dynamic_sigtramp_offset = NULL;
+ tdep->sigcontext_addr = NULL;
+ tdep->sc_pc_offset = 2 * 8;
+ tdep->sc_regs_offset = 4 * 8;
+ tdep->sc_fpregs_offset = tdep->sc_regs_offset + 32 * 8 + 8;
+
+ tdep->jb_pc = -1; /* longjmp support not enabled by default */
+
+ /* Type sizes */
+ set_gdbarch_short_bit (gdbarch, 16);
+ set_gdbarch_int_bit (gdbarch, 32);
+ set_gdbarch_long_bit (gdbarch, 64);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ set_gdbarch_float_bit (gdbarch, 32);
+ set_gdbarch_double_bit (gdbarch, 64);
+ set_gdbarch_long_double_bit (gdbarch, 64);
+ set_gdbarch_ptr_bit (gdbarch, 64);
+
+ /* Register info */
+ set_gdbarch_num_regs (gdbarch, ALPHA_NUM_REGS);
+ set_gdbarch_sp_regnum (gdbarch, ALPHA_SP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, ALPHA_PC_REGNUM);
+ set_gdbarch_fp0_regnum (gdbarch, ALPHA_FP0_REGNUM);
+
+ set_gdbarch_register_name (gdbarch, alpha_register_name);
+ set_gdbarch_deprecated_register_byte (gdbarch, alpha_register_byte);
+ set_gdbarch_deprecated_register_raw_size (gdbarch, alpha_register_raw_size);
+ set_gdbarch_deprecated_register_virtual_size (gdbarch, alpha_register_virtual_size);
+ set_gdbarch_register_type (gdbarch, alpha_register_type);
+
+ set_gdbarch_cannot_fetch_register (gdbarch, alpha_cannot_fetch_register);
+ set_gdbarch_cannot_store_register (gdbarch, alpha_cannot_store_register);
+
+ set_gdbarch_convert_register_p (gdbarch, alpha_convert_register_p);
+ set_gdbarch_register_to_value (gdbarch, alpha_register_to_value);
+ set_gdbarch_value_to_register (gdbarch, alpha_value_to_register);
+
+ set_gdbarch_register_reggroup_p (gdbarch, alpha_register_reggroup_p);
+
+ /* Prologue heuristics. */
+ set_gdbarch_skip_prologue (gdbarch, alpha_skip_prologue);
+
+ /* Disassembler. */
+ set_gdbarch_print_insn (gdbarch, print_insn_alpha);
+
+ /* Call info. */
+
+ set_gdbarch_use_struct_convention (gdbarch, always_use_struct_convention);
+ set_gdbarch_extract_return_value (gdbarch, alpha_extract_return_value);
+ set_gdbarch_store_return_value (gdbarch, alpha_store_return_value);
+ set_gdbarch_deprecated_extract_struct_value_address (gdbarch, alpha_extract_struct_value_address);
+
+ /* Settings for calling functions in the inferior. */
+ set_gdbarch_push_dummy_call (gdbarch, alpha_push_dummy_call);
+
+ /* Methods for saving / extracting a dummy frame's ID. */
+ set_gdbarch_unwind_dummy_id (gdbarch, alpha_unwind_dummy_id);
+
+ /* Return the unwound PC value. */
+ set_gdbarch_unwind_pc (gdbarch, alpha_unwind_pc);
+
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+
+ set_gdbarch_breakpoint_from_pc (gdbarch, alpha_breakpoint_from_pc);
+ set_gdbarch_decr_pc_after_break (gdbarch, 4);
+
+ /* Hook in ABI-specific overrides, if they have been registered. */
+ gdbarch_init_osabi (info, gdbarch);
+
+ /* Now that we have tuned the configuration, set a few final things
+ based on what the OS ABI has told us. */
+
+ if (tdep->jb_pc >= 0)
+ set_gdbarch_get_longjmp_target (gdbarch, alpha_get_longjmp_target);
+
+ frame_unwind_append_sniffer (gdbarch, alpha_sigtramp_frame_sniffer);
+ frame_unwind_append_sniffer (gdbarch, alpha_heuristic_frame_sniffer);
+
+ frame_base_set_default (gdbarch, &alpha_heuristic_frame_base);
+
+ return gdbarch;
+}
+
+void
+alpha_dwarf2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+ frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
+}
+
+extern initialize_file_ftype _initialize_alpha_tdep; /* -Wmissing-prototypes */
+
void
_initialize_alpha_tdep (void)
{
struct cmd_list_element *c;
- tm_print_insn = print_insn_alpha;
+ gdbarch_register (bfd_arch_alpha, alpha_gdbarch_init, NULL);
/* Let the user set the fence post for heuristic_proc_start. */
diff --git a/contrib/gdb/gdb/coffread.c b/contrib/gdb/gdb/coffread.c
index 84b3761..056ba13 100644
--- a/contrib/gdb/gdb/coffread.c
+++ b/contrib/gdb/gdb/coffread.c
@@ -1,6 +1,6 @@
/* Read coff symbol tables and convert to internal format, for GDB.
Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
@@ -28,15 +28,13 @@
#include "breakpoint.h"
#include "bfd.h"
-#include "obstack.h"
+#include "gdb_obstack.h"
#include "gdb_string.h"
#include <ctype.h>
#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
#include "libcoff.h" /* FIXME secret internal data from BFD */
-
-#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "gdb-stabs.h"
@@ -44,6 +42,10 @@
#include "complaints.h"
#include "target.h"
#include "gdb_assert.h"
+#include "block.h"
+#include "dictionary.h"
+
+#include "coff-pe-read.h"
extern void _initialize_coffread (void);
@@ -122,41 +124,6 @@ static int pe_file;
static struct symbol *opaque_type_chain[HASHSIZE];
-/* Complaints about various problems in the file being read */
-
-struct complaint ef_complaint =
-{"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0};
-
-struct complaint ef_stack_complaint =
-{"`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d", 0, 0};
-
-struct complaint eb_stack_complaint =
-{"`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d", 0, 0};
-
-struct complaint bf_no_aux_complaint =
-{"`.bf' symbol %d has no aux entry", 0, 0};
-
-struct complaint ef_no_aux_complaint =
-{"`.ef' symbol %d has no aux entry", 0, 0};
-
-struct complaint lineno_complaint =
-{"Line number pointer %d lower than start of line numbers", 0, 0};
-
-struct complaint unexpected_type_complaint =
-{"Unexpected type for symbol %s", 0, 0};
-
-struct complaint bad_sclass_complaint =
-{"Bad n_sclass for symbol %s", 0, 0};
-
-struct complaint misordered_blocks_complaint =
-{"Blocks out of order at address %x", 0, 0};
-
-struct complaint tagndx_bad_complaint =
-{"Symbol table entry for %s has bad tagndx value", 0, 0};
-
-struct complaint eb_complaint =
-{"Mismatched .eb symbol ignored starting at symnum %d", 0, 0};
-
/* Simplified internal version of coff symbol table information */
struct coff_symbol
@@ -228,12 +195,12 @@ static void coff_symtab_read (long, unsigned int, struct objfile *);
static void
coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
{
- register struct coff_symfile_info *csi;
+ struct coff_symfile_info *csi;
const char *name;
csi = (struct coff_symfile_info *) csip;
name = bfd_get_section_name (abfd, sectp);
- if (STREQ (name, ".text"))
+ if (DEPRECATED_STREQ (name, ".text"))
{
csi->textaddr = bfd_section_vma (abfd, sectp);
csi->textsize += bfd_section_size (abfd, sectp);
@@ -242,7 +209,7 @@ coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
{
csi->textsize += bfd_section_size (abfd, sectp);
}
- else if (STREQ (name, ".stabstr"))
+ else if (DEPRECATED_STREQ (name, ".stabstr"))
{
csi->stabstrsect = sectp;
}
@@ -344,7 +311,7 @@ cs_section_address (struct coff_symbol *cs, bfd *abfd)
or for associating a new type with the index. */
static struct type **
-coff_lookup_type (register int index)
+coff_lookup_type (int index)
{
if (index >= type_vector_length)
{
@@ -370,8 +337,8 @@ coff_lookup_type (register int index)
static struct type *
coff_alloc_type (int index)
{
- register struct type **type_addr = coff_lookup_type (index);
- register struct type *type = *type_addr;
+ struct type **type_addr = coff_lookup_type (index);
+ struct type *type = *type_addr;
/* If we are referring to a type not known at all yet,
allocate an empty type for it.
@@ -422,8 +389,8 @@ complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
if (current_objfile->ei.entry_point >= current_source_start_addr &&
current_objfile->ei.entry_point < current_source_end_addr)
{
- current_objfile->ei.entry_file_lowpc = current_source_start_addr;
- current_objfile->ei.entry_file_highpc = current_source_end_addr;
+ current_objfile->ei.deprecated_entry_file_lowpc = current_source_start_addr;
+ current_objfile->ei.deprecated_entry_file_highpc = current_source_end_addr;
}
}
@@ -500,9 +467,8 @@ coff_symfile_init (struct objfile *objfile)
of the line table (minimum and maximum file offset) so that the
mainline code can read the whole thing for efficiency. */
-/* ARGSUSED */
static void
-find_linenos (bfd *abfd, sec_ptr asect, void *vpinfo)
+find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
{
struct coff_symfile_info *info;
int size, count;
@@ -537,7 +503,6 @@ static bfd *symfile_bfd;
/* Read a symbol file, after initialization by coff_symfile_init. */
-/* ARGSUSED */
static void
coff_symfile_read (struct objfile *objfile, int mainline)
{
@@ -546,11 +511,11 @@ coff_symfile_read (struct objfile *objfile, int mainline)
bfd *abfd = objfile->obfd;
coff_data_type *cdata = coff_data (abfd);
char *name = bfd_get_filename (abfd);
- register int val;
+ int val;
unsigned int num_symbols;
int symtab_offset;
int stringtab_offset;
- struct cleanup *back_to;
+ struct cleanup *back_to, *cleanup_minimal_symbols;
int stabstrsize;
int len;
char * target;
@@ -593,16 +558,34 @@ coff_symfile_read (struct objfile *objfile, int mainline)
/* End of warning */
- /* Read the line number table, all at once. */
info->min_lineno_offset = 0;
info->max_lineno_offset = 0;
- bfd_map_over_sections (abfd, find_linenos, (void *) info);
- make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
- val = init_lineno (abfd, info->min_lineno_offset,
- info->max_lineno_offset - info->min_lineno_offset);
- if (val < 0)
- error ("\"%s\": error reading line numbers\n", name);
+ /* Only read line number information if we have symbols.
+
+ On Windows NT, some of the system's DLL's have sections with
+ PointerToLinenumbers fields that are non-zero, but point at
+ random places within the image file. (In the case I found,
+ KERNEL32.DLL's .text section has a line number info pointer that
+ points into the middle of the string `lib\\i386\kernel32.dll'.)
+
+ However, these DLL's also have no symbols. The line number
+ tables are meaningless without symbols. And in fact, GDB never
+ uses the line number information unless there are symbols. So we
+ can avoid spurious error messages (and maybe run a little
+ faster!) by not even reading the line number table unless we have
+ symbols. */
+ if (num_symbols > 0)
+ {
+ /* Read the line number table, all at once. */
+ bfd_map_over_sections (abfd, find_linenos, (void *) info);
+
+ make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
+ val = init_lineno (abfd, info->min_lineno_offset,
+ info->max_lineno_offset - info->min_lineno_offset);
+ if (val < 0)
+ error ("\"%s\": error reading line numbers\n", name);
+ }
/* Now read the string table, all at once. */
@@ -612,27 +595,21 @@ coff_symfile_read (struct objfile *objfile, int mainline)
error ("\"%s\": can't get string table", name);
init_minimal_symbol_collection ();
- make_cleanup_discard_minimal_symbols ();
+ cleanup_minimal_symbols = make_cleanup_discard_minimal_symbols ();
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
- /* Sort symbols alphabetically within each block. */
-
- {
- struct symtab *s;
-
- for (s = objfile->symtabs; s != NULL; s = s->next)
- sort_symtab_syms (s);
- }
-
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
install_minimal_symbols (objfile);
+ /* Free the installed minimal symbol data. */
+ do_cleanups (cleanup_minimal_symbols);
+
bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
if (info->stabsects)
@@ -698,9 +675,9 @@ static void
coff_symtab_read (long symtab_offset, unsigned int nsyms,
struct objfile *objfile)
{
- register struct context_stack *new;
+ struct context_stack *new;
struct coff_symbol coff_symbol;
- register struct coff_symbol *cs = &coff_symbol;
+ struct coff_symbol *cs = &coff_symbol;
static struct internal_syment main_sym;
static union internal_auxent main_aux;
struct coff_symbol fcn_cs_saved;
@@ -803,7 +780,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
case C_LINE:
case C_ALIAS:
case C_HIDDEN:
- complain (&bad_sclass_complaint, cs->c_name);
+ complaint (&symfile_complaints, "Bad n_sclass for symbol %s",
+ cs->c_name);
break;
case C_FILE:
@@ -839,7 +817,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
case C_THUMBSTATFUNC:
if (cs->c_name[0] == '.')
{
- if (STREQ (cs->c_name, ".text"))
+ if (DEPRECATED_STREQ (cs->c_name, ".text"))
{
/* FIXME: don't wire in ".text" as section name
or symbol name! */
@@ -879,7 +857,6 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
print_address_symbolic work right without the (now
gone) "set fast-symbolic-addr off" kludge. */
- /* FIXME: should use mst_abs, and not relocate, if absolute. */
enum minimal_symbol_type ms_type;
int sec;
@@ -901,12 +878,23 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|| cs->c_sclass == C_THUMBEXT ?
mst_bss : mst_file_bss;
}
+ else if (cs->c_secnum == N_ABS)
+ {
+ /* Use the correct minimal symbol type (and don't
+ relocate) for absolute values. */
+ ms_type = mst_abs;
+ sec = cs_to_section (cs, objfile);
+ tmpaddr = cs->c_value;
+ }
else
{
sec = cs_to_section (cs, objfile);
tmpaddr = cs->c_value;
- if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
- || cs->c_sclass == C_THUMBEXT)
+ /* Statics in a PE file also get relocated */
+ if (cs->c_sclass == C_EXT
+ || cs->c_sclass == C_THUMBEXTFUNC
+ || cs->c_sclass == C_THUMBEXT
+ || (pe_file && (cs->c_sclass == C_STAT)))
tmpaddr += ANOFFSET (objfile->section_offsets, sec);
if (sec == SECT_OFF_TEXT (objfile))
@@ -936,15 +924,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
if (cs->c_name[0] != '@' /* Skip tdesc symbols */ )
{
struct minimal_symbol *msym;
-
- /* FIXME: cagney/2001-02-01: The nasty (int) -> (long)
- -> (void*) cast is to ensure that that the value of
- cs->c_sclass can be correctly stored in a void
- pointer in MSYMBOL_INFO. Better solutions
- welcome. */
- gdb_assert (sizeof (void *) >= sizeof (cs->c_sclass));
msym = prim_record_minimal_symbol_and_info
- (cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass,
+ (cs->c_name, tmpaddr, ms_type, NULL,
sec, NULL, objfile);
if (msym)
COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
@@ -961,7 +942,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
break;
case C_FCN:
- if (STREQ (cs->c_name, ".bf"))
+ if (DEPRECATED_STREQ (cs->c_name, ".bf"))
{
within_function = 1;
@@ -969,7 +950,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
/* main_aux.x_sym.x_misc.x_lnsz.x_lnno
contains line number of '{' } */
if (cs->c_naux != 1)
- complain (&bf_no_aux_complaint, cs->c_symnum);
+ complaint (&symfile_complaints,
+ "`.bf' symbol %d has no aux entry", cs->c_symnum);
fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
fcn_first_line_addr = cs->c_value;
@@ -982,7 +964,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
new->name =
process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile);
}
- else if (STREQ (cs->c_name, ".ef"))
+ else if (DEPRECATED_STREQ (cs->c_name, ".ef"))
{
if (!within_function)
error ("Bad coff function information\n");
@@ -993,7 +975,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
if (context_stack_depth <= 0)
{ /* We attempted to pop an empty context stack */
- complain (&ef_stack_complaint, cs->c_symnum);
+ complaint (&symfile_complaints,
+ "`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d",
+ cs->c_symnum);
within_function = 0;
break;
}
@@ -1002,13 +986,16 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
/* Stack must be empty now. */
if (context_stack_depth > 0 || new == NULL)
{
- complain (&ef_complaint, cs->c_symnum);
+ complaint (&symfile_complaints,
+ "Unmatched .ef symbol(s) ignored starting at symnum %d",
+ cs->c_symnum);
within_function = 0;
break;
}
if (cs->c_naux != 1)
{
- complain (&ef_no_aux_complaint, cs->c_symnum);
+ complaint (&symfile_complaints,
+ "`.ef' symbol %d has no aux entry", cs->c_symnum);
fcn_last_line = 0x7FFFFFFF;
}
else
@@ -1053,24 +1040,28 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
break;
case C_BLOCK:
- if (STREQ (cs->c_name, ".bb"))
+ if (DEPRECATED_STREQ (cs->c_name, ".bb"))
{
tmpaddr = cs->c_value;
tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
push_context (++depth, tmpaddr);
}
- else if (STREQ (cs->c_name, ".eb"))
+ else if (DEPRECATED_STREQ (cs->c_name, ".eb"))
{
if (context_stack_depth <= 0)
{ /* We attempted to pop an empty context stack */
- complain (&eb_stack_complaint, cs->c_symnum);
+ complaint (&symfile_complaints,
+ "`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d",
+ cs->c_symnum);
break;
}
new = pop_context ();
if (depth-- != new->depth)
{
- complain (&eb_complaint, symnum);
+ complaint (&symfile_complaints,
+ "Mismatched .eb symbol ignored starting at symnum %d",
+ symnum);
break;
}
if (local_symbols && context_stack_depth > 0)
@@ -1092,6 +1083,13 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
}
}
+ if ((nsyms == 0) && (pe_file))
+ {
+ /* We've got no debugging symbols, but it's is a portable
+ executable, so try to read the export table */
+ read_pe_exported_syms (objfile);
+ }
+
if (last_source_file)
coff_end_symtab (objfile);
@@ -1110,9 +1108,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
in internal_auxent form, and skip any other auxents. */
static void
-read_one_sym (register struct coff_symbol *cs,
- register struct internal_syment *sym,
- register union internal_auxent *aux)
+read_one_sym (struct coff_symbol *cs,
+ struct internal_syment *sym,
+ union internal_auxent *aux)
{
int i;
@@ -1261,7 +1259,7 @@ static char *
coff_getfilename (union internal_auxent *aux_entry)
{
static char buffer[BUFSIZ];
- register char *temp;
+ char *temp;
char *result;
if (aux_entry->x_file.x_n.x_zeroes == 0)
@@ -1339,17 +1337,19 @@ free_linetab_cleanup (void *ignore)
#endif
static void
-enter_linenos (long file_offset, register int first_line,
- register int last_line, struct objfile *objfile)
+enter_linenos (long file_offset, int first_line,
+ int last_line, struct objfile *objfile)
{
- register char *rawptr;
+ char *rawptr;
struct internal_lineno lptr;
if (!linetab)
return;
if (file_offset < linetab_offset)
{
- complain (&lineno_complaint, file_offset);
+ complaint (&symfile_complaints,
+ "Line number pointer %ld lower than start of line numbers",
+ file_offset);
if (file_offset > linetab_size) /* Too big to be an offset? */
return;
file_offset += linetab_offset; /* Try reading at that linetab offset */
@@ -1362,11 +1362,15 @@ enter_linenos (long file_offset, register int first_line,
/* line numbers start at one for the first line of the function */
first_line--;
- for (;;)
+ /* If the line number table is full (e.g. 64K lines in COFF debug
+ info), the next function's L_LNNO32 might not be zero, so don't
+ overstep the table's end in any case. */
+ while (rawptr <= &linetab[0] + linetab_size)
{
bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr);
rawptr += local_linesz;
- /* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */
+ /* The next function, or the sentinel, will have L_LNNO32 zero;
+ we exit. */
if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
record_line (current_subfile, first_line + L_LNNO32 (&lptr),
lptr.l_addr.l_paddr
@@ -1379,8 +1383,8 @@ enter_linenos (long file_offset, register int first_line,
static void
patch_type (struct type *type, struct type *real_type)
{
- register struct type *target = TYPE_TARGET_TYPE (type);
- register struct type *real_target = TYPE_TARGET_TYPE (real_type);
+ struct type *target = TYPE_TARGET_TYPE (type);
+ struct type *real_target = TYPE_TARGET_TYPE (real_type);
int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field);
TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
@@ -1403,33 +1407,32 @@ patch_type (struct type *type, struct type *real_type)
static void
patch_opaque_types (struct symtab *s)
{
- register struct block *b;
- register int i;
- register struct symbol *real_sym;
+ struct block *b;
+ struct dict_iterator iter;
+ struct symbol *real_sym;
/* Go through the per-file symbols only */
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
- for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)
+ ALL_BLOCK_SYMBOLS (b, iter, real_sym)
{
/* Find completed typedefs to use to fix opaque ones.
Remove syms from the chain when their types are stored,
but search the whole chain, as there may be several syms
from different files with the same name. */
- real_sym = BLOCK_SYM (b, i);
if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
- SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
+ SYMBOL_DOMAIN (real_sym) == VAR_DOMAIN &&
TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
{
- register char *name = SYMBOL_NAME (real_sym);
- register int hash = hashname (name);
- register struct symbol *sym, *prev;
+ char *name = DEPRECATED_SYMBOL_NAME (real_sym);
+ int hash = hashname (name);
+ struct symbol *sym, *prev;
prev = 0;
for (sym = opaque_type_chain[hash]; sym;)
{
- if (name[0] == SYMBOL_NAME (sym)[0] &&
- STREQ (name + 1, SYMBOL_NAME (sym) + 1))
+ if (name[0] == DEPRECATED_SYMBOL_NAME (sym)[0] &&
+ strcmp (name + 1, DEPRECATED_SYMBOL_NAME (sym) + 1) == 0)
{
if (prev)
{
@@ -1462,26 +1465,24 @@ patch_opaque_types (struct symtab *s)
}
static struct symbol *
-process_coff_symbol (register struct coff_symbol *cs,
- register union internal_auxent *aux,
+process_coff_symbol (struct coff_symbol *cs,
+ union internal_auxent *aux,
struct objfile *objfile)
{
- register struct symbol *sym
- = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ struct symbol *sym
+ = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
char *name;
memset (sym, 0, sizeof (struct symbol));
name = cs->c_name;
name = EXTERNAL_NAME (name, objfile->obfd);
- SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
- &objfile->symbol_obstack);
SYMBOL_LANGUAGE (sym) = language_auto;
- SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+ SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
/* default assumptions */
SYMBOL_VALUE (sym) = cs->c_value;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_SECTION (sym) = cs_to_section (cs, objfile);
if (ISFCN (cs->c_type))
@@ -1603,7 +1604,7 @@ process_coff_symbol (register struct coff_symbol *cs,
case C_TPDEF:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
/* If type has no name, give it one */
if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
@@ -1633,13 +1634,8 @@ process_coff_symbol (register struct coff_symbol *cs,
}
else
TYPE_NAME (SYMBOL_TYPE (sym)) =
- concat (SYMBOL_NAME (sym), NULL);
+ concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
}
-#ifdef CXUX_TARGET
- /* Ignore vendor section for Harris CX/UX targets. */
- else if (cs->c_name[0] == '$')
- break;
-#endif /* CXUX_TARGET */
/* Keep track of any type which points to empty structured type,
so it can be filled from a definition from another file. A
@@ -1651,7 +1647,7 @@ process_coff_symbol (register struct coff_symbol *cs,
TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
TYPE_CODE_UNDEF)
{
- register int i = hashname (SYMBOL_NAME (sym));
+ int i = hashname (DEPRECATED_SYMBOL_NAME (sym));
SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
opaque_type_chain[i] = sym;
@@ -1663,17 +1659,17 @@ process_coff_symbol (register struct coff_symbol *cs,
case C_UNTAG:
case C_ENTAG:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
- SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+ SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
/* Some compilers try to be helpful by inventing "fake"
names for anonymous enums, structures, and unions, like
"~0fake" or ".0fake". Thanks, but no thanks... */
if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
- if (SYMBOL_NAME (sym) != NULL
- && *SYMBOL_NAME (sym) != '~'
- && *SYMBOL_NAME (sym) != '.')
+ if (DEPRECATED_SYMBOL_NAME (sym) != NULL
+ && *DEPRECATED_SYMBOL_NAME (sym) != '~'
+ && *DEPRECATED_SYMBOL_NAME (sym) != '.')
TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
- concat (SYMBOL_NAME (sym), NULL);
+ concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
add_symbol_to_list (sym, &file_symbols);
break;
@@ -1688,10 +1684,10 @@ process_coff_symbol (register struct coff_symbol *cs,
/* Decode a coff type specifier; return the type that is meant. */
static struct type *
-decode_type (register struct coff_symbol *cs, unsigned int c_type,
- register union internal_auxent *aux)
+decode_type (struct coff_symbol *cs, unsigned int c_type,
+ union internal_auxent *aux)
{
- register struct type *type = 0;
+ struct type *type = 0;
unsigned int new_c_type;
if (c_type & ~N_BTMASK)
@@ -1710,7 +1706,7 @@ decode_type (register struct coff_symbol *cs, unsigned int c_type,
else if (ISARY (c_type))
{
int i, n;
- register unsigned short *dim;
+ unsigned short *dim;
struct type *base_type, *index_type, *range_type;
/* Define an array type. */
@@ -1755,7 +1751,9 @@ decode_type (register struct coff_symbol *cs, unsigned int c_type,
}
else
{
- complain (&tagndx_bad_complaint, cs->c_name);
+ complaint (&symfile_complaints,
+ "Symbol table entry for %s has bad tagndx value",
+ cs->c_name);
/* And fall through to decode_base_type... */
}
}
@@ -1767,8 +1765,8 @@ decode_type (register struct coff_symbol *cs, unsigned int c_type,
return the type that the function returns. */
static struct type *
-decode_function_type (register struct coff_symbol *cs, unsigned int c_type,
- register union internal_auxent *aux)
+decode_function_type (struct coff_symbol *cs, unsigned int c_type,
+ union internal_auxent *aux)
{
if (aux->x_sym.x_tagndx.l == 0)
cs->c_naux = 0; /* auxent refers to function, not base type */
@@ -1779,8 +1777,8 @@ decode_function_type (register struct coff_symbol *cs, unsigned int c_type,
/* basic C types */
static struct type *
-decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
- register union internal_auxent *aux)
+decode_base_type (struct coff_symbol *cs, unsigned int c_type,
+ union internal_auxent *aux)
{
struct type *type;
@@ -1790,15 +1788,6 @@ decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
/* shows up with "void (*foo)();" structure members */
return lookup_fundamental_type (current_objfile, FT_VOID);
-#if 0
-/* DGUX actually defines both T_ARG and T_VOID to the same value. */
-#ifdef T_ARG
- case T_ARG:
- /* Shows up in DGUX, I think. Not sure where. */
- return lookup_fundamental_type (current_objfile, FT_VOID); /* shouldn't show up here */
-#endif
-#endif /* 0 */
-
#ifdef T_VOID
case T_VOID:
/* Intel 960 COFF has this symbol and meaning. */
@@ -1921,7 +1910,7 @@ decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
else
return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
}
- complain (&unexpected_type_complaint, cs->c_name);
+ complaint (&symfile_complaints, "Unexpected type for symbol %s", cs->c_name);
return lookup_fundamental_type (current_objfile, FT_VOID);
}
@@ -1939,14 +1928,14 @@ coff_read_struct_type (int index, int length, int lastsym)
struct field field;
};
- register struct type *type;
- register struct nextfield *list = 0;
+ struct type *type;
+ struct nextfield *list = 0;
struct nextfield *new;
int nfields = 0;
- register int n;
+ int n;
char *name;
struct coff_symbol member_sym;
- register struct coff_symbol *ms = &member_sym;
+ struct coff_symbol *ms = &member_sym;
struct internal_syment sub_sym;
union internal_auxent sub_aux;
int done = 0;
@@ -1976,10 +1965,11 @@ coff_read_struct_type (int index, int length, int lastsym)
list->field.name =
obsavestring (name,
strlen (name),
- &current_objfile->symbol_obstack);
+ &current_objfile->objfile_obstack);
FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
FIELD_BITPOS (list->field) = 8 * ms->c_value;
FIELD_BITSIZE (list->field) = 0;
+ FIELD_STATIC_KIND (list->field) = 0;
nfields++;
break;
@@ -1994,10 +1984,11 @@ coff_read_struct_type (int index, int length, int lastsym)
list->field.name =
obsavestring (name,
strlen (name),
- &current_objfile->symbol_obstack);
+ &current_objfile->objfile_obstack);
FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
FIELD_BITPOS (list->field) = ms->c_value;
FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
+ FIELD_STATIC_KIND (list->field) = 0;
nfields++;
break;
@@ -2024,22 +2015,21 @@ coff_read_struct_type (int index, int length, int lastsym)
and create and return a suitable type object.
Also defines the symbols that represent the values of the type. */
-/* ARGSUSED */
static struct type *
coff_read_enum_type (int index, int length, int lastsym)
{
- register struct symbol *sym;
- register struct type *type;
+ struct symbol *sym;
+ struct type *type;
int nsyms = 0;
int done = 0;
struct pending **symlist;
struct coff_symbol member_sym;
- register struct coff_symbol *ms = &member_sym;
+ struct coff_symbol *ms = &member_sym;
struct internal_syment sub_sym;
union internal_auxent sub_aux;
struct pending *osyms, *syms;
int o_nsyms;
- register int n;
+ int n;
char *name;
int unsigned_enum = 1;
@@ -2061,15 +2051,15 @@ coff_read_enum_type (int index, int length, int lastsym)
{
case C_MOE:
sym = (struct symbol *) obstack_alloc
- (&current_objfile->symbol_obstack,
+ (&current_objfile->objfile_obstack,
sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
- SYMBOL_NAME (sym) =
+ DEPRECATED_SYMBOL_NAME (sym) =
obsavestring (name, strlen (name),
- &current_objfile->symbol_obstack);
+ &current_objfile->objfile_obstack);
SYMBOL_CLASS (sym) = LOC_CONST;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_VALUE (sym) = ms->c_value;
add_symbol_to_list (sym, symlist);
nsyms++;
@@ -2113,11 +2103,12 @@ coff_read_enum_type (int index, int length, int lastsym)
{
struct symbol *xsym = syms->symbol[j];
SYMBOL_TYPE (xsym) = type;
- TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+ TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
if (SYMBOL_VALUE (xsym) < 0)
unsigned_enum = 0;
TYPE_FIELD_BITSIZE (type, n) = 0;
+ TYPE_FIELD_STATIC_KIND (type, n) = 0;
}
if (syms == osyms)
break;
diff --git a/contrib/gdb/gdb/config/alpha/tm-alpha.h b/contrib/gdb/gdb/config/alpha/tm-alpha.h
index 58412d0..0b7878c 100644
--- a/contrib/gdb/gdb/config/alpha/tm-alpha.h
+++ b/contrib/gdb/gdb/config/alpha/tm-alpha.h
@@ -1,7 +1,7 @@
/* Definitions to make GDB run on an Alpha box under OSF1. This is
also used by the Alpha/Netware and Alpha GNU/Linux targets.
- Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002 Free
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2004 Free
Software Foundation, Inc.
This file is part of GDB.
@@ -24,353 +24,21 @@
#ifndef TM_ALPHA_H
#define TM_ALPHA_H
-#include "regcache.h"
#include "bfd.h"
#include "coff/sym.h" /* Needed for PDR below. */
#include "coff/symconst.h"
struct frame_info;
-struct type;
-struct value;
struct symbol;
-/* Redefine some target bit sizes from the default. */
-
-#define TARGET_LONG_BIT 64
-#define TARGET_LONG_LONG_BIT 64
-#define TARGET_PTR_BIT 64
-
-/* Number of traps that happen between exec'ing the shell
- * to run an inferior, and when we finally get to
- * the inferior code. This is 2 on most implementations.
- */
-#define START_INFERIOR_TRAPS_EXPECTED 3
-
-/* Offset from address of function to start of its code.
- Zero on most machines. */
-
-#define FUNCTION_START_OFFSET 0
-
-/* Advance PC across any function entry prologue instructions
- to reach some "real" code. */
-
-#define SKIP_PROLOGUE(pc) alpha_skip_prologue((pc))
-extern CORE_ADDR alpha_skip_prologue (CORE_ADDR addr);
-
-/* Immediately after a function call, return the saved pc.
- Can't always go through the frames for this because on some machines
- the new frame is not set up until the new function executes
- some instructions. */
-
-#define SAVED_PC_AFTER_CALL(frame) alpha_saved_pc_after_call(frame)
-extern CORE_ADDR alpha_saved_pc_after_call (struct frame_info *);
-
-/* Are we currently handling a signal ? */
-
-#define IN_SIGTRAMP(pc, name) alpha_osf_in_sigtramp ((pc), (name))
-extern int alpha_osf_in_sigtramp (CORE_ADDR, char *);
-
-/* Stack grows downward. */
-
-#define INNER_THAN(lhs,rhs) core_addr_lessthan ((lhs), (rhs))
-
-#define BREAKPOINT {0x80, 0, 0, 0} /* call_pal bpt */
-
-/* Amount PC must be decremented by after a breakpoint.
- This is often the number of bytes in BREAKPOINT
- but not always. */
-
-#ifndef DECR_PC_AFTER_BREAK
-#define DECR_PC_AFTER_BREAK 4
-#endif
-
-/* Say how long (ordinary) registers are. This is a piece of bogosity
- used in push_word and a few other places; REGISTER_RAW_SIZE is the
- real way to know how big a register is. */
-
-#define REGISTER_SIZE 8
-
-/* Number of machine registers */
-
-#define NUM_REGS 66
-
-
-/* Return the name of register REGNO. */
-
-#define REGISTER_NAME(regno) alpha_register_name ((regno))
-extern char *alpha_register_name (int);
-
-
-/* Register numbers of various important registers.
- Note that most of these values are "real" register numbers,
- and correspond to the general registers of the machine,
- and FP_REGNUM is a "phony" register number which is too large
- to be an actual register number as far as the user is concerned
- but serves to get the desired value when passed to read_register. */
-
-#define V0_REGNUM 0 /* Function integer return value */
-#define T7_REGNUM 8 /* Return address register for OSF/1 __add* */
-#define GCC_FP_REGNUM 15 /* Used by gcc as frame register */
-#define A0_REGNUM 16 /* Loc of first arg during a subr call */
-#define T9_REGNUM 23 /* Return address register for OSF/1 __div* */
-#define T12_REGNUM 27 /* Contains start addr of current proc */
-#define SP_REGNUM 30 /* Contains address of top of stack */
-#define RA_REGNUM 26 /* Contains return address value */
-#define ZERO_REGNUM 31 /* Read-only register, always 0 */
-#define FP0_REGNUM 32 /* Floating point register 0 */
-#define FPA0_REGNUM 48 /* First float arg during a subr call */
-#define FPCR_REGNUM 63 /* Floating point control register */
-#define PC_REGNUM 64 /* Contains program counter */
-#define FP_REGNUM 65 /* Virtual frame pointer */
-
-#define CANNOT_FETCH_REGISTER(regno) \
- alpha_cannot_fetch_register ((regno))
-extern int alpha_cannot_fetch_register (int);
-
-#define CANNOT_STORE_REGISTER(regno) \
- alpha_cannot_store_register ((regno))
-extern int alpha_cannot_store_register (int);
-
-/* Total amount of space needed to store our copies of the machine's
- register state, the array `registers'. */
-#define REGISTER_BYTES (NUM_REGS * 8)
-
-/* Index within `registers' of the first byte of the space for
- register N. */
-
-#define REGISTER_BYTE(N) alpha_register_byte ((N))
-extern int alpha_register_byte (int);
-
-/* Number of bytes of storage in the actual machine representation
- for register N. On Alphas, all regs are 8 bytes. */
-
-#define REGISTER_RAW_SIZE(N) alpha_register_raw_size ((N))
-extern int alpha_register_raw_size (int);
-
-/* Number of bytes of storage in the program's representation
- for register N. On Alphas, all regs are 8 bytes. */
-
-#define REGISTER_VIRTUAL_SIZE(N) alpha_register_virtual_size ((N))
-extern int alpha_register_virtual_size (int);
-
-/* Largest value REGISTER_RAW_SIZE can have. */
-
-#define MAX_REGISTER_RAW_SIZE 8
-
-/* Largest value REGISTER_VIRTUAL_SIZE can have. */
-
-#define MAX_REGISTER_VIRTUAL_SIZE 8
-
-/* Nonzero if register N requires conversion
- from raw format to virtual format.
- The alpha needs a conversion between register and memory format if
- the register is a floating point register and
- memory format is float, as the register format must be double
- or
- memory format is an integer with 4 bytes or less, as the representation
- of integers in floating point registers is different. */
-
-#define REGISTER_CONVERTIBLE(N) alpha_register_convertible ((N))
-extern int alpha_register_convertible (int);
-
-/* Convert data from raw format for register REGNUM in buffer FROM
- to virtual format with type TYPE in buffer TO. */
-
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM, TYPE, FROM, TO) \
- alpha_register_convert_to_virtual (REGNUM, TYPE, FROM, TO)
-extern void
-alpha_register_convert_to_virtual (int, struct type *, char *, char *);
-
-/* Convert data from virtual format with type TYPE in buffer FROM
- to raw format for register REGNUM in buffer TO. */
-
-#define REGISTER_CONVERT_TO_RAW(TYPE, REGNUM, FROM, TO) \
- alpha_register_convert_to_raw (TYPE, REGNUM, FROM, TO)
-extern void
-alpha_register_convert_to_raw (struct type *, int, char *, char *);
-
-/* Return the GDB type object for the "standard" data type
- of data in register N. */
-
-#define REGISTER_VIRTUAL_TYPE(N) alpha_register_virtual_type ((N))
-extern struct type * alpha_register_virtual_type (int);
-
-/* Store the address of the place in which to copy the structure the
- subroutine will return. Handled by alpha_push_arguments. */
-
-#define STORE_STRUCT_RETURN(addr, sp) \
- alpha_store_struct_return ((addr), (sp))
-extern void alpha_store_struct_return (CORE_ADDR, CORE_ADDR);
-/**/
-
-/* Extract from an array REGBUF containing the (raw) register state
- a function return value of type TYPE, and copy that, in virtual format,
- into VALBUF. */
-
-#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
- alpha_extract_return_value(TYPE, REGBUF, VALBUF)
-extern void alpha_extract_return_value (struct type *, char *, char *);
-
-/* Write into appropriate registers a function return value
- of type TYPE, given in virtual format. */
-
-#define STORE_RETURN_VALUE(TYPE,VALBUF) \
- alpha_store_return_value(TYPE, VALBUF)
-extern void alpha_store_return_value (struct type *, char *);
-
-/* Extract from an array REGBUF containing the (raw) register state
- the address in which a function should return its structure value,
- as a CORE_ADDR (or an expression that can be used as one). */
-/* The address is passed in a0 upon entry to the function, but when
- the function exits, the compiler has copied the value to v0. This
- convention is specified by the System V ABI, so I think we can rely
- on it. */
-
-#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
- alpha_extract_struct_value_address (REGBUF)
-extern CORE_ADDR alpha_extract_struct_value_address (char *);
-
-/* Structures are returned by ref in extra arg0 */
-#define USE_STRUCT_CONVENTION(gcc_p, type) \
- alpha_use_struct_convention ((gcc_p), (type))
-extern int alpha_use_struct_convention (int, struct type *);
-
-
-/* Describe the pointer in each stack frame to the previous stack frame
- (its caller). */
-
-/* FRAME_CHAIN takes a frame's nominal address
- and produces the frame's chain-pointer. */
-
-#define FRAME_CHAIN(thisframe) alpha_frame_chain (thisframe)
-extern CORE_ADDR alpha_frame_chain (struct frame_info *);
-
-/* Define other aspects of the stack frame. */
-
-
-/* An expression that tells us whether the function invocation represented
- by FI does not have a frame on the stack associated with it. */
-/* We handle this differently for alpha, and maybe we should not */
-
-#define FRAMELESS_FUNCTION_INVOCATION(FI) \
- generic_frameless_function_invocation_not ((FI))
-
-/* Saved Pc. */
-
-#define FRAME_SAVED_PC(FRAME) alpha_frame_saved_pc(FRAME)
-extern CORE_ADDR alpha_frame_saved_pc (struct frame_info *);
-
-/* The alpha has two different virtual pointers for arguments and locals.
-
- The virtual argument pointer is pointing to the bottom of the argument
- transfer area, which is located immediately below the virtual frame
- pointer. Its size is fixed for the native compiler, it is either zero
- (for the no arguments case) or large enough to hold all argument registers.
- gcc uses a variable sized argument transfer area. As it has
- to stay compatible with the native debugging tools it has to use the same
- virtual argument pointer and adjust the argument offsets accordingly.
-
- The virtual local pointer is localoff bytes below the virtual frame
- pointer, the value of localoff is obtained from the PDR. */
-
-#define ALPHA_NUM_ARG_REGS 6
-
-#define FRAME_ARGS_ADDRESS(fi) alpha_frame_args_address ((fi))
-extern CORE_ADDR alpha_frame_args_address (struct frame_info *);
-
-#define FRAME_LOCALS_ADDRESS(fi) alpha_frame_locals_address ((fi))
-extern CORE_ADDR alpha_frame_locals_address (struct frame_info *);
-
-/* Return number of args passed to a frame.
- Can return -1, meaning no way to tell. */
-
-#define FRAME_NUM_ARGS(fi) frame_num_args_unknown ((fi))
-
-/* Return number of bytes at start of arglist that are not really args. */
-
-#define FRAME_ARGS_SKIP 0
-
-/* Put here the code to store, into a struct frame_saved_regs,
- the addresses of the saved registers of frame described by FRAME_INFO.
- This includes special registers such as pc and fp saved in special
- ways in the stack frame. sp is even more special:
- the address we return for it IS the sp for the next frame. */
-
-#define FRAME_INIT_SAVED_REGS(frame_info) \
- alpha_frame_init_saved_regs (frame_info)
-extern void alpha_frame_init_saved_regs (struct frame_info *);
-
-
-/* Things needed for making the inferior call functions. */
-
-#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
- (alpha_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr)))
-extern CORE_ADDR
-alpha_push_arguments (int, struct value **, CORE_ADDR, int, CORE_ADDR);
-
-/* Push an empty stack frame, to record the current PC, etc. */
-
-#define PUSH_DUMMY_FRAME alpha_push_dummy_frame()
-extern void alpha_push_dummy_frame (void);
-
-/* Discard from the stack the innermost frame, restoring all registers. */
-
-#define POP_FRAME alpha_pop_frame()
-extern void alpha_pop_frame (void);
-
-/* Alpha OSF/1 inhibits execution of code on the stack.
- But there is no need for a dummy on the alpha. PUSH_ARGUMENTS
- takes care of all argument handling and bp_call_dummy takes care
- of stopping the dummy. */
-
-#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
-
-/* On the Alpha the call dummy code is never copied to user space,
- stopping the user call is achieved via a bp_call_dummy breakpoint.
- But we need a fake CALL_DUMMY definition to enable the proper
- call_function_by_hand and to avoid zero length array warnings
- in valops.c */
-
-#define CALL_DUMMY_P (1)
-
-#define CALL_DUMMY_WORDS alpha_call_dummy_words
-extern LONGEST alpha_call_dummy_words[];
-
-#define SIZEOF_CALL_DUMMY_WORDS 0
-
-#define CALL_DUMMY_START_OFFSET (0)
-
-#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
-
-#define CALL_DUMMY_ADDRESS() alpha_call_dummy_address()
-extern CORE_ADDR alpha_call_dummy_address (void);
-
-/* Insert the specified number of args and function address
- into a call sequence of the above form stored at DUMMYNAME.
- We only have to set RA_REGNUM to the dummy breakpoint address
- and T12_REGNUM (the `procedure value register') to the function address. */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
- alpha_fix_call_dummy ((dummyname), (pc), (fun), (nargs), (args), \
- (type), (gcc_p))
-extern void alpha_fix_call_dummy (char *, CORE_ADDR, CORE_ADDR, int,
- struct value **, struct type *, int);
-
-/* There's a mess in stack frame creation. See comments in blockframe.c
- near reference to INIT_FRAME_PC_FIRST. */
-
-#define INIT_FRAME_PC(fromleaf, prev) init_frame_pc_noop ((fromleaf), (prev))
-
-#define INIT_FRAME_PC_FIRST(fromleaf, prev) \
- alpha_init_frame_pc_first ((fromleaf), (prev))
-extern void alpha_init_frame_pc_first (int, struct frame_info *);
-
/* Special symbol found in blocks associated with routines. We can hang
alpha_extra_func_info_t's off of this. */
#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__"
extern void ecoff_relocate_efi (struct symbol *, CORE_ADDR);
+#define RA_REGNUM 26 /* XXXJRT needed by mdebugread.c */
+
/* Specific information about a procedure.
This overlays the ALPHA's PDR records,
alpharead.c (ab)uses this to save memory */
@@ -389,15 +57,6 @@ typedef struct alpha_extra_func_info
#define mips_extra_func_info alpha_extra_func_info
#define mips_extra_func_info_t alpha_extra_func_info_t
-
-#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) \
- alpha_init_extra_frame_info(fromleaf, fci)
-extern void alpha_init_extra_frame_info (int, struct frame_info *);
-
-#define PRINT_EXTRA_FRAME_INFO(fi) alpha_print_extra_frame_info ((fi))
-extern void alpha_print_extra_frame_info (struct frame_info *);
-
-
/* It takes two values to specify a frame on the ALPHA. Sigh.
In fact, at the moment, the *PC* is the primary value that sets up
@@ -408,64 +67,8 @@ extern void alpha_print_extra_frame_info (struct frame_info *);
up so that the primary value is the SP, and the PC is used to disambiguate
multiple functions with the same SP that are at different stack levels. */
-#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv)
-extern struct frame_info *setup_arbitrary_frame (int, CORE_ADDR *);
-
-/* This is used by heuristic_proc_start. It should be shot it the head. */
-#ifndef VM_MIN_ADDRESS
-#define VM_MIN_ADDRESS (CORE_ADDR)0x120000000
-#endif
-
-/* If PC is in a shared library trampoline code, return the PC
- where the function itself actually starts. If not, return 0. */
-#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc)
-
-/* If the current gcc for for this target does not produce correct debugging
- information for float parameters, both prototyped and unprototyped, then
- define this macro. This forces gdb to always assume that floats are
- passed as doubles and then converted in the callee.
-
- For the alpha, it appears that the debug info marks the parameters as
- floats regardless of whether the function is prototyped, but the actual
- values are always passed in as doubles. Thus by setting this to 1, both
- types of calls will work. */
-
-#define COERCE_FLOAT_TO_DOUBLE(formal, actual) \
- standard_coerce_float_to_double ((formal), (actual))
-
-/* Return TRUE if procedure descriptor PROC is a procedure descriptor
- that refers to a dynamically generated sigtramp function.
-
- OSF/1 doesn't use dynamic sigtramp functions, so this is always
- FALSE. */
-
-#define PROC_DESC_IS_DYN_SIGTRAMP(proc) (0)
-#define SET_PROC_DESC_IS_DYN_SIGTRAMP(proc)
-
-/* If PC is inside a dynamically generated sigtramp function, return
- how many bytes the program counter is beyond the start of that
- function. Otherwise, return a negative value.
-
- OSF/1 doesn't use dynamic sigtramp functions, so this always
- returns -1. */
-
-#define DYNAMIC_SIGTRAMP_OFFSET(pc) (-1)
-
-/* Translate a signal handler frame into the address of the sigcontext
- structure. */
-
-#define SIGCONTEXT_ADDR(frame) \
- (read_memory_integer ((frame)->next ? frame->next->frame : frame->frame, 8))
-
-/* If FRAME refers to a sigtramp frame, return the address of the next
- frame. */
-
-#define FRAME_PAST_SIGTRAMP_FRAME(frame, pc) \
- (alpha_osf_skip_sigtramp_frame (frame, pc))
-extern CORE_ADDR alpha_osf_skip_sigtramp_frame (struct frame_info *,
- CORE_ADDR);
-
-/* Single step based on where the current instruction will take us. */
-extern void alpha_software_single_step (enum target_signal, int);
+#define SETUP_ARBITRARY_FRAME(argc, argv) \
+ alpha_setup_arbitrary_frame (argc, argv)
+extern struct frame_info *alpha_setup_arbitrary_frame (int, CORE_ADDR *);
#endif /* TM_ALPHA_H */
diff --git a/contrib/gdb/gdb/config/i386/tm-fbsd.h b/contrib/gdb/gdb/config/i386/tm-fbsd.h
index 5c819ce..98a2702 100644
--- a/contrib/gdb/gdb/config/i386/tm-fbsd.h
+++ b/contrib/gdb/gdb/config/i386/tm-fbsd.h
@@ -1,5 +1,6 @@
/* Target-dependent definitions for FreeBSD/i386.
- Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ Copyright 1997, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
This file is part of GDB.
@@ -21,73 +22,10 @@
#ifndef TM_FBSD_H
#define TM_FBSD_H
-#define HAVE_I387_REGS
-#include "i386/tm-i386.h"
+#include "solib.h"
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
-/* FreeBSD/ELF uses stabs-in-ELF with the DWARF register numbering
- scheme by default, so we must redefine STAB_REG_TO_REGNUM. This
- messes up the floating-point registers for a.out, but there is not
- much we can do about that. */
-
-#undef STAB_REG_TO_REGNUM
-#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
-
-/* FreeBSD uses the old gcc convention for struct returns. */
-
-#define USE_STRUCT_CONVENTION(gcc_p, type) \
- generic_use_struct_convention (1, type)
-
-
-/* Support for longjmp. */
-
-/* Details about jmp_buf. It's supposed to be an array of integers. */
-
-#define JB_ELEMENT_SIZE 4 /* Size of elements in jmp_buf. */
-#define JB_PC 0 /* Array index of saved PC. */
-
-/* Figure out where the longjmp will land. Store the address that
- longjmp will jump to in *ADDR, and return non-zero if successful. */
-
-#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr)
-extern int get_longjmp_target (CORE_ADDR *addr);
-
-
-/* Support for signal handlers. */
-
-#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name)
-extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name);
-
-/* These defines allow the recognition of sigtramps as a function name
- <sigtramp>.
-
- FIXME: kettenis/2001-07-13: These should be added to the target
- vector and turned into functions when we go "multi-arch". */
-
-#define SIGTRAMP_START(pc) i386bsd_sigtramp_start
-#define SIGTRAMP_END(pc) i386bsd_sigtramp_end
-extern CORE_ADDR i386bsd_sigtramp_start;
-extern CORE_ADDR i386bsd_sigtramp_end;
-
-/* Override FRAME_SAVED_PC to enable the recognition of signal handlers. */
-
-#undef FRAME_SAVED_PC
-#define FRAME_SAVED_PC(frame) i386bsd_frame_saved_pc (frame)
-extern CORE_ADDR i386bsd_frame_saved_pc (struct frame_info *frame);
-
-
-/* Shared library support. */
-
-#ifndef SVR4_SHARED_LIBS
-
-/* Return non-zero if we are in a shared library trampoline code stub. */
-
-#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
- (name && !strcmp(name, "_DYNAMIC"))
-
-#endif /* !SVR4_SHARED_LIBS */
-
-#endif /* TM_FBSD_H */
+#endif /* tm-fbsd.h */
diff --git a/contrib/gdb/gdb/core-regset.c b/contrib/gdb/gdb/core-regset.c
index 16cfde5..0600837 100644
--- a/contrib/gdb/gdb/core-regset.c
+++ b/contrib/gdb/gdb/core-regset.c
@@ -1,5 +1,6 @@
/* Machine independent GDB support for core files on systems using "regsets".
- Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000
+
+ Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2003
Free Software Foundation, Inc.
This file is part of GDB.
@@ -19,66 +20,43 @@
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-
-/* N O T E S
-
- This file is used by most systems that implement /proc. For these systems,
- the general registers are laid out the same way in both the core file and
- the gregset_p structure. The current exception to this is Irix-4.*, where
- the gregset_p structure is split up into two pieces in the core file.
-
- The general register and floating point register sets are manipulated by
- separate ioctl's. This file makes the assumption that if FP0_REGNUM is
- defined, then support for the floating point register set is desired,
- regardless of whether or not the actual target has floating point hardware.
-
- */
+/* This file is used by most systems that use ELF for their core
+ dumps. This includes most systems that have SVR4-ish variant of
+ /proc. For these systems, the registers are laid out the same way
+ in core files as in the gregset_t and fpregset_t structures that
+ are used in the interaction with /proc (Irix 4 is an exception and
+ therefore doesn't use this file). Quite a few systems without a
+ SVR4-ish /proc define these structures too, and can make use of
+ this code too. */
#include "defs.h"
+#include "command.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "target.h"
+#include <fcntl.h>
+#include <errno.h>
+#include "gdb_string.h"
#include <time.h>
#ifdef HAVE_SYS_PROCFS_H
#include <sys/procfs.h>
#endif
-#include <fcntl.h>
-#include <errno.h>
-#include "gdb_string.h"
-#include "inferior.h"
-#include "target.h"
-#include "command.h"
-#include "gdbcore.h"
-
-/* Prototypes for supply_gregset etc. */
+/* Prototypes for supply_gregset etc. */
#include "gregset.h"
-static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
-
-void _initialize_core_regset (void);
-
-/*
-
- GLOBAL FUNCTION
+/* Provide registers to GDB from a core file.
- fetch_core_registers -- fetch current registers from core file
+ CORE_REG_SECT points to an array of bytes, which are the contents
+ of a `note' from a core file which BFD thinks might contain
+ register contents. CORE_REG_SIZE is its size.
- SYNOPSIS
+ WHICH says which register set corelow suspects this is:
+ 0 --- the general-purpose register set, in gregset_t format
+ 2 --- the floating-point register set, in fpregset_t format
- void fetch_core_registers (char *core_reg_sect,
- unsigned core_reg_size,
- int which, CORE_ADDR reg_addr)
-
- DESCRIPTION
-
- Read the values of either the general register set (WHICH equals 0)
- or the floating point register set (WHICH equals 2) from the core
- file data (pointed to by CORE_REG_SECT), and update gdb's idea of
- their current values. The CORE_REG_SIZE parameter is compared to
- the size of the gregset or fpgregset structures (as appropriate) to
- validate the size of the structure from the core file. The
- REG_ADDR parameter is ignored.
-
- */
+ REG_ADDR is ignored. */
static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
@@ -87,36 +65,40 @@ fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
gdb_gregset_t gregset;
gdb_fpregset_t fpregset;
- if (which == 0)
+ switch (which)
{
+ case 0:
if (core_reg_size != sizeof (gregset))
- {
- warning ("wrong size gregset struct in core file");
- }
+ warning ("Wrong size gregset in core file.");
else
{
- memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
+ memcpy (&gregset, core_reg_sect, sizeof (gregset));
supply_gregset (&gregset);
}
- }
- else if (which == 2)
- {
+ break;
+
+ case 2:
if (core_reg_size != sizeof (fpregset))
- {
- warning ("wrong size fpregset struct in core file");
- }
+ warning ("Wrong size fpregset in core file.");
else
{
- memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
+ memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
if (FP0_REGNUM >= 0)
supply_fpregset (&fpregset);
}
+ break;
+
+ default:
+ /* We've covered all the kinds of registers we know about here,
+ so this must be something we wouldn't know what to do with
+ anyway. Just ignore it. */
+ break;
}
}
-/* Register that we are able to handle ELF file formats using standard
- procfs "regset" structures. */
+/* Register that we are able to handle ELF core file formats using
+ standard procfs "regset" structures. */
static struct core_fns regset_core_fns =
{
@@ -127,6 +109,9 @@ static struct core_fns regset_core_fns =
NULL /* next */
};
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern void _initialize_core_regset (void);
+
void
_initialize_core_regset (void)
{
diff --git a/contrib/gdb/gdb/dbxread.c b/contrib/gdb/gdb/dbxread.c
index 16d0043..efbbf2a 100644
--- a/contrib/gdb/gdb/dbxread.c
+++ b/contrib/gdb/gdb/dbxread.c
@@ -1,6 +1,6 @@
/* Read dbx symbol tables and convert to internal format, for GDB.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004.
Free Software Foundation, Inc.
This file is part of GDB.
@@ -42,14 +42,13 @@
#include <fcntl.h>
#endif
-#include "obstack.h"
+#include "gdb_obstack.h"
#include "gdb_stat.h"
#include "symtab.h"
#include "breakpoint.h"
#include "target.h"
#include "gdbcore.h" /* for bfd stuff */
#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */
-#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "stabsread.h"
@@ -58,32 +57,17 @@
#include "language.h" /* Needed for local_hex_string */
#include "complaints.h"
#include "cp-abi.h"
+#include "gdb_assert.h"
#include "aout/aout64.h"
#include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */
-/* This macro returns the size field of a minimal symbol, which is normally
- stored in the "info" field. The macro can be overridden for specific
- targets (e.g. MIPS16) that use the info field for other purposes. */
-#ifndef MSYMBOL_SIZE
-#define MSYMBOL_SIZE(msym) ((long) MSYMBOL_INFO (msym))
-#endif
-
-
/* We put a pointer to this structure in the read_symtab_private field
of the psymtab. */
struct symloc
{
- /* The start (inclusive) and end (exclusive) addresses for this
- partial symtab's text. STABS doesn't reliably give us nice
- start and end addresses for each function. Instead, we are
- told the addresses of various boundary points, and we have to
- gather those together to build ranges. These are our running
- best guess as to the range of text addresses for this psymtab. */
- CORE_ADDR textlow, texthigh;
-
/* Offset within the file symbol table of first local symbol for this
file. */
@@ -112,8 +96,6 @@ struct symloc
#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
-#define TEXTLOW(p) (SYMLOC(p)->textlow)
-#define TEXTHIGH(p) (SYMLOC(p)->texthigh)
#define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size)
#define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset)
#define STRING_OFFSET(p) (SYMLOC(p)->string_offset)
@@ -177,33 +159,27 @@ static int has_line_numbers;
/* Complaints about the symbols we have encountered. */
-struct complaint lbrac_complaint =
-{"bad block start address patched", 0, 0};
-
-struct complaint string_table_offset_complaint =
-{"bad string table offset in symbol %d", 0, 0};
-
-struct complaint unknown_symtype_complaint =
-{"unknown symbol type %s", 0, 0};
-
-struct complaint unknown_symchar_complaint =
-{"unknown symbol descriptor `%c'", 0, 0};
-
-struct complaint lbrac_rbrac_complaint =
-{"block start larger than block end", 0, 0};
-
-struct complaint lbrac_unmatched_complaint =
-{"unmatched N_LBRAC before symtab pos %d", 0, 0};
+static void
+unknown_symtype_complaint (const char *arg1)
+{
+ complaint (&symfile_complaints, "unknown symbol type %s", arg1);
+}
-struct complaint lbrac_mismatch_complaint =
-{"N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", 0, 0};
+static void
+lbrac_mismatch_complaint (int arg1)
+{
+ complaint (&symfile_complaints,
+ "N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", arg1);
+}
-struct complaint repeated_header_complaint =
-{"\"repeated\" header file %s not previously seen, at symtab pos %d", 0, 0};
+static void
+repeated_header_complaint (const char *arg1, int arg2)
+{
+ complaint (&symfile_complaints,
+ "\"repeated\" header file %s not previously seen, at symtab pos %d",
+ arg1, arg2);
+}
-struct complaint unclaimed_bincl_complaint =
-{"N_BINCL %s not in entries for any file, at symtab pos %d", 0, 0};
-
/* find_text_range --- find start and end of loadable code sections
The find_text_range function finds the shortest address range that
@@ -273,8 +249,6 @@ static int bincls_allocated;
extern void _initialize_dbxread (void);
-static void process_now (struct objfile *);
-
static void read_ofile_symtab (struct partial_symtab *);
static void dbx_psymtab_to_symtab (struct partial_symtab *);
@@ -365,16 +339,16 @@ add_this_object_header_file (int i)
static void
add_old_header_file (char *name, int instance)
{
- register struct header_file *p = HEADER_FILES (current_objfile);
- register int i;
+ struct header_file *p = HEADER_FILES (current_objfile);
+ int i;
for (i = 0; i < N_HEADER_FILES (current_objfile); i++)
- if (STREQ (p[i].name, name) && instance == p[i].instance)
+ if (strcmp (p[i].name, name) == 0 && instance == p[i].instance)
{
add_this_object_header_file (i);
return;
}
- complain (&repeated_header_complaint, name, symnum);
+ repeated_header_complaint (name, symnum);
}
/* Add to this file a "new" header file: definitions for its types follow.
@@ -391,8 +365,8 @@ add_old_header_file (char *name, int instance)
static void
add_new_header_file (char *name, int instance)
{
- register int i;
- register struct header_file *hfile;
+ int i;
+ struct header_file *hfile;
/* Make sure there is room for one more header file. */
@@ -434,7 +408,7 @@ add_new_header_file (char *name, int instance)
static struct type **
explicit_lookup_type (int real_filenum, int index)
{
- register struct header_file *f = &HEADER_FILES (current_objfile)[real_filenum];
+ struct header_file *f = &HEADER_FILES (current_objfile)[real_filenum];
if (index >= f->length)
{
@@ -508,7 +482,7 @@ record_minimal_symbol (char *name, CORE_ADDR address, int type,
Record it as global even if it's local, not global, so
lookup_minimal_symbol can find it. We don't check symbol_leading_char
because for SunOS4 it always is '_'. */
- if (name[8] == 'C' && STREQ ("__DYNAMIC", name))
+ if (name[8] == 'C' && DEPRECATED_STREQ ("__DYNAMIC", name))
ms_type = mst_data;
/* Same with virtual function tables, both global and static. */
@@ -604,19 +578,6 @@ dbx_symfile_read (struct objfile *objfile, int mainline)
read_dbx_dynamic_symtab (objfile);
- /* Take the text ranges the STABS partial symbol scanner computed
- for each of the psymtabs and convert it into the canonical form
- for psymtabs. */
- {
- struct partial_symtab *p;
-
- ALL_OBJFILE_PSYMTABS (objfile, p)
- {
- p->textlow = TEXTLOW (p);
- p->texthigh = TEXTHIGH (p);
- }
- }
-
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
@@ -665,7 +626,7 @@ dbx_symfile_init (struct objfile *objfile)
/* Allocate struct to keep track of the symfile */
objfile->sym_stab_info = (struct dbx_symfile_info *)
xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
- memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
+ memset (objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
DBX_TEXT_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".text");
DBX_DATA_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".data");
@@ -689,14 +650,13 @@ dbx_symfile_init (struct objfile *objfile)
DBX_SYMCOUNT (objfile) = bfd_get_symcount (sym_bfd);
DBX_SYMTAB_OFFSET (objfile) = SYMBOL_TABLE_OFFSET;
- /* Read the string table and stash it away in the psymbol_obstack. It is
- only needed as long as we need to expand psymbols into full symbols,
- so when we blow away the psymbol the string table goes away as well.
+ /* Read the string table and stash it away in the objfile_obstack.
+ When we blow away the objfile the string table goes away as well.
Note that gdb used to use the results of attempting to malloc the
string table, based on the size it read, as a form of sanity check
for botched byte swapping, on the theory that a byte swapped string
table size would be so totally bogus that the malloc would fail. Now
- that we put in on the psymbol_obstack, we can't do this since gdb gets
+ that we put in on the objfile_obstack, we can't do this since gdb gets
a fatal error (out of virtual memory) if the size is bogus. We can
however at least check to see if the size is less than the size of
the size field itself, or larger than the size of the entire file.
@@ -717,8 +677,8 @@ dbx_symfile_init (struct objfile *objfile)
if (val < 0)
perror_with_name (name);
- memset ((PTR) size_temp, 0, sizeof (size_temp));
- val = bfd_bread ((PTR) size_temp, sizeof (size_temp), sym_bfd);
+ memset (size_temp, 0, sizeof (size_temp));
+ val = bfd_bread (size_temp, sizeof (size_temp), sym_bfd);
if (val < 0)
{
perror_with_name (name);
@@ -748,7 +708,7 @@ dbx_symfile_init (struct objfile *objfile)
DBX_STRINGTAB_SIZE (objfile));
DBX_STRINGTAB (objfile) =
- (char *) obstack_alloc (&objfile->psymbol_obstack,
+ (char *) obstack_alloc (&objfile->objfile_obstack,
DBX_STRINGTAB_SIZE (objfile));
OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile));
@@ -778,8 +738,8 @@ dbx_symfile_finish (struct objfile *objfile)
{
if (HEADER_FILES (objfile) != NULL)
{
- register int i = N_HEADER_FILES (objfile);
- register struct header_file *hfiles = HEADER_FILES (objfile);
+ int i = N_HEADER_FILES (objfile);
+ struct header_file *hfiles = HEADER_FILES (objfile);
while (--i >= 0)
{
@@ -799,106 +759,6 @@ static struct external_nlist symbuf[4096];
static int symbuf_idx;
static int symbuf_end;
-/* cont_elem is used for continuing information in cfront.
- It saves information about which types need to be fixed up and
- completed after all the stabs are read. */
-struct cont_elem
- {
- /* sym and stabstring for continuing information in cfront */
- struct symbol *sym;
- char *stabs;
- /* state dependencies (statics that must be preserved) */
- int sym_idx;
- int sym_end;
- int symnum;
- int (*func) (struct objfile *, struct symbol *, char *);
- /* other state dependencies include:
- (assumption is that these will not change since process_now FIXME!!)
- stringtab_global
- n_stabs
- objfile
- symfile_bfd */
- };
-
-static struct cont_elem *cont_list = 0;
-static int cont_limit = 0;
-static int cont_count = 0;
-
-/* Arrange for function F to be called with arguments SYM and P later
- in the stabs reading process. */
-void
-process_later (struct symbol *sym, char *p,
- int (*f) (struct objfile *, struct symbol *, char *))
-{
-
- /* Allocate more space for the deferred list. */
- if (cont_count >= cont_limit - 1)
- {
- cont_limit += 32; /* chunk size */
-
- cont_list
- = (struct cont_elem *) xrealloc (cont_list,
- (cont_limit
- * sizeof (struct cont_elem)));
- if (!cont_list)
- error ("Virtual memory exhausted\n");
- }
-
- /* Save state variables so we can process these stabs later. */
- cont_list[cont_count].sym_idx = symbuf_idx;
- cont_list[cont_count].sym_end = symbuf_end;
- cont_list[cont_count].symnum = symnum;
- cont_list[cont_count].sym = sym;
- cont_list[cont_count].stabs = p;
- cont_list[cont_count].func = f;
- cont_count++;
-}
-
-/* Call deferred funtions in CONT_LIST. */
-
-static void
-process_now (struct objfile *objfile)
-{
- int i;
- int save_symbuf_idx;
- int save_symbuf_end;
- int save_symnum;
- struct symbol *sym;
- char *stabs;
- int err;
- int (*func) (struct objfile *, struct symbol *, char *);
-
- /* Save the state of our caller, we'll want to restore it before
- returning. */
- save_symbuf_idx = symbuf_idx;
- save_symbuf_end = symbuf_end;
- save_symnum = symnum;
-
- /* Iterate over all the deferred stabs. */
- for (i = 0; i < cont_count; i++)
- {
- /* Restore the state for this deferred stab. */
- symbuf_idx = cont_list[i].sym_idx;
- symbuf_end = cont_list[i].sym_end;
- symnum = cont_list[i].symnum;
- sym = cont_list[i].sym;
- stabs = cont_list[i].stabs;
- func = cont_list[i].func;
-
- /* Call the function to handle this deferrd stab. */
- err = (*func) (objfile, sym, stabs);
- if (err)
- error ("Internal error: unable to resolve stab.\n");
- }
-
- /* Restore our caller's state. */
- symbuf_idx = save_symbuf_idx;
- symbuf_end = save_symbuf_end;
- symnum = save_symnum;
- cont_count = 0;
-}
-
-
/* Name of last function encountered. Used in Solaris to approximate
object file boundaries. */
static char *last_function_name;
@@ -919,6 +779,10 @@ static struct stab_section_list *symbuf_sections;
static unsigned int symbuf_left;
static unsigned int symbuf_read;
+/* This variable stores a global stabs buffer, if we read stabs into
+ memory in one chunk in order to process relocations. */
+static bfd_byte *stabs_data;
+
/* Refill the symbol table input buffer
and set the variables that control fetching entries from it.
Reports an error if no data available.
@@ -931,8 +795,18 @@ fill_symbuf (bfd *sym_bfd)
unsigned int count;
int nbytes;
- if (symbuf_sections == NULL)
- count = sizeof (symbuf);
+ if (stabs_data)
+ {
+ nbytes = sizeof (symbuf);
+ if (nbytes > symbuf_left)
+ nbytes = symbuf_left;
+ memcpy (symbuf, stabs_data + symbuf_read, nbytes);
+ }
+ else if (symbuf_sections == NULL)
+ {
+ count = sizeof (symbuf);
+ nbytes = bfd_bread (symbuf, count, sym_bfd);
+ }
else
{
if (symbuf_left <= 0)
@@ -948,9 +822,9 @@ fill_symbuf (bfd *sym_bfd)
count = symbuf_left;
if (count > sizeof (symbuf))
count = sizeof (symbuf);
+ nbytes = bfd_bread (symbuf, count, sym_bfd);
}
- nbytes = bfd_bread ((PTR) symbuf, count, sym_bfd);
if (nbytes < 0)
perror_with_name (bfd_get_filename (sym_bfd));
else if (nbytes == 0)
@@ -961,6 +835,18 @@ fill_symbuf (bfd *sym_bfd)
symbuf_read += nbytes;
}
+static void
+stabs_seek (int sym_offset)
+{
+ if (stabs_data)
+ {
+ symbuf_read += sym_offset;
+ symbuf_left -= sym_offset;
+ }
+ else
+ bfd_seek (symfile_bfd, sym_offset, SEEK_CUR);
+}
+
#define INTERNALIZE_SYMBOL(intern, extern, abfd) \
{ \
(intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type); \
@@ -1039,10 +925,10 @@ find_corresponding_bincl_psymtab (char *name, int instance)
for (bincl = bincl_list; bincl < next_bincl; bincl++)
if (bincl->instance == instance
- && STREQ (name, bincl->name))
+ && strcmp (name, bincl->name) == 0)
return bincl->pst;
- complain (&repeated_header_complaint, name, symnum);
+ repeated_header_complaint (name, symnum);
return (struct partial_symtab *) 0;
}
@@ -1051,7 +937,7 @@ find_corresponding_bincl_psymtab (char *name, int instance)
static void
free_bincl_list (struct objfile *objfile)
{
- xmfree (objfile->md, (PTR) bincl_list);
+ xmfree (objfile->md, bincl_list);
bincls_allocated = 0;
}
@@ -1079,7 +965,8 @@ set_namestring (struct objfile *objfile, struct internal_nlist nlist)
if (((unsigned) nlist.n_strx + file_string_table_offset) >=
DBX_STRINGTAB_SIZE (objfile))
{
- complain (&string_table_offset_complaint, symnum);
+ complaint (&symfile_complaints, "bad string table offset in symbol %d",
+ symnum);
namestring = "<bad string table offset>";
}
else
@@ -1230,18 +1117,72 @@ read_dbx_dynamic_symtab (struct objfile *objfile)
do_cleanups (back_to);
}
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+static CORE_ADDR
+find_stab_function_addr (char *namestring, char *filename,
+ struct objfile *objfile)
+{
+ struct minimal_symbol *msym;
+ char *p;
+ int n;
+
+ p = strchr (namestring, ':');
+ if (p == NULL)
+ p = namestring;
+ n = p - namestring;
+ p = alloca (n + 2);
+ strncpy (p, namestring, n);
+ p[n] = 0;
+
+ msym = lookup_minimal_symbol (p, filename, objfile);
+ if (msym == NULL)
+ {
+ /* Sun Fortran appends an underscore to the minimal symbol name,
+ try again with an appended underscore if the minimal symbol
+ was not found. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ msym = lookup_minimal_symbol (p, filename, objfile);
+ }
+
+ if (msym == NULL && filename != NULL)
+ {
+ /* Try again without the filename. */
+ p[n] = 0;
+ msym = lookup_minimal_symbol (p, NULL, objfile);
+ }
+ if (msym == NULL && filename != NULL)
+ {
+ /* And try again for Sun Fortran, but without the filename. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ msym = lookup_minimal_symbol (p, NULL, objfile);
+ }
+
+ return msym == NULL ? 0 : SYMBOL_VALUE_ADDRESS (msym);
+}
+#endif /* SOFUN_ADDRESS_MAYBE_MISSING */
+
+static void
+function_outside_compilation_unit_complaint (const char *arg1)
+{
+ complaint (&symfile_complaints,
+ "function `%s' appears to be defined outside of all compilation units",
+ arg1);
+}
+
/* Setup partial_symtab's describing each source file for which
debugging information is available. */
static void
read_dbx_symtab (struct objfile *objfile)
{
- register struct external_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch */
+ struct external_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch */
struct internal_nlist nlist;
CORE_ADDR text_addr;
int text_size;
- register char *namestring;
+ char *namestring;
int nsl;
int past_first_source_file = 0;
CORE_ADDR last_o_file_start = 0;
@@ -1249,6 +1190,7 @@ read_dbx_symtab (struct objfile *objfile)
struct cleanup *back_to;
bfd *abfd;
int textlow_not_set;
+ int data_sect_index;
/* Current partial symtab */
struct partial_symtab *pst;
@@ -1300,6 +1242,38 @@ read_dbx_symtab (struct objfile *objfile)
textlow_not_set = 1;
has_line_numbers = 0;
+ /* FIXME: jimb/2003-09-12: We don't apply the right section's offset
+ to global and static variables. The stab for a global or static
+ variable doesn't give us any indication of which section it's in,
+ so we can't tell immediately which offset in
+ objfile->section_offsets we should apply to the variable's
+ address.
+
+ We could certainly find out which section contains the variable
+ by looking up the variable's unrelocated address with
+ find_pc_section, but that would be expensive; this is the
+ function that constructs the partial symbol tables by examining
+ every symbol in the entire executable, and it's
+ performance-critical. So that expense would not be welcome. I'm
+ not sure what to do about this at the moment.
+
+ What we have done for years is to simply assume that the .data
+ section's offset is appropriate for all global and static
+ variables. Recently, this was expanded to fall back to the .bss
+ section's offset if there is no .data section, and then to the
+ .rodata section's offset. */
+ data_sect_index = objfile->sect_index_data;
+ if (data_sect_index == -1)
+ data_sect_index = SECT_OFF_BSS (objfile);
+ if (data_sect_index == -1)
+ data_sect_index = SECT_OFF_RODATA (objfile);
+
+ /* If data_sect_index is still -1, that's okay. It's perfectly fine
+ for the file to have no .data, no .bss, and no .text at all, if
+ it also has no global or static variables. If it does, we will
+ get an internal error from an ANOFFSET macro below when we try to
+ use data_sect_index. */
+
for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
{
/* Get the symbol for this run and pull out some info */
@@ -1334,9 +1308,6 @@ read_dbx_symtab (struct objfile *objfile)
switch (nlist.n_type)
{
- static struct complaint function_outside_compilation_unit = {
- "function `%s' appears to be defined outside of all compilation units", 0, 0
- };
char *p;
/*
* Standard, external, non-debugger, symbols
@@ -1390,18 +1361,18 @@ read_dbx_symtab (struct objfile *objfile)
if (objfile->ei.entry_point < nlist.n_value &&
objfile->ei.entry_point >= last_o_file_start)
{
- objfile->ei.entry_file_lowpc = last_o_file_start;
- objfile->ei.entry_file_highpc = nlist.n_value;
+ objfile->ei.deprecated_entry_file_lowpc = last_o_file_start;
+ objfile->ei.deprecated_entry_file_highpc = nlist.n_value;
}
if (past_first_source_file && pst
/* The gould NP1 uses low values for .o and -l symbols
which are not the address. */
- && nlist.n_value >= TEXTLOW (pst))
+ && nlist.n_value >= pst->textlow)
{
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
- nlist.n_value > TEXTHIGH (pst)
- ? nlist.n_value : TEXTHIGH (pst),
+ nlist.n_value > pst->texthigh
+ ? nlist.n_value : pst->texthigh,
dependency_list, dependencies_used, textlow_not_set);
pst = (struct partial_symtab *) 0;
includes_used = 0;
@@ -1523,7 +1494,7 @@ read_dbx_symtab (struct objfile *objfile)
{
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
- valu > TEXTHIGH (pst) ? valu : TEXTHIGH (pst),
+ valu > pst->texthigh ? valu : pst->texthigh,
dependency_list, dependencies_used,
prev_textlow_not_set);
pst = (struct partial_symtab *) 0;
@@ -1587,7 +1558,9 @@ read_dbx_symtab (struct objfile *objfile)
{
/* FIXME: we should not get here without a PST to work on.
Attempt to recover. */
- complain (&unclaimed_bincl_complaint, namestring, symnum);
+ complaint (&symfile_complaints,
+ "N_BINCL %s not in entries for any file, at symtab pos %d",
+ namestring, symnum);
continue;
}
add_bincl_to_list (pst, namestring, nlist.n_value);
@@ -1624,12 +1597,12 @@ read_dbx_symtab (struct objfile *objfile)
things like "break c-exp.y:435" need to work (I
suppose the psymtab_include_list could be hashed or put
in a binary tree, if profiling shows this is a major hog). */
- if (pst && STREQ (namestring, pst->filename))
+ if (pst && strcmp (namestring, pst->filename) == 0)
continue;
{
- register int i;
+ int i;
for (i = 0; i < includes_used; i++)
- if (STREQ (namestring, psymtab_include_list[i]))
+ if (strcmp (namestring, psymtab_include_list[i]) == 0)
{
i = -1;
break;
@@ -1648,7 +1621,7 @@ read_dbx_symtab (struct objfile *objfile)
psymtab_include_list = (char **)
alloca ((includes_allocated *= 2) *
sizeof (char *));
- memcpy ((PTR) psymtab_include_list, (PTR) orig,
+ memcpy (psymtab_include_list, orig,
includes_used * sizeof (char *));
}
continue;
@@ -1682,8 +1655,8 @@ read_dbx_symtab (struct objfile *objfile)
function relative stabs, or the address of the function's
end for old style stabs. */
valu = nlist.n_value + last_function_start;
- if (TEXTHIGH (pst) == 0 || valu > TEXTHIGH (pst))
- TEXTHIGH (pst) = valu;
+ if (pst->texthigh == 0 || valu > pst->texthigh)
+ pst->texthigh = valu;
break;
}
@@ -1703,22 +1676,22 @@ read_dbx_symtab (struct objfile *objfile)
switch (p[1])
{
case 'S':
- nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ nlist.n_value += ANOFFSET (objfile->section_offsets, data_sect_index);
#ifdef STATIC_TRANSFORM_NAME
namestring = STATIC_TRANSFORM_NAME (namestring);
#endif
add_psymbol_to_list (namestring, p - namestring,
- VAR_NAMESPACE, LOC_STATIC,
+ VAR_DOMAIN, LOC_STATIC,
&objfile->static_psymbols,
0, nlist.n_value,
psymtab_language, objfile);
continue;
case 'G':
- nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+ nlist.n_value += ANOFFSET (objfile->section_offsets, data_sect_index);
/* The addresses in these entries are reported to be
wrong. See the code that reads 'G's for symtabs. */
add_psymbol_to_list (namestring, p - namestring,
- VAR_NAMESPACE, LOC_STATIC,
+ VAR_DOMAIN, LOC_STATIC,
&objfile->global_psymbols,
0, nlist.n_value,
psymtab_language, objfile);
@@ -1736,7 +1709,7 @@ read_dbx_symtab (struct objfile *objfile)
&& namestring[0] != ' '))
{
add_psymbol_to_list (namestring, p - namestring,
- STRUCT_NAMESPACE, LOC_TYPEDEF,
+ STRUCT_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
nlist.n_value, 0,
psymtab_language, objfile);
@@ -1744,33 +1717,19 @@ read_dbx_symtab (struct objfile *objfile)
{
/* Also a typedef with the same name. */
add_psymbol_to_list (namestring, p - namestring,
- VAR_NAMESPACE, LOC_TYPEDEF,
+ VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
nlist.n_value, 0,
psymtab_language, objfile);
p += 1;
}
- /* The semantics of C++ state that "struct foo { ... }"
- also defines a typedef for "foo". Unfortuantely, cfront
- never makes the typedef when translating from C++ to C.
- We make the typedef here so that "ptype foo" works as
- expected for cfront translated code. */
- else if (psymtab_language == language_cplus)
- {
- /* Also a typedef with the same name. */
- add_psymbol_to_list (namestring, p - namestring,
- VAR_NAMESPACE, LOC_TYPEDEF,
- &objfile->static_psymbols,
- nlist.n_value, 0,
- psymtab_language, objfile);
- }
}
goto check_enum;
case 't':
if (p != namestring) /* a name is there, not just :T... */
{
add_psymbol_to_list (namestring, p - namestring,
- VAR_NAMESPACE, LOC_TYPEDEF,
+ VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
nlist.n_value, 0,
psymtab_language, objfile);
@@ -1832,7 +1791,7 @@ read_dbx_symtab (struct objfile *objfile)
/* Note that the value doesn't matter for
enum constants in psymtabs, just in symtabs. */
add_psymbol_to_list (p, q - p,
- VAR_NAMESPACE, LOC_CONST,
+ VAR_DOMAIN, LOC_CONST,
&objfile->static_psymbols, 0,
0, psymtab_language, objfile);
/* Point past the name. */
@@ -1849,7 +1808,7 @@ read_dbx_symtab (struct objfile *objfile)
case 'c':
/* Constant, e.g. from "const" in Pascal. */
add_psymbol_to_list (namestring, p - namestring,
- VAR_NAMESPACE, LOC_CONST,
+ VAR_DOMAIN, LOC_CONST,
&objfile->static_psymbols, nlist.n_value,
0, psymtab_language, objfile);
continue;
@@ -1861,7 +1820,7 @@ read_dbx_symtab (struct objfile *objfile)
char *name = xmalloc (name_len + 1);
memcpy (name, namestring, name_len);
name[name_len] = '\0';
- complain (&function_outside_compilation_unit, name);
+ function_outside_compilation_unit_complaint (name);
xfree (name);
}
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
@@ -1885,7 +1844,7 @@ read_dbx_symtab (struct objfile *objfile)
}
if (pst && textlow_not_set)
{
- TEXTLOW (pst) = nlist.n_value;
+ pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
#endif
@@ -1901,16 +1860,16 @@ read_dbx_symtab (struct objfile *objfile)
the partial symbol table. */
if (pst
&& (textlow_not_set
- || (nlist.n_value < TEXTLOW (pst)
+ || (nlist.n_value < pst->textlow
&& (nlist.n_value
!= ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile))))))
{
- TEXTLOW (pst) = nlist.n_value;
+ pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
add_psymbol_to_list (namestring, p - namestring,
- VAR_NAMESPACE, LOC_BLOCK,
+ VAR_DOMAIN, LOC_BLOCK,
&objfile->static_psymbols,
0, nlist.n_value,
psymtab_language, objfile);
@@ -1926,7 +1885,7 @@ read_dbx_symtab (struct objfile *objfile)
char *name = xmalloc (name_len + 1);
memcpy (name, namestring, name_len);
name[name_len] = '\0';
- complain (&function_outside_compilation_unit, name);
+ function_outside_compilation_unit_complaint (name);
xfree (name);
}
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
@@ -1950,7 +1909,7 @@ read_dbx_symtab (struct objfile *objfile)
}
if (pst && textlow_not_set)
{
- TEXTLOW (pst) = nlist.n_value;
+ pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
#endif
@@ -1966,16 +1925,16 @@ read_dbx_symtab (struct objfile *objfile)
the partial symbol table. */
if (pst
&& (textlow_not_set
- || (nlist.n_value < TEXTLOW (pst)
+ || (nlist.n_value < pst->textlow
&& (nlist.n_value
!= ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile))))))
{
- TEXTLOW (pst) = nlist.n_value;
+ pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
add_psymbol_to_list (namestring, p - namestring,
- VAR_NAMESPACE, LOC_BLOCK,
+ VAR_DOMAIN, LOC_BLOCK,
&objfile->global_psymbols,
0, nlist.n_value,
psymtab_language, objfile);
@@ -1998,9 +1957,6 @@ read_dbx_symtab (struct objfile *objfile)
case '9':
case '-':
case '#': /* for symbol identification (used in live ranges) */
- /* added to support cfront stabs strings */
- case 'Z': /* for definition continuations */
- case 'P': /* for prototypes */
continue;
case ':':
@@ -2021,7 +1977,8 @@ read_dbx_symtab (struct objfile *objfile)
time searching to the end of every string looking for
a backslash. */
- complain (&unknown_symchar_complaint, p[1]);
+ complaint (&symfile_complaints, "unknown symbol descriptor `%c'",
+ p[1]);
/* Ignore it; perhaps it is an extension that we don't
know about. */
@@ -2067,7 +2024,7 @@ read_dbx_symtab (struct objfile *objfile)
(struct partial_symtab **)
alloca ((dependencies_allocated *= 2)
* sizeof (struct partial_symtab *));
- memcpy ((PTR) dependency_list, (PTR) orig,
+ memcpy (dependency_list, orig,
(dependencies_used
* sizeof (struct partial_symtab *)));
#ifdef DEBUG_INFO
@@ -2083,7 +2040,7 @@ read_dbx_symtab (struct objfile *objfile)
case N_ENDM:
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* Solaris 2 end of module, finish current partial symbol table.
- end_psymtab will set TEXTHIGH (pst) to the proper value, which
+ end_psymtab will set pst->texthigh to the proper value, which
is necessary if a module compiled without debugging info
follows this module. */
if (pst)
@@ -2128,6 +2085,7 @@ read_dbx_symtab (struct objfile *objfile)
case N_OBJ: /* useless types from Solaris */
case N_OPT:
+ case N_PATCH:
/* These symbols aren't interesting; don't worry about them */
continue;
@@ -2135,8 +2093,7 @@ read_dbx_symtab (struct objfile *objfile)
default:
/* If we haven't found it yet, ignore it. It's probably some
new type we don't know about yet. */
- complain (&unknown_symtype_complaint,
- local_hex_string (nlist.n_type));
+ unknown_symtype_complaint (local_hex_string (nlist.n_type));
continue;
}
}
@@ -2148,8 +2105,8 @@ read_dbx_symtab (struct objfile *objfile)
&& objfile->ei.entry_point < nlist.n_value
&& objfile->ei.entry_point >= last_o_file_start)
{
- objfile->ei.entry_file_lowpc = last_o_file_start;
- objfile->ei.entry_file_highpc = nlist.n_value;
+ objfile->ei.deprecated_entry_file_lowpc = last_o_file_start;
+ objfile->ei.deprecated_entry_file_highpc = nlist.n_value;
}
if (pst)
@@ -2163,7 +2120,7 @@ read_dbx_symtab (struct objfile *objfile)
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
- text_end > TEXTHIGH (pst) ? text_end : TEXTHIGH (pst),
+ text_end > pst->texthigh ? text_end : pst->texthigh,
dependency_list, dependencies_used, textlow_not_set);
}
@@ -2188,9 +2145,7 @@ start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
filename, textlow, global_syms, static_syms);
result->read_symtab_private = (char *)
- obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
- TEXTLOW (result) = result->textlow;
- TEXTHIGH (result) = result->texthigh;
+ obstack_alloc (&objfile->objfile_obstack, sizeof (struct symloc));
LDSYMOFF (result) = ldsymoff;
result->read_symtab = dbx_psymtab_to_symtab;
SYMBOL_SIZE (result) = symbol_size;
@@ -2226,7 +2181,7 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
if (capping_symbol_offset != -1)
LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
- TEXTHIGH (pst) = capping_text;
+ pst->texthigh = capping_text;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* Under Solaris, the N_SO symbols always have a value of 0,
@@ -2244,7 +2199,7 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
a reliable texthigh by taking the address plus size of the
last function in the file. */
- if (TEXTHIGH (pst) == 0 && last_function_name)
+ if (pst->texthigh == 0 && last_function_name)
{
char *p;
int n;
@@ -2270,14 +2225,14 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
}
if (minsym)
- TEXTHIGH (pst) = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
+ pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
last_function_name = NULL;
}
/* this test will be true if the last .o file is only data */
if (textlow_not_set)
- TEXTLOW (pst) = TEXTHIGH (pst);
+ pst->textlow = pst->texthigh;
else
{
struct partial_symtab *p1;
@@ -2290,12 +2245,12 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
ALL_OBJFILE_PSYMTABS (objfile, p1)
{
- if (TEXTHIGH (p1) == 0 && TEXTLOW (p1) != 0 && p1 != pst)
+ if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst)
{
- TEXTHIGH (p1) = TEXTLOW (pst);
+ p1->texthigh = pst->textlow;
/* if this file has only data, then make textlow match texthigh */
- if (TEXTLOW (p1) == 0)
- TEXTLOW (p1) = TEXTHIGH (p1);
+ if (p1->textlow == 0)
+ p1->textlow = p1->texthigh;
}
}
}
@@ -2312,7 +2267,7 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
if (number_dependencies)
{
pst->dependencies = (struct partial_symtab **)
- obstack_alloc (&objfile->psymbol_obstack,
+ obstack_alloc (&objfile->objfile_obstack,
number_dependencies * sizeof (struct partial_symtab *));
memcpy (pst->dependencies, dependency_list,
number_dependencies * sizeof (struct partial_symtab *));
@@ -2328,17 +2283,17 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
/* Copy the sesction_offsets array from the main psymtab. */
subpst->section_offsets = pst->section_offsets;
subpst->read_symtab_private =
- (char *) obstack_alloc (&objfile->psymbol_obstack,
+ (char *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symloc));
LDSYMOFF (subpst) =
LDSYMLEN (subpst) =
- TEXTLOW (subpst) =
- TEXTHIGH (subpst) = 0;
+ subpst->textlow =
+ subpst->texthigh = 0;
/* We could save slight bits of space by only making one of these,
shared by the entire set of include files. FIXME-someday. */
subpst->dependencies = (struct partial_symtab **)
- obstack_alloc (&objfile->psymbol_obstack,
+ obstack_alloc (&objfile->objfile_obstack,
sizeof (struct partial_symtab *));
subpst->dependencies[0] = pst;
subpst->number_of_dependencies = 1;
@@ -2428,7 +2383,6 @@ dbx_psymtab_to_symtab_1 (struct partial_symtab *pst)
/* Read in this file's symbols */
bfd_seek (pst->objfile->obfd, SYMBOL_OFFSET (pst), SEEK_SET);
read_ofile_symtab (pst);
- sort_symtab_syms (pst->symtab);
do_cleanups (old_chain);
}
@@ -2443,6 +2397,7 @@ static void
dbx_psymtab_to_symtab (struct partial_symtab *pst)
{
bfd *sym_bfd;
+ struct cleanup *back_to = NULL;
if (!pst)
return;
@@ -2468,8 +2423,21 @@ dbx_psymtab_to_symtab (struct partial_symtab *pst)
next_symbol_text_func = dbx_next_symbol_text;
+ if (DBX_STAB_SECTION (pst->objfile))
+ {
+ stabs_data
+ = symfile_relocate_debug_section (pst->objfile->obfd,
+ DBX_STAB_SECTION (pst->objfile),
+ NULL);
+ if (stabs_data)
+ back_to = make_cleanup (free_current_contents, (void *) &stabs_data);
+ }
+
dbx_psymtab_to_symtab_1 (pst);
+ if (back_to)
+ do_cleanups (back_to);
+
/* Match with global symbols. This only needs to be done once,
after all of the symtabs and dependencies have been read in. */
scan_file_globals (pst->objfile);
@@ -2485,12 +2453,12 @@ dbx_psymtab_to_symtab (struct partial_symtab *pst)
static void
read_ofile_symtab (struct partial_symtab *pst)
{
- register char *namestring;
- register struct external_nlist *bufp;
+ char *namestring;
+ struct external_nlist *bufp;
struct internal_nlist nlist;
unsigned char type;
unsigned max_symnum;
- register bfd *abfd;
+ bfd *abfd;
struct objfile *objfile;
int sym_offset; /* Offset to start of symbols to read */
int sym_size; /* Size of symbols to read */
@@ -2501,8 +2469,8 @@ read_ofile_symtab (struct partial_symtab *pst)
objfile = pst->objfile;
sym_offset = LDSYMOFF (pst);
sym_size = LDSYMLEN (pst);
- text_offset = TEXTLOW (pst);
- text_size = TEXTHIGH (pst) - TEXTLOW (pst);
+ text_offset = pst->textlow;
+ text_size = pst->texthigh - pst->textlow;
/* This cannot be simply objfile->section_offsets because of
elfstab_offset_sections() which initializes the psymtab section
offsets information in a special way, and that is different from
@@ -2518,6 +2486,8 @@ read_ofile_symtab (struct partial_symtab *pst)
abfd = objfile->obfd;
symfile_bfd = objfile->obfd; /* Implicit param to next_text_symbol */
symbuf_end = symbuf_idx = 0;
+ symbuf_read = 0;
+ symbuf_left = sym_offset + sym_size;
/* It is necessary to actually read one symbol *before* the start
of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL
@@ -2527,7 +2497,7 @@ read_ofile_symtab (struct partial_symtab *pst)
would slow down initial readin, so we look for it here instead. */
if (!processing_acc_compilation && sym_offset >= (int) symbol_size)
{
- bfd_seek (symfile_bfd, sym_offset - symbol_size, SEEK_CUR);
+ stabs_seek (sym_offset - symbol_size);
fill_symbuf (abfd);
bufp = &symbuf[symbuf_idx++];
INTERNALIZE_SYMBOL (nlist, bufp, abfd);
@@ -2540,13 +2510,13 @@ read_ofile_symtab (struct partial_symtab *pst)
{
const char *tempstring = namestring;
- if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
+ if (DEPRECATED_STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
processing_gcc_compilation = 1;
- else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
+ else if (DEPRECATED_STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
processing_gcc_compilation = 2;
if (tempstring[0] == bfd_get_symbol_leading_char (symfile_bfd))
++tempstring;
- if (STREQN (tempstring, "__gnu_compiled", 14))
+ if (DEPRECATED_STREQN (tempstring, "__gnu_compiled", 14))
processing_gcc_compilation = 2;
}
@@ -2570,7 +2540,7 @@ read_ofile_symtab (struct partial_symtab *pst)
/* The N_SO starting this symtab is the first symbol, so we
better not check the symbol before it. I'm not this can
happen, but it doesn't hurt to check for it. */
- bfd_seek (symfile_bfd, sym_offset, SEEK_CUR);
+ stabs_seek (sym_offset);
processing_gcc_compilation = 0;
}
@@ -2612,9 +2582,9 @@ read_ofile_symtab (struct partial_symtab *pst)
However, there is no reason not to accept
the GCC_COMPILED_FLAG_SYMBOL anywhere. */
- if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
+ if (DEPRECATED_STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
processing_gcc_compilation = 1;
- else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
+ else if (DEPRECATED_STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
processing_gcc_compilation = 2;
#if 0
@@ -2647,22 +2617,18 @@ read_ofile_symtab (struct partial_symtab *pst)
/* In a Solaris elf file, this variable, which comes from the
value of the N_SO symbol, will still be 0. Luckily, text_offset,
- which comes from TEXTLOW (pst) is correct. */
+ which comes from pst->textlow is correct. */
if (last_source_start_addr == 0)
last_source_start_addr = text_offset;
/* In reordered executables last_source_start_addr may not be the
lower bound for this symtab, instead use text_offset which comes
- from TEXTLOW (pst) which is correct. */
+ from pst->textlow which is correct. */
if (last_source_start_addr > text_offset)
last_source_start_addr = text_offset;
pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
- /* Process items which we had to "process_later" due to dependencies
- on other stabs. */
- process_now (objfile);
-
end_stabs ();
}
@@ -2699,7 +2665,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
static CORE_ADDR last_pc_address;
#endif
- register struct context_stack *new;
+ struct context_stack *new;
/* This remembers the address of the start of a function. It is used
because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries are
relative to the current function's start address. On systems
@@ -2711,9 +2677,10 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
peculiarities of function_start_offset. */
static CORE_ADDR last_function_start;
- /* If this is nonzero, we've seen an N_SLINE since the start of the current
- function. Initialized to nonzero to assure that last_function_start
- is never used uninitialized. */
+ /* If this is nonzero, we've seen an N_SLINE since the start of the
+ current function. We use this to tell us to move the first sline
+ to the beginning of the function regardless of what its given
+ value is. */
static int sline_found_in_function = 1;
/* If this is nonzero, we've seen a non-gcc N_OPT symbol for this source
@@ -2750,7 +2717,20 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
{
/* This N_FUN marks the end of a function. This closes off the
current block. */
- record_line (current_subfile, 0, function_start_offset + valu);
+
+ if (context_stack_depth <= 0)
+ {
+ lbrac_mismatch_complaint (symnum);
+ break;
+ }
+
+ /* The following check is added before recording line 0 at
+ end of function so as to handle hand-generated stabs
+ which may have an N_FUN stabs at the end of the function, but
+ no N_SLINE stabs. */
+ if (sline_found_in_function)
+ record_line (current_subfile, 0, last_function_start + valu);
+
within_function = 0;
new = pop_context ();
@@ -2796,7 +2776,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
if (!SUN_FIXED_LBRAC_BUG && valu < last_pc_address)
{
/* Patch current LBRAC pc value to match last handy pc value */
- complain (&lbrac_complaint);
+ complaint (&symfile_complaints, "bad block start address patched");
valu = last_pc_address;
}
#endif
@@ -2819,9 +2799,15 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
N_SO, the linker did not relocate them (sigh). */
valu += last_source_start_addr;
+ if (context_stack_depth <= 0)
+ {
+ lbrac_mismatch_complaint (symnum);
+ break;
+ }
+
new = pop_context ();
if (desc != new->depth)
- complain (&lbrac_mismatch_complaint, symnum);
+ lbrac_mismatch_complaint (symnum);
/* Some compilers put the variable decls inside of an
LBRAC/RBRAC block. This macro should be nonzero if this
@@ -2835,7 +2821,22 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
/* Can only use new->locals as local symbols here if we're in
gcc or on a machine that puts them before the lbrack. */
if (!VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
- local_symbols = new->locals;
+ {
+ if (local_symbols != NULL)
+ {
+ /* GCC development snapshots from March to December of
+ 2000 would output N_LSYM entries after N_LBRAC
+ entries. As a consequence, these symbols are simply
+ discarded. Complain if this is the case. Note that
+ there are some compilers which legitimately put local
+ symbols within an LBRAC/RBRAC block; this complaint
+ might also help sort out problems in which
+ VARIABLES_INSIDE_BLOCK is incorrectly defined. */
+ complaint (&symfile_complaints,
+ "misplaced N_LBRAC entry; discarding local symbols which have no enclosing block");
+ }
+ local_symbols = new->locals;
+ }
if (context_stack_depth
> !VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
@@ -2852,7 +2853,8 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
compilers? Is this ever harmful?). */
if (new->start_addr > valu)
{
- complain (&lbrac_rbrac_complaint);
+ complaint (&symfile_complaints,
+ "block start larger than block end");
new->start_addr = valu;
}
/* Make a block for the local symbols within. */
@@ -3076,7 +3078,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
case N_NBBSS:
case N_NBSTS:
case N_NBLCS:
- complain (&unknown_symtype_complaint, local_hex_string (type));
+ unknown_symtype_complaint (local_hex_string (type));
/* FALLTHROUGH */
/* The following symbol types don't need the address field relocated,
@@ -3158,13 +3160,13 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
int l = colon_pos - name;
m = lookup_minimal_symbol_by_pc (last_pc_address);
- if (m && STREQN (SYMBOL_NAME (m), name, l)
- && SYMBOL_NAME (m)[l] == '\0')
+ if (m && strncmp (DEPRECATED_SYMBOL_NAME (m), name, l) == 0
+ && DEPRECATED_SYMBOL_NAME (m)[l] == '\0')
/* last_pc_address was in this function */
valu = SYMBOL_VALUE (m);
- else if (m && SYMBOL_NAME (m + 1)
- && STREQN (SYMBOL_NAME (m + 1), name, l)
- && SYMBOL_NAME (m + 1)[l] == '\0')
+ else if (m && DEPRECATED_SYMBOL_NAME (m + 1)
+ && strncmp (DEPRECATED_SYMBOL_NAME (m + 1), name, l) == 0
+ && DEPRECATED_SYMBOL_NAME (m + 1)[l] == '\0')
/* last_pc_address was in last function */
valu = SYMBOL_VALUE (m + 1);
else
@@ -3188,7 +3190,8 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
if (context_stack_depth > 1)
{
- complain (&lbrac_unmatched_complaint, symnum);
+ complaint (&symfile_complaints,
+ "unmatched N_LBRAC before symtab pos %d", symnum);
break;
}
@@ -3217,7 +3220,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
case N_OPT: /* Solaris 2: Compiler options */
if (name)
{
- if (STREQ (name, GCC2_COMPILED_FLAG_SYMBOL))
+ if (strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0)
{
processing_gcc_compilation = 2;
#if 0 /* Works, but is experimental. -fnf */
@@ -3249,6 +3252,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
/* The following symbol types can be ignored. */
case N_OBJ: /* Solaris 2: Object file dir and name */
+ case N_PATCH: /* Solaris2: Patch Run Time Checker. */
/* N_UNDF: Solaris 2: file separator mark */
/* N_UNDF: -- we will never encounter it, since we only process one
file's symbols at once. */
@@ -3338,7 +3342,7 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline,
if (stabstrsize > bfd_get_size (sym_bfd))
error ("ridiculous string table size: %d bytes", stabstrsize);
DBX_STRINGTAB (objfile) = (char *)
- obstack_alloc (&objfile->psymbol_obstack, stabstrsize + 1);
+ obstack_alloc (&objfile->objfile_obstack, stabstrsize + 1);
OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
/* Now read in the string table in one big gulp. */
@@ -3399,8 +3403,7 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline,
the base address of the text segment).
MAINLINE is true if we are reading the main symbol
table (as opposed to a shared lib or dynamically loaded file).
- STABOFFSET and STABSIZE define the location in OBJFILE where the .stab
- section exists.
+ STABSECT is the BFD section information for the .stab section.
STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
.stabstr section exists.
@@ -3409,13 +3412,14 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline,
void
elfstab_build_psymtabs (struct objfile *objfile, int mainline,
- file_ptr staboffset, unsigned int stabsize,
+ asection *stabsect,
file_ptr stabstroffset, unsigned int stabstrsize)
{
int val;
bfd *sym_bfd = objfile->obfd;
char *name = bfd_get_filename (sym_bfd);
struct dbx_symfile_info *info;
+ struct cleanup *back_to = NULL;
/* There is already a dbx_symfile_info allocated by our caller.
It might even contain some info from the ELF symtab to help us. */
@@ -3427,14 +3431,16 @@ elfstab_build_psymtabs (struct objfile *objfile, int mainline,
#define ELF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */
DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE;
- DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
+ DBX_SYMCOUNT (objfile)
+ = bfd_section_size (objfile->obfd, stabsect) / DBX_SYMBOL_SIZE (objfile);
DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
- DBX_SYMTAB_OFFSET (objfile) = staboffset;
+ DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos;
+ DBX_STAB_SECTION (objfile) = stabsect;
if (stabstrsize > bfd_get_size (sym_bfd))
error ("ridiculous string table size: %d bytes", stabstrsize);
DBX_STRINGTAB (objfile) = (char *)
- obstack_alloc (&objfile->psymbol_obstack, stabstrsize + 1);
+ obstack_alloc (&objfile->objfile_obstack, stabstrsize + 1);
OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
/* Now read in the string table in one big gulp. */
@@ -3450,14 +3456,25 @@ elfstab_build_psymtabs (struct objfile *objfile, int mainline,
buildsym_new_init ();
free_header_files ();
init_header_files ();
- install_minimal_symbols (objfile);
processing_acc_compilation = 1;
+ symbuf_read = 0;
+ symbuf_left = bfd_section_size (objfile->obfd, stabsect);
+ stabs_data = symfile_relocate_debug_section (objfile->obfd, stabsect, NULL);
+ if (stabs_data)
+ back_to = make_cleanup (free_current_contents, (void *) &stabs_data);
+
/* In an elf file, we've already installed the minimal symbols that came
from the elf (non-stab) symbol table, so always act like an
- incremental load here. */
+ incremental load here. dbx_symfile_read should not generate any new
+ minimal symbols, since we will have already read the ELF dynamic symbol
+ table and normal symbol entries won't be in the ".stab" section; but in
+ case it does, it will install them itself. */
dbx_symfile_read (objfile, 0);
+
+ if (back_to)
+ do_cleanups (back_to);
}
/* Scan and build partial symbols for a file with special sections for stabs
@@ -3517,7 +3534,7 @@ stabsect_build_psymtabs (struct objfile *objfile, int mainline, char *stab_name,
if (DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd))
error ("ridiculous string table size: %d bytes", DBX_STRINGTAB_SIZE (objfile));
DBX_STRINGTAB (objfile) = (char *)
- obstack_alloc (&objfile->psymbol_obstack, DBX_STRINGTAB_SIZE (objfile) + 1);
+ obstack_alloc (&objfile->objfile_obstack, DBX_STRINGTAB_SIZE (objfile) + 1);
OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile) + 1);
/* Now read in the string table in one big gulp. */
@@ -3535,7 +3552,6 @@ stabsect_build_psymtabs (struct objfile *objfile, int mainline, char *stab_name,
buildsym_new_init ();
free_header_files ();
init_header_files ();
- install_minimal_symbols (objfile);
/* Now, do an incremental load */
diff --git a/contrib/gdb/gdb/defs.h b/contrib/gdb/gdb/defs.h
index b6e7953..e49f9e0 100644
--- a/contrib/gdb/gdb/defs.h
+++ b/contrib/gdb/gdb/defs.h
@@ -1,7 +1,7 @@
/* *INDENT-OFF* */ /* ATTR_FORMAT confuses indent, avoid running it for now */
/* Basic, host-specific, and target-specific definitions for GDB.
Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GDB.
@@ -24,22 +24,33 @@
#ifndef DEFS_H
#define DEFS_H
-#include "config.h" /* Generated by configure */
+#include "config.h" /* Generated by configure. */
+
#include <stdio.h>
-#include <errno.h> /* System call error return status */
+#include <errno.h> /* System call error return status. */
#include <limits.h>
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#else
-#include <sys/types.h> /* for size_t */
+#include <sys/types.h> /* For size_t. */
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-/* Just in case they're not defined in stdio.h. */
+/* First include ansidecl.h so we can use the various macro definitions
+ here and in all subsequent file inclusions. */
+
+#include "ansidecl.h"
+
+#include "gdb_locale.h"
+
+/* For ``enum target_signal''. */
+#include "gdb/signals.h"
+
+/* Just in case they're not defined in stdio.h. */
#ifndef SEEK_SET
#define SEEK_SET 0
@@ -48,17 +59,10 @@
#define SEEK_CUR 1
#endif
-/* First include ansidecl.h so we can use the various macro definitions
- here and in all subsequent file inclusions. */
-
-#include "ansidecl.h"
-
-#include <stdarg.h> /* for va_list */
+#include <stdarg.h> /* For va_list. */
#include "libiberty.h"
-#include "progress.h"
-
/* For BFD64 and bfd_vma. */
#include "bfd.h"
@@ -148,25 +152,32 @@ typedef bfd_vma CORE_ADDR;
issue is found that we spend the effort on algorithmic
optimizations than micro-optimizing.'' J.T. */
-#define STREQ(a,b) (*(a) == *(b) ? !strcmp ((a), (b)) : 0)
-#define STREQN(a,b,c) (*(a) == *(b) ? !strncmp ((a), (b), (c)) : 0)
+/* NOTE: cagney/2003-11-23: All instances of STREQ[N] covered by
+ testing GDB on a stabs system have been replaced by equivalent
+ str[n]cmp calls. To avoid the possability of introducing bugs when
+ making untested changes, the remaining references were deprecated
+ rather than replaced. */
-/* The character GNU C++ uses to build identifiers that must be unique from
- the program's identifiers (such as $this and $$vptr). */
-#define CPLUS_MARKER '$' /* May be overridden to '.' for SysV */
+/* DISCLAIMER: cagney/2003-11-23: Simplified definition of these
+ macros so that they just map directly onto strcmp equivalent. I'm
+ not responsible for any breakage due to code that relied on the old
+ underlying implementation. */
+
+#define DEPRECATED_STREQ(a,b) (strcmp ((a), (b)) == 0)
+#define DEPRECATED_STREQN(a,b,c) (strncmp ((a), (b), (c)) == 0)
/* Check if a character is one of the commonly used C++ marker characters. */
extern int is_cplus_marker (int);
-/* use tui interface if non-zero */
-extern int tui_version;
-
/* enable xdb commands if set */
extern int xdb_commands;
/* enable dbx commands if set */
extern int dbx_commands;
+/* System root path, used to find libraries etc. */
+extern char *gdb_sysroot;
+
extern int quit_flag;
extern int immediate_quit;
extern int sevenbit_strings;
@@ -188,7 +199,6 @@ extern void quit (void);
#define QUIT { \
if (quit_flag) quit (); \
if (interactive_hook) interactive_hook (); \
- PROGRESS (1); \
}
#endif
@@ -203,13 +213,14 @@ enum language
language_auto, /* Placeholder for automatic setting */
language_c, /* C */
language_cplus, /* C++ */
+ language_objc, /* Objective-C */
language_java, /* Java */
- language_chill, /* Chill */
language_fortran, /* Fortran */
language_m2, /* Modula-2 */
language_asm, /* Assembly language */
language_scm, /* Scheme / Guile */
- language_pascal /* Pascal */
+ language_pascal, /* Pascal */
+ language_minimal /* All other languages, minimal support only */
};
enum precision_type
@@ -219,212 +230,28 @@ enum precision_type
unspecified_precision
};
-/* The numbering of these signals is chosen to match traditional unix
- signals (insofar as various unices use the same numbers, anyway).
- It is also the numbering of the GDB remote protocol. Other remote
- protocols, if they use a different numbering, should make sure to
- translate appropriately.
-
- Since these numbers have actually made it out into other software
- (stubs, etc.), you mustn't disturb the assigned numbering. If you
- need to add new signals here, add them to the end of the explicitly
- numbered signals.
-
- This is based strongly on Unix/POSIX signals for several reasons:
- (1) This set of signals represents a widely-accepted attempt to
- represent events of this sort in a portable fashion, (2) we want a
- signal to make it from wait to child_wait to the user intact, (3) many
- remote protocols use a similar encoding. However, it is
- recognized that this set of signals has limitations (such as not
- distinguishing between various kinds of SIGSEGV, or not
- distinguishing hitting a breakpoint from finishing a single step).
- So in the future we may get around this either by adding additional
- signals for breakpoint, single-step, etc., or by adding signal
- codes; the latter seems more in the spirit of what BSD, System V,
- etc. are doing to address these issues. */
-
-/* For an explanation of what each signal means, see
- target_signal_to_string. */
-
-enum target_signal
- {
- /* Used some places (e.g. stop_signal) to record the concept that
- there is no signal. */
- TARGET_SIGNAL_0 = 0,
- TARGET_SIGNAL_FIRST = 0,
- TARGET_SIGNAL_HUP = 1,
- TARGET_SIGNAL_INT = 2,
- TARGET_SIGNAL_QUIT = 3,
- TARGET_SIGNAL_ILL = 4,
- TARGET_SIGNAL_TRAP = 5,
- TARGET_SIGNAL_ABRT = 6,
- TARGET_SIGNAL_EMT = 7,
- TARGET_SIGNAL_FPE = 8,
- TARGET_SIGNAL_KILL = 9,
- TARGET_SIGNAL_BUS = 10,
- TARGET_SIGNAL_SEGV = 11,
- TARGET_SIGNAL_SYS = 12,
- TARGET_SIGNAL_PIPE = 13,
- TARGET_SIGNAL_ALRM = 14,
- TARGET_SIGNAL_TERM = 15,
- TARGET_SIGNAL_URG = 16,
- TARGET_SIGNAL_STOP = 17,
- TARGET_SIGNAL_TSTP = 18,
- TARGET_SIGNAL_CONT = 19,
- TARGET_SIGNAL_CHLD = 20,
- TARGET_SIGNAL_TTIN = 21,
- TARGET_SIGNAL_TTOU = 22,
- TARGET_SIGNAL_IO = 23,
- TARGET_SIGNAL_XCPU = 24,
- TARGET_SIGNAL_XFSZ = 25,
- TARGET_SIGNAL_VTALRM = 26,
- TARGET_SIGNAL_PROF = 27,
- TARGET_SIGNAL_WINCH = 28,
- TARGET_SIGNAL_LOST = 29,
- TARGET_SIGNAL_USR1 = 30,
- TARGET_SIGNAL_USR2 = 31,
- TARGET_SIGNAL_PWR = 32,
- /* Similar to SIGIO. Perhaps they should have the same number. */
- TARGET_SIGNAL_POLL = 33,
- TARGET_SIGNAL_WIND = 34,
- TARGET_SIGNAL_PHONE = 35,
- TARGET_SIGNAL_WAITING = 36,
- TARGET_SIGNAL_LWP = 37,
- TARGET_SIGNAL_DANGER = 38,
- TARGET_SIGNAL_GRANT = 39,
- TARGET_SIGNAL_RETRACT = 40,
- TARGET_SIGNAL_MSG = 41,
- TARGET_SIGNAL_SOUND = 42,
- TARGET_SIGNAL_SAK = 43,
- TARGET_SIGNAL_PRIO = 44,
- TARGET_SIGNAL_REALTIME_33 = 45,
- TARGET_SIGNAL_REALTIME_34 = 46,
- TARGET_SIGNAL_REALTIME_35 = 47,
- TARGET_SIGNAL_REALTIME_36 = 48,
- TARGET_SIGNAL_REALTIME_37 = 49,
- TARGET_SIGNAL_REALTIME_38 = 50,
- TARGET_SIGNAL_REALTIME_39 = 51,
- TARGET_SIGNAL_REALTIME_40 = 52,
- TARGET_SIGNAL_REALTIME_41 = 53,
- TARGET_SIGNAL_REALTIME_42 = 54,
- TARGET_SIGNAL_REALTIME_43 = 55,
- TARGET_SIGNAL_REALTIME_44 = 56,
- TARGET_SIGNAL_REALTIME_45 = 57,
- TARGET_SIGNAL_REALTIME_46 = 58,
- TARGET_SIGNAL_REALTIME_47 = 59,
- TARGET_SIGNAL_REALTIME_48 = 60,
- TARGET_SIGNAL_REALTIME_49 = 61,
- TARGET_SIGNAL_REALTIME_50 = 62,
- TARGET_SIGNAL_REALTIME_51 = 63,
- TARGET_SIGNAL_REALTIME_52 = 64,
- TARGET_SIGNAL_REALTIME_53 = 65,
- TARGET_SIGNAL_REALTIME_54 = 66,
- TARGET_SIGNAL_REALTIME_55 = 67,
- TARGET_SIGNAL_REALTIME_56 = 68,
- TARGET_SIGNAL_REALTIME_57 = 69,
- TARGET_SIGNAL_REALTIME_58 = 70,
- TARGET_SIGNAL_REALTIME_59 = 71,
- TARGET_SIGNAL_REALTIME_60 = 72,
- TARGET_SIGNAL_REALTIME_61 = 73,
- TARGET_SIGNAL_REALTIME_62 = 74,
- TARGET_SIGNAL_REALTIME_63 = 75,
-
- /* Used internally by Solaris threads. See signal(5) on Solaris. */
- TARGET_SIGNAL_CANCEL = 76,
-
- /* Yes, this pains me, too. But LynxOS didn't have SIG32, and now
- GNU/Linux does, and we can't disturb the numbering, since it's
- part of the remote protocol. Note that in some GDB's
- TARGET_SIGNAL_REALTIME_32 is number 76. */
- TARGET_SIGNAL_REALTIME_32,
- /* Yet another pain, IRIX 6 has SIG64. */
- TARGET_SIGNAL_REALTIME_64,
- /* Yet another pain, GNU/Linux MIPS might go up to 128. */
- TARGET_SIGNAL_REALTIME_65,
- TARGET_SIGNAL_REALTIME_66,
- TARGET_SIGNAL_REALTIME_67,
- TARGET_SIGNAL_REALTIME_68,
- TARGET_SIGNAL_REALTIME_69,
- TARGET_SIGNAL_REALTIME_70,
- TARGET_SIGNAL_REALTIME_71,
- TARGET_SIGNAL_REALTIME_72,
- TARGET_SIGNAL_REALTIME_73,
- TARGET_SIGNAL_REALTIME_74,
- TARGET_SIGNAL_REALTIME_75,
- TARGET_SIGNAL_REALTIME_76,
- TARGET_SIGNAL_REALTIME_77,
- TARGET_SIGNAL_REALTIME_78,
- TARGET_SIGNAL_REALTIME_79,
- TARGET_SIGNAL_REALTIME_80,
- TARGET_SIGNAL_REALTIME_81,
- TARGET_SIGNAL_REALTIME_82,
- TARGET_SIGNAL_REALTIME_83,
- TARGET_SIGNAL_REALTIME_84,
- TARGET_SIGNAL_REALTIME_85,
- TARGET_SIGNAL_REALTIME_86,
- TARGET_SIGNAL_REALTIME_87,
- TARGET_SIGNAL_REALTIME_88,
- TARGET_SIGNAL_REALTIME_89,
- TARGET_SIGNAL_REALTIME_90,
- TARGET_SIGNAL_REALTIME_91,
- TARGET_SIGNAL_REALTIME_92,
- TARGET_SIGNAL_REALTIME_93,
- TARGET_SIGNAL_REALTIME_94,
- TARGET_SIGNAL_REALTIME_95,
- TARGET_SIGNAL_REALTIME_96,
- TARGET_SIGNAL_REALTIME_97,
- TARGET_SIGNAL_REALTIME_98,
- TARGET_SIGNAL_REALTIME_99,
- TARGET_SIGNAL_REALTIME_100,
- TARGET_SIGNAL_REALTIME_101,
- TARGET_SIGNAL_REALTIME_102,
- TARGET_SIGNAL_REALTIME_103,
- TARGET_SIGNAL_REALTIME_104,
- TARGET_SIGNAL_REALTIME_105,
- TARGET_SIGNAL_REALTIME_106,
- TARGET_SIGNAL_REALTIME_107,
- TARGET_SIGNAL_REALTIME_108,
- TARGET_SIGNAL_REALTIME_109,
- TARGET_SIGNAL_REALTIME_110,
- TARGET_SIGNAL_REALTIME_111,
- TARGET_SIGNAL_REALTIME_112,
- TARGET_SIGNAL_REALTIME_113,
- TARGET_SIGNAL_REALTIME_114,
- TARGET_SIGNAL_REALTIME_115,
- TARGET_SIGNAL_REALTIME_116,
- TARGET_SIGNAL_REALTIME_117,
- TARGET_SIGNAL_REALTIME_118,
- TARGET_SIGNAL_REALTIME_119,
- TARGET_SIGNAL_REALTIME_120,
- TARGET_SIGNAL_REALTIME_121,
- TARGET_SIGNAL_REALTIME_122,
- TARGET_SIGNAL_REALTIME_123,
- TARGET_SIGNAL_REALTIME_124,
- TARGET_SIGNAL_REALTIME_125,
- TARGET_SIGNAL_REALTIME_126,
- TARGET_SIGNAL_REALTIME_127,
-
-#if defined(MACH) || defined(__MACH__)
- /* Mach exceptions */
- TARGET_EXC_BAD_ACCESS,
- TARGET_EXC_BAD_INSTRUCTION,
- TARGET_EXC_ARITHMETIC,
- TARGET_EXC_EMULATION,
- TARGET_EXC_SOFTWARE,
- TARGET_EXC_BREAKPOINT,
-#endif
- TARGET_SIGNAL_INFO,
-
- /* Some signal we don't know about. */
- TARGET_SIGNAL_UNKNOWN,
-
- /* Use whatever signal we use when one is not specifically specified
- (for passing to proceed and so on). */
- TARGET_SIGNAL_DEFAULT,
-
- /* Last and unused enum value, for sizing arrays, etc. */
- TARGET_SIGNAL_LAST
- };
+/* A generic, not quite boolean, enumeration. */
+enum auto_boolean
+{
+ AUTO_BOOLEAN_TRUE,
+ AUTO_BOOLEAN_FALSE,
+ AUTO_BOOLEAN_AUTO
+};
+
+/* Potential ways that a function can return a value of a given type. */
+enum return_value_convention
+{
+ /* Where the return value has been squeezed into one or more
+ registers. */
+ RETURN_VALUE_REGISTER_CONVENTION,
+ /* Commonly known as the "struct return convention". The caller
+ passes an additional hidden first parameter to the caller. That
+ parameter contains the address at which the value being returned
+ should be stored. While typically, and historically, used for
+ large structs, this is convention is applied to values of many
+ different types. */
+ RETURN_VALUE_STRUCT_CONVENTION
+};
/* the cleanup list records things that have to be undone
if an error happens (descriptors to be closed, memory to be freed, etc.)
@@ -439,8 +266,8 @@ enum target_signal
struct cleanup
{
struct cleanup *next;
- void (*function) (PTR);
- PTR arg;
+ void (*function) (void *);
+ void *arg;
};
@@ -481,23 +308,29 @@ struct cleanup
#endif
#endif
+/* Be conservative and use enum bitfields only with GCC.
+ This is copied from gcc 3.3.1, system.h. */
+
+#if defined(__GNUC__) && (__GNUC__ >= 2)
+#define ENUM_BITFIELD(TYPE) enum TYPE
+#else
+#define ENUM_BITFIELD(TYPE) unsigned int
+#endif
+
/* Needed for various prototypes */
struct symtab;
struct breakpoint;
+struct frame_info;
/* From blockframe.c */
-extern int inside_entry_func (CORE_ADDR);
+extern int inside_entry_func (struct frame_info *this_frame);
-extern int inside_entry_file (CORE_ADDR addr);
+extern int deprecated_inside_entry_file (CORE_ADDR addr);
extern int inside_main_func (CORE_ADDR pc);
-/* From ch-lang.c, for the moment. (FIXME) */
-
-extern char *chill_demangle (const char *);
-
/* From utils.c */
extern void initialize_utils (void);
@@ -506,6 +339,10 @@ extern void notice_quit (void);
extern int strcmp_iw (const char *, const char *);
+extern int strcmp_iw_ordered (const char *, const char *);
+
+extern int streq (const char *, const char *);
+
extern int subset_compare (char *, char *);
extern char *safe_strerror (int);
@@ -516,7 +353,6 @@ extern void request_quit (int);
extern void do_cleanups (struct cleanup *);
extern void do_final_cleanups (struct cleanup *);
-extern void do_my_cleanups (struct cleanup **, struct cleanup *);
extern void do_run_cleanups (struct cleanup *);
extern void do_exec_cleanups (struct cleanup *);
extern void do_exec_error_cleanups (struct cleanup *);
@@ -569,13 +405,16 @@ extern void null_cleanup (void *);
extern int myread (int, char *, int);
extern int query (const char *, ...) ATTR_FORMAT (printf, 1, 2);
+extern int nquery (const char *, ...) ATTR_FORMAT (printf, 1, 2);
+extern int yquery (const char *, ...) ATTR_FORMAT (printf, 1, 2);
extern void init_page_info (void);
-extern CORE_ADDR host_pointer_to_address (void *ptr);
-extern void *address_to_host_pointer (CORE_ADDR addr);
-
extern char *gdb_realpath (const char *);
+extern char *xfullpath (const char *);
+
+extern unsigned long gnu_debuglink_crc32 (unsigned long crc,
+ unsigned char *buf, size_t len);
/* From demangle.c */
@@ -587,7 +426,6 @@ struct type;
typedef int (use_struct_convention_fn) (int gcc_p, struct type * value_type);
extern use_struct_convention_fn generic_use_struct_convention;
-typedef unsigned char *(breakpoint_from_pc_fn) (CORE_ADDR * pcptr, int *lenptr);
/* Annotation stuff. */
@@ -601,22 +439,22 @@ extern void reinitialize_more_filter (void);
/* Normal results */
extern struct ui_file *gdb_stdout;
+/* Input stream */
+extern struct ui_file *gdb_stdin;
/* Serious error notifications */
extern struct ui_file *gdb_stderr;
/* Log/debug/trace messages that should bypass normal stdout/stderr
- filtering. For momement, always call this stream using
+ filtering. For moment, always call this stream using
*_unfiltered. In the very near future that restriction shall be
removed - either call shall be unfiltered. (cagney 1999-06-13). */
extern struct ui_file *gdb_stdlog;
/* Target output that should bypass normal stdout/stderr filtering.
- For momement, always call this stream using *_unfiltered. In the
+ For moment, always call this stream using *_unfiltered. In the
very near future that restriction shall be removed - either call
shall be unfiltered. (cagney 1999-07-02). */
extern struct ui_file *gdb_stdtarg;
-
-#if defined(TUI)
-#include "tui.h"
-#endif
+extern struct ui_file *gdb_stdtargerr;
+extern struct ui_file *gdb_stdtargin;
#include "ui-file.h"
@@ -639,6 +477,8 @@ extern void puts_filtered (const char *);
extern void puts_unfiltered (const char *);
+extern void puts_filtered_tabular (char *string, int width, int right);
+
extern void puts_debug (char *prefix, char *string, char *suffix);
extern void vprintf_filtered (const char *, va_list) ATTR_FORMAT (printf, 1, 0);
@@ -674,7 +514,7 @@ extern void fputstr_unfiltered (const char *str, int quotr, struct ui_file * str
extern void fputstrn_unfiltered (const char *str, int n, int quotr, struct ui_file * stream);
/* Display the host ADDR on STREAM formatted as ``0x%x''. */
-extern void gdb_print_host_address (void *addr, struct ui_file *stream);
+extern void gdb_print_host_address (const void *addr, struct ui_file *stream);
/* Convert a CORE_ADDR into a HEX string. paddr() is like %08lx.
paddr_nz() is like %lx. paddr_u() is like %lu. paddr_width() is
@@ -729,6 +569,8 @@ extern char *skip_quoted (char *);
extern char *gdb_readline (char *);
+extern char *gdb_readline_wrapper (char *);
+
extern char *command_line_input (char *, int, char *);
extern void print_prompt (void);
@@ -764,10 +606,16 @@ extern int source_full_path_of (char *, char **);
extern void mod_path (char *, char **);
+extern void add_path (char *, char **, int);
+
extern void directory_command (char *, int);
+extern char *source_path;
+
extern void init_source_path (void);
+extern void init_last_source_visited (void);
+
extern char *symtab_to_filename (struct symtab *);
/* From exec.c */
@@ -783,10 +631,6 @@ extern void exec_set_find_memory_regions (int (*) (int (*) (CORE_ADDR,
void *),
void *));
-/* From findvar.c */
-
-extern int read_relative_register_raw_bytes (int, char *);
-
/* Possible lvalue types. Like enum language, this should be in
value.h, but needs to be here for the same reason. */
@@ -808,12 +652,6 @@ enum lval_type
lval_reg_frame_relative
};
-struct frame_info;
-
-/* From readline (but not in any readline .h files). */
-
-extern char *tilde_expand (char *);
-
/* Control types for commands */
enum misc_command_type
@@ -970,16 +808,6 @@ typedef struct ptid ptid_t;
#include "tm.h"
#endif
-/* GDB_MULTI_ARCH is normally set by configure.in using information
- from configure.tgt or the config/%/%.mt Makefile fragment. Since
- some targets have defined it in their "tm.h" file, delay providing
- a default definition until after "tm.h" has been included.. */
-
-#ifndef GDB_MULTI_ARCH
-#define GDB_MULTI_ARCH 0
-#endif
-
-
/* If the xm.h file did not define the mode string used to open the
files, assume that binary files are opened the same way as text
files */
@@ -1044,11 +872,21 @@ extern void xmfree (void *md, void *ptr);
"libiberty.h". */
extern void xfree (void *);
+/* Utility macros to allocate typed memory. Avoids errors like:
+ struct foo *foo = xmalloc (sizeof struct bar); and memset (foo,
+ sizeof (struct foo), 0). */
+#define XZALLOC(TYPE) ((TYPE*) memset (xmalloc (sizeof (TYPE)), 0, sizeof (TYPE)))
+#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
+#define XCALLOC(NMEMB, TYPE) ((TYPE*) xcalloc ((NMEMB), sizeof (TYPE)))
+
/* Like asprintf/vasprintf but get an internal_error if the call
fails. */
extern void xasprintf (char **ret, const char *format, ...) ATTR_FORMAT (printf, 2, 3);
extern void xvasprintf (char **ret, const char *format, va_list ap);
+/* Like asprintf, but return the string, throw an error if no memory. */
+extern char *xstrprintf (const char *format, ...) ATTR_FORMAT (printf, 1, 2);
+
extern int parse_escape (char **);
/* Message to be printed before the error message, when an error occurs. */
@@ -1065,20 +903,34 @@ extern char *warning_pre_print;
extern NORETURN void verror (const char *fmt, va_list ap) ATTR_NORETURN;
-extern NORETURN void error (const char *fmt, ...) ATTR_NORETURN;
+extern NORETURN void error (const char *fmt, ...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
+
+extern NORETURN void error_silent (const char *fmt, ...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
extern NORETURN void error_stream (struct ui_file *) ATTR_NORETURN;
+/* Initialize the error buffer. */
+extern void error_init (void);
+
/* Returns a freshly allocate buffer containing the last error
message. */
extern char *error_last_message (void);
+/* Output arbitrary error message. */
+extern void error_output_message (char *pre_print, char *msg);
+
extern NORETURN void internal_verror (const char *file, int line,
const char *, va_list ap) ATTR_NORETURN;
extern NORETURN void internal_error (const char *file, int line,
const char *, ...) ATTR_NORETURN ATTR_FORMAT (printf, 3, 4);
+extern void internal_vwarning (const char *file, int line,
+ const char *, va_list ap);
+
+extern void internal_warning (const char *file, int line,
+ const char *, ...) ATTR_FORMAT (printf, 3, 4);
+
extern NORETURN void nomem (long) ATTR_NORETURN;
/* Reasons for calling throw_exception(). NOTE: all reason values
@@ -1129,6 +981,11 @@ extern NORETURN void throw_exception (enum return_reason) ATTR_NORETURN;
new cleanup_chain is established. The old values are restored
before catch_exceptions() returns.
+ The variant catch_exceptions_with_msg() is the same as
+ catch_exceptions() but adds the ability to return an allocated
+ copy of the gdb error message. This is used when a silent error is
+ issued and the caller wants to manually issue the error message.
+
FIXME; cagney/2001-08-13: The need to override the global UIOUT
builder variable should just go away.
@@ -1141,6 +998,11 @@ typedef int (catch_exceptions_ftype) (struct ui_out *ui_out, void *args);
extern int catch_exceptions (struct ui_out *uiout,
catch_exceptions_ftype *func, void *func_args,
char *errstring, return_mask mask);
+extern int catch_exceptions_with_msg (struct ui_out *uiout,
+ catch_exceptions_ftype *func,
+ void *func_args,
+ char *errstring, char **gdberrmsg,
+ return_mask mask);
/* If CATCH_ERRORS_FTYPE throws an error, catch_errors() returns zero
otherwize the result from CATCH_ERRORS_FTYPE is returned. It is
@@ -1151,7 +1013,7 @@ extern int catch_exceptions (struct ui_out *uiout,
This function is superseeded by catch_exceptions(). */
-typedef int (catch_errors_ftype) (PTR);
+typedef int (catch_errors_ftype) (void *);
extern int catch_errors (catch_errors_ftype *, void *, char *, return_mask);
/* Template to catch_errors() that wraps calls to command
@@ -1164,6 +1026,43 @@ extern void warning (const char *, ...) ATTR_FORMAT (printf, 1, 2);
extern void vwarning (const char *, va_list args);
+/* List of known OS ABIs. If you change this, make sure to update the
+ table in osabi.c. */
+enum gdb_osabi
+{
+ GDB_OSABI_UNINITIALIZED = -1, /* For struct gdbarch_info. */
+
+ GDB_OSABI_UNKNOWN = 0, /* keep this zero */
+
+ GDB_OSABI_SVR4,
+ GDB_OSABI_HURD,
+ GDB_OSABI_SOLARIS,
+ GDB_OSABI_OSF1,
+ GDB_OSABI_LINUX,
+ GDB_OSABI_FREEBSD_AOUT,
+ GDB_OSABI_FREEBSD_ELF,
+ GDB_OSABI_NETBSD_AOUT,
+ GDB_OSABI_NETBSD_ELF,
+ GDB_OSABI_OPENBSD_ELF,
+ GDB_OSABI_WINCE,
+ GDB_OSABI_GO32,
+ GDB_OSABI_NETWARE,
+ GDB_OSABI_IRIX,
+ GDB_OSABI_LYNXOS,
+ GDB_OSABI_INTERIX,
+ GDB_OSABI_HPUX_ELF,
+ GDB_OSABI_HPUX_SOM,
+
+ GDB_OSABI_ARM_EABI_V1,
+ GDB_OSABI_ARM_EABI_V2,
+ GDB_OSABI_ARM_APCS,
+ GDB_OSABI_QNXNTO,
+
+ GDB_OSABI_CYGWIN,
+
+ GDB_OSABI_INVALID /* keep this last */
+};
+
/* Global functions from other, non-gdb GNU thingies.
Libiberty thingies are no longer declared here. We include libiberty.h
above, instead. */
@@ -1223,14 +1122,22 @@ extern void *alloca ();
#endif /* Not GNU C */
#endif /* alloca not defined */
+/* Is GDB multi-arch? If there's a "tm.h" file, it is not. */
+#ifndef GDB_MULTI_ARCH
+#ifdef GDB_TM_FILE
+#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL
+#else
+#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PURE
+#endif
+#endif
+
/* Dynamic target-system-dependent parameters for GDB. */
#include "gdbarch.h"
-#if (GDB_MULTI_ARCH == 0)
-/* Multi-arch targets _should_ be including "arch-utils.h" directly
- into their *-tdep.c file. This is a prop to help old non-
- multi-arch targets to continue to compile. */
-#include "arch-utils.h"
-#endif
+
+/* Maximum size of a register. Something small, but large enough for
+ all known ISAs. If it turns out to be too small, make it bigger. */
+
+enum { MAX_REGISTER_SIZE = 16 };
/* Static target-system-dependent parameters for GDB. */
@@ -1261,22 +1168,18 @@ extern void *alloca ();
/* In findvar.c. */
-extern LONGEST extract_signed_integer (void *, int);
+extern LONGEST extract_signed_integer (const void *, int);
-extern ULONGEST extract_unsigned_integer (void *, int);
+extern ULONGEST extract_unsigned_integer (const void *, int);
-extern int extract_long_unsigned_integer (void *, int, LONGEST *);
+extern int extract_long_unsigned_integer (const void *, int, LONGEST *);
-extern CORE_ADDR extract_address (void *, int);
-
-extern CORE_ADDR extract_typed_address (void *buf, struct type *type);
+extern CORE_ADDR extract_typed_address (const void *buf, struct type *type);
extern void store_signed_integer (void *, int, LONGEST);
extern void store_unsigned_integer (void *, int, ULONGEST);
-extern void store_address (void *, int, LONGEST);
-
extern void store_typed_address (void *buf, struct type *type, CORE_ADDR addr);
@@ -1397,4 +1300,36 @@ extern int use_windows;
#define ISATTY(FP) (isatty (fileno (FP)))
#endif
+/* Ensure that V is aligned to an N byte boundary (B's assumed to be a
+ power of 2). Round up/down when necessary. Examples of correct
+ use include:
+
+ addr = align_up (addr, 8); -- VALUE needs 8 byte alignment
+ write_memory (addr, value, len);
+ addr += len;
+
+ and:
+
+ sp = align_down (sp - len, 16); -- Keep SP 16 byte aligned
+ write_memory (sp, value, len);
+
+ Note that uses such as:
+
+ write_memory (addr, value, len);
+ addr += align_up (len, 8);
+
+ and:
+
+ sp -= align_up (len, 8);
+ write_memory (sp, value, len);
+
+ are typically not correct as they don't ensure that the address (SP
+ or ADDR) is correctly aligned (relying on previous alignment to
+ keep things right). This is also why the methods are called
+ "align_..." instead of "round_..." as the latter reads better with
+ this incorrect coding style. */
+
+extern ULONGEST align_up (ULONGEST v, int n);
+extern ULONGEST align_down (ULONGEST v, int n);
+
#endif /* #ifndef DEFS_H */
diff --git a/contrib/gdb/gdb/demangle.c b/contrib/gdb/gdb/demangle.c
index 1fd69be..bcf9b77 100644
--- a/contrib/gdb/gdb/demangle.c
+++ b/contrib/gdb/gdb/demangle.c
@@ -1,6 +1,8 @@
/* Basic C++ demangling support for GDB.
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
- Free Software Foundation, Inc.
+
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+ 2001, 2003 Free Software Foundation, Inc.
+
Written by Fred Fish at Cygnus Support.
This file is part of GDB.
@@ -87,8 +89,8 @@ set_demangling_command (char *ignore, int from_tty, struct cmd_list_element *c)
dem->demangling_style != unknown_demangling;
dem++)
{
- if (STREQ (current_demangling_style_string,
- dem->demangling_style_name))
+ if (strcmp (current_demangling_style_string,
+ dem->demangling_style_name) == 0)
{
current_demangling_style = dem->demangling_style;
break;
@@ -150,24 +152,18 @@ set_demangling_style (char *style)
set_demangling_command ((char *) NULL, 0, (struct cmd_list_element *) NULL);
}
-/* In order to allow a single demangler executable to demangle strings
- using various common values of CPLUS_MARKER, as well as any specific
- one set at compile time, we maintain a string containing all the
- commonly used ones, and check to see if the marker we are looking for
- is in that string. CPLUS_MARKER is usually '$' on systems where the
- assembler can deal with that. Where the assembler can't, it's usually
- '.' (but on many systems '.' is used for other things). We put the
- current defined CPLUS_MARKER first (which defaults to '$'), followed
- by the next most common value, followed by an explicit '$' in case
- the value of CPLUS_MARKER is not '$'.
-
- We could avoid this if we could just get g++ to tell us what the actual
- cplus marker character is as part of the debug information, perhaps by
- ensuring that it is the character that terminates the gcc<n>_compiled
- marker symbol (FIXME). */
-
-static char cplus_markers[] =
-{CPLUS_MARKER, '.', '$', '\0'};
+/* G++ uses a special character to indicate certain internal names. Which
+ character it is depends on the platform:
+ - Usually '$' on systems where the assembler will accept that
+ - Usually '.' otherwise (this includes most sysv4-like systems and most
+ ELF targets)
+ - Occasionally '_' if neither of the above is usable
+
+ We check '$' first because it is the safest, and '.' often has another
+ meaning. We don't currently try to handle '_' because the precise forms
+ of the names are different on those targets. */
+
+static char cplus_markers[] = {'$', '.', '\0'};
int
is_cplus_marker (int c)
@@ -204,5 +200,4 @@ Use `set demangle-style' without arguments for a list of demangling styles.",
/* Set the default demangling style chosen at compilation time. */
set_demangling_style (DEFAULT_DEMANGLING_STYLE);
- set_cplus_marker_for_demangling (CPLUS_MARKER);
}
diff --git a/contrib/gdb/gdb/doc/gdb.texinfo b/contrib/gdb/gdb/doc/gdb.texinfo
index 04a0624..772d1eb 100644
--- a/contrib/gdb/gdb/doc/gdb.texinfo
+++ b/contrib/gdb/gdb/doc/gdb.texinfo
@@ -1,6 +1,6 @@
\input texinfo @c -*-texinfo-*-
@c Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
-@c 1999, 2000, 2001, 2002
+@c 1999, 2000, 2001, 2002, 2003, 2004
@c Free Software Foundation, Inc.
@c
@c %**start of header
@@ -28,30 +28,31 @@
@syncodeindex fn cp
@c !!set GDB manual's edition---not the same as GDB version!
+@c This is updated by GNU Press.
@set EDITION Ninth
-@c !!set GDB manual's revision date
-@set DATE December 2001
+@c !!set GDB edit command default editor
+@set EDITOR /bin/ex
@c THIS MANUAL REQUIRES TEXINFO 4.0 OR LATER.
@c This is a dir.info fragment to support semi-automated addition of
@c manuals to an info tree.
-@dircategory Programming & development tools.
+@dircategory Software development
@direntry
-* Gdb: (gdb). The @sc{gnu} debugger.
+* Gdb: (gdb). The GNU debugger.
@end direntry
@ifinfo
This file documents the @sc{gnu} debugger @value{GDBN}.
-This is the @value{EDITION} Edition, @value{DATE},
-of @cite{Debugging with @value{GDBN}: the @sc{gnu} Source-Level Debugger}
-for @value{GDBN} Version @value{GDBVN}.
+This is the @value{EDITION} Edition, of @cite{Debugging with
+@value{GDBN}: the @sc{gnu} Source-Level Debugger} for @value{GDBN}
+Version @value{GDBVN}.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,@*
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
@@ -71,7 +72,6 @@ development.''
@subtitle The @sc{gnu} Source-Level Debugger
@sp 1
@subtitle @value{EDITION} Edition, for @value{GDBN} version @value{GDBVN}
-@subtitle @value{DATE}
@author Richard Stallman, Roland Pesch, Stan Shebs, et al.
@page
@tex
@@ -84,7 +84,7 @@ development.''
@vskip 0pt plus 1filll
Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
@sp 2
Published by the Free Software Foundation @*
59 Temple Place - Suite 330, @*
@@ -112,10 +112,10 @@ development.''
This file describes @value{GDBN}, the @sc{gnu} symbolic debugger.
-This is the @value{EDITION} Edition, @value{DATE}, for @value{GDBN} Version
+This is the @value{EDITION} Edition, for @value{GDBN} Version
@value{GDBVN}.
-Copyright (C) 1988-2002 Free Software Foundation, Inc.
+Copyright (C) 1988-2004 Free Software Foundation, Inc.
@menu
* Summary:: Summary of @value{GDBN}
@@ -128,6 +128,7 @@ Copyright (C) 1988-2002 Free Software Foundation, Inc.
* Stack:: Examining the stack
* Source:: Examining source files
* Data:: Examining data
+* Macros:: Preprocessor Macros
* Tracepoints:: Debugging remote targets non-intrusively
* Overlays:: Debugging programs that use overlays
@@ -142,6 +143,7 @@ Copyright (C) 1988-2002 Free Software Foundation, Inc.
* Controlling GDB:: Controlling @value{GDBN}
* Sequences:: Canned sequences of commands
* TUI:: @value{GDBN} Text User Interface
+* Interpreters:: Command Interpreters
* Emacs:: Using @value{GDBN} under @sc{gnu} Emacs
* Annotations:: @value{GDBN}'s annotation interface.
* GDB/MI:: @value{GDBN}'s Machine Interface.
@@ -154,6 +156,7 @@ Copyright (C) 1988-2002 Free Software Foundation, Inc.
* Installing GDB:: Installing GDB
* Maintenance Commands:: Maintenance Commands
* Remote Protocol:: GDB Remote Serial Protocol
+* Agent Expressions:: The GDB Agent Expression Mechanism
* Copying:: GNU General Public License says
how you can copy and share GDB
* GNU Free Documentation License:: The license for this documentation
@@ -189,14 +192,13 @@ Change things in your program, so you can experiment with correcting the
effects of one bug and go on to learn about another.
@end itemize
-You can use @value{GDBN} to debug programs written in C and C++.
+You can use @value{GDBN} to debug programs written in C and C@t{++}.
For more information, see @ref{Support,,Supported languages}.
For more information, see @ref{C,,C and C++}.
-@cindex Chill
@cindex Modula-2
-Support for Modula-2 and Chill is partial. For information on Modula-2,
-see @ref{Modula-2,,Modula-2}. For information on Chill, see @ref{Chill}.
+Support for Modula-2 is partial. For information on Modula-2, see
+@ref{Modula-2,,Modula-2}.
@cindex Pascal
Debugging Pascal programs which use sets, subranges, file variables, or
@@ -209,6 +211,9 @@ syntax.
it may be necessary to refer to some variables with a trailing
underscore.
+@value{GDBN} can be used to debug programs written in Objective-C,
+using either the Apple/NeXT or the GNU Objective-C runtime.
+
@menu
* Free Software:: Freely redistributable software
* Contributors:: Contributors to GDB
@@ -342,7 +347,7 @@ omitted from this list, we would like to add your names!
So that they may not regard their many labors as thankless, we
particularly thank those who shepherded @value{GDBN} through major
releases:
-Andrew Cagney (releases 5.0 and 5.1);
+Andrew Cagney (releases 6.1, 6.0, 5.3, 5.2, 5.1 and 5.0);
Jim Blandy (release 4.18);
Jason Molenda (release 4.17);
Stan Shebs (release 4.14);
@@ -368,7 +373,7 @@ Henkel-Wallace, Rich Pixley, Steve Chamberlain, and John Gilmore.
David Johnson wrote the original COFF support; Pace Willison did
the original support for encapsulated COFF.
-Brent Benson of Harris Computer Systems contributed DWARF2 support.
+Brent Benson of Harris Computer Systems contributed DWARF 2 support.
Adam de Boor and Bradley Davis contributed the ISI Optimum V support.
Per Bothner, Noboyuki Hikichi, and Alessandro Forin contributed MIPS
@@ -388,8 +393,9 @@ Michael Tiemann contributed SPARC support.
Tim Tucker contributed support for the Gould NP1 and Gould Powernode.
Pace Willison contributed Intel 386 support.
Jay Vosburgh contributed Symmetry support.
+Marko Mlinar contributed OpenRISC 1000 support.
-Andreas Schwab contributed M68K Linux support.
+Andreas Schwab contributed M68K @sc{gnu}/Linux support.
Rich Schaefer and Peter Schauer helped with support of SunOS shared
libraries.
@@ -412,12 +418,13 @@ Fred Fish wrote most of the support for Unix System Vr4.
He also enhanced the command-completion support to cover C@t{++} overloaded
symbols.
-Hitachi America, Ltd. sponsored the support for H8/300, H8/500, and
-Super-H processors.
+Hitachi America (now Renesas America), Ltd. sponsored the support for
+H8/300, H8/500, and Super-H processors.
NEC sponsored the support for the v850, Vr4xxx, and Vr5xxx processors.
-Mitsubishi sponsored the support for D10V, D30V, and M32R/D processors.
+Mitsubishi (now Renesas) sponsored the support for D10V, D30V, and M32R/D
+processors.
Toshiba sponsored the support for the TX39 Mips processor.
@@ -438,10 +445,10 @@ nearly innumerable bug fixes and cleanups throughout @value{GDBN}.
The following people at the Hewlett-Packard Company contributed
support for the PA-RISC 2.0 architecture, HP-UX 10.20, 10.30, and 11.0
(narrow mode), HP's implementation of kernel threads, HP's aC@t{++}
-compiler, and the terminal user interface: Ben Krepp, Richard Title,
-John Bishop, Susan Macchia, Kathy Mann, Satish Pai, India Paul, Steve
-Rehrauer, and Elena Zannoni. Kim Haase provided HP-specific
-information in this manual.
+compiler, and the Text User Interface (nee Terminal User Interface):
+Ben Krepp, Richard Title, John Bishop, Susan Macchia, Kathy Mann,
+Satish Pai, India Paul, Steve Rehrauer, and Elena Zannoni. Kim Haase
+provided HP-specific information in this manual.
DJ Delorie ported @value{GDBN} to MS-DOS, for the DJGPP project.
Robert Hoehne made significant contributions to the DJGPP port.
@@ -462,6 +469,8 @@ Romig-Koch, Rob Savoye, Jamie Smith, Mike Stump, Ian Taylor, Angela
Thomas, Michael Tiemann, Tom Tromey, Ron Unrau, Jim Wilson, and David
Zuhn have made contributions both large and small.
+Jim Blandy added support for preprocessor macros, while working for Red
+Hat.
@node Sample Session
@chapter A Sample @value{GDBN} Session
@@ -749,6 +758,7 @@ type @kbd{quit} or @kbd{C-d} to exit.
* Invoking GDB:: How to start @value{GDBN}
* Quitting GDB:: How to quit @value{GDBN}
* Shell Commands:: How to use shell commands inside @value{GDBN}
+* Logging output:: How to log @value{GDBN}'s output to a file
@end menu
@node Invoking GDB
@@ -767,24 +777,24 @@ options may effectively be unavailable.
The most usual way to start @value{GDBN} is with one argument,
specifying an executable program:
-@example
+@smallexample
@value{GDBP} @var{program}
-@end example
+@end smallexample
@noindent
You can also start with both an executable program and a core file
specified:
-@example
+@smallexample
@value{GDBP} @var{program} @var{core}
-@end example
+@end smallexample
You can, instead, specify a process ID as a second argument, if you want
to debug a running process:
-@example
+@smallexample
@value{GDBP} @var{program} 1234
-@end example
+@end smallexample
@noindent
would attach @value{GDBN} to process @code{1234} (unless you also have a file
@@ -799,9 +809,9 @@ will warn you if it is unable to attach or to read core dumps.
You can optionally have @code{@value{GDBP}} pass any arguments after the
executable file to the inferior using @code{--args}. This option stops
option processing.
-@example
+@smallexample
gdb --args gcc -O2 -c foo.c
-@end example
+@end smallexample
This will cause @code{@value{GDBP}} to debug @code{gcc}, and to set
@code{gcc}'s command-line arguments (@pxref{Arguments}) to @samp{-O2 -c foo.c}.
@@ -819,9 +829,9 @@ options. @value{GDBN} itself can remind you of the options available.
@noindent
Type
-@example
+@smallexample
@value{GDBP} -help
-@end example
+@end smallexample
@noindent
to display all available options and briefly describe their use
@@ -851,7 +861,7 @@ equivalent to the @samp{-c}/@samp{-p} option followed by that argument.)
If the second argument begins with a decimal digit, @value{GDBN} will
first attempt to attach to it as a process, and if that fails, attempt
to open it as a corefile. If you have a corefile whose name begins with
-a digit, you can prevent @value{GDBN} from treating it as a pid by
+a digit, you can prevent @value{GDBN} from treating it as a pid by
prefixing it with @file{./}, eg. @file{./12345}.
If @value{GDBN} has not been configured to included core file support,
@@ -891,7 +901,7 @@ file.
@itemx -c @var{file}
@cindex @code{--core}
@cindex @code{-c}
-Use file @var{file} as a core dump to examine.
+Use file @var{file} as a core dump to examine.
@item -c @var{number}
@item -pid @var{number}
@@ -950,9 +960,9 @@ information. (@xref{Files,,Commands to specify files}, for information
on @file{.syms} files.) A simple @value{GDBN} invocation to do nothing
but build a @file{.syms} file for future use is:
-@example
+@smallexample
gdb -batch -nx -mapped -readnow programname
-@end example
+@end smallexample
@node Mode Options
@subsection Choosing modes
@@ -991,9 +1001,9 @@ Batch mode may be useful for running @value{GDBN} as a filter, for
example to download and run a program on another computer; in order to
make this more useful, the message
-@example
+@smallexample
Program exited normally.
-@end example
+@end smallexample
@noindent
(which is ordinarily issued whenever a program running under
@@ -1045,12 +1055,15 @@ separate window.
@cindex @code{--annotate}
This option sets the @dfn{annotation level} inside @value{GDBN}. Its
effect is identical to using @samp{set annotate @var{level}}
-(@pxref{Annotations}).
-Annotation level controls how much information does @value{GDBN} print
-together with its prompt, values of expressions, source lines, and other
-types of output. Level 0 is the normal, level 1 is for use when
-@value{GDBN} is run as a subprocess of @sc{gnu} Emacs, level 2 is the
-maximum annotation suitable for programs that control @value{GDBN}.
+(@pxref{Annotations}). The annotation @var{level} controls how much
+information @value{GDBN} prints together with its prompt, values of
+expressions, source lines, and other types of output. Level 0 is the
+normal, level 1 is for use when @value{GDBN} is run as a subprocess of
+@sc{gnu} Emacs, level 3 is the maximum annotation suitable for programs
+that control @value{GDBN}, and level 2 has been deprecated.
+
+The annotation mechanism has largely been superseeded by @sc{gdb/mi}
+(@pxref{GDB/MI}).
@item -async
@cindex @code{--async}
@@ -1099,12 +1112,13 @@ Run using @var{device} for your program's standard input and output.
@c resolve the situation of these eventually
@item -tui
@cindex @code{--tui}
-Activate the Terminal User Interface when starting.
-The Terminal User Interface manages several text windows on the terminal,
-showing source, assembly, registers and @value{GDBN} command outputs
-(@pxref{TUI, ,@value{GDBN} Text User Interface}).
-Do not use this option if you run @value{GDBN} from Emacs
-(@pxref{Emacs, ,Using @value{GDBN} under @sc{gnu} Emacs}).
+Activate the @dfn{Text User Interface} when starting. The Text User
+Interface manages several text windows on the terminal, showing
+source, assembly, registers and @value{GDBN} command outputs
+(@pxref{TUI, ,@value{GDBN} Text User Interface}). Alternatively, the
+Text User Interface can be enabled by invoking the program
+@samp{gdbtui}. Do not use this option if you run @value{GDBN} from
+Emacs (@pxref{Emacs, ,Using @value{GDBN} under @sc{gnu} Emacs}).
@c @item -xdb
@c @cindex @code{--xdb}
@@ -1118,11 +1132,14 @@ Do not use this option if you run @value{GDBN} from Emacs
Use the interpreter @var{interp} for interface with the controlling
program or device. This option is meant to be set by programs which
communicate with @value{GDBN} using it as a back end.
+@xref{Interpreters, , Command Interpreters}.
-@samp{--interpreter=mi} (or @samp{--interpreter=mi1}) causes
-@value{GDBN} to use the @dfn{gdb/mi interface} (@pxref{GDB/MI, , The
-@sc{gdb/mi} Interface}). The older @sc{gdb/mi} interface, included in
-@value{GDBN} version 5.0 can be selected with @samp{--interpreter=mi0}.
+@samp{--interpreter=mi} (or @samp{--interpreter=mi2}) causes
+@value{GDBN} to use the @dfn{@sc{gdb/mi} interface} (@pxref{GDB/MI, ,
+The @sc{gdb/mi} Interface}) included since @var{GDBN} version 6.0. The
+previous @sc{gdb/mi} interface, included in @value{GDBN} version 5.3 and
+selected with @samp{--interpreter=mi1}, is deprecated. Earlier
+@sc{gdb/mi} interfaces are no longer supported.
@item -write
@cindex @code{--write}
@@ -1199,6 +1216,32 @@ Execute the @code{make} program with the specified
arguments. This is equivalent to @samp{shell make @var{make-args}}.
@end table
+@node Logging output
+@section Logging output
+@cindex logging @value{GDBN} output
+
+You may want to save the output of @value{GDBN} commands to a file.
+There are several commands to control @value{GDBN}'s logging.
+
+@table @code
+@kindex set logging
+@item set logging on
+Enable logging.
+@item set logging off
+Disable logging.
+@item set logging file @var{file}
+Change the name of the current logfile. The default logfile is @file{gdb.txt}.
+@item set logging overwrite [on|off]
+By default, @value{GDBN} will append to the logfile. Set @code{overwrite} if
+you want @code{set logging on} to overwrite the logfile instead.
+@item set logging redirect [on|off]
+By default, @value{GDBN} output will go to both the terminal and the logfile.
+Set @code{redirect} if you want output to go only to the log file.
+@kindex show logging
+@item show logging
+Show the current values of the logging settings.
+@end table
+
@node Commands
@chapter @value{GDBN} Commands
@@ -1283,17 +1326,17 @@ enter it). For example, if you type
@c complete accuracy in these examples; space introduced for clarity.
@c If texinfo enhancements make it unnecessary, it would be nice to
@c replace " @key" by "@key" in the following...
-@example
+@smallexample
(@value{GDBP}) info bre @key{TAB}
-@end example
+@end smallexample
@noindent
@value{GDBN} fills in the rest of the word @samp{breakpoints}, since that is
the only @code{info} subcommand beginning with @samp{bre}:
-@example
+@smallexample
(@value{GDBP}) info breakpoints
-@end example
+@end smallexample
@noindent
You can either press @key{RET} at this point, to run the @code{info
@@ -1313,7 +1356,7 @@ just sounds the bell. Typing @key{TAB} again displays all the
function names in your program that begin with those characters, for
example:
-@example
+@smallexample
(@value{GDBP}) b make_ @key{TAB}
@exdent @value{GDBN} sounds bell; press @key{TAB} again, to see:
make_a_section_from_file make_environ
@@ -1322,7 +1365,7 @@ make_blockvector make_pointer_type
make_cleanup make_reference_type
make_command make_symbol_completion_list
(@value{GDBP}) b make_
-@end example
+@end smallexample
@noindent
After displaying the available possibilities, @value{GDBN} copies your
@@ -1355,22 +1398,22 @@ word-completion facilities in this situation, type a single quote
@value{GDBN} that it may need to consider more information than usual
when you press @key{TAB} or @kbd{M-?} to request word completion:
-@example
+@smallexample
(@value{GDBP}) b 'bubble( @kbd{M-?}
bubble(double,double) bubble(int,int)
(@value{GDBP}) b 'bubble(
-@end example
+@end smallexample
In some cases, @value{GDBN} can tell that completing a name requires using
quotes. When this happens, @value{GDBN} inserts the quote for you (while
completing as much as it can) if you do not type the quote in the first
place:
-@example
+@smallexample
(@value{GDBP}) b bub @key{TAB}
@exdent @value{GDBN} alters your input line to the following, and rings a bell:
(@value{GDBP}) b 'bubble(
-@end example
+@end smallexample
@noindent
In general, @value{GDBN} can tell that a quote is needed (and inserts it) if
@@ -1609,6 +1652,16 @@ and addresses in the executable code.
To request debugging information, specify the @samp{-g} option when you run
the compiler.
+Most compilers do not include information about preprocessor macros in
+the debugging information if you specify the @option{-g} flag alone,
+because this information is rather large. Version 3.1 of @value{NGCC},
+the @sc{gnu} C compiler, provides macro information if you specify the
+options @option{-gdwarf-2} and @option{-g3}; the former option requests
+debugging information in the Dwarf 2 format, and the latter requests
+``extra information''. In the future, we hope to find more compact ways
+to represent macro information, so that it can be included with
+@option{-g} alone.
+
Many C compilers are unable to handle the @samp{-g} and @samp{-O}
options together. Using those compilers, you cannot generate optimized
executables containing debugging information.
@@ -1806,9 +1859,9 @@ null value.
For example, this command:
-@example
+@smallexample
set env USER = foo
-@end example
+@end smallexample
@noindent
tells the debugged program, when subsequently run, that its user is named
@@ -1879,9 +1932,9 @@ program is using.
You can redirect your program's input and/or output using shell
redirection with the @code{run} command. For example,
-@example
+@smallexample
run > outfile
-@end example
+@end smallexample
@noindent
starts your program, diverting its output to the file @file{outfile}.
@@ -1894,9 +1947,9 @@ argument, and causes this file to be the default for future @code{run}
commands. It also resets the controlling terminal for the child
process, for future @code{run} commands. For example,
-@example
+@smallexample
tty /dev/ttyb
-@end example
+@end smallexample
@noindent
directs that processes started with subsequent @code{run} commands
@@ -2055,9 +2108,9 @@ form @samp{[New @var{systag}]}. @var{systag} is a thread identifier
whose form varies depending on the particular system. For example, on
LynxOS, you might see
-@example
+@smallexample
[New process 35 thread 27]
-@end example
+@end smallexample
@noindent
when @value{GDBN} notices a new thread. In contrast, on an SGI system,
@@ -2126,9 +2179,9 @@ form @samp{[New @var{systag}]}. @var{systag} is a thread identifier
whose form varies depending on the particular system. For example, on
HP-UX, you see
-@example
+@smallexample
[New thread 2 (system thread 26594)]
-@end example
+@end smallexample
@noindent
when @value{GDBN} notices a new thread.
@@ -2155,7 +2208,7 @@ For example,
@end table
@c end table here to get a little more width for example
-@example
+@smallexample
(@value{GDBP}) info threads
* 3 system thread 26607 worker (wptr=0x7b09c318 "@@") \@*
at quicksort.c:137
@@ -2163,7 +2216,7 @@ For example,
from /usr/lib/libc.2
1 system thread 27905 0x7b003498 in _brk () \@*
from /usr/lib/libc.2
-@end example
+@end smallexample
@table @code
@kindex thread @var{threadno}
@@ -2237,9 +2290,10 @@ get its process ID. Then tell @value{GDBN} (a new invocation of
the child process (@pxref{Attach}). From that point on you can debug
the child process just like any other process which you attached to.
-On HP-UX (11.x and later only?), @value{GDBN} provides support for
-debugging programs that create additional processes using the
-@code{fork} or @code{vfork} function.
+On some systems, @value{GDBN} provides support for debugging programs that
+create additional processes using the @code{fork} or @code{vfork} functions.
+Currently, the only platforms with this feature are HP-UX (11.x and later
+only?) and GNU/Linux (kernel version 2.5.60 and later).
By default, when a program forks, @value{GDBN} will continue to debug
the parent process and the child process will run unimpeded.
@@ -2263,8 +2317,6 @@ unimpeded. This is the default.
The new process is debugged after a fork. The parent process runs
unimpeded.
-@item ask
-The debugger will ask for one of the above choices.
@end table
@item show follow-fork-mode
@@ -2390,6 +2442,7 @@ all breakpoint in that range are operated on.
* Break Commands:: Breakpoint command lists
* Breakpoint Menus:: Breakpoint menus
* Error in Breakpoints:: ``Cannot insert breakpoints''
+* Breakpoint related warnings:: ``Breakpoint address adjusted...''
@end menu
@node Set Breaks
@@ -2494,6 +2547,8 @@ example, on the DSU, only two data breakpoints can be set at a time, and
@value{GDBN} will reject this command if more than two are used. Delete
or disable unused hardware breakpoints before setting new ones
(@pxref{Disabling, ,Disabling}). @xref{Conditions, ,Break conditions}.
+@xref{set remote hardware-breakpoint-limit}.
+
@kindex thbreak
@item thbreak @var{args}
@@ -2545,16 +2600,23 @@ Whether the breakpoint is marked to be disabled or deleted when hit.
Enabled breakpoints are marked with @samp{y}. @samp{n} marks breakpoints
that are not enabled.
@item Address
-Where the breakpoint is in your program, as a memory address.
+Where the breakpoint is in your program, as a memory address. If the
+breakpoint is pending (see below for details) on a future load of a shared library, the address
+will be listed as @samp{<PENDING>}.
@item What
Where the breakpoint is in the source for your program, as a file and
-line number.
+line number. For a pending breakpoint, the original string passed to
+the breakpoint command will be listed as it cannot be resolved until
+the appropriate shared library is loaded in the future.
@end table
@noindent
If a breakpoint is conditional, @code{info break} shows the condition on
the line following the affected breakpoint; breakpoint commands, if any,
-are listed after that.
+are listed after that. A pending breakpoint is allowed to have a condition
+specified for it. The condition is not parsed for validity until a shared
+library is loaded that allows the pending breakpoint to resolve to a
+valid location.
@noindent
@code{info break} with a breakpoint
@@ -2577,6 +2639,58 @@ your program. There is nothing silly or meaningless about this. When
the breakpoints are conditional, this is even useful
(@pxref{Conditions, ,Break conditions}).
+@cindex pending breakpoints
+If a specified breakpoint location cannot be found, it may be due to the fact
+that the location is in a shared library that is yet to be loaded. In such
+a case, you may want @value{GDBN} to create a special breakpoint (known as
+a @dfn{pending breakpoint}) that
+attempts to resolve itself in the future when an appropriate shared library
+gets loaded.
+
+Pending breakpoints are useful to set at the start of your
+@value{GDBN} session for locations that you know will be dynamically loaded
+later by the program being debugged. When shared libraries are loaded,
+a check is made to see if the load resolves any pending breakpoint locations.
+If a pending breakpoint location gets resolved,
+a regular breakpoint is created and the original pending breakpoint is removed.
+
+@value{GDBN} provides some additional commands for controlling pending
+breakpoint support:
+
+@kindex set breakpoint pending
+@kindex show breakpoint pending
+@table @code
+@item set breakpoint pending auto
+This is the default behavior. When @value{GDBN} cannot find the breakpoint
+location, it queries you whether a pending breakpoint should be created.
+
+@item set breakpoint pending on
+This indicates that an unrecognized breakpoint location should automatically
+result in a pending breakpoint being created.
+
+@item set breakpoint pending off
+This indicates that pending breakpoints are not to be created. Any
+unrecognized breakpoint location results in an error. This setting does
+not affect any pending breakpoints previously created.
+
+@item show breakpoint pending
+Show the current behavior setting for creating pending breakpoints.
+@end table
+
+@cindex operations allowed on pending breakpoints
+Normal breakpoint operations apply to pending breakpoints as well. You may
+specify a condition for a pending breakpoint and/or commands to run when the
+breakpoint is reached. You can also enable or disable
+the pending breakpoint. When you specify a condition for a pending breakpoint,
+the parsing of the condition will be deferred until the point where the
+pending breakpoint location is resolved. Disabling a pending breakpoint
+tells @value{GDBN} to not attempt to resolve the breakpoint on any subsequent
+shared library load. When a pending breakpoint is re-enabled,
+@value{GDBN} checks to see if the location is already resolved.
+This is done because any number of shared library loads could have
+occurred since the time the breakpoint was disabled and one or more
+of these loads could resolve the location.
+
@cindex negative breakpoint numbers
@cindex internal @value{GDBN} breakpoints
@value{GDBN} itself sometimes sets breakpoints in your program for
@@ -2604,7 +2718,7 @@ times slower than normal execution. (But this may still be worth it, to
catch errors where you have no clue what part of your program is the
culprit.)
-On some systems, such as HP-UX, Linux and some other x86-based targets,
+On some systems, such as HP-UX, @sc{gnu}/Linux and some other x86-based targets,
@value{GDBN} includes support for
hardware watchpoints, which do not slow down the running of your
program.
@@ -2639,9 +2753,9 @@ statement, not the instruction, after the change occurs.
When you issue the @code{watch} command, @value{GDBN} reports
-@example
+@smallexample
Hardware watchpoint @var{num}: @var{expr}
-@end example
+@end smallexample
@noindent
if it was able to set a hardware watchpoint.
@@ -2730,6 +2844,8 @@ when a non-current thread's activity changes the expression. (Hardware
watchpoints, in contrast, watch an expression in all threads.)
@end quotation
+@xref{set remote hardware-watchpoint-limit}.
+
@node Set Catchpoints
@subsection Setting catchpoints
@cindex catchpoints, setting
@@ -2820,11 +2936,11 @@ knowledge of the implementation. In the case of @sc{gnu} C@t{++}, exceptions ar
raised by calling a library function named @code{__raise_exception}
which has the following ANSI C interface:
-@example
+@smallexample
/* @var{addr} is where the exception identifier is stored.
@var{id} is the exception identifier. */
void __raise_exception (void **addr, void *id);
-@end example
+@end smallexample
@noindent
To make the debugger catch all exceptions before any stack
@@ -3017,9 +3133,9 @@ referents in the context of your breakpoint. If @var{expression} uses
symbols not referenced in the context of the breakpoint, @value{GDBN}
prints an error message:
-@example
+@smallexample
No symbol "foo" in current context.
-@end example
+@end smallexample
@noindent
@value{GDBN} does
@@ -3128,14 +3244,14 @@ breakpoints. @xref{Output, ,Commands for controlled output}.
For example, here is how you could use breakpoint commands to print the
value of @code{x} at entry to @code{foo} whenever @code{x} is positive.
-@example
+@smallexample
break foo if x>0
commands
silent
printf "x is %d\n",x
cont
end
-@end example
+@end smallexample
One application for breakpoint commands is to compensate for one bug so
you can test for another. Put a breakpoint just after the erroneous line
@@ -3145,21 +3261,22 @@ to any variables that need them. End with the @code{continue} command
so that your program does not stop, and start with the @code{silent}
command so that no output is produced. Here is an example:
-@example
+@smallexample
break 403
commands
silent
set x = y + 4
cont
end
-@end example
+@end smallexample
@node Breakpoint Menus
@subsection Breakpoint menus
@cindex overloading
@cindex symbol overloading
-Some programming languages (notably C@t{++}) permit a single function name
+Some programming languages (notably C@t{++} and Objective-C) permit a
+single function name
to be defined several times, for application in different contexts.
This is called @dfn{overloading}. When a function name is overloaded,
@samp{break @var{function}} is not enough to tell @value{GDBN} where you want
@@ -3211,10 +3328,10 @@ any other process is running that program. In this situation,
attempting to run or continue a program with a breakpoint causes
@value{GDBN} to print an error message:
-@example
+@smallexample
Cannot insert breakpoints.
The same program may be running in another process.
-@end example
+@end smallexample
When this happens, you have three ways to proceed:
@@ -3253,6 +3370,58 @@ watchpoints it needs to insert.
When this message is printed, you need to disable or remove some of the
hardware-assisted breakpoints and watchpoints, and then continue.
+@node Breakpoint related warnings
+@subsection ``Breakpoint address adjusted...''
+@cindex breakpoint address adjusted
+
+Some processor architectures place constraints on the addresses at
+which breakpoints may be placed. For architectures thus constrained,
+@value{GDBN} will attempt to adjust the breakpoint's address to comply
+with the constraints dictated by the architecture.
+
+One example of such an architecture is the Fujitsu FR-V. The FR-V is
+a VLIW architecture in which a number of RISC-like instructions may be
+bundled together for parallel execution. The FR-V architecture
+constrains the location of a breakpoint instruction within such a
+bundle to the instruction with the lowest address. @value{GDBN}
+honors this constraint by adjusting a breakpoint's address to the
+first in the bundle.
+
+It is not uncommon for optimized code to have bundles which contain
+instructions from different source statements, thus it may happen that
+a breakpoint's address will be adjusted from one source statement to
+another. Since this adjustment may significantly alter @value{GDBN}'s
+breakpoint related behavior from what the user expects, a warning is
+printed when the breakpoint is first set and also when the breakpoint
+is hit.
+
+A warning like the one below is printed when setting a breakpoint
+that's been subject to address adjustment:
+
+@smallexample
+warning: Breakpoint address adjusted from 0x00010414 to 0x00010410.
+@end smallexample
+
+Such warnings are printed both for user settable and @value{GDBN}'s
+internal breakpoints. If you see one of these warnings, you should
+verify that a breakpoint set at the adjusted address will have the
+desired affect. If not, the breakpoint in question may be removed and
+other breakpoints may be set which will have the desired behavior.
+E.g., it may be sufficient to place the breakpoint at a later
+instruction. A conditional breakpoint may also be useful in some
+cases to prevent the breakpoint from triggering too often.
+
+@value{GDBN} will also issue a warning when stopping at one of these
+adjusted breakpoints:
+
+@smallexample
+warning: Breakpoint 1 address previously adjusted from 0x00010414
+to 0x00010410.
+@end smallexample
+
+When this warning is encountered, it may be too late to take remedial
+action except in cases where the breakpoint is hit earlier or more
+frequently than expected.
@node Continuing and Stepping
@section Continuing and stepping
@@ -3419,13 +3588,13 @@ example, in the following excerpt from a debugging session, the @code{f}
(@code{frame}) command shows that execution is stopped at line
@code{206}; yet when we use @code{until}, we get to line @code{195}:
-@example
+@smallexample
(@value{GDBP}) f
#0 main (argc=4, argv=0xf7fffae8) at m4.c:206
206 expand_input();
(@value{GDBP}) until
195 for ( ; argc > 0; NEXTARG) @{
-@end example
+@end smallexample
This happened because, for execution efficiency, the compiler had
generated code for the loop closure test at the end, rather than the
@@ -3444,8 +3613,35 @@ argument.
Continue running your program until either the specified location is
reached, or the current stack frame returns. @var{location} is any of
the forms of argument acceptable to @code{break} (@pxref{Set Breaks,
-,Setting breakpoints}). This form of the command uses breakpoints,
-and hence is quicker than @code{until} without an argument.
+,Setting breakpoints}). This form of the command uses breakpoints, and
+hence is quicker than @code{until} without an argument. The specified
+location is actually reached only if it is in the current frame. This
+implies that @code{until} can be used to skip over recursive function
+invocations. For instance in the code below, if the current location is
+line @code{96}, issuing @code{until 99} will execute the program up to
+line @code{99} in the same invocation of factorial, i.e. after the inner
+invocations have returned.
+
+@smallexample
+94 int factorial (int value)
+95 @{
+96 if (value > 1) @{
+97 value *= factorial (value - 1);
+98 @}
+99 return (value);
+100 @}
+@end smallexample
+
+
+@kindex advance @var{location}
+@itemx advance @var{location}
+Continue running the program up to the given location. An argument is
+required, anything of the same form as arguments for the @code{break}
+command. Execution will also stop upon exit from the current stack
+frame. This command is similar to @code{until}, but @code{advance} will
+not skip over recursive function calls, and the target location doesn't
+have to be in the same frame as the current one.
+
@kindex stepi
@kindex si @r{(@code{stepi})}
@@ -3624,6 +3820,47 @@ allows you to examine the overall state of the program, including
switching between threads, without worrying that things may change
underfoot.
+@cindex thread breakpoints and system calls
+@cindex system calls and thread breakpoints
+@cindex premature return from system calls
+There is an unfortunate side effect. If one thread stops for a
+breakpoint, or for some other reason, and another thread is blocked in a
+system call, then the system call may return prematurely. This is a
+consequence of the interaction between multiple threads and the signals
+that @value{GDBN} uses to implement breakpoints and other events that
+stop execution.
+
+To handle this problem, your program should check the return value of
+each system call and react appropriately. This is good programming
+style anyways.
+
+For example, do not write code like this:
+
+@smallexample
+ sleep (10);
+@end smallexample
+
+The call to @code{sleep} will return early if a different thread stops
+at a breakpoint or for some other reason.
+
+Instead, write this:
+
+@smallexample
+ int unslept = 10;
+ while (unslept > 0)
+ unslept = sleep (unslept);
+@end smallexample
+
+A system call is allowed to return early, so the system is still
+conforming to its specification. But @value{GDBN} does cause your
+multi-threaded program to behave differently than it would without
+@value{GDBN}.
+
+Also, @value{GDBN} uses internal breakpoints in the thread library to
+monitor certain events such as thread creation and thread destruction.
+When such an event happens, a system call in another thread may return
+prematurely, even though your program does not appear to stop.
+
@cindex continuing threads
@cindex threads, continuing
Conversely, whenever you restart the program, @emph{all} threads start
@@ -3747,9 +3984,9 @@ frames in @value{GDBN} commands.
@cindex frameless execution
Some compilers provide a way to compile functions so that they operate
without stack frames. (For example, the @value{GCC} option
-@example
+@smallexample
@samp{-fomit-frame-pointer}
-@end example
+@end smallexample
generates functions without a frame.)
This is occasionally done with heavily used library functions to save
the frame setup time. @value{GDBN} has limited facilities for dealing
@@ -3839,6 +4076,42 @@ The display for frame zero does not begin with a program counter
value, indicating that your program has stopped at the beginning of the
code for line @code{993} of @code{builtin.c}.
+@kindex set backtrace past-main
+@kindex show backtrace past-main
+@kindex set backtrace limit
+@kindex show backtrace limit
+
+Most programs have a standard user entry point---a place where system
+libraries and startup code transition into user code. For C this is
+@code{main}. When @value{GDBN} finds the entry function in a backtrace
+it will terminate the backtrace, to avoid tracing into highly
+system-specific (and generally uninteresting) code.
+
+If you need to examine the startup code, or limit the number of levels
+in a backtrace, you can change this behavior:
+
+@table @code
+@item set backtrace past-main
+@itemx set backtrace past-main on
+Backtraces will continue past the user entry point.
+
+@item set backtrace past-main off
+Backtraces will stop when they encounter the user entry point. This is the
+default.
+
+@item show backtrace past-main
+Display the current user entry point backtrace policy.
+
+@item set backtrace limit @var{n}
+@itemx set backtrace limit 0
+@cindex backtrace limit
+Limit the backtrace to @var{n} levels. A value of zero means
+unlimited.
+
+@item show backtrace limit
+Display the current limit on backtrace levels.
+@end table
+
@node Selection
@section Selecting a frame
@@ -3911,7 +4184,10 @@ For example:
After such a printout, the @code{list} command with no arguments
prints ten lines centered on the point of execution in the frame.
-@xref{List, ,Printing source lines}.
+You can also edit the program at the point of execution with your favorite
+editing program by typing @code{edit}.
+@xref{List, ,Printing source lines},
+for details.
@table @code
@kindex down-silently
@@ -4018,6 +4294,7 @@ prefer to use Emacs facilities to view source; see @ref{Emacs, ,Using
@menu
* List:: Printing source lines
+* Edit:: Editing source files
* Search:: Searching source files
* Source Path:: Specifying source directories
* Machine Code:: Source and machine code
@@ -4140,6 +4417,69 @@ Specifies the line containing the program address @var{address}.
@var{address} may be any expression.
@end table
+@node Edit
+@section Editing source files
+@cindex editing source files
+
+@kindex edit
+@kindex e @r{(@code{edit})}
+To edit the lines in a source file, use the @code{edit} command.
+The editing program of your choice
+is invoked with the current line set to
+the active line in the program.
+Alternatively, there are several ways to specify what part of the file you
+want to print if you want to see other parts of the program.
+
+Here are the forms of the @code{edit} command most commonly used:
+
+@table @code
+@item edit
+Edit the current source file at the active line number in the program.
+
+@item edit @var{number}
+Edit the current source file with @var{number} as the active line number.
+
+@item edit @var{function}
+Edit the file containing @var{function} at the beginning of its definition.
+
+@item edit @var{filename}:@var{number}
+Specifies line @var{number} in the source file @var{filename}.
+
+@item edit @var{filename}:@var{function}
+Specifies the line that begins the body of the
+function @var{function} in the file @var{filename}. You only need the
+file name with a function name to avoid ambiguity when there are
+identically named functions in different source files.
+
+@item edit *@var{address}
+Specifies the line containing the program address @var{address}.
+@var{address} may be any expression.
+@end table
+
+@subsection Choosing your editor
+You can customize @value{GDBN} to use any editor you want
+@footnote{
+The only restriction is that your editor (say @code{ex}), recognizes the
+following command-line syntax:
+@smallexample
+ex +@var{number} file
+@end smallexample
+The optional numeric value +@var{number} designates the active line in
+the file.}. By default, it is @value{EDITOR}, but you can change this
+by setting the environment variable @code{EDITOR} before using
+@value{GDBN}. For example, to configure @value{GDBN} to use the
+@code{vi} editor, you could use these commands with the @code{sh} shell:
+@smallexample
+EDITOR=/usr/bin/vi
+export EDITOR
+gdb ...
+@end smallexample
+or in the @code{csh} shell,
+@smallexample
+setenv EDITOR /usr/bin/vi
+gdb ...
+@end smallexample
+
@node Search
@section Searching source files
@cindex searching
@@ -4403,7 +4743,12 @@ Table}.
* Convenience Vars:: Convenience variables
* Registers:: Registers
* Floating Point Hardware:: Floating point hardware
+* Vector Unit:: Vector Unit
+* Auxiliary Vector:: Auxiliary data provided by operating system
* Memory Region Attributes:: Memory region attributes
+* Dump/Restore Files:: Copy between memory and a file
+* Character Sets:: Debugging programs that use a different
+ character set than GDB does
@end menu
@node Expressions
@@ -4413,9 +4758,10 @@ Table}.
@code{print} and many other @value{GDBN} commands accept an expression and
compute its value. Any kind of constant, variable or operator defined
by the programming language you are using is valid in an expression in
-@value{GDBN}. This includes conditional expressions, function calls, casts
-and string constants. It unfortunately does not include symbols defined
-by preprocessor @code{#define} commands.
+@value{GDBN}. This includes conditional expressions, function calls,
+casts, and string constants. It also includes preprocessor macros, if
+you compiled your program to include this information; see
+@ref{Compilation}.
@value{GDBN} supports array constants in expressions input by
the user. The syntax is @{@var{element}, @var{element}@dots{}@}. For example,
@@ -4483,7 +4829,7 @@ programming language from the point of execution in that frame
@noindent This means that in the function
-@example
+@smallexample
foo (a)
int a;
@{
@@ -4493,7 +4839,7 @@ foo (a)
bar (b);
@}
@}
-@end example
+@end smallexample
@noindent
you can examine and use the variable @code{a} whenever your program is
@@ -4515,10 +4861,10 @@ using the colon-colon notation:
@c info cannot cope with a :: index entry, but why deprive hard copy readers?
@cindex @code{::}, context for variables/functions
@end iftex
-@example
+@smallexample
@var{file}::@var{variable}
@var{function}::@var{variable}
-@end example
+@end smallexample
@noindent
Here @var{file} or @var{function} is the name of the context for the
@@ -4526,9 +4872,9 @@ static @var{variable}. In the case of file names, you can use quotes to
make sure @value{GDBN} parses the file name as a single word---for example,
to print a global value of @code{x} defined in @file{f2.c}:
-@example
+@smallexample
(@value{GDBP}) p 'f2.c'::x
-@end example
+@end smallexample
@cindex C@t{++} scope resolution
This use of @samp{::} is very rarely in conflict with the very similar
@@ -4565,19 +4911,18 @@ offered by the debug info format used by the compiler, @value{GDBN}
might not be able to display values for such local variables. If that
happens, @value{GDBN} will print a message like this:
-@example
+@smallexample
No symbol "foo" in current context.
-@end example
+@end smallexample
To solve such problems, either recompile without optimizations, or use a
different debug info format, if the compiler supports several such
-formats. For example, @value{NGCC}, the @sc{gnu} C/C@t{++} compiler usually
-supports the @samp{-gstabs} option. @samp{-gstabs} produces debug info
-in a format that is superior to formats such as COFF. You may be able
-to use DWARF2 (@samp{-gdwarf-2}), which is also an effective form for
-debug info. See @ref{Debugging Options,,Options for Debugging Your
-Program or @sc{gnu} CC, gcc.info, Using @sc{gnu} CC}, for more
-information.
+formats. For example, @value{NGCC}, the @sc{gnu} C/C@t{++} compiler
+usually supports the @option{-gstabs+} option. @option{-gstabs+}
+produces debug info in a format that is superior to formats such as
+COFF. You may be able to use DWARF 2 (@option{-gdwarf-2}), which is also
+an effective form for debug info. @xref{Debugging Options,,Options
+for Debugging Your Program or @sc{gnu} CC, gcc.info, Using @sc{gnu} CC}.
@node Arrays
@@ -4600,16 +4945,16 @@ argument; the second element comes from bytes of memory immediately
following those that hold the first element, and so on. Here is an
example. If a program says
-@example
+@smallexample
int *array = (int *) malloc (len * sizeof (int));
-@end example
+@end smallexample
@noindent
you can print the contents of @code{array} with
-@example
+@smallexample
p *array@@len
-@end example
+@end smallexample
The left operand of @samp{@@} must reside in memory. Array values made
with @samp{@@} in this way behave just like other arrays in terms of
@@ -4620,18 +4965,18 @@ Artificial arrays most often appear in expressions via the value history
Another way to create an artificial array is to use a cast.
This re-interprets a value as if it were an array.
The value need not be in memory:
-@example
+@smallexample
(@value{GDBP}) p/x (short[2])0x12345678
$1 = @{0x1234, 0x5678@}
-@end example
+@end smallexample
As a convenience, if you leave the array length out (as in
@samp{(@var{type}[])@var{value}}) @value{GDBN} calculates the size to fill
the value (as @samp{sizeof(@var{value})/sizeof(@var{type})}:
-@example
+@smallexample
(@value{GDBP}) p/x (short[])0x12345678
$2 = @{0x1234, 0x5678@}
-@end example
+@end smallexample
Sometimes the artificial array mechanism is not quite enough; in
moderately complex data structures, the elements of interest may not
@@ -4644,13 +4989,13 @@ instance, suppose you have an array @code{dtab} of pointers to
structures, and you are interested in the values of a field @code{fv}
in each structure. Here is an example of what you might type:
-@example
+@smallexample
set $i = 0
p dtab[$i++]->fv
@key{RET}
@key{RET}
@dots{}
-@end example
+@end smallexample
@node Output Formats
@section Output formats
@@ -4695,10 +5040,10 @@ Print as an address, both absolute in hexadecimal and as an offset from
the nearest preceding symbol. You can use this format used to discover
where (in what function) an unknown address is located:
-@example
+@smallexample
(@value{GDBP}) p/a 0x54320
$3 = 0x54320 <_initialize_vx+396>
-@end example
+@end smallexample
@noindent
The command @code{info symbol 0x54320} yields similar results.
@@ -4714,9 +5059,9 @@ using typical floating point syntax.
For example, to print the program counter in hex (@pxref{Registers}), type
-@example
+@smallexample
p/x $pc
-@end example
+@end smallexample
@noindent
Note that no space is required before the slash; this is because command
@@ -4843,10 +5188,10 @@ Each expression added to the list is given a number to identify it;
to remove an expression from the list, you specify that number.
The automatic display looks like this:
-@example
+@smallexample
2: foo = 38
3: bar[5] = (struct hack *) 0x3804
-@end example
+@end smallexample
@noindent
This display shows item numbers, expressions and their current values. As with
@@ -5034,11 +5379,11 @@ and source file location of the variable where it points, using
For example, here @value{GDBN} shows that a variable @code{ptt} points
at another variable @code{t}, defined in @file{hi2.c}:
-@example
+@smallexample
(@value{GDBP}) set print symbol-filename on
(@value{GDBP}) p/a ptt
$4 = 0xe008 <t in hi2.c>
-@end example
+@end smallexample
@quotation
@emph{Warning:} For pointers that point to a local variable, @samp{p/a}
@@ -5320,16 +5665,16 @@ is the value just prior to @code{$$}, @code{$$1} is equivalent to
For example, suppose you have just printed a pointer to a structure and
want to see the contents of the structure. It suffices to type
-@example
+@smallexample
p *$
-@end example
+@end smallexample
If you have a chain of structures where the component @code{next} points
to the next one, you can print the contents of the next one with this:
-@example
+@smallexample
p *$.next
-@end example
+@end smallexample
@noindent
You can print successive links in the chain by repeating this
@@ -5338,10 +5683,10 @@ command---which you can do by just typing @key{RET}.
Note that the history records values, not expressions. If the value of
@code{x} is 4 and you type these commands:
-@example
+@smallexample
print x
set x=5
-@end example
+@end smallexample
@noindent
then the value recorded in the value history by the @code{print} command
@@ -5385,9 +5730,9 @@ You can save a value in a convenience variable with an assignment
expression, just as you would set a variable in your program.
For example:
-@example
+@smallexample
set $foo = *object_ptr
-@end example
+@end smallexample
@noindent
would save in @code{$foo} the value contained in the object pointed to by
@@ -5413,10 +5758,10 @@ One of the ways to use a convenience variable is as a counter to be
incremented or a pointer to be advanced. For example, to print
a field from successive elements of an array of structures:
-@example
+@smallexample
set $i = 0
print bar[$i++]->contents
-@end example
+@end smallexample
@noindent
Repeat that command by typing @key{RET}.
@@ -5464,13 +5809,13 @@ your machine.
@kindex info registers
@item info registers
Print the names and values of all registers except floating-point
-registers (in the selected stack frame).
+and vector registers (in the selected stack frame).
@kindex info all-registers
@cindex floating point registers
@item info all-registers
Print the names and values of all registers, including floating-point
-registers.
+and vector registers (in the selected stack frame).
@item info registers @var{regname} @dots{}
Print the @dfn{relativized} value of each specified register @var{regname}.
@@ -5488,16 +5833,16 @@ pointer to the current stack frame, and @code{$ps} is used for a
register that contains the processor status. For example,
you could print the program counter in hex with
-@example
+@smallexample
p/x $pc
-@end example
+@end smallexample
@noindent
or print the instruction to be executed next with
-@example
+@smallexample
x/i $pc
-@end example
+@end smallexample
@noindent
or add four to the stack pointer@footnote{This is a way of removing
@@ -5508,9 +5853,9 @@ stack frames are selected. To pop entire frames off the stack,
regardless of machine architecture, use @code{return};
see @ref{Returning, ,Returning from a function}.} with
-@example
+@smallexample
set $sp += 4
-@end example
+@end smallexample
Whenever possible, these four standard register names are available on
your machine even though the machine has different canonical mnemonics,
@@ -5566,12 +5911,52 @@ floating point chip. Currently, @samp{info float} is supported on
the ARM and x86 machines.
@end table
+@node Vector Unit
+@section Vector Unit
+@cindex vector unit
+
+Depending on the configuration, @value{GDBN} may be able to give you
+more information about the status of the vector unit.
+
+@table @code
+@kindex info vector
+@item info vector
+Display information about the vector unit. The exact contents and
+layout vary depending on the hardware.
+@end table
+
+@node Auxiliary Vector
+@section Operating system auxiliary vector
+@cindex auxiliary vector
+@cindex vector, auxiliary
+
+Some operating systems supply an @dfn{auxiliary vector} to programs at
+startup. This is akin to the arguments and environment that you
+specify for a program, but contains a system-dependent variety of
+binary values that tell system libraries important details about the
+hardware, operating system, and process. Each value's purpose is
+identified by an integer tag; the meanings are well-known but system-specific.
+Depending on the configuration and operating system facilities,
+@value{GDBN} may be able to show you this information.
+
+@table @code
+@kindex info auxv
+@item info auxv
+Display the auxiliary vector of the inferior, which can be either a
+live process or a core dump file. @value{GDBN} prints each tag value
+numerically, and also shows names and text descriptions for recognized
+tags. Some values in the vector are numbers, some bit masks, and some
+pointers to strings or other data. @value{GDBN} displays each value in the
+most appropriate form for a recognized tag, and in hexadecimal for
+an unrecognized tag.
+@end table
+
@node Memory Region Attributes
-@section Memory Region Attributes
+@section Memory region attributes
@cindex memory region attributes
-@dfn{Memory region attributes} allow you to describe special handling
-required by regions of your target's memory. @value{GDBN} uses attributes
+@dfn{Memory region attributes} allow you to describe special handling
+required by regions of your target's memory. @value{GDBN} uses attributes
to determine whether to allow certain types of memory accesses; whether to
use specific width accesses; and whether to cache target memory.
@@ -5581,14 +5966,16 @@ accessing memory in that region. Similarly, if no memory regions have
been defined, @value{GDBN} uses the default attributes when accessing
all memory.
-When a memory region is defined, it is given a number to identify it;
+When a memory region is defined, it is given a number to identify it;
to enable, disable, or remove a memory region, you specify that number.
@table @code
@kindex mem
-@item mem @var{address1} @var{address2} @var{attributes}@dots{}
-Define memory region bounded by @var{address1} and @var{address2}
-with attributes @var{attributes}@dots{}.
+@item mem @var{lower} @var{upper} @var{attributes}@dots{}
+Define memory region bounded by @var{lower} and @var{upper} with
+attributes @var{attributes}@dots{}. Note that @var{upper} == 0 is a
+special case: it is treated as the the target's maximum memory address.
+(0xffff on 16 bit targets, 0xffffffff on 32 bit targets, etc.)
@kindex delete mem
@item delete mem @var{nums}@dots{}
@@ -5597,7 +5984,7 @@ Remove memory regions @var{nums}@dots{}.
@kindex disable mem
@item disable mem @var{nums}@dots{}
Disable memory regions @var{nums}@dots{}.
-A disabled memory region is not forgotten.
+A disabled memory region is not forgotten.
It may be enabled again later.
@kindex enable mem
@@ -5612,7 +5999,7 @@ for each region.
@table @emph
@item Memory Region Number
@item Enabled or Disabled.
-Enabled memory regions are marked with @samp{y}.
+Enabled memory regions are marked with @samp{y}.
Disabled memory regions are marked with @samp{n}.
@item Lo Address
@@ -5629,7 +6016,7 @@ The list of attributes set for this memory region.
@subsection Attributes
-@subsubsection Memory Access Mode
+@subsubsection Memory Access Mode
The access mode attributes set whether @value{GDBN} may make read or
write accesses to a memory region.
@@ -5670,7 +6057,7 @@ Use 64 bit memory accesses.
@c
@c @table @code
@c @item hwbreak
-@c Always use hardware breakpoints
+@c Always use hardware breakpoints
@c @item swbreak (default)
@c @end table
@@ -5683,13 +6070,13 @@ registers.
@table @code
@item cache
-Enable @value{GDBN} to cache target memory.
+Enable @value{GDBN} to cache target memory.
@item nocache
Disable @value{GDBN} from caching target memory. This is the default.
@end table
@c @subsubsection Memory Write Verification
-@c The memory write verification attributes set whether @value{GDBN}
+@c The memory write verification attributes set whether @value{GDBN}
@c will re-reads data after each write to verify the write was successful.
@c
@c @table @code
@@ -5697,6 +6084,542 @@ Disable @value{GDBN} from caching target memory. This is the default.
@c @item noverify (default)
@c @end table
+@node Dump/Restore Files
+@section Copy between memory and a file
+@cindex dump/restore files
+@cindex append data to a file
+@cindex dump data to a file
+@cindex restore data from a file
+
+You can use the commands @code{dump}, @code{append}, and
+@code{restore} to copy data between target memory and a file. The
+@code{dump} and @code{append} commands write data to a file, and the
+@code{restore} command reads data from a file back into the inferior's
+memory. Files may be in binary, Motorola S-record, Intel hex, or
+Tektronix Hex format; however, @value{GDBN} can only append to binary
+files.
+
+@table @code
+
+@kindex dump
+@item dump @r{[}@var{format}@r{]} memory @var{filename} @var{start_addr} @var{end_addr}
+@itemx dump @r{[}@var{format}@r{]} value @var{filename} @var{expr}
+Dump the contents of memory from @var{start_addr} to @var{end_addr},
+or the value of @var{expr}, to @var{filename} in the given format.
+
+The @var{format} parameter may be any one of:
+@table @code
+@item binary
+Raw binary form.
+@item ihex
+Intel hex format.
+@item srec
+Motorola S-record format.
+@item tekhex
+Tektronix Hex format.
+@end table
+
+@value{GDBN} uses the same definitions of these formats as the
+@sc{gnu} binary utilities, like @samp{objdump} and @samp{objcopy}. If
+@var{format} is omitted, @value{GDBN} dumps the data in raw binary
+form.
+
+@kindex append
+@item append @r{[}binary@r{]} memory @var{filename} @var{start_addr} @var{end_addr}
+@itemx append @r{[}binary@r{]} value @var{filename} @var{expr}
+Append the contents of memory from @var{start_addr} to @var{end_addr},
+or the value of @var{expr}, to @var{filename}, in raw binary form.
+(@value{GDBN} can only append data to files in raw binary form.)
+
+@kindex restore
+@item restore @var{filename} @r{[}binary@r{]} @var{bias} @var{start} @var{end}
+Restore the contents of file @var{filename} into memory. The
+@code{restore} command can automatically recognize any known @sc{bfd}
+file format, except for raw binary. To restore a raw binary file you
+must specify the optional keyword @code{binary} after the filename.
+
+If @var{bias} is non-zero, its value will be added to the addresses
+contained in the file. Binary files always start at address zero, so
+they will be restored at address @var{bias}. Other bfd files have
+a built-in location; they will be restored at offset @var{bias}
+from that location.
+
+If @var{start} and/or @var{end} are non-zero, then only data between
+file offset @var{start} and file offset @var{end} will be restored.
+These offsets are relative to the addresses in the file, before
+the @var{bias} argument is applied.
+
+@end table
+
+@node Character Sets
+@section Character Sets
+@cindex character sets
+@cindex charset
+@cindex translating between character sets
+@cindex host character set
+@cindex target character set
+
+If the program you are debugging uses a different character set to
+represent characters and strings than the one @value{GDBN} uses itself,
+@value{GDBN} can automatically translate between the character sets for
+you. The character set @value{GDBN} uses we call the @dfn{host
+character set}; the one the inferior program uses we call the
+@dfn{target character set}.
+
+For example, if you are running @value{GDBN} on a @sc{gnu}/Linux system, which
+uses the ISO Latin 1 character set, but you are using @value{GDBN}'s
+remote protocol (@pxref{Remote,Remote Debugging}) to debug a program
+running on an IBM mainframe, which uses the @sc{ebcdic} character set,
+then the host character set is Latin-1, and the target character set is
+@sc{ebcdic}. If you give @value{GDBN} the command @code{set
+target-charset EBCDIC-US}, then @value{GDBN} translates between
+@sc{ebcdic} and Latin 1 as you print character or string values, or use
+character and string literals in expressions.
+
+@value{GDBN} has no way to automatically recognize which character set
+the inferior program uses; you must tell it, using the @code{set
+target-charset} command, described below.
+
+Here are the commands for controlling @value{GDBN}'s character set
+support:
+
+@table @code
+@item set target-charset @var{charset}
+@kindex set target-charset
+Set the current target character set to @var{charset}. We list the
+character set names @value{GDBN} recognizes below, but if you type
+@code{set target-charset} followed by @key{TAB}@key{TAB}, @value{GDBN} will
+list the target character sets it supports.
+@end table
+
+@table @code
+@item set host-charset @var{charset}
+@kindex set host-charset
+Set the current host character set to @var{charset}.
+
+By default, @value{GDBN} uses a host character set appropriate to the
+system it is running on; you can override that default using the
+@code{set host-charset} command.
+
+@value{GDBN} can only use certain character sets as its host character
+set. We list the character set names @value{GDBN} recognizes below, and
+indicate which can be host character sets, but if you type
+@code{set target-charset} followed by @key{TAB}@key{TAB}, @value{GDBN} will
+list the host character sets it supports.
+
+@item set charset @var{charset}
+@kindex set charset
+Set the current host and target character sets to @var{charset}. As
+above, if you type @code{set charset} followed by @key{TAB}@key{TAB},
+@value{GDBN} will list the name of the character sets that can be used
+for both host and target.
+
+
+@item show charset
+@kindex show charset
+Show the names of the current host and target charsets.
+
+@itemx show host-charset
+@kindex show host-charset
+Show the name of the current host charset.
+
+@itemx show target-charset
+@kindex show target-charset
+Show the name of the current target charset.
+
+@end table
+
+@value{GDBN} currently includes support for the following character
+sets:
+
+@table @code
+
+@item ASCII
+@cindex ASCII character set
+Seven-bit U.S. @sc{ascii}. @value{GDBN} can use this as its host
+character set.
+
+@item ISO-8859-1
+@cindex ISO 8859-1 character set
+@cindex ISO Latin 1 character set
+The ISO Latin 1 character set. This extends @sc{ascii} with accented
+characters needed for French, German, and Spanish. @value{GDBN} can use
+this as its host character set.
+
+@item EBCDIC-US
+@itemx IBM1047
+@cindex EBCDIC character set
+@cindex IBM1047 character set
+Variants of the @sc{ebcdic} character set, used on some of IBM's
+mainframe operating systems. (@sc{gnu}/Linux on the S/390 uses U.S. @sc{ascii}.)
+@value{GDBN} cannot use these as its host character set.
+
+@end table
+
+Note that these are all single-byte character sets. More work inside
+GDB is needed to support multi-byte or variable-width character
+encodings, like the UTF-8 and UCS-2 encodings of Unicode.
+
+Here is an example of @value{GDBN}'s character set support in action.
+Assume that the following source code has been placed in the file
+@file{charset-test.c}:
+
+@smallexample
+#include <stdio.h>
+
+char ascii_hello[]
+ = @{72, 101, 108, 108, 111, 44, 32, 119,
+ 111, 114, 108, 100, 33, 10, 0@};
+char ibm1047_hello[]
+ = @{200, 133, 147, 147, 150, 107, 64, 166,
+ 150, 153, 147, 132, 90, 37, 0@};
+
+main ()
+@{
+ printf ("Hello, world!\n");
+@}
+@end smallexample
+
+In this program, @code{ascii_hello} and @code{ibm1047_hello} are arrays
+containing the string @samp{Hello, world!} followed by a newline,
+encoded in the @sc{ascii} and @sc{ibm1047} character sets.
+
+We compile the program, and invoke the debugger on it:
+
+@smallexample
+$ gcc -g charset-test.c -o charset-test
+$ gdb -nw charset-test
+GNU gdb 2001-12-19-cvs
+Copyright 2001 Free Software Foundation, Inc.
+@dots{}
+(gdb)
+@end smallexample
+
+We can use the @code{show charset} command to see what character sets
+@value{GDBN} is currently using to interpret and display characters and
+strings:
+
+@smallexample
+(gdb) show charset
+The current host and target character set is `ISO-8859-1'.
+(gdb)
+@end smallexample
+
+For the sake of printing this manual, let's use @sc{ascii} as our
+initial character set:
+@smallexample
+(gdb) set charset ASCII
+(gdb) show charset
+The current host and target character set is `ASCII'.
+(gdb)
+@end smallexample
+
+Let's assume that @sc{ascii} is indeed the correct character set for our
+host system --- in other words, let's assume that if @value{GDBN} prints
+characters using the @sc{ascii} character set, our terminal will display
+them properly. Since our current target character set is also
+@sc{ascii}, the contents of @code{ascii_hello} print legibly:
+
+@smallexample
+(gdb) print ascii_hello
+$1 = 0x401698 "Hello, world!\n"
+(gdb) print ascii_hello[0]
+$2 = 72 'H'
+(gdb)
+@end smallexample
+
+@value{GDBN} uses the target character set for character and string
+literals you use in expressions:
+
+@smallexample
+(gdb) print '+'
+$3 = 43 '+'
+(gdb)
+@end smallexample
+
+The @sc{ascii} character set uses the number 43 to encode the @samp{+}
+character.
+
+@value{GDBN} relies on the user to tell it which character set the
+target program uses. If we print @code{ibm1047_hello} while our target
+character set is still @sc{ascii}, we get jibberish:
+
+@smallexample
+(gdb) print ibm1047_hello
+$4 = 0x4016a8 "\310\205\223\223\226k@@\246\226\231\223\204Z%"
+(gdb) print ibm1047_hello[0]
+$5 = 200 '\310'
+(gdb)
+@end smallexample
+
+If we invoke the @code{set target-charset} followed by @key{TAB}@key{TAB},
+@value{GDBN} tells us the character sets it supports:
+
+@smallexample
+(gdb) set target-charset
+ASCII EBCDIC-US IBM1047 ISO-8859-1
+(gdb) set target-charset
+@end smallexample
+
+We can select @sc{ibm1047} as our target character set, and examine the
+program's strings again. Now the @sc{ascii} string is wrong, but
+@value{GDBN} translates the contents of @code{ibm1047_hello} from the
+target character set, @sc{ibm1047}, to the host character set,
+@sc{ascii}, and they display correctly:
+
+@smallexample
+(gdb) set target-charset IBM1047
+(gdb) show charset
+The current host character set is `ASCII'.
+The current target character set is `IBM1047'.
+(gdb) print ascii_hello
+$6 = 0x401698 "\110\145%%?\054\040\167?\162%\144\041\012"
+(gdb) print ascii_hello[0]
+$7 = 72 '\110'
+(gdb) print ibm1047_hello
+$8 = 0x4016a8 "Hello, world!\n"
+(gdb) print ibm1047_hello[0]
+$9 = 200 'H'
+(gdb)
+@end smallexample
+
+As above, @value{GDBN} uses the target character set for character and
+string literals you use in expressions:
+
+@smallexample
+(gdb) print '+'
+$10 = 78 '+'
+(gdb)
+@end smallexample
+
+The @sc{ibm1047} character set uses the number 78 to encode the @samp{+}
+character.
+
+
+@node Macros
+@chapter C Preprocessor Macros
+
+Some languages, such as C and C@t{++}, provide a way to define and invoke
+``preprocessor macros'' which expand into strings of tokens.
+@value{GDBN} can evaluate expressions containing macro invocations, show
+the result of macro expansion, and show a macro's definition, including
+where it was defined.
+
+You may need to compile your program specially to provide @value{GDBN}
+with information about preprocessor macros. Most compilers do not
+include macros in their debugging information, even when you compile
+with the @option{-g} flag. @xref{Compilation}.
+
+A program may define a macro at one point, remove that definition later,
+and then provide a different definition after that. Thus, at different
+points in the program, a macro may have different definitions, or have
+no definition at all. If there is a current stack frame, @value{GDBN}
+uses the macros in scope at that frame's source code line. Otherwise,
+@value{GDBN} uses the macros in scope at the current listing location;
+see @ref{List}.
+
+At the moment, @value{GDBN} does not support the @code{##}
+token-splicing operator, the @code{#} stringification operator, or
+variable-arity macros.
+
+Whenever @value{GDBN} evaluates an expression, it always expands any
+macro invocations present in the expression. @value{GDBN} also provides
+the following commands for working with macros explicitly.
+
+@table @code
+
+@kindex macro expand
+@cindex macro expansion, showing the results of preprocessor
+@cindex preprocessor macro expansion, showing the results of
+@cindex expanding preprocessor macros
+@item macro expand @var{expression}
+@itemx macro exp @var{expression}
+Show the results of expanding all preprocessor macro invocations in
+@var{expression}. Since @value{GDBN} simply expands macros, but does
+not parse the result, @var{expression} need not be a valid expression;
+it can be any string of tokens.
+
+@kindex macro expand-once
+@item macro expand-once @var{expression}
+@itemx macro exp1 @var{expression}
+@i{(This command is not yet implemented.)} Show the results of
+expanding those preprocessor macro invocations that appear explicitly in
+@var{expression}. Macro invocations appearing in that expansion are
+left unchanged. This command allows you to see the effect of a
+particular macro more clearly, without being confused by further
+expansions. Since @value{GDBN} simply expands macros, but does not
+parse the result, @var{expression} need not be a valid expression; it
+can be any string of tokens.
+
+@kindex info macro
+@cindex macro definition, showing
+@cindex definition, showing a macro's
+@item info macro @var{macro}
+Show the definition of the macro named @var{macro}, and describe the
+source location where that definition was established.
+
+@kindex macro define
+@cindex user-defined macros
+@cindex defining macros interactively
+@cindex macros, user-defined
+@item macro define @var{macro} @var{replacement-list}
+@itemx macro define @var{macro}(@var{arglist}) @var{replacement-list}
+@i{(This command is not yet implemented.)} Introduce a definition for a
+preprocessor macro named @var{macro}, invocations of which are replaced
+by the tokens given in @var{replacement-list}. The first form of this
+command defines an ``object-like'' macro, which takes no arguments; the
+second form defines a ``function-like'' macro, which takes the arguments
+given in @var{arglist}.
+
+A definition introduced by this command is in scope in every expression
+evaluated in @value{GDBN}, until it is removed with the @command{macro
+undef} command, described below. The definition overrides all
+definitions for @var{macro} present in the program being debugged, as
+well as any previous user-supplied definition.
+
+@kindex macro undef
+@item macro undef @var{macro}
+@i{(This command is not yet implemented.)} Remove any user-supplied
+definition for the macro named @var{macro}. This command only affects
+definitions provided with the @command{macro define} command, described
+above; it cannot remove definitions present in the program being
+debugged.
+
+@end table
+
+@cindex macros, example of debugging with
+Here is a transcript showing the above commands in action. First, we
+show our source files:
+
+@smallexample
+$ cat sample.c
+#include <stdio.h>
+#include "sample.h"
+
+#define M 42
+#define ADD(x) (M + x)
+
+main ()
+@{
+#define N 28
+ printf ("Hello, world!\n");
+#undef N
+ printf ("We're so creative.\n");
+#define N 1729
+ printf ("Goodbye, world!\n");
+@}
+$ cat sample.h
+#define Q <
+$
+@end smallexample
+
+Now, we compile the program using the @sc{gnu} C compiler, @value{NGCC}.
+We pass the @option{-gdwarf-2} and @option{-g3} flags to ensure the
+compiler includes information about preprocessor macros in the debugging
+information.
+
+@smallexample
+$ gcc -gdwarf-2 -g3 sample.c -o sample
+$
+@end smallexample
+
+Now, we start @value{GDBN} on our sample program:
+
+@smallexample
+$ gdb -nw sample
+GNU gdb 2002-05-06-cvs
+Copyright 2002 Free Software Foundation, Inc.
+GDB is free software, @dots{}
+(gdb)
+@end smallexample
+
+We can expand macros and examine their definitions, even when the
+program is not running. @value{GDBN} uses the current listing position
+to decide which macro definitions are in scope:
+
+@smallexample
+(gdb) list main
+3
+4 #define M 42
+5 #define ADD(x) (M + x)
+6
+7 main ()
+8 @{
+9 #define N 28
+10 printf ("Hello, world!\n");
+11 #undef N
+12 printf ("We're so creative.\n");
+(gdb) info macro ADD
+Defined at /home/jimb/gdb/macros/play/sample.c:5
+#define ADD(x) (M + x)
+(gdb) info macro Q
+Defined at /home/jimb/gdb/macros/play/sample.h:1
+ included at /home/jimb/gdb/macros/play/sample.c:2
+#define Q <
+(gdb) macro expand ADD(1)
+expands to: (42 + 1)
+(gdb) macro expand-once ADD(1)
+expands to: once (M + 1)
+(gdb)
+@end smallexample
+
+In the example above, note that @command{macro expand-once} expands only
+the macro invocation explicit in the original text --- the invocation of
+@code{ADD} --- but does not expand the invocation of the macro @code{M},
+which was introduced by @code{ADD}.
+
+Once the program is running, GDB uses the macro definitions in force at
+the source line of the current stack frame:
+
+@smallexample
+(gdb) break main
+Breakpoint 1 at 0x8048370: file sample.c, line 10.
+(gdb) run
+Starting program: /home/jimb/gdb/macros/play/sample
+
+Breakpoint 1, main () at sample.c:10
+10 printf ("Hello, world!\n");
+(gdb)
+@end smallexample
+
+At line 10, the definition of the macro @code{N} at line 9 is in force:
+
+@smallexample
+(gdb) info macro N
+Defined at /home/jimb/gdb/macros/play/sample.c:9
+#define N 28
+(gdb) macro expand N Q M
+expands to: 28 < 42
+(gdb) print N Q M
+$1 = 1
+(gdb)
+@end smallexample
+
+As we step over directives that remove @code{N}'s definition, and then
+give it a new definition, @value{GDBN} finds the definition (or lack
+thereof) in force at each point:
+
+@smallexample
+(gdb) next
+Hello, world!
+12 printf ("We're so creative.\n");
+(gdb) info macro N
+The symbol `N' has no definition as a C/C++ preprocessor macro
+at /home/jimb/gdb/macros/play/sample.c:12
+(gdb) next
+We're so creative.
+14 printf ("Goodbye, world!\n");
+(gdb) info macro N
+Defined at /home/jimb/gdb/macros/play/sample.c:13
+#define N 1729
+(gdb) macro expand N Q M
+expands to: 1729 < 42
+(gdb) print N Q M
+$2 = 0
+(gdb)
+@end smallexample
+
+
@node Tracepoints
@chapter Tracepoints
@c This chapter is based on the documentation written by Michael
@@ -5732,9 +6655,9 @@ tracepoints as of this writing.
This chapter describes the tracepoint commands and features.
@menu
-* Set Tracepoints::
-* Analyze Collected Data::
-* Tracepoint Variables::
+* Set Tracepoints::
+* Analyze Collected Data::
+* Tracepoint Variables::
@end menu
@node Set Tracepoints
@@ -5759,12 +6682,12 @@ This section describes commands to set tracepoints and associated
conditions and actions.
@menu
-* Create and Delete Tracepoints::
-* Enable and Disable Tracepoints::
-* Tracepoint Passcounts::
-* Tracepoint Actions::
-* Listing Tracepoints::
-* Starting and Stopping Trace Experiment::
+* Create and Delete Tracepoints::
+* Enable and Disable Tracepoints::
+* Tracepoint Passcounts::
+* Tracepoint Actions::
+* Listing Tracepoints::
+* Starting and Stopping Trace Experiment::
@end menu
@node Create and Delete Tracepoints
@@ -5863,7 +6786,7 @@ user.
Examples:
@smallexample
-(@value{GDBP}) @b{passcount 5 2} // Stop on the 5th execution of
+(@value{GDBP}) @b{passcount 5 2} // Stop on the 5th execution of
@exdent @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @code{// tracepoint 2}
(@value{GDBP}) @b{passcount 12} // Stop on the 12th execution of the
@@ -6368,7 +7291,7 @@ there.
@c size of all overlays. This is intentional to remind the developer
@c that overlays don't necessarily need to be the same size.
-@example
+@smallexample
@group
Data Instruction Larger
Address Space Address Space Address Space
@@ -6396,7 +7319,7 @@ Address Space Address Space Address Space
@anchor{A code overlay}A code overlay
@end group
-@end example
+@end smallexample
The diagram (@pxref{A code overlay}) shows a system with separate data
and instruction address spaces. To map an overlay, the program copies
@@ -6553,33 +7476,33 @@ addresses, load addresses, and sizes.
Normally, when @value{GDBN} prints a code address, it includes the name
of the function the address falls in:
-@example
+@smallexample
(gdb) print main
$3 = @{int ()@} 0x11a0 <main>
-@end example
+@end smallexample
@noindent
When overlay debugging is enabled, @value{GDBN} recognizes code in
unmapped overlays, and prints the names of unmapped functions with
asterisks around them. For example, if @code{foo} is a function in an
unmapped overlay, @value{GDBN} prints it this way:
-@example
+@smallexample
(gdb) overlay list
No sections are mapped.
(gdb) print foo
$5 = @{int (int)@} 0x100000 <*foo*>
-@end example
+@end smallexample
@noindent
When @code{foo}'s overlay is mapped, @value{GDBN} prints the function's
name normally:
-@example
+@smallexample
(gdb) overlay list
-Section .ov.foo.text, loaded at 0x100000 - 0x100034,
+Section .ov.foo.text, loaded at 0x100000 - 0x100034,
mapped at 0x1016 - 0x104a
(gdb) print foo
$6 = @{int (int)@} 0x1016 <foo>
-@end example
+@end smallexample
When overlay debugging is enabled, @value{GDBN} can find the correct
address for functions and variables in an overlay, whether or not the
@@ -6621,7 +7544,7 @@ Here are the variables your overlay manager must define to support
@item @code{_ovly_table}:
This variable must be an array of the following structures:
-@example
+@smallexample
struct
@{
/* The overlay's mapped address. */
@@ -6637,7 +7560,7 @@ struct
zero otherwise. */
unsigned long mapped;
@}
-@end example
+@end smallexample
@item @code{_novlys}:
This variable must be a four-byte signed integer, holding the total
@@ -6658,7 +7581,7 @@ will silently set a breakpoint there. If the overlay manager then
calls this function whenever it has changed the overlay table, this
will enable @value{GDBN} to accurately keep track of which overlays
are in program memory, and update any breakpoints that may be set
-in overlays. This will allow breakpoints to work even if the
+in overlays. This will allow breakpoints to work even if the
overlays are kept in ROM or other non-writable memory while they
are not being executed.
@@ -6698,7 +7621,7 @@ and @code{m32r-elf} targets.
You can build the test program using the @code{d10v-elf} GCC
cross-compiler like this:
-@example
+@smallexample
$ d10v-elf-gcc -g -c overlays.c
$ d10v-elf-gcc -g -c ovlymgr.c
$ d10v-elf-gcc -g -c foo.c
@@ -6707,7 +7630,7 @@ $ d10v-elf-gcc -g -c baz.c
$ d10v-elf-gcc -g -c grbx.c
$ d10v-elf-gcc -g overlays.o ovlymgr.o foo.o bar.o \
baz.o grbx.o -Wl,-Td10v.ld -o overlays
-@end example
+@end smallexample
The build process is identical for any other architecture, except that
you must substitute the appropriate compiler and linker script for the
@@ -6738,6 +7661,7 @@ language}.
* Show:: Displaying the language
* Checks:: Type and range checks
* Support:: Supported languages
+* Unsupported languages:: Unsupported languages
@end menu
@node Setting
@@ -6793,15 +7717,13 @@ C source file
@itemx .c++
C@t{++} source file
+@item .m
+Objective-C source file
+
@item .f
@itemx .F
Fortran source file
-@item .ch
-@itemx .c186
-@itemx .c286
-CHILL source file
-
@item .mod
Modula-2 source file
@@ -6836,9 +7758,9 @@ languages---but means different things. For instance, if the current
source file were written in C, and @value{GDBN} was parsing Modula-2, a
command such as:
-@example
+@smallexample
print a = b + c
-@end example
+@end smallexample
@noindent
might not have the effect you intended. In C, this means to add
@@ -7032,9 +7954,9 @@ error. In many implementations of C, mathematical overflow causes the
result to ``wrap around'' to lower values---for example, if @var{m} is
the largest integer value, and @var{s} is the smallest, then
-@example
+@smallexample
@var{m} + 1 @result{} @var{s}
-@end example
+@end smallexample
This, too, is specific to individual languages, and in some cases
specific to individual compilers or machines. @xref{Support, ,
@@ -7073,7 +7995,7 @@ being set automatically by @value{GDBN}.
@node Support
@section Supported languages
-@value{GDBN} supports C, C@t{++}, Fortran, Java, Chill, assembly, and Modula-2.
+@value{GDBN} supports C, C@t{++}, Objective-C, Fortran, Java, assembly, and Modula-2.
@c This is false ...
Some @value{GDBN} features may be used in expressions regardless of the
language you use: the @value{GDBN} @code{@@} and @code{::} operators,
@@ -7090,9 +8012,9 @@ books written on each of these languages; please look to these for a
language reference or tutorial.
@menu
-* C:: C and C@t{++}
-* Modula-2:: Modula-2
-* Chill:: Chill
+* C:: C and C@t{++}
+* Objective-C:: Objective-C
+* Modula-2:: Modula-2
@end menu
@node C
@@ -7114,11 +8036,12 @@ effectively, you must compile your C@t{++} programs with a supported
C@t{++} compiler, such as @sc{gnu} @code{g++}, or the HP ANSI C@t{++}
compiler (@code{aCC}).
-For best results when using @sc{gnu} C@t{++}, use the stabs debugging
-format. You can select that format explicitly with the @code{g++}
-command-line options @samp{-gstabs} or @samp{-gstabs+}. See
-@ref{Debugging Options,,Options for Debugging Your Program or @sc{gnu}
-CC, gcc.info, Using @sc{gnu} CC}, for more information.
+For best results when using @sc{gnu} C@t{++}, use the DWARF 2 debugging
+format; if it doesn't work on your system, try the stabs+ debugging
+format. You can select those formats explicitly with the @code{g++}
+command-line options @option{-gdwarf-2} and @option{-gstabs+}.
+@xref{Debugging Options,,Options for Debugging Your Program or @sc{gnu}
+CC, gcc.info, Using @sc{gnu} CC}.
@menu
* C Operators:: C and C@t{++} operators
@@ -7364,28 +8287,21 @@ and @samp{@{&"hi", &"there", &"fred"@}} is a three-element array of pointers.
@cindex expressions in C@t{++}
@value{GDBN} expression handling can interpret most C@t{++} expressions.
-@cindex C@t{++} support, not in @sc{coff}
-@cindex @sc{coff} versus C@t{++}
-@cindex C@t{++} and object formats
-@cindex object formats and C@t{++}
-@cindex a.out and C@t{++}
-@cindex @sc{ecoff} and C@t{++}
-@cindex @sc{xcoff} and C@t{++}
-@cindex @sc{elf}/stabs and C@t{++}
-@cindex @sc{elf}/@sc{dwarf} and C@t{++}
-@c FIXME!! GDB may eventually be able to debug C++ using DWARF; check
-@c periodically whether this has happened...
+@cindex debugging C@t{++} programs
+@cindex C@t{++} compilers
+@cindex debug formats and C@t{++}
+@cindex @value{NGCC} and C@t{++}
@quotation
@emph{Warning:} @value{GDBN} can only debug C@t{++} code if you use the
-proper compiler. Typically, C@t{++} debugging depends on the use of
-additional debugging information in the symbol table, and thus requires
-special support. In particular, if your compiler generates a.out, MIPS
-@sc{ecoff}, RS/6000 @sc{xcoff}, or @sc{elf} with stabs extensions to the
-symbol table, these facilities are all available. (With @sc{gnu} CC,
-you can use the @samp{-gstabs} option to request stabs debugging
-extensions explicitly.) Where the object code format is standard
-@sc{coff} or @sc{dwarf} in @sc{elf}, on the other hand, most of the C@t{++}
-support in @value{GDBN} does @emph{not} work.
+proper compiler and the proper debug format. Currently, @value{GDBN}
+works best when debugging C@t{++} code that is compiled with
+@value{NGCC} 2.95.3 or with @value{NGCC} 3.1 or newer, using the options
+@option{-gdwarf-2} or @option{-gstabs+}. DWARF 2 is preferred over
+stabs+. Most configurations of @value{NGCC} emit either DWARF 2 or
+stabs+ as their default debug format, so you usually don't need to
+specify a debug format explicitly. Other compilers and/or debug formats
+are likely to work badly or not at all when using @value{GDBN} to debug
+C@t{++} code.
@end quotation
@enumerate
@@ -7394,9 +8310,9 @@ support in @value{GDBN} does @emph{not} work.
@item
Member function calls are allowed; you can use expressions like
-@example
+@smallexample
count = aml->GetOriginal(x, y)
-@end example
+@end smallexample
@vindex this@r{, inside C@t{++} member functions}
@cindex namespace in C@t{++}
@@ -7615,7 +8531,106 @@ available choices, or to finish the type list for you.
@xref{Completion,, Command completion}, for details on how to do this.
@end table
-@node Modula-2
+@node Objective-C
+@subsection Objective-C
+
+@cindex Objective-C
+This section provides information about some commands and command
+options that are useful for debugging Objective-C code.
+
+@menu
+* Method Names in Commands::
+* The Print Command with Objective-C::
+@end menu
+
+@node Method Names in Commands, The Print Command with Objective-C, Objective-C, Objective-C
+@subsubsection Method Names in Commands
+
+The following commands have been extended to accept Objective-C method
+names as line specifications:
+
+@kindex clear@r{, and Objective-C}
+@kindex break@r{, and Objective-C}
+@kindex info line@r{, and Objective-C}
+@kindex jump@r{, and Objective-C}
+@kindex list@r{, and Objective-C}
+@itemize
+@item @code{clear}
+@item @code{break}
+@item @code{info line}
+@item @code{jump}
+@item @code{list}
+@end itemize
+
+A fully qualified Objective-C method name is specified as
+
+@smallexample
+-[@var{Class} @var{methodName}]
+@end smallexample
+
+where the minus sign is used to indicate an instance method and a
+plus sign (not shown) is used to indicate a class method. The class
+name @var{Class} and method name @var{methodName} are enclosed in
+brackets, similar to the way messages are specified in Objective-C
+source code. For example, to set a breakpoint at the @code{create}
+instance method of class @code{Fruit} in the program currently being
+debugged, enter:
+
+@smallexample
+break -[Fruit create]
+@end smallexample
+
+To list ten program lines around the @code{initialize} class method,
+enter:
+
+@smallexample
+list +[NSText initialize]
+@end smallexample
+
+In the current version of @value{GDBN}, the plus or minus sign is
+required. In future versions of @value{GDBN}, the plus or minus
+sign will be optional, but you can use it to narrow the search. It
+is also possible to specify just a method name:
+
+@smallexample
+break create
+@end smallexample
+
+You must specify the complete method name, including any colons. If
+your program's source files contain more than one @code{create} method,
+you'll be presented with a numbered list of classes that implement that
+method. Indicate your choice by number, or type @samp{0} to exit if
+none apply.
+
+As another example, to clear a breakpoint established at the
+@code{makeKeyAndOrderFront:} method of the @code{NSWindow} class, enter:
+
+@smallexample
+clear -[NSWindow makeKeyAndOrderFront:]
+@end smallexample
+
+@node The Print Command with Objective-C
+@subsubsection The Print Command With Objective-C
+@kindex print-object
+@kindex po @r{(@code{print-object})}
+
+The print command has also been extended to accept methods. For example:
+
+@smallexample
+print -[@var{object} hash]
+@end smallexample
+
+@cindex print an Objective-C object description
+@cindex @code{_NSPrintForDebugger}, and printing Objective-C objects
+@noindent
+will tell @value{GDBN} to send the @code{hash} message to @var{object}
+and print the result. Also, an additional command has been added,
+@code{print-object} or @code{po} for short, which is meant to print
+the description of an object. However, this command may only work
+with certain Objective-C libraries that have a particular hook
+function, @code{_NSPrintForDebugger}, defined.
+
+@node Modula-2, , Objective-C, Support
@subsection Modula-2
@cindex Modula-2, @value{GDBN} support
@@ -8014,11 +9029,11 @@ There are a few subtle differences between the Modula-2 scope operator
(@code{.}) and the @value{GDBN} scope operator (@code{::}). The two have
similar syntax:
-@example
+@smallexample
@var{module} . @var{id}
@var{scope} :: @var{id}
-@end example
+@end smallexample
@noindent
where @var{scope} is the name of a module or a procedure,
@@ -8058,504 +9073,21 @@ address can be specified by an integral constant, the construct
In @value{GDBN} scripts, the Modula-2 inequality operator @code{#} is
interpreted as the beginning of a comment. Use @code{<>} instead.
-@node Chill
-@subsection Chill
-
-The extensions made to @value{GDBN} to support Chill only support output
-from the @sc{gnu} Chill compiler. Other Chill compilers are not currently
-supported, and attempting to debug executables produced by them is most
-likely to give an error as @value{GDBN} reads in the executable's symbol
-table.
-
-@c This used to say "... following Chill related topics ...", but since
-@c menus are not shown in the printed manual, it would look awkward.
-This section covers the Chill related topics and the features
-of @value{GDBN} which support these topics.
-
-@menu
-* How modes are displayed:: How modes are displayed
-* Locations:: Locations and their accesses
-* Values and their Operations:: Values and their Operations
-* Chill type and range checks::
-* Chill defaults::
-@end menu
-
-@node How modes are displayed
-@subsubsection How modes are displayed
-
-The Chill Datatype- (Mode) support of @value{GDBN} is directly related
-with the functionality of the @sc{gnu} Chill compiler, and therefore deviates
-slightly from the standard specification of the Chill language. The
-provided modes are:
-
-@c FIXME: this @table's contents effectively disable @code by using @r
-@c on every @item. So why does it need @code?
-@table @code
-@item @r{@emph{Discrete modes:}}
-@itemize @bullet
-@item
-@emph{Integer Modes} which are predefined by @code{BYTE, UBYTE, INT,
-UINT, LONG, ULONG},
-@item
-@emph{Boolean Mode} which is predefined by @code{BOOL},
-@item
-@emph{Character Mode} which is predefined by @code{CHAR},
-@item
-@emph{Set Mode} which is displayed by the keyword @code{SET}.
-@smallexample
-(@value{GDBP}) ptype x
-type = SET (karli = 10, susi = 20, fritzi = 100)
-@end smallexample
-If the type is an unnumbered set the set element values are omitted.
-@item
-@emph{Range Mode} which is displayed by
-@smallexample
-@code{type = <basemode>(<lower bound> : <upper bound>)}
-@end smallexample
-where @code{<lower bound>, <upper bound>} can be of any discrete literal
-expression (e.g. set element names).
-@end itemize
-
-@item @r{@emph{Powerset Mode:}}
-A Powerset Mode is displayed by the keyword @code{POWERSET} followed by
-the member mode of the powerset. The member mode can be any discrete mode.
-@smallexample
-(@value{GDBP}) ptype x
-type = POWERSET SET (egon, hugo, otto)
-@end smallexample
-
-@item @r{@emph{Reference Modes:}}
-@itemize @bullet
-@item
-@emph{Bound Reference Mode} which is displayed by the keyword @code{REF}
-followed by the mode name to which the reference is bound.
-@item
-@emph{Free Reference Mode} which is displayed by the keyword @code{PTR}.
-@end itemize
-
-@item @r{@emph{Procedure mode}}
-The procedure mode is displayed by @code{type = PROC(<parameter list>)
-<return mode> EXCEPTIONS (<exception list>)}. The @code{<parameter
-list>} is a list of the parameter modes. @code{<return mode>} indicates
-the mode of the result of the procedure if any. The exceptionlist lists
-all possible exceptions which can be raised by the procedure.
-
-@ignore
-@item @r{@emph{Instance mode}}
-The instance mode is represented by a structure, which has a static
-type, and is therefore not really of interest.
-@end ignore
-
-@item @r{@emph{Synchronization Modes:}}
-@itemize @bullet
-@item
-@emph{Event Mode} which is displayed by
-@smallexample
-@code{EVENT (<event length>)}
-@end smallexample
-where @code{(<event length>)} is optional.
-@item
-@emph{Buffer Mode} which is displayed by
-@smallexample
-@code{BUFFER (<buffer length>)<buffer element mode>}
-@end smallexample
-where @code{(<buffer length>)} is optional.
-@end itemize
-
-@item @r{@emph{Timing Modes:}}
-@itemize @bullet
-@item
-@emph{Duration Mode} which is predefined by @code{DURATION}
-@item
-@emph{Absolute Time Mode} which is predefined by @code{TIME}
-@end itemize
-
-@item @r{@emph{Real Modes:}}
-Real Modes are predefined with @code{REAL} and @code{LONG_REAL}.
+@node Unsupported languages
+@section Unsupported languages
-@item @r{@emph{String Modes:}}
-@itemize @bullet
-@item
-@emph{Character String Mode} which is displayed by
-@smallexample
-@code{CHARS(<string length>)}
-@end smallexample
-followed by the keyword @code{VARYING} if the String Mode is a varying
-mode
-@item
-@emph{Bit String Mode} which is displayed by
-@smallexample
-@code{BOOLS(<string
-length>)}
-@end smallexample
-@end itemize
-
-@item @r{@emph{Array Mode:}}
-The Array Mode is displayed by the keyword @code{ARRAY(<range>)}
-followed by the element mode (which may in turn be an array mode).
-@smallexample
-(@value{GDBP}) ptype x
-type = ARRAY (1:42)
- ARRAY (1:20)
- SET (karli = 10, susi = 20, fritzi = 100)
-@end smallexample
-
-@item @r{@emph{Structure Mode}}
-The Structure mode is displayed by the keyword @code{STRUCT(<field
-list>)}. The @code{<field list>} consists of names and modes of fields
-of the structure. Variant structures have the keyword @code{CASE <field>
-OF <variant fields> ESAC} in their field list. Since the current version
-of the GNU Chill compiler doesn't implement tag processing (no runtime
-checks of variant fields, and therefore no debugging info), the output
-always displays all variant fields.
-@smallexample
-(@value{GDBP}) ptype str
-type = STRUCT (
- as x,
- bs x,
- CASE bs OF
- (karli):
- cs a
- (ott):
- ds x
- ESAC
-)
-@end smallexample
-@end table
-
-@node Locations
-@subsubsection Locations and their accesses
-
-A location in Chill is an object which can contain values.
-
-A value of a location is generally accessed by the (declared) name of
-the location. The output conforms to the specification of values in
-Chill programs. How values are specified
-is the topic of the next section, @ref{Values and their Operations}.
-
-The pseudo-location @code{RESULT} (or @code{result}) can be used to
-display or change the result of a currently-active procedure:
-
-@smallexample
-set result := EXPR
-@end smallexample
-
-@noindent
-This does the same as the Chill action @code{RESULT EXPR} (which
-is not available in @value{GDBN}).
-
-Values of reference mode locations are printed by @code{PTR(<hex
-value>)} in case of a free reference mode, and by @code{(REF <reference
-mode>) (<hex-value>)} in case of a bound reference. @code{<hex value>}
-represents the address where the reference points to. To access the
-value of the location referenced by the pointer, use the dereference
-operator @samp{->}.
-
-Values of procedure mode locations are displayed by
-@smallexample
-@code{@{ PROC
-(<argument modes> ) <return mode> @} <address> <name of procedure
-location>}
-@end smallexample
-@code{<argument modes>} is a list of modes according to the parameter
-specification of the procedure and @code{<address>} shows the address of
-the entry point.
-
-@ignore
-Locations of instance modes are displayed just like a structure with two
-fields specifying the @emph{process type} and the @emph{copy number} of
-the investigated instance location@footnote{This comes from the current
-implementation of instances. They are implemented as a structure (no
-na). The output should be something like @code{[<name of the process>;
-<instance number>]}.}. The field names are @code{__proc_type} and
-@code{__proc_copy}.
-
-Locations of synchronization modes are displayed like a structure with
-the field name @code{__event_data} in case of a event mode location, and
-like a structure with the field @code{__buffer_data} in case of a buffer
-mode location (refer to previous paragraph).
-
-Structure Mode locations are printed by @code{[.<field name>: <value>,
-...]}. The @code{<field name>} corresponds to the structure mode
-definition and the layout of @code{<value>} varies depending of the mode
-of the field. If the investigated structure mode location is of variant
-structure mode, the variant parts of the structure are enclosed in curled
-braces (@samp{@{@}}). Fields enclosed by @samp{@{,@}} are residing
-on the same memory location and represent the current values of the
-memory location in their specific modes. Since no tag processing is done
-all variants are displayed. A variant field is printed by
-@code{(<variant name>) = .<field name>: <value>}. (who implements the
-stuff ???)
-@smallexample
-(@value{GDBP}) print str1 $4 = [.as: 0, .bs: karli, .<TAG>: { (karli) =
-[.cs: []], (susi) = [.ds: susi]}]
-@end smallexample
-@end ignore
-
-Substructures of string mode-, array mode- or structure mode-values
-(e.g. array slices, fields of structure locations) are accessed using
-certain operations which are described in the next section, @ref{Values
-and their Operations}.
-
-A location value may be interpreted as having a different mode using the
-location conversion. This mode conversion is written as @code{<mode
-name>(<location>)}. The user has to consider that the sizes of the modes
-have to be equal otherwise an error occurs. Furthermore, no range
-checking of the location against the destination mode is performed, and
-therefore the result can be quite confusing.
-
-@smallexample
-(@value{GDBP}) print int (s(3 up 4)) XXX TO be filled in !! XXX
-@end smallexample
-
-@node Values and their Operations
-@subsubsection Values and their Operations
-
-Values are used to alter locations, to investigate complex structures in
-more detail or to filter relevant information out of a large amount of
-data. There are several (mode dependent) operations defined which enable
-such investigations. These operations are not only applicable to
-constant values but also to locations, which can become quite useful
-when debugging complex structures. During parsing the command line
-(e.g. evaluating an expression) @value{GDBN} treats location names as
-the values behind these locations.
-
-This section describes how values have to be specified and which
-operations are legal to be used with such values.
-
-@table @code
-@item Literal Values
-Literal values are specified in the same manner as in @sc{gnu} Chill programs.
-For detailed specification refer to the @sc{gnu} Chill implementation Manual
-chapter 1.5.
-@c FIXME: if the Chill Manual is a Texinfo documents, the above should
-@c be converted to a @ref.
-
-@ignore
-@itemize @bullet
-@item
-@emph{Integer Literals} are specified in the same manner as in Chill
-programs (refer to the Chill Standard z200/88 chpt 5.2.4.2)
-@item
-@emph{Boolean Literals} are defined by @code{TRUE} and @code{FALSE}.
-@item
-@emph{Character Literals} are defined by @code{'<character>'}. (e.g.
-@code{'M'})
-@item
-@emph{Set Literals} are defined by a name which was specified in a set
-mode. The value delivered by a Set Literal is the set value. This is
-comparable to an enumeration in C/C@t{++} language.
-@item
-@emph{Emptiness Literal} is predefined by @code{NULL}. The value of the
-emptiness literal delivers either the empty reference value, the empty
-procedure value or the empty instance value.
-
-@item
-@emph{Character String Literals} are defined by a sequence of characters
-enclosed in single- or double quotes. If a single- or double quote has
-to be part of the string literal it has to be stuffed (specified twice).
-@item
-@emph{Bitstring Literals} are specified in the same manner as in Chill
-programs (refer z200/88 chpt 5.2.4.8).
-@item
-@emph{Floating point literals} are specified in the same manner as in
-(gnu-)Chill programs (refer @sc{gnu} Chill implementation Manual chapter 1.5).
-@end itemize
-@end ignore
-
-@item Tuple Values
-A tuple is specified by @code{<mode name>[<tuple>]}, where @code{<mode
-name>} can be omitted if the mode of the tuple is unambiguous. This
-unambiguity is derived from the context of a evaluated expression.
-@code{<tuple>} can be one of the following:
-
-@itemize @bullet
-@item @emph{Powerset Tuple}
-@item @emph{Array Tuple}
-@item @emph{Structure Tuple}
-Powerset tuples, array tuples and structure tuples are specified in the
-same manner as in Chill programs refer to z200/88 chpt 5.2.5.
-@end itemize
+@cindex unsupported languages
+@cindex minimal language
+In addition to the other fully-supported programming languages,
+@value{GDBN} also provides a pseudo-language, called @code{minimal}.
+It does not represent a real programming language, but provides a set
+of capabilities close to what the C or assembly languages provide.
+This should allow most simple operations to be performed while debugging
+an application that uses a language currently not supported by @value{GDBN}.
-@item String Element Value
-A string element value is specified by
-@smallexample
-@code{<string value>(<index>)}
-@end smallexample
-where @code{<index>} is a integer expression. It delivers a character
-value which is equivalent to the character indexed by @code{<index>} in
-the string.
-
-@item String Slice Value
-A string slice value is specified by @code{<string value>(<slice
-spec>)}, where @code{<slice spec>} can be either a range of integer
-expressions or specified by @code{<start expr> up <size>}.
-@code{<size>} denotes the number of elements which the slice contains.
-The delivered value is a string value, which is part of the specified
-string.
-
-@item Array Element Values
-An array element value is specified by @code{<array value>(<expr>)} and
-delivers a array element value of the mode of the specified array.
-
-@item Array Slice Values
-An array slice is specified by @code{<array value>(<slice spec>)}, where
-@code{<slice spec>} can be either a range specified by expressions or by
-@code{<start expr> up <size>}. @code{<size>} denotes the number of
-arrayelements the slice contains. The delivered value is an array value
-which is part of the specified array.
-
-@item Structure Field Values
-A structure field value is derived by @code{<structure value>.<field
-name>}, where @code{<field name>} indicates the name of a field specified
-in the mode definition of the structure. The mode of the delivered value
-corresponds to this mode definition in the structure definition.
-
-@item Procedure Call Value
-The procedure call value is derived from the return value of the
-procedure@footnote{If a procedure call is used for instance in an
-expression, then this procedure is called with all its side
-effects. This can lead to confusing results if used carelessly.}.
-
-Values of duration mode locations are represented by @code{ULONG} literals.
-
-Values of time mode locations appear as
-@smallexample
-@code{TIME(<secs>:<nsecs>)}
-@end smallexample
-
-
-@ignore
-This is not implemented yet:
-@item Built-in Value
-@noindent
-The following built in functions are provided:
-
-@table @code
-@item @code{ADDR()}
-@item @code{NUM()}
-@item @code{PRED()}
-@item @code{SUCC()}
-@item @code{ABS()}
-@item @code{CARD()}
-@item @code{MAX()}
-@item @code{MIN()}
-@item @code{SIZE()}
-@item @code{UPPER()}
-@item @code{LOWER()}
-@item @code{LENGTH()}
-@item @code{SIN()}
-@item @code{COS()}
-@item @code{TAN()}
-@item @code{ARCSIN()}
-@item @code{ARCCOS()}
-@item @code{ARCTAN()}
-@item @code{EXP()}
-@item @code{LN()}
-@item @code{LOG()}
-@item @code{SQRT()}
-@end table
-
-For a detailed description refer to the GNU Chill implementation manual
-chapter 1.6.
-@end ignore
-
-@item Zero-adic Operator Value
-The zero-adic operator value is derived from the instance value for the
-current active process.
-
-@item Expression Values
-The value delivered by an expression is the result of the evaluation of
-the specified expression. If there are error conditions (mode
-incompatibility, etc.) the evaluation of expressions is aborted with a
-corresponding error message. Expressions may be parenthesised which
-causes the evaluation of this expression before any other expression
-which uses the result of the parenthesised expression. The following
-operators are supported by @value{GDBN}:
-
-@table @code
-@item @code{OR, ORIF, XOR}
-@itemx @code{AND, ANDIF}
-@itemx @code{NOT}
-Logical operators defined over operands of boolean mode.
-
-@item @code{=, /=}
-Equality and inequality operators defined over all modes.
-
-@item @code{>, >=}
-@itemx @code{<, <=}
-Relational operators defined over predefined modes.
-
-@item @code{+, -}
-@itemx @code{*, /, MOD, REM}
-Arithmetic operators defined over predefined modes.
-
-@item @code{-}
-Change sign operator.
-
-@item @code{//}
-String concatenation operator.
-
-@item @code{()}
-String repetition operator.
-
-@item @code{->}
-Referenced location operator which can be used either to take the
-address of a location (@code{->loc}), or to dereference a reference
-location (@code{loc->}).
-
-@item @code{OR, XOR}
-@itemx @code{AND}
-@itemx @code{NOT}
-Powerset and bitstring operators.
-
-@item @code{>, >=}
-@itemx @code{<, <=}
-Powerset inclusion operators.
-
-@item @code{IN}
-Membership operator.
-@end table
-@end table
-
-@node Chill type and range checks
-@subsubsection Chill type and range checks
-
-@value{GDBN} considers two Chill variables mode equivalent if the sizes
-of the two modes are equal. This rule applies recursively to more
-complex datatypes which means that complex modes are treated
-equivalent if all element modes (which also can be complex modes like
-structures, arrays, etc.) have the same size.
-
-Range checking is done on all mathematical operations, assignment, array
-index bounds and all built in procedures.
-
-Strong type checks are forced using the @value{GDBN} command @code{set
-check strong}. This enforces strong type and range checks on all
-operations where Chill constructs are used (expressions, built in
-functions, etc.) in respect to the semantics as defined in the z.200
-language specification.
-
-All checks can be disabled by the @value{GDBN} command @code{set check
-off}.
-
-@ignore
-@c Deviations from the Chill Standard Z200/88
-see last paragraph ?
-@end ignore
-
-@node Chill defaults
-@subsubsection Chill defaults
-
-If type and range checking are set automatically by @value{GDBN}, they
-both default to @code{on} whenever the working language changes to
-Chill. This happens regardless of whether you or @value{GDBN}
-selected the working language.
-
-If you allow @value{GDBN} to set the language automatically, then entering
-code compiled from a file whose name ends with @file{.ch} sets the
-working language to Chill. @xref{Automatically, ,Having @value{GDBN} set
-the language automatically}, for further details.
+If the language is set to @code{auto}, @value{GDBN} will automatically
+select this language if the current frame corresponds to an unsupported
+language.
@node Symbols
@chapter Examining the Symbol Table
@@ -8580,9 +9112,9 @@ ordinarily parse a typical file name, like @file{foo.c}, as the three words
@samp{foo} @samp{.} @samp{c}. To allow @value{GDBN} to recognize
@samp{foo.c} as a single symbol, enclose it in single quotes; for example,
-@example
+@smallexample
p 'foo.c'::x
-@end example
+@end smallexample
@noindent
looks up the value of @code{x} in the scope of the file @file{foo.c}.
@@ -8607,10 +9139,10 @@ Print the name of a symbol which is stored at the address @var{addr}.
If no symbol is stored exactly at @var{addr}, @value{GDBN} prints the
nearest symbol and an offset from it:
-@example
+@smallexample
(@value{GDBP}) info symbol 0x54320
_initialize_vx + 396 in section .text
-@end example
+@end smallexample
@noindent
This is the opposite of the @code{info address} command. You can use
@@ -8641,14 +9173,14 @@ of just the name of the type.
For example, for this variable declaration:
-@example
+@smallexample
struct complex @{double real; double imag;@} v;
-@end example
+@end smallexample
@noindent
the two commands give this output:
-@example
+@smallexample
@group
(@value{GDBP}) whatis v
type = struct complex
@@ -8658,7 +9190,7 @@ type = struct complex @{
double imag;
@}
@end group
-@end example
+@end smallexample
@noindent
As with @code{whatis}, using @code{ptype} without an argument refers to
@@ -8705,9 +9237,25 @@ collect}.
@kindex info source
@item info source
-Show the name of the current source file---that is, the source file for
-the function containing the current point of execution---and the language
-it was written in.
+Show information about the current source file---that is, the source file for
+the function containing the current point of execution:
+@itemize @bullet
+@item
+the name of the source file, and the directory containing it,
+@item
+the directory it was compiled in,
+@item
+its length, in lines,
+@item
+which programming language it is written in,
+@item
+whether the executable includes debugging information for that file, and
+if so, what format the information is in (e.g., STABS, Dwarf 2, etc.), and
+@item
+whether the debugging information includes information about
+preprocessor macros.
+@end itemize
+
@kindex info sources
@item info sources
@@ -8724,8 +9272,8 @@ Print the names and data types of all defined functions
whose names contain a match for regular expression @var{regexp}.
Thus, @samp{info fun step} finds all functions whose names
include @code{step}; @samp{info fun ^step} finds those whose names
-start with @code{step}. If a function name contains characters
-that conflict with the regular expression language (eg.
+start with @code{step}. If a function name contains characters
+that conflict with the regular expression language (eg.
@samp{operator*()}), they may be quoted with a backslash.
@kindex info variables
@@ -8738,6 +9286,20 @@ Print the names and data types of all variables (except for local
variables) whose names contain a match for regular expression
@var{regexp}.
+@kindex info classes
+@item info classes
+@itemx info classes @var{regexp}
+Display all Objective-C classes in your program, or
+(with the @var{regexp} argument) all those matching a particular regular
+expression.
+
+@kindex info selectors
+@item info selectors
+@itemx info selectors @var{regexp}
+Display all Objective-C selectors in your program, or
+(with the @var{regexp} argument) all those matching a particular regular
+expression.
+
@ignore
This was never implemented.
@kindex info methods
@@ -8822,8 +9384,66 @@ files that @value{GDBN} has skimmed, but not yet read completely. Finally,
required for each object file from which @value{GDBN} has read some symbols.
@xref{Files, ,Commands to specify files}, for a discussion of how
@value{GDBN} reads symbols (in the description of @code{symbol-file}).
+
+@kindex maint info symtabs
+@kindex maint info psymtabs
+@cindex listing @value{GDBN}'s internal symbol tables
+@cindex symbol tables, listing @value{GDBN}'s internal
+@cindex full symbol tables, listing @value{GDBN}'s internal
+@cindex partial symbol tables, listing @value{GDBN}'s internal
+@item maint info symtabs @r{[} @var{regexp} @r{]}
+@itemx maint info psymtabs @r{[} @var{regexp} @r{]}
+
+List the @code{struct symtab} or @code{struct partial_symtab}
+structures whose names match @var{regexp}. If @var{regexp} is not
+given, list them all. The output includes expressions which you can
+copy into a @value{GDBN} debugging this one to examine a particular
+structure in more detail. For example:
+
+@smallexample
+(@value{GDBP}) maint info psymtabs dwarf2read
+@{ objfile /home/gnu/build/gdb/gdb
+ ((struct objfile *) 0x82e69d0)
+ @{ psymtab /home/gnu/src/gdb/dwarf2read.c
+ ((struct partial_symtab *) 0x8474b10)
+ readin no
+ fullname (null)
+ text addresses 0x814d3c8 -- 0x8158074
+ globals (* (struct partial_symbol **) 0x8507a08 @@ 9)
+ statics (* (struct partial_symbol **) 0x40e95b78 @@ 2882)
+ dependencies (none)
+ @}
+@}
+(@value{GDBP}) maint info symtabs
+(@value{GDBP})
+@end smallexample
+@noindent
+We see that there is one partial symbol table whose filename contains
+the string @samp{dwarf2read}, belonging to the @samp{gdb} executable;
+and we see that @value{GDBN} has not read in any symtabs yet at all.
+If we set a breakpoint on a function, that will cause @value{GDBN} to
+read the symtab for the compilation unit containing that function:
+
+@smallexample
+(@value{GDBP}) break dwarf2_psymtab_to_symtab
+Breakpoint 1 at 0x814e5da: file /home/gnu/src/gdb/dwarf2read.c,
+line 1574.
+(@value{GDBP}) maint info symtabs
+@{ objfile /home/gnu/build/gdb/gdb
+ ((struct objfile *) 0x82e69d0)
+ @{ symtab /home/gnu/src/gdb/dwarf2read.c
+ ((struct symtab *) 0x86c1f38)
+ dirname (null)
+ fullname (null)
+ blockvector ((struct blockvector *) 0x86c1bd0) (primary)
+ debugformat DWARF 2
+ @}
+@}
+(@value{GDBP})
+@end smallexample
@end table
+
@node Altering
@chapter Altering Execution
@@ -8854,9 +9474,9 @@ address, or even return prematurely from a function.
To alter the value of a variable, evaluate an assignment expression.
@xref{Expressions, ,Expressions}. For example,
-@example
+@smallexample
print x=4
-@end example
+@end smallexample
@noindent
stores the value 4 into the variable @code{x}, and then prints the
@@ -8880,22 +9500,22 @@ program has a variable @code{width}, you get an error if you try to set
a new value with just @samp{set width=13}, because @value{GDBN} has the
command @code{set width}:
-@example
+@smallexample
(@value{GDBP}) whatis width
type = double
(@value{GDBP}) p width
$4 = 13
(@value{GDBP}) set width=47
Invalid syntax in expression.
-@end example
+@end smallexample
@noindent
The invalid expression, of course, is @samp{=47}. In
order to actually set the program's variable @code{width}, use
-@example
+@smallexample
(@value{GDBP}) set var width=47
-@end example
+@end smallexample
Because the @code{set} command has many subcommands that can conflict
with the names of program variables, it is a good idea to use the
@@ -8904,7 +9524,7 @@ your program has a variable @code{g}, you run into problems if you try
to set a new value with just @samp{set g=4}, because @value{GDBN} has
the command @code{set gnutarget}, abbreviated @code{set g}:
-@example
+@smallexample
@group
(@value{GDBP}) whatis g
type = double
@@ -8922,16 +9542,16 @@ Starting program: /home/smith/cc_progs/a.out
(@value{GDBP}) show g
The current BFD target is "=4".
@end group
-@end example
+@end smallexample
@noindent
The program variable @code{g} did not change, and you silently set the
@code{gnutarget} to an invalid value. In order to set the variable
@code{g}, use
-@example
+@smallexample
(@value{GDBP}) set var g=4
-@end example
+@end smallexample
@value{GDBN} allows more implicit conversions in assignments than C; you can
freely store an integer value into a pointer variable or vice versa,
@@ -8946,9 +9566,9 @@ construct to generate a value of specified type at a specified address
to memory location @code{0x83040} as an integer (which implies a certain size
and representation in memory), and
-@example
+@smallexample
set @{int@}0x83040 = 4
-@end example
+@end smallexample
@noindent
stores the value 4 into that memory location.
@@ -8991,9 +9611,9 @@ difference is that this does not start your program running; it only
changes the address of where it @emph{will} run when you continue. For
example,
-@example
+@smallexample
set $pc = 0x485
-@end example
+@end smallexample
@noindent
makes the next @code{continue} command or stepping command execute at
@@ -9082,12 +9702,6 @@ execute a function from your program, but without cluttering the output
with @code{void} returned values. If the result is not void, it
is printed and saved in the value history.
-@c OBSOLETE For the A29K, a user-controlled variable @code{call_scratch_address},
-@c OBSOLETE specifies the location of a scratch area to be used when @value{GDBN}
-@c OBSOLETE calls a function in the target. This is necessary because the usual
-@c OBSOLETE method of putting the scratch area on the stack does not work in systems
-@c OBSOLETE that have separate instruction and data spaces.
-
@node Patching
@section Patching programs
@@ -9133,6 +9747,7 @@ program. To debug a core dump of a previous run, you must also tell
@menu
* Files:: Commands to specify files
+* Separate Debug Files:: Debugging information in separate files
* Symbol Errors:: Errors reading symbol files
@end menu
@@ -9338,7 +9953,7 @@ Some embedded operating systems, like Sun Chorus and VxWorks, can load
relocatable files into an already running program; such systems
typically make the requirements above easy to meet. However, it's
important to recognize that many native systems use complex link
-procedures (@code{.linkonce} section factoring and C++ constructor table
+procedures (@code{.linkonce} section factoring and C@t{++} constructor table
assembly, for example) that make the requirements difficult to meet. In
general, one cannot assume that using @code{add-symbol-file} to read a
relocatable object file's symbolic information will have the same effect
@@ -9537,6 +10152,233 @@ Mb).
Display the current autoloading size threshold, in megabytes.
@end table
+Shared libraries are also supported in many cross or remote debugging
+configurations. A copy of the target's libraries need to be present on the
+host system; they need to be the same as the target libraries, although the
+copies on the target can be stripped as long as the copies on the host are
+not.
+
+You need to tell @value{GDBN} where the target libraries are, so that it can
+load the correct copies---otherwise, it may try to load the host's libraries.
+@value{GDBN} has two variables to specify the search directories for target
+libraries.
+
+@table @code
+@kindex set solib-absolute-prefix
+@item set solib-absolute-prefix @var{path}
+If this variable is set, @var{path} will be used as a prefix for any
+absolute shared library paths; many runtime loaders store the absolute
+paths to the shared library in the target program's memory. If you use
+@samp{solib-absolute-prefix} to find shared libraries, they need to be laid
+out in the same way that they are on the target, with e.g.@: a
+@file{/usr/lib} hierarchy under @var{path}.
+
+You can set the default value of @samp{solib-absolute-prefix} by using the
+configure-time @samp{--with-sysroot} option.
+
+@kindex show solib-absolute-prefix
+@item show solib-absolute-prefix
+Display the current shared library prefix.
+
+@kindex set solib-search-path
+@item set solib-search-path @var{path}
+If this variable is set, @var{path} is a colon-separated list of directories
+to search for shared libraries. @samp{solib-search-path} is used after
+@samp{solib-absolute-prefix} fails to locate the library, or if the path to
+the library is relative instead of absolute. If you want to use
+@samp{solib-search-path} instead of @samp{solib-absolute-prefix}, be sure to
+set @samp{solib-absolute-prefix} to a nonexistant directory to prevent
+@value{GDBN} from finding your host's libraries.
+
+@kindex show solib-search-path
+@item show solib-search-path
+Display the current shared library search path.
+@end table
+
+
+@node Separate Debug Files
+@section Debugging Information in Separate Files
+@cindex separate debugging information files
+@cindex debugging information in separate files
+@cindex @file{.debug} subdirectories
+@cindex debugging information directory, global
+@cindex global debugging information directory
+
+@value{GDBN} allows you to put a program's debugging information in a
+file separate from the executable itself, in a way that allows
+@value{GDBN} to find and load the debugging information automatically.
+Since debugging information can be very large --- sometimes larger
+than the executable code itself --- some systems distribute debugging
+information for their executables in separate files, which users can
+install only when they need to debug a problem.
+
+If an executable's debugging information has been extracted to a
+separate file, the executable should contain a @dfn{debug link} giving
+the name of the debugging information file (with no directory
+components), and a checksum of its contents. (The exact form of a
+debug link is described below.) If the full name of the directory
+containing the executable is @var{execdir}, and the executable has a
+debug link that specifies the name @var{debugfile}, then @value{GDBN}
+will automatically search for the debugging information file in three
+places:
+
+@itemize @bullet
+@item
+the directory containing the executable file (that is, it will look
+for a file named @file{@var{execdir}/@var{debugfile}},
+@item
+a subdirectory of that directory named @file{.debug} (that is, the
+file @file{@var{execdir}/.debug/@var{debugfile}}, and
+@item
+a subdirectory of the global debug file directory that includes the
+executable's full path, and the name from the link (that is, the file
+@file{@var{globaldebugdir}/@var{execdir}/@var{debugfile}}, where
+@var{globaldebugdir} is the global debug file directory, and
+@var{execdir} has been turned into a relative path).
+@end itemize
+@noindent
+@value{GDBN} checks under each of these names for a debugging
+information file whose checksum matches that given in the link, and
+reads the debugging information from the first one it finds.
+
+So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls},
+which has a link containing the name @file{ls.debug}, and the global
+debug directory is @file{/usr/lib/debug}, then @value{GDBN} will look
+for debug information in @file{/usr/bin/ls.debug},
+@file{/usr/bin/.debug/ls.debug}, and
+@file{/usr/lib/debug/usr/bin/ls.debug}.
+
+You can set the global debugging info directory's name, and view the
+name @value{GDBN} is currently using.
+
+@table @code
+
+@kindex set debug-file-directory
+@item set debug-file-directory @var{directory}
+Set the directory which @value{GDBN} searches for separate debugging
+information files to @var{directory}.
+
+@kindex show debug-file-directory
+@item show debug-file-directory
+Show the directory @value{GDBN} searches for separate debugging
+information files.
+
+@end table
+
+@cindex @code{.gnu_debuglink} sections
+@cindex debug links
+A debug link is a special section of the executable file named
+@code{.gnu_debuglink}. The section must contain:
+
+@itemize
+@item
+A filename, with any leading directory components removed, followed by
+a zero byte,
+@item
+zero to three bytes of padding, as needed to reach the next four-byte
+boundary within the section, and
+@item
+a four-byte CRC checksum, stored in the same endianness used for the
+executable file itself. The checksum is computed on the debugging
+information file's full contents by the function given below, passing
+zero as the @var{crc} argument.
+@end itemize
+
+Any executable file format can carry a debug link, as long as it can
+contain a section named @code{.gnu_debuglink} with the contents
+described above.
+
+The debugging information file itself should be an ordinary
+executable, containing a full set of linker symbols, sections, and
+debugging information. The sections of the debugging information file
+should have the same names, addresses and sizes as the original file,
+but they need not contain any data --- much like a @code{.bss} section
+in an ordinary executable.
+
+As of December 2002, there is no standard GNU utility to produce
+separated executable / debugging information file pairs. Ulrich
+Drepper's @file{elfutils} package, starting with version 0.53,
+contains a version of the @code{strip} command such that the command
+@kbd{strip foo -f foo.debug} removes the debugging information from
+the executable file @file{foo}, places it in the file
+@file{foo.debug}, and leaves behind a debug link in @file{foo}.
+
+Since there are many different ways to compute CRC's (different
+polynomials, reversals, byte ordering, etc.), the simplest way to
+describe the CRC used in @code{.gnu_debuglink} sections is to give the
+complete code for a function that computes it:
+
+@kindex @code{gnu_debuglink_crc32}
+@smallexample
+unsigned long
+gnu_debuglink_crc32 (unsigned long crc,
+ unsigned char *buf, size_t len)
+@{
+ static const unsigned long crc32_table[256] =
+ @{
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d
+ @};
+ unsigned char *end;
+
+ crc = ~crc & 0xffffffff;
+ for (end = buf + len; buf < end; ++buf)
+ crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+ return ~crc & 0xffffffff;
+@}
+@end smallexample
+
+
@node Symbol Errors
@section Errors reading symbol files
@@ -9765,11 +10607,11 @@ it somewhere in memory where it won't get clobbered by the download.
@item target sim
Builtin CPU simulator. @value{GDBN} includes simulators for most architectures.
In general,
-@example
+@smallexample
target sim
load
run
-@end example
+@end smallexample
@noindent
works; however, you cannot assume that a specific memory map, device
drivers, or even basic I/O is available, although some simulators do
@@ -9825,7 +10667,7 @@ specifies a fixed address.
@cindex choosing target byte order
@cindex target byte order
-Some types of processors, such as the MIPS, PowerPC, and Hitachi SH,
+Some types of processors, such as the MIPS, PowerPC, and Renesas SH,
offer the ability to run either big-endian or little-endian byte
orders. Usually the executable or symbol will include a bit to
designate the endian-ness, and you will not need to worry about
@@ -9877,9 +10719,7 @@ configuration of @value{GDBN}; use @code{help target} to list them.
@node KOD
@section Kernel Object Display
-
@cindex kernel object display
-@cindex kernel object
@cindex KOD
Some targets support kernel object display. Using this facility,
@@ -9888,41 +10728,151 @@ and can display information about operating system-level objects such as
mutexes and other synchronization objects. Exactly which objects can be
displayed is determined on a per-OS basis.
+@kindex set os
Use the @code{set os} command to set the operating system. This tells
@value{GDBN} which kernel object display module to initialize:
-@example
+@smallexample
(@value{GDBP}) set os cisco
-@end example
+@end smallexample
+
+@kindex show os
+The associated command @code{show os} displays the operating system
+set with the @code{set os} command; if no operating system has been
+set, @code{show os} will display an empty string @samp{""}.
If @code{set os} succeeds, @value{GDBN} will display some information
about the operating system, and will create a new @code{info} command
which can be used to query the target. The @code{info} command is named
after the operating system:
-@example
+@kindex info cisco
+@smallexample
(@value{GDBP}) info cisco
List of Cisco Kernel Objects
Object Description
any Any and all objects
-@end example
+@end smallexample
Further subcommands can be used to query about particular objects known
by the kernel.
-There is currently no way to determine whether a given operating system
-is supported other than to try it.
+There is currently no way to determine whether a given operating
+system is supported other than to try setting it with @kbd{set os
+@var{name}}, where @var{name} is the name of the operating system you
+want to try.
@node Remote Debugging
@chapter Debugging remote programs
@menu
+* Connecting:: Connecting to a remote target
* Server:: Using the gdbserver program
* NetWare:: Using the gdbserve.nlm program
+* Remote configuration:: Remote configuration
* remote stub:: Implementing a remote stub
@end menu
+@node Connecting
+@section Connecting to a remote target
+
+On the @value{GDBN} host machine, you will need an unstripped copy of
+your program, since @value{GDBN} needs symobl and debugging information.
+Start up @value{GDBN} as usual, using the name of the local copy of your
+program as the first argument.
+
+@cindex serial line, @code{target remote}
+If you're using a serial line, you may want to give @value{GDBN} the
+@w{@samp{--baud}} option, or use the @code{set remotebaud} command
+before the @code{target} command.
+
+After that, use @code{target remote} to establish communications with
+the target machine. Its argument specifies how to communicate---either
+via a devicename attached to a direct serial line, or a TCP or UDP port
+(possibly to a terminal server which in turn has a serial line to the
+target). For example, to use a serial line connected to the device
+named @file{/dev/ttyb}:
+
+@smallexample
+target remote /dev/ttyb
+@end smallexample
+
+@cindex TCP port, @code{target remote}
+To use a TCP connection, use an argument of the form
+@code{@var{host}:@var{port}} or @code{tcp:@var{host}:@var{port}}.
+For example, to connect to port 2828 on a
+terminal server named @code{manyfarms}:
+
+@smallexample
+target remote manyfarms:2828
+@end smallexample
+
+If your remote target is actually running on the same machine as
+your debugger session (e.g.@: a simulator of your target running on
+the same host), you can omit the hostname. For example, to connect
+to port 1234 on your local machine:
+
+@smallexample
+target remote :1234
+@end smallexample
+@noindent
+
+Note that the colon is still required here.
+
+@cindex UDP port, @code{target remote}
+To use a UDP connection, use an argument of the form
+@code{udp:@var{host}:@var{port}}. For example, to connect to UDP port 2828
+on a terminal server named @code{manyfarms}:
+
+@smallexample
+target remote udp:manyfarms:2828
+@end smallexample
+
+When using a UDP connection for remote debugging, you should keep in mind
+that the `U' stands for ``Unreliable''. UDP can silently drop packets on
+busy or unreliable networks, which will cause havoc with your debugging
+session.
+
+Now you can use all the usual commands to examine and change data and to
+step and continue the remote program.
+
+@cindex interrupting remote programs
+@cindex remote programs, interrupting
+Whenever @value{GDBN} is waiting for the remote program, if you type the
+interrupt character (often @key{C-C}), @value{GDBN} attempts to stop the
+program. This may or may not succeed, depending in part on the hardware
+and the serial drivers the remote system uses. If you type the
+interrupt character once again, @value{GDBN} displays this prompt:
+
+@smallexample
+Interrupted while waiting for the program.
+Give up (and stop debugging it)? (y or n)
+@end smallexample
+
+If you type @kbd{y}, @value{GDBN} abandons the remote debugging session.
+(If you decide you want to try again later, you can use @samp{target
+remote} again to connect once more.) If you type @kbd{n}, @value{GDBN}
+goes back to waiting.
+
+@table @code
+@kindex detach (remote)
+@item detach
+When you have finished debugging the remote program, you can use the
+@code{detach} command to release it from @value{GDBN} control.
+Detaching from the target normally resumes its execution, but the results
+will depend on your particular remote stub. After the @code{detach}
+command, @value{GDBN} is free to connect to another target.
+
+@kindex disconnect
+@item disconnect
+The @code{disconnect} command behaves like @code{detach}, except that
+the target is generally not resumed. It will wait for @value{GDBN}
+(this instance or another one) to connect and continue debugging. After
+the @code{disconnect} command, @value{GDBN} is again free to connect to
+another target.
+@end table
+
@node Server
@section Using the @code{gdbserver} program
@@ -10005,34 +10955,28 @@ target> gdbserver @var{comm} --attach @var{pid}
@var{pid} is the process ID of a currently running process. It isn't necessary
to point @code{gdbserver} at a binary for the running process.
-@item On the @value{GDBN} host machine,
-you need an unstripped copy of your program, since @value{GDBN} needs
-symbols and debugging information. Start up @value{GDBN} as usual,
-using the name of the local copy of your program as the first argument.
-(You may also need the @w{@samp{--baud}} option if the serial line is
-running at anything other than 9600@dmn{bps}.) After that, use @code{target
-remote} to establish communications with @code{gdbserver}. Its argument
-is either a device name (usually a serial device, like
-@file{/dev/ttyb}), or a TCP port descriptor in the form
-@code{@var{host}:@var{PORT}}. For example:
+@pindex pidof
+@cindex attach to a program by name
+You can debug processes by name instead of process ID if your target has the
+@code{pidof} utility:
@smallexample
-(@value{GDBP}) target remote /dev/ttyb
+target> gdbserver @var{comm} --attach `pidof @var{PROGRAM}`
@end smallexample
-@noindent
-communicates with the server via serial line @file{/dev/ttyb}, and
-
-@smallexample
-(@value{GDBP}) target remote the-target:2345
-@end smallexample
+In case more than one copy of @var{PROGRAM} is running, or @var{PROGRAM}
+has multiple threads, most versions of @code{pidof} support the
+@code{-s} option to only return the first process ID.
-@noindent
-communicates via a TCP connection to port 2345 on host @w{@file{the-target}}.
+@item On the host machine,
+connect to your target (@pxref{Connecting,,Connecting to a remote target}).
For TCP connections, you must start up @code{gdbserver} prior to using
the @code{target remote} command. Otherwise you may get an error whose
text depends on the host system, but which usually looks something like
-@samp{Connection refused}.
+@samp{Connection refused}. You don't need to use the @code{load}
+command in @value{GDBN} when using gdbserver, since the program is
+already on the target.
+
@end table
@node NetWare
@@ -10074,22 +11018,27 @@ using a 19200@dmn{bps} connection:
load gdbserve BOARD=1 PORT=2 BAUD=19200 emacs foo.txt
@end smallexample
-@item On the @value{GDBN} host machine,
-you need an unstripped copy of your program, since @value{GDBN} needs
-symbols and debugging information. Start up @value{GDBN} as usual,
-using the name of the local copy of your program as the first argument.
-(You may also need the @w{@samp{--baud}} option if the serial line is
-running at anything other than 9600@dmn{bps}. After that, use @code{target
-remote} to establish communications with @code{gdbserve.nlm}. Its
-argument is a device name (usually a serial device, like
-@file{/dev/ttyb}). For example:
+@item
+On the @value{GDBN} host machine, connect to your target (@pxref{Connecting,,
+Connecting to a remote target}).
-@smallexample
-(@value{GDBP}) target remote /dev/ttyb
-@end smallexample
+@end table
-@noindent
-communications with the server via serial line @file{/dev/ttyb}.
+@node Remote configuration
+@section Remote configuration
+
+The following configuration options are available when debugging remote
+programs:
+
+@table @code
+@kindex set remote hardware-watchpoint-limit
+@kindex set remote hardware-breakpoint-limit
+@anchor{set remote hardware-watchpoint-limit}
+@anchor{set remote hardware-breakpoint-limit}
+@item set remote hardware-watchpoint-limit @var{limit}
+@itemx set remote hardware-breakpoint-limit @var{limit}
+Restrict @value{GDBN} to using @var{limit} remote hardware breakpoint or
+watchpoints. A limit of -1, the default, is treated as unlimited.
@end table
@node remote stub
@@ -10172,9 +11121,9 @@ For Motorola 680x0 architectures.
@item sh-stub.c
@cindex @file{sh-stub.c}
-@cindex Hitachi
+@cindex Renesas
@cindex SH
-For Hitachi SH architectures.
+For Renesas SH architectures.
@item sparc-stub.c
@cindex @file{sparc-stub.c}
@@ -10359,18 +11308,18 @@ Make sure you have defined the supporting low-level routines
@item
Insert these lines near the top of your program:
-@example
+@smallexample
set_debug_traps();
breakpoint();
-@end example
+@end smallexample
@item
For the 680x0 stub only, you need to provide a variable called
@code{exceptionHook}. Normally you just use:
-@example
+@smallexample
void (*exceptionHook)() = 0;
-@end example
+@end smallexample
@noindent
but if before calling @code{set_debug_traps}, you set it to point to a
@@ -10394,71 +11343,11 @@ Download your program to your target machine (or get it there by
whatever means the manufacturer provides), and start it.
@item
-To start remote debugging, run @value{GDBN} on the host machine, and specify
-as an executable file the program that is running in the remote machine.
-This tells @value{GDBN} how to find your program's symbols and the contents
-of its pure text.
-
-@item
-@cindex serial line, @code{target remote}
-Establish communication using the @code{target remote} command.
-Its argument specifies how to communicate with the target
-machine---either via a devicename attached to a direct serial line, or a
-TCP port (usually to a terminal server which in turn has a serial line
-to the target). For example, to use a serial line connected to the
-device named @file{/dev/ttyb}:
-
-@example
-target remote /dev/ttyb
-@end example
-
-@cindex TCP port, @code{target remote}
-To use a TCP connection, use an argument of the form
-@code{@var{host}:port}. For example, to connect to port 2828 on a
-terminal server named @code{manyfarms}:
-
-@example
-target remote manyfarms:2828
-@end example
-
-If your remote target is actually running on the same machine as
-your debugger session (e.g.@: a simulator of your target running on
-the same host), you can omit the hostname. For example, to connect
-to port 1234 on your local machine:
-
-@example
-target remote :1234
-@end example
-@noindent
+Start @value{GDBN} on the host, and connect to the target
+(@pxref{Connecting,,Connecting to a remote target}).
-Note that the colon is still required here.
@end enumerate
-Now you can use all the usual commands to examine and change data and to
-step and continue the remote program.
-
-To resume the remote program and stop debugging it, use the @code{detach}
-command.
-
-@cindex interrupting remote programs
-@cindex remote programs, interrupting
-Whenever @value{GDBN} is waiting for the remote program, if you type the
-interrupt character (often @key{C-C}), @value{GDBN} attempts to stop the
-program. This may or may not succeed, depending in part on the hardware
-and the serial drivers the remote system uses. If you type the
-interrupt character once again, @value{GDBN} displays this prompt:
-
-@example
-Interrupted while waiting for the program.
-Give up (and stop debugging it)? (y or n)
-@end example
-
-If you type @kbd{y}, @value{GDBN} abandons the remote debugging session.
-(If you decide you want to try again later, you can use @samp{target
-remote} again to connect once more.) If you type @kbd{n}, @value{GDBN}
-goes back to waiting.
-
-
@node Configurations
@chapter Configuration-Specific Information
@@ -10512,7 +11401,7 @@ this facility, the command @code{info proc} is available to report on
several kinds of information about the process running your program.
@code{info proc} works only on SVR4 systems that include the
@code{procfs} code. This includes OSF/1 (Digital Unix), Solaris, Irix,
-and Unixware, but not HP-UX or Linux, for example.
+and Unixware, but not HP-UX or @sc{gnu}/Linux, for example.
@table @code
@kindex info proc
@@ -10652,10 +11541,10 @@ accepts addresses which may belong to @emph{any} segment. For
example, here's how to display the Page Table entry for the page where
the variable @code{i} is stored:
-@smallexample
+@smallexample
@exdent @code{(@value{GDBP}) info dos address-pte __djgpp_base_address + (char *)&i}
@exdent @code{Page Table entry for address 0x11a00d30:}
-@exdent @code{Base=0x02698000 Dirty Acc. Not-Cached Write-Back Usr Read-Write +0xd30}
+@exdent @code{Base=0x02698000 Dirty Acc. Not-Cached Write-Back Usr Read-Write +0xd30}
@end smallexample
@noindent
@@ -10694,9 +11583,12 @@ This command is supported only with some DPMI servers.
@cindex native Cygwin debugging
@cindex Cygwin-specific commands
-@value{GDBN} supports native debugging of MS Windows programs, and
-defines a few commands specific to the Cygwin port. This
-subsection describes those commands.
+@value{GDBN} supports native debugging of MS Windows programs, including
+DLLs with and without symbolic debugging information. There are various
+additional Cygwin-specific commands, described in this subsection. The
+subsubsection @pxref{Non-debug DLL symbols} describes working with DLLs
+that have no debugging symbols.
+
@table @code
@kindex info w32
@@ -10721,9 +11613,9 @@ This is a Cygwin specific alias of info shared.
This command loads symbols from a dll similarly to
add-sym command but without the need to specify a base address.
-@kindex set new-console
+@kindex set new-console
@item set new-console @var{mode}
-If @var{mode} is @code{on} the debuggee will
+If @var{mode} is @code{on} the debuggee will
be started in a new console on next start.
If @var{mode} is @code{off}i, the debuggee will
be started in the same console as the debugger.
@@ -10750,17 +11642,17 @@ This boolean value adds debug output concerning events seen by the debugger.
@kindex set debugexec
@item set debugexec
-This boolean value adds debug output concerning execute events
+This boolean value adds debug output concerning execute events
seen by the debugger.
@kindex set debugexceptions
@item set debugexceptions
-This boolean value adds debug ouptut concerning exception events
+This boolean value adds debug ouptut concerning exception events
seen by the debugger.
@kindex set debugmemory
@item set debugmemory
-This boolean value adds debug ouptut concerning memory events
+This boolean value adds debug ouptut concerning memory events
seen by the debugger.
@kindex set shell
@@ -10774,6 +11666,130 @@ Displays if the debuggee will be started with a shell.
@end table
+@menu
+* Non-debug DLL symbols:: Support for DLLs without debugging symbols
+@end menu
+
+@node Non-debug DLL symbols
+@subsubsection Support for DLLs without debugging symbols
+@cindex DLLs with no debugging symbols
+@cindex Minimal symbols and DLLs
+
+Very often on windows, some of the DLLs that your program relies on do
+not include symbolic debugging information (for example,
+@file{kernel32.dll}). When @value{GDBN} doesn't recognize any debugging
+symbols in a DLL, it relies on the minimal amount of symbolic
+information contained in the DLL's export table. This subsubsection
+describes working with such symbols, known internally to @value{GDBN} as
+``minimal symbols''.
+
+Note that before the debugged program has started execution, no DLLs
+will have been loaded. The easiest way around this problem is simply to
+start the program --- either by setting a breakpoint or letting the
+program run once to completion. It is also possible to force
+@value{GDBN} to load a particular DLL before starting the executable ---
+see the shared library information in @pxref{Files} or the
+@code{dll-symbols} command in @pxref{Cygwin Native}. Currently,
+explicitly loading symbols from a DLL with no debugging information will
+cause the symbol names to be duplicated in @value{GDBN}'s lookup table,
+which may adversely affect symbol lookup performance.
+
+@subsubsection DLL name prefixes
+
+In keeping with the naming conventions used by the Microsoft debugging
+tools, DLL export symbols are made available with a prefix based on the
+DLL name, for instance @code{KERNEL32!CreateFileA}. The plain name is
+also entered into the symbol table, so @code{CreateFileA} is often
+sufficient. In some cases there will be name clashes within a program
+(particularly if the executable itself includes full debugging symbols)
+necessitating the use of the fully qualified name when referring to the
+contents of the DLL. Use single-quotes around the name to avoid the
+exclamation mark (``!'') being interpreted as a language operator.
+
+Note that the internal name of the DLL may be all upper-case, even
+though the file name of the DLL is lower-case, or vice-versa. Since
+symbols within @value{GDBN} are @emph{case-sensitive} this may cause
+some confusion. If in doubt, try the @code{info functions} and
+@code{info variables} commands or even @code{maint print msymbols} (see
+@pxref{Symbols}). Here's an example:
+
+@smallexample
+(gdb) info function CreateFileA
+All functions matching regular expression "CreateFileA":
+
+Non-debugging symbols:
+0x77e885f4 CreateFileA
+0x77e885f4 KERNEL32!CreateFileA
+@end smallexample
+
+@smallexample
+(gdb) info function !
+All functions matching regular expression "!":
+
+Non-debugging symbols:
+0x6100114c cygwin1!__assert
+0x61004034 cygwin1!_dll_crt0@@0
+0x61004240 cygwin1!dll_crt0(per_process *)
+[etc...]
+@end smallexample
+
+@subsubsection Working with minimal symbols
+
+Symbols extracted from a DLL's export table do not contain very much
+type information. All that @value{GDBN} can do is guess whether a symbol
+refers to a function or variable depending on the linker section that
+contains the symbol. Also note that the actual contents of the memory
+contained in a DLL are not available unless the program is running. This
+means that you cannot examine the contents of a variable or disassemble
+a function within a DLL without a running program.
+
+Variables are generally treated as pointers and dereferenced
+automatically. For this reason, it is often necessary to prefix a
+variable name with the address-of operator (``&'') and provide explicit
+type information in the command. Here's an example of the type of
+problem:
+
+@smallexample
+(gdb) print 'cygwin1!__argv'
+$1 = 268572168
+@end smallexample
+
+@smallexample
+(gdb) x 'cygwin1!__argv'
+0x10021610: "\230y\""
+@end smallexample
+
+And two possible solutions:
+
+@smallexample
+(gdb) print ((char **)'cygwin1!__argv')[0]
+$2 = 0x22fd98 "/cygdrive/c/mydirectory/myprogram"
+@end smallexample
+
+@smallexample
+(gdb) x/2x &'cygwin1!__argv'
+0x610c0aa8 <cygwin1!__argv>: 0x10021608 0x00000000
+(gdb) x/x 0x10021608
+0x10021608: 0x0022fd98
+(gdb) x/s 0x0022fd98
+0x22fd98: "/cygdrive/c/mydirectory/myprogram"
+@end smallexample
+
+Setting a break point within a DLL is possible even before the program
+starts execution. However, under these circumstances, @value{GDBN} can't
+examine the initial instructions of the function in order to skip the
+function's frame set-up code. You can work around this by using ``*&''
+to set the breakpoint at a raw memory address:
+
+@smallexample
+(gdb) break *&'python22!PyOS_Readline'
+Breakpoint 1 at 0x1e04eff0
+@end smallexample
+
+The author of these extensions is not entirely convinced that setting a
+break point within a shared DLL like @file{kernel32.dll} is completely
+safe.
+
@node Embedded OS
@section Embedded Operating Systems
@@ -10845,9 +11861,9 @@ run @value{GDBN}. From your Unix host, run @code{@value{GDBP}} (or
@value{GDBN} comes up showing the prompt:
-@example
+@smallexample
(vxgdb)
-@end example
+@end smallexample
@menu
* VxWorks Connection:: Connecting to VxWorks
@@ -10861,9 +11877,9 @@ run @value{GDBN}. From your Unix host, run @code{@value{GDBP}} (or
The @value{GDBN} command @code{target} lets you connect to a VxWorks target on the
network. To connect to a target whose host name is ``@code{tt}'', type:
-@example
+@smallexample
(vxgdb) target vxworks tt
-@end example
+@end smallexample
@need 750
@value{GDBN} displays messages like these:
@@ -10880,9 +11896,9 @@ these files by searching the directories listed in the command search
path (@pxref{Environment, ,Your program's environment}); if it fails
to find an object file, it displays a message such as:
-@example
+@smallexample
prog.o: No such file or directory.
-@end example
+@end smallexample
When this happens, add the appropriate directory to the search path with
the @value{GDBN} command @code{path}, and execute the @code{target}
@@ -10908,17 +11924,17 @@ the file by its name, without any path. For instance, a program
and in @file{@var{hostpath}/vw/demo/rdb} on the host. To load this
program, type this on VxWorks:
-@example
+@smallexample
-> cd "@var{vxpath}/vw/demo/rdb"
-@end example
+@end smallexample
@noindent
Then, in @value{GDBN}, type:
-@example
+@smallexample
(vxgdb) cd @var{hostpath}/vw/demo/rdb
(vxgdb) load prog.o
-@end example
+@end smallexample
@value{GDBN} displays a response similar to this:
@@ -10941,9 +11957,9 @@ table.)
You can also attach to an existing task using the @code{attach} command as
follows:
-@example
+@smallexample
(vxgdb) attach @var{task}
-@end example
+@end smallexample
@noindent
where @var{task} is the VxWorks hexadecimal task ID. The task can be running
@@ -10957,270 +11973,23 @@ This section goes into details specific to particular embedded
configurations.
-@c OBSOLETE * A29K Embedded:: AMD A29K Embedded
@menu
* ARM:: ARM
-* H8/300:: Hitachi H8/300
-* H8/500:: Hitachi H8/500
-* i960:: Intel i960
-* M32R/D:: Mitsubishi M32R/D
+* H8/300:: Renesas H8/300
+* H8/500:: Renesas H8/500
+* M32R/D:: Renesas M32R/D
* M68K:: Motorola M68K
-* M88K:: Motorola M88K
* MIPS Embedded:: MIPS Embedded
+* OpenRISC 1000:: OpenRisc 1000
* PA:: HP PA Embedded
* PowerPC: PowerPC
-* SH:: Hitachi SH
+* SH:: Renesas SH
* Sparclet:: Tsqware Sparclet
* Sparclite:: Fujitsu Sparclite
* ST2000:: Tandem ST2000
* Z8000:: Zilog Z8000
@end menu
-@c OBSOLETE @node A29K Embedded
-@c OBSOLETE @subsection AMD A29K Embedded
-@c OBSOLETE
-@c OBSOLETE @menu
-@c OBSOLETE * A29K UDI::
-@c OBSOLETE * A29K EB29K::
-@c OBSOLETE * Comms (EB29K):: Communications setup
-@c OBSOLETE * gdb-EB29K:: EB29K cross-debugging
-@c OBSOLETE * Remote Log:: Remote log
-@c OBSOLETE @end menu
-@c OBSOLETE
-@c OBSOLETE @table @code
-@c OBSOLETE
-@c OBSOLETE @kindex target adapt
-@c OBSOLETE @item target adapt @var{dev}
-@c OBSOLETE Adapt monitor for A29K.
-@c OBSOLETE
-@c OBSOLETE @kindex target amd-eb
-@c OBSOLETE @item target amd-eb @var{dev} @var{speed} @var{PROG}
-@c OBSOLETE @cindex AMD EB29K
-@c OBSOLETE Remote PC-resident AMD EB29K board, attached over serial lines.
-@c OBSOLETE @var{dev} is the serial device, as for @code{target remote};
-@c OBSOLETE @var{speed} allows you to specify the linespeed; and @var{PROG} is the
-@c OBSOLETE name of the program to be debugged, as it appears to DOS on the PC.
-@c OBSOLETE @xref{A29K EB29K, ,EBMON protocol for AMD29K}.
-@c OBSOLETE
-@c OBSOLETE @end table
-@c OBSOLETE
-@c OBSOLETE @node A29K UDI
-@c OBSOLETE @subsubsection A29K UDI
-@c OBSOLETE
-@c OBSOLETE @cindex UDI
-@c OBSOLETE @cindex AMD29K via UDI
-@c OBSOLETE
-@c OBSOLETE @value{GDBN} supports AMD's UDI (``Universal Debugger Interface'')
-@c OBSOLETE protocol for debugging the a29k processor family. To use this
-@c OBSOLETE configuration with AMD targets running the MiniMON monitor, you need the
-@c OBSOLETE program @code{MONTIP}, available from AMD at no charge. You can also
-@c OBSOLETE use @value{GDBN} with the UDI-conformant a29k simulator program
-@c OBSOLETE @code{ISSTIP}, also available from AMD.
-@c OBSOLETE
-@c OBSOLETE @table @code
-@c OBSOLETE @item target udi @var{keyword}
-@c OBSOLETE @kindex udi
-@c OBSOLETE Select the UDI interface to a remote a29k board or simulator, where
-@c OBSOLETE @var{keyword} is an entry in the AMD configuration file @file{udi_soc}.
-@c OBSOLETE This file contains keyword entries which specify parameters used to
-@c OBSOLETE connect to a29k targets. If the @file{udi_soc} file is not in your
-@c OBSOLETE working directory, you must set the environment variable @samp{UDICONF}
-@c OBSOLETE to its pathname.
-@c OBSOLETE @end table
-@c OBSOLETE
-@c OBSOLETE @node A29K EB29K
-@c OBSOLETE @subsubsection EBMON protocol for AMD29K
-@c OBSOLETE
-@c OBSOLETE @cindex EB29K board
-@c OBSOLETE @cindex running 29K programs
-@c OBSOLETE
-@c OBSOLETE AMD distributes a 29K development board meant to fit in a PC, together
-@c OBSOLETE with a DOS-hosted monitor program called @code{EBMON}. As a shorthand
-@c OBSOLETE term, this development system is called the ``EB29K''. To use
-@c OBSOLETE @value{GDBN} from a Unix system to run programs on the EB29K board, you
-@c OBSOLETE must first connect a serial cable between the PC (which hosts the EB29K
-@c OBSOLETE board) and a serial port on the Unix system. In the following, we
-@c OBSOLETE assume you've hooked the cable between the PC's @file{COM1} port and
-@c OBSOLETE @file{/dev/ttya} on the Unix system.
-@c OBSOLETE
-@c OBSOLETE @node Comms (EB29K)
-@c OBSOLETE @subsubsection Communications setup
-@c OBSOLETE
-@c OBSOLETE The next step is to set up the PC's port, by doing something like this
-@c OBSOLETE in DOS on the PC:
-@c OBSOLETE
-@c OBSOLETE @example
-@c OBSOLETE C:\> MODE com1:9600,n,8,1,none
-@c OBSOLETE @end example
-@c OBSOLETE
-@c OBSOLETE @noindent
-@c OBSOLETE This example---run on an MS DOS 4.0 system---sets the PC port to 9600
-@c OBSOLETE bps, no parity, eight data bits, one stop bit, and no ``retry'' action;
-@c OBSOLETE you must match the communications parameters when establishing the Unix
-@c OBSOLETE end of the connection as well.
-@c OBSOLETE @c FIXME: Who knows what this "no retry action" crud from the DOS manual may
-@c OBSOLETE @c mean? It's optional; leave it out? ---doc@cygnus.com, 25feb91
-@c OBSOLETE @c
-@c OBSOLETE @c It's optional, but it's unwise to omit it: who knows what is the
-@c OBSOLETE @c default value set when the DOS machines boots? "No retry" means that
-@c OBSOLETE @c the DOS serial device driver won't retry the operation if it fails;
-@c OBSOLETE @c I understand that this is needed because the GDB serial protocol
-@c OBSOLETE @c handles any errors and retransmissions itself. ---Eli Zaretskii, 3sep99
-@c OBSOLETE
-@c OBSOLETE To give control of the PC to the Unix side of the serial line, type
-@c OBSOLETE the following at the DOS console:
-@c OBSOLETE
-@c OBSOLETE @example
-@c OBSOLETE C:\> CTTY com1
-@c OBSOLETE @end example
-@c OBSOLETE
-@c OBSOLETE @noindent
-@c OBSOLETE (Later, if you wish to return control to the DOS console, you can use
-@c OBSOLETE the command @code{CTTY con}---but you must send it over the device that
-@c OBSOLETE had control, in our example over the @file{COM1} serial line.)
-@c OBSOLETE
-@c OBSOLETE From the Unix host, use a communications program such as @code{tip} or
-@c OBSOLETE @code{cu} to communicate with the PC; for example,
-@c OBSOLETE
-@c OBSOLETE @example
-@c OBSOLETE cu -s 9600 -l /dev/ttya
-@c OBSOLETE @end example
-@c OBSOLETE
-@c OBSOLETE @noindent
-@c OBSOLETE The @code{cu} options shown specify, respectively, the linespeed and the
-@c OBSOLETE serial port to use. If you use @code{tip} instead, your command line
-@c OBSOLETE may look something like the following:
-@c OBSOLETE
-@c OBSOLETE @example
-@c OBSOLETE tip -9600 /dev/ttya
-@c OBSOLETE @end example
-@c OBSOLETE
-@c OBSOLETE @noindent
-@c OBSOLETE Your system may require a different name where we show
-@c OBSOLETE @file{/dev/ttya} as the argument to @code{tip}. The communications
-@c OBSOLETE parameters, including which port to use, are associated with the
-@c OBSOLETE @code{tip} argument in the ``remote'' descriptions file---normally the
-@c OBSOLETE system table @file{/etc/remote}.
-@c OBSOLETE @c FIXME: What if anything needs doing to match the "n,8,1,none" part of
-@c OBSOLETE @c the DOS side's comms setup? cu can support -o (odd
-@c OBSOLETE @c parity), -e (even parity)---apparently no settings for no parity or
-@c OBSOLETE @c for character size. Taken from stty maybe...? John points out tip
-@c OBSOLETE @c can set these as internal variables, eg ~s parity=none; man stty
-@c OBSOLETE @c suggests that it *might* work to stty these options with stdin or
-@c OBSOLETE @c stdout redirected... ---doc@cygnus.com, 25feb91
-@c OBSOLETE @c
-@c OBSOLETE @c There's nothing to be done for the "none" part of the DOS MODE
-@c OBSOLETE @c command. The rest of the parameters should be matched by the
-@c OBSOLETE @c baudrate, bits, and parity used by the Unix side. ---Eli Zaretskii, 3Sep99
-@c OBSOLETE
-@c OBSOLETE @kindex EBMON
-@c OBSOLETE Using the @code{tip} or @code{cu} connection, change the DOS working
-@c OBSOLETE directory to the directory containing a copy of your 29K program, then
-@c OBSOLETE start the PC program @code{EBMON} (an EB29K control program supplied
-@c OBSOLETE with your board by AMD). You should see an initial display from
-@c OBSOLETE @code{EBMON} similar to the one that follows, ending with the
-@c OBSOLETE @code{EBMON} prompt @samp{#}---
-@c OBSOLETE
-@c OBSOLETE @example
-@c OBSOLETE C:\> G:
-@c OBSOLETE
-@c OBSOLETE G:\> CD \usr\joe\work29k
-@c OBSOLETE
-@c OBSOLETE G:\USR\JOE\WORK29K> EBMON
-@c OBSOLETE Am29000 PC Coprocessor Board Monitor, version 3.0-18
-@c OBSOLETE Copyright 1990 Advanced Micro Devices, Inc.
-@c OBSOLETE Written by Gibbons and Associates, Inc.
-@c OBSOLETE
-@c OBSOLETE Enter '?' or 'H' for help
-@c OBSOLETE
-@c OBSOLETE PC Coprocessor Type = EB29K
-@c OBSOLETE I/O Base = 0x208
-@c OBSOLETE Memory Base = 0xd0000
-@c OBSOLETE
-@c OBSOLETE Data Memory Size = 2048KB
-@c OBSOLETE Available I-RAM Range = 0x8000 to 0x1fffff
-@c OBSOLETE Available D-RAM Range = 0x80002000 to 0x801fffff
-@c OBSOLETE
-@c OBSOLETE PageSize = 0x400
-@c OBSOLETE Register Stack Size = 0x800
-@c OBSOLETE Memory Stack Size = 0x1800
-@c OBSOLETE
-@c OBSOLETE CPU PRL = 0x3
-@c OBSOLETE Am29027 Available = No
-@c OBSOLETE Byte Write Available = Yes
-@c OBSOLETE
-@c OBSOLETE # ~.
-@c OBSOLETE @end example
-@c OBSOLETE
-@c OBSOLETE Then exit the @code{cu} or @code{tip} program (done in the example by
-@c OBSOLETE typing @code{~.} at the @code{EBMON} prompt). @code{EBMON} keeps
-@c OBSOLETE running, ready for @value{GDBN} to take over.
-@c OBSOLETE
-@c OBSOLETE For this example, we've assumed what is probably the most convenient
-@c OBSOLETE way to make sure the same 29K program is on both the PC and the Unix
-@c OBSOLETE system: a PC/NFS connection that establishes ``drive @file{G:}'' on the
-@c OBSOLETE PC as a file system on the Unix host. If you do not have PC/NFS or
-@c OBSOLETE something similar connecting the two systems, you must arrange some
-@c OBSOLETE other way---perhaps floppy-disk transfer---of getting the 29K program
-@c OBSOLETE from the Unix system to the PC; @value{GDBN} does @emph{not} download it over the
-@c OBSOLETE serial line.
-@c OBSOLETE
-@c OBSOLETE @node gdb-EB29K
-@c OBSOLETE @subsubsection EB29K cross-debugging
-@c OBSOLETE
-@c OBSOLETE Finally, @code{cd} to the directory containing an image of your 29K
-@c OBSOLETE program on the Unix system, and start @value{GDBN}---specifying as argument the
-@c OBSOLETE name of your 29K program:
-@c OBSOLETE
-@c OBSOLETE @example
-@c OBSOLETE cd /usr/joe/work29k
-@c OBSOLETE @value{GDBP} myfoo
-@c OBSOLETE @end example
-@c OBSOLETE
-@c OBSOLETE @need 500
-@c OBSOLETE Now you can use the @code{target} command:
-@c OBSOLETE
-@c OBSOLETE @example
-@c OBSOLETE target amd-eb /dev/ttya 9600 MYFOO
-@c OBSOLETE @c FIXME: test above 'target amd-eb' as spelled, with caps! caps are meant to
-@c OBSOLETE @c emphasize that this is the name as seen by DOS (since I think DOS is
-@c OBSOLETE @c single-minded about case of letters). ---doc@cygnus.com, 25feb91
-@c OBSOLETE @end example
-@c OBSOLETE
-@c OBSOLETE @noindent
-@c OBSOLETE In this example, we've assumed your program is in a file called
-@c OBSOLETE @file{myfoo}. Note that the filename given as the last argument to
-@c OBSOLETE @code{target amd-eb} should be the name of the program as it appears to DOS.
-@c OBSOLETE In our example this is simply @code{MYFOO}, but in general it can include
-@c OBSOLETE a DOS path, and depending on your transfer mechanism may not resemble
-@c OBSOLETE the name on the Unix side.
-@c OBSOLETE
-@c OBSOLETE At this point, you can set any breakpoints you wish; when you are ready
-@c OBSOLETE to see your program run on the 29K board, use the @value{GDBN} command
-@c OBSOLETE @code{run}.
-@c OBSOLETE
-@c OBSOLETE To stop debugging the remote program, use the @value{GDBN} @code{detach}
-@c OBSOLETE command.
-@c OBSOLETE
-@c OBSOLETE To return control of the PC to its console, use @code{tip} or @code{cu}
-@c OBSOLETE once again, after your @value{GDBN} session has concluded, to attach to
-@c OBSOLETE @code{EBMON}. You can then type the command @code{q} to shut down
-@c OBSOLETE @code{EBMON}, returning control to the DOS command-line interpreter.
-@c OBSOLETE Type @kbd{CTTY con} to return command input to the main DOS console,
-@c OBSOLETE and type @kbd{~.} to leave @code{tip} or @code{cu}.
-@c OBSOLETE
-@c OBSOLETE @node Remote Log
-@c OBSOLETE @subsubsection Remote log
-@c OBSOLETE @cindex @file{eb.log}, a log file for EB29K
-@c OBSOLETE @cindex log file for EB29K
-@c OBSOLETE
-@c OBSOLETE The @code{target amd-eb} command creates a file @file{eb.log} in the
-@c OBSOLETE current working directory, to help debug problems with the connection.
-@c OBSOLETE @file{eb.log} records all the output from @code{EBMON}, including echoes
-@c OBSOLETE of the commands sent to it. Running @samp{tail -f} on this file in
-@c OBSOLETE another window often helps to understand trouble with @code{EBMON}, or
-@c OBSOLETE unexpected events on the PC side of the connection.
-
@node ARM
@subsection ARM
@@ -11239,50 +12008,50 @@ ARM Demon monitor.
@end table
@node H8/300
-@subsection Hitachi H8/300
+@subsection Renesas H8/300
@table @code
@kindex target hms@r{, with H8/300}
@item target hms @var{dev}
-A Hitachi SH, H8/300, or H8/500 board, attached via serial line to your host.
+A Renesas SH, H8/300, or H8/500 board, attached via serial line to your host.
Use special commands @code{device} and @code{speed} to control the serial
line and the communications speed used.
@kindex target e7000@r{, with H8/300}
@item target e7000 @var{dev}
-E7000 emulator for Hitachi H8 and SH.
+E7000 emulator for Renesas H8 and SH.
@kindex target sh3@r{, with H8/300}
@kindex target sh3e@r{, with H8/300}
@item target sh3 @var{dev}
@itemx target sh3e @var{dev}
-Hitachi SH-3 and SH-3E target systems.
+Renesas SH-3 and SH-3E target systems.
@end table
@cindex download to H8/300 or H8/500
@cindex H8/300 or H8/500 download
-@cindex download to Hitachi SH
-@cindex Hitachi SH download
-When you select remote debugging to a Hitachi SH, H8/300, or H8/500
-board, the @code{load} command downloads your program to the Hitachi
+@cindex download to Renesas SH
+@cindex Renesas SH download
+When you select remote debugging to a Renesas SH, H8/300, or H8/500
+board, the @code{load} command downloads your program to the Renesas
board and also opens it as the current executable target for
@value{GDBN} on your host (like the @code{file} command).
@value{GDBN} needs to know these things to talk to your
-Hitachi SH, H8/300, or H8/500:
+Renesas SH, H8/300, or H8/500:
@enumerate
@item
that you want to use @samp{target hms}, the remote debugging interface
-for Hitachi microprocessors, or @samp{target e7000}, the in-circuit
-emulator for the Hitachi SH and the Hitachi 300H. (@samp{target hms} is
-the default when @value{GDBN} is configured specifically for the Hitachi SH,
+for Renesas microprocessors, or @samp{target e7000}, the in-circuit
+emulator for the Renesas SH and the Renesas 300H. (@samp{target hms} is
+the default when @value{GDBN} is configured specifically for the Renesas SH,
H8/300, or H8/500.)
@item
-what serial device connects your host to your Hitachi board (the first
+what serial device connects your host to your Renesas board (the first
serial device available on your host is the default).
@item
@@ -11290,24 +12059,24 @@ what speed to use over the serial device.
@end enumerate
@menu
-* Hitachi Boards:: Connecting to Hitachi boards.
-* Hitachi ICE:: Using the E7000 In-Circuit Emulator.
-* Hitachi Special:: Special @value{GDBN} commands for Hitachi micros.
+* Renesas Boards:: Connecting to Renesas boards.
+* Renesas ICE:: Using the E7000 In-Circuit Emulator.
+* Renesas Special:: Special @value{GDBN} commands for Renesas micros.
@end menu
-@node Hitachi Boards
-@subsubsection Connecting to Hitachi boards
+@node Renesas Boards
+@subsubsection Connecting to Renesas boards
@c only for Unix hosts
@kindex device
-@cindex serial device, Hitachi micros
+@cindex serial device, Renesas micros
Use the special @code{@value{GDBN}} command @samp{device @var{port}} if you
need to explicitly set the serial device. The default @var{port} is the
first available port on your host. This is only necessary on Unix
hosts, where it is typically something like @file{/dev/ttya}.
@kindex speed
-@cindex serial line speed, Hitachi micros
+@cindex serial line speed, Renesas micros
@code{@value{GDBN}} has another special command to set the communications
speed: @samp{speed @var{bps}}. This command also is only used from Unix
hosts; on DOS hosts, set the line speed as usual from outside @value{GDBN} with
@@ -11315,7 +12084,7 @@ the DOS @code{mode} command (for instance,
@w{@kbd{mode com2:9600,n,8,1,p}} for a 9600@dmn{bps} connection).
The @samp{device} and @samp{speed} commands are available only when you
-use a Unix host to debug your Hitachi microprocessor programs. If you
+use a Unix host to debug your Renesas microprocessor programs. If you
use a DOS host,
@value{GDBN} depends on an auxiliary terminate-and-stay-resident program
called @code{asynctsr} to communicate with the development board
@@ -11325,7 +12094,7 @@ to set up the serial port on the DOS side.
The following sample session illustrates the steps needed to start a
program under @value{GDBN} control on an H8/300. The example uses a
sample H8/300 program called @file{t.x}. The procedure is the same for
-the Hitachi SH and the H8/500.
+the Renesas SH and the H8/500.
First hook up your development board. In this example, we use a
board attached to serial port @code{COM2}; if you use a different serial
@@ -11335,7 +12104,7 @@ debugger, you give it just the numeric part of the serial port's name;
for example, @samp{asyncstr 2} below runs @code{asyncstr} on
@code{COM2}.
-@example
+@smallexample
C:\H8300\TEST> asynctsr 2
C:\H8300\TEST> mode com2:9600,n,8,1,p
@@ -11343,7 +12112,7 @@ Resident portion of MODE loaded
COM2: 9600, n, 8, 1, p
-@end example
+@end smallexample
@quotation
@emph{Warning:} We have noticed a bug in PC-NFS that conflicts with
@@ -11358,7 +12127,7 @@ connected, you can start up @value{GDBN}. Call @code{@value{GDBP}} with
the name of your program as the argument. @code{@value{GDBN}} prompts
you, as usual, with the prompt @samp{(@value{GDBP})}. Use two special
commands to begin your debugging session: @samp{target hms} to specify
-cross-debugging to the Hitachi board, and the @code{load} command to
+cross-debugging to the Renesas board, and the @code{load} command to
download your program to the board. @code{load} displays the names of
the program's sections, and a @samp{*} for each 2K of data downloaded.
(If you want to refresh @value{GDBN} data on symbols or on the
@@ -11408,12 +12177,12 @@ to detect program completion.
In either case, @value{GDBN} sees the effect of a @sc{reset} on the
development board as a ``normal exit'' of your program.
-@node Hitachi ICE
+@node Renesas ICE
@subsubsection Using the E7000 in-circuit emulator
-@kindex target e7000@r{, with Hitachi ICE}
+@kindex target e7000@r{, with Renesas ICE}
You can use the E7000 in-circuit emulator to develop code for either the
-Hitachi SH or the H8/300H. Use one of these forms of the @samp{target
+Renesas SH or the H8/300H. Use one of these forms of the @samp{target
e7000} command to connect @value{GDBN} to your E7000:
@table @code
@@ -11428,8 +12197,8 @@ If your E7000 is installed as a host on a TCP/IP network, you can just
specify its hostname; @value{GDBN} uses @code{telnet} to connect.
@end table
-@node Hitachi Special
-@subsubsection Special @value{GDBN} commands for Hitachi micros
+@node Renesas Special
+@subsubsection Special @value{GDBN} commands for Renesas micros
Some @value{GDBN} commands are available only for the H8/300:
@@ -11461,136 +12230,18 @@ memory}. The accepted values for @var{mod} are @code{small},
@end table
-@node i960
-@subsection Intel i960
-
-@table @code
-
-@kindex target mon960
-@item target mon960 @var{dev}
-MON960 monitor for Intel i960.
-
-@kindex target nindy
-@item target nindy @var{devicename}
-An Intel 960 board controlled by a Nindy Monitor. @var{devicename} is
-the name of the serial device to use for the connection, e.g.
-@file{/dev/ttya}.
-
-@end table
-
-@cindex Nindy
-@cindex i960
-@dfn{Nindy} is a ROM Monitor program for Intel 960 target systems. When
-@value{GDBN} is configured to control a remote Intel 960 using Nindy, you can
-tell @value{GDBN} how to connect to the 960 in several ways:
-
-@itemize @bullet
-@item
-Through command line options specifying serial port, version of the
-Nindy protocol, and communications speed;
-
-@item
-By responding to a prompt on startup;
-
-@item
-By using the @code{target} command at any point during your @value{GDBN}
-session. @xref{Target Commands, ,Commands for managing targets}.
-
-@end itemize
-
-@cindex download to Nindy-960
-With the Nindy interface to an Intel 960 board, @code{load}
-downloads @var{filename} to the 960 as well as adding its symbols in
-@value{GDBN}.
-
-@menu
-* Nindy Startup:: Startup with Nindy
-* Nindy Options:: Options for Nindy
-* Nindy Reset:: Nindy reset command
-@end menu
-
-@node Nindy Startup
-@subsubsection Startup with Nindy
-
-If you simply start @code{@value{GDBP}} without using any command-line
-options, you are prompted for what serial port to use, @emph{before} you
-reach the ordinary @value{GDBN} prompt:
-
-@example
-Attach /dev/ttyNN -- specify NN, or "quit" to quit:
-@end example
-
-@noindent
-Respond to the prompt with whatever suffix (after @samp{/dev/tty})
-identifies the serial port you want to use. You can, if you choose,
-simply start up with no Nindy connection by responding to the prompt
-with an empty line. If you do this and later wish to attach to Nindy,
-use @code{target} (@pxref{Target Commands, ,Commands for managing targets}).
-
-@node Nindy Options
-@subsubsection Options for Nindy
-
-These are the startup options for beginning your @value{GDBN} session with a
-Nindy-960 board attached:
-
-@table @code
-@item -r @var{port}
-Specify the serial port name of a serial interface to be used to connect
-to the target system. This option is only available when @value{GDBN} is
-configured for the Intel 960 target architecture. You may specify
-@var{port} as any of: a full pathname (e.g. @samp{-r /dev/ttya}), a
-device name in @file{/dev} (e.g. @samp{-r ttya}), or simply the unique
-suffix for a specific @code{tty} (e.g. @samp{-r a}).
-
-@item -O
-(An uppercase letter ``O'', not a zero.) Specify that @value{GDBN} should use
-the ``old'' Nindy monitor protocol to connect to the target system.
-This option is only available when @value{GDBN} is configured for the Intel 960
-target architecture.
-
-@quotation
-@emph{Warning:} if you specify @samp{-O}, but are actually trying to
-connect to a target system that expects the newer protocol, the connection
-fails, appearing to be a speed mismatch. @value{GDBN} repeatedly
-attempts to reconnect at several different line speeds. You can abort
-this process with an interrupt.
-@end quotation
-
-@item -brk
-Specify that @value{GDBN} should first send a @code{BREAK} signal to the target
-system, in an attempt to reset it, before connecting to a Nindy target.
-
-@quotation
-@emph{Warning:} Many target systems do not have the hardware that this
-requires; it only works with a few boards.
-@end quotation
-@end table
-
-The standard @samp{-b} option controls the line speed used on the serial
-port.
-
-@c @group
-@node Nindy Reset
-@subsubsection Nindy reset command
-
-@table @code
-@item reset
-@kindex reset
-For a Nindy target, this command sends a ``break'' to the remote target
-system; this is only useful if the target has been equipped with a
-circuit to perform a hard reset (or some other interesting action) when
-a break is detected.
-@end table
-@c @end group
-
@node M32R/D
-@subsection Mitsubishi M32R/D
+@subsection Renesas M32R/D
@table @code
@kindex target m32r
@item target m32r @var{dev}
-Mitsubishi M32R/D ROM monitor.
+Renesas M32R/D ROM monitor.
+
+@kindex target m32rsdi
+@item target m32rsdi @var{dev}
+Renesas M32R SDI server, connected via parallel port to the board.
@end table
@@ -11624,19 +12275,6 @@ ROM 68K monitor, running on an M68K IDP board.
@end table
-If @value{GDBN} is configured with @code{m68*-ericsson-*}, it will
-instead have only a single special target command:
-
-@table @code
-
-@kindex target es1800
-@item target es1800 @var{dev}
-ES-1800 emulator for M68K.
-
-@end table
-
-[context?]
-
@table @code
@kindex target rombug
@@ -11645,17 +12283,6 @@ ROMBUG ROM monitor for OS/9000.
@end table
-@node M88K
-@subsection M88K
-
-@table @code
-
-@kindex target bug
-@item target bug @var{dev}
-BUG monitor, running on a MVME187 (m88k) board.
-
-@end table
-
@node MIPS Embedded
@subsection MIPS Embedded
@@ -11681,13 +12308,13 @@ For example, this sequence connects to the target board through a serial
port, and loads and runs a program called @var{prog} through the
debugger:
-@example
+@smallexample
host$ @value{GDBP} @var{prog}
@value{GDBN} is free software and @dots{}
(@value{GDBP}) target mips /dev/ttyb
(@value{GDBP}) load @var{prog}
(@value{GDBP}) run
-@end example
+@end smallexample
@item target mips @var{hostname}:@var{portnumber}
On some @value{GDBN} host configurations, you can specify a TCP
@@ -11800,6 +12427,130 @@ forever because it has no way of knowing how long the program is going
to run before stopping.
@end table
+@node OpenRISC 1000
+@subsection OpenRISC 1000
+@cindex OpenRISC 1000
+
+@cindex or1k boards
+See OR1k Architecture document (@uref{www.opencores.org}) for more information
+about platform and commands.
+
+@table @code
+
+@kindex target jtag
+@item target jtag jtag://@var{host}:@var{port}
+
+Connects to remote JTAG server.
+JTAG remote server can be either an or1ksim or JTAG server,
+connected via parallel port to the board.
+
+Example: @code{target jtag jtag://localhost:9999}
+
+@kindex or1ksim
+@item or1ksim @var{command}
+If connected to @code{or1ksim} OpenRISC 1000 Architectural
+Simulator, proprietary commands can be executed.
+
+@kindex info or1k spr
+@item info or1k spr
+Displays spr groups.
+
+@item info or1k spr @var{group}
+@itemx info or1k spr @var{groupno}
+Displays register names in selected group.
+
+@item info or1k spr @var{group} @var{register}
+@itemx info or1k spr @var{register}
+@itemx info or1k spr @var{groupno} @var{registerno}
+@itemx info or1k spr @var{registerno}
+Shows information about specified spr register.
+
+@kindex spr
+@item spr @var{group} @var{register} @var{value}
+@itemx spr @var{register @var{value}}
+@itemx spr @var{groupno} @var{registerno @var{value}}
+@itemx spr @var{registerno @var{value}}
+Writes @var{value} to specified spr register.
+@end table
+
+Some implementations of OpenRISC 1000 Architecture also have hardware trace.
+It is very similar to @value{GDBN} trace, except it does not interfere with normal
+program execution and is thus much faster. Hardware breakpoints/watchpoint
+triggers can be set using:
+@table @code
+@item $LEA/$LDATA
+Load effective address/data
+@item $SEA/$SDATA
+Store effective address/data
+@item $AEA/$ADATA
+Access effective address ($SEA or $LEA) or data ($SDATA/$LDATA)
+@item $FETCH
+Fetch data
+@end table
+
+When triggered, it can capture low level data, like: @code{PC}, @code{LSEA},
+@code{LDATA}, @code{SDATA}, @code{READSPR}, @code{WRITESPR}, @code{INSTR}.
+
+@code{htrace} commands:
+@cindex OpenRISC 1000 htrace
+@table @code
+@kindex hwatch
+@item hwatch @var{conditional}
+Set hardware watchpoint on combination of Load/Store Effecive Address(es)
+or Data. For example:
+
+@code{hwatch ($LEA == my_var) && ($LDATA < 50) || ($SEA == my_var) && ($SDATA >= 50)}
+
+@code{hwatch ($LEA == my_var) && ($LDATA < 50) || ($SEA == my_var) && ($SDATA >= 50)}
+
+@kindex htrace info
+@item htrace info
+Display information about current HW trace configuration.
+
+@kindex htrace trigger
+@item htrace trigger @var{conditional}
+Set starting criteria for HW trace.
+
+@kindex htrace qualifier
+@item htrace qualifier @var{conditional}
+Set acquisition qualifier for HW trace.
+
+@kindex htrace stop
+@item htrace stop @var{conditional}
+Set HW trace stopping criteria.
+
+@kindex htrace record
+@item htrace record [@var{data}]*
+Selects the data to be recorded, when qualifier is met and HW trace was
+triggered.
+
+@kindex htrace enable
+@item htrace enable
+@kindex htrace disable
+@itemx htrace disable
+Enables/disables the HW trace.
+
+@kindex htrace rewind
+@item htrace rewind [@var{filename}]
+Clears currently recorded trace data.
+
+If filename is specified, new trace file is made and any newly collected data
+will be written there.
+
+@kindex htrace print
+@item htrace print [@var{start} [@var{len}]]
+Prints trace buffer, using current record configuration.
+
+@kindex htrace mode continuous
+@item htrace mode continuous
+Set continuous trace mode.
+
+@kindex htrace mode suspend
+@item htrace mode suspend
+Set suspend trace mode.
+
+@end table
+
@node PowerPC
@subsection PowerPC
@@ -11837,25 +12588,25 @@ W89K monitor, running on a Winbond HPPA board.
@end table
@node SH
-@subsection Hitachi SH
+@subsection Renesas SH
@table @code
-@kindex target hms@r{, with Hitachi SH}
+@kindex target hms@r{, with Renesas SH}
@item target hms @var{dev}
-A Hitachi SH board attached via serial line to your host. Use special
+A Renesas SH board attached via serial line to your host. Use special
commands @code{device} and @code{speed} to control the serial line and
the communications speed used.
-@kindex target e7000@r{, with Hitachi SH}
+@kindex target e7000@r{, with Renesas SH}
@item target e7000 @var{dev}
-E7000 emulator for Hitachi SH.
+E7000 emulator for Renesas SH.
@kindex target sh3@r{, with SH}
@kindex target sh3e@r{, with SH}
@item target sh3 @var{dev}
@item target sh3e @var{dev}
-Hitachi SH-3 and SH-3E target systems.
+Renesas SH-3 and SH-3E target systems.
@end table
@@ -11884,15 +12635,15 @@ information and @samp{-Ttext} to relocate the program to where you wish to
load it on the target. You may also want to add the options @samp{-n} or
@samp{-N} in order to reduce the size of the sections. Example:
-@example
+@smallexample
sparclet-aout-gcc prog.c -Ttext 0x12010000 -g -o prog -N
-@end example
+@end smallexample
You can use @code{objdump} to verify that the addresses are what you intended:
-@example
+@smallexample
sparclet-aout-objdump --headers --syms prog
-@end example
+@end smallexample
@cindex running, on Sparclet
Once you have set
@@ -11902,9 +12653,9 @@ run @value{GDBN}. From your Unix host, run @code{@value{GDBP}}
@value{GDBN} comes up showing the prompt:
-@example
+@smallexample
(gdbslet)
-@end example
+@end smallexample
@menu
* Sparclet File:: Setting the file to debug
@@ -11918,9 +12669,9 @@ run @value{GDBN}. From your Unix host, run @code{@value{GDBP}}
The @value{GDBN} command @code{file} lets you choose with program to debug.
-@example
+@smallexample
(gdbslet) file prog
-@end example
+@end smallexample
@need 1000
@value{GDBN} then attempts to read the symbol table of @file{prog}.
@@ -11935,9 +12686,9 @@ path (@pxref{Environment, ,Your program's environment}).
If it fails
to find a file, it displays a message such as:
-@example
+@smallexample
prog: No such file or directory.
-@end example
+@end smallexample
When this happens, add the appropriate directories to the search paths with
the @value{GDBN} commands @code{path} and @code{dir}, and execute the
@@ -11949,18 +12700,18 @@ the @value{GDBN} commands @code{path} and @code{dir}, and execute the
The @value{GDBN} command @code{target} lets you connect to a Sparclet target.
To connect to a target on serial port ``@code{ttya}'', type:
-@example
+@smallexample
(gdbslet) target sparclet /dev/ttya
Remote target sparclet connected to /dev/ttya
main () at ../prog.c:3
-@end example
+@end smallexample
@need 750
@value{GDBN} displays messages like these:
-@example
+@smallexample
Connected to ttya.
-@end example
+@end smallexample
@node Sparclet Download
@subsubsection Sparclet download
@@ -11979,10 +12730,10 @@ For instance, if the program
@file{prog} was linked to text address 0x1201000, with data at 0x12010160
and bss at 0x12010170, in @value{GDBN}, type:
-@example
+@smallexample
(gdbslet) load prog 0x12010000
Loading section .text, size 0xdb0 vma 0x12010000
-@end example
+@end smallexample
If the code is loaded at a different address then what the program was linked
to, you may need to use the @code{section} and @code{add-symbol-file} commands
@@ -11996,7 +12747,7 @@ You can now begin debugging the task using @value{GDBN}'s execution control
commands, @code{b}, @code{step}, @code{run}, etc. See the @value{GDBN}
manual for the list of commands.
-@example
+@smallexample
(gdbslet) b main
Breakpoint 1 at 0x12010000: file prog.c, line 3.
(gdbslet) run
@@ -12006,7 +12757,7 @@ Breakpoint 1, main (argc=1, argv=0xeffff21c) at prog.c:3
(gdbslet) step
4 char *execarg = "hello!";
(gdbslet)
-@end example
+@end smallexample
@node Sparclite
@subsection Fujitsu Sparclite
@@ -12031,9 +12782,9 @@ STDBUG protocol.
To connect your ST2000 to the host system, see the manufacturer's
manual. Once the ST2000 is physically attached, you can run:
-@example
+@smallexample
target st2000 @var{dev} @var{speed}
-@end example
+@end smallexample
@noindent
to establish it as your debugging environment. @var{dev} is normally
@@ -12214,6 +12965,7 @@ described here.
* History:: Command history
* Screen Size:: Screen size
* Numbers:: Numbers
+* ABI:: Configuring the current ABI
* Messages/Warnings:: Optional warnings and messages
* Debugging Output:: Optional messages about internal happenings
@end menu
@@ -12460,6 +13212,89 @@ Display the current default base for numeric input.
Display the current default base for numeric display.
@end table
+@node ABI
+@section Configuring the current ABI
+
+@value{GDBN} can determine the @dfn{ABI} (Application Binary Interface) of your
+application automatically. However, sometimes you need to override its
+conclusions. Use these commands to manage @value{GDBN}'s view of the
+current ABI.
+
+@cindex OS ABI
+@kindex set osabi
+@kindex show osabi
+
+One @value{GDBN} configuration can debug binaries for multiple operating
+system targets, either via remote debugging or native emulation.
+@value{GDBN} will autodetect the @dfn{OS ABI} (Operating System ABI) in use,
+but you can override its conclusion using the @code{set osabi} command.
+One example where this is useful is in debugging of binaries which use
+an alternate C library (e.g.@: @sc{uClibc} for @sc{gnu}/Linux) which does
+not have the same identifying marks that the standard C library for your
+platform provides.
+
+@table @code
+@item show osabi
+Show the OS ABI currently in use.
+
+@item set osabi
+With no argument, show the list of registered available OS ABI's.
+
+@item set osabi @var{abi}
+Set the current OS ABI to @var{abi}.
+@end table
+
+@cindex float promotion
+@kindex set coerce-float-to-double
+
+Generally, the way that an argument of type @code{float} is passed to a
+function depends on whether the function is prototyped. For a prototyped
+(i.e.@: ANSI/ISO style) function, @code{float} arguments are passed unchanged,
+according to the architecture's convention for @code{float}. For unprototyped
+(i.e.@: K&R style) functions, @code{float} arguments are first promoted to type
+@code{double} and then passed.
+
+Unfortunately, some forms of debug information do not reliably indicate whether
+a function is prototyped. If @value{GDBN} calls a function that is not marked
+as prototyped, it consults @kbd{set coerce-float-to-double}.
+
+@table @code
+@item set coerce-float-to-double
+@itemx set coerce-float-to-double on
+Arguments of type @code{float} will be promoted to @code{double} when passed
+to an unprototyped function. This is the default setting.
+
+@item set coerce-float-to-double off
+Arguments of type @code{float} will be passed directly to unprototyped
+functions.
+@end table
+
+@kindex set cp-abi
+@kindex show cp-abi
+@value{GDBN} needs to know the ABI used for your program's C@t{++}
+objects. The correct C@t{++} ABI depends on which C@t{++} compiler was
+used to build your application. @value{GDBN} only fully supports
+programs with a single C@t{++} ABI; if your program contains code using
+multiple C@t{++} ABI's or if @value{GDBN} can not identify your
+program's ABI correctly, you can tell @value{GDBN} which ABI to use.
+Currently supported ABI's include ``gnu-v2'', for @code{g++} versions
+before 3.0, ``gnu-v3'', for @code{g++} versions 3.0 and later, and
+``hpaCC'' for the HP ANSI C@t{++} compiler. Other C@t{++} compilers may
+use the ``gnu-v2'' or ``gnu-v3'' ABI's as well. The default setting is
+``auto''.
+
+@table @code
+@item show cp-abi
+Show the C@t{++} ABI currently in use.
+
+@item set cp-abi
+With no argument, show the list of supported C@t{++} ABI's.
+
+@item set cp-abi @var{abi}
+@itemx set cp-abi auto
+Set the current C@t{++} ABI to @var{abi}, or return to automatic detection.
+@end table
+
@node Messages/Warnings
@section Optional warnings and messages
@@ -12509,11 +13344,11 @@ By default, @value{GDBN} is cautious, and asks what sometimes seems to be a
lot of stupid questions to confirm certain commands. For example, if
you try to run a program which is already running:
-@example
+@smallexample
(@value{GDBP}) run
The program being debugged has been started already.
Start it from the beginning? (y or n)
-@end example
+@end smallexample
If you are willing to unflinchingly face the consequences of your own
commands, you can disable this ``feature'':
@@ -12561,6 +13396,14 @@ default is off.
@item show debug expression
Displays the current state of displaying @value{GDBN} expression
debugging info.
+@kindex set debug frame
+@item set debug frame
+Turns on or off display of @value{GDBN} frame debugging info. The
+default is off.
+@kindex show debug frame
+@item show debug frame
+Displays the current state of displaying @value{GDBN} frame debugging
+info.
@kindex set debug overload
@item set debug overload
Turns on or off display of @value{GDBN} C@t{++} overload debugging
@@ -12704,6 +13547,14 @@ Display the @value{GDBN} commands used to define @var{commandname} (but
not its documentation). If no @var{commandname} is given, display the
definitions for all user-defined commands.
+@kindex show max-user-call-depth
+@kindex set max-user-call-depth
+@item show max-user-call-depth
+@itemx set max-user-call-depth
+The value of @code{max-user-call-depth} controls how many recursion
+levels are allowed in user-defined commands before GDB suspects an
+infinite recursion and aborts the command.
+
@end table
When user-defined commands are executed, the
@@ -12753,7 +13604,7 @@ For example, to ignore @code{SIGALRM} signals while
single-stepping, but treat them normally during normal execution,
you could define:
-@example
+@smallexample
define hook-stop
handle SIGALRM nopass
end
@@ -12765,13 +13616,13 @@ end
define hook-continue
handle SIGLARM pass
end
-@end example
+@end smallexample
As a further example, to hook at the begining and end of the @code{echo}
-command, and to add extra text to the beginning and end of the message,
+command, and to add extra text to the beginning and end of the message,
you could define:
-@example
+@smallexample
define hook-echo
echo <<<---
end
@@ -12784,7 +13635,7 @@ end
<<<---Hello World--->>>
(@value{GDBP})
-@end example
+@end smallexample
You can define a hook for any single-word command in @value{GDBN}, but
not for command aliases; you should define a hook for the basic command
@@ -12868,8 +13719,8 @@ Execute the command file @var{filename}.
@end table
The lines in a command file are executed sequentially. They are not
-printed as they are executed. An error in any command terminates execution
-of the command file.
+printed as they are executed. An error in any command terminates
+execution of the command file and control is returned to the console.
Commands that would ask for confirmation if used interactively proceed
without asking when used in a command file. Many @value{GDBN} commands that
@@ -12882,9 +13733,9 @@ standard error. Errors in a command file supplied on standard input do
not terminate execution of the command file --- execution continues with
the next command.
-@example
+@smallexample
gdb < cmds > log 2>&1
-@end example
+@end smallexample
(The syntax above will vary depending on the shell used.) This example
will execute commands from the file @file{cmds}. All output and errors
@@ -12917,19 +13768,19 @@ To print @samp{@w{ }and foo =@w{ }}, use the command
A backslash at the end of @var{text} can be used, as in C, to continue
the command onto subsequent lines. For example,
-@example
+@smallexample
echo This is some text\n\
which is continued\n\
onto several lines.\n
-@end example
+@end smallexample
produces the same output as
-@example
+@smallexample
echo This is some text\n
echo which is continued\n
echo onto several lines.\n
-@end example
+@end smallexample
@kindex output
@item output @var{expression}
@@ -12955,9 +13806,9 @@ subroutine
@c Either this is a bug, or the manual should document what formats are
@c supported.
-@example
+@smallexample
printf (@var{string}, @var{expressions}@dots{});
-@end example
+@end smallexample
For example, you can print two values in hex like this:
@@ -12970,23 +13821,90 @@ string are the simple ones that consist of backslash followed by a
letter.
@end table
+@node Interpreters
+@chapter Command Interpreters
+@cindex command interpreters
+
+@value{GDBN} supports multiple command interpreters, and some command
+infrastructure to allow users or user interface writers to switch
+between interpreters or run commands in other interpreters.
+
+@value{GDBN} currently supports two command interpreters, the console
+interpreter (sometimes called the command-line interpreter or @sc{cli})
+and the machine interface interpreter (or @sc{gdb/mi}). This manual
+describes both of these interfaces in great detail.
+
+By default, @value{GDBN} will start with the console interpreter.
+However, the user may choose to start @value{GDBN} with another
+interpreter by specifying the @option{-i} or @option{--interpreter}
+startup options. Defined interpreters include:
+
+@table @code
+@item console
+@cindex console interpreter
+The traditional console or command-line interpreter. This is the most often
+used interpreter with @value{GDBN}. With no interpreter specified at runtime,
+@value{GDBN} will use this interpreter.
+
+@item mi
+@cindex mi interpreter
+The newest @sc{gdb/mi} interface (currently @code{mi2}). Used primarily
+by programs wishing to use @value{GDBN} as a backend for a debugger GUI
+or an IDE. For more information, see @ref{GDB/MI, ,The @sc{gdb/mi}
+Interface}.
+
+@item mi2
+@cindex mi2 interpreter
+The current @sc{gdb/mi} interface.
+
+@item mi1
+@cindex mi1 interpreter
+The @sc{gdb/mi} interface included in @value{GDBN} 5.1, 5.2, and 5.3.
+
+@end table
+
+@cindex invoke another interpreter
+The interpreter being used by @value{GDBN} may not be dynamically
+switched at runtime. Although possible, this could lead to a very
+precarious situation. Consider an IDE using @sc{gdb/mi}. If a user
+enters the command "interpreter-set console" in a console view,
+@value{GDBN} would switch to using the console interpreter, rendering
+the IDE inoperable!
+
+@kindex interpreter-exec
+Although you may only choose a single interpreter at startup, you may execute
+commands in any interpreter from the current interpreter using the appropriate
+command. If you are running the console interpreter, simply use the
+@code{interpreter-exec} command:
+
+@smallexample
+interpreter-exec mi "-data-list-register-names"
+@end smallexample
+
+@sc{gdb/mi} has a similar command, although it is only available in versions of
+@value{GDBN} which support @sc{gdb/mi} version 2 (or greater).
+
@node TUI
@chapter @value{GDBN} Text User Interface
@cindex TUI
+@cindex Text User Interface
@menu
* TUI Overview:: TUI overview
* TUI Keys:: TUI key bindings
+* TUI Single Key Mode:: TUI single key mode
* TUI Commands:: TUI specific commands
* TUI Configuration:: TUI configuration variables
@end menu
-The @value{GDBN} Text User Interface, TUI in short,
-is a terminal interface which uses the @code{curses} library
-to show the source file, the assembly output, the program registers
-and @value{GDBN} commands in separate text windows.
-The TUI is available only when @value{GDBN} is configured
-with the @code{--enable-tui} configure option (@pxref{Configure Options}).
+The @value{GDBN} Text User Interface, TUI in short, is a terminal
+interface which uses the @code{curses} library to show the source
+file, the assembly output, the program registers and @value{GDBN}
+commands in separate text windows.
+
+The TUI is enabled by invoking @value{GDBN} using either
+@pindex gdbtui
+@samp{gdbtui} or @samp{gdb -tui}.
@node TUI Overview
@section TUI overview
@@ -13017,8 +13935,6 @@ window is always visible.
@item source
The source window shows the source file of the program. The current
line as well as active breakpoints are displayed in this window.
-The current program position is shown with the @samp{>} marker and
-active breakpoints are shown with @samp{*} markers.
@item assembly
The assembly window shows the disassembly output of the program.
@@ -13026,7 +13942,38 @@ The assembly window shows the disassembly output of the program.
@item register
This window shows the processor registers. It detects when
a register is changed and when this is the case, registers that have
-changed are highlighted.
+changed are highlighted.
+
+@end table
+
+The source and assembly windows show the current program position
+by highlighting the current line and marking them with the @samp{>} marker.
+Breakpoints are also indicated with two markers. A first one
+indicates the breakpoint type:
+
+@table @code
+@item B
+Breakpoint which was hit at least once.
+
+@item b
+Breakpoint which was never hit.
+
+@item H
+Hardware breakpoint which was hit at least once.
+
+@item h
+Hardware breakpoint which was never hit.
+
+@end table
+
+The second marker indicates whether the breakpoint is enabled or not:
+
+@table @code
+@item +
+Breakpoint is enabled.
+
+@item -
+Breakpoint is disabled.
@end table
@@ -13055,6 +14002,35 @@ assembly and registers
@end itemize
+On top of the command window a status line gives various information
+concerning the current process begin debugged. The status line is
+updated when the information it shows changes. The following fields
+are displayed:
+
+@table @emph
+@item target
+Indicates the current gdb target
+(@pxref{Targets, ,Specifying a Debugging Target}).
+
+@item process
+Gives information about the current process or thread number.
+When no process is being debugged, this field is set to @code{No process}.
+
+@item function
+Gives the current function name for the selected frame.
+The name is demangled if demangling is turned on (@pxref{Print Settings}).
+When there is no symbol corresponding to the current program counter
+the string @code{??} is displayed.
+
+@item line
+Indicates the current line number for the selected frame.
+When the current line number is not known the string @code{??} is displayed.
+
+@item pc
+Indicates the current program counter address.
+
+@end table
+
@node TUI Keys
@section TUI Key Bindings
@cindex TUI key bindings
@@ -13062,7 +14038,9 @@ assembly and registers
The TUI installs several key bindings in the readline keymaps
(@pxref{Command Line Editing}).
They allow to leave or enter in the TUI mode or they operate
-directly on the TUI layout and windows. The following key bindings
+directly on the TUI layout and windows. The TUI also provides
+a @emph{SingleKey} keymap which binds several keys directly to
+@value{GDBN} commands. The following key bindings
are installed for both TUI mode and the @value{GDBN} standard mode.
@table @kbd
@@ -13095,6 +14073,19 @@ previous layout and the new one.
Think of it as the Emacs @kbd{C-x 2} binding.
+@kindex C-x o
+@item C-x o
+Change the active window. The TUI associates several key bindings
+(like scrolling and arrow keys) to the active window. This command
+gives the focus to the next TUI window.
+
+Think of it as the Emacs @kbd{C-x o} binding.
+
+@kindex C-x s
+@item C-x s
+Use the TUI @emph{SingleKey} keymap that binds single key to gdb commands
+(@pxref{TUI Single Key Mode}).
+
@end table
The following key bindings are handled only by the TUI mode:
@@ -13131,9 +14122,69 @@ Refresh the screen.
@end table
In the TUI mode, the arrow keys are used by the active window
-for scrolling. This means they are not available for readline. It is
-necessary to use other readline key bindings such as @key{C-p}, @key{C-n},
-@key{C-b} and @key{C-f}.
+for scrolling. This means they are available for readline when the
+active window is the command window. When the command window
+does not have the focus, it is necessary to use other readline
+key bindings such as @key{C-p}, @key{C-n}, @key{C-b} and @key{C-f}.
+
+@node TUI Single Key Mode
+@section TUI Single Key Mode
+@cindex TUI single key mode
+
+The TUI provides a @emph{SingleKey} mode in which it installs a particular
+key binding in the readline keymaps to connect single keys to
+some gdb commands.
+
+@table @kbd
+@kindex c @r{(SingleKey TUI key)}
+@item c
+continue
+
+@kindex d @r{(SingleKey TUI key)}
+@item d
+down
+
+@kindex f @r{(SingleKey TUI key)}
+@item f
+finish
+
+@kindex n @r{(SingleKey TUI key)}
+@item n
+next
+
+@kindex q @r{(SingleKey TUI key)}
+@item q
+exit the @emph{SingleKey} mode.
+
+@kindex r @r{(SingleKey TUI key)}
+@item r
+run
+
+@kindex s @r{(SingleKey TUI key)}
+@item s
+step
+
+@kindex u @r{(SingleKey TUI key)}
+@item u
+up
+
+@kindex v @r{(SingleKey TUI key)}
+@item v
+info locals
+
+@kindex w @r{(SingleKey TUI key)}
+@item w
+where
+
+@end table
+
+Other keys temporarily switch to the @value{GDBN} command prompt.
+The key that was pressed is inserted in the editing buffer so that
+it is possible to type most @value{GDBN} commands without interaction
+with the TUI @emph{SingleKey} mode. Once the command is entered the TUI
+@emph{SingleKey} mode is restored. The only way to permanently leave
+this mode is by hitting @key{q} or @samp{@key{C-x} @key{s}}.
+
@node TUI Commands
@section TUI specific commands
@@ -13146,6 +14197,10 @@ is in the standard mode, using these commands will automatically switch
in the TUI mode.
@table @code
+@item info win
+@kindex info win
+List and give the size of all displayed windows.
+
@item layout next
@kindex layout next
Display the next layout.
@@ -13180,6 +14235,22 @@ can be affected to another window.
@kindex refresh
Refresh the screen. This is similar to using @key{C-L} key.
+@item tui reg float
+@kindex tui reg
+Show the floating point registers in the register window.
+
+@item tui reg general
+Show the general registers in the register window.
+
+@item tui reg next
+Show the next register group. The list of register groups as well as
+their order is target specific. The predefined register groups are the
+following: @code{general}, @code{float}, @code{system}, @code{vector},
+@code{all}, @code{save}, @code{restore}.
+
+@item tui reg system
+Show the system registers in the register window.
+
@item update
@kindex update
Update the source window and the current execution point.
@@ -13303,36 +14374,26 @@ and the source.
Explicit @value{GDBN} @code{list} or search commands still produce output as
usual, but you probably have no reason to use them from Emacs.
-@quotation
-@emph{Warning:} If the directory where your program resides is not your
-current directory, it can be easy to confuse Emacs about the location of
-the source files, in which case the auxiliary display buffer does not
-appear to show your source. @value{GDBN} can find programs by searching your
-environment's @code{PATH} variable, so the @value{GDBN} input and output
-session proceeds normally; but Emacs does not get enough information
-back from @value{GDBN} to locate the source files in this situation. To
-avoid this problem, either start @value{GDBN} mode from the directory where
-your program resides, or specify an absolute file name when prompted for the
-@kbd{M-x gdb} argument.
-
-A similar confusion can result if you use the @value{GDBN} @code{file} command to
-switch to debugging a program in some other location, from an existing
-@value{GDBN} buffer in Emacs.
-@end quotation
-
-By default, @kbd{M-x gdb} calls the program called @file{gdb}. If
-you need to call @value{GDBN} by a different name (for example, if you keep
-several configurations around, with different names) you can set the
-Emacs variable @code{gdb-command-name}; for example,
-
-@example
-(setq gdb-command-name "mygdb")
-@end example
-
-@noindent
-(preceded by @kbd{M-:} or @kbd{ESC :}, or typed in the @code{*scratch*} buffer, or
-in your @file{.emacs} file) makes Emacs call the program named
-``@code{mygdb}'' instead.
+If you specify an absolute file name when prompted for the @kbd{M-x
+gdb} argument, then Emacs sets your current working directory to where
+your program resides. If you only specify the file name, then Emacs
+sets your current working directory to to the directory associated
+with the previous buffer. In this case, @value{GDBN} may find your
+program by searching your environment's @code{PATH} variable, but on
+some operating systems it might not find the source. So, although the
+@value{GDBN} input and output session proceeds normally, the auxiliary
+buffer does not display the current source and line of execution.
+
+The initial working directory of @value{GDBN} is printed on the top
+line of the @value{GDBN} I/O buffer and this serves as a default for
+the commands that specify files for @value{GDBN} to operate
+on. @xref{Files, ,Commands to specify files}.
+
+By default, @kbd{M-x gdb} calls the program called @file{gdb}. If you
+need to call @value{GDBN} by a different name (for example, if you
+keep several configurations around, with different names) you can
+customize the Emacs variable @code{gud-gdb-command-name} to run the
+one you want.
In the @value{GDBN} I/O buffer, you can use these special Emacs commands in
addition to the standard Shell mode commands:
@@ -13341,66 +14402,47 @@ addition to the standard Shell mode commands:
@item C-h m
Describe the features of Emacs' @value{GDBN} Mode.
-@item M-s
+@item C-c C-s
Execute to another source line, like the @value{GDBN} @code{step} command; also
update the display window to show the current file and location.
-@item M-n
+@item C-c C-n
Execute to next source line in this function, skipping all function
calls, like the @value{GDBN} @code{next} command. Then update the display window
to show the current file and location.
-@item M-i
+@item C-c C-i
Execute one instruction, like the @value{GDBN} @code{stepi} command; update
display window accordingly.
-@item M-x gdb-nexti
-Execute to next instruction, using the @value{GDBN} @code{nexti} command; update
-display window accordingly.
-
@item C-c C-f
Execute until exit from the selected stack frame, like the @value{GDBN}
@code{finish} command.
-@item M-c
+@item C-c C-r
Continue execution of your program, like the @value{GDBN} @code{continue}
command.
-@emph{Warning:} In Emacs v19, this command is @kbd{C-c C-p}.
-
-@item M-u
+@item C-c <
Go up the number of frames indicated by the numeric argument
(@pxref{Arguments, , Numeric Arguments, Emacs, The @sc{gnu} Emacs Manual}),
like the @value{GDBN} @code{up} command.
-@emph{Warning:} In Emacs v19, this command is @kbd{C-c C-u}.
-
-@item M-d
+@item C-c >
Go down the number of frames indicated by the numeric argument, like the
@value{GDBN} @code{down} command.
-
-@emph{Warning:} In Emacs v19, this command is @kbd{C-c C-d}.
-
-@item C-x &
-Read the number where the cursor is positioned, and insert it at the end
-of the @value{GDBN} I/O buffer. For example, if you wish to disassemble code
-around an address that was displayed earlier, type @kbd{disassemble};
-then move the cursor to the address display, and pick up the
-argument for @code{disassemble} by typing @kbd{C-x &}.
-
-You can customize this further by defining elements of the list
-@code{gdb-print-command}; once it is defined, you can format or
-otherwise process numbers picked up by @kbd{C-x &} before they are
-inserted. A numeric argument to @kbd{C-x &} indicates that you
-wish special formatting, and also acts as an index to pick an element of the
-list. If the list element is a string, the number to be inserted is
-formatted using the Emacs function @code{format}; otherwise the number
-is passed as an argument to the corresponding list element.
@end table
-In any source file, the Emacs command @kbd{C-x SPC} (@code{gdb-break})
+In any source file, the Emacs command @kbd{C-x SPC} (@code{gud-break})
tells @value{GDBN} to set a breakpoint on the source line point is on.
+If you type @kbd{M-x speedbar}, then Emacs displays a separate frame which
+shows a backtrace when the @value{GDBN} I/O buffer is current. Move
+point to any frame in the stack and type @key{RET} to make it become the
+current frame and display the associated source in the source buffer.
+Alternatively, click @kbd{Mouse-2} to make the selected frame become the
+current one.
+
If you accidentally delete the source-display buffer, an easy way to get
it back is to type the command @code{f} in the @value{GDBN} buffer, to
request a frame display; when you run under Emacs, this recreates
@@ -13414,6 +14456,10 @@ communicates with Emacs in terms of line numbers. If you add or
delete lines from the text, the line numbers that @value{GDBN} knows cease
to correspond properly with the code.
+The description given here is for GNU Emacs version 21.3 and a more
+detailed description of its interaction with @value{GDBN} is given in
+the Emacs manual (@pxref{Debuggers,,, Emacs, The @sc{gnu} Emacs Manual}).
+
@c The following dropped because Epoch is nonstandard. Reactivate
@c if/when v19 does something similar. ---doc@cygnus.com 19dec1990
@ignore
@@ -13428,8 +14474,4269 @@ environment. Users of this environment can use a new command,
each value is printed in its own window.
@end ignore
-@include annotate.texi
-@include gdbmi.texinfo
+
+@node GDB/MI
+@chapter The @sc{gdb/mi} Interface
+
+@unnumberedsec Function and Purpose
+
+@cindex @sc{gdb/mi}, its purpose
+@sc{gdb/mi} is a line based machine oriented text interface to @value{GDBN}. It is
+specifically intended to support the development of systems which use
+the debugger as just one small component of a larger system.
+
+This chapter is a specification of the @sc{gdb/mi} interface. It is written
+in the form of a reference manual.
+
+Note that @sc{gdb/mi} is still under construction, so some of the
+features described below are incomplete and subject to change.
+
+@unnumberedsec Notation and Terminology
+
+@cindex notational conventions, for @sc{gdb/mi}
+This chapter uses the following notation:
+
+@itemize @bullet
+@item
+@code{|} separates two alternatives.
+
+@item
+@code{[ @var{something} ]} indicates that @var{something} is optional:
+it may or may not be given.
+
+@item
+@code{( @var{group} )*} means that @var{group} inside the parentheses
+may repeat zero or more times.
+
+@item
+@code{( @var{group} )+} means that @var{group} inside the parentheses
+may repeat one or more times.
+
+@item
+@code{"@var{string}"} means a literal @var{string}.
+@end itemize
+
+@ignore
+@heading Dependencies
+@end ignore
+
+@heading Acknowledgments
+
+In alphabetic order: Andrew Cagney, Fernando Nasser, Stan Shebs and
+Elena Zannoni.
+
+@menu
+* GDB/MI Command Syntax::
+* GDB/MI Compatibility with CLI::
+* GDB/MI Output Records::
+* GDB/MI Command Description Format::
+* GDB/MI Breakpoint Table Commands::
+* GDB/MI Data Manipulation::
+* GDB/MI Program Control::
+* GDB/MI Miscellaneous Commands::
+@ignore
+* GDB/MI Kod Commands::
+* GDB/MI Memory Overlay Commands::
+* GDB/MI Signal Handling Commands::
+@end ignore
+* GDB/MI Stack Manipulation::
+* GDB/MI Symbol Query::
+* GDB/MI Target Manipulation::
+* GDB/MI Thread Commands::
+* GDB/MI Tracepoint Commands::
+* GDB/MI Variable Objects::
+@end menu
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Command Syntax
+@section @sc{gdb/mi} Command Syntax
+
+@menu
+* GDB/MI Input Syntax::
+* GDB/MI Output Syntax::
+* GDB/MI Simple Examples::
+@end menu
+
+@node GDB/MI Input Syntax
+@subsection @sc{gdb/mi} Input Syntax
+
+@cindex input syntax for @sc{gdb/mi}
+@cindex @sc{gdb/mi}, input syntax
+@table @code
+@item @var{command} @expansion{}
+@code{@var{cli-command} | @var{mi-command}}
+
+@item @var{cli-command} @expansion{}
+@code{[ @var{token} ] @var{cli-command} @var{nl}}, where
+@var{cli-command} is any existing @value{GDBN} CLI command.
+
+@item @var{mi-command} @expansion{}
+@code{[ @var{token} ] "-" @var{operation} ( " " @var{option} )*
+@code{[} " --" @code{]} ( " " @var{parameter} )* @var{nl}}
+
+@item @var{token} @expansion{}
+"any sequence of digits"
+
+@item @var{option} @expansion{}
+@code{"-" @var{parameter} [ " " @var{parameter} ]}
+
+@item @var{parameter} @expansion{}
+@code{@var{non-blank-sequence} | @var{c-string}}
+
+@item @var{operation} @expansion{}
+@emph{any of the operations described in this chapter}
+
+@item @var{non-blank-sequence} @expansion{}
+@emph{anything, provided it doesn't contain special characters such as
+"-", @var{nl}, """ and of course " "}
+
+@item @var{c-string} @expansion{}
+@code{""" @var{seven-bit-iso-c-string-content} """}
+
+@item @var{nl} @expansion{}
+@code{CR | CR-LF}
+@end table
+
+@noindent
+Notes:
+
+@itemize @bullet
+@item
+The CLI commands are still handled by the @sc{mi} interpreter; their
+output is described below.
+
+@item
+The @code{@var{token}}, when present, is passed back when the command
+finishes.
+
+@item
+Some @sc{mi} commands accept optional arguments as part of the parameter
+list. Each option is identified by a leading @samp{-} (dash) and may be
+followed by an optional argument parameter. Options occur first in the
+parameter list and can be delimited from normal parameters using
+@samp{--} (this is useful when some parameters begin with a dash).
+@end itemize
+
+Pragmatics:
+
+@itemize @bullet
+@item
+We want easy access to the existing CLI syntax (for debugging).
+
+@item
+We want it to be easy to spot a @sc{mi} operation.
+@end itemize
+
+@node GDB/MI Output Syntax
+@subsection @sc{gdb/mi} Output Syntax
+
+@cindex output syntax of @sc{gdb/mi}
+@cindex @sc{gdb/mi}, output syntax
+The output from @sc{gdb/mi} consists of zero or more out-of-band records
+followed, optionally, by a single result record. This result record
+is for the most recent command. The sequence of output records is
+terminated by @samp{(@value{GDBP})}.
+
+If an input command was prefixed with a @code{@var{token}} then the
+corresponding output for that command will also be prefixed by that same
+@var{token}.
+
+@table @code
+@item @var{output} @expansion{}
+@code{( @var{out-of-band-record} )* [ @var{result-record} ] "(gdb)" @var{nl}}
+
+@item @var{result-record} @expansion{}
+@code{ [ @var{token} ] "^" @var{result-class} ( "," @var{result} )* @var{nl}}
+
+@item @var{out-of-band-record} @expansion{}
+@code{@var{async-record} | @var{stream-record}}
+
+@item @var{async-record} @expansion{}
+@code{@var{exec-async-output} | @var{status-async-output} | @var{notify-async-output}}
+
+@item @var{exec-async-output} @expansion{}
+@code{[ @var{token} ] "*" @var{async-output}}
+
+@item @var{status-async-output} @expansion{}
+@code{[ @var{token} ] "+" @var{async-output}}
+
+@item @var{notify-async-output} @expansion{}
+@code{[ @var{token} ] "=" @var{async-output}}
+
+@item @var{async-output} @expansion{}
+@code{@var{async-class} ( "," @var{result} )* @var{nl}}
+
+@item @var{result-class} @expansion{}
+@code{"done" | "running" | "connected" | "error" | "exit"}
+
+@item @var{async-class} @expansion{}
+@code{"stopped" | @var{others}} (where @var{others} will be added
+depending on the needs---this is still in development).
+
+@item @var{result} @expansion{}
+@code{ @var{variable} "=" @var{value}}
+
+@item @var{variable} @expansion{}
+@code{ @var{string} }
+
+@item @var{value} @expansion{}
+@code{ @var{const} | @var{tuple} | @var{list} }
+
+@item @var{const} @expansion{}
+@code{@var{c-string}}
+
+@item @var{tuple} @expansion{}
+@code{ "@{@}" | "@{" @var{result} ( "," @var{result} )* "@}" }
+
+@item @var{list} @expansion{}
+@code{ "[]" | "[" @var{value} ( "," @var{value} )* "]" | "["
+@var{result} ( "," @var{result} )* "]" }
+
+@item @var{stream-record} @expansion{}
+@code{@var{console-stream-output} | @var{target-stream-output} | @var{log-stream-output}}
+
+@item @var{console-stream-output} @expansion{}
+@code{"~" @var{c-string}}
+
+@item @var{target-stream-output} @expansion{}
+@code{"@@" @var{c-string}}
+
+@item @var{log-stream-output} @expansion{}
+@code{"&" @var{c-string}}
+
+@item @var{nl} @expansion{}
+@code{CR | CR-LF}
+
+@item @var{token} @expansion{}
+@emph{any sequence of digits}.
+@end table
+
+@noindent
+Notes:
+
+@itemize @bullet
+@item
+All output sequences end in a single line containing a period.
+
+@item
+The @code{@var{token}} is from the corresponding request. If an execution
+command is interrupted by the @samp{-exec-interrupt} command, the
+@var{token} associated with the @samp{*stopped} message is the one of the
+original execution command, not the one of the interrupt command.
+
+@item
+@cindex status output in @sc{gdb/mi}
+@var{status-async-output} contains on-going status information about the
+progress of a slow operation. It can be discarded. All status output is
+prefixed by @samp{+}.
+
+@item
+@cindex async output in @sc{gdb/mi}
+@var{exec-async-output} contains asynchronous state change on the target
+(stopped, started, disappeared). All async output is prefixed by
+@samp{*}.
+
+@item
+@cindex notify output in @sc{gdb/mi}
+@var{notify-async-output} contains supplementary information that the
+client should handle (e.g., a new breakpoint information). All notify
+output is prefixed by @samp{=}.
+
+@item
+@cindex console output in @sc{gdb/mi}
+@var{console-stream-output} is output that should be displayed as is in the
+console. It is the textual response to a CLI command. All the console
+output is prefixed by @samp{~}.
+
+@item
+@cindex target output in @sc{gdb/mi}
+@var{target-stream-output} is the output produced by the target program.
+All the target output is prefixed by @samp{@@}.
+
+@item
+@cindex log output in @sc{gdb/mi}
+@var{log-stream-output} is output text coming from @value{GDBN}'s internals, for
+instance messages that should be displayed as part of an error log. All
+the log output is prefixed by @samp{&}.
+
+@item
+@cindex list output in @sc{gdb/mi}
+New @sc{gdb/mi} commands should only output @var{lists} containing
+@var{values}.
+
+
+@end itemize
+
+@xref{GDB/MI Stream Records, , @sc{gdb/mi} Stream Records}, for more
+details about the various output records.
+
+@node GDB/MI Simple Examples
+@subsection Simple Examples of @sc{gdb/mi} Interaction
+@cindex @sc{gdb/mi}, simple examples
+
+This subsection presents several simple examples of interaction using
+the @sc{gdb/mi} interface. In these examples, @samp{->} means that the
+following line is passed to @sc{gdb/mi} as input, while @samp{<-} means
+the output received from @sc{gdb/mi}.
+
+@subsubheading Target Stop
+@c Ummm... There is no "-stop" command. This assumes async, no?
+Here's an example of stopping the inferior process:
+
+@smallexample
+-> -stop
+<- (@value{GDBP})
+@end smallexample
+
+@noindent
+and later:
+
+@smallexample
+<- *stop,reason="stop",address="0x123",source="a.c:123"
+<- (@value{GDBP})
+@end smallexample
+
+@subsubheading Simple CLI Command
+
+Here's an example of a simple CLI command being passed through
+@sc{gdb/mi} and on to the CLI.
+
+@smallexample
+-> print 1+2
+<- &"print 1+2\n"
+<- ~"$1 = 3\n"
+<- ^done
+<- (@value{GDBP})
+@end smallexample
+
+@subsubheading Command With Side Effects
+
+@smallexample
+-> -symbol-file xyz.exe
+<- *breakpoint,nr="3",address="0x123",source="a.c:123"
+<- (@value{GDBP})
+@end smallexample
+
+@subsubheading A Bad Command
+
+Here's what happens if you pass a non-existent command:
+
+@smallexample
+-> -rubbish
+<- ^error,msg="Undefined MI command: rubbish"
+<- (@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Compatibility with CLI
+@section @sc{gdb/mi} Compatibility with CLI
+
+@cindex compatibility, @sc{gdb/mi} and CLI
+@cindex @sc{gdb/mi}, compatibility with CLI
+To help users familiar with @value{GDBN}'s existing CLI interface, @sc{gdb/mi}
+accepts existing CLI commands. As specified by the syntax, such
+commands can be directly entered into the @sc{gdb/mi} interface and @value{GDBN} will
+respond.
+
+This mechanism is provided as an aid to developers of @sc{gdb/mi}
+clients and not as a reliable interface into the CLI. Since the command
+is being interpreteted in an environment that assumes @sc{gdb/mi}
+behaviour, the exact output of such commands is likely to end up being
+an un-supported hybrid of @sc{gdb/mi} and CLI output.
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Output Records
+@section @sc{gdb/mi} Output Records
+
+@menu
+* GDB/MI Result Records::
+* GDB/MI Stream Records::
+* GDB/MI Out-of-band Records::
+@end menu
+
+@node GDB/MI Result Records
+@subsection @sc{gdb/mi} Result Records
+
+@cindex result records in @sc{gdb/mi}
+@cindex @sc{gdb/mi}, result records
+In addition to a number of out-of-band notifications, the response to a
+@sc{gdb/mi} command includes one of the following result indications:
+
+@table @code
+@findex ^done
+@item "^done" [ "," @var{results} ]
+The synchronous operation was successful, @code{@var{results}} are the return
+values.
+
+@item "^running"
+@findex ^running
+@c Is this one correct? Should it be an out-of-band notification?
+The asynchronous operation was successfully started. The target is
+running.
+
+@item "^error" "," @var{c-string}
+@findex ^error
+The operation failed. The @code{@var{c-string}} contains the corresponding
+error message.
+@end table
+
+@node GDB/MI Stream Records
+@subsection @sc{gdb/mi} Stream Records
+
+@cindex @sc{gdb/mi}, stream records
+@cindex stream records in @sc{gdb/mi}
+@value{GDBN} internally maintains a number of output streams: the console, the
+target, and the log. The output intended for each of these streams is
+funneled through the @sc{gdb/mi} interface using @dfn{stream records}.
+
+Each stream record begins with a unique @dfn{prefix character} which
+identifies its stream (@pxref{GDB/MI Output Syntax, , @sc{gdb/mi} Output
+Syntax}). In addition to the prefix, each stream record contains a
+@code{@var{string-output}}. This is either raw text (with an implicit new
+line) or a quoted C string (which does not contain an implicit newline).
+
+@table @code
+@item "~" @var{string-output}
+The console output stream contains text that should be displayed in the
+CLI console window. It contains the textual responses to CLI commands.
+
+@item "@@" @var{string-output}
+The target output stream contains any textual output from the running
+target.
+
+@item "&" @var{string-output}
+The log stream contains debugging messages being produced by @value{GDBN}'s
+internals.
+@end table
+
+@node GDB/MI Out-of-band Records
+@subsection @sc{gdb/mi} Out-of-band Records
+
+@cindex out-of-band records in @sc{gdb/mi}
+@cindex @sc{gdb/mi}, out-of-band records
+@dfn{Out-of-band} records are used to notify the @sc{gdb/mi} client of
+additional changes that have occurred. Those changes can either be a
+consequence of @sc{gdb/mi} (e.g., a breakpoint modified) or a result of
+target activity (e.g., target stopped).
+
+The following is a preliminary list of possible out-of-band records.
+
+@table @code
+@item "*" "stop"
+@end table
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Command Description Format
+@section @sc{gdb/mi} Command Description Format
+
+The remaining sections describe blocks of commands. Each block of
+commands is laid out in a fashion similar to this section.
+
+Note the the line breaks shown in the examples are here only for
+readability. They don't appear in the real output.
+Also note that the commands with a non-available example (N.A.@:) are
+not yet implemented.
+
+@subheading Motivation
+
+The motivation for this collection of commands.
+
+@subheading Introduction
+
+A brief introduction to this collection of commands as a whole.
+
+@subheading Commands
+
+For each command in the block, the following is described:
+
+@subsubheading Synopsis
+
+@smallexample
+ -command @var{args}@dots{}
+@end smallexample
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} CLI command.
+
+@subsubheading Result
+
+@subsubheading Out-of-band
+
+@subsubheading Notes
+
+@subsubheading Example
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Breakpoint Table Commands
+@section @sc{gdb/mi} Breakpoint table commands
+
+@cindex breakpoint commands for @sc{gdb/mi}
+@cindex @sc{gdb/mi}, breakpoint commands
+This section documents @sc{gdb/mi} commands for manipulating
+breakpoints.
+
+@subheading The @code{-break-after} Command
+@findex -break-after
+
+@subsubheading Synopsis
+
+@smallexample
+ -break-after @var{number} @var{count}
+@end smallexample
+
+The breakpoint number @var{number} is not in effect until it has been
+hit @var{count} times. To see how this is reflected in the output of
+the @samp{-break-list} command, see the description of the
+@samp{-break-list} command below.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{ignore}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-insert main
+^done,bkpt=@{number="1",addr="0x000100d0",file="hello.c",line="5"@}
+(@value{GDBP})
+-break-after 1 3
+~
+^done
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="1",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0",
+ignore="3"@}]@}
+(@value{GDBP})
+@end smallexample
+
+@ignore
+@subheading The @code{-break-catch} Command
+@findex -break-catch
+
+@subheading The @code{-break-commands} Command
+@findex -break-commands
+@end ignore
+
+
+@subheading The @code{-break-condition} Command
+@findex -break-condition
+
+@subsubheading Synopsis
+
+@smallexample
+ -break-condition @var{number} @var{expr}
+@end smallexample
+
+Breakpoint @var{number} will stop the program only if the condition in
+@var{expr} is true. The condition becomes part of the
+@samp{-break-list} output (see the description of the @samp{-break-list}
+command below).
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{condition}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-condition 1 1
+^done
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="1",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",cond="1",
+times="0",ignore="3"@}]@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-delete} Command
+@findex -break-delete
+
+@subsubheading Synopsis
+
+@smallexample
+ -break-delete ( @var{breakpoint} )+
+@end smallexample
+
+Delete the breakpoint(s) whose number(s) are specified in the argument
+list. This is obviously reflected in the breakpoint list.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{delete}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-delete 1
+^done
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="0",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[]@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-disable} Command
+@findex -break-disable
+
+@subsubheading Synopsis
+
+@smallexample
+ -break-disable ( @var{breakpoint} )+
+@end smallexample
+
+Disable the named @var{breakpoint}(s). The field @samp{enabled} in the
+break list is now set to @samp{n} for the named @var{breakpoint}(s).
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{disable}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-disable 2
+^done
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="1",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="2",type="breakpoint",disp="keep",enabled="n",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}]@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-enable} Command
+@findex -break-enable
+
+@subsubheading Synopsis
+
+@smallexample
+ -break-enable ( @var{breakpoint} )+
+@end smallexample
+
+Enable (previously disabled) @var{breakpoint}(s).
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{enable}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-enable 2
+^done
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="1",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}]@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-info} Command
+@findex -break-info
+
+@subsubheading Synopsis
+
+@smallexample
+ -break-info @var{breakpoint}
+@end smallexample
+
+@c REDUNDANT???
+Get information about a single breakpoint.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{info break @var{breakpoint}}.
+
+@subsubheading Example
+N.A.
+
+@subheading The @code{-break-insert} Command
+@findex -break-insert
+
+@subsubheading Synopsis
+
+@smallexample
+ -break-insert [ -t ] [ -h ] [ -r ]
+ [ -c @var{condition} ] [ -i @var{ignore-count} ]
+ [ -p @var{thread} ] [ @var{line} | @var{addr} ]
+@end smallexample
+
+@noindent
+If specified, @var{line}, can be one of:
+
+@itemize @bullet
+@item function
+@c @item +offset
+@c @item -offset
+@c @item linenum
+@item filename:linenum
+@item filename:function
+@item *address
+@end itemize
+
+The possible optional parameters of this command are:
+
+@table @samp
+@item -t
+Insert a tempoary breakpoint.
+@item -h
+Insert a hardware breakpoint.
+@item -c @var{condition}
+Make the breakpoint conditional on @var{condition}.
+@item -i @var{ignore-count}
+Initialize the @var{ignore-count}.
+@item -r
+Insert a regular breakpoint in all the functions whose names match the
+given regular expression. Other flags are not applicable to regular
+expresson.
+@end table
+
+@subsubheading Result
+
+The result is in the form:
+
+@smallexample
+ ^done,bkptno="@var{number}",func="@var{funcname}",
+ file="@var{filename}",line="@var{lineno}"
+@end smallexample
+
+@noindent
+where @var{number} is the @value{GDBN} number for this breakpoint, @var{funcname}
+is the name of the function where the breakpoint was inserted,
+@var{filename} is the name of the source file which contains this
+function, and @var{lineno} is the source line number within that file.
+
+Note: this format is open to change.
+@c An out-of-band breakpoint instead of part of the result?
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{break}, @samp{tbreak},
+@samp{hbreak}, @samp{thbreak}, and @samp{rbreak}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-insert main
+^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@}
+(@value{GDBP})
+-break-insert -t foo
+^done,bkpt=@{number="2",addr="0x00010774",file="recursive2.c",line="11"@}
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="2",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x0001072c", func="main",file="recursive2.c",line="4",times="0"@},
+bkpt=@{number="2",type="breakpoint",disp="del",enabled="y",
+addr="0x00010774",func="foo",file="recursive2.c",line="11",times="0"@}]@}
+(@value{GDBP})
+-break-insert -r foo.*
+~int foo(int, int);
+^done,bkpt=@{number="3",addr="0x00010774",file="recursive2.c",line="11"@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-list} Command
+@findex -break-list
+
+@subsubheading Synopsis
+
+@smallexample
+ -break-list
+@end smallexample
+
+Displays the list of inserted breakpoints, showing the following fields:
+
+@table @samp
+@item Number
+number of the breakpoint
+@item Type
+type of the breakpoint: @samp{breakpoint} or @samp{watchpoint}
+@item Disposition
+should the breakpoint be deleted or disabled when it is hit: @samp{keep}
+or @samp{nokeep}
+@item Enabled
+is the breakpoint enabled or no: @samp{y} or @samp{n}
+@item Address
+memory location at which the breakpoint is set
+@item What
+logical location of the breakpoint, expressed by function name, file
+name, line number
+@item Times
+number of times the breakpoint has been hit
+@end table
+
+If there are no breakpoints or watchpoints, the @code{BreakpointTable}
+@code{body} field is an empty list.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info break}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="2",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@},
+bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y",
+addr="0x00010114",func="foo",file="hello.c",line="13",times="0"@}]@}
+(@value{GDBP})
+@end smallexample
+
+Here's an example of the result when there are no breakpoints:
+
+@smallexample
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="0",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[]@}
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-break-watch} Command
+@findex -break-watch
+
+@subsubheading Synopsis
+
+@smallexample
+ -break-watch [ -a | -r ]
+@end smallexample
+
+Create a watchpoint. With the @samp{-a} option it will create an
+@dfn{access} watchpoint, i.e. a watchpoint that triggers either on a
+read from or on a write to the memory location. With the @samp{-r}
+option, the watchpoint created is a @dfn{read} watchpoint, i.e. it will
+trigger only when the memory location is accessed for reading. Without
+either of the options, the watchpoint created is a regular watchpoint,
+i.e. it will trigger when the memory location is accessed for writing.
+@xref{Set Watchpoints, , Setting watchpoints}.
+
+Note that @samp{-break-list} will report a single list of watchpoints and
+breakpoints inserted.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{watch}, @samp{awatch}, and
+@samp{rwatch}.
+
+@subsubheading Example
+
+Setting a watchpoint on a variable in the @code{main} function:
+
+@smallexample
+(@value{GDBP})
+-break-watch x
+^done,wpt=@{number="2",exp="x"@}
+(@value{GDBP})
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",wpt=@{number="2",exp="x"@},
+value=@{old="-268439212",new="55"@},
+frame=@{func="main",args=[],file="recursive2.c",line="5"@}
+(@value{GDBP})
+@end smallexample
+
+Setting a watchpoint on a variable local to a function. @value{GDBN} will stop
+the program execution twice: first for the variable changing value, then
+for the watchpoint going out of scope.
+
+@smallexample
+(@value{GDBP})
+-break-watch C
+^done,wpt=@{number="5",exp="C"@}
+(@value{GDBP})
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",
+wpt=@{number="5",exp="C"@},value=@{old="-276895068",new="3"@},
+frame=@{func="callee4",args=[],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"@}
+(@value{GDBP})
+-exec-continue
+^running
+^done,reason="watchpoint-scope",wpnum="5",
+frame=@{func="callee3",args=[@{name="strarg",
+value="0x11940 \"A string argument.\""@}],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(@value{GDBP})
+@end smallexample
+
+Listing breakpoints and watchpoints, at different points in the program
+execution. Note that once the watchpoint goes out of scope, it is
+deleted.
+
+@smallexample
+(@value{GDBP})
+-break-watch C
+^done,wpt=@{number="2",exp="C"@}
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="2",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x00010734",func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@},
+bkpt=@{number="2",type="watchpoint",disp="keep",
+enabled="y",addr="",what="C",times="0"@}]@}
+(@value{GDBP})
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",wpt=@{number="2",exp="C"@},
+value=@{old="-276895068",new="3"@},
+frame=@{func="callee4",args=[],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"@}
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="2",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x00010734",func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@},
+bkpt=@{number="2",type="watchpoint",disp="keep",
+enabled="y",addr="",what="C",times="-5"@}]@}
+(@value{GDBP})
+-exec-continue
+^running
+^done,reason="watchpoint-scope",wpnum="2",
+frame=@{func="callee3",args=[@{name="strarg",
+value="0x11940 \"A string argument.\""@}],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(@value{GDBP})
+-break-list
+^done,BreakpointTable=@{nr_rows="1",nr_cols="6",
+hdr=[@{width="3",alignment="-1",col_name="number",colhdr="Num"@},
+@{width="14",alignment="-1",col_name="type",colhdr="Type"@},
+@{width="4",alignment="-1",col_name="disp",colhdr="Disp"@},
+@{width="3",alignment="-1",col_name="enabled",colhdr="Enb"@},
+@{width="10",alignment="-1",col_name="addr",colhdr="Address"@},
+@{width="40",alignment="2",col_name="what",colhdr="What"@}],
+body=[bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x00010734",func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@}]@}
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Data Manipulation
+@section @sc{gdb/mi} Data Manipulation
+
+@cindex data manipulation, in @sc{gdb/mi}
+@cindex @sc{gdb/mi}, data manipulation
+This section describes the @sc{gdb/mi} commands that manipulate data:
+examine memory and registers, evaluate expressions, etc.
+
+@c REMOVED FROM THE INTERFACE.
+@c @subheading -data-assign
+@c Change the value of a program variable. Plenty of side effects.
+@c @subsubheading GDB command
+@c set variable
+@c @subsubheading Example
+@c N.A.
+
+@subheading The @code{-data-disassemble} Command
+@findex -data-disassemble
+
+@subsubheading Synopsis
+
+@smallexample
+ -data-disassemble
+ [ -s @var{start-addr} -e @var{end-addr} ]
+ | [ -f @var{filename} -l @var{linenum} [ -n @var{lines} ] ]
+ -- @var{mode}
+@end smallexample
+
+@noindent
+Where:
+
+@table @samp
+@item @var{start-addr}
+is the beginning address (or @code{$pc})
+@item @var{end-addr}
+is the end address
+@item @var{filename}
+is the name of the file to disassemble
+@item @var{linenum}
+is the line number to disassemble around
+@item @var{lines}
+is the the number of disassembly lines to be produced. If it is -1,
+the whole function will be disassembled, in case no @var{end-addr} is
+specified. If @var{end-addr} is specified as a non-zero value, and
+@var{lines} is lower than the number of disassembly lines between
+@var{start-addr} and @var{end-addr}, only @var{lines} lines are
+displayed; if @var{lines} is higher than the number of lines between
+@var{start-addr} and @var{end-addr}, only the lines up to @var{end-addr}
+are displayed.
+@item @var{mode}
+is either 0 (meaning only disassembly) or 1 (meaning mixed source and
+disassembly).
+@end table
+
+@subsubheading Result
+
+The output for each instruction is composed of four fields:
+
+@itemize @bullet
+@item Address
+@item Func-name
+@item Offset
+@item Instruction
+@end itemize
+
+Note that whatever included in the instruction field, is not manipulated
+directely by @sc{gdb/mi}, i.e. it is not possible to adjust its format.
+
+@subsubheading @value{GDBN} Command
+
+There's no direct mapping from this command to the CLI.
+
+@subsubheading Example
+
+Disassemble from the current value of @code{$pc} to @code{$pc + 20}:
+
+@smallexample
+(@value{GDBP})
+-data-disassemble -s $pc -e "$pc + 20" -- 0
+^done,
+asm_insns=[
+@{address="0x000107c0",func-name="main",offset="4",
+inst="mov 2, %o0"@},
+@{address="0x000107c4",func-name="main",offset="8",
+inst="sethi %hi(0x11800), %o2"@},
+@{address="0x000107c8",func-name="main",offset="12",
+inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"@},
+@{address="0x000107cc",func-name="main",offset="16",
+inst="sethi %hi(0x11800), %o2"@},
+@{address="0x000107d0",func-name="main",offset="20",
+inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"@}]
+(@value{GDBP})
+@end smallexample
+
+Disassemble the whole @code{main} function. Line 32 is part of
+@code{main}.
+
+@smallexample
+-data-disassemble -f basics.c -l 32 -- 0
+^done,asm_insns=[
+@{address="0x000107bc",func-name="main",offset="0",
+inst="save %sp, -112, %sp"@},
+@{address="0x000107c0",func-name="main",offset="4",
+inst="mov 2, %o0"@},
+@{address="0x000107c4",func-name="main",offset="8",
+inst="sethi %hi(0x11800), %o2"@},
+[@dots{}]
+@{address="0x0001081c",func-name="main",offset="96",inst="ret "@},
+@{address="0x00010820",func-name="main",offset="100",inst="restore "@}]
+(@value{GDBP})
+@end smallexample
+
+Disassemble 3 instructions from the start of @code{main}:
+
+@smallexample
+(@value{GDBP})
+-data-disassemble -f basics.c -l 32 -n 3 -- 0
+^done,asm_insns=[
+@{address="0x000107bc",func-name="main",offset="0",
+inst="save %sp, -112, %sp"@},
+@{address="0x000107c0",func-name="main",offset="4",
+inst="mov 2, %o0"@},
+@{address="0x000107c4",func-name="main",offset="8",
+inst="sethi %hi(0x11800), %o2"@}]
+(@value{GDBP})
+@end smallexample
+
+Disassemble 3 instructions from the start of @code{main} in mixed mode:
+
+@smallexample
+(@value{GDBP})
+-data-disassemble -f basics.c -l 32 -n 3 -- 1
+^done,asm_insns=[
+src_and_asm_line=@{line="31",
+file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \
+ testsuite/gdb.mi/basics.c",line_asm_insn=[
+@{address="0x000107bc",func-name="main",offset="0",
+inst="save %sp, -112, %sp"@}]@},
+src_and_asm_line=@{line="32",
+file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \
+ testsuite/gdb.mi/basics.c",line_asm_insn=[
+@{address="0x000107c0",func-name="main",offset="4",
+inst="mov 2, %o0"@},
+@{address="0x000107c4",func-name="main",offset="8",
+inst="sethi %hi(0x11800), %o2"@}]@}]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-data-evaluate-expression} Command
+@findex -data-evaluate-expression
+
+@subsubheading Synopsis
+
+@smallexample
+ -data-evaluate-expression @var{expr}
+@end smallexample
+
+Evaluate @var{expr} as an expression. The expression could contain an
+inferior function call. The function call will execute synchronously.
+If the expression contains spaces, it must be enclosed in double quotes.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{print}, @samp{output}, and
+@samp{call}. In @code{gdbtk} only, there's a corresponding
+@samp{gdb_eval} command.
+
+@subsubheading Example
+
+In the following example, the numbers that precede the commands are the
+@dfn{tokens} described in @ref{GDB/MI Command Syntax, ,@sc{gdb/mi}
+Command Syntax}. Notice how @sc{gdb/mi} returns the same tokens in its
+output.
+
+@smallexample
+211-data-evaluate-expression A
+211^done,value="1"
+(@value{GDBP})
+311-data-evaluate-expression &A
+311^done,value="0xefffeb7c"
+(@value{GDBP})
+411-data-evaluate-expression A+3
+411^done,value="4"
+(@value{GDBP})
+511-data-evaluate-expression "A + 3"
+511^done,value="4"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-data-list-changed-registers} Command
+@findex -data-list-changed-registers
+
+@subsubheading Synopsis
+
+@smallexample
+ -data-list-changed-registers
+@end smallexample
+
+Display a list of the registers that have changed.
+
+@subsubheading @value{GDBN} Command
+
+@value{GDBN} doesn't have a direct analog for this command; @code{gdbtk}
+has the corresponding command @samp{gdb_changed_register_list}.
+
+@subsubheading Example
+
+On a PPC MBX board:
+
+@smallexample
+(@value{GDBP})
+-exec-continue
+^running
+
+(@value{GDBP})
+*stopped,reason="breakpoint-hit",bkptno="1",frame=@{func="main",
+args=[],file="try.c",line="5"@}
+(@value{GDBP})
+-data-list-changed-registers
+^done,changed-registers=["0","1","2","4","5","6","7","8","9",
+"10","11","13","14","15","16","17","18","19","20","21","22","23",
+"24","25","26","27","28","30","31","64","65","66","67","69"]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-data-list-register-names} Command
+@findex -data-list-register-names
+
+@subsubheading Synopsis
+
+@smallexample
+ -data-list-register-names [ ( @var{regno} )+ ]
+@end smallexample
+
+Show a list of register names for the current target. If no arguments
+are given, it shows a list of the names of all the registers. If
+integer numbers are given as arguments, it will print a list of the
+names of the registers corresponding to the arguments. To ensure
+consistency between a register name and its number, the output list may
+include empty register names.
+
+@subsubheading @value{GDBN} Command
+
+@value{GDBN} does not have a command which corresponds to
+@samp{-data-list-register-names}. In @code{gdbtk} there is a
+corresponding command @samp{gdb_regnames}.
+
+@subsubheading Example
+
+For the PPC MBX board:
+@smallexample
+(@value{GDBP})
+-data-list-register-names
+^done,register-names=["r0","r1","r2","r3","r4","r5","r6","r7",
+"r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18",
+"r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29",
+"r30","r31","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9",
+"f10","f11","f12","f13","f14","f15","f16","f17","f18","f19","f20",
+"f21","f22","f23","f24","f25","f26","f27","f28","f29","f30","f31",
+"", "pc","ps","cr","lr","ctr","xer"]
+(@value{GDBP})
+-data-list-register-names 1 2 3
+^done,register-names=["r1","r2","r3"]
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-data-list-register-values} Command
+@findex -data-list-register-values
+
+@subsubheading Synopsis
+
+@smallexample
+ -data-list-register-values @var{fmt} [ ( @var{regno} )*]
+@end smallexample
+
+Display the registers' contents. @var{fmt} is the format according to
+which the registers' contents are to be returned, followed by an optional
+list of numbers specifying the registers to display. A missing list of
+numbers indicates that the contents of all the registers must be returned.
+
+Allowed formats for @var{fmt} are:
+
+@table @code
+@item x
+Hexadecimal
+@item o
+Octal
+@item t
+Binary
+@item d
+Decimal
+@item r
+Raw
+@item N
+Natural
+@end table
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{info reg}, @samp{info
+all-reg}, and (in @code{gdbtk}) @samp{gdb_fetch_registers}.
+
+@subsubheading Example
+
+For a PPC MBX board (note: line breaks are for readability only, they
+don't appear in the actual output):
+
+@smallexample
+(@value{GDBP})
+-data-list-register-values r 64 65
+^done,register-values=[@{number="64",value="0xfe00a300"@},
+@{number="65",value="0x00029002"@}]
+(@value{GDBP})
+-data-list-register-values x
+^done,register-values=[@{number="0",value="0xfe0043c8"@},
+@{number="1",value="0x3fff88"@},@{number="2",value="0xfffffffe"@},
+@{number="3",value="0x0"@},@{number="4",value="0xa"@},
+@{number="5",value="0x3fff68"@},@{number="6",value="0x3fff58"@},
+@{number="7",value="0xfe011e98"@},@{number="8",value="0x2"@},
+@{number="9",value="0xfa202820"@},@{number="10",value="0xfa202808"@},
+@{number="11",value="0x1"@},@{number="12",value="0x0"@},
+@{number="13",value="0x4544"@},@{number="14",value="0xffdfffff"@},
+@{number="15",value="0xffffffff"@},@{number="16",value="0xfffffeff"@},
+@{number="17",value="0xefffffed"@},@{number="18",value="0xfffffffe"@},
+@{number="19",value="0xffffffff"@},@{number="20",value="0xffffffff"@},
+@{number="21",value="0xffffffff"@},@{number="22",value="0xfffffff7"@},
+@{number="23",value="0xffffffff"@},@{number="24",value="0xffffffff"@},
+@{number="25",value="0xffffffff"@},@{number="26",value="0xfffffffb"@},
+@{number="27",value="0xffffffff"@},@{number="28",value="0xf7bfffff"@},
+@{number="29",value="0x0"@},@{number="30",value="0xfe010000"@},
+@{number="31",value="0x0"@},@{number="32",value="0x0"@},
+@{number="33",value="0x0"@},@{number="34",value="0x0"@},
+@{number="35",value="0x0"@},@{number="36",value="0x0"@},
+@{number="37",value="0x0"@},@{number="38",value="0x0"@},
+@{number="39",value="0x0"@},@{number="40",value="0x0"@},
+@{number="41",value="0x0"@},@{number="42",value="0x0"@},
+@{number="43",value="0x0"@},@{number="44",value="0x0"@},
+@{number="45",value="0x0"@},@{number="46",value="0x0"@},
+@{number="47",value="0x0"@},@{number="48",value="0x0"@},
+@{number="49",value="0x0"@},@{number="50",value="0x0"@},
+@{number="51",value="0x0"@},@{number="52",value="0x0"@},
+@{number="53",value="0x0"@},@{number="54",value="0x0"@},
+@{number="55",value="0x0"@},@{number="56",value="0x0"@},
+@{number="57",value="0x0"@},@{number="58",value="0x0"@},
+@{number="59",value="0x0"@},@{number="60",value="0x0"@},
+@{number="61",value="0x0"@},@{number="62",value="0x0"@},
+@{number="63",value="0x0"@},@{number="64",value="0xfe00a300"@},
+@{number="65",value="0x29002"@},@{number="66",value="0x202f04b5"@},
+@{number="67",value="0xfe0043b0"@},@{number="68",value="0xfe00b3e4"@},
+@{number="69",value="0x20002b03"@}]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-data-read-memory} Command
+@findex -data-read-memory
+
+@subsubheading Synopsis
+
+@smallexample
+ -data-read-memory [ -o @var{byte-offset} ]
+ @var{address} @var{word-format} @var{word-size}
+ @var{nr-rows} @var{nr-cols} [ @var{aschar} ]
+@end smallexample
+
+@noindent
+where:
+
+@table @samp
+@item @var{address}
+An expression specifying the address of the first memory word to be
+read. Complex expressions containing embedded white space should be
+quoted using the C convention.
+
+@item @var{word-format}
+The format to be used to print the memory words. The notation is the
+same as for @value{GDBN}'s @code{print} command (@pxref{Output Formats,
+,Output formats}).
+
+@item @var{word-size}
+The size of each memory word in bytes.
+
+@item @var{nr-rows}
+The number of rows in the output table.
+
+@item @var{nr-cols}
+The number of columns in the output table.
+
+@item @var{aschar}
+If present, indicates that each row should include an @sc{ascii} dump. The
+value of @var{aschar} is used as a padding character when a byte is not a
+member of the printable @sc{ascii} character set (printable @sc{ascii}
+characters are those whose code is between 32 and 126, inclusively).
+
+@item @var{byte-offset}
+An offset to add to the @var{address} before fetching memory.
+@end table
+
+This command displays memory contents as a table of @var{nr-rows} by
+@var{nr-cols} words, each word being @var{word-size} bytes. In total,
+@code{@var{nr-rows} * @var{nr-cols} * @var{word-size}} bytes are read
+(returned as @samp{total-bytes}). Should less than the requested number
+of bytes be returned by the target, the missing words are identified
+using @samp{N/A}. The number of bytes read from the target is returned
+in @samp{nr-bytes} and the starting address used to read memory in
+@samp{addr}.
+
+The address of the next/previous row or page is available in
+@samp{next-row} and @samp{prev-row}, @samp{next-page} and
+@samp{prev-page}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{x}. @code{gdbtk} has
+@samp{gdb_get_mem} memory read command.
+
+@subsubheading Example
+
+Read six bytes of memory starting at @code{bytes+6} but then offset by
+@code{-6} bytes. Format as three rows of two columns. One byte per
+word. Display each word in hex.
+
+@smallexample
+(@value{GDBP})
+9-data-read-memory -o -6 -- bytes+6 x 1 3 2
+9^done,addr="0x00001390",nr-bytes="6",total-bytes="6",
+next-row="0x00001396",prev-row="0x0000138e",next-page="0x00001396",
+prev-page="0x0000138a",memory=[
+@{addr="0x00001390",data=["0x00","0x01"]@},
+@{addr="0x00001392",data=["0x02","0x03"]@},
+@{addr="0x00001394",data=["0x04","0x05"]@}]
+(@value{GDBP})
+@end smallexample
+
+Read two bytes of memory starting at address @code{shorts + 64} and
+display as a single word formatted in decimal.
+
+@smallexample
+(@value{GDBP})
+5-data-read-memory shorts+64 d 2 1 1
+5^done,addr="0x00001510",nr-bytes="2",total-bytes="2",
+next-row="0x00001512",prev-row="0x0000150e",
+next-page="0x00001512",prev-page="0x0000150e",memory=[
+@{addr="0x00001510",data=["128"]@}]
+(@value{GDBP})
+@end smallexample
+
+Read thirty two bytes of memory starting at @code{bytes+16} and format
+as eight rows of four columns. Include a string encoding with @samp{x}
+used as the non-printable character.
+
+@smallexample
+(@value{GDBP})
+4-data-read-memory bytes+16 x 1 8 4 x
+4^done,addr="0x000013a0",nr-bytes="32",total-bytes="32",
+next-row="0x000013c0",prev-row="0x0000139c",
+next-page="0x000013c0",prev-page="0x00001380",memory=[
+@{addr="0x000013a0",data=["0x10","0x11","0x12","0x13"],ascii="xxxx"@},
+@{addr="0x000013a4",data=["0x14","0x15","0x16","0x17"],ascii="xxxx"@},
+@{addr="0x000013a8",data=["0x18","0x19","0x1a","0x1b"],ascii="xxxx"@},
+@{addr="0x000013ac",data=["0x1c","0x1d","0x1e","0x1f"],ascii="xxxx"@},
+@{addr="0x000013b0",data=["0x20","0x21","0x22","0x23"],ascii=" !\"#"@},
+@{addr="0x000013b4",data=["0x24","0x25","0x26","0x27"],ascii="$%&'"@},
+@{addr="0x000013b8",data=["0x28","0x29","0x2a","0x2b"],ascii="()*+"@},
+@{addr="0x000013bc",data=["0x2c","0x2d","0x2e","0x2f"],ascii=",-./"@}]
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-display-delete} Command
+@findex -display-delete
+
+@subsubheading Synopsis
+
+@smallexample
+ -display-delete @var{number}
+@end smallexample
+
+Delete the display @var{number}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{delete display}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-display-disable} Command
+@findex -display-disable
+
+@subsubheading Synopsis
+
+@smallexample
+ -display-disable @var{number}
+@end smallexample
+
+Disable display @var{number}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{disable display}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-display-enable} Command
+@findex -display-enable
+
+@subsubheading Synopsis
+
+@smallexample
+ -display-enable @var{number}
+@end smallexample
+
+Enable display @var{number}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{enable display}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-display-insert} Command
+@findex -display-insert
+
+@subsubheading Synopsis
+
+@smallexample
+ -display-insert @var{expression}
+@end smallexample
+
+Display @var{expression} every time the program stops.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{display}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-display-list} Command
+@findex -display-list
+
+@subsubheading Synopsis
+
+@smallexample
+ -display-list
+@end smallexample
+
+List the displays. Do not show the current values.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info display}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-environment-cd} Command
+@findex -environment-cd
+
+@subsubheading Synopsis
+
+@smallexample
+ -environment-cd @var{pathdir}
+@end smallexample
+
+Set @value{GDBN}'s working directory.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{cd}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-environment-cd /kwikemart/marge/ezannoni/flathead-dev/devo/gdb
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-environment-directory} Command
+@findex -environment-directory
+
+@subsubheading Synopsis
+
+@smallexample
+ -environment-directory [ -r ] [ @var{pathdir} ]+
+@end smallexample
+
+Add directories @var{pathdir} to beginning of search path for source files.
+If the @samp{-r} option is used, the search path is reset to the default
+search path. If directories @var{pathdir} are supplied in addition to the
+@samp{-r} option, the search path is first reset and then addition
+occurs as normal.
+Multiple directories may be specified, separated by blanks. Specifying
+multiple directories in a single command
+results in the directories added to the beginning of the
+search path in the same order they were presented in the command.
+If blanks are needed as
+part of a directory name, double-quotes should be used around
+the name. In the command output, the path will show up separated
+by the system directory-separator character. The directory-seperator
+character must not be used
+in any directory name.
+If no directories are specified, the current search path is displayed.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{dir}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-environment-directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb
+^done,source-path="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb:$cdir:$cwd"
+(@value{GDBP})
+-environment-directory ""
+^done,source-path="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb:$cdir:$cwd"
+(@value{GDBP})
+-environment-directory -r /home/jjohnstn/src/gdb /usr/src
+^done,source-path="/home/jjohnstn/src/gdb:/usr/src:$cdir:$cwd"
+(@value{GDBP})
+-environment-directory -r
+^done,source-path="$cdir:$cwd"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-environment-path} Command
+@findex -environment-path
+
+@subsubheading Synopsis
+
+@smallexample
+ -environment-path [ -r ] [ @var{pathdir} ]+
+@end smallexample
+
+Add directories @var{pathdir} to beginning of search path for object files.
+If the @samp{-r} option is used, the search path is reset to the original
+search path that existed at gdb start-up. If directories @var{pathdir} are
+supplied in addition to the
+@samp{-r} option, the search path is first reset and then addition
+occurs as normal.
+Multiple directories may be specified, separated by blanks. Specifying
+multiple directories in a single command
+results in the directories added to the beginning of the
+search path in the same order they were presented in the command.
+If blanks are needed as
+part of a directory name, double-quotes should be used around
+the name. In the command output, the path will show up separated
+by the system directory-separator character. The directory-seperator
+character must not be used
+in any directory name.
+If no directories are specified, the current path is displayed.
+
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{path}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-environment-path
+^done,path="/usr/bin"
+(@value{GDBP})
+-environment-path /kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb /bin
+^done,path="/kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb:/bin:/usr/bin"
+(@value{GDBP})
+-environment-path -r /usr/local/bin
+^done,path="/usr/local/bin:/usr/bin"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-environment-pwd} Command
+@findex -environment-pwd
+
+@subsubheading Synopsis
+
+@smallexample
+ -environment-pwd
+@end smallexample
+
+Show the current working directory.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{pwd}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-environment-pwd
+^done,cwd="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb"
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Program Control
+@section @sc{gdb/mi} Program control
+
+@subsubheading Program termination
+
+As a result of execution, the inferior program can run to completion, if
+it doesn't encounter any breakpoints. In this case the output will
+include an exit code, if the program has exited exceptionally.
+
+@subsubheading Examples
+
+@noindent
+Program exited normally:
+
+@smallexample
+(@value{GDBP})
+-exec-run
+^running
+(@value{GDBP})
+x = 55
+*stopped,reason="exited-normally"
+(@value{GDBP})
+@end smallexample
+
+@noindent
+Program exited exceptionally:
+
+@smallexample
+(@value{GDBP})
+-exec-run
+^running
+(@value{GDBP})
+x = 55
+*stopped,reason="exited",exit-code="01"
+(@value{GDBP})
+@end smallexample
+
+Another way the program can terminate is if it receives a signal such as
+@code{SIGINT}. In this case, @sc{gdb/mi} displays this:
+
+@smallexample
+(@value{GDBP})
+*stopped,reason="exited-signalled",signal-name="SIGINT",
+signal-meaning="Interrupt"
+@end smallexample
+
+
+@subheading The @code{-exec-abort} Command
+@findex -exec-abort
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-abort
+@end smallexample
+
+Kill the inferior running program.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{kill}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-exec-arguments} Command
+@findex -exec-arguments
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-arguments @var{args}
+@end smallexample
+
+Set the inferior program arguments, to be used in the next
+@samp{-exec-run}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{set args}.
+
+@subsubheading Example
+
+@c FIXME!
+Don't have one around.
+
+
+@subheading The @code{-exec-continue} Command
+@findex -exec-continue
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-continue
+@end smallexample
+
+Asynchronous command. Resumes the execution of the inferior program
+until a breakpoint is encountered, or until the inferior exits.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} corresponding is @samp{continue}.
+
+@subsubheading Example
+
+@smallexample
+-exec-continue
+^running
+(@value{GDBP})
+@@Hello world
+*stopped,reason="breakpoint-hit",bkptno="2",frame=@{func="foo",args=[],
+file="hello.c",line="13"@}
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-finish} Command
+@findex -exec-finish
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-finish
+@end smallexample
+
+Asynchronous command. Resumes the execution of the inferior program
+until the current function is exited. Displays the results returned by
+the function.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{finish}.
+
+@subsubheading Example
+
+Function returning @code{void}.
+
+@smallexample
+-exec-finish
+^running
+(@value{GDBP})
+@@hello from foo
+*stopped,reason="function-finished",frame=@{func="main",args=[],
+file="hello.c",line="7"@}
+(@value{GDBP})
+@end smallexample
+
+Function returning other than @code{void}. The name of the internal
+@value{GDBN} variable storing the result is printed, together with the
+value itself.
+
+@smallexample
+-exec-finish
+^running
+(@value{GDBP})
+*stopped,reason="function-finished",frame=@{addr="0x000107b0",func="foo",
+args=[@{name="a",value="1"],@{name="b",value="9"@}@},
+file="recursive2.c",line="14"@},
+gdb-result-var="$1",return-value="0"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-interrupt} Command
+@findex -exec-interrupt
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-interrupt
+@end smallexample
+
+Asynchronous command. Interrupts the background execution of the target.
+Note how the token associated with the stop message is the one for the
+execution command that has been interrupted. The token for the interrupt
+itself only appears in the @samp{^done} output. If the user is trying to
+interrupt a non-running program, an error message will be printed.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{interrupt}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+111-exec-continue
+111^running
+
+(@value{GDBP})
+222-exec-interrupt
+222^done
+(@value{GDBP})
+111*stopped,signal-name="SIGINT",signal-meaning="Interrupt",
+frame=@{addr="0x00010140",func="foo",args=[],file="try.c",line="13"@}
+(@value{GDBP})
+
+(@value{GDBP})
+-exec-interrupt
+^error,msg="mi_cmd_exec_interrupt: Inferior not executing."
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-next} Command
+@findex -exec-next
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-next
+@end smallexample
+
+Asynchronous command. Resumes execution of the inferior program, stopping
+when the beginning of the next source line is reached.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{next}.
+
+@subsubheading Example
+
+@smallexample
+-exec-next
+^running
+(@value{GDBP})
+*stopped,reason="end-stepping-range",line="8",file="hello.c"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-next-instruction} Command
+@findex -exec-next-instruction
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-next-instruction
+@end smallexample
+
+Asynchronous command. Executes one machine instruction. If the
+instruction is a function call continues until the function returns. If
+the program stops at an instruction in the middle of a source line, the
+address will be printed as well.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{nexti}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-exec-next-instruction
+^running
+
+(@value{GDBP})
+*stopped,reason="end-stepping-range",
+addr="0x000100d4",line="5",file="hello.c"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-return} Command
+@findex -exec-return
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-return
+@end smallexample
+
+Makes current function return immediately. Doesn't execute the inferior.
+Displays the new current frame.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{return}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+200-break-insert callee4
+200^done,bkpt=@{number="1",addr="0x00010734",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@}
+(@value{GDBP})
+000-exec-run
+000^running
+(@value{GDBP})
+000*stopped,reason="breakpoint-hit",bkptno="1",
+frame=@{func="callee4",args=[],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@}
+(@value{GDBP})
+205-break-delete
+205^done
+(@value{GDBP})
+111-exec-return
+111^done,frame=@{level="0",func="callee3",
+args=[@{name="strarg",
+value="0x11940 \"A string argument.\""@}],
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-run} Command
+@findex -exec-run
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-run
+@end smallexample
+
+Asynchronous command. Starts execution of the inferior from the
+beginning. The inferior executes until either a breakpoint is
+encountered or the program exits.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{run}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-break-insert main
+^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@}
+(@value{GDBP})
+-exec-run
+^running
+(@value{GDBP})
+*stopped,reason="breakpoint-hit",bkptno="1",
+frame=@{func="main",args=[],file="recursive2.c",line="4"@}
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-show-arguments} Command
+@findex -exec-show-arguments
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-show-arguments
+@end smallexample
+
+Print the arguments of the program.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{show args}.
+
+@subsubheading Example
+N.A.
+
+@c @subheading -exec-signal
+
+@subheading The @code{-exec-step} Command
+@findex -exec-step
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-step
+@end smallexample
+
+Asynchronous command. Resumes execution of the inferior program, stopping
+when the beginning of the next source line is reached, if the next
+source line is not a function call. If it is, stop at the first
+instruction of the called function.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{step}.
+
+@subsubheading Example
+
+Stepping into a function:
+
+@smallexample
+-exec-step
+^running
+(@value{GDBP})
+*stopped,reason="end-stepping-range",
+frame=@{func="foo",args=[@{name="a",value="10"@},
+@{name="b",value="0"@}],file="recursive2.c",line="11"@}
+(@value{GDBP})
+@end smallexample
+
+Regular stepping:
+
+@smallexample
+-exec-step
+^running
+(@value{GDBP})
+*stopped,reason="end-stepping-range",line="14",file="recursive2.c"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-step-instruction} Command
+@findex -exec-step-instruction
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-step-instruction
+@end smallexample
+
+Asynchronous command. Resumes the inferior which executes one machine
+instruction. The output, once @value{GDBN} has stopped, will vary depending on
+whether we have stopped in the middle of a source line or not. In the
+former case, the address at which the program stopped will be printed as
+well.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{stepi}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-exec-step-instruction
+^running
+
+(@value{GDBP})
+*stopped,reason="end-stepping-range",
+frame=@{func="foo",args=[],file="try.c",line="10"@}
+(@value{GDBP})
+-exec-step-instruction
+^running
+
+(@value{GDBP})
+*stopped,reason="end-stepping-range",
+frame=@{addr="0x000100f4",func="foo",args=[],file="try.c",line="10"@}
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-exec-until} Command
+@findex -exec-until
+
+@subsubheading Synopsis
+
+@smallexample
+ -exec-until [ @var{location} ]
+@end smallexample
+
+Asynchronous command. Executes the inferior until the @var{location}
+specified in the argument is reached. If there is no argument, the inferior
+executes until a source line greater than the current one is reached.
+The reason for stopping in this case will be @samp{location-reached}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{until}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-exec-until recursive2.c:6
+^running
+(@value{GDBP})
+x = 55
+*stopped,reason="location-reached",frame=@{func="main",args=[],
+file="recursive2.c",line="6"@}
+(@value{GDBP})
+@end smallexample
+
+@ignore
+@subheading -file-clear
+Is this going away????
+@end ignore
+
+
+@subheading The @code{-file-exec-and-symbols} Command
+@findex -file-exec-and-symbols
+
+@subsubheading Synopsis
+
+@smallexample
+ -file-exec-and-symbols @var{file}
+@end smallexample
+
+Specify the executable file to be debugged. This file is the one from
+which the symbol table is also read. If no file is specified, the
+command clears the executable and symbol information. If breakpoints
+are set when using this command with no arguments, @value{GDBN} will produce
+error messages. Otherwise, no output is produced, except a completion
+notification.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{file}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-file-exec-and-symbols /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-file-exec-file} Command
+@findex -file-exec-file
+
+@subsubheading Synopsis
+
+@smallexample
+ -file-exec-file @var{file}
+@end smallexample
+
+Specify the executable file to be debugged. Unlike
+@samp{-file-exec-and-symbols}, the symbol table is @emph{not} read
+from this file. If used without argument, @value{GDBN} clears the information
+about the executable file. No output is produced, except a completion
+notification.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{exec-file}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-file-list-exec-sections} Command
+@findex -file-list-exec-sections
+
+@subsubheading Synopsis
+
+@smallexample
+ -file-list-exec-sections
+@end smallexample
+
+List the sections of the current executable file.
+
+@subsubheading @value{GDBN} Command
+
+The @value{GDBN} command @samp{info file} shows, among the rest, the same
+information as this command. @code{gdbtk} has a corresponding command
+@samp{gdb_load_info}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-file-list-exec-source-file} Command
+@findex -file-list-exec-source-file
+
+@subsubheading Synopsis
+
+@smallexample
+ -file-list-exec-source-file
+@end smallexample
+
+List the line number, the current source file, and the absolute path
+to the current source file for the current executable.
+
+@subsubheading @value{GDBN} Command
+
+There's no @value{GDBN} command which directly corresponds to this one.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+123-file-list-exec-source-file
+123^done,line="1",file="foo.c",fullname="/home/bar/foo.c"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-file-list-exec-source-files} Command
+@findex -file-list-exec-source-files
+
+@subsubheading Synopsis
+
+@smallexample
+ -file-list-exec-source-files
+@end smallexample
+
+List the source files for the current executable.
+
+@subsubheading @value{GDBN} Command
+
+There's no @value{GDBN} command which directly corresponds to this one.
+@code{gdbtk} has an analogous command @samp{gdb_listfiles}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-file-list-shared-libraries} Command
+@findex -file-list-shared-libraries
+
+@subsubheading Synopsis
+
+@smallexample
+ -file-list-shared-libraries
+@end smallexample
+
+List the shared libraries in the program.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info shared}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-file-list-symbol-files} Command
+@findex -file-list-symbol-files
+
+@subsubheading Synopsis
+
+@smallexample
+ -file-list-symbol-files
+@end smallexample
+
+List symbol files.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info file} (part of it).
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-file-symbol-file} Command
+@findex -file-symbol-file
+
+@subsubheading Synopsis
+
+@smallexample
+ -file-symbol-file @var{file}
+@end smallexample
+
+Read symbol table info from the specified @var{file} argument. When
+used without arguments, clears @value{GDBN}'s symbol table info. No output is
+produced, except for a completion notification.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{symbol-file}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-file-symbol-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Miscellaneous Commands
+@section Miscellaneous @value{GDBN} commands in @sc{gdb/mi}
+
+@c @subheading -gdb-complete
+
+@subheading The @code{-gdb-exit} Command
+@findex -gdb-exit
+
+@subsubheading Synopsis
+
+@smallexample
+ -gdb-exit
+@end smallexample
+
+Exit @value{GDBN} immediately.
+
+@subsubheading @value{GDBN} Command
+
+Approximately corresponds to @samp{quit}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-gdb-exit
+@end smallexample
+
+@subheading The @code{-gdb-set} Command
+@findex -gdb-set
+
+@subsubheading Synopsis
+
+@smallexample
+ -gdb-set
+@end smallexample
+
+Set an internal @value{GDBN} variable.
+@c IS THIS A DOLLAR VARIABLE? OR SOMETHING LIKE ANNOTATE ?????
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{set}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-gdb-set $foo=3
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-gdb-show} Command
+@findex -gdb-show
+
+@subsubheading Synopsis
+
+@smallexample
+ -gdb-show
+@end smallexample
+
+Show the current value of a @value{GDBN} variable.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{show}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-gdb-show annotate
+^done,value="0"
+(@value{GDBP})
+@end smallexample
+
+@c @subheading -gdb-source
+
+
+@subheading The @code{-gdb-version} Command
+@findex -gdb-version
+
+@subsubheading Synopsis
+
+@smallexample
+ -gdb-version
+@end smallexample
+
+Show version information for @value{GDBN}. Used mostly in testing.
+
+@subsubheading @value{GDBN} Command
+
+There's no equivalent @value{GDBN} command. @value{GDBN} by default shows this
+information when you start an interactive session.
+
+@subsubheading Example
+
+@c This example modifies the actual output from GDB to avoid overfull
+@c box in TeX.
+@smallexample
+(@value{GDBP})
+-gdb-version
+~GNU gdb 5.2.1
+~Copyright 2000 Free Software Foundation, Inc.
+~GDB is free software, covered by the GNU General Public License, and
+~you are welcome to change it and/or distribute copies of it under
+~ certain conditions.
+~Type "show copying" to see the conditions.
+~There is absolutely no warranty for GDB. Type "show warranty" for
+~ details.
+~This GDB was configured as
+ "--host=sparc-sun-solaris2.5.1 --target=ppc-eabi".
+^done
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-interpreter-exec} Command
+@findex -interpreter-exec
+
+@subheading Synopsis
+
+@smallexample
+-interpreter-exec @var{interpreter} @var{command}
+@end smallexample
+
+Execute the specified @var{command} in the given @var{interpreter}.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{interpreter-exec}.
+
+@subheading Example
+
+@smallexample
+(@value{GDBP})
+-interpreter-exec console "break main"
+&"During symbol reading, couldn't parse type; debugger out of date?.\n"
+&"During symbol reading, bad structure-type format.\n"
+~"Breakpoint 1 at 0x8074fc6: file ../../src/gdb/main.c, line 743.\n"
+^done
+(@value{GDBP})
+@end smallexample
+
+@ignore
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Kod Commands
+@section @sc{gdb/mi} Kod Commands
+
+The Kod commands are not implemented.
+
+@c @subheading -kod-info
+
+@c @subheading -kod-list
+
+@c @subheading -kod-list-object-types
+
+@c @subheading -kod-show
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Memory Overlay Commands
+@section @sc{gdb/mi} Memory Overlay Commands
+
+The memory overlay commands are not implemented.
+
+@c @subheading -overlay-auto
+
+@c @subheading -overlay-list-mapping-state
+
+@c @subheading -overlay-list-overlays
+
+@c @subheading -overlay-map
+
+@c @subheading -overlay-off
+
+@c @subheading -overlay-on
+
+@c @subheading -overlay-unmap
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Signal Handling Commands
+@section @sc{gdb/mi} Signal Handling Commands
+
+Signal handling commands are not implemented.
+
+@c @subheading -signal-handle
+
+@c @subheading -signal-list-handle-actions
+
+@c @subheading -signal-list-signal-types
+@end ignore
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Stack Manipulation
+@section @sc{gdb/mi} Stack Manipulation Commands
+
+
+@subheading The @code{-stack-info-frame} Command
+@findex -stack-info-frame
+
+@subsubheading Synopsis
+
+@smallexample
+ -stack-info-frame
+@end smallexample
+
+Get info on the current frame.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info frame} or @samp{frame}
+(without arguments).
+
+@subsubheading Example
+N.A.
+
+@subheading The @code{-stack-info-depth} Command
+@findex -stack-info-depth
+
+@subsubheading Synopsis
+
+@smallexample
+ -stack-info-depth [ @var{max-depth} ]
+@end smallexample
+
+Return the depth of the stack. If the integer argument @var{max-depth}
+is specified, do not count beyond @var{max-depth} frames.
+
+@subsubheading @value{GDBN} Command
+
+There's no equivalent @value{GDBN} command.
+
+@subsubheading Example
+
+For a stack with frame levels 0 through 11:
+
+@smallexample
+(@value{GDBP})
+-stack-info-depth
+^done,depth="12"
+(@value{GDBP})
+-stack-info-depth 4
+^done,depth="4"
+(@value{GDBP})
+-stack-info-depth 12
+^done,depth="12"
+(@value{GDBP})
+-stack-info-depth 11
+^done,depth="11"
+(@value{GDBP})
+-stack-info-depth 13
+^done,depth="12"
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-stack-list-arguments} Command
+@findex -stack-list-arguments
+
+@subsubheading Synopsis
+
+@smallexample
+ -stack-list-arguments @var{show-values}
+ [ @var{low-frame} @var{high-frame} ]
+@end smallexample
+
+Display a list of the arguments for the frames between @var{low-frame}
+and @var{high-frame} (inclusive). If @var{low-frame} and
+@var{high-frame} are not provided, list the arguments for the whole call
+stack.
+
+The @var{show-values} argument must have a value of 0 or 1. A value of
+0 means that only the names of the arguments are listed, a value of 1
+means that both names and values of the arguments are printed.
+
+@subsubheading @value{GDBN} Command
+
+@value{GDBN} does not have an equivalent command. @code{gdbtk} has a
+@samp{gdb_get_args} command which partially overlaps with the
+functionality of @samp{-stack-list-arguments}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-stack-list-frames
+^done,
+stack=[
+frame=@{level="0",addr="0x00010734",func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@},
+frame=@{level="1",addr="0x0001076c",func="callee3",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="17"@},
+frame=@{level="2",addr="0x0001078c",func="callee2",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="22"@},
+frame=@{level="3",addr="0x000107b4",func="callee1",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="27"@},
+frame=@{level="4",addr="0x000107e0",func="main",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="32"@}]
+(@value{GDBP})
+-stack-list-arguments 0
+^done,
+stack-args=[
+frame=@{level="0",args=[]@},
+frame=@{level="1",args=[name="strarg"]@},
+frame=@{level="2",args=[name="intarg",name="strarg"]@},
+frame=@{level="3",args=[name="intarg",name="strarg",name="fltarg"]@},
+frame=@{level="4",args=[]@}]
+(@value{GDBP})
+-stack-list-arguments 1
+^done,
+stack-args=[
+frame=@{level="0",args=[]@},
+frame=@{level="1",
+ args=[@{name="strarg",value="0x11940 \"A string argument.\""@}]@},
+frame=@{level="2",args=[
+@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@}]@},
+@{frame=@{level="3",args=[
+@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@},
+@{name="fltarg",value="3.5"@}]@},
+frame=@{level="4",args=[]@}]
+(@value{GDBP})
+-stack-list-arguments 0 2 2
+^done,stack-args=[frame=@{level="2",args=[name="intarg",name="strarg"]@}]
+(@value{GDBP})
+-stack-list-arguments 1 2 2
+^done,stack-args=[frame=@{level="2",
+args=[@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@}]@}]
+(@value{GDBP})
+@end smallexample
+
+@c @subheading -stack-list-exception-handlers
+
+
+@subheading The @code{-stack-list-frames} Command
+@findex -stack-list-frames
+
+@subsubheading Synopsis
+
+@smallexample
+ -stack-list-frames [ @var{low-frame} @var{high-frame} ]
+@end smallexample
+
+List the frames currently on the stack. For each frame it displays the
+following info:
+
+@table @samp
+@item @var{level}
+The frame number, 0 being the topmost frame, i.e. the innermost function.
+@item @var{addr}
+The @code{$pc} value for that frame.
+@item @var{func}
+Function name.
+@item @var{file}
+File name of the source file where the function lives.
+@item @var{line}
+Line number corresponding to the @code{$pc}.
+@end table
+
+If invoked without arguments, this command prints a backtrace for the
+whole stack. If given two integer arguments, it shows the frames whose
+levels are between the two arguments (inclusive). If the two arguments
+are equal, it shows the single frame at the corresponding level.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{backtrace} and @samp{where}.
+
+@subsubheading Example
+
+Full stack backtrace:
+
+@smallexample
+(@value{GDBP})
+-stack-list-frames
+^done,stack=
+[frame=@{level="0",addr="0x0001076c",func="foo",
+ file="recursive2.c",line="11"@},
+frame=@{level="1",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="2",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="3",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="4",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="5",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="6",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="7",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="8",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="9",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="10",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="11",addr="0x00010738",func="main",
+ file="recursive2.c",line="4"@}]
+(@value{GDBP})
+@end smallexample
+
+Show frames between @var{low_frame} and @var{high_frame}:
+
+@smallexample
+(@value{GDBP})
+-stack-list-frames 3 5
+^done,stack=
+[frame=@{level="3",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="4",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@},
+frame=@{level="5",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@}]
+(@value{GDBP})
+@end smallexample
+
+Show a single frame:
+
+@smallexample
+(@value{GDBP})
+-stack-list-frames 3 3
+^done,stack=
+[frame=@{level="3",addr="0x000107a4",func="foo",
+ file="recursive2.c",line="14"@}]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-stack-list-locals} Command
+@findex -stack-list-locals
+
+@subsubheading Synopsis
+
+@smallexample
+ -stack-list-locals @var{print-values}
+@end smallexample
+
+Display the local variable names for the current frame. With an
+argument of 0 or @code{--no-values}, prints only the names of the variables.
+With argument of 1 or @code{--all-values}, prints also their values. With
+argument of 2 or @code{--simple-values}, prints the name, type and value for
+simple data types and the name and type for arrays, structures and
+unions. In this last case, the idea is that the user can see the
+value of simple data types immediately and he can create variable
+objects for other data types if he wishes to explore their values in
+more detail.
+
+@subsubheading @value{GDBN} Command
+
+@samp{info locals} in @value{GDBN}, @samp{gdb_get_locals} in @code{gdbtk}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-stack-list-locals 0
+^done,locals=[name="A",name="B",name="C"]
+(@value{GDBP})
+-stack-list-locals --all-values
+^done,locals=[@{name="A",value="1"@},@{name="B",value="2"@},
+ @{name="C",value="@{1, 2, 3@}"@}]
+-stack-list-locals --simple-values
+^done,locals=[@{name="A",type="int",value="1"@},
+ @{name="B",type="int",value="2"@},@{name="C",type="int [3]"@}]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-stack-select-frame} Command
+@findex -stack-select-frame
+
+@subsubheading Synopsis
+
+@smallexample
+ -stack-select-frame @var{framenum}
+@end smallexample
+
+Change the current frame. Select a different frame @var{framenum} on
+the stack.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} commands are @samp{frame}, @samp{up},
+@samp{down}, @samp{select-frame}, @samp{up-silent}, and @samp{down-silent}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-stack-select-frame 2
+^done
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Symbol Query
+@section @sc{gdb/mi} Symbol Query Commands
+
+
+@subheading The @code{-symbol-info-address} Command
+@findex -symbol-info-address
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-info-address @var{symbol}
+@end smallexample
+
+Describe where @var{symbol} is stored.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info address}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-info-file} Command
+@findex -symbol-info-file
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-info-file
+@end smallexample
+
+Show the file for the symbol.
+
+@subsubheading @value{GDBN} Command
+
+There's no equivalent @value{GDBN} command. @code{gdbtk} has
+@samp{gdb_find_file}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-info-function} Command
+@findex -symbol-info-function
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-info-function
+@end smallexample
+
+Show which function the symbol lives in.
+
+@subsubheading @value{GDBN} Command
+
+@samp{gdb_get_function} in @code{gdbtk}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-info-line} Command
+@findex -symbol-info-line
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-info-line
+@end smallexample
+
+Show the core addresses of the code for a source line.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info line}.
+@code{gdbtk} has the @samp{gdb_get_line} and @samp{gdb_get_file} commands.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-info-symbol} Command
+@findex -symbol-info-symbol
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-info-symbol @var{addr}
+@end smallexample
+
+Describe what symbol is at location @var{addr}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{info symbol}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-list-functions} Command
+@findex -symbol-list-functions
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-list-functions
+@end smallexample
+
+List the functions in the executable.
+
+@subsubheading @value{GDBN} Command
+
+@samp{info functions} in @value{GDBN}, @samp{gdb_listfunc} and
+@samp{gdb_search} in @code{gdbtk}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-list-lines} Command
+@findex -symbol-list-lines
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-list-lines @var{filename}
+@end smallexample
+
+Print the list of lines that contain code and their associated program
+addresses for the given source filename. The entries are sorted in
+ascending PC order.
+
+@subsubheading @value{GDBN} Command
+
+There is no corresponding @value{GDBN} command.
+
+@subsubheading Example
+@smallexample
+(@value{GDBP})
+-symbol-list-lines basics.c
+^done,lines=[@{pc="0x08048554",line="7"@},@{pc="0x0804855a",line="8"@}]
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-symbol-list-types} Command
+@findex -symbol-list-types
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-list-types
+@end smallexample
+
+List all the type names.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding commands are @samp{info types} in @value{GDBN},
+@samp{gdb_search} in @code{gdbtk}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-list-variables} Command
+@findex -symbol-list-variables
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-list-variables
+@end smallexample
+
+List all the global and static variable names.
+
+@subsubheading @value{GDBN} Command
+
+@samp{info variables} in @value{GDBN}, @samp{gdb_search} in @code{gdbtk}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-locate} Command
+@findex -symbol-locate
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-locate
+@end smallexample
+
+@subsubheading @value{GDBN} Command
+
+@samp{gdb_loc} in @code{gdbtk}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-symbol-type} Command
+@findex -symbol-type
+
+@subsubheading Synopsis
+
+@smallexample
+ -symbol-type @var{variable}
+@end smallexample
+
+Show type of @var{variable}.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{ptype}, @code{gdbtk} has
+@samp{gdb_obj_variable}.
+
+@subsubheading Example
+N.A.
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Target Manipulation
+@section @sc{gdb/mi} Target Manipulation Commands
+
+
+@subheading The @code{-target-attach} Command
+@findex -target-attach
+
+@subsubheading Synopsis
+
+@smallexample
+ -target-attach @var{pid} | @var{file}
+@end smallexample
+
+Attach to a process @var{pid} or a file @var{file} outside of @value{GDBN}.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{attach}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-compare-sections} Command
+@findex -target-compare-sections
+
+@subsubheading Synopsis
+
+@smallexample
+ -target-compare-sections [ @var{section} ]
+@end smallexample
+
+Compare data of section @var{section} on target to the exec file.
+Without the argument, all sections are compared.
+
+@subsubheading @value{GDBN} Command
+
+The @value{GDBN} equivalent is @samp{compare-sections}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-detach} Command
+@findex -target-detach
+
+@subsubheading Synopsis
+
+@smallexample
+ -target-detach
+@end smallexample
+
+Disconnect from the remote target. There's no output.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{detach}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-target-detach
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-target-disconnect} Command
+@findex -target-disconnect
+
+@subsubheading Synopsis
+
+@example
+ -target-disconnect
+@end example
+
+Disconnect from the remote target. There's no output.
+
+@subsubheading @value{GDBN} command
+
+The corresponding @value{GDBN} command is @samp{disconnect}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-target-disconnect
+^done
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-target-download} Command
+@findex -target-download
+
+@subsubheading Synopsis
+
+@smallexample
+ -target-download
+@end smallexample
+
+Loads the executable onto the remote target.
+It prints out an update message every half second, which includes the fields:
+
+@table @samp
+@item section
+The name of the section.
+@item section-sent
+The size of what has been sent so far for that section.
+@item section-size
+The size of the section.
+@item total-sent
+The total size of what was sent so far (the current and the previous sections).
+@item total-size
+The size of the overall executable to download.
+@end table
+
+@noindent
+Each message is sent as status record (@pxref{GDB/MI Output Syntax, ,
+@sc{gdb/mi} Output Syntax}).
+
+In addition, it prints the name and size of the sections, as they are
+downloaded. These messages include the following fields:
+
+@table @samp
+@item section
+The name of the section.
+@item section-size
+The size of the section.
+@item total-size
+The size of the overall executable to download.
+@end table
+
+@noindent
+At the end, a summary is printed.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{load}.
+
+@subsubheading Example
+
+Note: each status message appears on a single line. Here the messages
+have been broken down so that they can fit onto a page.
+
+@smallexample
+(@value{GDBP})
+-target-download
++download,@{section=".text",section-size="6668",total-size="9880"@}
++download,@{section=".text",section-sent="512",section-size="6668",
+total-sent="512",total-size="9880"@}
++download,@{section=".text",section-sent="1024",section-size="6668",
+total-sent="1024",total-size="9880"@}
++download,@{section=".text",section-sent="1536",section-size="6668",
+total-sent="1536",total-size="9880"@}
++download,@{section=".text",section-sent="2048",section-size="6668",
+total-sent="2048",total-size="9880"@}
++download,@{section=".text",section-sent="2560",section-size="6668",
+total-sent="2560",total-size="9880"@}
++download,@{section=".text",section-sent="3072",section-size="6668",
+total-sent="3072",total-size="9880"@}
++download,@{section=".text",section-sent="3584",section-size="6668",
+total-sent="3584",total-size="9880"@}
++download,@{section=".text",section-sent="4096",section-size="6668",
+total-sent="4096",total-size="9880"@}
++download,@{section=".text",section-sent="4608",section-size="6668",
+total-sent="4608",total-size="9880"@}
++download,@{section=".text",section-sent="5120",section-size="6668",
+total-sent="5120",total-size="9880"@}
++download,@{section=".text",section-sent="5632",section-size="6668",
+total-sent="5632",total-size="9880"@}
++download,@{section=".text",section-sent="6144",section-size="6668",
+total-sent="6144",total-size="9880"@}
++download,@{section=".text",section-sent="6656",section-size="6668",
+total-sent="6656",total-size="9880"@}
++download,@{section=".init",section-size="28",total-size="9880"@}
++download,@{section=".fini",section-size="28",total-size="9880"@}
++download,@{section=".data",section-size="3156",total-size="9880"@}
++download,@{section=".data",section-sent="512",section-size="3156",
+total-sent="7236",total-size="9880"@}
++download,@{section=".data",section-sent="1024",section-size="3156",
+total-sent="7748",total-size="9880"@}
++download,@{section=".data",section-sent="1536",section-size="3156",
+total-sent="8260",total-size="9880"@}
++download,@{section=".data",section-sent="2048",section-size="3156",
+total-sent="8772",total-size="9880"@}
++download,@{section=".data",section-sent="2560",section-size="3156",
+total-sent="9284",total-size="9880"@}
++download,@{section=".data",section-sent="3072",section-size="3156",
+total-sent="9796",total-size="9880"@}
+^done,address="0x10004",load-size="9880",transfer-rate="6586",
+write-rate="429"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-target-exec-status} Command
+@findex -target-exec-status
+
+@subsubheading Synopsis
+
+@smallexample
+ -target-exec-status
+@end smallexample
+
+Provide information on the state of the target (whether it is running or
+not, for instance).
+
+@subsubheading @value{GDBN} Command
+
+There's no equivalent @value{GDBN} command.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-list-available-targets} Command
+@findex -target-list-available-targets
+
+@subsubheading Synopsis
+
+@smallexample
+ -target-list-available-targets
+@end smallexample
+
+List the possible targets to connect to.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{help target}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-list-current-targets} Command
+@findex -target-list-current-targets
+
+@subsubheading Synopsis
+
+@smallexample
+ -target-list-current-targets
+@end smallexample
+
+Describe the current target.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding information is printed by @samp{info file} (among
+other things).
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-list-parameters} Command
+@findex -target-list-parameters
+
+@subsubheading Synopsis
+
+@smallexample
+ -target-list-parameters
+@end smallexample
+
+@c ????
+
+@subsubheading @value{GDBN} Command
+
+No equivalent.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-target-select} Command
+@findex -target-select
+
+@subsubheading Synopsis
+
+@smallexample
+ -target-select @var{type} @var{parameters @dots{}}
+@end smallexample
+
+Connect @value{GDBN} to the remote target. This command takes two args:
+
+@table @samp
+@item @var{type}
+The type of target, for instance @samp{async}, @samp{remote}, etc.
+@item @var{parameters}
+Device names, host names and the like. @xref{Target Commands, ,
+Commands for managing targets}, for more details.
+@end table
+
+The output is a connection notification, followed by the address at
+which the target program is, in the following form:
+
+@smallexample
+^connected,addr="@var{address}",func="@var{function name}",
+ args=[@var{arg list}]
+@end smallexample
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{target}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-target-select async /dev/ttya
+^connected,addr="0xfe00a300",func="??",args=[]
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Thread Commands
+@section @sc{gdb/mi} Thread Commands
+
+
+@subheading The @code{-thread-info} Command
+@findex -thread-info
+
+@subsubheading Synopsis
+
+@smallexample
+ -thread-info
+@end smallexample
+
+@subsubheading @value{GDBN} command
+
+No equivalent.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-thread-list-all-threads} Command
+@findex -thread-list-all-threads
+
+@subsubheading Synopsis
+
+@smallexample
+ -thread-list-all-threads
+@end smallexample
+
+@subsubheading @value{GDBN} Command
+
+The equivalent @value{GDBN} command is @samp{info threads}.
+
+@subsubheading Example
+N.A.
+
+
+@subheading The @code{-thread-list-ids} Command
+@findex -thread-list-ids
+
+@subsubheading Synopsis
+
+@smallexample
+ -thread-list-ids
+@end smallexample
+
+Produces a list of the currently known @value{GDBN} thread ids. At the
+end of the list it also prints the total number of such threads.
+
+@subsubheading @value{GDBN} Command
+
+Part of @samp{info threads} supplies the same information.
+
+@subsubheading Example
+
+No threads present, besides the main process:
+
+@smallexample
+(@value{GDBP})
+-thread-list-ids
+^done,thread-ids=@{@},number-of-threads="0"
+(@value{GDBP})
+@end smallexample
+
+
+Several threads:
+
+@smallexample
+(@value{GDBP})
+-thread-list-ids
+^done,thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@},
+number-of-threads="3"
+(@value{GDBP})
+@end smallexample
+
+
+@subheading The @code{-thread-select} Command
+@findex -thread-select
+
+@subsubheading Synopsis
+
+@smallexample
+ -thread-select @var{threadnum}
+@end smallexample
+
+Make @var{threadnum} the current thread. It prints the number of the new
+current thread, and the topmost frame for that thread.
+
+@subsubheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{thread}.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-exec-next
+^running
+(@value{GDBP})
+*stopped,reason="end-stepping-range",thread-id="2",line="187",
+file="../../../devo/gdb/testsuite/gdb.threads/linux-dp.c"
+(@value{GDBP})
+-thread-list-ids
+^done,
+thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@},
+number-of-threads="3"
+(@value{GDBP})
+-thread-select 3
+^done,new-thread-id="3",
+frame=@{level="0",func="vprintf",
+args=[@{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""@},
+@{name="arg",value="0x2"@}],file="vprintf.c",line="31"@}
+(@value{GDBP})
+@end smallexample
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Tracepoint Commands
+@section @sc{gdb/mi} Tracepoint Commands
+
+The tracepoint commands are not yet implemented.
+
+@c @subheading -trace-actions
+
+@c @subheading -trace-delete
+
+@c @subheading -trace-disable
+
+@c @subheading -trace-dump
+
+@c @subheading -trace-enable
+
+@c @subheading -trace-exists
+
+@c @subheading -trace-find
+
+@c @subheading -trace-frame-number
+
+@c @subheading -trace-info
+
+@c @subheading -trace-insert
+
+@c @subheading -trace-list
+
+@c @subheading -trace-pass-count
+
+@c @subheading -trace-save
+
+@c @subheading -trace-start
+
+@c @subheading -trace-stop
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@node GDB/MI Variable Objects
+@section @sc{gdb/mi} Variable Objects
+
+
+@subheading Motivation for Variable Objects in @sc{gdb/mi}
+
+For the implementation of a variable debugger window (locals, watched
+expressions, etc.), we are proposing the adaptation of the existing code
+used by @code{Insight}.
+
+The two main reasons for that are:
+
+@enumerate 1
+@item
+It has been proven in practice (it is already on its second generation).
+
+@item
+It will shorten development time (needless to say how important it is
+now).
+@end enumerate
+
+The original interface was designed to be used by Tcl code, so it was
+slightly changed so it could be used through @sc{gdb/mi}. This section
+describes the @sc{gdb/mi} operations that will be available and gives some
+hints about their use.
+
+@emph{Note}: In addition to the set of operations described here, we
+expect the @sc{gui} implementation of a variable window to require, at
+least, the following operations:
+
+@itemize @bullet
+@item @code{-gdb-show} @code{output-radix}
+@item @code{-stack-list-arguments}
+@item @code{-stack-list-locals}
+@item @code{-stack-select-frame}
+@end itemize
+
+@subheading Introduction to Variable Objects in @sc{gdb/mi}
+
+@cindex variable objects in @sc{gdb/mi}
+The basic idea behind variable objects is the creation of a named object
+to represent a variable, an expression, a memory location or even a CPU
+register. For each object created, a set of operations is available for
+examining or changing its properties.
+
+Furthermore, complex data types, such as C structures, are represented
+in a tree format. For instance, the @code{struct} type variable is the
+root and the children will represent the struct members. If a child
+is itself of a complex type, it will also have children of its own.
+Appropriate language differences are handled for C, C@t{++} and Java.
+
+When returning the actual values of the objects, this facility allows
+for the individual selection of the display format used in the result
+creation. It can be chosen among: binary, decimal, hexadecimal, octal
+and natural. Natural refers to a default format automatically
+chosen based on the variable type (like decimal for an @code{int}, hex
+for pointers, etc.).
+
+The following is the complete set of @sc{gdb/mi} operations defined to
+access this functionality:
+
+@multitable @columnfractions .4 .6
+@item @strong{Operation}
+@tab @strong{Description}
+
+@item @code{-var-create}
+@tab create a variable object
+@item @code{-var-delete}
+@tab delete the variable object and its children
+@item @code{-var-set-format}
+@tab set the display format of this variable
+@item @code{-var-show-format}
+@tab show the display format of this variable
+@item @code{-var-info-num-children}
+@tab tells how many children this object has
+@item @code{-var-list-children}
+@tab return a list of the object's children
+@item @code{-var-info-type}
+@tab show the type of this variable object
+@item @code{-var-info-expression}
+@tab print what this variable object represents
+@item @code{-var-show-attributes}
+@tab is this variable editable? does it exist here?
+@item @code{-var-evaluate-expression}
+@tab get the value of this variable
+@item @code{-var-assign}
+@tab set the value of this variable
+@item @code{-var-update}
+@tab update the variable and its children
+@end multitable
+
+In the next subsection we describe each operation in detail and suggest
+how it can be used.
+
+@subheading Description And Use of Operations on Variable Objects
+
+@subheading The @code{-var-create} Command
+@findex -var-create
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-create @{@var{name} | "-"@}
+ @{@var{frame-addr} | "*"@} @var{expression}
+@end smallexample
+
+This operation creates a variable object, which allows the monitoring of
+a variable, the result of an expression, a memory cell or a CPU
+register.
+
+The @var{name} parameter is the string by which the object can be
+referenced. It must be unique. If @samp{-} is specified, the varobj
+system will generate a string ``varNNNNNN'' automatically. It will be
+unique provided that one does not specify @var{name} on that format.
+The command fails if a duplicate name is found.
+
+The frame under which the expression should be evaluated can be
+specified by @var{frame-addr}. A @samp{*} indicates that the current
+frame should be used.
+
+@var{expression} is any expression valid on the current language set (must not
+begin with a @samp{*}), or one of the following:
+
+@itemize @bullet
+@item
+@samp{*@var{addr}}, where @var{addr} is the address of a memory cell
+
+@item
+@samp{*@var{addr}-@var{addr}} --- a memory address range (TBD)
+
+@item
+@samp{$@var{regname}} --- a CPU register name
+@end itemize
+
+@subsubheading Result
+
+This operation returns the name, number of children and the type of the
+object created. Type is returned as a string as the ones generated by
+the @value{GDBN} CLI:
+
+@smallexample
+ name="@var{name}",numchild="N",type="@var{type}"
+@end smallexample
+
+
+@subheading The @code{-var-delete} Command
+@findex -var-delete
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-delete @var{name}
+@end smallexample
+
+Deletes a previously created variable object and all of its children.
+
+Returns an error if the object @var{name} is not found.
+
+
+@subheading The @code{-var-set-format} Command
+@findex -var-set-format
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-set-format @var{name} @var{format-spec}
+@end smallexample
+
+Sets the output format for the value of the object @var{name} to be
+@var{format-spec}.
+
+The syntax for the @var{format-spec} is as follows:
+
+@smallexample
+ @var{format-spec} @expansion{}
+ @{binary | decimal | hexadecimal | octal | natural@}
+@end smallexample
+
+
+@subheading The @code{-var-show-format} Command
+@findex -var-show-format
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-show-format @var{name}
+@end smallexample
+
+Returns the format used to display the value of the object @var{name}.
+
+@smallexample
+ @var{format} @expansion{}
+ @var{format-spec}
+@end smallexample
+
+
+@subheading The @code{-var-info-num-children} Command
+@findex -var-info-num-children
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-info-num-children @var{name}
+@end smallexample
+
+Returns the number of children of a variable object @var{name}:
+
+@smallexample
+ numchild=@var{n}
+@end smallexample
+
+
+@subheading The @code{-var-list-children} Command
+@findex -var-list-children
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-list-children [@var{print-values}] @var{name}
+@end smallexample
+
+Returns a list of the children of the specified variable object. With
+just the variable object name as an argument or with an optional
+preceding argument of 0 or @code{--no-values}, prints only the names of the
+variables. With an optional preceding argument of 1 or @code{--all-values},
+also prints their values.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+ -var-list-children n
+ numchild=@var{n},children=[@{name=@var{name},
+ numchild=@var{n},type=@var{type}@},@r{(repeats N times)}]
+(@value{GDBP})
+ -var-list-children --all-values n
+ numchild=@var{n},children=[@{name=@var{name},
+ numchild=@var{n},value=@var{value},type=@var{type}@},@r{(repeats N times)}]
+@end smallexample
+
+
+@subheading The @code{-var-info-type} Command
+@findex -var-info-type
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-info-type @var{name}
+@end smallexample
+
+Returns the type of the specified variable @var{name}. The type is
+returned as a string in the same format as it is output by the
+@value{GDBN} CLI:
+
+@smallexample
+ type=@var{typename}
+@end smallexample
+
+
+@subheading The @code{-var-info-expression} Command
+@findex -var-info-expression
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-info-expression @var{name}
+@end smallexample
+
+Returns what is represented by the variable object @var{name}:
+
+@smallexample
+ lang=@var{lang-spec},exp=@var{expression}
+@end smallexample
+
+@noindent
+where @var{lang-spec} is @code{@{"C" | "C++" | "Java"@}}.
+
+@subheading The @code{-var-show-attributes} Command
+@findex -var-show-attributes
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-show-attributes @var{name}
+@end smallexample
+
+List attributes of the specified variable object @var{name}:
+
+@smallexample
+ status=@var{attr} [ ( ,@var{attr} )* ]
+@end smallexample
+
+@noindent
+where @var{attr} is @code{@{ @{ editable | noneditable @} | TBD @}}.
+
+@subheading The @code{-var-evaluate-expression} Command
+@findex -var-evaluate-expression
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-evaluate-expression @var{name}
+@end smallexample
+
+Evaluates the expression that is represented by the specified variable
+object and returns its value as a string in the current format specified
+for the object:
+
+@smallexample
+ value=@var{value}
+@end smallexample
+
+Note that one must invoke @code{-var-list-children} for a variable
+before the value of a child variable can be evaluated.
+
+@subheading The @code{-var-assign} Command
+@findex -var-assign
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-assign @var{name} @var{expression}
+@end smallexample
+
+Assigns the value of @var{expression} to the variable object specified
+by @var{name}. The object must be @samp{editable}. If the variable's
+value is altered by the assign, the variable will show up in any
+subsequent @code{-var-update} list.
+
+@subsubheading Example
+
+@smallexample
+(@value{GDBP})
+-var-assign var1 3
+^done,value="3"
+(@value{GDBP})
+-var-update *
+^done,changelist=[@{name="var1",in_scope="true",type_changed="false"@}]
+(@value{GDBP})
+@end smallexample
+
+@subheading The @code{-var-update} Command
+@findex -var-update
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-update @{@var{name} | "*"@}
+@end smallexample
+
+Update the value of the variable object @var{name} by evaluating its
+expression after fetching all the new values from memory or registers.
+A @samp{*} causes all existing variable objects to be updated.
+
+
+@node Annotations
+@chapter @value{GDBN} Annotations
+
+This chapter describes annotations in @value{GDBN}. Annotations were
+designed to interface @value{GDBN} to graphical user interfaces or other
+similar programs which want to interact with @value{GDBN} at a
+relatively high level.
+
+The annotation mechanism has largely been superseeded by @sc{gdb/mi}
+(@pxref{GDB/MI}).
+
+@ignore
+This is Edition @value{EDITION}, @value{DATE}.
+@end ignore
+
+@menu
+* Annotations Overview:: What annotations are; the general syntax.
+* Server Prefix:: Issuing a command without affecting user state.
+* Prompting:: Annotations marking @value{GDBN}'s need for input.
+* Errors:: Annotations for error messages.
+* Invalidation:: Some annotations describe things now invalid.
+* Annotations for Running::
+ Whether the program is running, how it stopped, etc.
+* Source Annotations:: Annotations describing source code.
+@end menu
+
+@node Annotations Overview
+@section What is an Annotation?
+@cindex annotations
+
+Annotations start with a newline character, two @samp{control-z}
+characters, and the name of the annotation. If there is no additional
+information associated with this annotation, the name of the annotation
+is followed immediately by a newline. If there is additional
+information, the name of the annotation is followed by a space, the
+additional information, and a newline. The additional information
+cannot contain newline characters.
+
+Any output not beginning with a newline and two @samp{control-z}
+characters denotes literal output from @value{GDBN}. Currently there is
+no need for @value{GDBN} to output a newline followed by two
+@samp{control-z} characters, but if there was such a need, the
+annotations could be extended with an @samp{escape} annotation which
+means those three characters as output.
+
+The annotation @var{level}, which is specified using the
+@option{--annotate} command line option (@pxref{Mode Options}), controls
+how much information @value{GDBN} prints together with its prompt,
+values of expressions, source lines, and other types of output. Level 0
+is for no anntations, level 1 is for use when @value{GDBN} is run as a
+subprocess of @sc{gnu} Emacs, level 3 is the maximum annotation suitable
+for programs that control @value{GDBN}, and level 2 annotations have
+been made obsolete (@pxref{Limitations, , Limitations of the Annotation
+Interface, annotate, GDB's Obsolete Annotations}). This chapter
+describes level 3 annotations.
+
+A simple example of starting up @value{GDBN} with annotations is:
+
+@smallexample
+$ @kbd{gdb --annotate=3}
+GNU gdb 6.0
+Copyright 2003 Free Software Foundation, Inc.
+GDB is free software, covered by the GNU General Public License,
+and you are welcome to change it and/or distribute copies of it
+under certain conditions.
+Type "show copying" to see the conditions.
+There is absolutely no warranty for GDB. Type "show warranty"
+for details.
+This GDB was configured as "i386-pc-linux-gnu"
+
+^Z^Zpre-prompt
+(gdb)
+^Z^Zprompt
+@kbd{quit}
+
+^Z^Zpost-prompt
+$
+@end smallexample
+
+Here @samp{quit} is input to @value{GDBN}; the rest is output from
+@value{GDBN}. The three lines beginning @samp{^Z^Z} (where @samp{^Z}
+denotes a @samp{control-z} character) are annotations; the rest is
+output from @value{GDBN}.
+
+@node Server Prefix
+@section The Server Prefix
+@cindex server prefix for annotations
+
+To issue a command to @value{GDBN} without affecting certain aspects of
+the state which is seen by users, prefix it with @samp{server }. This
+means that this command will not affect the command history, nor will it
+affect @value{GDBN}'s notion of which command to repeat if @key{RET} is
+pressed on a line by itself.
+
+The server prefix does not affect the recording of values into the value
+history; to print a value without recording it into the value history,
+use the @code{output} command instead of the @code{print} command.
+
+@node Prompting
+@section Annotation for @value{GDBN} Input
+
+@cindex annotations for prompts
+When @value{GDBN} prompts for input, it annotates this fact so it is possible
+to know when to send output, when the output from a given command is
+over, etc.
+
+Different kinds of input each have a different @dfn{input type}. Each
+input type has three annotations: a @code{pre-} annotation, which
+denotes the beginning of any prompt which is being output, a plain
+annotation, which denotes the end of the prompt, and then a @code{post-}
+annotation which denotes the end of any echo which may (or may not) be
+associated with the input. For example, the @code{prompt} input type
+features the following annotations:
+
+@smallexample
+^Z^Zpre-prompt
+^Z^Zprompt
+^Z^Zpost-prompt
+@end smallexample
+
+The input types are
+
+@table @code
+@findex pre-prompt
+@findex prompt
+@findex post-prompt
+@item prompt
+When @value{GDBN} is prompting for a command (the main @value{GDBN} prompt).
+
+@findex pre-commands
+@findex commands
+@findex post-commands
+@item commands
+When @value{GDBN} prompts for a set of commands, like in the @code{commands}
+command. The annotations are repeated for each command which is input.
+
+@findex pre-overload-choice
+@findex overload-choice
+@findex post-overload-choice
+@item overload-choice
+When @value{GDBN} wants the user to select between various overloaded functions.
+
+@findex pre-query
+@findex query
+@findex post-query
+@item query
+When @value{GDBN} wants the user to confirm a potentially dangerous operation.
+
+@findex pre-prompt-for-continue
+@findex prompt-for-continue
+@findex post-prompt-for-continue
+@item prompt-for-continue
+When @value{GDBN} is asking the user to press return to continue. Note: Don't
+expect this to work well; instead use @code{set height 0} to disable
+prompting. This is because the counting of lines is buggy in the
+presence of annotations.
+@end table
+
+@node Errors
+@section Errors
+@cindex annotations for errors, warnings and interrupts
+
+@findex quit
+@smallexample
+^Z^Zquit
+@end smallexample
+
+This annotation occurs right before @value{GDBN} responds to an interrupt.
+
+@findex error
+@smallexample
+^Z^Zerror
+@end smallexample
+
+This annotation occurs right before @value{GDBN} responds to an error.
+
+Quit and error annotations indicate that any annotations which @value{GDBN} was
+in the middle of may end abruptly. For example, if a
+@code{value-history-begin} annotation is followed by a @code{error}, one
+cannot expect to receive the matching @code{value-history-end}. One
+cannot expect not to receive it either, however; an error annotation
+does not necessarily mean that @value{GDBN} is immediately returning all the way
+to the top level.
+
+@findex error-begin
+A quit or error annotation may be preceded by
+
+@smallexample
+^Z^Zerror-begin
+@end smallexample
+
+Any output between that and the quit or error annotation is the error
+message.
+
+Warning messages are not yet annotated.
+@c If we want to change that, need to fix warning(), type_error(),
+@c range_error(), and possibly other places.
+
+@node Invalidation
+@section Invalidation Notices
+
+@cindex annotations for invalidation messages
+The following annotations say that certain pieces of state may have
+changed.
+
+@table @code
+@findex frames-invalid
+@item ^Z^Zframes-invalid
+
+The frames (for example, output from the @code{backtrace} command) may
+have changed.
+
+@findex breakpoints-invalid
+@item ^Z^Zbreakpoints-invalid
+
+The breakpoints may have changed. For example, the user just added or
+deleted a breakpoint.
+@end table
+
+@node Annotations for Running
+@section Running the Program
+@cindex annotations for running programs
+
+@findex starting
+@findex stopping
+When the program starts executing due to a @value{GDBN} command such as
+@code{step} or @code{continue},
+
+@smallexample
+^Z^Zstarting
+@end smallexample
+
+is output. When the program stops,
+
+@smallexample
+^Z^Zstopped
+@end smallexample
+
+is output. Before the @code{stopped} annotation, a variety of
+annotations describe how the program stopped.
+
+@table @code
+@findex exited
+@item ^Z^Zexited @var{exit-status}
+The program exited, and @var{exit-status} is the exit status (zero for
+successful exit, otherwise nonzero).
+
+@findex signalled
+@findex signal-name
+@findex signal-name-end
+@findex signal-string
+@findex signal-string-end
+@item ^Z^Zsignalled
+The program exited with a signal. After the @code{^Z^Zsignalled}, the
+annotation continues:
+
+@smallexample
+@var{intro-text}
+^Z^Zsignal-name
+@var{name}
+^Z^Zsignal-name-end
+@var{middle-text}
+^Z^Zsignal-string
+@var{string}
+^Z^Zsignal-string-end
+@var{end-text}
+@end smallexample
+
+@noindent
+where @var{name} is the name of the signal, such as @code{SIGILL} or
+@code{SIGSEGV}, and @var{string} is the explanation of the signal, such
+as @code{Illegal Instruction} or @code{Segmentation fault}.
+@var{intro-text}, @var{middle-text}, and @var{end-text} are for the
+user's benefit and have no particular format.
+
+@findex signal
+@item ^Z^Zsignal
+The syntax of this annotation is just like @code{signalled}, but @value{GDBN} is
+just saying that the program received the signal, not that it was
+terminated with it.
+
+@findex breakpoint
+@item ^Z^Zbreakpoint @var{number}
+The program hit breakpoint number @var{number}.
+
+@findex watchpoint
+@item ^Z^Zwatchpoint @var{number}
+The program hit watchpoint number @var{number}.
+@end table
+
+@node Source Annotations
+@section Displaying Source
+@cindex annotations for source display
+
+@findex source
+The following annotation is used instead of displaying source code:
+
+@smallexample
+^Z^Zsource @var{filename}:@var{line}:@var{character}:@var{middle}:@var{addr}
+@end smallexample
+
+where @var{filename} is an absolute file name indicating which source
+file, @var{line} is the line number within that file (where 1 is the
+first line in the file), @var{character} is the character position
+within the file (where 0 is the first character in the file) (for most
+debug formats this will necessarily point to the beginning of a line),
+@var{middle} is @samp{middle} if @var{addr} is in the middle of the
+line, or @samp{beg} if @var{addr} is at the beginning of the line, and
+@var{addr} is the address in the target program associated with the
+source which is being displayed. @var{addr} is in the form @samp{0x}
+followed by one or more lowercase hex digits (note that this does not
+depend on the language).
@node GDB Bugs
@chapter Reporting Bugs in @value{GDBN}
@@ -13680,9 +18987,9 @@ you can print the reference card immediately with @file{refcard.ps}.
The release also includes the source for the reference card. You
can format it, using @TeX{}, by typing:
-@example
+@smallexample
make refcard.dvi
-@end example
+@end smallexample
The @value{GDBN} reference card is designed to print in @dfn{landscape}
mode on US ``letter'' size paper;
@@ -13716,10 +19023,10 @@ If you have @code{makeinfo} installed, and are in the top level
@value{GDBN} source directory (@file{gdb-@value{GDBVN}}, in the case of
version @value{GDBVN}), you can make the Info file by typing:
-@example
+@smallexample
cd gdb
make gdb.info
-@end example
+@end smallexample
If you want to typeset and print copies of this manual, you need @TeX{},
a program to print its @sc{dvi} output files, and @file{texinfo.tex}, the
@@ -13745,9 +19052,9 @@ typeset and print this manual. First switch to the the @file{gdb}
subdirectory of the main source directory (for example, to
@file{gdb-@value{GDBVN}/gdb}) and type:
-@example
+@smallexample
make gdb.dvi
-@end example
+@end smallexample
Then give @file{gdb.dvi} to your @sc{dvi} printing program.
@@ -13755,6 +19062,7 @@ Then give @file{gdb.dvi} to your @sc{dvi} printing program.
@appendix Installing @value{GDBN}
@cindex configuring @value{GDBN}
@cindex installation
+@cindex configuring @value{GDBN}, and source tree subdirectories
@value{GDBN} comes with a @code{configure} script that automates the process
of preparing @value{GDBN} for installation; you can then use @code{make} to
@@ -13813,11 +19121,11 @@ argument.
For example:
-@example
+@smallexample
cd gdb-@value{GDBVN}
./configure @var{host}
make
-@end example
+@end smallexample
@noindent
where @var{host} is an identifier such as @samp{sun4} or
@@ -13835,9 +19143,9 @@ binaries, are left in the corresponding source directories.
system does not recognize this automatically when you run a different
shell, you may need to run @code{sh} on it explicitly:
-@example
+@smallexample
sh configure @var{host}
-@end example
+@end smallexample
If you run @code{configure} from a directory that contains source
directories for multiple libraries or programs, such as the
@@ -13845,19 +19153,15 @@ directories for multiple libraries or programs, such as the
creates configuration files for every directory level underneath (unless
you tell it not to, with the @samp{--norecursion} option).
-You can run the @code{configure} script from any of the
-subordinate directories in the @value{GDBN} distribution if you only want to
-configure that subdirectory, but be sure to specify a path to it.
-
-For example, with version @value{GDBVN}, type the following to configure only
-the @code{bfd} subdirectory:
-
-@example
-@group
-cd gdb-@value{GDBVN}/bfd
-../configure @var{host}
-@end group
-@end example
+You should run the @code{configure} script from the top directory in the
+source tree, the @file{gdb-@var{version-number}} directory. If you run
+@code{configure} from one of the subdirectories, you will configure only
+that subdirectory. That is usually not what you want. In particular,
+if you run the first @code{configure} from the @file{gdb} subdirectory
+of the @file{gdb-@var{version-number}} directory, you will omit the
+configuration of @file{bfd}, @file{readline}, and other sibling
+directories of the @file{gdb} subdirectory. This leads to build errors
+about missing include files such as @file{bfd/bfd.h}.
You can install @code{@value{GDBP}} anywhere; it has no hardwired paths.
However, you should make sure that the shell on your path (named by
@@ -13893,7 +19197,7 @@ the @samp{--srcdir} option; it is assumed.)
For example, with version @value{GDBVN}, you can build @value{GDBN} in a
separate directory for a Sun 4 like this:
-@example
+@smallexample
@group
cd gdb-@value{GDBVN}
mkdir ../gdb-sun4
@@ -13901,7 +19205,7 @@ cd ../gdb-sun4
../gdb-@value{GDBVN}/configure sun4
make
@end group
-@end example
+@end smallexample
When @code{configure} builds a configuration using a remote source
directory, it creates a tree for the binaries with the same structure
@@ -13910,6 +19214,12 @@ the example, you'd find the Sun 4 library @file{libiberty.a} in the
directory @file{gdb-sun4/libiberty}, and @value{GDBN} itself in
@file{gdb-sun4/gdb}.
+Make sure that your path to the @file{configure} script has just one
+instance of @file{gdb} in it. If your path to @file{configure} looks
+like @file{../gdb-@value{GDBVN}/gdb/configure}, you are configuring only
+one subdirectory of @value{GDBN}, not the whole package. This leads to
+build errors about missing include files such as @file{bfd/bfd.h}.
+
One popular reason to build several @value{GDBN} configurations in separate
directories is to configure @value{GDBN} for cross-compiling (where
@value{GDBN} runs on one machine---the @dfn{host}---while debugging
@@ -13940,9 +19250,9 @@ script are based on a three-part naming scheme, but some short predefined
aliases are also supported. The full naming scheme encodes three pieces
of information in the following pattern:
-@example
+@smallexample
@var{architecture}-@var{vendor}-@var{os}
-@end example
+@end smallexample
For example, you can use the alias @code{sun4} as a @var{host} argument,
or as the value for @var{target} in a @code{--target=@var{target}}
@@ -13982,7 +19292,7 @@ are most often useful for building @value{GDBN}. @code{configure} also has
several other options not listed here. @inforef{What Configure
Does,,configure.info}, for a full explanation of @code{configure}.
-@example
+@smallexample
configure @r{[}--help@r{]}
@r{[}--prefix=@var{dir}@r{]}
@r{[}--exec-prefix=@var{dir}@r{]}
@@ -13990,7 +19300,7 @@ configure @r{[}--help@r{]}
@r{[}--norecursion@r{]} @r{[}--rm@r{]}
@r{[}--target=@var{target}@r{]}
@var{host}
-@end example
+@end smallexample
@noindent
You may introduce options with a single @samp{-} rather than
@@ -14086,18 +19396,132 @@ Shared library events.
@end table
+@kindex maint internal-error
+@kindex maint internal-warning
+@item maint internal-error
+@itemx maint internal-warning
+Cause @value{GDBN} to call the internal function @code{internal_error}
+or @code{internal_warning} and hence behave as though an internal error
+or internal warning has been detected. In addition to reporting the
+internal problem, these functions give the user the opportunity to
+either quit @value{GDBN} or create a core file of the current
+@value{GDBN} session.
+
+@smallexample
+(gdb) @kbd{maint internal-error testing, 1, 2}
+@dots{}/maint.c:121: internal-error: testing, 1, 2
+A problem internal to GDB has been detected. Further
+debugging may prove unreliable.
+Quit this debugging session? (y or n) @kbd{n}
+Create a core file? (y or n) @kbd{n}
+(gdb)
+@end smallexample
+
+Takes an optional parameter that is used as the text of the error or
+warning message.
+
+@kindex maint print dummy-frames
+@item maint print dummy-frames
+
+Prints the contents of @value{GDBN}'s internal dummy-frame stack.
+
+@smallexample
+(gdb) @kbd{b add}
+@dots{}
+(gdb) @kbd{print add(2,3)}
+Breakpoint 2, add (a=2, b=3) at @dots{}
+58 return (a + b);
+The program being debugged stopped while in a function called from GDB.
+@dots{}
+(gdb) @kbd{maint print dummy-frames}
+0x1a57c80: pc=0x01014068 fp=0x0200bddc sp=0x0200bdd6
+ top=0x0200bdd4 id=@{stack=0x200bddc,code=0x101405c@}
+ call_lo=0x01014000 call_hi=0x01014001
+(gdb)
+@end smallexample
+
+Takes an optional file parameter.
+
+@kindex maint print registers
+@kindex maint print raw-registers
+@kindex maint print cooked-registers
+@kindex maint print register-groups
+@item maint print registers
+@itemx maint print raw-registers
+@itemx maint print cooked-registers
+@itemx maint print register-groups
+Print @value{GDBN}'s internal register data structures.
+
+The command @code{maint print raw-registers} includes the contents of
+the raw register cache; the command @code{maint print cooked-registers}
+includes the (cooked) value of all registers; and the command
+@code{maint print register-groups} includes the groups that each
+register is a member of. @xref{Registers,, Registers, gdbint,
+@value{GDBN} Internals}.
+
+Takes an optional file parameter.
+
+@kindex maint print reggroups
+@item maint print reggroups
+Print @value{GDBN}'s internal register group data structures.
+
+Takes an optional file parameter.
+
+@smallexample
+(gdb) @kbd{maint print reggroups}
+ Group Type
+ general user
+ float user
+ all user
+ vector user
+ system user
+ save internal
+ restore internal
+@end smallexample
+
+@kindex maint set profile
+@kindex maint show profile
+@cindex profiling GDB
+@item maint set profile
+@itemx maint show profile
+Control profiling of @value{GDBN}.
+
+Profiling will be disabled until you use the @samp{maint set profile}
+command to enable it. When you enable profiling, the system will begin
+collecting timing and execution count data; when you disable profiling or
+exit @value{GDBN}, the results will be written to a log file. Remember that
+if you use profiling, @value{GDBN} will overwrite the profiling log file
+(often called @file{gmon.out}). If you have a record of important profiling
+data in a @file{gmon.out} file, be sure to move it to a safe location.
+
+Configuring with @samp{--enable-profiling} arranges for @value{GDBN} to be
+compiled with the @samp{-pg} compiler option.
+
@end table
@node Remote Protocol
@appendix @value{GDBN} Remote Serial Protocol
+@menu
+* Overview::
+* Packets::
+* Stop Reply Packets::
+* General Query Packets::
+* Register Packet Format::
+* Examples::
+* File-I/O remote protocol extension::
+@end menu
+
+@node Overview
+@section Overview
+
There may be occasions when you need to know something about the
protocol---for example, if there is only one serial port to your target
machine, you might want your program to do something special if it
recognizes a packet meant for @value{GDBN}.
-In the examples below, @samp{<-} and @samp{->} are used to indicate
+In the examples below, @samp{->} and @samp{<-} are used to indicate
transmitted and received data respectfully.
@cindex protocol, @value{GDBN} remote serial
@@ -14108,9 +19532,9 @@ sent as a @var{packet}. A @var{packet} is introduced with the character
@samp{$}, the actual @var{packet-data}, and the terminating character
@samp{#} followed by a two-digit @var{checksum}:
-@example
+@smallexample
@code{$}@var{packet-data}@code{#}@var{checksum}
-@end example
+@end smallexample
@noindent
@cindex checksum, for @value{GDBN} remote
@@ -14122,9 +19546,9 @@ eight bit unsigned checksum).
Implementors should note that prior to @value{GDBN} 5.0 the protocol
specification also included an optional two-digit @var{sequence-id}:
-@example
+@smallexample
@code{$}@var{sequence-id}@code{:}@var{packet-data}@code{#}@var{checksum}
-@end example
+@end smallexample
@cindex sequence-id, for @value{GDBN} remote
@noindent
@@ -14138,10 +19562,10 @@ response expected is an acknowledgment: either @samp{+} (to indicate
the package was received correctly) or @samp{-} (to request
retransmission):
-@example
-<- @code{$}@var{packet-data}@code{#}@var{checksum}
--> @code{+}
-@end example
+@smallexample
+-> @code{$}@var{packet-data}@code{#}@var{checksum}
+<- @code{+}
+@end smallexample
@noindent
The host (@value{GDBN}) sends @var{command}s, and the target (the
@@ -14154,8 +19578,9 @@ exception of @samp{#} and @samp{$} (see @samp{X} packet for additional
exceptions).
Fields within the packet should be separated using @samp{,} @samp{;} or
+@cindex remote protocol, field separator
@samp{:}. Except where otherwise noted all numbers are represented in
-HEX with leading zeros suppressed.
+@sc{hex} with leading zeros suppressed.
Implementors should note that prior to @value{GDBN} 5.0, the character
@samp{:} could not appear as the third character in a packet (as it
@@ -14169,14 +19594,10 @@ where @code{n >=3} (which is where rle starts to win). The printable
characters @samp{$}, @samp{#}, @samp{+} and @samp{-} or with a numeric
value greater than 126 should not be used.
-Some remote systems have used a different run-length encoding mechanism
-loosely refered to as the cisco encoding. Following the @samp{*}
-character are two hex digits that indicate the size of the packet.
-
So:
-@example
+@smallexample
"@code{0* }"
-@end example
+@end smallexample
@noindent
means the same as "0000".
@@ -14188,170 +19609,188 @@ For any @var{command} not supported by the stub, an empty response
protocol. A newer @value{GDBN} can tell if a packet is supported based
on that response.
-A stub is required to support the @samp{g}, @samp{G}, @samp{m}, @samp{M},
-@samp{c}, and @samp{s} @var{command}s. All other @var{command}s are
+A stub is required to support the @samp{g}, @samp{G}, @samp{m}, @samp{M},
+@samp{c}, and @samp{s} @var{command}s. All other @var{command}s are
optional.
-Below is a complete list of all currently defined @var{command}s and
-their corresponding response @var{data}:
-@page
-@multitable @columnfractions .30 .30 .40
-@item Packet
-@tab Request
-@tab Description
-
-@item extended mode
-@tab @code{!}
-@tab
+@node Packets
+@section Packets
+
+The following table provides a complete list of all currently defined
+@var{command}s and their corresponding response @var{data}.
+
+@table @r
+
+@item @code{!} --- extended mode
+@cindex @code{!} packet
+
Enable extended mode. In extended mode, the remote server is made
persistent. The @samp{R} packet is used to restart the program being
debugged.
-@item
-@tab reply @samp{OK}
-@tab
+
+Reply:
+@table @samp
+@item OK
The remote target both supports and has enabled extended mode.
+@end table
-@item last signal
-@tab @code{?}
-@tab
-Indicate the reason the target halted. The reply is the same as for step
-and continue.
-@item
-@tab reply
-@tab see below
+@item @code{?} --- last signal
+@cindex @code{?} packet
+Indicate the reason the target halted. The reply is the same as for
+step and continue.
-@item reserved
-@tab @code{a}
-@tab Reserved for future use
+Reply:
+@xref{Stop Reply Packets}, for the reply specifications.
+
+@item @code{a} --- reserved
+
+Reserved for future use.
+
+@item @code{A}@var{arglen}@code{,}@var{argnum}@code{,}@var{arg}@code{,@dots{}} --- set program arguments @strong{(reserved)}
+@cindex @code{A} packet
-@item set program arguments @strong{(reserved)}
-@tab @code{A}@var{arglen}@code{,}@var{argnum}@code{,}@var{arg}@code{,...}
-@tab
-@item
-@tab
-@tab
Initialized @samp{argv[]} array passed into program. @var{arglen}
specifies the number of bytes in the hex encoded byte stream @var{arg}.
-See @file{gdbserver} for more details.
-@item
-@tab reply @code{OK}
-@item
-@tab reply @code{E}@var{NN}
-
-@item set baud @strong{(deprecated)}
-@tab @code{b}@var{baud}
-@tab
-Change the serial line speed to @var{baud}. JTC: @emph{When does the
-transport layer state change? When it's received, or after the ACK is
-transmitted. In either case, there are problems if the command or the
-acknowledgment packet is dropped.} Stan: @emph{If people really wanted
-to add something like this, and get it working for the first time, they
-ought to modify ser-unix.c to send some kind of out-of-band message to a
-specially-setup stub and have the switch happen "in between" packets, so
-that from remote protocol's point of view, nothing actually
-happened.}
-
-@item set breakpoint @strong{(deprecated)}
-@tab @code{B}@var{addr},@var{mode}
-@tab
+See @code{gdbserver} for more details.
+
+Reply:
+@table @samp
+@item OK
+@item E@var{NN}
+@end table
+
+@item @code{b}@var{baud} --- set baud @strong{(deprecated)}
+@cindex @code{b} packet
+
+Change the serial line speed to @var{baud}.
+
+JTC: @emph{When does the transport layer state change? When it's
+received, or after the ACK is transmitted. In either case, there are
+problems if the command or the acknowledgment packet is dropped.}
+
+Stan: @emph{If people really wanted to add something like this, and get
+it working for the first time, they ought to modify ser-unix.c to send
+some kind of out-of-band message to a specially-setup stub and have the
+switch happen "in between" packets, so that from remote protocol's point
+of view, nothing actually happened.}
+
+@item @code{B}@var{addr},@var{mode} --- set breakpoint @strong{(deprecated)}
+@cindex @code{B} packet
+
Set (@var{mode} is @samp{S}) or clear (@var{mode} is @samp{C}) a
-breakpoint at @var{addr}. @emph{This has been replaced by the @samp{Z} and
-@samp{z} packets.}
+breakpoint at @var{addr}.
+
+This packet has been replaced by the @samp{Z} and @samp{z} packets
+(@pxref{insert breakpoint or watchpoint packet}).
+
+@item @code{c}@var{addr} --- continue
+@cindex @code{c} packet
-@item continue
-@tab @code{c}@var{addr}
-@tab
-@var{addr} is address to resume. If @var{addr} is omitted, resume at
+@var{addr} is address to resume. If @var{addr} is omitted, resume at
current address.
-@item
-@tab reply
-@tab see below
-@item continue with signal
-@tab @code{C}@var{sig}@code{;}@var{addr}
-@tab
+Reply:
+@xref{Stop Reply Packets}, for the reply specifications.
+
+@item @code{C}@var{sig}@code{;}@var{addr} --- continue with signal
+@cindex @code{C} packet
+
Continue with signal @var{sig} (hex signal number). If
@code{;}@var{addr} is omitted, resume at same address.
-@item
-@tab reply
-@tab see below
-@item toggle debug @strong{(deprecated)}
-@tab @code{d}
-@tab
-toggle debug flag.
+Reply:
+@xref{Stop Reply Packets}, for the reply specifications.
-@item detach
-@tab @code{D}
-@tab
-Detach @value{GDBN} from the remote system. Sent to the remote target before
-@value{GDBN} disconnects.
-@item
-@tab reply @emph{no response}
-@tab
+@item @code{d} --- toggle debug @strong{(deprecated)}
+@cindex @code{d} packet
+
+Toggle debug flag.
+
+@item @code{D} --- detach
+@cindex @code{D} packet
+
+Detach @value{GDBN} from the remote system. Sent to the remote target
+before @value{GDBN} disconnects via the @code{detach} command.
+
+Reply:
+@table @samp
+@item @emph{no response}
@value{GDBN} does not check for any response after sending this packet.
+@end table
-@item reserved
-@tab @code{e}
-@tab Reserved for future use
+@item @code{e} --- reserved
-@item reserved
-@tab @code{E}
-@tab Reserved for future use
+Reserved for future use.
-@item reserved
-@tab @code{f}
-@tab Reserved for future use
+@item @code{E} --- reserved
-@item reserved
-@tab @code{F}
-@tab Reserved for future use
+Reserved for future use.
-@item read registers
-@tab @code{g}
-@tab Read general registers.
-@item
-@tab reply @var{XX...}
-@tab
+@item @code{f} --- reserved
+
+Reserved for future use.
+
+@item @code{F}@var{RC}@code{,}@var{EE}@code{,}@var{CF}@code{;}@var{XX} --- Reply to target's F packet.
+@cindex @code{F} packet
+
+This packet is send by @value{GDBN} as reply to a @code{F} request packet
+sent by the target. This is part of the File-I/O protocol extension.
+@xref{File-I/O remote protocol extension}, for the specification.
+
+@item @code{g} --- read registers
+@anchor{read registers packet}
+@cindex @code{g} packet
+
+Read general registers.
+
+Reply:
+@table @samp
+@item @var{XX@dots{}}
Each byte of register data is described by two hex digits. The bytes
with the register are transmitted in target byte order. The size of
each register and their position within the @samp{g} @var{packet} are
-determined by the @value{GDBN} internal macros @var{REGISTER_RAW_SIZE} and
-@var{REGISTER_NAME} macros. The specification of several standard
-@code{g} packets is specified below.
-@item
-@tab @code{E}@var{NN}
-@tab for an error.
+determined by the @value{GDBN} internal macros
+@var{DEPRECATED_REGISTER_RAW_SIZE} and @var{REGISTER_NAME} macros. The
+specification of several standard @code{g} packets is specified below.
+@item E@var{NN}
+for an error.
+@end table
-@item write regs
-@tab @code{G}@var{XX...}
-@tab
-See @samp{g} for a description of the @var{XX...} data.
-@item
-@tab reply @code{OK}
-@tab for success
-@item
-@tab reply @code{E}@var{NN}
-@tab for an error
+@item @code{G}@var{XX@dots{}} --- write regs
+@cindex @code{G} packet
+
+@xref{read registers packet}, for a description of the @var{XX@dots{}}
+data.
-@item reserved
-@tab @code{h}
-@tab Reserved for future use
+Reply:
+@table @samp
+@item OK
+for success
+@item E@var{NN}
+for an error
+@end table
+
+@item @code{h} --- reserved
+
+Reserved for future use.
+
+@item @code{H}@var{c}@var{t@dots{}} --- set thread
+@cindex @code{H} packet
-@item set thread
-@tab @code{H}@var{c}@var{t...}
-@tab
Set thread for subsequent operations (@samp{m}, @samp{M}, @samp{g},
-@samp{G}, et.al.). @var{c} = @samp{c} for thread used in step and
-continue; @var{t...} can be -1 for all threads. @var{c} = @samp{g} for
-thread used in other operations. If zero, pick a thread, any thread.
-@item
-@tab reply @code{OK}
-@tab for success
-@item
-@tab reply @code{E}@var{NN}
-@tab for an error
+@samp{G}, et.al.). @var{c} depends on the operation to be performed: it
+should be @samp{c} for step and continue operations, @samp{g} for other
+operations. The thread designator @var{t@dots{}} may be -1, meaning all
+the threads, a thread number, or zero which means pick any thread.
+
+Reply:
+@table @samp
+@item OK
+for success
+@item E@var{NN}
+for an error
+@end table
@c FIXME: JTC:
@c 'H': How restrictive (or permissive) is the thread model. If a
@@ -14368,262 +19807,427 @@ thread used in other operations. If zero, pick a thread, any thread.
@c selected, sets the registers of the register block of
@c that thread; otherwise sets current registers.
-@item cycle step @strong{(draft)}
-@tab @code{i}@var{addr}@code{,}@var{nnn}
-@tab
+@item @code{i}@var{addr}@code{,}@var{nnn} --- cycle step @strong{(draft)}
+@anchor{cycle step packet}
+@cindex @code{i} packet
+
Step the remote target by a single clock cycle. If @code{,}@var{nnn} is
present, cycle step @var{nnn} cycles. If @var{addr} is present, cycle
step starting at that address.
-@item signal then cycle step @strong{(reserved)}
-@tab @code{I}
-@tab
-See @samp{i} and @samp{S} for likely syntax and semantics.
+@item @code{I} --- signal then cycle step @strong{(reserved)}
+@cindex @code{I} packet
-@item reserved
-@tab @code{j}
-@tab Reserved for future use
+@xref{step with signal packet}. @xref{cycle step packet}.
-@item reserved
-@tab @code{J}
-@tab Reserved for future use
+@item @code{j} --- reserved
+
+Reserved for future use.
+
+@item @code{J} --- reserved
+
+Reserved for future use.
+
+@item @code{k} --- kill request
+@cindex @code{k} packet
-@item kill request
-@tab @code{k}
-@tab
FIXME: @emph{There is no description of how to operate when a specific
-thread context has been selected (i.e.@: does 'k' kill only that thread?)}.
+thread context has been selected (i.e.@: does 'k' kill only that
+thread?)}.
+
+@item @code{K} --- reserved
+
+Reserved for future use.
+
+@item @code{l} --- reserved
+
+Reserved for future use.
-@item reserved
-@tab @code{l}
-@tab Reserved for future use
+@item @code{L} --- reserved
-@item reserved
-@tab @code{L}
-@tab Reserved for future use
+Reserved for future use.
+
+@item @code{m}@var{addr}@code{,}@var{length} --- read memory
+@cindex @code{m} packet
-@item read memory
-@tab @code{m}@var{addr}@code{,}@var{length}
-@tab
Read @var{length} bytes of memory starting at address @var{addr}.
-Neither @value{GDBN} nor the stub assume that sized memory transfers are assumed
-using word alligned accesses. FIXME: @emph{A word aligned memory
+Neither @value{GDBN} nor the stub assume that sized memory transfers are
+assumed using word aligned accesses. FIXME: @emph{A word aligned memory
transfer mechanism is needed.}
-@item
-@tab reply @var{XX...}
-@tab
-@var{XX...} is mem contents. Can be fewer bytes than requested if able
-to read only part of the data. Neither @value{GDBN} nor the stub assume that
-sized memory transfers are assumed using word alligned accesses. FIXME:
-@emph{A word aligned memory transfer mechanism is needed.}
-@item
-@tab reply @code{E}@var{NN}
-@tab @var{NN} is errno
-@item write mem
-@tab @code{M}@var{addr},@var{length}@code{:}@var{XX...}
-@tab
+Reply:
+@table @samp
+@item @var{XX@dots{}}
+@var{XX@dots{}} is mem contents. Can be fewer bytes than requested if able
+to read only part of the data. Neither @value{GDBN} nor the stub assume
+that sized memory transfers are assumed using word aligned
+accesses. FIXME: @emph{A word aligned memory transfer mechanism is
+needed.}
+@item E@var{NN}
+@var{NN} is errno
+@end table
+
+@item @code{M}@var{addr},@var{length}@code{:}@var{XX@dots{}} --- write mem
+@cindex @code{M} packet
+
Write @var{length} bytes of memory starting at address @var{addr}.
-@var{XX...} is the data.
-@item
-@tab reply @code{OK}
-@tab for success
-@item
-@tab reply @code{E}@var{NN}
-@tab
+@var{XX@dots{}} is the data.
+
+Reply:
+@table @samp
+@item OK
+for success
+@item E@var{NN}
for an error (this includes the case where only part of the data was
written).
+@end table
-@item reserved
-@tab @code{n}
-@tab Reserved for future use
+@item @code{n} --- reserved
-@item reserved
-@tab @code{N}
-@tab Reserved for future use
+Reserved for future use.
-@item reserved
-@tab @code{o}
-@tab Reserved for future use
+@item @code{N} --- reserved
-@item reserved
-@tab @code{O}
-@tab Reserved for future use
+Reserved for future use.
-@item read reg @strong{(reserved)}
-@tab @code{p}@var{n...}
-@tab
-See write register.
-@item
-@tab return @var{r....}
-@tab The hex encoded value of the register in target byte order.
+@item @code{o} --- reserved
+
+Reserved for future use.
+
+@item @code{O} --- reserved
+
+Reserved for future use.
+
+@item @code{p}@var{n@dots{}} --- read reg @strong{(reserved)}
+@cindex @code{p} packet
-@item write reg
-@tab @code{P}@var{n...}@code{=}@var{r...}
-@tab
-Write register @var{n...} with value @var{r...}, which contains two hex
+@xref{write register packet}.
+
+Reply:
+@table @samp
+@item @var{r@dots{}.}
+The hex encoded value of the register in target byte order.
+@end table
+
+@item @code{P}@var{n@dots{}}@code{=}@var{r@dots{}} --- write register
+@anchor{write register packet}
+@cindex @code{P} packet
+
+Write register @var{n@dots{}} with value @var{r@dots{}}, which contains two hex
digits for each byte in the register (target byte order).
-@item
-@tab reply @code{OK}
-@tab for success
-@item
-@tab reply @code{E}@var{NN}
-@tab for an error
-@item general query
-@tab @code{q}@var{query}
-@tab
-Request info about @var{query}. In general @value{GDBN} queries
-have a leading upper case letter. Custom vendor queries should use a
-company prefix (in lower case) ex: @samp{qfsf.var}. @var{query} may
-optionally be followed by a @samp{,} or @samp{;} separated list. Stubs
-must ensure that they match the full @var{query} name.
-@item
-@tab reply @code{XX...}
-@tab Hex encoded data from query. The reply can not be empty.
-@item
-@tab reply @code{E}@var{NN}
-@tab error reply
+Reply:
+@table @samp
+@item OK
+for success
+@item E@var{NN}
+for an error
+@end table
+
+@item @code{q}@var{query} --- general query
+@anchor{general query packet}
+@cindex @code{q} packet
+
+Request info about @var{query}. In general @value{GDBN} queries have a
+leading upper case letter. Custom vendor queries should use a company
+prefix (in lower case) ex: @samp{qfsf.var}. @var{query} may optionally
+be followed by a @samp{,} or @samp{;} separated list. Stubs must ensure
+that they match the full @var{query} name.
+
+Reply:
+@table @samp
+@item @var{XX@dots{}}
+Hex encoded data from query. The reply can not be empty.
+@item E@var{NN}
+error reply
@item
-@tab reply @samp{}
-@tab Indicating an unrecognized @var{query}.
+Indicating an unrecognized @var{query}.
+@end table
-@item general set
-@tab @code{Q}@var{var}@code{=}@var{val}
-@tab
-Set value of @var{var} to @var{val}. See @samp{q} for a discussing of
-naming conventions.
+@item @code{Q}@var{var}@code{=}@var{val} --- general set
+@cindex @code{Q} packet
+
+Set value of @var{var} to @var{val}.
+
+@xref{general query packet}, for a discussion of naming conventions.
+
+@item @code{r} --- reset @strong{(deprecated)}
+@cindex @code{r} packet
-@item reset @strong{(deprecated)}
-@tab @code{r}
-@tab
Reset the entire system.
-@item remote restart
-@tab @code{R}@var{XX}
-@tab
+@item @code{R}@var{XX} --- remote restart
+@cindex @code{R} packet
+
Restart the program being debugged. @var{XX}, while needed, is ignored.
This packet is only available in extended mode.
-@item
-@tab
-no reply
-@tab
+
+Reply:
+@table @samp
+@item @emph{no reply}
The @samp{R} packet has no reply.
+@end table
+
+@item @code{s}@var{addr} --- step
+@cindex @code{s} packet
-@item step
-@tab @code{s}@var{addr}
-@tab
@var{addr} is address to resume. If @var{addr} is omitted, resume at
same address.
-@item
-@tab reply
-@tab see below
-@item step with signal
-@tab @code{S}@var{sig}@code{;}@var{addr}
-@tab
+Reply:
+@xref{Stop Reply Packets}, for the reply specifications.
+
+@item @code{S}@var{sig}@code{;}@var{addr} --- step with signal
+@anchor{step with signal packet}
+@cindex @code{S} packet
+
Like @samp{C} but step not continue.
-@item
-@tab reply
-@tab see below
-@item search
-@tab @code{t}@var{addr}@code{:}@var{PP}@code{,}@var{MM}
-@tab
+Reply:
+@xref{Stop Reply Packets}, for the reply specifications.
+
+@item @code{t}@var{addr}@code{:}@var{PP}@code{,}@var{MM} --- search
+@cindex @code{t} packet
+
Search backwards starting at address @var{addr} for a match with pattern
-@var{PP} and mask @var{MM}. @var{PP} and @var{MM} are 4
-bytes. @var{addr} must be at least 3 digits.
+@var{PP} and mask @var{MM}. @var{PP} and @var{MM} are 4 bytes.
+@var{addr} must be at least 3 digits.
-@item thread alive
-@tab @code{T}@var{XX}
-@tab Find out if the thread XX is alive.
-@item
-@tab reply @code{OK}
-@tab thread is still alive
+@item @code{T}@var{XX} --- thread alive
+@cindex @code{T} packet
+
+Find out if the thread XX is alive.
+
+Reply:
+@table @samp
+@item OK
+thread is still alive
+@item E@var{NN}
+thread is dead
+@end table
+
+@item @code{u} --- reserved
+
+Reserved for future use.
+
+@item @code{U} --- reserved
+
+Reserved for future use.
+
+@item @code{v} --- verbose packet prefix
+
+Packets starting with @code{v} are identified by a multi-letter name,
+up to the first @code{;} or @code{?} (or the end of the packet).
+
+@item @code{vCont}[;@var{action}[@code{:}@var{tid}]]... --- extended resume
+@cindex @code{vCont} packet
+
+Resume the inferior. Different actions may be specified for each thread.
+If an action is specified with no @var{tid}, then it is applied to any
+threads that don't have a specific action specified; if no default action is
+specified then other threads should remain stopped. Specifying multiple
+default actions is an error; specifying no actions is also an error.
+Thread IDs are specified in hexadecimal. Currently supported actions are:
+
+@table @code
+@item c
+Continue.
+@item C@var{sig}
+Continue with signal @var{sig}. @var{sig} should be two hex digits.
+@item s
+Step.
+@item S@var{sig}
+Step with signal @var{sig}. @var{sig} should be two hex digits.
+@end table
+
+The optional @var{addr} argument normally associated with these packets is
+not supported in @code{vCont}.
+
+Reply:
+@xref{Stop Reply Packets}, for the reply specifications.
+
+@item @code{vCont?} --- extended resume query
+@cindex @code{vCont?} packet
+
+Query support for the @code{vCont} packet.
+
+Reply:
+@table @samp
+@item @code{vCont}[;@var{action}]...
+The @code{vCont} packet is supported. Each @var{action} is a supported
+command in the @code{vCont} packet.
@item
-@tab reply @code{E}@var{NN}
-@tab thread is dead
+The @code{vCont} packet is not supported.
+@end table
-@item reserved
-@tab @code{u}
-@tab Reserved for future use
+@item @code{V} --- reserved
-@item reserved
-@tab @code{U}
-@tab Reserved for future use
+Reserved for future use.
-@item reserved
-@tab @code{v}
-@tab Reserved for future use
+@item @code{w} --- reserved
-@item reserved
-@tab @code{V}
-@tab Reserved for future use
+Reserved for future use.
-@item reserved
-@tab @code{w}
-@tab Reserved for future use
+@item @code{W} --- reserved
-@item reserved
-@tab @code{W}
-@tab Reserved for future use
+Reserved for future use.
-@item reserved
-@tab @code{x}
-@tab Reserved for future use
+@item @code{x} --- reserved
-@item write mem (binary)
-@tab @code{X}@var{addr}@code{,}@var{length}@var{:}@var{XX...}
-@tab
-@var{addr} is address, @var{length} is number of bytes, @var{XX...} is
-binary data. The characters @code{$}, @code{#}, and @code{0x7d} are
+Reserved for future use.
+
+@item @code{X}@var{addr}@code{,}@var{length}@var{:}@var{XX@dots{}} --- write mem (binary)
+@cindex @code{X} packet
+
+@var{addr} is address, @var{length} is number of bytes, @var{XX@dots{}}
+is binary data. The characters @code{$}, @code{#}, and @code{0x7d} are
escaped using @code{0x7d}.
+
+Reply:
+@table @samp
+@item OK
+for success
+@item E@var{NN}
+for an error
+@end table
+
+@item @code{y} --- reserved
+
+Reserved for future use.
+
+@item @code{Y} reserved
+
+Reserved for future use.
+
+@item @code{z}@var{type}@code{,}@var{addr}@code{,}@var{length} --- remove breakpoint or watchpoint @strong{(draft)}
+@itemx @code{Z}@var{type}@code{,}@var{addr}@code{,}@var{length} --- insert breakpoint or watchpoint @strong{(draft)}
+@anchor{insert breakpoint or watchpoint packet}
+@cindex @code{z} packet
+@cindex @code{Z} packets
+
+Insert (@code{Z}) or remove (@code{z}) a @var{type} breakpoint or
+watchpoint starting at address @var{address} and covering the next
+@var{length} bytes.
+
+Each breakpoint and watchpoint packet @var{type} is documented
+separately.
+
+@emph{Implementation notes: A remote target shall return an empty string
+for an unrecognized breakpoint or watchpoint packet @var{type}. A
+remote target shall support either both or neither of a given
+@code{Z}@var{type}@dots{} and @code{z}@var{type}@dots{} packet pair. To
+avoid potential problems with duplicate packets, the operations should
+be implemented in an idempotent way.}
+
+@item @code{z}@code{0}@code{,}@var{addr}@code{,}@var{length} --- remove memory breakpoint @strong{(draft)}
+@item @code{Z}@code{0}@code{,}@var{addr}@code{,}@var{length} --- insert memory breakpoint @strong{(draft)}
+@cindex @code{z0} packet
+@cindex @code{Z0} packet
+
+Insert (@code{Z0}) or remove (@code{z0}) a memory breakpoint at address
+@code{addr} of size @code{length}.
+
+A memory breakpoint is implemented by replacing the instruction at
+@var{addr} with a software breakpoint or trap instruction. The
+@code{length} is used by targets that indicates the size of the
+breakpoint (in bytes) that should be inserted (e.g., the @sc{arm} and
+@sc{mips} can insert either a 2 or 4 byte breakpoint).
+
+@emph{Implementation note: It is possible for a target to copy or move
+code that contains memory breakpoints (e.g., when implementing
+overlays). The behavior of this packet, in the presence of such a
+target, is not defined.}
+
+Reply:
+@table @samp
+@item OK
+success
@item
-@tab reply @code{OK}
-@tab for success
-@item
-@tab reply @code{E}@var{NN}
-@tab for an error
+not supported
+@item E@var{NN}
+for an error
+@end table
+
+@item @code{z}@code{1}@code{,}@var{addr}@code{,}@var{length} --- remove hardware breakpoint @strong{(draft)}
+@item @code{Z}@code{1}@code{,}@var{addr}@code{,}@var{length} --- insert hardware breakpoint @strong{(draft)}
+@cindex @code{z1} packet
+@cindex @code{Z1} packet
-@item reserved
-@tab @code{y}
-@tab Reserved for future use
+Insert (@code{Z1}) or remove (@code{z1}) a hardware breakpoint at
+address @code{addr} of size @code{length}.
-@item reserved
-@tab @code{Y}
-@tab Reserved for future use
+A hardware breakpoint is implemented using a mechanism that is not
+dependant on being able to modify the target's memory.
-@item remove break or watchpoint @strong{(draft)}
-@tab @code{z}@var{t}@code{,}@var{addr}@code{,}@var{length}
-@tab
-See @samp{Z}.
+@emph{Implementation note: A hardware breakpoint is not affected by code
+movement.}
-@item insert break or watchpoint @strong{(draft)}
-@tab @code{Z}@var{t}@code{,}@var{addr}@code{,}@var{length}
-@tab
-@var{t} is type: @samp{0} - software breakpoint, @samp{1} - hardware
-breakpoint, @samp{2} - write watchpoint, @samp{3} - read watchpoint,
-@samp{4} - access watchpoint; @var{addr} is address; @var{length} is in
-bytes. For a software breakpoint, @var{length} specifies the size of
-the instruction to be patched. For hardware breakpoints and watchpoints
-@var{length} specifies the memory region to be monitored. To avoid
-potential problems with duplicate packets, the operations should be
-implemented in an idempotent way.
+Reply:
+@table @samp
+@item OK
+success
@item
-@tab reply @code{E}@var{NN}
-@tab for an error
+not supported
+@item E@var{NN}
+for an error
+@end table
+
+@item @code{z}@code{2}@code{,}@var{addr}@code{,}@var{length} --- remove write watchpoint @strong{(draft)}
+@item @code{Z}@code{2}@code{,}@var{addr}@code{,}@var{length} --- insert write watchpoint @strong{(draft)}
+@cindex @code{z2} packet
+@cindex @code{Z2} packet
+
+Insert (@code{Z2}) or remove (@code{z2}) a write watchpoint.
+
+Reply:
+@table @samp
+@item OK
+success
@item
-@tab reply @code{OK}
-@tab for success
+not supported
+@item E@var{NN}
+for an error
+@end table
+
+@item @code{z}@code{3}@code{,}@var{addr}@code{,}@var{length} --- remove read watchpoint @strong{(draft)}
+@item @code{Z}@code{3}@code{,}@var{addr}@code{,}@var{length} --- insert read watchpoint @strong{(draft)}
+@cindex @code{z3} packet
+@cindex @code{Z3} packet
+
+Insert (@code{Z3}) or remove (@code{z3}) a read watchpoint.
+
+Reply:
+@table @samp
+@item OK
+success
@item
-@tab @samp{}
-@tab If not supported.
+not supported
+@item E@var{NN}
+for an error
+@end table
-@item reserved
-@tab <other>
-@tab Reserved for future use
+@item @code{z}@code{4}@code{,}@var{addr}@code{,}@var{length} --- remove access watchpoint @strong{(draft)}
+@item @code{Z}@code{4}@code{,}@var{addr}@code{,}@var{length} --- insert access watchpoint @strong{(draft)}
+@cindex @code{z4} packet
+@cindex @code{Z4} packet
-@end multitable
+Insert (@code{Z4}) or remove (@code{z4}) an access watchpoint.
+
+Reply:
+@table @samp
+@item OK
+success
+@item
+not supported
+@item E@var{NN}
+for an error
+@end table
+
+@end table
+
+@node Stop Reply Packets
+@section Stop Reply Packets
+@cindex stop reply packets
The @samp{C}, @samp{c}, @samp{S}, @samp{s} and @samp{?} packets can
receive any of the below as a reply. In the case of the @samp{C},
@@ -14632,315 +20236,1525 @@ when the target halts. In the below the exact meaning of @samp{signal
number} is poorly defined. In general one of the UNIX signal numbering
conventions is used.
-@multitable @columnfractions .4 .6
+@table @samp
-@item @code{S}@var{AA}
-@tab @var{AA} is the signal number
+@item S@var{AA}
+@var{AA} is the signal number
@item @code{T}@var{AA}@var{n...}@code{:}@var{r...}@code{;}@var{n...}@code{:}@var{r...}@code{;}@var{n...}@code{:}@var{r...}@code{;}
-@tab
+@cindex @code{T} packet reply
+
@var{AA} = two hex digit signal number; @var{n...} = register number
(hex), @var{r...} = target byte ordered register contents, size defined
-by @code{REGISTER_RAW_SIZE}; @var{n...} = @samp{thread}, @var{r...} =
-thread process ID, this is a hex integer; @var{n...} = other string not
-starting with valid hex digit. @value{GDBN} should ignore this
-@var{n...}, @var{r...} pair and go on to the next. This way we can
-extend the protocol.
-
-@item @code{W}@var{AA}
-@tab
+by @code{DEPRECATED_REGISTER_RAW_SIZE}; @var{n...} = @samp{thread},
+@var{r...} = thread process ID, this is a hex integer; @var{n...} =
+(@samp{watch} | @samp{rwatch} | @samp{awatch}, @var{r...} = data
+address, this is a hex integer; @var{n...} = other string not starting
+with valid hex digit. @value{GDBN} should ignore this @var{n...},
+@var{r...} pair and go on to the next. This way we can extend the
+protocol.
+
+@item W@var{AA}
+
The process exited, and @var{AA} is the exit status. This is only
-applicable for certains sorts of targets.
+applicable to certain targets.
+
+@item X@var{AA}
-@item @code{X}@var{AA}
-@tab
The process terminated with signal @var{AA}.
-@item @code{N}@var{AA}@code{;}@var{t...}@code{;}@var{d...}@code{;}@var{b...} @strong{(obsolete)}
-@tab
-@var{AA} = signal number; @var{t...} = address of symbol "_start";
-@var{d...} = base of data section; @var{b...} = base of bss section.
-@emph{Note: only used by Cisco Systems targets. The difference between
-this reply and the "qOffsets" query is that the 'N' packet may arrive
-spontaneously whereas the 'qOffsets' is a query initiated by the host
-debugger.}
-
-@item @code{O}@var{XX...}
-@tab
-@var{XX...} is hex encoding of @sc{ascii} data. This can happen at any time
-while the program is running and the debugger should continue to wait
-for 'W', 'T', etc.
+@item O@var{XX@dots{}}
-@end multitable
+@var{XX@dots{}} is hex encoding of @sc{ascii} data. This can happen at
+any time while the program is running and the debugger should continue
+to wait for @samp{W}, @samp{T}, etc.
+
+@item F@var{call-id}@code{,}@var{parameter@dots{}}
+
+@var{call-id} is the identifier which says which host system call should
+be called. This is just the name of the function. Translation into the
+correct system call is only applicable as it's defined in @value{GDBN}.
+@xref{File-I/O remote protocol extension}, for a list of implemented
+system calls.
+
+@var{parameter@dots{}} is a list of parameters as defined for this very
+system call.
+
+The target replies with this packet when it expects @value{GDBN} to call
+a host system call on behalf of the target. @value{GDBN} replies with
+an appropriate @code{F} packet and keeps up waiting for the next reply
+packet from the target. The latest @samp{C}, @samp{c}, @samp{S} or
+@samp{s} action is expected to be continued.
+@xref{File-I/O remote protocol extension}, for more details.
+
+@end table
+
+@node General Query Packets
+@section General Query Packets
The following set and query packets have already been defined.
-@multitable @columnfractions .2 .2 .6
+@table @r
-@item current thread
-@tab @code{q}@code{C}
-@tab Return the current thread id.
-@item
-@tab reply @code{QC}@var{pid}
-@tab
+@item @code{q}@code{C} --- current thread
+
+Return the current thread id.
+
+Reply:
+@table @samp
+@item @code{QC}@var{pid}
Where @var{pid} is a HEX encoded 16 bit process id.
-@item
-@tab reply *
-@tab Any other reply implies the old pid.
+@item *
+Any other reply implies the old pid.
+@end table
+
+@item @code{q}@code{fThreadInfo} -- all thread ids
+
+@code{q}@code{sThreadInfo}
-@item all thread ids
-@tab @code{q}@code{fThreadInfo}
-@item
-@tab @code{q}@code{sThreadInfo}
-@tab
Obtain a list of active thread ids from the target (OS). Since there
may be too many active threads to fit into one reply packet, this query
works iteratively: it may require more than one query/reply sequence to
obtain the entire list of threads. The first query of the sequence will
be the @code{qf}@code{ThreadInfo} query; subsequent queries in the
sequence will be the @code{qs}@code{ThreadInfo} query.
-@item
-@tab
-@tab NOTE: replaces the @code{qL} query (see below).
-@item
-@tab reply @code{m}@var{<id>}
-@tab A single thread id
-@item
-@tab reply @code{m}@var{<id>},@var{<id>...}
-@tab a comma-separated list of thread ids
-@item
-@tab reply @code{l}
-@tab (lower case 'el') denotes end of list.
-@item
-@tab
-@tab
-In response to each query, the target will reply with a list of one
-or more thread ids, in big-endian hex, separated by commas. GDB will
-respond to each reply with a request for more thread ids (using the
+
+NOTE: replaces the @code{qL} query (see below).
+
+Reply:
+@table @samp
+@item @code{m}@var{id}
+A single thread id
+@item @code{m}@var{id},@var{id}@dots{}
+a comma-separated list of thread ids
+@item @code{l}
+(lower case 'el') denotes end of list.
+@end table
+
+In response to each query, the target will reply with a list of one or
+more thread ids, in big-endian hex, separated by commas. @value{GDBN}
+will respond to each reply with a request for more thread ids (using the
@code{qs} form of the query), until the target responds with @code{l}
(lower-case el, for @code{'last'}).
-@item extra thread info
-@tab @code{q}@code{ThreadExtraInfo}@code{,}@var{id}
-@tab
-@item
-@tab
-@tab
-Where @var{<id>} is a thread-id in big-endian hex.
-Obtain a printable string description of a thread's attributes from
-the target OS. This string may contain anything that the target OS
-thinks is interesting for @value{GDBN} to tell the user about the thread.
-The string is displayed in @value{GDBN}'s @samp{info threads} display.
-Some examples of possible thread extra info strings are "Runnable", or
-"Blocked on Mutex".
-@item
-@tab reply @var{XX...}
-@tab
-Where @var{XX...} is a hex encoding of @sc{ascii} data, comprising the
-printable string containing the extra information about the thread's
+@item @code{q}@code{ThreadExtraInfo}@code{,}@var{id} --- extra thread info
+
+Where @var{id} is a thread-id in big-endian hex. Obtain a printable
+string description of a thread's attributes from the target OS. This
+string may contain anything that the target OS thinks is interesting for
+@value{GDBN} to tell the user about the thread. The string is displayed
+in @value{GDBN}'s @samp{info threads} display. Some examples of
+possible thread extra info strings are ``Runnable'', or ``Blocked on
+Mutex''.
+
+Reply:
+@table @samp
+@item @var{XX@dots{}}
+Where @var{XX@dots{}} is a hex encoding of @sc{ascii} data, comprising
+the printable string containing the extra information about the thread's
attributes.
+@end table
+
+@item @code{q}@code{L}@var{startflag}@var{threadcount}@var{nextthread} --- query @var{LIST} or @var{threadLIST} @strong{(deprecated)}
-@item query @var{LIST} or @var{threadLIST} @strong{(deprecated)}
-@tab @code{q}@code{L}@var{startflag}@var{threadcount}@var{nextthread}
-@tab
-@item
-@tab
-@tab
Obtain thread information from RTOS. Where: @var{startflag} (one hex
digit) is one to indicate the first query and zero to indicate a
subsequent query; @var{threadcount} (two hex digits) is the maximum
number of threads the response packet can contain; and @var{nextthread}
(eight hex digits), for subsequent queries (@var{startflag} is zero), is
returned in the response as @var{argthread}.
-@item
-@tab
-@tab NOTE: this query is replaced by the @code{q}@code{fThreadInfo}
-query (see above).
-@item
-@tab reply @code{q}@code{M}@var{count}@var{done}@var{argthread}@var{thread...}
-@tab
-@item
-@tab
-@tab
+
+NOTE: this query is replaced by the @code{q}@code{fThreadInfo} query
+(see above).
+
+Reply:
+@table @samp
+@item @code{q}@code{M}@var{count}@var{done}@var{argthread}@var{thread@dots{}}
Where: @var{count} (two hex digits) is the number of threads being
returned; @var{done} (one hex digit) is zero to indicate more threads
and one indicates no further threads; @var{argthreadid} (eight hex
-digits) is @var{nextthread} from the request packet; @var{thread...} is
-a sequence of thread IDs from the target. @var{threadid} (eight hex
+digits) is @var{nextthread} from the request packet; @var{thread@dots{}}
+is a sequence of thread IDs from the target. @var{threadid} (eight hex
digits). See @code{remote.c:parse_threadlist_response()}.
+@end table
-@item compute CRC of memory block
-@tab @code{q}@code{CRC:}@var{addr}@code{,}@var{length}
-@tab
-@item
-@tab reply @code{E}@var{NN}
-@tab An error (such as memory fault)
-@item
-@tab reply @code{C}@var{CRC32}
-@tab A 32 bit cyclic redundancy check of the specified memory region.
+@item @code{q}@code{CRC:}@var{addr}@code{,}@var{length} --- compute CRC of memory block
+
+Reply:
+@table @samp
+@item @code{E}@var{NN}
+An error (such as memory fault)
+@item @code{C}@var{CRC32}
+A 32 bit cyclic redundancy check of the specified memory region.
+@end table
+
+@item @code{q}@code{Offsets} --- query sect offs
-@item query sect offs
-@tab @code{q}@code{Offsets}
-@tab
Get section offsets that the target used when re-locating the downloaded
image. @emph{Note: while a @code{Bss} offset is included in the
response, @value{GDBN} ignores this and instead applies the @code{Data}
offset to the @code{Bss} section.}
-@item
-@tab reply @code{Text=}@var{xxx}@code{;Data=}@var{yyy}@code{;Bss=}@var{zzz}
-@item thread info request
-@tab @code{q}@code{P}@var{mode}@var{threadid}
-@tab
-@item
-@tab
-@tab
+Reply:
+@table @samp
+@item @code{Text=}@var{xxx}@code{;Data=}@var{yyy}@code{;Bss=}@var{zzz}
+@end table
+
+@item @code{q}@code{P}@var{mode}@var{threadid} --- thread info request
+
Returns information on @var{threadid}. Where: @var{mode} is a hex
encoded 32 bit mode; @var{threadid} is a hex encoded 64 bit thread ID.
-@item
-@tab reply *
-@tab
+
+Reply:
+@table @samp
+@item *
+@end table
+
See @code{remote.c:remote_unpack_thread_info_response()}.
-@item remote command
-@tab @code{q}@code{Rcmd,}@var{COMMAND}
-@tab
-@item
-@tab
-@tab
-@var{COMMAND} (hex encoded) is passed to the local interpreter for
+@item @code{q}@code{Rcmd,}@var{command} --- remote command
+
+@var{command} (hex encoded) is passed to the local interpreter for
execution. Invalid commands should be reported using the output string.
Before the final result packet, the target may also respond with a
-number of intermediate @code{O}@var{OUTPUT} console output
-packets. @emph{Implementors should note that providing access to a
-stubs's interpreter may have security implications}.
-@item
-@tab reply @code{OK}
-@tab
+number of intermediate @code{O}@var{output} console output packets.
+@emph{Implementors should note that providing access to a stubs's
+interpreter may have security implications}.
+
+Reply:
+@table @samp
+@item OK
A command response with no output.
-@item
-@tab reply @var{OUTPUT}
-@tab
+@item @var{OUTPUT}
A command response with the hex encoded output string @var{OUTPUT}.
-@item
-@tab reply @code{E}@var{NN}
-@tab
+@item @code{E}@var{NN}
Indicate a badly formed request.
-
-@item
-@tab reply @samp{}
-@tab
+@item @samp{}
When @samp{q}@samp{Rcmd} is not recognized.
+@end table
+
+@item @code{qSymbol::} --- symbol lookup
-@item symbol lookup
-@tab @code{qSymbol::}
-@tab
Notify the target that @value{GDBN} is prepared to serve symbol lookup
requests. Accept requests from the target for the values of symbols.
-@item
-@tab
-@tab
-@item
-@tab reply @code{OK}
-@tab
+
+Reply:
+@table @samp
+@item @code{OK}
The target does not need to look up any (more) symbols.
-@item
-@tab reply @code{qSymbol:}@var{sym_name}
-@tab
-@sp 2
-@noindent
-The target requests the value of symbol @var{sym_name} (hex encoded).
-@value{GDBN} may provide the value by using the
-@code{qSymbol:}@var{sym_value}:@var{sym_name}
-message, described below.
+@item @code{qSymbol:}@var{sym_name}
+The target requests the value of symbol @var{sym_name} (hex encoded).
+@value{GDBN} may provide the value by using the
+@code{qSymbol:}@var{sym_value}:@var{sym_name} message, described below.
+@end table
-@item symbol value
-@tab @code{qSymbol:}@var{sym_value}:@var{sym_name}
-@tab
-@sp 1
-@noindent
-Set the value of SYM_NAME to SYM_VALUE.
-@item
-@tab
-@tab
-@var{sym_name} (hex encoded) is the name of a symbol whose value
-the target has previously requested.
-@item
-@tab
-@tab
-@var{sym_value} (hex) is the value for symbol @var{sym_name}.
-If @value{GDBN} cannot supply a value for @var{sym_name}, then this
-field will be empty.
-@item
-@tab reply @code{OK}
-@tab
+@item @code{qSymbol:}@var{sym_value}:@var{sym_name} --- symbol value
+
+Set the value of @var{sym_name} to @var{sym_value}.
+
+@var{sym_name} (hex encoded) is the name of a symbol whose value the
+target has previously requested.
+
+@var{sym_value} (hex) is the value for symbol @var{sym_name}. If
+@value{GDBN} cannot supply a value for @var{sym_name}, then this field
+will be empty.
+
+Reply:
+@table @samp
+@item @code{OK}
The target does not need to look up any (more) symbols.
-@item
-@tab reply @code{qSymbol:}@var{sym_name}
-@tab
-@sp 2
-@noindent
-The target requests the value of a new symbol @var{sym_name} (hex encoded).
-@value{GDBN} will continue to supply the values of symbols (if available),
-until the target ceases to request them.
+@item @code{qSymbol:}@var{sym_name}
+The target requests the value of a new symbol @var{sym_name} (hex
+encoded). @value{GDBN} will continue to supply the values of symbols
+(if available), until the target ceases to request them.
+@end table
-@end multitable
+@item @code{qPart}:@var{object}:@code{read}:@var{annex}:@var{offset},@var{length} --- read special data
+
+Read uninterpreted bytes from the target's special data area
+identified by the keyword @code{object}.
+Request @var{length} bytes starting at @var{offset} bytes into the data.
+The content and encoding of @var{annex} is specific to the object;
+it can supply additional details about what data to access.
+
+Here are the specific requests of this form defined so far.
+All @samp{@code{qPart}:@var{object}:@code{read}:@dots{}}
+requests use the same reply formats, listed below.
+
+@table @asis
+@item @code{qPart}:@code{auxv}:@code{read}::@var{offset},@var{length}
+Access the target's @dfn{auxiliary vector}. @xref{Auxiliary Vector}.
+Note @var{annex} must be empty.
+@end table
+
+Reply:
+@table @asis
+@item @code{OK}
+The @var{offset} in the request is at the end of the data.
+There is no more data to be read.
+
+@item @var{XX@dots{}}
+Hex encoded data bytes read.
+This may be fewer bytes than the @var{length} in the request.
+
+@item @code{E00}
+The request was malformed, or @var{annex} was invalid.
+
+@item @code{E}@var{nn}
+The offset was invalid, or there was an error encountered reading the data.
+@var{nn} is a hex-encoded @code{errno} value.
+
+@item @code{""} (empty)
+An empty reply indicates the @var{object} or @var{annex} string was not
+recognized by the stub.
+@end table
+
+@item @code{qPart}:@var{object}:@code{write}:@var{annex}:@var{offset}:@var{data@dots{}}
+
+Write uninterpreted bytes into the target's special data area
+identified by the keyword @code{object},
+starting at @var{offset} bytes into the data.
+@var{data@dots{}} is the hex-encoded data to be written.
+The content and encoding of @var{annex} is specific to the object;
+it can supply additional details about what data to access.
+
+No requests of this form are presently in use. This specification
+serves as a placeholder to document the common format that new
+specific request specifications ought to use.
+
+Reply:
+@table @asis
+@item @var{nn}
+@var{nn} (hex encoded) is the number of bytes written.
+This may be fewer bytes than supplied in the request.
+
+@item @code{E00}
+The request was malformed, or @var{annex} was invalid.
+
+@item @code{E}@var{nn}
+The offset was invalid, or there was an error encountered writing the data.
+@var{nn} is a hex-encoded @code{errno} value.
+
+@item @code{""} (empty)
+An empty reply indicates the @var{object} or @var{annex} string was not
+recognized by the stub, or that the object does not support writing.
+@end table
+
+@item @code{qPart}:@var{object}:@var{operation}:@dots{}
+Requests of this form may be added in the future. When a stub does
+not recognize the @var{object} keyword, or its support for
+@var{object} does not recognize the @var{operation} keyword,
+the stub must respond with an empty packet.
+@end table
+
+@node Register Packet Format
+@section Register Packet Format
The following @samp{g}/@samp{G} packets have previously been defined.
-In the below, some thirty-two bit registers are transferred as sixty-four
-bits. Those registers should be zero/sign extended (which?) to fill the
-space allocated. Register bytes are transfered in target byte order.
-The two nibbles within a register byte are transfered most-significant -
-least-significant.
+In the below, some thirty-two bit registers are transferred as
+sixty-four bits. Those registers should be zero/sign extended (which?)
+to fill the space allocated. Register bytes are transfered in target
+byte order. The two nibbles within a register byte are transfered
+most-significant - least-significant.
-@multitable @columnfractions .5 .5
+@table @r
@item MIPS32
-@tab
+
All registers are transfered as thirty-two bit quantities in the order:
32 general-purpose; sr; lo; hi; bad; cause; pc; 32 floating-point
registers; fsr; fir; fp.
@item MIPS64
-@tab
+
All registers are transfered as sixty-four bit quantities (including
thirty-two bit registers such as @code{sr}). The ordering is the same
as @code{MIPS32}.
-@end multitable
+@end table
+
+@node Examples
+@section Examples
Example sequence of a target being re-started. Notice how the restart
does not get any direct output:
-@example
-<- @code{R00}
--> @code{+}
+@smallexample
+-> @code{R00}
+<- @code{+}
@emph{target restarts}
-<- @code{?}
--> @code{+}
--> @code{T001:1234123412341234}
+-> @code{?}
<- @code{+}
-@end example
+<- @code{T001:1234123412341234}
+-> @code{+}
+@end smallexample
Example sequence of a target being stepped by a single instruction:
-@example
-<- @code{G1445...}
--> @code{+}
-<- @code{s}
--> @code{+}
-@emph{time passes}
--> @code{T001:1234123412341234}
+@smallexample
+-> @code{G1445@dots{}}
<- @code{+}
-<- @code{g}
+-> @code{s}
+<- @code{+}
+@emph{time passes}
+<- @code{T001:1234123412341234}
-> @code{+}
--> @code{1455...}
+-> @code{g}
<- @code{+}
-@end example
+<- @code{1455@dots{}}
+-> @code{+}
+@end smallexample
+
+@node File-I/O remote protocol extension
+@section File-I/O remote protocol extension
+@cindex File-I/O remote protocol extension
+
+@menu
+* File-I/O Overview::
+* Protocol basics::
+* The F request packet::
+* The F reply packet::
+* Memory transfer::
+* The Ctrl-C message::
+* Console I/O::
+* The isatty call::
+* The system call::
+* List of supported calls::
+* Protocol specific representation of datatypes::
+* Constants::
+* File-I/O Examples::
+@end menu
+
+@node File-I/O Overview
+@subsection File-I/O Overview
+@cindex file-i/o overview
+
+The File I/O remote protocol extension (short: File-I/O) allows the
+target to use the hosts file system and console I/O when calling various
+system calls. System calls on the target system are translated into a
+remote protocol packet to the host system which then performs the needed
+actions and returns with an adequate response packet to the target system.
+This simulates file system operations even on targets that lack file systems.
+
+The protocol is defined host- and target-system independent. It uses
+it's own independent representation of datatypes and values. Both,
+@value{GDBN} and the target's @value{GDBN} stub are responsible for
+translating the system dependent values into the unified protocol values
+when data is transmitted.
+
+The communication is synchronous. A system call is possible only
+when GDB is waiting for the @samp{C}, @samp{c}, @samp{S} or @samp{s}
+packets. While @value{GDBN} handles the request for a system call,
+the target is stopped to allow deterministic access to the target's
+memory. Therefore File-I/O is not interuptible by target signals. It
+is possible to interrupt File-I/O by a user interrupt (Ctrl-C), though.
+
+The target's request to perform a host system call does not finish
+the latest @samp{C}, @samp{c}, @samp{S} or @samp{s} action. That means,
+after finishing the system call, the target returns to continuing the
+previous activity (continue, step). No additional continue or step
+request from @value{GDBN} is required.
+
+@smallexample
+(gdb) continue
+ <- target requests 'system call X'
+ target is stopped, @value{GDBN} executes system call
+ -> GDB returns result
+ ... target continues, GDB returns to wait for the target
+ <- target hits breakpoint and sends a Txx packet
+@end smallexample
+
+The protocol is only used for files on the host file system and
+for I/O on the console. Character or block special devices, pipes,
+named pipes or sockets or any other communication method on the host
+system are not supported by this protocol.
+
+@node Protocol basics
+@subsection Protocol basics
+@cindex protocol basics, file-i/o
+
+The File-I/O protocol uses the @code{F} packet, as request as well
+as as reply packet. Since a File-I/O system call can only occur when
+@value{GDBN} is waiting for the continuing or stepping target, the
+File-I/O request is a reply that @value{GDBN} has to expect as a result
+of a former @samp{C}, @samp{c}, @samp{S} or @samp{s} packet.
+This @code{F} packet contains all information needed to allow @value{GDBN}
+to call the appropriate host system call:
+
+@itemize @bullet
+@item
+A unique identifier for the requested system call.
+
+@item
+All parameters to the system call. Pointers are given as addresses
+in the target memory address space. Pointers to strings are given as
+pointer/length pair. Numerical values are given as they are.
+Numerical control values are given in a protocol specific representation.
+
+@end itemize
+
+At that point @value{GDBN} has to perform the following actions.
+
+@itemize @bullet
+@item
+If parameter pointer values are given, which point to data needed as input
+to a system call, @value{GDBN} requests this data from the target with a
+standard @code{m} packet request. This additional communication has to be
+expected by the target implementation and is handled as any other @code{m}
+packet.
+
+@item
+@value{GDBN} translates all value from protocol representation to host
+representation as needed. Datatypes are coerced into the host types.
+
+@item
+@value{GDBN} calls the system call
+
+@item
+It then coerces datatypes back to protocol representation.
+
+@item
+If pointer parameters in the request packet point to buffer space in which
+a system call is expected to copy data to, the data is transmitted to the
+target using a @code{M} or @code{X} packet. This packet has to be expected
+by the target implementation and is handled as any other @code{M} or @code{X}
+packet.
+
+@end itemize
+
+Eventually @value{GDBN} replies with another @code{F} packet which contains all
+necessary information for the target to continue. This at least contains
+
+@itemize @bullet
+@item
+Return value.
+
+@item
+@code{errno}, if has been changed by the system call.
+
+@item
+``Ctrl-C'' flag.
+
+@end itemize
+
+After having done the needed type and value coercion, the target continues
+the latest continue or step action.
+
+@node The F request packet
+@subsection The @code{F} request packet
+@cindex file-i/o request packet
+@cindex @code{F} request packet
+
+The @code{F} request packet has the following format:
+
+@table @samp
+
+@smallexample
+@code{F}@var{call-id}@code{,}@var{parameter@dots{}}
+@end smallexample
+
+@var{call-id} is the identifier to indicate the host system call to be called.
+This is just the name of the function.
+
+@var{parameter@dots{}} are the parameters to the system call.
+
+@end table
+
+Parameters are hexadecimal integer values, either the real values in case
+of scalar datatypes, as pointers to target buffer space in case of compound
+datatypes and unspecified memory areas or as pointer/length pairs in case
+of string parameters. These are appended to the call-id, each separated
+from its predecessor by a comma. All values are transmitted in ASCII
+string representation, pointer/length pairs separated by a slash.
+
+@node The F reply packet
+@subsection The @code{F} reply packet
+@cindex file-i/o reply packet
+@cindex @code{F} reply packet
+
+The @code{F} reply packet has the following format:
+
+@table @samp
+
+@smallexample
+@code{F}@var{retcode}@code{,}@var{errno}@code{,}@var{Ctrl-C flag}@code{;}@var{call specific attachment}
+@end smallexample
+
+@var{retcode} is the return code of the system call as hexadecimal value.
+
+@var{errno} is the errno set by the call, in protocol specific representation.
+This parameter can be omitted if the call was successful.
+
+@var{Ctrl-C flag} is only send if the user requested a break. In this
+case, @var{errno} must be send as well, even if the call was successful.
+The @var{Ctrl-C flag} itself consists of the character 'C':
+
+@smallexample
+F0,0,C
+@end smallexample
+
+@noindent
+or, if the call was interupted before the host call has been performed:
+
+@smallexample
+F-1,4,C
+@end smallexample
+
+@noindent
+assuming 4 is the protocol specific representation of @code{EINTR}.
+
+@end table
+
+@node Memory transfer
+@subsection Memory transfer
+@cindex memory transfer, in file-i/o protocol
+
+Structured data which is transferred using a memory read or write as e.g.@:
+a @code{struct stat} is expected to be in a protocol specific format with
+all scalar multibyte datatypes being big endian. This should be done by
+the target before the @code{F} packet is sent resp.@: by @value{GDBN} before
+it transfers memory to the target. Transferred pointers to structured
+data should point to the already coerced data at any time.
+
+@node The Ctrl-C message
+@subsection The Ctrl-C message
+@cindex ctrl-c message, in file-i/o protocol
+
+A special case is, if the @var{Ctrl-C flag} is set in the @value{GDBN}
+reply packet. In this case the target should behave, as if it had
+gotten a break message. The meaning for the target is ``system call
+interupted by @code{SIGINT}''. Consequentially, the target should actually stop
+(as with a break message) and return to @value{GDBN} with a @code{T02}
+packet. In this case, it's important for the target to know, in which
+state the system call was interrupted. Since this action is by design
+not an atomic operation, we have to differ between two cases:
+
+@itemize @bullet
+@item
+The system call hasn't been performed on the host yet.
+
+@item
+The system call on the host has been finished.
+
+@end itemize
+
+These two states can be distinguished by the target by the value of the
+returned @code{errno}. If it's the protocol representation of @code{EINTR}, the system
+call hasn't been performed. This is equivalent to the @code{EINTR} handling
+on POSIX systems. In any other case, the target may presume that the
+system call has been finished --- successful or not --- and should behave
+as if the break message arrived right after the system call.
+
+@value{GDBN} must behave reliable. If the system call has not been called
+yet, @value{GDBN} may send the @code{F} reply immediately, setting @code{EINTR} as
+@code{errno} in the packet. If the system call on the host has been finished
+before the user requests a break, the full action must be finshed by
+@value{GDBN}. This requires sending @code{M} or @code{X} packets as they fit.
+The @code{F} packet may only be send when either nothing has happened
+or the full action has been completed.
+
+@node Console I/O
+@subsection Console I/O
+@cindex console i/o as part of file-i/o
+
+By default and if not explicitely closed by the target system, the file
+descriptors 0, 1 and 2 are connected to the @value{GDBN} console. Output
+on the @value{GDBN} console is handled as any other file output operation
+(@code{write(1, @dots{})} or @code{write(2, @dots{})}). Console input is handled
+by @value{GDBN} so that after the target read request from file descriptor
+0 all following typing is buffered until either one of the following
+conditions is met:
+
+@itemize @bullet
+@item
+The user presses @kbd{Ctrl-C}. The behaviour is as explained above, the
+@code{read}
+system call is treated as finished.
+
+@item
+The user presses @kbd{Enter}. This is treated as end of input with a trailing
+line feed.
+
+@item
+The user presses @kbd{Ctrl-D}. This is treated as end of input. No trailing
+character, especially no Ctrl-D is appended to the input.
+
+@end itemize
+
+If the user has typed more characters as fit in the buffer given to
+the read call, the trailing characters are buffered in @value{GDBN} until
+either another @code{read(0, @dots{})} is requested by the target or debugging
+is stopped on users request.
+
+@node The isatty call
+@subsection The isatty(3) call
+@cindex isatty call, file-i/o protocol
+
+A special case in this protocol is the library call @code{isatty} which
+is implemented as it's own call inside of this protocol. It returns
+1 to the target if the file descriptor given as parameter is attached
+to the @value{GDBN} console, 0 otherwise. Implementing through system calls
+would require implementing @code{ioctl} and would be more complex than
+needed.
+
+@node The system call
+@subsection The system(3) call
+@cindex system call, file-i/o protocol
+
+The other special case in this protocol is the @code{system} call which
+is implemented as it's own call, too. @value{GDBN} is taking over the full
+task of calling the necessary host calls to perform the @code{system}
+call. The return value of @code{system} is simplified before it's returned
+to the target. Basically, the only signal transmitted back is @code{EINTR}
+in case the user pressed @kbd{Ctrl-C}. Otherwise the return value consists
+entirely of the exit status of the called command.
+
+Due to security concerns, the @code{system} call is refused to be called
+by @value{GDBN} by default. The user has to allow this call explicitly by
+entering
+
+@table @samp
+@kindex set remote system-call-allowed 1
+@item @code{set remote system-call-allowed 1}
+@end table
+
+Disabling the @code{system} call is done by
+
+@table @samp
+@kindex set remote system-call-allowed 0
+@item @code{set remote system-call-allowed 0}
+@end table
+
+The current setting is shown by typing
+
+@table @samp
+@kindex show remote system-call-allowed
+@item @code{show remote system-call-allowed}
+@end table
+
+@node List of supported calls
+@subsection List of supported calls
+@cindex list of supported file-i/o calls
+
+@menu
+* open::
+* close::
+* read::
+* write::
+* lseek::
+* rename::
+* unlink::
+* stat/fstat::
+* gettimeofday::
+* isatty::
+* system::
+@end menu
+
+@node open
+@unnumberedsubsubsec open
+@cindex open, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+int open(const char *pathname, int flags);
+int open(const char *pathname, int flags, mode_t mode);
+
+@exdent Request:
+Fopen,pathptr/len,flags,mode
+@end smallexample
+
+@noindent
+@code{flags} is the bitwise or of the following values:
+
+@table @code
+@item O_CREAT
+If the file does not exist it will be created. The host
+rules apply as far as file ownership and time stamps
+are concerned.
+
+@item O_EXCL
+When used with O_CREAT, if the file already exists it is
+an error and open() fails.
+
+@item O_TRUNC
+If the file already exists and the open mode allows
+writing (O_RDWR or O_WRONLY is given) it will be
+truncated to length 0.
+
+@item O_APPEND
+The file is opened in append mode.
+
+@item O_RDONLY
+The file is opened for reading only.
+
+@item O_WRONLY
+The file is opened for writing only.
+
+@item O_RDWR
+The file is opened for reading and writing.
+
+@noindent
+Each other bit is silently ignored.
+
+@end table
+
+@noindent
+@code{mode} is the bitwise or of the following values:
+
+@table @code
+@item S_IRUSR
+User has read permission.
+
+@item S_IWUSR
+User has write permission.
+
+@item S_IRGRP
+Group has read permission.
+
+@item S_IWGRP
+Group has write permission.
+
+@item S_IROTH
+Others have read permission.
+
+@item S_IWOTH
+Others have write permission.
+
+@noindent
+Each other bit is silently ignored.
+
+@end table
+
+@smallexample
+@exdent Return value:
+open returns the new file descriptor or -1 if an error
+occured.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EEXIST
+pathname already exists and O_CREAT and O_EXCL were used.
+
+@item EISDIR
+pathname refers to a directory.
+
+@item EACCES
+The requested access is not allowed.
+
+@item ENAMETOOLONG
+pathname was too long.
+
+@item ENOENT
+A directory component in pathname does not exist.
+
+@item ENODEV
+pathname refers to a device, pipe, named pipe or socket.
+
+@item EROFS
+pathname refers to a file on a read-only filesystem and
+write access was requested.
+
+@item EFAULT
+pathname is an invalid pointer value.
+
+@item ENOSPC
+No space on device to create the file.
+
+@item EMFILE
+The process already has the maximum number of files open.
+
+@item ENFILE
+The limit on the total number of files open on the system
+has been reached.
+
+@item EINTR
+The call was interrupted by the user.
+@end table
+
+@node close
+@unnumberedsubsubsec close
+@cindex close, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+int close(int fd);
+
+@exdent Request:
+Fclose,fd
+
+@exdent Return value:
+close returns zero on success, or -1 if an error occurred.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EBADF
+fd isn't a valid open file descriptor.
+
+@item EINTR
+The call was interrupted by the user.
+@end table
+
+@node read
+@unnumberedsubsubsec read
+@cindex read, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+int read(int fd, void *buf, unsigned int count);
+
+@exdent Request:
+Fread,fd,bufptr,count
+
+@exdent Return value:
+On success, the number of bytes read is returned.
+Zero indicates end of file. If count is zero, read
+returns zero as well. On error, -1 is returned.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EBADF
+fd is not a valid file descriptor or is not open for
+reading.
+
+@item EFAULT
+buf is an invalid pointer value.
+
+@item EINTR
+The call was interrupted by the user.
+@end table
+
+@node write
+@unnumberedsubsubsec write
+@cindex write, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+int write(int fd, const void *buf, unsigned int count);
+
+@exdent Request:
+Fwrite,fd,bufptr,count
+
+@exdent Return value:
+On success, the number of bytes written are returned.
+Zero indicates nothing was written. On error, -1
+is returned.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EBADF
+fd is not a valid file descriptor or is not open for
+writing.
+
+@item EFAULT
+buf is an invalid pointer value.
+
+@item EFBIG
+An attempt was made to write a file that exceeds the
+host specific maximum file size allowed.
+
+@item ENOSPC
+No space on device to write the data.
+
+@item EINTR
+The call was interrupted by the user.
+@end table
+
+@node lseek
+@unnumberedsubsubsec lseek
+@cindex lseek, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+long lseek (int fd, long offset, int flag);
+
+@exdent Request:
+Flseek,fd,offset,flag
+@end smallexample
+
+@code{flag} is one of:
+
+@table @code
+@item SEEK_SET
+The offset is set to offset bytes.
+
+@item SEEK_CUR
+The offset is set to its current location plus offset
+bytes.
+
+@item SEEK_END
+The offset is set to the size of the file plus offset
+bytes.
+@end table
+
+@smallexample
+@exdent Return value:
+On success, the resulting unsigned offset in bytes from
+the beginning of the file is returned. Otherwise, a
+value of -1 is returned.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EBADF
+fd is not a valid open file descriptor.
+
+@item ESPIPE
+fd is associated with the @value{GDBN} console.
+
+@item EINVAL
+flag is not a proper value.
+
+@item EINTR
+The call was interrupted by the user.
+@end table
+
+@node rename
+@unnumberedsubsubsec rename
+@cindex rename, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+int rename(const char *oldpath, const char *newpath);
+
+@exdent Request:
+Frename,oldpathptr/len,newpathptr/len
+
+@exdent Return value:
+On success, zero is returned. On error, -1 is returned.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EISDIR
+newpath is an existing directory, but oldpath is not a
+directory.
+
+@item EEXIST
+newpath is a non-empty directory.
+
+@item EBUSY
+oldpath or newpath is a directory that is in use by some
+process.
+
+@item EINVAL
+An attempt was made to make a directory a subdirectory
+of itself.
+
+@item ENOTDIR
+A component used as a directory in oldpath or new
+path is not a directory. Or oldpath is a directory
+and newpath exists but is not a directory.
+
+@item EFAULT
+oldpathptr or newpathptr are invalid pointer values.
+
+@item EACCES
+No access to the file or the path of the file.
+
+@item ENAMETOOLONG
+
+oldpath or newpath was too long.
+
+@item ENOENT
+A directory component in oldpath or newpath does not exist.
+
+@item EROFS
+The file is on a read-only filesystem.
+
+@item ENOSPC
+The device containing the file has no room for the new
+directory entry.
+
+@item EINTR
+The call was interrupted by the user.
+@end table
+
+@node unlink
+@unnumberedsubsubsec unlink
+@cindex unlink, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+int unlink(const char *pathname);
+
+@exdent Request:
+Funlink,pathnameptr/len
+
+@exdent Return value:
+On success, zero is returned. On error, -1 is returned.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EACCES
+No access to the file or the path of the file.
+
+@item EPERM
+The system does not allow unlinking of directories.
+
+@item EBUSY
+The file pathname cannot be unlinked because it's
+being used by another process.
+
+@item EFAULT
+pathnameptr is an invalid pointer value.
+
+@item ENAMETOOLONG
+pathname was too long.
+
+@item ENOENT
+A directory component in pathname does not exist.
+
+@item ENOTDIR
+A component of the path is not a directory.
+
+@item EROFS
+The file is on a read-only filesystem.
+
+@item EINTR
+The call was interrupted by the user.
+@end table
+
+@node stat/fstat
+@unnumberedsubsubsec stat/fstat
+@cindex fstat, file-i/o system call
+@cindex stat, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+int stat(const char *pathname, struct stat *buf);
+int fstat(int fd, struct stat *buf);
+
+@exdent Request:
+Fstat,pathnameptr/len,bufptr
+Ffstat,fd,bufptr
+
+@exdent Return value:
+On success, zero is returned. On error, -1 is returned.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EBADF
+fd is not a valid open file.
+
+@item ENOENT
+A directory component in pathname does not exist or the
+path is an empty string.
+
+@item ENOTDIR
+A component of the path is not a directory.
+
+@item EFAULT
+pathnameptr is an invalid pointer value.
+
+@item EACCES
+No access to the file or the path of the file.
+
+@item ENAMETOOLONG
+pathname was too long.
+
+@item EINTR
+The call was interrupted by the user.
+@end table
+
+@node gettimeofday
+@unnumberedsubsubsec gettimeofday
+@cindex gettimeofday, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+int gettimeofday(struct timeval *tv, void *tz);
+
+@exdent Request:
+Fgettimeofday,tvptr,tzptr
+
+@exdent Return value:
+On success, 0 is returned, -1 otherwise.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EINVAL
+tz is a non-NULL pointer.
+
+@item EFAULT
+tvptr and/or tzptr is an invalid pointer value.
+@end table
+
+@node isatty
+@unnumberedsubsubsec isatty
+@cindex isatty, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+int isatty(int fd);
+
+@exdent Request:
+Fisatty,fd
+
+@exdent Return value:
+Returns 1 if fd refers to the @value{GDBN} console, 0 otherwise.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EINTR
+The call was interrupted by the user.
+@end table
+
+@node system
+@unnumberedsubsubsec system
+@cindex system, file-i/o system call
+
+@smallexample
+@exdent Synopsis:
+int system(const char *command);
+
+@exdent Request:
+Fsystem,commandptr/len
+
+@exdent Return value:
+The value returned is -1 on error and the return status
+of the command otherwise. Only the exit status of the
+command is returned, which is extracted from the hosts
+system return value by calling WEXITSTATUS(retval).
+In case /bin/sh could not be executed, 127 is returned.
+
+@exdent Errors:
+@end smallexample
+
+@table @code
+@item EINTR
+The call was interrupted by the user.
+@end table
+
+@node Protocol specific representation of datatypes
+@subsection Protocol specific representation of datatypes
+@cindex protocol specific representation of datatypes, in file-i/o protocol
+
+@menu
+* Integral datatypes::
+* Pointer values::
+* struct stat::
+* struct timeval::
+@end menu
+
+@node Integral datatypes
+@unnumberedsubsubsec Integral datatypes
+@cindex integral datatypes, in file-i/o protocol
+
+The integral datatypes used in the system calls are
+
+@smallexample
+int@r{,} unsigned int@r{,} long@r{,} unsigned long@r{,} mode_t @r{and} time_t
+@end smallexample
+
+@code{Int}, @code{unsigned int}, @code{mode_t} and @code{time_t} are
+implemented as 32 bit values in this protocol.
+
+@code{Long} and @code{unsigned long} are implemented as 64 bit types.
+
+@xref{Limits}, for corresponding MIN and MAX values (similar to those
+in @file{limits.h}) to allow range checking on host and target.
+
+@code{time_t} datatypes are defined as seconds since the Epoch.
+
+All integral datatypes transferred as part of a memory read or write of a
+structured datatype e.g.@: a @code{struct stat} have to be given in big endian
+byte order.
+
+@node Pointer values
+@unnumberedsubsubsec Pointer values
+@cindex pointer values, in file-i/o protocol
+
+Pointers to target data are transmitted as they are. An exception
+is made for pointers to buffers for which the length isn't
+transmitted as part of the function call, namely strings. Strings
+are transmitted as a pointer/length pair, both as hex values, e.g.@:
+
+@smallexample
+@code{1aaf/12}
+@end smallexample
+
+@noindent
+which is a pointer to data of length 18 bytes at position 0x1aaf.
+The length is defined as the full string length in bytes, including
+the trailing null byte. Example:
+
+@smallexample
+``hello, world'' at address 0x123456
+@end smallexample
+
+@noindent
+is transmitted as
+
+@smallexample
+@code{123456/d}
+@end smallexample
+
+@node struct stat
+@unnumberedsubsubsec struct stat
+@cindex struct stat, in file-i/o protocol
+
+The buffer of type struct stat used by the target and @value{GDBN} is defined
+as follows:
+
+@smallexample
+struct stat @{
+ unsigned int st_dev; /* device */
+ unsigned int st_ino; /* inode */
+ mode_t st_mode; /* protection */
+ unsigned int st_nlink; /* number of hard links */
+ unsigned int st_uid; /* user ID of owner */
+ unsigned int st_gid; /* group ID of owner */
+ unsigned int st_rdev; /* device type (if inode device) */
+ unsigned long st_size; /* total size, in bytes */
+ unsigned long st_blksize; /* blocksize for filesystem I/O */
+ unsigned long st_blocks; /* number of blocks allocated */
+ time_t st_atime; /* time of last access */
+ time_t st_mtime; /* time of last modification */
+ time_t st_ctime; /* time of last change */
+@};
+@end smallexample
+
+The integral datatypes are conforming to the definitions given in the
+approriate section (see @ref{Integral datatypes}, for details) so this
+structure is of size 64 bytes.
+
+The values of several fields have a restricted meaning and/or
+range of values.
+
+@smallexample
+st_dev: 0 file
+ 1 console
+
+st_ino: No valid meaning for the target. Transmitted unchanged.
+
+st_mode: Valid mode bits are described in Appendix C. Any other
+ bits have currently no meaning for the target.
+
+st_uid: No valid meaning for the target. Transmitted unchanged.
+
+st_gid: No valid meaning for the target. Transmitted unchanged.
+
+st_rdev: No valid meaning for the target. Transmitted unchanged.
+
+st_atime, st_mtime, st_ctime:
+ These values have a host and file system dependent
+ accuracy. Especially on Windows hosts the file systems
+ don't support exact timing values.
+@end smallexample
+
+The target gets a struct stat of the above representation and is
+responsible to coerce it to the target representation before
+continuing.
+
+Note that due to size differences between the host and target
+representation of stat members, these members could eventually
+get truncated on the target.
+
+@node struct timeval
+@unnumberedsubsubsec struct timeval
+@cindex struct timeval, in file-i/o protocol
+
+The buffer of type struct timeval used by the target and @value{GDBN}
+is defined as follows:
+
+@smallexample
+struct timeval @{
+ time_t tv_sec; /* second */
+ long tv_usec; /* microsecond */
+@};
+@end smallexample
+
+The integral datatypes are conforming to the definitions given in the
+approriate section (see @ref{Integral datatypes}, for details) so this
+structure is of size 8 bytes.
+
+@node Constants
+@subsection Constants
+@cindex constants, in file-i/o protocol
+
+The following values are used for the constants inside of the
+protocol. @value{GDBN} and target are resposible to translate these
+values before and after the call as needed.
+
+@menu
+* Open flags::
+* mode_t values::
+* Errno values::
+* Lseek flags::
+* Limits::
+@end menu
+
+@node Open flags
+@unnumberedsubsubsec Open flags
+@cindex open flags, in file-i/o protocol
+
+All values are given in hexadecimal representation.
+
+@smallexample
+ O_RDONLY 0x0
+ O_WRONLY 0x1
+ O_RDWR 0x2
+ O_APPEND 0x8
+ O_CREAT 0x200
+ O_TRUNC 0x400
+ O_EXCL 0x800
+@end smallexample
+
+@node mode_t values
+@unnumberedsubsubsec mode_t values
+@cindex mode_t values, in file-i/o protocol
+
+All values are given in octal representation.
+
+@smallexample
+ S_IFREG 0100000
+ S_IFDIR 040000
+ S_IRUSR 0400
+ S_IWUSR 0200
+ S_IXUSR 0100
+ S_IRGRP 040
+ S_IWGRP 020
+ S_IXGRP 010
+ S_IROTH 04
+ S_IWOTH 02
+ S_IXOTH 01
+@end smallexample
+
+@node Errno values
+@unnumberedsubsubsec Errno values
+@cindex errno values, in file-i/o protocol
+
+All values are given in decimal representation.
+
+@smallexample
+ EPERM 1
+ ENOENT 2
+ EINTR 4
+ EBADF 9
+ EACCES 13
+ EFAULT 14
+ EBUSY 16
+ EEXIST 17
+ ENODEV 19
+ ENOTDIR 20
+ EISDIR 21
+ EINVAL 22
+ ENFILE 23
+ EMFILE 24
+ EFBIG 27
+ ENOSPC 28
+ ESPIPE 29
+ EROFS 30
+ ENAMETOOLONG 91
+ EUNKNOWN 9999
+@end smallexample
+
+ EUNKNOWN is used as a fallback error value if a host system returns
+ any error value not in the list of supported error numbers.
+
+@node Lseek flags
+@unnumberedsubsubsec Lseek flags
+@cindex lseek flags, in file-i/o protocol
+
+@smallexample
+ SEEK_SET 0
+ SEEK_CUR 1
+ SEEK_END 2
+@end smallexample
+
+@node Limits
+@unnumberedsubsubsec Limits
+@cindex limits, in file-i/o protocol
+
+All values are given in decimal representation.
+
+@smallexample
+ INT_MIN -2147483648
+ INT_MAX 2147483647
+ UINT_MAX 4294967295
+ LONG_MIN -9223372036854775808
+ LONG_MAX 9223372036854775807
+ ULONG_MAX 18446744073709551615
+@end smallexample
+
+@node File-I/O Examples
+@subsection File-I/O Examples
+@cindex file-i/o examples
+
+Example sequence of a write call, file descriptor 3, buffer is at target
+address 0x1234, 6 bytes should be written:
+
+@smallexample
+<- @code{Fwrite,3,1234,6}
+@emph{request memory read from target}
+-> @code{m1234,6}
+<- XXXXXX
+@emph{return "6 bytes written"}
+-> @code{F6}
+@end smallexample
+
+Example sequence of a read call, file descriptor 3, buffer is at target
+address 0x1234, 6 bytes should be read:
+
+@smallexample
+<- @code{Fread,3,1234,6}
+@emph{request memory write to target}
+-> @code{X1234,6:XXXXXX}
+@emph{return "6 bytes read"}
+-> @code{F6}
+@end smallexample
+
+Example sequence of a read call, call fails on the host due to invalid
+file descriptor (EBADF):
+
+@smallexample
+<- @code{Fread,3,1234,6}
+-> @code{F-1,9}
+@end smallexample
+
+Example sequence of a read call, user presses Ctrl-C before syscall on
+host is called:
+
+@smallexample
+<- @code{Fread,3,1234,6}
+-> @code{F-1,4,C}
+<- @code{T02}
+@end smallexample
+
+Example sequence of a read call, user presses Ctrl-C after syscall on
+host is called:
+
+@smallexample
+<- @code{Fread,3,1234,6}
+-> @code{X1234,6:XXXXXX}
+<- @code{T02}
+@end smallexample
+
+@include agentexpr.texi
@include gpl.texi
+@raisesections
@include fdl.texi
+@lowersections
@node Index
@unnumbered Index
diff --git a/contrib/gdb/gdb/doc/stabs.texinfo b/contrib/gdb/gdb/doc/stabs.texinfo
index 2a14dcc..d43ef37 100644
--- a/contrib/gdb/gdb/doc/stabs.texinfo
+++ b/contrib/gdb/gdb/doc/stabs.texinfo
@@ -3,13 +3,12 @@
@c @finalout
-@ifinfo
-@format
-START-INFO-DIR-ENTRY
-* Stabs: (stabs). The "stabs" debugging information format.
-END-INFO-DIR-ENTRY
-@end format
-@end ifinfo
+@c This is a dir.info fragment to support semi-automated addition of
+@c manuals to an info tree.
+@dircategory Software development
+@direntry
+* Stabs: (stabs). The "stabs" debugging information format.
+@end direntry
@ifinfo
This document describes the stabs debugging symbol tables.
@@ -22,12 +21,9 @@ and David MacKenzie.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
-and with the Back-Cover Texts as in (a) below.
-
-(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
-this GNU Manual, like GNU software. Copies published by the Free
-Software Foundation raise funds for GNU development.''
+Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
+Texts. A copy of the license is included in the section entitled ``GNU
+Free Documentation License''.
@end ifinfo
@setchapternewpage odd
@@ -54,13 +50,9 @@ Contributed by Cygnus Support.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
-and with the Back-Cover Texts as in (a) below.
-
-(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
-this GNU Manual, like GNU software. Copies published by the Free
-Software Foundation raise funds for GNU development.''
-
+Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
+Texts. A copy of the license is included in the section entitled ``GNU
+Free Documentation License''.
@end titlepage
@ifinfo
@@ -85,6 +77,7 @@ This document describes the stabs debugging format.
* Stab Sections:: In some object file formats, stabs are
in sections.
* Symbol Types Index:: Index of symbolic stab symbol type names.
+* GNU Free Documentation License:: The license for this documentation
@end menu
@end ifinfo
@@ -259,10 +252,10 @@ There is an AIX extension for type attributes. Following the @samp{=}
are any number of type attributes. Each one starts with @samp{@@} and
ends with @samp{;}. Debuggers, including AIX's dbx and GDB 4.10, skip
any type attributes they do not recognize. GDB 4.9 and other versions
-of dbx may not do this. Because of a conflict with C++
+of dbx may not do this. Because of a conflict with C@t{++}
(@pxref{Cplusplus}), new attributes should not be defined which begin
with a digit, @samp{(}, or @samp{-}; GDB may be unable to distinguish
-those from the C++ type descriptor @samp{@@}. The attributes are:
+those from the C@t{++} type descriptor @samp{@@}. The attributes are:
@table @code
@item a@var{boundary}
@@ -287,6 +280,12 @@ Indicate that this type is a string instead of an array of characters,
or a bitstring instead of a set. It doesn't change the layout of the
data being represented, but does enable the debugger to know which type
it is.
+
+@item V
+Indicate that this type is a vector instead of an array. The only
+major difference between vectors and arrays is that vectors are
+passed by value instead of by reference (vector coprocessor extension).
+
@end table
All of this can make the string field quite long. All versions of GDB,
@@ -431,7 +430,7 @@ Some compilers (for example, GCC2 and SunOS4 @file{/bin/cc}) also
include the directory in which the source was compiled, in a second
@code{N_SO} symbol preceding the one containing the file name. This
symbol can be distinguished by the fact that it ends in a slash. Code
-from the @code{cfront} C++ compiler can have additional @code{N_SO} symbols for
+from the @code{cfront} C@t{++} compiler can have additional @code{N_SO} symbols for
nonexistent source files after the @code{N_SO} for the real source file;
these are believed to contain no useful information.
@@ -1766,7 +1765,7 @@ Another way is with the @samp{x} type descriptor, which is followed by
@samp{s} for a structure tag, @samp{u} for a union tag, or @samp{e} for
a enumerator tag, followed by the name of the tag, followed by @samp{:}.
If the name contains @samp{::} between a @samp{<} and @samp{>} pair (for
-C++ templates), such a @samp{::} does not end the name---only a single
+C@t{++} templates), such a @samp{::} does not end the name---only a single
@samp{:} ends the name; see @ref{Nested Symbols}.
For example, the following C declarations:
@@ -2041,8 +2040,9 @@ definition narrows the symbol type to structure.
Following the @samp{s} type descriptor is the number of bytes the
structure occupies, followed by a description of each structure element.
-The structure element descriptions are of the form @var{name:type, bit
-offset from the start of the struct, number of bits in the element}.
+The structure element descriptions are of the form
+@samp{@var{name}:@var{type}, @var{bit offset from the start of the
+struct}, @var{number of bits in the element}}.
@c FIXME: phony line break. Can probably be fixed by using an example
@c with fewer fields.
@@ -2062,13 +2062,13 @@ The @code{s_next} field is a pointer to the same kind of structure that
the field is an element of. So the definition of structure type 16
contains a type definition for an element which is a pointer to type 16.
-If a field is a static member (this is a C++ feature in which a single
+If a field is a static member (this is a C@t{++} feature in which a single
variable appears to be a field of every structure of a given type) it
still starts out with the field name, a colon, and the type, but then
instead of a comma, bit position, comma, and bit size, there is a colon
followed by the name of the variable which each such field refers to.
-If the structure has methods (a C++ feature), they follow the non-method
+If the structure has methods (a C@t{++} feature), they follow the non-method
fields; see @ref{Cplusplus}.
@node Typedefs
@@ -2140,8 +2140,8 @@ the stab describes an enumeration, structure, or union tag. The type
descriptor @samp{u}, following the @samp{23=} of the type definition,
narrows it down to a union type definition. Following the @samp{u} is
the number of bytes in the union. After that is a list of union element
-descriptions. Their format is @var{name:type, bit offset into the
-union, number of bytes for the element;}.
+descriptions. Their format is @samp{@var{name}:@var{type}, @var{bit
+offset into the union}, @var{number of bytes for the element};}.
The stab for the union variable is:
@@ -2389,7 +2389,7 @@ Symnum n_type n_othr n_desc n_value n_strx String
@end example
@node Cplusplus
-@chapter GNU C++ Stabs
+@chapter GNU C@t{++} Stabs
@menu
* Class Names:: C++ class names are both tags and typedefs.
@@ -2409,9 +2409,9 @@ Symnum n_type n_othr n_desc n_value n_strx String
@end menu
@node Class Names
-@section C++ Class Names
+@section C@t{++} Class Names
-In C++, a class name which is declared with @code{class}, @code{struct},
+In C@t{++}, a class name which is declared with @code{class}, @code{struct},
or @code{union}, is not only a tag, as in C, but also a type name. Thus
there should be stabs with both @samp{t} and @samp{T} symbol descriptors
(@pxref{Typedefs}).
@@ -2420,7 +2420,7 @@ To save space, there is a special abbreviation for this case. If the
@samp{T} symbol descriptor is followed by @samp{t}, then the stab
defines both a type name and a tag.
-For example, the C++ code
+For example, the C@t{++} code
@example
struct foo @{int x;@};
@@ -2442,7 +2442,7 @@ or
@node Nested Symbols
@section Defining a Symbol Within Another Type
-In C++, a symbol (such as a type name) can be defined within another type.
+In C@t{++}, a symbol (such as a type name) can be defined within another type.
@c FIXME: Needs example.
In stabs, this is sometimes represented by making the name of a symbol
@@ -2457,12 +2457,12 @@ then @code{foo::bar::baz} is the name of the symbol, @samp{t} is the
symbol descriptor, and @samp{5=*6} is the type information.
@node Basic Cplusplus Types
-@section Basic Types For C++
+@section Basic Types For C@t{++}
<< the examples that follow are based on a01.C >>
-C++ adds two more builtin types to the set defined for C. These are
+C@t{++} adds two more builtin types to the set defined for C. These are
the unknown type and the vtable record type. The unknown type, type
16, is defined in terms of itself like the void type.
@@ -2473,7 +2473,7 @@ pfn, and delta2. pfn is the function pointer.
<< In boilerplate $vtbl_ptr_type, what are the fields delta,
index, and delta2 used for? >>
-This basic type is present in all C++ programs even if there are no
+This basic type is present in all C@t{++} programs even if there are no
virtual methods defined.
@display
@@ -2503,8 +2503,8 @@ virtual methods defined.
@node Simple Classes
@section Simple Class Definition
-The stabs describing C++ language features are an extension of the
-stabs describing C. Stabs representing C++ class types elaborate
+The stabs describing C@t{++} language features are an extension of the
+stabs describing C. Stabs representing C@t{++} class types elaborate
extensively on the stab format used to describe structure types in C.
Stabs representing class type variables look just like stabs
representing C language variables.
@@ -2526,20 +2526,20 @@ stab is not located between an @code{N_FUN} and an @code{N_LBRAC} stab this indi
that the class is defined at file scope. If it were, then the @code{N_LSYM}
would signify a local variable.
-A stab describing a C++ class type is similar in format to a stab
+A stab describing a C@t{++} class type is similar in format to a stab
describing a C struct, with each class member shown as a field in the
structure. The part of the struct format describing fields is
-expanded to include extra information relevant to C++ class members.
+expanded to include extra information relevant to C@t{++} class members.
In addition, if the class has multiple base classes or virtual
functions the struct format outside of the field parts is also
augmented.
-In this simple example the field part of the C++ class stab
+In this simple example the field part of the C@t{++} class stab
representing member data looks just like the field part of a C struct
stab. The section on protections describes how its format is
sometimes extended for member data.
-The field part of a C++ class stab representing a member function
+The field part of a C@t{++} class stab representing a member function
differs substantially from the field part of a C struct stab. It
still begins with @samp{name:} but then goes on to define a new type number
for the member function, describe its return type, its argument types,
@@ -2566,7 +2566,7 @@ occur in the @var{operator-name} string.
The next part of the method description represents the arguments to the
method, preceded by a colon and ending with a semi-colon. The types of
the arguments are expressed in the same way argument types are expressed
-in C++ name mangling. In this example an @code{int} and a @code{char}
+in C@t{++} name mangling. In this example an @code{int} and a @code{char}
map to @samp{ic}.
This is followed by a number, a letter, and an asterisk or period,
@@ -2600,7 +2600,7 @@ information present for virtual methods.
@node Class Instance
@section Class Instance
-As shown above, describing even a simple C++ class definition is
+As shown above, describing even a simple C@t{++} class definition is
accomplished by massively extending the stab format used in C to
describe structure types. However, once the class is defined, C stabs
with no modifications can be used to describe class instances. The
@@ -2627,7 +2627,7 @@ different from a standard C stab describing a local variable.
@node Methods
@section Method Definition
-The class definition shown above declares Ameth. The C++ source below
+The class definition shown above declares Ameth. The C@t{++} source below
defines Ameth:
@example
@@ -2718,15 +2718,26 @@ compiler it can also be used in other contexts.
@node Member Type Descriptor
@section The @samp{@@} Type Descriptor
-The @samp{@@} type descriptor is for a member (class and variable) type.
-It is followed by type information for the offset basetype, a comma, and
-type information for the type of the field being pointed to. (FIXME:
-this is acknowledged to be gibberish. Can anyone say what really goes
-here?).
+The @samp{@@} type descriptor is used together with the @samp{*} type
+descriptor for a pointer-to-non-static-member-data type. It is followed
+by type information for the class (or union), a comma, and type
+information for the member data.
+
+The following C@t{++} source:
+
+@smallexample
+typedef int A::*int_in_a;
+@end smallexample
+
+generates the following stab:
+
+@smallexample
+.stabs "int_in_a:t20=*21=@@19,1",128,0,0,0
+@end smallexample
Note that there is a conflict between this and type attributes
(@pxref{String Field}); both use type descriptor @samp{@@}.
-Fortunately, the @samp{@@} type descriptor used in this C++ sense always
+Fortunately, the @samp{@@} type descriptor used in this C@t{++} sense always
will be followed by a digit, @samp{(}, or @samp{-}, and type attributes
never start with those things.
@@ -2736,7 +2747,7 @@ never start with those things.
In the simple class definition shown above all member data and
functions were publicly accessible. The example that follows
contrasts public, protected and privately accessible fields and shows
-how these protections are encoded in C++ stabs.
+how these protections are encoded in C@t{++} stabs.
If the character following the @samp{@var{field-name}:} part of the
string is @samp{/}, then the next character is the visibility. @samp{0}
@@ -2750,7 +2761,7 @@ an optimized out field with a private or protected visibility).
Visibility @samp{9} is not supported by GDB 4.11; this should be fixed
in the next GDB release.
-The following C++ source:
+The following C@t{++} source:
@example
class vis @{
@@ -2780,7 +2791,7 @@ type float (@samp{12}), and offset and size @samp{,64,32;}.
Protections for member functions are signified by one digit embedded in
the field part of the stab describing the method. The digit is 0 if
-private, 1 if protected and 2 if public. Consider the C++ class
+private, 1 if protected and 2 if public. Consider the C@t{++} class
definition below:
@example
@@ -2878,7 +2889,7 @@ struct is @samp{Adat}, an integer, starting at structure offset 0 and
occupying 32 bits.
The second field in the class struct is not explicitly defined by the
-C++ class definition but is implied by the fact that the class
+C@t{++} class definition but is implied by the fact that the class
contains a virtual method. This field is the vtable pointer. The
name of the vtable pointer field starts with @samp{$vf} and continues with a
type reference to the class it is part of. In this example the type
@@ -2890,7 +2901,7 @@ This is in turn defined as a pointer to another new type (22).
Type 22 is the vtable itself, which is defined as an array, indexed by
a range of integers between 0 and 1, and whose elements are of type
-17. Type 17 was the vtable record type defined by the boilerplate C++
+17. Type 17 was the vtable record type defined by the boilerplate C@t{++}
type definitions, as shown earlier.
The bit offset of the vtable pointer field is 32. The number of bits
@@ -2944,7 +2955,7 @@ class. This is preceded by @samp{~%} and followed by a final semi-colon.
@node Inheritance
@section Inheritance
-Stabs describing C++ derived classes include additional sections that
+Stabs describing C@t{++} derived classes include additional sections that
describe the inheritance hierarchy of the class. A derived class stab
also encodes the number of base classes. For each base class it tells
if the base class is virtual or not, and if the inheritance is private
@@ -3275,13 +3286,13 @@ GNU Modula2 definition module dependency; see @ref{N_DEFD}.
Function start/body/end line numbers (Solaris2).
@item 0x50 N_EHDECL
-GNU C++ exception variable; see @ref{N_EHDECL}.
+GNU C@t{++} exception variable; see @ref{N_EHDECL}.
@item 0x50 N_MOD2
Modula2 info "for imc" (according to Ultrix V4.0); see @ref{N_MOD2}.
@item 0x54 N_CATCH
-GNU C++ @code{catch} clause; see @ref{N_CATCH}.
+GNU C@t{++} @code{catch} clause; see @ref{N_CATCH}.
@item 0x60 N_SSYM
Structure of union element; see @ref{N_SSYM}.
@@ -3375,7 +3386,7 @@ for more information about their use.
Variable on the stack; see @ref{Stack Variables}.
@item :
-C++ nested symbol; see @xref{Nested Symbols}.
+C@t{++} nested symbol; see @xref{Nested Symbols}.
@item a
Parameter passed by reference in register; see @ref{Reference Parameters}.
@@ -3388,7 +3399,7 @@ Constant; see @ref{Constants}.
@item C
Conformant array bound (Pascal, maybe other languages); @ref{Conformant
-Arrays}. Name of a caught exception (GNU C++). These can be
+Arrays}. Name of a caught exception (GNU C@t{++}). These can be
distinguished because the latter uses @code{N_CATCH} and the former uses
another symbol type.
@@ -3489,17 +3500,17 @@ Type reference; see @ref{String Field}.
Reference to builtin type; see @ref{Negative Type Numbers}.
@item #
-Method (C++); see @ref{Method Type Descriptor}.
+Method (C@t{++}); see @ref{Method Type Descriptor}.
@item *
Pointer; see @ref{Miscellaneous Types}.
@item &
-Reference (C++).
+Reference (C@t{++}).
@item @@
Type Attributes (AIX); see @ref{String Field}. Member (class and variable)
-type (GNU C++); see @ref{Member Type Descriptor}.
+type (GNU C@t{++}); see @ref{Member Type Descriptor}.
@item a
Array; see @ref{Arrays}.
@@ -3604,7 +3615,7 @@ Wide character; see @ref{Builtin Type Descriptors}.
Cross-reference; see @ref{Cross-References}.
@item Y
-Used by IBM's xlC C++ compiler (for structures, I think).
+Used by IBM's xlC C@t{++} compiler (for structures, I think).
@item z
gstring; see @ref{Strings}.
@@ -3746,7 +3757,7 @@ if it is imported with the GNU M2 keyword @code{%INITIALIZE}. Perhaps
@deffn @code{.stabs} N_EHDECL
@findex N_EHDECL
-GNU C++ exception variable <<?>>.
+GNU C@t{++} exception variable <<?>>.
"@var{string} is variable name"
@@ -3768,9 +3779,9 @@ Note: conflicts with @code{N_EHDECL} <<?>>
@deffn @code{.stabn} N_CATCH
@findex N_CATCH
-GNU C++ @code{catch} clause
+GNU C@t{++} @code{catch} clause
-GNU C++ @code{catch} clause. The value is its address. The desc field
+GNU C@t{++} @code{catch} clause. The value is its address. The desc field
is nonzero if this entry is immediately followed by a @code{CAUGHT} stab
saying what exception was caught. Multiple @code{CAUGHT} stabs means
that multiple exceptions can be caught here. If desc is 0, it means all
@@ -4015,6 +4026,10 @@ is no more work than having the linker relocate ELF symbols, and it
solves the problem of having to associate the ELF and stab symbols.
However, no one has yet designed or implemented such a scheme.
+@raisesections
+@include fdl.texi
+@lowersections
+
@node Symbol Types Index
@unnumbered Symbol Types Index
diff --git a/contrib/gdb/gdb/exec.c b/contrib/gdb/gdb/exec.c
index b07175e..418b0b3 100644
--- a/contrib/gdb/gdb/exec.c
+++ b/contrib/gdb/gdb/exec.c
@@ -1,7 +1,8 @@
/* Work with executable files, for GDB.
- Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
+ Inc.
This file is part of GDB.
@@ -30,12 +31,14 @@
#include "objfiles.h"
#include "completer.h"
#include "value.h"
+#include "exec.h"
#ifdef USG
#include <sys/types.h>
#endif
#include <fcntl.h>
+#include "readline/readline.h"
#include "gdb_string.h"
#include "gdbcore.h"
@@ -54,8 +57,6 @@ void (*file_changed_hook) (char *);
/* Prototypes for local functions */
-static void add_to_section_table (bfd *, sec_ptr, PTR);
-
static void exec_close (int);
static void file_command (char *, int);
@@ -64,8 +65,6 @@ static void set_section_command (char *, int);
static void exec_files_info (struct target_ops *);
-static void bfdsec_to_vmap (bfd *, sec_ptr, PTR);
-
static int ignore (CORE_ADDR, char *);
static void init_exec_ops (void);
@@ -84,14 +83,6 @@ bfd *exec_bfd = NULL;
int write_files = 0;
-/* Text start and end addresses (KLUDGE) if needed */
-
-#ifndef NEED_TEXT_START_END
-#define NEED_TEXT_START_END (0)
-#endif
-CORE_ADDR text_start = 0;
-CORE_ADDR text_end = 0;
-
struct vmap *vmap;
void
@@ -101,7 +92,6 @@ exec_open (char *args, int from_tty)
exec_file_attach (args, from_tty);
}
-/* ARGSUSED */
static void
exec_close (int quitting)
{
@@ -242,7 +232,7 @@ exec_file_attach (char *filename, int from_tty)
/* FIXME - This should only be run for RS6000, but the ifdef is a poor
way to accomplish. */
-#ifdef IBM6000_TARGET
+#ifdef DEPRECATED_IBM6000_TARGET
/* Setup initial vmap. */
map_vmap (exec_bfd, 0);
@@ -254,7 +244,7 @@ exec_file_attach (char *filename, int from_tty)
error ("\"%s\": can't find the file sections: %s",
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
-#endif /* IBM6000_TARGET */
+#endif /* DEPRECATED_IBM6000_TARGET */
if (build_section_table (exec_bfd, &exec_ops.to_sections,
&exec_ops.to_sections_end))
@@ -266,30 +256,9 @@ exec_file_attach (char *filename, int from_tty)
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
- /* text_end is sometimes used for where to put call dummies. A
- few ports use these for other purposes too. */
- if (NEED_TEXT_START_END)
- {
- struct section_table *p;
-
- /* Set text_start to the lowest address of the start of any
- readonly code section and set text_end to the highest
- address of the end of any readonly code section. */
- /* FIXME: The comment above does not match the code. The
- code checks for sections with are either code *or*
- readonly. */
- text_start = ~(CORE_ADDR) 0;
- text_end = (CORE_ADDR) 0;
- for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
- if (bfd_get_section_flags (p->bfd, p->the_bfd_section)
- & (SEC_CODE | SEC_READONLY))
- {
- if (text_start > p->addr)
- text_start = p->addr;
- if (text_end < p->endaddr)
- text_end = p->endaddr;
- }
- }
+#ifdef DEPRECATED_HPUX_TEXT_END
+ DEPRECATED_HPUX_TEXT_END (&exec_ops);
+#endif
validate_files ();
@@ -365,7 +334,8 @@ file_command (char *arg, int from_tty)
we cast it back to its proper type. */
static void
-add_to_section_table (bfd *abfd, sec_ptr asect, PTR table_pp_char)
+add_to_section_table (bfd *abfd, struct bfd_section *asect,
+ void *table_pp_char)
{
struct section_table **table_pp = (struct section_table **) table_pp_char;
flagword aflag;
@@ -386,7 +356,7 @@ add_to_section_table (bfd *abfd, sec_ptr asect, PTR table_pp_char)
Returns 0 if OK, 1 on error. */
int
-build_section_table (bfd *some_bfd, struct section_table **start,
+build_section_table (struct bfd *some_bfd, struct section_table **start,
struct section_table **end)
{
unsigned count;
@@ -404,7 +374,7 @@ build_section_table (bfd *some_bfd, struct section_table **start,
}
static void
-bfdsec_to_vmap (bfd *abfd, sec_ptr sect, PTR arg3)
+bfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3)
{
struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3;
struct vmap *vp;
@@ -414,14 +384,14 @@ bfdsec_to_vmap (bfd *abfd, sec_ptr sect, PTR arg3)
if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0)
return;
- if (STREQ (bfd_section_name (abfd, sect), ".text"))
+ if (DEPRECATED_STREQ (bfd_section_name (abfd, sect), ".text"))
{
vp->tstart = bfd_section_vma (abfd, sect);
vp->tend = vp->tstart + bfd_section_size (abfd, sect);
vp->tvma = bfd_section_vma (abfd, sect);
vp->toffs = sect->filepos;
}
- else if (STREQ (bfd_section_name (abfd, sect), ".data"))
+ else if (DEPRECATED_STREQ (bfd_section_name (abfd, sect), ".data"))
{
vp->dstart = bfd_section_vma (abfd, sect);
vp->dend = vp->dstart + bfd_section_size (abfd, sect);
@@ -481,10 +451,9 @@ xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
struct mem_attrib *attrib,
struct target_ops *target)
{
- boolean res;
+ int res;
struct section_table *p;
CORE_ADDR nextsectaddr, memend;
- boolean (*xfer_fn) (bfd *, sec_ptr, PTR, file_ptr, bfd_size_type);
asection *section = NULL;
if (len <= 0)
@@ -498,7 +467,6 @@ xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
}
memend = memaddr + len;
- xfer_fn = write ? bfd_set_section_contents : bfd_get_section_contents;
nextsectaddr = memend;
for (p = target->to_sections; p < target->to_sections_end; p++)
@@ -507,26 +475,40 @@ xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
strcmp (section->name, p->the_bfd_section->name) != 0)
continue; /* not the section we need */
if (memaddr >= p->addr)
- if (memend <= p->endaddr)
- {
- /* Entire transfer is within this section. */
- res = xfer_fn (p->bfd, p->the_bfd_section, myaddr,
- memaddr - p->addr, len);
- return (res != 0) ? len : 0;
- }
- else if (memaddr >= p->endaddr)
- {
- /* This section ends before the transfer starts. */
- continue;
- }
- else
- {
- /* This section overlaps the transfer. Just do half. */
- len = p->endaddr - memaddr;
- res = xfer_fn (p->bfd, p->the_bfd_section, myaddr,
- memaddr - p->addr, len);
- return (res != 0) ? len : 0;
- }
+ {
+ if (memend <= p->endaddr)
+ {
+ /* Entire transfer is within this section. */
+ if (write)
+ res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
+ myaddr, memaddr - p->addr,
+ len);
+ else
+ res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
+ myaddr, memaddr - p->addr,
+ len);
+ return (res != 0) ? len : 0;
+ }
+ else if (memaddr >= p->endaddr)
+ {
+ /* This section ends before the transfer starts. */
+ continue;
+ }
+ else
+ {
+ /* This section overlaps the transfer. Just do half. */
+ len = p->endaddr - memaddr;
+ if (write)
+ res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
+ myaddr, memaddr - p->addr,
+ len);
+ else
+ res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
+ myaddr, memaddr - p->addr,
+ len);
+ return (res != 0) ? len : 0;
+ }
+ }
else
nextsectaddr = min (nextsectaddr, p->addr);
}
@@ -542,6 +524,8 @@ void
print_section_info (struct target_ops *t, bfd *abfd)
{
struct section_table *p;
+ /* FIXME: "016l" is not wide enough when TARGET_ADDR_BIT > 64. */
+ char *fmt = TARGET_ADDR_BIT <= 32 ? "08l" : "016l";
printf_filtered ("\t`%s', ", bfd_get_filename (abfd));
wrap_here (" ");
@@ -554,12 +538,17 @@ print_section_info (struct target_ops *t, bfd *abfd)
}
for (p = t->to_sections; p < t->to_sections_end; p++)
{
- /* FIXME-32x64 need a print_address_numeric with field width */
- printf_filtered ("\t%s", local_hex_string_custom ((unsigned long) p->addr, "08l"));
- printf_filtered (" - %s", local_hex_string_custom ((unsigned long) p->endaddr, "08l"));
+ printf_filtered ("\t%s", local_hex_string_custom (p->addr, fmt));
+ printf_filtered (" - %s", local_hex_string_custom (p->endaddr, fmt));
+
+ /* FIXME: A format of "08l" is not wide enough for file offsets
+ larger than 4GB. OTOH, making it "016l" isn't desirable either
+ since most output will then be much wider than necessary. It
+ may make sense to test the size of the file and choose the
+ format string accordingly. */
if (info_verbose)
printf_filtered (" @ %s",
- local_hex_string_custom ((unsigned long) p->the_bfd_section->filepos, "08l"));
+ local_hex_string_custom (p->the_bfd_section->filepos, "08l"));
printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section));
if (p->bfd != abfd)
{
@@ -712,14 +701,11 @@ Specify the filename of the executable file.";
exec_ops.to_open = exec_open;
exec_ops.to_close = exec_close;
exec_ops.to_attach = find_default_attach;
- exec_ops.to_require_attach = find_default_require_attach;
- exec_ops.to_require_detach = find_default_require_detach;
exec_ops.to_xfer_memory = xfer_memory;
exec_ops.to_files_info = exec_files_info;
exec_ops.to_insert_breakpoint = ignore;
exec_ops.to_remove_breakpoint = ignore;
exec_ops.to_create_inferior = find_default_create_inferior;
- exec_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
exec_ops.to_stratum = file_stratum;
exec_ops.to_has_memory = 1;
exec_ops.to_make_corefile_notes = exec_make_note_section;
@@ -742,7 +728,7 @@ and it is the program executed when you use the `run' command.\n\
If FILE cannot be found as specified, your execution directory path\n\
($PATH) is searched for a command of that name.\n\
No arg means to have no executable file and no symbols.", &cmdlist);
- c->completer = filename_completer;
+ set_cmd_completer (c, filename_completer);
}
c = add_cmd ("exec-file", class_files, exec_file_command,
@@ -750,7 +736,7 @@ No arg means to have no executable file and no symbols.", &cmdlist);
If FILE cannot be found as specified, your execution directory path\n\
is searched for a command of that name.\n\
No arg means have no executable file.", &cmdlist);
- c->completer = filename_completer;
+ set_cmd_completer (c, filename_completer);
add_com ("section", class_files, set_section_command,
"Change the base address of section SECTION of the exec file to ADDR.\n\
diff --git a/contrib/gdb/gdb/gdbserver/gdbreplay.c b/contrib/gdb/gdb/gdbserver/gdbreplay.c
index 8c57906..7c9064b 100644
--- a/contrib/gdb/gdb/gdbserver/gdbreplay.c
+++ b/contrib/gdb/gdb/gdbserver/gdbreplay.c
@@ -1,5 +1,5 @@
/* Replay a remote debug session logfile for GDB.
- Copyright 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright 1996, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
Written by Fred Fish (fnf@cygnus.com) from pieces of gdbserver.
This file is part of GDB.
@@ -54,14 +54,15 @@ static void
perror_with_name (char *string)
{
#ifndef STDC_HEADERS
- extern int sys_nerr;
- extern char *sys_errlist[];
extern int errno;
#endif
const char *err;
char *combined;
- err = (errno < sys_nerr) ? sys_errlist[errno] : "unknown error";
+ err = strerror (errno);
+ if (err == NULL)
+ err = "unknown error";
+
combined = (char *) alloca (strlen (err) + strlen (string) + 3);
strcpy (combined, string);
strcat (combined, ": ");
@@ -93,10 +94,6 @@ remote_close (void)
static void
remote_open (char *name)
{
-#ifndef HAVE_STRING_H
- extern char *strchr ();
-#endif
-
if (!strchr (name, ':'))
{
fprintf (stderr, "%s: Must specify tcp connection as host:addr\n", name);
diff --git a/contrib/gdb/gdb/gdbserver/utils.c b/contrib/gdb/gdb/gdbserver/utils.c
index a8ea9a1..44bdccf 100644
--- a/contrib/gdb/gdb/gdbserver/utils.c
+++ b/contrib/gdb/gdb/gdbserver/utils.c
@@ -1,5 +1,5 @@
/* General utility routines for the remote server for GDB.
- Copyright 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002
+ Copyright 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002, 2003
Free Software Foundation, Inc.
This file is part of GDB.
@@ -33,16 +33,13 @@ void
perror_with_name (char *string)
{
#ifndef STDC_HEADERS
- extern int sys_nerr;
- extern char *sys_errlist[];
extern int errno;
#endif
const char *err;
char *combined;
- if (errno < sys_nerr)
- err = sys_errlist[errno];
- else
+ err = strerror (errno);
+ if (err == NULL)
err = "unknown error";
combined = (char *) alloca (strlen (err) + strlen (string) + 3);
@@ -57,7 +54,7 @@ perror_with_name (char *string)
STRING is the error message, used as a fprintf string,
and ARG is passed as an argument to it. */
-NORETURN void
+void
error (const char *string,...)
{
extern jmp_buf toplevel;
@@ -74,7 +71,7 @@ error (const char *string,...)
STRING and ARG are passed to fprintf. */
/* VARARGS */
-NORETURN void
+void
fatal (const char *string,...)
{
va_list args;
diff --git a/contrib/gdb/gdb/i386-tdep.c b/contrib/gdb/gdb/i386-tdep.c
index b2ddd28..e1ce81f 100644
--- a/contrib/gdb/gdb/i386-tdep.c
+++ b/contrib/gdb/gdb/i386-tdep.c
@@ -1,7 +1,8 @@
/* Intel 386 target-dependent stuff.
- Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001
- Free Software Foundation, Inc.
+
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
This file is part of GDB.
@@ -21,30 +22,38 @@
Boston, MA 02111-1307, USA. */
#include "defs.h"
-#include "gdb_string.h"
+#include "arch-utils.h"
+#include "command.h"
+#include "dummy-frame.h"
+#include "dwarf2-frame.h"
+#include "doublest.h"
+#include "floatformat.h"
#include "frame.h"
+#include "frame-base.h"
+#include "frame-unwind.h"
#include "inferior.h"
-#include "gdbcore.h"
-#include "target.h"
-#include "floatformat.h"
-#include "symtab.h"
#include "gdbcmd.h"
-#include "command.h"
-#include "arch-utils.h"
+#include "gdbcore.h"
+#include "objfiles.h"
+#include "osabi.h"
#include "regcache.h"
-#include "doublest.h"
+#include "reggroups.h"
+#include "regset.h"
+#include "symfile.h"
+#include "symtab.h"
+#include "target.h"
#include "value.h"
-#include "gdb_assert.h"
+#include "dis-asm.h"
-#include "elf-bfd.h"
+#include "gdb_assert.h"
+#include "gdb_string.h"
#include "i386-tdep.h"
-
-#undef XMALLOC
-#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
+#include "i387-tdep.h"
/* Names of the registers. The first 10 registers match the register
numbering scheme used by GCC for stabs and DWARF. */
+
static char *i386_register_names[] =
{
"eax", "ecx", "edx", "ebx",
@@ -60,116 +69,152 @@ static char *i386_register_names[] =
"mxcsr"
};
-/* i386_register_offset[i] is the offset into the register file of the
- start of register number i. We initialize this from
- i386_register_size. */
-static int i386_register_offset[MAX_NUM_REGS];
-
-/* i386_register_size[i] is the number of bytes of storage in GDB's
- register array occupied by register i. */
-static int i386_register_size[MAX_NUM_REGS] = {
- 4, 4, 4, 4,
- 4, 4, 4, 4,
- 4, 4, 4, 4,
- 4, 4, 4, 4,
- 10, 10, 10, 10,
- 10, 10, 10, 10,
- 4, 4, 4, 4,
- 4, 4, 4, 4,
- 16, 16, 16, 16,
- 16, 16, 16, 16,
- 4
+static const int i386_num_register_names = ARRAY_SIZE (i386_register_names);
+
+/* MMX registers. */
+
+static char *i386_mmx_names[] =
+{
+ "mm0", "mm1", "mm2", "mm3",
+ "mm4", "mm5", "mm6", "mm7"
};
-/* Return the name of register REG. */
+static const int i386_num_mmx_regs = ARRAY_SIZE (i386_mmx_names);
-char *
-i386_register_name (int reg)
+static int
+i386_mmx_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- if (reg < 0)
- return NULL;
- if (reg >= sizeof (i386_register_names) / sizeof (*i386_register_names))
- return NULL;
+ int mm0_regnum = gdbarch_tdep (gdbarch)->mm0_regnum;
- return i386_register_names[reg];
+ if (mm0_regnum < 0)
+ return 0;
+
+ return (regnum >= mm0_regnum && regnum < mm0_regnum + i386_num_mmx_regs);
}
-/* Return the offset into the register array of the start of register
- number REG. */
-int
-i386_register_byte (int reg)
+/* SSE register? */
+
+static int
+i386_sse_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- return i386_register_offset[reg];
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+#define I387_ST0_REGNUM tdep->st0_regnum
+#define I387_NUM_XMM_REGS tdep->num_xmm_regs
+
+ if (I387_NUM_XMM_REGS == 0)
+ return 0;
+
+ return (I387_XMM0_REGNUM <= regnum && regnum < I387_MXCSR_REGNUM);
+
+#undef I387_ST0_REGNUM
+#undef I387_NUM_XMM_REGS
+}
+
+static int
+i386_mxcsr_regnum_p (struct gdbarch *gdbarch, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+#define I387_ST0_REGNUM tdep->st0_regnum
+#define I387_NUM_XMM_REGS tdep->num_xmm_regs
+
+ if (I387_NUM_XMM_REGS == 0)
+ return 0;
+
+ return (regnum == I387_MXCSR_REGNUM);
+
+#undef I387_ST0_REGNUM
+#undef I387_NUM_XMM_REGS
}
-/* Return the number of bytes of storage in GDB's register array
- occupied by register REG. */
+#define I387_ST0_REGNUM (gdbarch_tdep (current_gdbarch)->st0_regnum)
+#define I387_MM0_REGNUM (gdbarch_tdep (current_gdbarch)->mm0_regnum)
+#define I387_NUM_XMM_REGS (gdbarch_tdep (current_gdbarch)->num_xmm_regs)
+
+/* FP register? */
int
-i386_register_raw_size (int reg)
+i386_fp_regnum_p (int regnum)
{
- return i386_register_size[reg];
-}
+ if (I387_ST0_REGNUM < 0)
+ return 0;
-/* Return the size in bytes of the virtual type of register REG. */
+ return (I387_ST0_REGNUM <= regnum && regnum < I387_FCTRL_REGNUM);
+}
int
-i386_register_virtual_size (int reg)
+i386_fpc_regnum_p (int regnum)
+{
+ if (I387_ST0_REGNUM < 0)
+ return 0;
+
+ return (I387_FCTRL_REGNUM <= regnum && regnum < I387_XMM0_REGNUM);
+}
+
+/* Return the name of register REG. */
+
+const char *
+i386_register_name (int reg)
{
- return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (reg));
+ if (i386_mmx_regnum_p (current_gdbarch, reg))
+ return i386_mmx_names[reg - I387_MM0_REGNUM];
+
+ if (reg >= 0 && reg < i386_num_register_names)
+ return i386_register_names[reg];
+
+ return NULL;
}
/* Convert stabs register number REG to the appropriate register
number used by GDB. */
-int
+static int
i386_stab_reg_to_regnum (int reg)
{
/* This implements what GCC calls the "default" register map. */
if (reg >= 0 && reg <= 7)
{
- /* General registers. */
+ /* General-purpose registers. */
return reg;
}
else if (reg >= 12 && reg <= 19)
{
/* Floating-point registers. */
- return reg - 12 + FP0_REGNUM;
+ return reg - 12 + I387_ST0_REGNUM;
}
else if (reg >= 21 && reg <= 28)
{
/* SSE registers. */
- return reg - 21 + XMM0_REGNUM;
+ return reg - 21 + I387_XMM0_REGNUM;
}
else if (reg >= 29 && reg <= 36)
{
/* MMX registers. */
- /* FIXME: kettenis/2001-07-28: Should we have the MMX registers
- as pseudo-registers? */
- return reg - 29 + FP0_REGNUM;
+ return reg - 29 + I387_MM0_REGNUM;
}
/* This will hopefully provoke a warning. */
return NUM_REGS + NUM_PSEUDO_REGS;
}
-/* Convert Dwarf register number REG to the appropriate register
+/* Convert DWARF register number REG to the appropriate register
number used by GDB. */
-int
+static int
i386_dwarf_reg_to_regnum (int reg)
{
/* The DWARF register numbering includes %eip and %eflags, and
numbers the floating point registers differently. */
if (reg >= 0 && reg <= 9)
{
- /* General registers. */
+ /* General-purpose registers. */
return reg;
}
else if (reg >= 11 && reg <= 18)
{
/* Floating-point registers. */
- return reg - 11 + FP0_REGNUM;
+ return reg - 11 + I387_ST0_REGNUM;
}
else if (reg >= 21)
{
@@ -180,6 +225,10 @@ i386_dwarf_reg_to_regnum (int reg)
/* This will hopefully provoke a warning. */
return NUM_REGS + NUM_PSEUDO_REGS;
}
+
+#undef I387_ST0_REGNUM
+#undef I387_MM0_REGNUM
+#undef I387_NUM_XMM_REGS
/* This is the variable that is set with "set disassembly-flavor", and
@@ -193,415 +242,402 @@ static const char *valid_flavors[] =
NULL
};
static const char *disassembly_flavor = att_flavor;
+
-/* Stdio style buffering was used to minimize calls to ptrace, but
- this buffering did not take into account that the code section
- being accessed may not be an even number of buffers long (even if
- the buffer is only sizeof(int) long). In cases where the code
- section size happened to be a non-integral number of buffers long,
- attempting to read the last buffer would fail. Simply using
- target_read_memory and ignoring errors, rather than read_memory, is
- not the correct solution, since legitimate access errors would then
- be totally ignored. To properly handle this situation and continue
- to use buffering would require that this code be able to determine
- the minimum code section size granularity (not the alignment of the
- section itself, since the actual failing case that pointed out this
- problem had a section alignment of 4 but was not a multiple of 4
- bytes long), on a target by target basis, and then adjust it's
- buffer size accordingly. This is messy, but potentially feasible.
- It probably needs the bfd library's help and support. For now, the
- buffer size is set to 1. (FIXME -fnf) */
-
-#define CODESTREAM_BUFSIZ 1 /* Was sizeof(int), see note above. */
-static CORE_ADDR codestream_next_addr;
-static CORE_ADDR codestream_addr;
-static unsigned char codestream_buf[CODESTREAM_BUFSIZ];
-static int codestream_off;
-static int codestream_cnt;
-
-#define codestream_tell() (codestream_addr + codestream_off)
-#define codestream_peek() \
- (codestream_cnt == 0 ? \
- codestream_fill(1) : codestream_buf[codestream_off])
-#define codestream_get() \
- (codestream_cnt-- == 0 ? \
- codestream_fill(0) : codestream_buf[codestream_off++])
-
-static unsigned char
-codestream_fill (int peek_flag)
-{
- codestream_addr = codestream_next_addr;
- codestream_next_addr += CODESTREAM_BUFSIZ;
- codestream_off = 0;
- codestream_cnt = CODESTREAM_BUFSIZ;
- read_memory (codestream_addr, (char *) codestream_buf, CODESTREAM_BUFSIZ);
-
- if (peek_flag)
- return (codestream_peek ());
- else
- return (codestream_get ());
-}
+/* Use the program counter to determine the contents and size of a
+ breakpoint instruction. Return a pointer to a string of bytes that
+ encode a breakpoint instruction, store the length of the string in
+ *LEN and optionally adjust *PC to point to the correct memory
+ location for inserting the breakpoint.
-static void
-codestream_seek (CORE_ADDR place)
-{
- codestream_next_addr = place / CODESTREAM_BUFSIZ;
- codestream_next_addr *= CODESTREAM_BUFSIZ;
- codestream_cnt = 0;
- codestream_fill (1);
- while (codestream_tell () != place)
- codestream_get ();
-}
+ On the i386 we have a single breakpoint that fits in a single byte
+ and can be inserted anywhere.
-static void
-codestream_read (unsigned char *buf, int count)
+ This function is 64-bit safe. */
+
+static const unsigned char *
+i386_breakpoint_from_pc (CORE_ADDR *pc, int *len)
{
- unsigned char *p;
- int i;
- p = buf;
- for (i = 0; i < count; i++)
- *p++ = codestream_get ();
+ static unsigned char break_insn[] = { 0xcc }; /* int 3 */
+
+ *len = sizeof (break_insn);
+ return break_insn;
}
+#ifdef I386_REGNO_TO_SYMMETRY
+#error "The Sequent Symmetry is no longer supported."
+#endif
-/* If the next instruction is a jump, move to its target. */
+/* According to the System V ABI, the registers %ebp, %ebx, %edi, %esi
+ and %esp "belong" to the calling function. Therefore these
+ registers should be saved if they're going to be modified. */
-static void
-i386_follow_jump (void)
+/* The maximum number of saved registers. This should include all
+ registers mentioned above, and %eip. */
+#define I386_NUM_SAVED_REGS I386_NUM_GREGS
+
+struct i386_frame_cache
{
- unsigned char buf[4];
- long delta;
+ /* Base address. */
+ CORE_ADDR base;
+ CORE_ADDR sp_offset;
+ CORE_ADDR pc;
+
+ /* Saved registers. */
+ CORE_ADDR saved_regs[I386_NUM_SAVED_REGS];
+ CORE_ADDR saved_sp;
+ int pc_in_eax;
+
+ /* Stack space reserved for local variables. */
+ long locals;
+};
- int data16;
- CORE_ADDR pos;
+/* Allocate and initialize a frame cache. */
- pos = codestream_tell ();
+static struct i386_frame_cache *
+i386_alloc_frame_cache (void)
+{
+ struct i386_frame_cache *cache;
+ int i;
+
+ cache = FRAME_OBSTACK_ZALLOC (struct i386_frame_cache);
+
+ /* Base address. */
+ cache->base = 0;
+ cache->sp_offset = -4;
+ cache->pc = 0;
+
+ /* Saved registers. We initialize these to -1 since zero is a valid
+ offset (that's where %ebp is supposed to be stored). */
+ for (i = 0; i < I386_NUM_SAVED_REGS; i++)
+ cache->saved_regs[i] = -1;
+ cache->saved_sp = 0;
+ cache->pc_in_eax = 0;
- data16 = 0;
- if (codestream_peek () == 0x66)
+ /* Frameless until proven otherwise. */
+ cache->locals = -1;
+
+ return cache;
+}
+
+/* If the instruction at PC is a jump, return the address of its
+ target. Otherwise, return PC. */
+
+static CORE_ADDR
+i386_follow_jump (CORE_ADDR pc)
+{
+ unsigned char op;
+ long delta = 0;
+ int data16 = 0;
+
+ op = read_memory_unsigned_integer (pc, 1);
+ if (op == 0x66)
{
- codestream_get ();
data16 = 1;
+ op = read_memory_unsigned_integer (pc + 1, 1);
}
- switch (codestream_get ())
+ switch (op)
{
case 0xe9:
/* Relative jump: if data16 == 0, disp32, else disp16. */
if (data16)
{
- codestream_read (buf, 2);
- delta = extract_signed_integer (buf, 2);
+ delta = read_memory_integer (pc + 2, 2);
/* Include the size of the jmp instruction (including the
0x66 prefix). */
- pos += delta + 4;
+ delta += 4;
}
else
{
- codestream_read (buf, 4);
- delta = extract_signed_integer (buf, 4);
+ delta = read_memory_integer (pc + 1, 4);
- pos += delta + 5;
+ /* Include the size of the jmp instruction. */
+ delta += 5;
}
break;
case 0xeb:
/* Relative jump, disp8 (ignore data16). */
- codestream_read (buf, 1);
- /* Sign-extend it. */
- delta = extract_signed_integer (buf, 1);
+ delta = read_memory_integer (pc + data16 + 1, 1);
- pos += delta + 2;
+ delta += data16 + 2;
break;
}
- codestream_seek (pos);
-}
-/* Find & return the amount a local space allocated, and advance the
- codestream to the first register push (if any).
+ return pc + delta;
+}
- If the entry sequence doesn't make sense, return -1, and leave
- codestream pointer at a random spot. */
+/* Check whether PC points at a prologue for a function returning a
+ structure or union. If so, it updates CACHE and returns the
+ address of the first instruction after the code sequence that
+ removes the "hidden" argument from the stack or CURRENT_PC,
+ whichever is smaller. Otherwise, return PC. */
-static long
-i386_get_frame_setup (CORE_ADDR pc)
+static CORE_ADDR
+i386_analyze_struct_return (CORE_ADDR pc, CORE_ADDR current_pc,
+ struct i386_frame_cache *cache)
{
+ /* Functions that return a structure or union start with:
+
+ popl %eax 0x58
+ xchgl %eax, (%esp) 0x87 0x04 0x24
+ or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00
+
+ (the System V compiler puts out the second `xchg' instruction,
+ and the assembler doesn't try to optimize it, so the 'sib' form
+ gets generated). This sequence is used to get the address of the
+ return buffer for a function that returns a structure. */
+ static unsigned char proto1[3] = { 0x87, 0x04, 0x24 };
+ static unsigned char proto2[4] = { 0x87, 0x44, 0x24, 0x00 };
+ unsigned char buf[4];
unsigned char op;
- codestream_seek (pc);
+ if (current_pc <= pc)
+ return pc;
- i386_follow_jump ();
+ op = read_memory_unsigned_integer (pc, 1);
- op = codestream_get ();
+ if (op != 0x58) /* popl %eax */
+ return pc;
- if (op == 0x58) /* popl %eax */
+ read_memory (pc + 1, buf, 4);
+ if (memcmp (buf, proto1, 3) != 0 && memcmp (buf, proto2, 4) != 0)
+ return pc;
+
+ if (current_pc == pc)
{
- /* This function must start with
-
- popl %eax 0x58
- xchgl %eax, (%esp) 0x87 0x04 0x24
- or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00
-
- (the System V compiler puts out the second `xchg'
- instruction, and the assembler doesn't try to optimize it, so
- the 'sib' form gets generated). This sequence is used to get
- the address of the return buffer for a function that returns
- a structure. */
- int pos;
- unsigned char buf[4];
- static unsigned char proto1[3] = { 0x87, 0x04, 0x24 };
- static unsigned char proto2[4] = { 0x87, 0x44, 0x24, 0x00 };
-
- pos = codestream_tell ();
- codestream_read (buf, 4);
- if (memcmp (buf, proto1, 3) == 0)
- pos += 3;
- else if (memcmp (buf, proto2, 4) == 0)
- pos += 4;
-
- codestream_seek (pos);
- op = codestream_get (); /* Update next opcode. */
+ cache->sp_offset += 4;
+ return current_pc;
}
- if (op == 0x68 || op == 0x6a)
+ if (current_pc == pc + 1)
{
- /* This function may start with
+ cache->pc_in_eax = 1;
+ return current_pc;
+ }
+
+ if (buf[1] == proto1[1])
+ return pc + 4;
+ else
+ return pc + 5;
+}
+
+static CORE_ADDR
+i386_skip_probe (CORE_ADDR pc)
+{
+ /* A function may start with
- pushl constant
- call _probe
- addl $4, %esp
+ pushl constant
+ call _probe
+ addl $4, %esp
- followed by
+ followed by
- pushl %ebp
+ pushl %ebp
+
+ etc. */
+ unsigned char buf[8];
+ unsigned char op;
- etc. */
- int pos;
- unsigned char buf[8];
+ op = read_memory_unsigned_integer (pc, 1);
- /* Skip past the `pushl' instruction; it has either a one-byte
- or a four-byte operand, depending on the opcode. */
- pos = codestream_tell ();
+ if (op == 0x68 || op == 0x6a)
+ {
+ int delta;
+
+ /* Skip past the `pushl' instruction; it has either a one-byte or a
+ four-byte operand, depending on the opcode. */
if (op == 0x68)
- pos += 4;
+ delta = 5;
else
- pos += 1;
- codestream_seek (pos);
+ delta = 2;
- /* Read the following 8 bytes, which should be "call _probe" (6
- bytes) followed by "addl $4,%esp" (2 bytes). */
- codestream_read (buf, sizeof (buf));
+ /* Read the following 8 bytes, which should be `call _probe' (6
+ bytes) followed by `addl $4,%esp' (2 bytes). */
+ read_memory (pc + delta, buf, sizeof (buf));
if (buf[0] == 0xe8 && buf[6] == 0xc4 && buf[7] == 0x4)
- pos += sizeof (buf);
- codestream_seek (pos);
- op = codestream_get (); /* Update next opcode. */
+ pc += delta + sizeof (buf);
}
+ return pc;
+}
+
+/* Check whether PC points at a code that sets up a new stack frame.
+ If so, it updates CACHE and returns the address of the first
+ instruction after the sequence that sets removes the "hidden"
+ argument from the stack or CURRENT_PC, whichever is smaller.
+ Otherwise, return PC. */
+
+static CORE_ADDR
+i386_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc,
+ struct i386_frame_cache *cache)
+{
+ unsigned char op;
+ int skip = 0;
+
+ if (current_pc <= pc)
+ return current_pc;
+
+ op = read_memory_unsigned_integer (pc, 1);
+
if (op == 0x55) /* pushl %ebp */
{
- /* Check for "movl %esp, %ebp" -- can be written in two ways. */
- switch (codestream_get ())
+ /* Take into account that we've executed the `pushl %ebp' that
+ starts this instruction sequence. */
+ cache->saved_regs[I386_EBP_REGNUM] = 0;
+ cache->sp_offset += 4;
+
+ /* If that's all, return now. */
+ if (current_pc <= pc + 1)
+ return current_pc;
+
+ op = read_memory_unsigned_integer (pc + 1, 1);
+
+ /* Check for some special instructions that might be migrated
+ by GCC into the prologue. We check for
+
+ xorl %ebx, %ebx
+ xorl %ecx, %ecx
+ xorl %edx, %edx
+ xorl %eax, %eax
+
+ and the equivalent
+
+ subl %ebx, %ebx
+ subl %ecx, %ecx
+ subl %edx, %edx
+ subl %eax, %eax
+
+ Because of the symmetry, there are actually two ways to
+ encode these instructions; with opcode bytes 0x29 and 0x2b
+ for `subl' and opcode bytes 0x31 and 0x33 for `xorl'.
+
+ Make sure we only skip these instructions if we later see the
+ `movl %esp, %ebp' that actually sets up the frame. */
+ while (op == 0x29 || op == 0x2b || op == 0x31 || op == 0x33)
+ {
+ op = read_memory_unsigned_integer (pc + skip + 2, 1);
+ switch (op)
+ {
+ case 0xdb: /* %ebx */
+ case 0xc9: /* %ecx */
+ case 0xd2: /* %edx */
+ case 0xc0: /* %eax */
+ skip += 2;
+ break;
+ default:
+ return pc + 1;
+ }
+
+ op = read_memory_unsigned_integer (pc + skip + 1, 1);
+ }
+
+ /* Check for `movl %esp, %ebp' -- can be written in two ways. */
+ switch (op)
{
case 0x8b:
- if (codestream_get () != 0xec)
- return -1;
+ if (read_memory_unsigned_integer (pc + skip + 2, 1) != 0xec)
+ return pc + 1;
break;
case 0x89:
- if (codestream_get () != 0xe5)
- return -1;
+ if (read_memory_unsigned_integer (pc + skip + 2, 1) != 0xe5)
+ return pc + 1;
break;
default:
- return -1;
+ return pc + 1;
}
+
+ /* OK, we actually have a frame. We just don't know how large
+ it is yet. Set its size to zero. We'll adjust it if
+ necessary. We also now commit to skipping the special
+ instructions mentioned before. */
+ cache->locals = 0;
+ pc += skip;
+
+ /* If that's all, return now. */
+ if (current_pc <= pc + 3)
+ return current_pc;
+
/* Check for stack adjustment
- subl $XXX, %esp
+ subl $XXX, %esp
NOTE: You can't subtract a 16 bit immediate from a 32 bit
reg, so we don't have to worry about a data16 prefix. */
- op = codestream_peek ();
+ op = read_memory_unsigned_integer (pc + 3, 1);
if (op == 0x83)
{
/* `subl' with 8 bit immediate. */
- codestream_get ();
- if (codestream_get () != 0xec)
+ if (read_memory_unsigned_integer (pc + 4, 1) != 0xec)
/* Some instruction starting with 0x83 other than `subl'. */
- {
- codestream_seek (codestream_tell () - 2);
- return 0;
- }
- /* `subl' with signed byte immediate (though it wouldn't
- make sense to be negative). */
- return (codestream_get ());
+ return pc + 3;
+
+ /* `subl' with signed byte immediate (though it wouldn't make
+ sense to be negative). */
+ cache->locals = read_memory_integer (pc + 5, 1);
+ return pc + 6;
}
else if (op == 0x81)
{
- char buf[4];
/* Maybe it is `subl' with a 32 bit immedediate. */
- codestream_get ();
- if (codestream_get () != 0xec)
+ if (read_memory_unsigned_integer (pc + 4, 1) != 0xec)
/* Some instruction starting with 0x81 other than `subl'. */
- {
- codestream_seek (codestream_tell () - 2);
- return 0;
- }
+ return pc + 3;
+
/* It is `subl' with a 32 bit immediate. */
- codestream_read ((unsigned char *) buf, 4);
- return extract_signed_integer (buf, 4);
+ cache->locals = read_memory_integer (pc + 5, 4);
+ return pc + 9;
}
else
{
- return 0;
+ /* Some instruction other than `subl'. */
+ return pc + 3;
}
}
- else if (op == 0xc8)
+ else if (op == 0xc8) /* enter $XXX */
{
- char buf[2];
- /* `enter' with 16 bit unsigned immediate. */
- codestream_read ((unsigned char *) buf, 2);
- codestream_get (); /* Flush final byte of enter instruction. */
- return extract_unsigned_integer (buf, 2);
+ cache->locals = read_memory_unsigned_integer (pc + 1, 2);
+ return pc + 4;
}
- return (-1);
-}
-
-/* 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. */
-
-CORE_ADDR
-i386_frame_chain (struct frame_info *frame)
-{
- if (frame->signal_handler_caller)
- return frame->frame;
-
- if (! inside_entry_file (frame->pc))
- return read_memory_unsigned_integer (frame->frame, 4);
-
- return 0;
-}
-
-/* Determine whether the function invocation represented by FRAME does
- not have a from on the stack associated with it. If it does not,
- return non-zero, otherwise return zero. */
-
-int
-i386_frameless_function_invocation (struct frame_info *frame)
-{
- if (frame->signal_handler_caller)
- return 0;
-
- return frameless_look_for_prologue (frame);
-}
-
-/* Return the saved program counter for FRAME. */
-
-CORE_ADDR
-i386_frame_saved_pc (struct frame_info *frame)
-{
- /* FIXME: kettenis/2001-05-09: Conditionalizing the next bit of code
- on SIGCONTEXT_PC_OFFSET and I386V4_SIGTRAMP_SAVED_PC should be
- considered a temporary hack. I plan to come up with something
- better when we go multi-arch. */
-#if defined (SIGCONTEXT_PC_OFFSET) || defined (I386V4_SIGTRAMP_SAVED_PC)
- if (frame->signal_handler_caller)
- return sigtramp_saved_pc (frame);
-#endif
- return read_memory_unsigned_integer (frame->frame + 4, 4);
-}
-
-CORE_ADDR
-i386go32_frame_saved_pc (struct frame_info *frame)
-{
- return read_memory_integer (frame->frame + 4, 4);
+ return pc;
}
-/* Immediately after a function call, return the saved pc. */
+/* Check whether PC points at code that saves registers on the stack.
+ If so, it updates CACHE and returns the address of the first
+ instruction after the register saves or CURRENT_PC, whichever is
+ smaller. Otherwise, return PC. */
-CORE_ADDR
-i386_saved_pc_after_call (struct frame_info *frame)
+static CORE_ADDR
+i386_analyze_register_saves (CORE_ADDR pc, CORE_ADDR current_pc,
+ struct i386_frame_cache *cache)
{
- 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
-i386_frame_num_args (struct frame_info *fi)
-{
-#if 1
- return -1;
-#else
- /* This loses because not only might the compiler not be popping the
- args right after the function call, it might be popping args from
- both this call and a previous one, and we would say there are
- more args than there really are. */
-
- int retpc;
+ CORE_ADDR offset = 0;
unsigned char op;
- struct frame_info *pfi;
-
- /* On the i386, the instruction following the call could be:
- popl %ecx - one arg
- addl $imm, %esp - imm/4 args; imm may be 8 or 32 bits
- anything else - zero args. */
-
- int frameless;
-
- frameless = FRAMELESS_FUNCTION_INVOCATION (fi);
- if (frameless)
- /* In the absence of a frame pointer, GDB doesn't get correct
- values for nameless arguments. Return -1, so it doesn't print
- any nameless arguments. */
- return -1;
+ int i;
- pfi = get_prev_frame (fi);
- if (pfi == 0)
+ if (cache->locals > 0)
+ offset -= cache->locals;
+ for (i = 0; i < 8 && pc < current_pc; i++)
{
- /* NOTE: This can happen if we are looking at the frame for
- main, because FRAME_CHAIN_VALID won't let us go into start.
- If we have debugging symbols, that's not really a big deal;
- it just means it will only show as many arguments to main as
- are declared. */
- return -1;
- }
- else
- {
- retpc = pfi->pc;
- op = read_memory_integer (retpc, 1);
- if (op == 0x59) /* pop %ecx */
- return 1;
- else if (op == 0x83)
- {
- op = read_memory_integer (retpc + 1, 1);
- if (op == 0xc4)
- /* addl $<signed imm 8 bits>, %esp */
- return (read_memory_integer (retpc + 2, 1) & 0xff) / 4;
- else
- return 0;
- }
- else if (op == 0x81) /* `add' with 32 bit immediate. */
- {
- op = read_memory_integer (retpc + 1, 1);
- if (op == 0xc4)
- /* addl $<imm 32>, %esp */
- return read_memory_integer (retpc + 2, 4) / 4;
- else
- return 0;
- }
- else
- {
- return 0;
- }
+ op = read_memory_unsigned_integer (pc, 1);
+ if (op < 0x50 || op > 0x57)
+ break;
+
+ offset -= 4;
+ cache->saved_regs[op - 0x50] = offset;
+ cache->sp_offset += 4;
+ pc++;
}
-#endif
+
+ return pc;
}
-/* Parse the first few instructions the function to see what registers
- were stored.
-
+/* Do a full analysis of the prologue at PC and update CACHE
+ accordingly. Bail out early if CURRENT_PC is reached. Return the
+ address where the analysis stopped.
+
We handle these cases:
The startup sequence can be at the start of the function, or the
@@ -625,97 +661,43 @@ 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
-i386_frame_init_saved_regs (struct frame_info *fip)
+static CORE_ADDR
+i386_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
+ struct i386_frame_cache *cache)
{
- long locals = -1;
- unsigned char op;
- CORE_ADDR dummy_bottom;
- CORE_ADDR addr;
- CORE_ADDR pc;
- int i;
-
- if (fip->saved_regs)
- return;
-
- frame_saved_regs_zalloc (fip);
-
- /* If the frame is the end of a dummy, compute where the beginning
- would be. */
- dummy_bottom = fip->frame - 4 - REGISTER_BYTES - CALL_DUMMY_LENGTH;
-
- /* Check if the PC points in the stack, in a dummy frame. */
- if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
- {
- /* All registers were saved by push_call_dummy. */
- addr = fip->frame;
- for (i = 0; i < NUM_REGS; i++)
- {
- addr -= REGISTER_RAW_SIZE (i);
- fip->saved_regs[i] = addr;
- }
- return;
- }
-
- pc = get_pc_function_start (fip->pc);
- if (pc != 0)
- locals = i386_get_frame_setup (pc);
-
- if (locals >= 0)
- {
- addr = fip->frame - 4 - locals;
- for (i = 0; i < 8; i++)
- {
- op = codestream_get ();
- if (op < 0x50 || op > 0x57)
- break;
-#ifdef I386_REGNO_TO_SYMMETRY
- /* Dynix uses different internal numbering. Ick. */
- fip->saved_regs[I386_REGNO_TO_SYMMETRY (op - 0x50)] = addr;
-#else
- fip->saved_regs[op - 0x50] = addr;
-#endif
- addr -= 4;
- }
- }
-
- fip->saved_regs[PC_REGNUM] = fip->frame + 4;
- fip->saved_regs[FP_REGNUM] = fip->frame;
+ pc = i386_follow_jump (pc);
+ pc = i386_analyze_struct_return (pc, current_pc, cache);
+ pc = i386_skip_probe (pc);
+ pc = i386_analyze_frame_setup (pc, current_pc, cache);
+ return i386_analyze_register_saves (pc, current_pc, cache);
}
/* Return PC of first real instruction. */
-int
-i386_skip_prologue (int pc)
+static CORE_ADDR
+i386_skip_prologue (CORE_ADDR start_pc)
{
- unsigned char op;
- int i;
static unsigned char pic_pat[6] =
- { 0xe8, 0, 0, 0, 0, /* call 0x0 */
- 0x5b, /* popl %ebx */
+ {
+ 0xe8, 0, 0, 0, 0, /* call 0x0 */
+ 0x5b, /* popl %ebx */
};
- CORE_ADDR pos;
-
- if (i386_get_frame_setup (pc) < 0)
- return (pc);
+ struct i386_frame_cache cache;
+ CORE_ADDR pc;
+ unsigned char op;
+ int i;
- /* Found valid frame setup -- codestream now points to start of push
- instructions for saving registers. */
+ cache.locals = -1;
+ pc = i386_analyze_prologue (start_pc, 0xffffffff, &cache);
+ if (cache.locals < 0)
+ return start_pc;
- /* Skip over register saves. */
- for (i = 0; i < 8; i++)
- {
- op = codestream_peek ();
- /* Break if not `pushl' instrunction. */
- if (op < 0x50 || op > 0x57)
- break;
- codestream_get ();
- }
+ /* Found valid frame setup. */
/* The native cc on SVR4 in -K PIC mode inserts the following code
to get the address of the global offset table (GOT) into register
- %ebx
-
+ %ebx:
+
call 0x0
popl %ebx
movl %ebx,x(%ebp) (optional)
@@ -725,212 +707,469 @@ i386_skip_prologue (int pc)
function), so we have to skip it to get to the first real
instruction at the start of the function. */
- pos = codestream_tell ();
for (i = 0; i < 6; i++)
{
- op = codestream_get ();
+ op = read_memory_unsigned_integer (pc + i, 1);
if (pic_pat[i] != op)
break;
}
if (i == 6)
{
- unsigned char buf[4];
- long delta = 6;
+ int delta = 6;
+
+ op = read_memory_unsigned_integer (pc + delta, 1);
- op = codestream_get ();
if (op == 0x89) /* movl %ebx, x(%ebp) */
{
- op = codestream_get ();
+ op = read_memory_unsigned_integer (pc + delta + 1, 1);
+
if (op == 0x5d) /* One byte offset from %ebp. */
- {
- delta += 3;
- codestream_read (buf, 1);
- }
+ delta += 3;
else if (op == 0x9d) /* Four byte offset from %ebp. */
- {
- delta += 6;
- codestream_read (buf, 4);
- }
+ delta += 6;
else /* Unexpected instruction. */
- delta = -1;
- op = codestream_get ();
+ delta = 0;
+
+ op = read_memory_unsigned_integer (pc + delta, 1);
}
+
/* addl y,%ebx */
- if (delta > 0 && op == 0x81 && codestream_get () == 0xc3)
+ if (delta > 0 && op == 0x81
+ && read_memory_unsigned_integer (pc + delta + 1, 1) == 0xc3);
{
- pos += delta + 6;
+ pc += delta + 6;
}
}
- codestream_seek (pos);
- i386_follow_jump ();
+ return i386_follow_jump (pc);
+}
+
+/* This function is 64-bit safe. */
+
+static CORE_ADDR
+i386_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ char buf[8];
- return (codestream_tell ());
+ frame_unwind_register (next_frame, PC_REGNUM, buf);
+ return extract_typed_address (buf, builtin_type_void_func_ptr);
}
+
-void
-i386_push_dummy_frame (void)
+/* Normal frames. */
+
+static struct i386_frame_cache *
+i386_frame_cache (struct frame_info *next_frame, void **this_cache)
{
- CORE_ADDR sp = read_register (SP_REGNUM);
- CORE_ADDR fp;
- int regnum;
- char regbuf[MAX_REGISTER_RAW_SIZE];
+ struct i386_frame_cache *cache;
+ char buf[4];
+ int i;
+
+ if (*this_cache)
+ return *this_cache;
+
+ cache = i386_alloc_frame_cache ();
+ *this_cache = cache;
- sp = push_word (sp, read_register (PC_REGNUM));
- sp = push_word (sp, read_register (FP_REGNUM));
- fp = sp;
- for (regnum = 0; regnum < NUM_REGS; regnum++)
+ /* In principle, for normal frames, %ebp holds the frame pointer,
+ which holds the base address for the current stack frame.
+ However, for functions that don't need it, the frame pointer is
+ optional. For these "frameless" functions the frame pointer is
+ actually the frame pointer of the calling frame. Signal
+ trampolines are just a special case of a "frameless" function.
+ They (usually) share their frame pointer with the frame that was
+ in progress when the signal occurred. */
+
+ frame_unwind_register (next_frame, I386_EBP_REGNUM, buf);
+ cache->base = extract_unsigned_integer (buf, 4);
+ if (cache->base == 0)
+ return cache;
+
+ /* For normal frames, %eip is stored at 4(%ebp). */
+ cache->saved_regs[I386_EIP_REGNUM] = 4;
+
+ cache->pc = frame_func_unwind (next_frame);
+ if (cache->pc != 0)
+ i386_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache);
+
+ if (cache->locals < 0)
{
- read_register_gen (regnum, regbuf);
- sp = push_bytes (sp, regbuf, REGISTER_RAW_SIZE (regnum));
+ /* We didn't find a valid frame, which means that CACHE->base
+ currently holds the frame pointer for our calling frame. If
+ we're at the start of a function, or somewhere half-way its
+ prologue, the function's frame probably hasn't been fully
+ setup yet. Try to reconstruct the base address for the stack
+ frame by looking at the stack pointer. For truly "frameless"
+ functions this might work too. */
+
+ frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
+ cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset;
}
- write_register (SP_REGNUM, sp);
- write_register (FP_REGNUM, fp);
-}
-/* Insert the (relative) function address into the call sequence
- stored at DYMMY. */
+ /* Now that we have the base address for the stack frame we can
+ calculate the value of %esp in the calling frame. */
+ cache->saved_sp = cache->base + 8;
-void
-i386_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
- struct value **args, struct type *type, int gcc_p)
+ /* Adjust all the saved registers such that they contain addresses
+ instead of offsets. */
+ for (i = 0; i < I386_NUM_SAVED_REGS; i++)
+ if (cache->saved_regs[i] != -1)
+ cache->saved_regs[i] += cache->base;
+
+ return cache;
+}
+
+static void
+i386_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ struct frame_id *this_id)
{
- int from, to, delta, loc;
+ struct i386_frame_cache *cache = i386_frame_cache (next_frame, this_cache);
- loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH);
- from = loc + 5;
- to = (int)(fun);
- delta = to - from;
+ /* This marks the outermost frame. */
+ if (cache->base == 0)
+ return;
- *((char *)(dummy) + 1) = (delta & 0xff);
- *((char *)(dummy) + 2) = ((delta >> 8) & 0xff);
- *((char *)(dummy) + 3) = ((delta >> 16) & 0xff);
- *((char *)(dummy) + 4) = ((delta >> 24) & 0xff);
+ /* See the end of i386_push_dummy_call. */
+ (*this_id) = frame_id_build (cache->base + 8, cache->pc);
}
-void
-i386_pop_frame (void)
+static void
+i386_frame_prev_register (struct frame_info *next_frame, void **this_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, void *valuep)
{
- struct frame_info *frame = get_current_frame ();
- CORE_ADDR fp;
- int regnum;
- char regbuf[MAX_REGISTER_RAW_SIZE];
+ struct i386_frame_cache *cache = i386_frame_cache (next_frame, this_cache);
- fp = FRAME_FP (frame);
- i386_frame_init_saved_regs (frame);
+ gdb_assert (regnum >= 0);
- for (regnum = 0; regnum < NUM_REGS; regnum++)
+ /* The System V ABI says that:
+
+ "The flags register contains the system flags, such as the
+ direction flag and the carry flag. The direction flag must be
+ set to the forward (that is, zero) direction before entry and
+ upon exit from a function. Other user flags have no specified
+ role in the standard calling sequence and are not preserved."
+
+ To guarantee the "upon exit" part of that statement we fake a
+ saved flags register that has its direction flag cleared.
+
+ Note that GCC doesn't seem to rely on the fact that the direction
+ flag is cleared after a function return; it always explicitly
+ clears the flag before operations where it matters.
+
+ FIXME: kettenis/20030316: I'm not quite sure whether this is the
+ right thing to do. The way we fake the flags register here makes
+ it impossible to change it. */
+
+ if (regnum == I386_EFLAGS_REGNUM)
+ {
+ *optimizedp = 0;
+ *lvalp = not_lval;
+ *addrp = 0;
+ *realnump = -1;
+ if (valuep)
+ {
+ ULONGEST val;
+
+ /* Clear the direction flag. */
+ val = frame_unwind_register_unsigned (next_frame,
+ I386_EFLAGS_REGNUM);
+ val &= ~(1 << 10);
+ store_unsigned_integer (valuep, 4, val);
+ }
+
+ return;
+ }
+
+ if (regnum == I386_EIP_REGNUM && cache->pc_in_eax)
+ {
+ frame_register_unwind (next_frame, I386_EAX_REGNUM,
+ optimizedp, lvalp, addrp, realnump, valuep);
+ return;
+ }
+
+ if (regnum == I386_ESP_REGNUM && cache->saved_sp)
+ {
+ *optimizedp = 0;
+ *lvalp = not_lval;
+ *addrp = 0;
+ *realnump = -1;
+ if (valuep)
+ {
+ /* Store the value. */
+ store_unsigned_integer (valuep, 4, cache->saved_sp);
+ }
+ return;
+ }
+
+ if (regnum < I386_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1)
{
- CORE_ADDR addr;
- addr = frame->saved_regs[regnum];
- if (addr)
+ *optimizedp = 0;
+ *lvalp = lval_memory;
+ *addrp = cache->saved_regs[regnum];
+ *realnump = -1;
+ if (valuep)
{
- read_memory (addr, regbuf, REGISTER_RAW_SIZE (regnum));
- write_register_bytes (REGISTER_BYTE (regnum), regbuf,
- REGISTER_RAW_SIZE (regnum));
+ /* Read the value in from memory. */
+ read_memory (*addrp, valuep,
+ register_size (current_gdbarch, regnum));
}
+ return;
}
- write_register (FP_REGNUM, read_memory_integer (fp, 4));
- write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
- write_register (SP_REGNUM, fp + 8);
- flush_cached_frames ();
+
+ frame_register_unwind (next_frame, regnum,
+ optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind i386_frame_unwind =
+{
+ NORMAL_FRAME,
+ i386_frame_this_id,
+ i386_frame_prev_register
+};
+
+static const struct frame_unwind *
+i386_frame_sniffer (struct frame_info *next_frame)
+{
+ return &i386_frame_unwind;
}
-#ifdef GET_LONGJMP_TARGET
+/* Signal trampolines. */
+
+static struct i386_frame_cache *
+i386_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
+{
+ struct i386_frame_cache *cache;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ CORE_ADDR addr;
+ char buf[4];
-/* FIXME: Multi-arching does not set JB_PC and JB_ELEMENT_SIZE yet.
- Fill in with dummy value to enable compilation. */
-#ifndef JB_PC
-#define JB_PC 0
-#endif /* JB_PC */
+ if (*this_cache)
+ return *this_cache;
+
+ cache = i386_alloc_frame_cache ();
+
+ frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
+ cache->base = extract_unsigned_integer (buf, 4) - 4;
+
+ addr = tdep->sigcontext_addr (next_frame);
+ if (tdep->sc_reg_offset)
+ {
+ int i;
-#ifndef JB_ELEMENT_SIZE
-#define JB_ELEMENT_SIZE 4
-#endif /* JB_ELEMENT_SIZE */
+ gdb_assert (tdep->sc_num_regs <= I386_NUM_SAVED_REGS);
+
+ for (i = 0; i < tdep->sc_num_regs; i++)
+ if (tdep->sc_reg_offset[i] != -1)
+ cache->saved_regs[i] = addr + tdep->sc_reg_offset[i];
+ }
+ else
+ {
+ cache->saved_regs[I386_EIP_REGNUM] = addr + tdep->sc_pc_offset;
+ cache->saved_regs[I386_ESP_REGNUM] = addr + tdep->sc_sp_offset;
+ }
+
+ *this_cache = cache;
+ return cache;
+}
+
+static void
+i386_sigtramp_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ struct frame_id *this_id)
+{
+ struct i386_frame_cache *cache =
+ i386_sigtramp_frame_cache (next_frame, this_cache);
+
+ /* See the end of i386_push_dummy_call. */
+ (*this_id) = frame_id_build (cache->base + 8, frame_pc_unwind (next_frame));
+}
+
+static void
+i386_sigtramp_frame_prev_register (struct frame_info *next_frame,
+ void **this_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, void *valuep)
+{
+ /* Make sure we've initialized the cache. */
+ i386_sigtramp_frame_cache (next_frame, this_cache);
+
+ i386_frame_prev_register (next_frame, this_cache, regnum,
+ optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind i386_sigtramp_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ i386_sigtramp_frame_this_id,
+ i386_sigtramp_frame_prev_register
+};
+
+static const struct frame_unwind *
+i386_sigtramp_frame_sniffer (struct frame_info *next_frame)
+{
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+ char *name;
+
+ /* We shouldn't even bother to try if the OSABI didn't register
+ a sigcontext_addr handler. */
+ if (!gdbarch_tdep (current_gdbarch)->sigcontext_addr)
+ return NULL;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (PC_IN_SIGTRAMP (pc, name))
+ return &i386_sigtramp_frame_unwind;
+
+ return NULL;
+}
+
+
+static CORE_ADDR
+i386_frame_base_address (struct frame_info *next_frame, void **this_cache)
+{
+ struct i386_frame_cache *cache = i386_frame_cache (next_frame, this_cache);
+
+ return cache->base;
+}
+
+static const struct frame_base i386_frame_base =
+{
+ &i386_frame_unwind,
+ i386_frame_base_address,
+ i386_frame_base_address,
+ i386_frame_base_address
+};
+
+static struct frame_id
+i386_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ char buf[4];
+ CORE_ADDR fp;
+
+ frame_unwind_register (next_frame, I386_EBP_REGNUM, buf);
+ fp = extract_unsigned_integer (buf, 4);
+
+ /* See the end of i386_push_dummy_call. */
+ return frame_id_build (fp + 8, frame_pc_unwind (next_frame));
+}
+
/* Figure out where the longjmp will land. Slurp the args out of the
stack. We expect the first arg to be a pointer to the jmp_buf
- structure from which we extract the pc (JB_PC) that we will land
- at. The pc is copied into PC. This routine returns true on
- success. */
+ structure from which we extract the address that we will land at.
+ This address is copied into PC. This routine returns non-zero on
+ success.
-int
-get_longjmp_target (CORE_ADDR *pc)
+ This function is 64-bit safe. */
+
+static int
+i386_get_longjmp_target (CORE_ADDR *pc)
{
- char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
+ char buf[8];
CORE_ADDR sp, jb_addr;
+ int jb_pc_offset = gdbarch_tdep (current_gdbarch)->jb_pc_offset;
+ int len = TYPE_LENGTH (builtin_type_void_func_ptr);
- sp = read_register (SP_REGNUM);
-
- if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack. */
- buf,
- TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ /* If JB_PC_OFFSET is -1, we have no way to find out where the
+ longjmp will land. */
+ if (jb_pc_offset == -1)
return 0;
- jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
-
- if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
- TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ /* Don't use I386_ESP_REGNUM here, since this function is also used
+ for AMD64. */
+ regcache_cooked_read (current_regcache, SP_REGNUM, buf);
+ sp = extract_typed_address (buf, builtin_type_void_data_ptr);
+ if (target_read_memory (sp + len, buf, len))
return 0;
- *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ jb_addr = extract_typed_address (buf, builtin_type_void_data_ptr);
+ if (target_read_memory (jb_addr + jb_pc_offset, buf, len))
+ return 0;
+ *pc = extract_typed_address (buf, builtin_type_void_func_ptr);
return 1;
}
-
-#endif /* GET_LONGJMP_TARGET */
-CORE_ADDR
-i386_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
+static CORE_ADDR
+i386_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+ struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+ struct value **args, CORE_ADDR sp, int struct_return,
+ CORE_ADDR struct_addr)
{
- sp = default_push_arguments (nargs, args, sp, struct_return, struct_addr);
-
- if (struct_return)
+ char buf[4];
+ int i;
+
+ /* Push arguments in reverse order. */
+ for (i = nargs - 1; i >= 0; i--)
{
- char buf[4];
+ int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
+
+ /* The System V ABI says that:
+
+ "An argument's size is increased, if necessary, to make it a
+ multiple of [32-bit] words. This may require tail padding,
+ depending on the size of the argument."
+
+ This makes sure the stack says word-aligned. */
+ sp -= (len + 3) & ~3;
+ write_memory (sp, VALUE_CONTENTS_ALL (args[i]), len);
+ }
+ /* Push value address. */
+ if (struct_return)
+ {
sp -= 4;
- store_address (buf, 4, struct_addr);
+ store_unsigned_integer (buf, 4, struct_addr);
write_memory (sp, buf, 4);
}
- return sp;
-}
-
-void
-i386_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
-{
- /* Do nothing. Everything was already done by i386_push_arguments. */
+ /* Store return address. */
+ sp -= 4;
+ store_unsigned_integer (buf, 4, bp_addr);
+ write_memory (sp, buf, 4);
+
+ /* Finally, update the stack pointer... */
+ store_unsigned_integer (buf, 4, sp);
+ regcache_cooked_write (regcache, I386_ESP_REGNUM, buf);
+
+ /* ...and fake a frame pointer. */
+ regcache_cooked_write (regcache, I386_EBP_REGNUM, buf);
+
+ /* MarkK wrote: This "+ 8" is all over the place:
+ (i386_frame_this_id, i386_sigtramp_frame_this_id,
+ i386_unwind_dummy_id). It's there, since all frame unwinders for
+ a given target have to agree (within a certain margin) on the
+ defenition of the stack address of a frame. Otherwise
+ frame_id_inner() won't work correctly. Since DWARF2/GCC uses the
+ stack address *before* the function call as a frame's CFA. On
+ the i386, when %ebp is used as a frame pointer, the offset
+ between the contents %ebp and the CFA as defined by GCC. */
+ return sp + 8;
}
/* These registers are used for returning integers (and on some
targets also for returning `struct' and `union' values when their
size and alignment match an integer type). */
-#define LOW_RETURN_REGNUM 0 /* %eax */
-#define HIGH_RETURN_REGNUM 2 /* %edx */
+#define LOW_RETURN_REGNUM I386_EAX_REGNUM /* %eax */
+#define HIGH_RETURN_REGNUM I386_EDX_REGNUM /* %edx */
-/* Extract from an array REGBUF containing the (raw) register state, a
- function return value of TYPE, and copy that, in virtual format,
- into VALBUF. */
+/* Read, for architecture GDBARCH, a function return value of TYPE
+ from REGCACHE, and copy that into VALBUF. */
-void
-i386_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+static void
+i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, void *valbuf)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int len = TYPE_LENGTH (type);
-
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT
- && TYPE_NFIELDS (type) == 1)
- {
- i386_extract_return_value (TYPE_FIELD_TYPE (type, 0), regbuf, valbuf);
- return;
- }
+ char buf[I386_MAX_REGISTER_SIZE];
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
- if (NUM_FREGS == 0)
+ if (tdep->st0_regnum < 0)
{
warning ("Cannot find floating-point return value.");
memset (valbuf, 0, len);
@@ -941,22 +1180,25 @@ i386_extract_return_value (struct type *type, char *regbuf, char *valbuf)
its contents to the desired type. This is probably not
exactly how it would happen on the target itself, but it is
the best we can do. */
- convert_typed_floating (&regbuf[REGISTER_BYTE (FP0_REGNUM)],
- builtin_type_i387_ext, valbuf, type);
+ regcache_raw_read (regcache, I386_ST0_REGNUM, buf);
+ convert_typed_floating (buf, builtin_type_i387_ext, valbuf, type);
}
else
{
- int low_size = REGISTER_RAW_SIZE (LOW_RETURN_REGNUM);
- int high_size = REGISTER_RAW_SIZE (HIGH_RETURN_REGNUM);
+ int low_size = register_size (current_gdbarch, LOW_RETURN_REGNUM);
+ int high_size = register_size (current_gdbarch, HIGH_RETURN_REGNUM);
if (len <= low_size)
- memcpy (valbuf, &regbuf[REGISTER_BYTE (LOW_RETURN_REGNUM)], len);
+ {
+ regcache_raw_read (regcache, LOW_RETURN_REGNUM, buf);
+ memcpy (valbuf, buf, len);
+ }
else if (len <= (low_size + high_size))
{
- memcpy (valbuf,
- &regbuf[REGISTER_BYTE (LOW_RETURN_REGNUM)], low_size);
- memcpy (valbuf + low_size,
- &regbuf[REGISTER_BYTE (HIGH_RETURN_REGNUM)], len - low_size);
+ regcache_raw_read (regcache, LOW_RETURN_REGNUM, buf);
+ memcpy (valbuf, buf, low_size);
+ regcache_raw_read (regcache, HIGH_RETURN_REGNUM, buf);
+ memcpy ((char *) valbuf + low_size, buf, len - low_size);
}
else
internal_error (__FILE__, __LINE__,
@@ -964,27 +1206,26 @@ 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. */
+/* Write, for architecture GDBARCH, a function return value of TYPE
+ from VALBUF into REGCACHE. */
-void
-i386_store_return_value (struct type *type, char *valbuf)
+static void
+i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, const void *valbuf)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int len = TYPE_LENGTH (type);
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT
- && TYPE_NFIELDS (type) == 1)
- {
- i386_store_return_value (TYPE_FIELD_TYPE (type, 0), valbuf);
- return;
- }
+ /* Define I387_ST0_REGNUM such that we use the proper definitions
+ for the architecture. */
+#define I387_ST0_REGNUM I386_ST0_REGNUM
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
- unsigned int fstat;
- char buf[FPU_REG_RAW_SIZE];
+ ULONGEST fstat;
+ char buf[I386_MAX_REGISTER_SIZE];
- if (NUM_FREGS == 0)
+ if (tdep->st0_regnum < 0)
{
warning ("Cannot set floating-point return value.");
return;
@@ -999,51 +1240,113 @@ i386_store_return_value (struct type *type, char *valbuf)
not exactly how it would happen on the target itself, but
it is the best we can do. */
convert_typed_floating (valbuf, type, buf, builtin_type_i387_ext);
- write_register_bytes (REGISTER_BYTE (FP0_REGNUM), buf,
- FPU_REG_RAW_SIZE);
+ regcache_raw_write (regcache, I386_ST0_REGNUM, buf);
/* Set the top of the floating-point register stack to 7. The
actual value doesn't really matter, but 7 is what a normal
function return would end up with if the program started out
with a freshly initialized FPU. */
- fstat = read_register (FSTAT_REGNUM);
+ regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat);
fstat |= (7 << 11);
- write_register (FSTAT_REGNUM, fstat);
+ regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM, fstat);
/* Mark %st(1) through %st(7) as empty. Since we set the top of
the floating-point register stack to 7, the appropriate value
for the tag word is 0x3fff. */
- write_register (FTAG_REGNUM, 0x3fff);
+ regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM, 0x3fff);
}
else
{
- int low_size = REGISTER_RAW_SIZE (LOW_RETURN_REGNUM);
- int high_size = REGISTER_RAW_SIZE (HIGH_RETURN_REGNUM);
+ int low_size = register_size (current_gdbarch, LOW_RETURN_REGNUM);
+ int high_size = register_size (current_gdbarch, HIGH_RETURN_REGNUM);
if (len <= low_size)
- write_register_bytes (REGISTER_BYTE (LOW_RETURN_REGNUM), valbuf, len);
+ regcache_raw_write_part (regcache, LOW_RETURN_REGNUM, 0, len, valbuf);
else if (len <= (low_size + high_size))
{
- write_register_bytes (REGISTER_BYTE (LOW_RETURN_REGNUM),
- valbuf, low_size);
- write_register_bytes (REGISTER_BYTE (HIGH_RETURN_REGNUM),
- valbuf + low_size, len - low_size);
+ regcache_raw_write (regcache, LOW_RETURN_REGNUM, valbuf);
+ regcache_raw_write_part (regcache, HIGH_RETURN_REGNUM, 0,
+ len - low_size, (char *) valbuf + low_size);
}
else
internal_error (__FILE__, __LINE__,
"Cannot store return value of %d bytes long.", len);
}
+
+#undef I387_ST0_REGNUM
}
+
+
+/* This is the variable that is set with "set struct-convention", and
+ its legitimate values. */
+static const char default_struct_convention[] = "default";
+static const char pcc_struct_convention[] = "pcc";
+static const char reg_struct_convention[] = "reg";
+static const char *valid_conventions[] =
+{
+ default_struct_convention,
+ pcc_struct_convention,
+ reg_struct_convention,
+ NULL
+};
+static const char *struct_convention = default_struct_convention;
-/* Extract from an array REGBUF containing the (raw) register state
- the address in which a function should return its structure value,
- as a CORE_ADDR. */
+/* Return non-zero if TYPE, which is assumed to be a structure or
+ union type, should be returned in registers for architecture
+ GDBARCH. */
-CORE_ADDR
-i386_extract_struct_value_address (char *regbuf)
+static int
+i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
{
- return extract_address (&regbuf[REGISTER_BYTE (LOW_RETURN_REGNUM)],
- REGISTER_RAW_SIZE (LOW_RETURN_REGNUM));
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum type_code code = TYPE_CODE (type);
+ int len = TYPE_LENGTH (type);
+
+ gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION);
+
+ if (struct_convention == pcc_struct_convention
+ || (struct_convention == default_struct_convention
+ && tdep->struct_return == pcc_struct_return))
+ return 0;
+
+ return (len == 1 || len == 2 || len == 4 || len == 8);
+}
+
+/* Determine, for architecture GDBARCH, how a return value of TYPE
+ should be returned. If it is supposed to be returned in registers,
+ and READBUF is non-zero, read the appropriate value from REGCACHE,
+ and copy it into READBUF. If WRITEBUF is non-zero, write the value
+ from WRITEBUF into REGCACHE. */
+
+static enum return_value_convention
+i386_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, void *readbuf,
+ const void *writebuf)
+{
+ enum type_code code = TYPE_CODE (type);
+
+ if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
+ && !i386_reg_struct_return_p (gdbarch, type))
+ return RETURN_VALUE_STRUCT_CONVENTION;
+
+ /* This special case is for structures consisting of a single
+ `float' or `double' member. These structures are returned in
+ %st(0). For these structures, we call ourselves recursively,
+ changing TYPE into the type of the first member of the structure.
+ Since that should work for all structures that have only one
+ member, we don't bother to check the member's type here. */
+ if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
+ {
+ type = check_typedef (TYPE_FIELD_TYPE (type, 0));
+ return i386_return_value (gdbarch, type, regcache, readbuf, writebuf);
+ }
+
+ if (readbuf)
+ i386_extract_return_value (gdbarch, type, regcache, readbuf);
+ if (writebuf)
+ i386_store_return_value (gdbarch, type, regcache, writebuf);
+
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
@@ -1051,106 +1354,291 @@ i386_extract_struct_value_address (char *regbuf)
register REGNUM. Perhaps %esi and %edi should go here, but
potentially they could be used for things other than address. */
-struct type *
-i386_register_virtual_type (int regnum)
+static struct type *
+i386_register_type (struct gdbarch *gdbarch, int regnum)
{
- if (regnum == PC_REGNUM || regnum == FP_REGNUM || regnum == SP_REGNUM)
+ if (regnum == I386_EIP_REGNUM
+ || regnum == I386_EBP_REGNUM || regnum == I386_ESP_REGNUM)
return lookup_pointer_type (builtin_type_void);
- if (IS_FP_REGNUM (regnum))
+ if (i386_fp_regnum_p (regnum))
return builtin_type_i387_ext;
- if (IS_SSE_REGNUM (regnum))
- return builtin_type_v4sf;
+ if (i386_sse_regnum_p (gdbarch, regnum))
+ return builtin_type_vec128i;
+
+ if (i386_mmx_regnum_p (gdbarch, regnum))
+ return builtin_type_vec64i;
return builtin_type_int;
}
-/* Return true iff register REGNUM's virtual format is different from
- its raw format. Note that this definition assumes that the host
- supports IEEE 32-bit floats, since it doesn't say that SSE
- registers need conversion. Even if we can't find a counterexample,
- this is still sloppy. */
+/* Map a cooked register onto a raw register or memory. For the i386,
+ the MMX registers need to be mapped onto floating point registers. */
-int
-i386_register_convertible (int regnum)
+static int
+i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
{
- return IS_FP_REGNUM (regnum);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+ int mmxreg, fpreg;
+ ULONGEST fstat;
+ int tos;
+
+ /* Define I387_ST0_REGNUM such that we use the proper definitions
+ for REGCACHE's architecture. */
+#define I387_ST0_REGNUM tdep->st0_regnum
+
+ mmxreg = regnum - tdep->mm0_regnum;
+ regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat);
+ tos = (fstat >> 11) & 0x7;
+ fpreg = (mmxreg + tos) % 8;
+
+ return (I387_ST0_REGNUM + fpreg);
+
+#undef I387_ST0_REGNUM
}
-/* Convert data from raw format for register REGNUM in buffer FROM to
- virtual format with type TYPE in buffer TO. */
+static void
+i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+ int regnum, void *buf)
+{
+ if (i386_mmx_regnum_p (gdbarch, regnum))
+ {
+ char mmx_buf[MAX_REGISTER_SIZE];
+ int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
-void
-i386_register_convert_to_virtual (int regnum, struct type *type,
- char *from, char *to)
+ /* Extract (always little endian). */
+ regcache_raw_read (regcache, fpnum, mmx_buf);
+ memcpy (buf, mmx_buf, register_size (gdbarch, regnum));
+ }
+ else
+ regcache_raw_read (regcache, regnum, buf);
+}
+
+static void
+i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+ int regnum, const void *buf)
{
- gdb_assert (IS_FP_REGNUM (regnum));
+ if (i386_mmx_regnum_p (gdbarch, regnum))
+ {
+ char mmx_buf[MAX_REGISTER_SIZE];
+ int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
+
+ /* Read ... */
+ regcache_raw_read (regcache, fpnum, mmx_buf);
+ /* ... Modify ... (always little endian). */
+ memcpy (mmx_buf, buf, register_size (gdbarch, regnum));
+ /* ... Write. */
+ regcache_raw_write (regcache, fpnum, mmx_buf);
+ }
+ else
+ regcache_raw_write (regcache, regnum, buf);
+}
+
+
+/* Return the register number of the register allocated by GCC after
+ REGNUM, or -1 if there is no such register. */
+
+static int
+i386_next_regnum (int regnum)
+{
+ /* GCC allocates the registers in the order:
+
+ %eax, %edx, %ecx, %ebx, %esi, %edi, %ebp, %esp, ...
+
+ Since storing a variable in %esp doesn't make any sense we return
+ -1 for %ebp and for %esp itself. */
+ static int next_regnum[] =
+ {
+ I386_EDX_REGNUM, /* Slot for %eax. */
+ I386_EBX_REGNUM, /* Slot for %ecx. */
+ I386_ECX_REGNUM, /* Slot for %edx. */
+ I386_ESI_REGNUM, /* Slot for %ebx. */
+ -1, -1, /* Slots for %esp and %ebp. */
+ I386_EDI_REGNUM, /* Slot for %esi. */
+ I386_EBP_REGNUM /* Slot for %edi. */
+ };
+
+ if (regnum >= 0 && regnum < sizeof (next_regnum) / sizeof (next_regnum[0]))
+ return next_regnum[regnum];
+
+ return -1;
+}
+
+/* Return nonzero if a value of type TYPE stored in register REGNUM
+ needs any special handling. */
+
+static int
+i386_convert_register_p (int regnum, struct type *type)
+{
+ int len = TYPE_LENGTH (type);
- /* We only support floating-point values. */
- if (TYPE_CODE (type) != TYPE_CODE_FLT)
+ /* Values may be spread across multiple registers. Most debugging
+ formats aren't expressive enough to specify the locations, so
+ some heuristics is involved. Right now we only handle types that
+ have a length that is a multiple of the word size, since GCC
+ doesn't seem to put any other types into registers. */
+ if (len > 4 && len % 4 == 0)
{
- warning ("Cannot convert floating-point register value "
- "to non-floating-point type.");
- memset (to, 0, TYPE_LENGTH (type));
+ int last_regnum = regnum;
+
+ while (len > 4)
+ {
+ last_regnum = i386_next_regnum (last_regnum);
+ len -= 4;
+ }
+
+ if (last_regnum != -1)
+ return 1;
+ }
+
+ return i386_fp_regnum_p (regnum);
+}
+
+/* Read a value of type TYPE from register REGNUM in frame FRAME, and
+ return its contents in TO. */
+
+static void
+i386_register_to_value (struct frame_info *frame, int regnum,
+ struct type *type, void *to)
+{
+ int len = TYPE_LENGTH (type);
+ char *buf = to;
+
+ /* FIXME: kettenis/20030609: What should we do if REGNUM isn't
+ available in FRAME (i.e. if it wasn't saved)? */
+
+ if (i386_fp_regnum_p (regnum))
+ {
+ i387_register_to_value (frame, regnum, type, to);
return;
}
- /* Convert to TYPE. This should be a no-op if TYPE is equivalent to
- the extended floating-point format used by the FPU. */
- convert_typed_floating (from, builtin_type_i387_ext, to, type);
+ /* Read a value spread accross multiple registers. */
+
+ gdb_assert (len > 4 && len % 4 == 0);
+
+ while (len > 0)
+ {
+ gdb_assert (regnum != -1);
+ gdb_assert (register_size (current_gdbarch, regnum) == 4);
+
+ get_frame_register (frame, regnum, buf);
+ regnum = i386_next_regnum (regnum);
+ len -= 4;
+ buf += 4;
+ }
}
-/* Convert data from virtual format with type TYPE in buffer FROM to
- raw format for register REGNUM in buffer TO. */
+/* Write the contents FROM of a value of type TYPE into register
+ REGNUM in frame FRAME. */
+
+static void
+i386_value_to_register (struct frame_info *frame, int regnum,
+ struct type *type, const void *from)
+{
+ int len = TYPE_LENGTH (type);
+ const char *buf = from;
+
+ if (i386_fp_regnum_p (regnum))
+ {
+ i387_value_to_register (frame, regnum, type, from);
+ return;
+ }
+
+ /* Write a value spread accross multiple registers. */
+
+ gdb_assert (len > 4 && len % 4 == 0);
+
+ while (len > 0)
+ {
+ gdb_assert (regnum != -1);
+ gdb_assert (register_size (current_gdbarch, regnum) == 4);
+
+ put_frame_register (frame, regnum, buf);
+ regnum = i386_next_regnum (regnum);
+ len -= 4;
+ buf += 4;
+ }
+}
+
+/* Supply register REGNUM from the general-purpose register set REGSET
+ to register cache REGCACHE. If REGNUM is -1, do this for all
+ registers in REGSET. */
void
-i386_register_convert_to_raw (struct type *type, int regnum,
- char *from, char *to)
+i386_supply_gregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
{
- gdb_assert (IS_FP_REGNUM (regnum));
+ const struct gdbarch_tdep *tdep = regset->descr;
+ const char *regs = gregs;
+ int i;
+
+ gdb_assert (len == tdep->sizeof_gregset);
+
+ for (i = 0; i < tdep->gregset_num_regs; i++)
+ {
+ if ((regnum == i || regnum == -1)
+ && tdep->gregset_reg_offset[i] != -1)
+ regcache_raw_supply (regcache, i, regs + tdep->gregset_reg_offset[i]);
+ }
+}
+
+/* Supply register REGNUM from the floating-point register set REGSET
+ to register cache REGCACHE. If REGNUM is -1, do this for all
+ registers in REGSET. */
+
+static void
+i386_supply_fpregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ const struct gdbarch_tdep *tdep = regset->descr;
- /* We only support floating-point values. */
- if (TYPE_CODE (type) != TYPE_CODE_FLT)
+ if (len == I387_SIZEOF_FXSAVE)
{
- warning ("Cannot convert non-floating-point type "
- "to floating-point register value.");
- memset (to, 0, TYPE_LENGTH (type));
+ i387_supply_fxsave (regcache, regnum, fpregs);
return;
}
- /* Convert from TYPE. This should be a no-op if TYPE is equivalent
- to the extended floating-point format used by the FPU. */
- convert_typed_floating (from, type, to, builtin_type_i387_ext);
+ gdb_assert (len == tdep->sizeof_fpregset);
+ i387_supply_fsave (regcache, regnum, fpregs);
}
-
-#ifdef I386V4_SIGTRAMP_SAVED_PC
-/* Get saved user PC for sigtramp from the pushed ucontext on the
- stack for all three variants of SVR4 sigtramps. */
+/* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
-CORE_ADDR
-i386v4_sigtramp_saved_pc (struct frame_info *frame)
+const struct regset *
+i386_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
{
- CORE_ADDR saved_pc_offset = 4;
- char *name = NULL;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- find_pc_partial_function (frame->pc, &name, NULL, NULL);
- if (name)
+ if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
{
- if (STREQ (name, "_sigreturn"))
- saved_pc_offset = 132 + 14 * 4;
- else if (STREQ (name, "_sigacthandler"))
- saved_pc_offset = 80 + 14 * 4;
- else if (STREQ (name, "sigvechandler"))
- saved_pc_offset = 120 + 14 * 4;
+ if (tdep->gregset == NULL)
+ {
+ tdep->gregset = XMALLOC (struct regset);
+ tdep->gregset->descr = tdep;
+ tdep->gregset->supply_regset = i386_supply_gregset;
+ }
+ return tdep->gregset;
}
- 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);
+ if ((strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset)
+ || (strcmp (sect_name, ".reg-xfp") == 0
+ && sect_size == I387_SIZEOF_FXSAVE))
+ {
+ if (tdep->fpregset == NULL)
+ {
+ tdep->fpregset = XMALLOC (struct regset);
+ tdep->fpregset->descr = tdep;
+ tdep->fpregset->supply_regset = i386_supply_fpregset;
+ }
+ return tdep->fpregset;
+ }
+
+ return NULL;
}
-#endif /* I386V4_SIGTRAMP_SAVED_PC */
#ifdef STATIC_TRANSFORM_NAME
@@ -1182,14 +1670,14 @@ sunpro_static_transform_name (char *name)
/* Stuff for WIN32 PE style DLL's but is pretty generic really. */
CORE_ADDR
-skip_trampoline_code (CORE_ADDR pc, char *name)
+i386_pe_skip_trampoline_code (CORE_ADDR pc, char *name)
{
if (pc && read_memory_unsigned_integer (pc, 2) == 0x25ff) /* jmp *(dest) */
{
unsigned long indirect = read_memory_unsigned_integer (pc + 2, 4);
struct minimal_symbol *indsym =
indirect ? lookup_minimal_symbol_by_pc (indirect) : 0;
- char *symname = indsym ? SYMBOL_NAME (indsym) : 0;
+ char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : 0;
if (symname)
{
@@ -1202,148 +1690,372 @@ skip_trampoline_code (CORE_ADDR pc, char *name)
}
+/* Return non-zero if PC and NAME show that we are in a signal
+ trampoline. */
+
+static int
+i386_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ return (name && strcmp ("_sigtramp", name) == 0);
+}
+
+
/* We have two flavours of disassembly. The machinery on this page
deals with switching between those. */
static int
-gdb_print_insn_i386 (bfd_vma memaddr, disassemble_info *info)
+i386_print_insn (bfd_vma pc, struct disassemble_info *info)
{
- if (disassembly_flavor == att_flavor)
- return print_insn_i386_att (memaddr, info);
- else if (disassembly_flavor == intel_flavor)
- return print_insn_i386_intel (memaddr, info);
- /* Never reached -- disassembly_flavour is always either att_flavor
- or intel_flavor. */
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ gdb_assert (disassembly_flavor == att_flavor
+ || disassembly_flavor == intel_flavor);
+
+ /* FIXME: kettenis/20020915: Until disassembler_options is properly
+ constified, cast to prevent a compiler warning. */
+ info->disassembler_options = (char *) disassembly_flavor;
+ info->mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
+
+ return print_insn_i386 (pc, info);
+}
+
+
+/* There are a few i386 architecture variants that differ only
+ slightly from the generic i386 target. For now, we don't give them
+ their own source file, but include them here. As a consequence,
+ they'll always be included. */
+
+/* System V Release 4 (SVR4). */
+
+static int
+i386_svr4_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ /* UnixWare uses _sigacthandler. The origin of the other symbols is
+ currently unknown. */
+ return (name && (strcmp ("_sigreturn", name) == 0
+ || strcmp ("_sigacthandler", name) == 0
+ || strcmp ("sigvechandler", name) == 0));
+}
+
+/* Assuming NEXT_FRAME is for a frame following a SVR4 sigtramp
+ routine, return the address of the associated sigcontext (ucontext)
+ structure. */
+
+static CORE_ADDR
+i386_svr4_sigcontext_addr (struct frame_info *next_frame)
+{
+ char buf[4];
+ CORE_ADDR sp;
+
+ frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
+ sp = extract_unsigned_integer (buf, 4);
+
+ return read_memory_unsigned_integer (sp + 8, 4);
}
+
+
+/* DJGPP. */
+static int
+i386_go32_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ /* DJGPP doesn't have any special frames for signal handlers. */
+ return 0;
+}
+
+/* Generic ELF. */
+
+void
+i386_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* We typically use stabs-in-ELF with the DWARF register numbering. */
+ set_gdbarch_stab_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum);
+}
+
+/* System V Release 4 (SVR4). */
+
+void
+i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* System V Release 4 uses ELF. */
+ i386_elf_init_abi (info, gdbarch);
+
+ /* System V Release 4 has shared libraries. */
+ set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+
+ set_gdbarch_pc_in_sigtramp (gdbarch, i386_svr4_pc_in_sigtramp);
+ tdep->sigcontext_addr = i386_svr4_sigcontext_addr;
+ tdep->sc_pc_offset = 36 + 14 * 4;
+ tdep->sc_sp_offset = 36 + 17 * 4;
+
+ tdep->jb_pc_offset = 20;
+}
+
+/* DJGPP. */
+
static void
-process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
+i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
- int *os_ident_ptr = obj;
- const char *name;
- unsigned int sect_size;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- name = bfd_get_section_name (abfd, sect);
- sect_size = bfd_section_size (abfd, sect);
- if (strcmp (name, ".note.ABI-tag") == 0 && sect_size > 0)
- {
- unsigned int name_length, data_length, note_type;
- char *note = alloca (sect_size);
-
- bfd_get_section_contents (abfd, sect, note,
- (file_ptr) 0, (bfd_size_type) sect_size);
-
- name_length = bfd_h_get_32 (abfd, note);
- data_length = bfd_h_get_32 (abfd, note + 4);
- note_type = bfd_h_get_32 (abfd, note + 8);
-
- if (name_length == 4 && data_length == 16 && note_type == 1
- && strcmp (note + 12, "GNU") == 0)
- {
- int os_number = bfd_h_get_32 (abfd, note + 16);
-
- /* The case numbers are from abi-tags in glibc. */
- switch (os_number)
- {
- case 0:
- *os_ident_ptr = ELFOSABI_LINUX;
- break;
- case 1:
- *os_ident_ptr = ELFOSABI_HURD;
- break;
- case 2:
- *os_ident_ptr = ELFOSABI_SOLARIS;
- break;
- default:
- internal_error (__FILE__, __LINE__,
- "process_note_abi_sections: "
- "unknown OS number %d", os_number);
- break;
- }
- }
- }
+ set_gdbarch_pc_in_sigtramp (gdbarch, i386_go32_pc_in_sigtramp);
+
+ tdep->jb_pc_offset = 36;
+}
+
+/* NetWare. */
+
+static void
+i386_nw_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->jb_pc_offset = 24;
+}
+
+
+/* i386 register groups. In addition to the normal groups, add "mmx"
+ and "sse". */
+
+static struct reggroup *i386_sse_reggroup;
+static struct reggroup *i386_mmx_reggroup;
+
+static void
+i386_init_reggroups (void)
+{
+ i386_sse_reggroup = reggroup_new ("sse", USER_REGGROUP);
+ i386_mmx_reggroup = reggroup_new ("mmx", USER_REGGROUP);
+}
+
+static void
+i386_add_reggroups (struct gdbarch *gdbarch)
+{
+ reggroup_add (gdbarch, i386_sse_reggroup);
+ reggroup_add (gdbarch, i386_mmx_reggroup);
+ reggroup_add (gdbarch, general_reggroup);
+ reggroup_add (gdbarch, float_reggroup);
+ reggroup_add (gdbarch, all_reggroup);
+ reggroup_add (gdbarch, save_reggroup);
+ reggroup_add (gdbarch, restore_reggroup);
+ reggroup_add (gdbarch, vector_reggroup);
+ reggroup_add (gdbarch, system_reggroup);
}
-struct gdbarch *
+int
+i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+ struct reggroup *group)
+{
+ int sse_regnum_p = (i386_sse_regnum_p (gdbarch, regnum)
+ || i386_mxcsr_regnum_p (gdbarch, regnum));
+ int fp_regnum_p = (i386_fp_regnum_p (regnum)
+ || i386_fpc_regnum_p (regnum));
+ int mmx_regnum_p = (i386_mmx_regnum_p (gdbarch, regnum));
+
+ if (group == i386_mmx_reggroup)
+ return mmx_regnum_p;
+ if (group == i386_sse_reggroup)
+ return sse_regnum_p;
+ if (group == vector_reggroup)
+ return (mmx_regnum_p || sse_regnum_p);
+ if (group == float_reggroup)
+ return fp_regnum_p;
+ if (group == general_reggroup)
+ return (!fp_regnum_p && !mmx_regnum_p && !sse_regnum_p);
+
+ return default_register_reggroup_p (gdbarch, regnum, group);
+}
+
+
+/* Get the ARGIth function argument for the current function. */
+
+static CORE_ADDR
+i386_fetch_pointer_argument (struct frame_info *frame, int argi,
+ struct type *type)
+{
+ CORE_ADDR sp = get_frame_register_unsigned (frame, I386_ESP_REGNUM);
+ return read_memory_unsigned_integer (sp + (4 * (argi + 1)), 4);
+}
+
+
+static struct gdbarch *
i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
struct gdbarch_tdep *tdep;
struct gdbarch *gdbarch;
- int os_ident;
-
- if (info.abfd != NULL
- && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
- {
- os_ident = elf_elfheader (info.abfd)->e_ident[EI_OSABI];
-
- /* If os_ident is 0, it is not necessarily the case that we're
- on a SYSV system. (ELFOSABI_NONE is defined to be 0.)
- GNU/Linux uses a note section to record OS/ABI info, but
- leaves e_ident[EI_OSABI] zero. So we have to check for note
- sections too. */
- if (os_ident == ELFOSABI_NONE)
- bfd_map_over_sections (info.abfd,
- process_note_abi_tag_sections,
- &os_ident);
-
- /* If that didn't help us, revert to some non-standard checks. */
- if (os_ident == ELFOSABI_NONE)
- {
- /* FreeBSD folks are naughty; they stored the string
- "FreeBSD" in the padding of the e_ident field of the ELF
- header. */
- if (strcmp (&elf_elfheader (info.abfd)->e_ident[8], "FreeBSD") == 0)
- os_ident = ELFOSABI_FREEBSD;
- }
- }
- else
- os_ident = -1;
- for (arches = gdbarch_list_lookup_by_info (arches, &info);
- arches != NULL;
- arches = gdbarch_list_lookup_by_info (arches->next, &info))
- {
- tdep = gdbarch_tdep (arches->gdbarch);
- if (tdep && tdep->os_ident == os_ident)
- return arches->gdbarch;
- }
+ /* If there is already a candidate, use it. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
/* Allocate space for the new architecture. */
tdep = XMALLOC (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
- tdep->os_ident = os_ident;
+ /* General-purpose registers. */
+ tdep->gregset = NULL;
+ tdep->gregset_reg_offset = NULL;
+ tdep->gregset_num_regs = I386_NUM_GREGS;
+ tdep->sizeof_gregset = 0;
+
+ /* Floating-point registers. */
+ tdep->fpregset = NULL;
+ tdep->sizeof_fpregset = I387_SIZEOF_FSAVE;
+
+ /* The default settings include the FPU registers, the MMX registers
+ and the SSE registers. This can be overidden for a specific ABI
+ by adjusting the members `st0_regnum', `mm0_regnum' and
+ `num_xmm_regs' of `struct gdbarch_tdep', otherwise the registers
+ will show up in the output of "info all-registers". Ideally we
+ should try to autodetect whether they are available, such that we
+ can prevent "info all-registers" from displaying registers that
+ aren't available.
+
+ NOTE: kevinb/2003-07-13: ... if it's a choice between printing
+ [the SSE registers] always (even when they don't exist) or never
+ showing them to the user (even when they do exist), I prefer the
+ former over the latter. */
+
+ tdep->st0_regnum = I386_ST0_REGNUM;
+
+ /* The MMX registers are implemented as pseudo-registers. Put off
+ caclulating the register number for %mm0 until we know the number
+ of raw registers. */
+ tdep->mm0_regnum = 0;
+
+ /* I386_NUM_XREGS includes %mxcsr, so substract one. */
+ tdep->num_xmm_regs = I386_NUM_XREGS - 1;
+
+ tdep->jb_pc_offset = -1;
+ tdep->struct_return = pcc_struct_return;
+ tdep->sigtramp_start = 0;
+ tdep->sigtramp_end = 0;
+ tdep->sigcontext_addr = NULL;
+ tdep->sc_reg_offset = 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 i387 extended floating-point has only 80 significant
+ bits, a `long double' actually takes up 96, probably to enforce
+ alignment. */
+ set_gdbarch_long_double_bit (gdbarch, 96);
+
+ /* The default ABI includes general-purpose registers,
+ floating-point registers, and the SSE registers. */
+ set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS);
+ set_gdbarch_register_name (gdbarch, i386_register_name);
+ set_gdbarch_register_type (gdbarch, i386_register_type);
+
+ /* Register numbers of various important registers. */
+ set_gdbarch_sp_regnum (gdbarch, I386_ESP_REGNUM); /* %esp */
+ set_gdbarch_pc_regnum (gdbarch, I386_EIP_REGNUM); /* %eip */
+ set_gdbarch_ps_regnum (gdbarch, I386_EFLAGS_REGNUM); /* %eflags */
+ set_gdbarch_fp0_regnum (gdbarch, I386_ST0_REGNUM); /* %st(0) */
+
+ /* Use the "default" register numbering scheme for stabs and COFF. */
+ set_gdbarch_stab_reg_to_regnum (gdbarch, i386_stab_reg_to_regnum);
+ set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_stab_reg_to_regnum);
+
+ /* Use the DWARF register numbering scheme for DWARF and DWARF 2. */
+ set_gdbarch_dwarf_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum);
+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_dwarf_reg_to_regnum);
+
+ /* We don't define ECOFF_REG_TO_REGNUM, since ECOFF doesn't seem to
+ be in use on any of the supported i386 targets. */
+
+ set_gdbarch_print_float_info (gdbarch, i387_print_float_info);
+
+ set_gdbarch_get_longjmp_target (gdbarch, i386_get_longjmp_target);
- /* FIXME: kettenis/2001-11-24: Although not all IA-32 processors
- have the SSE registers, it's easier to set the default to 8. */
- tdep->num_xmm_regs = 8;
+ /* Call dummy code. */
+ set_gdbarch_push_dummy_call (gdbarch, i386_push_dummy_call);
- set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+ set_gdbarch_convert_register_p (gdbarch, i386_convert_register_p);
+ set_gdbarch_register_to_value (gdbarch, i386_register_to_value);
+ set_gdbarch_value_to_register (gdbarch, i386_value_to_register);
- /* Call dummy code. */
- set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
- set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 5);
- set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
- set_gdbarch_call_dummy_p (gdbarch, 1);
- set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+ set_gdbarch_return_value (gdbarch, i386_return_value);
+
+ set_gdbarch_skip_prologue (gdbarch, i386_skip_prologue);
+
+ /* Stack grows downward. */
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ set_gdbarch_breakpoint_from_pc (gdbarch, i386_breakpoint_from_pc);
+ set_gdbarch_decr_pc_after_break (gdbarch, 1);
+
+ set_gdbarch_frame_args_skip (gdbarch, 8);
+ set_gdbarch_pc_in_sigtramp (gdbarch, i386_pc_in_sigtramp);
+
+ /* Wire in the MMX registers. */
+ set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs);
+ set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
+ set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
- set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
- set_gdbarch_push_arguments (gdbarch, i386_push_arguments);
+ set_gdbarch_print_insn (gdbarch, i386_print_insn);
- set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
+ set_gdbarch_unwind_dummy_id (gdbarch, i386_unwind_dummy_id);
- /* NOTE: tm-i386nw.h and tm-i386v4.h override this. */
- set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+ set_gdbarch_unwind_pc (gdbarch, i386_unwind_pc);
- /* NOTE: tm-i386aix.h, tm-i386bsd.h, tm-i386os9k.h, tm-linux.h,
- tm-ptx.h, tm-symmetry.h currently override this. Sigh. */
- set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SSE_REGS);
+ /* Add the i386 register groups. */
+ i386_add_reggroups (gdbarch);
+ set_gdbarch_register_reggroup_p (gdbarch, i386_register_reggroup_p);
+
+ /* Helper for function argument information. */
+ set_gdbarch_fetch_pointer_argument (gdbarch, i386_fetch_pointer_argument);
+
+ /* Hook in the DWARF CFI frame unwinder. */
+ frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+
+ frame_base_set_default (gdbarch, &i386_frame_base);
+
+ /* Hook in ABI-specific overrides, if they have been registered. */
+ gdbarch_init_osabi (info, gdbarch);
+
+ frame_unwind_append_sniffer (gdbarch, i386_sigtramp_frame_sniffer);
+ frame_unwind_append_sniffer (gdbarch, i386_frame_sniffer);
+
+ /* If we have a register mapping, enable the generic core file
+ support, unless it has already been enabled. */
+ if (tdep->gregset_reg_offset
+ && !gdbarch_regset_from_core_section_p (gdbarch))
+ set_gdbarch_regset_from_core_section (gdbarch,
+ i386_regset_from_core_section);
+
+ /* Unless support for MMX has been disabled, make %mm0 the first
+ pseudo-register. */
+ if (tdep->mm0_regnum == 0)
+ tdep->mm0_regnum = gdbarch_num_regs (gdbarch);
return gdbarch;
}
+static enum gdb_osabi
+i386_coff_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "coff-go32-exe") == 0
+ || strcmp (bfd_get_target (abfd), "coff-go32") == 0)
+ return GDB_OSABI_GO32;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+static enum gdb_osabi
+i386_nlm_osabi_sniffer (bfd *abfd)
+{
+ return GDB_OSABI_NETWARE;
+}
+
+
/* Provide a prototype to silence -Wmissing-prototypes. */
void _initialize_i386_tdep (void);
@@ -1352,22 +2064,6 @@ _initialize_i386_tdep (void)
{
register_gdbarch_init (bfd_arch_i386, i386_gdbarch_init);
- /* Initialize the table saying where each register starts in the
- register file. */
- {
- int i, offset;
-
- offset = 0;
- for (i = 0; i < MAX_NUM_REGS; i++)
- {
- i386_register_offset[i] = offset;
- offset += i386_register_size[i];
- }
- }
-
- tm_print_insn = gdb_print_insn_i386;
- tm_print_insn_info.mach = bfd_lookup_arch (bfd_arch_i386, 0)->mach;
-
/* Add the variable that controls the disassembly flavor. */
{
struct cmd_list_element *new_cmd;
@@ -1381,4 +2077,33 @@ and the default value is \"att\".",
&setlist);
add_show_from_set (new_cmd, &showlist);
}
+
+ /* Add the variable that controls the convention for returning
+ structs. */
+ {
+ struct cmd_list_element *new_cmd;
+
+ new_cmd = add_set_enum_cmd ("struct-convention", no_class,
+ valid_conventions,
+ &struct_convention, "\
+Set the convention for returning small structs, valid values \
+are \"default\", \"pcc\" and \"reg\", and the default value is \"default\".",
+ &setlist);
+ add_show_from_set (new_cmd, &showlist);
+ }
+
+ gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
+ i386_coff_osabi_sniffer);
+ gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_nlm_flavour,
+ i386_nlm_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_SVR4,
+ i386_svr4_init_abi);
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_GO32,
+ i386_go32_init_abi);
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETWARE,
+ i386_nw_init_abi);
+
+ /* Initialize the i386 specific register groups. */
+ i386_init_reggroups ();
}
diff --git a/contrib/gdb/gdb/i386bsd-nat.c b/contrib/gdb/gdb/i386bsd-nat.c
index 5d35830..9383a1d 100644
--- a/contrib/gdb/gdb/i386bsd-nat.c
+++ b/contrib/gdb/gdb/i386bsd-nat.c
@@ -1,5 +1,5 @@
/* Native-dependent code for modern i386 BSD's.
- Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GDB.
@@ -43,6 +43,7 @@ typedef struct fpreg fpregset_t;
#endif
#include "gregset.h"
+#include "i386-tdep.h"
/* In older BSD versions we cannot get at some of the segment
@@ -125,7 +126,7 @@ supply_gregset (gregset_t *gregsetp)
{
int i;
- for (i = 0; i < NUM_GREGS; i++)
+ for (i = 0; i < I386_NUM_GREGS; i++)
{
if (CANNOT_FETCH_REGISTER (i))
supply_register (i, NULL);
@@ -143,12 +144,12 @@ fill_gregset (gregset_t *gregsetp, int regno)
{
int i;
- for (i = 0; i < NUM_GREGS; i++)
+ for (i = 0; i < I386_NUM_GREGS; i++)
if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i))
regcache_collect (i, REG_ADDR (gregsetp, i));
}
-#include "i387-nat.h"
+#include "i387-tdep.h"
/* Fill GDB's register array with the floating-point register values
in *FPREGSETP. */
@@ -156,7 +157,7 @@ fill_gregset (gregset_t *gregsetp, int regno)
void
supply_fpregset (fpregset_t *fpregsetp)
{
- i387_supply_fsave ((char *) fpregsetp);
+ i387_supply_fsave (current_regcache, -1, fpregsetp);
}
/* Fill register REGNO (if it is a floating-point register) in
@@ -175,7 +176,6 @@ fill_fpregset (fpregset_t *fpregsetp, int regno)
void
fetch_inferior_registers (int regno)
{
-
if (regno == -1 || GETREGS_SUPPLIES (regno))
{
gregset_t gregs;
@@ -195,12 +195,12 @@ fetch_inferior_registers (int regno)
#ifdef HAVE_PT_GETXMMREGS
char xmmregs[512];
- if (have_ptrace_xmmregs != 0 &&
- ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
- (PTRACE_ARG3_TYPE) xmmregs, 0) == 0)
+ if (have_ptrace_xmmregs != 0
+ && ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) xmmregs, 0) == 0)
{
have_ptrace_xmmregs = 1;
- i387_supply_fxsave (xmmregs);
+ i387_supply_fxsave (current_regcache, -1, xmmregs);
}
else
{
@@ -208,14 +208,14 @@ fetch_inferior_registers (int regno)
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
perror_with_name ("Couldn't get floating point status");
- supply_fpregset (&fpregs);
+ i387_supply_fsave (current_regcache, -1, &fpregs);
}
#else
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
perror_with_name ("Couldn't get floating point status");
- supply_fpregset (&fpregs);
+ i387_supply_fsave (current_regcache, -1, &fpregs);
#endif
}
}
@@ -226,7 +226,6 @@ fetch_inferior_registers (int regno)
void
store_inferior_registers (int regno)
{
-
if (regno == -1 || GETREGS_SUPPLIES (regno))
{
gregset_t gregs;
@@ -251,9 +250,9 @@ store_inferior_registers (int regno)
#ifdef HAVE_PT_GETXMMREGS
char xmmregs[512];
- if (have_ptrace_xmmregs != 0 &&
- ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
- (PTRACE_ARG3_TYPE) xmmregs, 0) == 0)
+ if (have_ptrace_xmmregs != 0
+ && ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) xmmregs, 0) == 0)
{
have_ptrace_xmmregs = 1;
@@ -271,7 +270,7 @@ store_inferior_registers (int regno)
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
perror_with_name ("Couldn't get floating point status");
- fill_fpregset (&fpregs, regno);
+ i387_fill_fsave ((char *) &fpregs, regno);
if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
@@ -305,7 +304,7 @@ i386bsd_dr_set (int regnum, unsigned int value)
/* For some mysterious reason, some of the reserved bits in the
debug control register get set. Mask these off, otherwise the
ptrace call below will fail. */
- dbregs.dr7 &= ~(0x0000fc00);
+ DBREG_DRX ((&dbregs), 7) &= ~(0x0000fc00);
DBREG_DRX ((&dbregs), regnum) = value;
@@ -354,7 +353,7 @@ i386bsd_dr_get_status (void)
return 0;
#endif
- return dbregs.dr6;
+ return DBREG_DRX ((&dbregs), 6);
}
#endif /* PT_GETDBREGS */
@@ -382,19 +381,76 @@ kernel_u_size (void)
return (sizeof (struct user));
}
-/* See i386bsd-tdep.c. */
-extern int i386bsd_sigcontext_pc_offset;
-
void
_initialize_i386bsd_nat (void)
{
+ int offset;
+
/* To support the recognition of signal handlers, i386bsd-tdep.c
hardcodes some constants. Inclusion of this file means that we
are compiling a native debugger, which means that we can use the
system header files and sysctl(3) to get at the relevant
information. */
+#if defined (__FreeBSD_version) && __FreeBSD_version >= 400011
+#define SC_REG_OFFSET i386fbsd4_sc_reg_offset
+#elif defined (__FreeBSD_version) && __FreeBSD_version >= 300005
+#define SC_REG_OFFSET i386fbsd_sc_reg_offset
+#elif defined (NetBSD) || defined (__NetBSD_Version__)
+#define SC_REG_OFFSET i386nbsd_sc_reg_offset
+#elif defined (OpenBSD)
+#define SC_REG_OFFSET i386obsd_sc_reg_offset
+#else
+#define SC_REG_OFFSET i386bsd_sc_reg_offset
+#endif
+
+ /* We only check the program counter, stack pointer and frame
+ pointer since these members of `struct sigcontext' are essential
+ for providing backtraces. More checks could be added, but would
+ involve adding configure checks for the appropriate structure
+ members, since older BSD's don't provide all of them. */
+
+#define SC_PC_OFFSET SC_REG_OFFSET[I386_EIP_REGNUM]
+#define SC_SP_OFFSET SC_REG_OFFSET[I386_ESP_REGNUM]
+#define SC_FP_OFFSET SC_REG_OFFSET[I386_EBP_REGNUM]
+
/* Override the default value for the offset of the program counter
in the sigcontext structure. */
- i386bsd_sigcontext_pc_offset = offsetof (struct sigcontext, sc_pc);
+ offset = offsetof (struct sigcontext, sc_pc);
+
+ if (SC_PC_OFFSET != offset)
+ {
+ warning ("\
+offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>.",
+ offset, SC_PC_OFFSET);
+ }
+
+ SC_PC_OFFSET = offset;
+
+ /* Likewise for the stack pointer. */
+ offset = offsetof (struct sigcontext, sc_sp);
+
+ if (SC_SP_OFFSET != offset)
+ {
+ warning ("\
+offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>.",
+ offset, SC_SP_OFFSET);
+ }
+
+ SC_SP_OFFSET = offset;
+
+ /* And the frame pointer. */
+ offset = offsetof (struct sigcontext, sc_fp);
+
+ if (SC_FP_OFFSET != offset)
+ {
+ warning ("\
+offsetof (struct sigcontext, sc_fp) yields %d instead of %d.\n\
+Please report this to <bug-gdb@gnu.org>.",
+ offset, SC_FP_OFFSET);
+ }
+
+ SC_FP_OFFSET = offset;
}
diff --git a/contrib/gdb/gdb/infptrace.c b/contrib/gdb/gdb/infptrace.c
index 777a5b4..ef86f90 100644
--- a/contrib/gdb/gdb/infptrace.c
+++ b/contrib/gdb/gdb/infptrace.c
@@ -208,6 +208,7 @@ ptrace_wait (ptid_t ptid, int *status)
return wstate;
}
+#ifndef KILL_INFERIOR
void
kill_inferior (void)
{
@@ -229,6 +230,7 @@ kill_inferior (void)
ptrace_wait (null_ptid, &status);
target_mourn_inferior ();
}
+#endif /* KILL_INFERIOR */
#ifndef CHILD_RESUME
@@ -302,7 +304,7 @@ detach (int signal)
ptrace (PT_DETACH, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) 1,
signal);
if (errno)
- perror_with_name ("ptrace");
+ print_sys_errmsg ("ptrace", errno);
attach_flag = 0;
}
#endif /* ATTACH_DETACH */
@@ -357,14 +359,14 @@ fetch_register (int regno)
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
char mess[128]; /* For messages */
- register int i;
+ int i;
unsigned int offset; /* Offset of registers within the u area. */
- char *buf = alloca (MAX_REGISTER_RAW_SIZE);
+ char buf[MAX_REGISTER_SIZE];
int tid;
if (CANNOT_FETCH_REGISTER (regno))
{
- memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
+ memset (buf, '\0', DEPRECATED_REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
supply_register (regno, buf);
return;
}
@@ -376,7 +378,7 @@ fetch_register (int regno)
offset = U_REGS_OFFSET;
regaddr = register_addr (regno, offset);
- for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
{
errno = 0;
*(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
@@ -421,10 +423,10 @@ store_register (int regno)
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
char mess[128]; /* For messages */
- register int i;
+ int i;
unsigned int offset; /* Offset of registers within the u area. */
int tid;
- char *buf = alloca (MAX_REGISTER_RAW_SIZE);
+ char buf[MAX_REGISTER_SIZE];
if (CANNOT_STORE_REGISTER (regno))
{
@@ -443,7 +445,7 @@ store_register (int regno)
regcache_collect (regno, buf);
/* Store the local buffer into the inferior a chunk at the time. */
- for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+ for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
{
errno = 0;
ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
@@ -514,6 +516,37 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
PTRACE_XFER_TYPE *buffer;
struct cleanup *old_chain = NULL;
+#ifdef PT_IO
+ /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO request
+ that promises to be much more efficient in reading and writing
+ data in the traced process's address space. */
+
+ {
+ struct ptrace_io_desc piod;
+
+ /* NOTE: We assume that there are no distinct address spaces for
+ instruction and data. */
+ piod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D;
+ piod.piod_offs = (void *) memaddr;
+ piod.piod_addr = myaddr;
+ piod.piod_len = len;
+
+ if (ptrace (PT_IO, PIDGET (inferior_ptid), (caddr_t) &piod, 0) == -1)
+ {
+ /* If the PT_IO request is somehow not supported, fallback on
+ using PT_WRITE_D/PT_READ_D. Otherwise we will return zero
+ to indicate failure. */
+ if (errno != EINVAL)
+ return 0;
+ }
+ else
+ {
+ /* Return the actual number of bytes read or written. */
+ return piod.piod_len;
+ }
+ }
+#endif
+
/* Allocate buffer of that many longwords. */
if (len < GDB_MAX_ALLOCA)
{
@@ -598,7 +631,7 @@ static void
udot_info (char *dummy1, int dummy2)
{
#if defined (KERNEL_U_SIZE)
- int udot_off; /* Offset into user struct */
+ long udot_off; /* Offset into user struct */
int udot_val; /* Value from user struct at udot_off */
char mess[128]; /* For messages */
#endif
@@ -626,12 +659,13 @@ udot_info (char *dummy1, int dummy2)
{
printf_filtered ("\n");
}
- printf_filtered ("%04x:", udot_off);
+ printf_filtered ("%s:", paddr (udot_off));
}
udot_val = ptrace (PT_READ_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) udot_off, 0);
if (errno != 0)
{
- sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
+ sprintf (mess, "\nreading user struct at offset 0x%s",
+ paddr_nz (udot_off));
perror_with_name (mess);
}
/* Avoid using nonportable (?) "*" in print specs */
diff --git a/contrib/gdb/gdb/main.c b/contrib/gdb/gdb/main.c
index 7ef8647..7385cfd 100644
--- a/contrib/gdb/gdb/main.c
+++ b/contrib/gdb/gdb/main.c
@@ -1,7 +1,8 @@
/* Top level stuff for GDB, the GNU debugger.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
This file is part of GDB.
@@ -37,6 +38,9 @@
#include "event-loop.h"
#include "ui-out.h"
+#include "interps.h"
+#include "main.h"
+
/* If nonzero, display time usage both at startup and for each command. */
int display_time;
@@ -51,26 +55,28 @@ int display_space;
processes UI events asynchronously. */
int event_loop_p = 1;
-/* Has an interpreter been specified and if so, which. */
+/* The selected interpreter. This will be used as a set command
+ variable, so it should always be malloc'ed - since
+ do_setshow_command will free it. */
char *interpreter_p;
-/* Whether this is the command line version or not */
-int tui_version = 0;
-
/* Whether xdb commands will be handled */
int xdb_commands = 0;
/* Whether dbx commands will be handled */
int dbx_commands = 0;
+/* System root path, used to find libraries etc. */
+char *gdb_sysroot = 0;
+
struct ui_file *gdb_stdout;
struct ui_file *gdb_stderr;
struct ui_file *gdb_stdlog;
+struct ui_file *gdb_stdin;
+/* target IO streams */
+struct ui_file *gdb_stdtargin;
struct ui_file *gdb_stdtarg;
-
-/* Used to initialize error() - defined in utils.c */
-
-extern void error_init (void);
+struct ui_file *gdb_stdtargerr;
/* Whether to enable writing into executable and core files */
extern int write_files;
@@ -88,10 +94,7 @@ extern char *external_editor_command;
static int
captured_command_loop (void *data)
{
- if (command_loop_hook == NULL)
- command_loop ();
- else
- command_loop_hook ();
+ current_interp_command_loop ();
/* FIXME: cagney/1999-11-05: A correct command_loop() implementaton
would clean things up (restoring the cleanup chain) to the state
they were just prior to the call. Technically, this means that
@@ -108,12 +111,6 @@ captured_command_loop (void *data)
return 1;
}
-struct captured_main_args
- {
- int argc;
- char **argv;
- };
-
static int
captured_main (void *data)
{
@@ -153,19 +150,25 @@ captured_main (void *data)
struct stat homebuf, cwdbuf;
char *homedir, *homeinit;
- register int i;
+ int i;
long time_at_startup = get_run_time ();
- START_PROGRESS (argv[0], 0);
-
-#ifdef MPW
- /* Do all Mac-specific setup. */
- mac_init ();
-#endif /* MPW */
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+#if defined (HAVE_SETLOCALE)
+ setlocale (LC_CTYPE, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
/* This needs to happen before the first use of malloc. */
- init_malloc ((PTR) NULL);
+ init_malloc (NULL);
+
+#ifdef HAVE_SBRK
+ lim_at_start = (char *) sbrk (0);
+#endif
#if defined (ALIGN_STACK_ON_STARTUP)
i = (int) &count & 0x3;
@@ -192,29 +195,73 @@ captured_main (void *data)
gdb_stderr = stdio_fileopen (stderr);
gdb_stdlog = gdb_stderr; /* for moment */
gdb_stdtarg = gdb_stderr; /* for moment */
+ gdb_stdin = stdio_fileopen (stdin);
+ gdb_stdtargerr = gdb_stderr; /* for moment */
+ gdb_stdtargin = gdb_stdin; /* for moment */
/* initialize error() */
error_init ();
+ /* Set the sysroot path. */
+#ifdef TARGET_SYSTEM_ROOT_RELOCATABLE
+ gdb_sysroot = make_relative_prefix (argv[0], BINDIR, TARGET_SYSTEM_ROOT);
+ if (gdb_sysroot)
+ {
+ struct stat s;
+ int res = 0;
+
+ if (stat (gdb_sysroot, &s) == 0)
+ if (S_ISDIR (s.st_mode))
+ res = 1;
+
+ if (res == 0)
+ {
+ xfree (gdb_sysroot);
+ gdb_sysroot = TARGET_SYSTEM_ROOT;
+ }
+ }
+ else
+ gdb_sysroot = TARGET_SYSTEM_ROOT;
+#else
+#if defined (TARGET_SYSTEM_ROOT)
+ gdb_sysroot = TARGET_SYSTEM_ROOT;
+#else
+ gdb_sysroot = "";
+#endif
+#endif
+
+ /* There will always be an interpreter. Either the one passed into
+ this captured main, or one specified by the user at start up, or
+ the console. Initialize the interpreter to the one requested by
+ the application. */
+ interpreter_p = xstrdup (context->interpreter_p);
+
/* Parse arguments and options. */
{
int c;
/* When var field is 0, use flag field to record the equivalent
short option (or arbitrary numbers starting at 10 for those
with no equivalent). */
+ enum {
+ OPT_SE = 10,
+ OPT_CD,
+ OPT_ANNOTATE,
+ OPT_STATISTICS,
+ OPT_TUI,
+ OPT_NOWINDOWS,
+ OPT_WINDOWS
+ };
static struct option long_options[] =
{
{"async", no_argument, &event_loop_p, 1},
{"noasync", no_argument, &event_loop_p, 0},
#if defined(TUI)
- {"tui", no_argument, &tui_version, 1},
+ {"tui", no_argument, 0, OPT_TUI},
#endif
{"xdb", no_argument, &xdb_commands, 1},
{"dbx", no_argument, &dbx_commands, 1},
{"readnow", no_argument, &readnow_symbol_files, 1},
{"r", no_argument, &readnow_symbol_files, 1},
- {"mapped", no_argument, &mapped_symbol_files, 1},
- {"m", no_argument, &mapped_symbol_files, 1},
{"quiet", no_argument, &quiet, 1},
{"q", no_argument, &quiet, 1},
{"silent", no_argument, &quiet, 1},
@@ -229,9 +276,9 @@ captured_main (void *data)
{"fullname", no_argument, 0, 'f'},
{"f", no_argument, 0, 'f'},
- {"annotate", required_argument, 0, 12},
+ {"annotate", required_argument, 0, OPT_ANNOTATE},
{"help", no_argument, &print_help, 1},
- {"se", required_argument, 0, 10},
+ {"se", required_argument, 0, OPT_SE},
{"symbols", required_argument, 0, 's'},
{"s", required_argument, 0, 's'},
{"exec", required_argument, 0, 'e'},
@@ -253,21 +300,17 @@ captured_main (void *data)
{"i", required_argument, 0, 'i'},
{"directory", required_argument, 0, 'd'},
{"d", required_argument, 0, 'd'},
- {"cd", required_argument, 0, 11},
+ {"cd", required_argument, 0, OPT_CD},
{"tty", required_argument, 0, 't'},
{"baud", required_argument, 0, 'b'},
{"b", required_argument, 0, 'b'},
- {"nw", no_argument, &use_windows, 0},
- {"nowindows", no_argument, &use_windows, 0},
- {"w", no_argument, &use_windows, 1},
- {"windows", no_argument, &use_windows, 1},
- {"statistics", no_argument, 0, 13},
+ {"nw", no_argument, NULL, OPT_NOWINDOWS},
+ {"nowindows", no_argument, NULL, OPT_NOWINDOWS},
+ {"w", no_argument, NULL, OPT_WINDOWS},
+ {"windows", no_argument, NULL, OPT_WINDOWS},
+ {"statistics", no_argument, 0, OPT_STATISTICS},
{"write", no_argument, &write_files, 1},
{"args", no_argument, &set_args, 1},
-/* Allow machine descriptions to add more options... */
-#ifdef ADDITIONAL_OPTIONS
- ADDITIONAL_OPTIONS
-#endif
{0, no_argument, 0, 0}
};
@@ -289,22 +332,38 @@ captured_main (void *data)
case 0:
/* Long option that just sets a flag. */
break;
- case 10:
+ case OPT_SE:
symarg = optarg;
execarg = optarg;
break;
- case 11:
+ case OPT_CD:
cdarg = optarg;
break;
- case 12:
+ case OPT_ANNOTATE:
/* FIXME: what if the syntax is wrong (e.g. not digits)? */
annotation_level = atoi (optarg);
break;
- case 13:
+ case OPT_STATISTICS:
/* Enable the display of both time and space usage. */
display_time = 1;
display_space = 1;
break;
+ case OPT_TUI:
+ /* --tui is equivalent to -i=tui. */
+ xfree (interpreter_p);
+ interpreter_p = xstrdup ("tui");
+ break;
+ case OPT_WINDOWS:
+ /* FIXME: cagney/2003-03-01: Not sure if this option is
+ actually useful, and if it is, what it should do. */
+ use_windows = 1;
+ break;
+ case OPT_NOWINDOWS:
+ /* -nw is equivalent to -i=console. */
+ xfree (interpreter_p);
+ interpreter_p = xstrdup (INTERP_CONSOLE);
+ use_windows = 0;
+ break;
case 'f':
annotation_level = 1;
/* We have probably been invoked from emacs. Disable window interface. */
@@ -338,7 +397,7 @@ captured_main (void *data)
extern int gdbtk_test (char *);
if (!gdbtk_test (optarg))
{
- fprintf_unfiltered (gdb_stderr, "%s: unable to load tclcommand file \"%s\"",
+ fprintf_unfiltered (gdb_stderr, _("%s: unable to load tclcommand file \"%s\""),
argv[0], optarg);
exit (1);
}
@@ -354,7 +413,8 @@ extern int gdbtk_test (char *);
}
#endif /* GDBTK */
case 'i':
- interpreter_p = optarg;
+ xfree (interpreter_p);
+ interpreter_p = xstrdup (optarg);
break;
case 'd':
dirarg[ndir++] = optarg;
@@ -384,10 +444,11 @@ extern int gdbtk_test (char *);
fprintf_unfiltered
(gdb_stderr,
- "warning: could not set baud rate to `%s'.\n", optarg);
+ _("warning: could not set baud rate to `%s'.\n"), optarg);
else
baud_rate = i;
}
+ break;
case 'l':
{
int i;
@@ -401,18 +462,15 @@ extern int gdbtk_test (char *);
fprintf_unfiltered
(gdb_stderr,
- "warning: could not set timeout limit to `%s'.\n", optarg);
+ _("warning: could not set timeout limit to `%s'.\n"), optarg);
else
remote_timeout = i;
}
break;
-#ifdef ADDITIONAL_OPTION_CASES
- ADDITIONAL_OPTION_CASES
-#endif
case '?':
fprintf_unfiltered (gdb_stderr,
- "Use `%s --help' for a complete list of options.\n",
+ _("Use `%s --help' for a complete list of options.\n"),
argv[0]);
exit (1);
}
@@ -422,19 +480,8 @@ extern int gdbtk_test (char *);
if (print_help || print_version)
{
use_windows = 0;
-#ifdef TUI
- /* Disable the TUI as well. */
- tui_version = 0;
-#endif
}
-#ifdef TUI
- /* An explicit --tui flag overrides the default UI, which is the
- window system. */
- if (tui_version)
- use_windows = 0;
-#endif
-
if (set_args)
{
/* The remaining options are the command-line options for the
@@ -443,7 +490,7 @@ extern int gdbtk_test (char *);
if (optind >= argc)
{
fprintf_unfiltered (gdb_stderr,
- "%s: `--args' specified but no program specified\n",
+ _("%s: `--args' specified but no program specified\n"),
argv[0]);
exit (1);
}
@@ -470,7 +517,7 @@ extern int gdbtk_test (char *);
break;
case 3:
fprintf_unfiltered (gdb_stderr,
- "Excess command line arguments ignored. (%s%s)\n",
+ _("Excess command line arguments ignored. (%s%s)\n"),
argv[optind], (optind == argc - 1) ? "" : " ...");
break;
}
@@ -484,7 +531,10 @@ extern int gdbtk_test (char *);
gdb_init (argv[0]);
/* Do these (and anything which might call wrap_here or *_filtered)
- after initialize_all_files. */
+ after initialize_all_files() but before the interpreter has been
+ installed. Otherwize the help/version messages will be eaten by
+ the interpreter's output handler. */
+
if (print_version)
{
print_gdb_version (gdb_stdout);
@@ -500,7 +550,45 @@ extern int gdbtk_test (char *);
exit (0);
}
- if (!quiet)
+ /* FIXME: cagney/2003-02-03: The big hack (part 1 of 2) that lets
+ GDB retain the old MI1 interpreter startup behavior. Output the
+ copyright message before the interpreter is installed. That way
+ it isn't encapsulated in MI output. */
+ if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
+ {
+ /* Print all the junk at the top, with trailing "..." if we are about
+ to read a symbol file (possibly slowly). */
+ print_gdb_version (gdb_stdout);
+ if (symarg)
+ printf_filtered ("..");
+ wrap_here ("");
+ gdb_flush (gdb_stdout); /* Force to screen during slow operations */
+ }
+
+
+ /* Install the default UI. All the interpreters should have had a
+ look at things by now. Initialize the default interpreter. */
+
+ {
+ /* Find it. */
+ struct interp *interp = interp_lookup (interpreter_p);
+ if (interp == NULL)
+ error ("Interpreter `%s' unrecognized", interpreter_p);
+ /* Install it. */
+ if (!interp_set (interp))
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "Interpreter `%s' failed to initialize.\n",
+ interpreter_p);
+ exit (1);
+ }
+ }
+
+ /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets
+ GDB retain the old MI1 interpreter startup behavior. Output the
+ copyright message after the interpreter is installed when it is
+ any sane interpreter. */
+ if (!quiet && !current_interp_named_p (INTERP_MI1))
{
/* Print all the junk at the top, with trailing "..." if we are about
to read a symbol file (possibly slowly). */
@@ -515,7 +603,7 @@ extern int gdbtk_test (char *);
quit_pre_print = error_pre_print;
/* We may get more than one warning, don't double space all of them... */
- warning_pre_print = "\nwarning: ";
+ warning_pre_print = _("\nwarning: ");
/* Read and execute $HOME/.gdbinit file, if it exists. This is done
*before* all the command line arguments are processed; it sets
@@ -560,7 +648,7 @@ extern int gdbtk_test (char *);
if (execarg != NULL
&& symarg != NULL
- && STREQ (execarg, symarg))
+ && strcmp (execarg, symarg) == 0)
{
/* The exec file and the symbol-file are the same. If we can't
open it, better only print one error message.
@@ -583,7 +671,7 @@ extern int gdbtk_test (char *);
printf_filtered ("\n");
error_pre_print = "\n";
quit_pre_print = error_pre_print;
- warning_pre_print = "\nwarning: ";
+ warning_pre_print = _("\nwarning: ");
if (corearg != NULL)
{
@@ -606,14 +694,10 @@ extern int gdbtk_test (char *);
if (ttyarg != NULL)
catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL);
-#ifdef ADDITIONAL_OPTION_HANDLER
- ADDITIONAL_OPTION_HANDLER;
-#endif
-
/* Error messages should no longer be distinguished with extra output. */
error_pre_print = NULL;
quit_pre_print = NULL;
- warning_pre_print = "warning: ";
+ warning_pre_print = _("warning: ");
/* Read the .gdbinit file in the current directory, *if* it isn't
the same as the $HOME/.gdbinit file (it should exist, also). */
@@ -664,15 +748,13 @@ extern int gdbtk_test (char *);
BEFORE_MAIN_LOOP_HOOK;
#endif
- END_PROGRESS (argv[0]);
-
/* Show time and/or space usage. */
if (display_time)
{
long init_time = get_run_time () - time_at_startup;
- printf_unfiltered ("Startup time: %ld.%06ld\n",
+ printf_unfiltered (_("Startup time: %ld.%06ld\n"),
init_time / 1000000, init_time % 1000000);
}
@@ -682,7 +764,7 @@ extern int gdbtk_test (char *);
extern char **environ;
char *lim = (char *) sbrk (0);
- printf_unfiltered ("Startup size: data size %ld\n",
+ printf_unfiltered (_("Startup size: data size %ld\n"),
(long) (lim - (char *) &environ));
#endif
}
@@ -726,13 +808,13 @@ extern int gdbtk_test (char *);
}
int
-main (int argc, char **argv)
+gdb_main (struct captured_main_args *args)
{
- struct captured_main_args args;
- args.argc = argc;
- args.argv = argv;
- catch_errors (captured_main, &args, "", RETURN_MASK_ALL);
- return 0;
+ use_windows = args->use_windows;
+ catch_errors (captured_main, args, "", RETURN_MASK_ALL);
+ /* The only way to end up here is by an error (normal exit is
+ handled by quit_force()), hence always return an error status. */
+ return 1;
}
@@ -743,69 +825,66 @@ main (int argc, char **argv)
static void
print_gdb_help (struct ui_file *stream)
{
- fputs_unfiltered ("\
+ fputs_unfiltered (_("\
This is the GNU debugger. Usage:\n\n\
gdb [options] [executable-file [core-file or process-id]]\n\
gdb [options] --args executable-file [inferior-arguments ...]\n\n\
Options:\n\n\
-", stream);
- fputs_unfiltered ("\
+"), stream);
+ fputs_unfiltered (_("\
--args Arguments after executable-file are passed to inferior\n\
-", stream);
- fputs_unfiltered ("\
+"), stream);
+ fputs_unfiltered (_("\
--[no]async Enable (disable) asynchronous version of CLI\n\
-", stream);
- fputs_unfiltered ("\
+"), stream);
+ fputs_unfiltered (_("\
-b BAUDRATE Set serial port baud rate used for remote debugging.\n\
--batch Exit after processing options.\n\
--cd=DIR Change current directory to DIR.\n\
--command=FILE Execute GDB commands from FILE.\n\
--core=COREFILE Analyze the core dump COREFILE.\n\
--pid=PID Attach to running process PID.\n\
-", stream);
- fputs_unfiltered ("\
+"), stream);
+ fputs_unfiltered (_("\
--dbx DBX compatibility mode.\n\
--directory=DIR Search for source files in DIR.\n\
--epoch Output information used by epoch emacs-GDB interface.\n\
--exec=EXECFILE Use EXECFILE as the executable.\n\
--fullname Output information used by emacs-GDB interface.\n\
--help Print this message.\n\
-", stream);
- fputs_unfiltered ("\
+"), stream);
+ fputs_unfiltered (_("\
--interpreter=INTERP\n\
Select a specific interpreter / user interface\n\
-", stream);
- fputs_unfiltered ("\
+"), stream);
+ fputs_unfiltered (_("\
--mapped Use mapped symbol files if supported on this system.\n\
--nw Do not use a window interface.\n\
- --nx Do not read ", stream);
+ --nx Do not read "), stream);
fputs_unfiltered (gdbinit, stream);
- fputs_unfiltered (" file.\n\
+ fputs_unfiltered (_(" file.\n\
--quiet Do not print version number on startup.\n\
--readnow Fully read symbol files on first access.\n\
-", stream);
- fputs_unfiltered ("\
+"), stream);
+ fputs_unfiltered (_("\
--se=FILE Use FILE as symbol file and executable file.\n\
--symbols=SYMFILE Read symbols from SYMFILE.\n\
--tty=TTY Use TTY for input/output by the program being debugged.\n\
-", stream);
+"), stream);
#if defined(TUI)
- fputs_unfiltered ("\
+ fputs_unfiltered (_("\
--tui Use a terminal user interface.\n\
-", stream);
+"), stream);
#endif
- fputs_unfiltered ("\
+ fputs_unfiltered (_("\
--version Print version information and then exit.\n\
-w Use a window interface.\n\
--write Set writing into executable and core files.\n\
--xdb XDB compatibility mode.\n\
-", stream);
-#ifdef ADDITIONAL_OPTION_HELP
- fputs_unfiltered (ADDITIONAL_OPTION_HELP, stream);
-#endif
- fputs_unfiltered ("\n\
+"), stream);
+ fputs_unfiltered (_("\n\
For more information, type \"help\" from within GDB, or consult the\n\
GDB manual (available as on-line info or a printed manual).\n\
Report bugs to \"bug-gdb@gnu.org\".\
-", stream);
+"), stream);
}
diff --git a/contrib/gdb/gdb/objfiles.c b/contrib/gdb/gdb/objfiles.c
index e2a6f85..6179077 100644
--- a/contrib/gdb/gdb/objfiles.c
+++ b/contrib/gdb/gdb/objfiles.c
@@ -1,6 +1,8 @@
/* GDB routines for manipulating objfiles.
- Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
- Free Software Foundation, Inc.
+
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
Contributed by Cygnus Support, using pieces from other GDB modules.
This file is part of GDB.
@@ -30,30 +32,24 @@
#include "objfiles.h"
#include "gdb-stabs.h"
#include "target.h"
+#include "bcache.h"
+#include "gdb_assert.h"
#include <sys/types.h>
#include "gdb_stat.h"
#include <fcntl.h>
-#include "obstack.h"
+#include "gdb_obstack.h"
#include "gdb_string.h"
+#include "hashtab.h"
#include "breakpoint.h"
+#include "block.h"
+#include "dictionary.h"
/* Prototypes for local functions */
-#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
-
-#include "mmalloc.h"
-
-static int open_existing_mapped_file (char *, long, int);
-
-static int open_mapped_file (char *filename, long mtime, int flags);
-
-static PTR map_to_file (int);
-
-#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
-
-static void add_to_objfile_sections (bfd *, sec_ptr, PTR);
+static void objfile_alloc_data (struct objfile *objfile);
+static void objfile_free_data (struct objfile *objfile);
/* Externally visible variables that are owned by this module.
See declarations in objfile.h for more info. */
@@ -63,8 +59,6 @@ struct objfile *current_objfile; /* For symbol file being read in */
struct objfile *symfile_objfile; /* Main symbol table loaded from */
struct objfile *rt_common_objfile; /* For runtime common symbols */
-int mapped_symbol_files; /* Try to use mapped symbol files */
-
/* Locate all mappable sections of a BFD file.
objfile_p_char is a char * to get it through
bfd_map_over_sections; we cast it back to its proper type. */
@@ -79,7 +73,8 @@ int mapped_symbol_files; /* Try to use mapped symbol files */
the end of the table (objfile->sections_end). */
static void
-add_to_objfile_sections (bfd *abfd, sec_ptr asect, PTR objfile_p_char)
+add_to_objfile_sections (struct bfd *abfd, struct bfd_section *asect,
+ void *objfile_p_char)
{
struct objfile *objfile = (struct objfile *) objfile_p_char;
struct obj_section section;
@@ -98,7 +93,7 @@ add_to_objfile_sections (bfd *abfd, sec_ptr asect, PTR objfile_p_char)
section.ovly_mapped = 0;
section.addr = bfd_section_vma (abfd, asect);
section.endaddr = section.addr + bfd_section_size (abfd, asect);
- obstack_grow (&objfile->psymbol_obstack, (char *) &section, sizeof (section));
+ obstack_grow (&objfile->objfile_obstack, (char *) &section, sizeof (section));
objfile->sections_end = (struct obj_section *) (((unsigned long) objfile->sections_end) + 1);
}
@@ -124,13 +119,13 @@ build_objfile_section_table (struct objfile *objfile)
/* objfile->sections can be already set when reading a mapped symbol
file. I believe that we do need to rebuild the section table in
this case (we rebuild other things derived from the bfd), but we
- can't free the old one (it's in the psymbol_obstack). So we just
+ can't free the old one (it's in the objfile_obstack). So we just
waste some memory. */
objfile->sections_end = 0;
bfd_map_over_sections (objfile->obfd, add_to_objfile_sections, (char *) objfile);
objfile->sections = (struct obj_section *)
- obstack_finish (&objfile->psymbol_obstack);
+ obstack_finish (&objfile->objfile_obstack);
objfile->sections_end = objfile->sections + (unsigned long) objfile->sections_end;
return (0);
}
@@ -141,10 +136,17 @@ build_objfile_section_table (struct objfile *objfile)
new objfile struct.
The FLAGS word contains various bits (OBJF_*) that can be taken as
- requests for specific operations, like trying to open a mapped
- version of the objfile (OBJF_MAPPED). Other bits like
- OBJF_SHARED are simply copied through to the new objfile flags
- member. */
+ requests for specific operations. Other bits like OBJF_SHARED are
+ simply copied through to the new objfile flags member. */
+
+/* NOTE: carlton/2003-02-04: This function is called with args NULL, 0
+ by jv-lang.c, to create an artificial objfile used to hold
+ information about dynamically-loaded Java classes. Unfortunately,
+ that branch of this function doesn't get tested very frequently, so
+ it's prone to breakage. (E.g. at one time the name was set to NULL
+ in that situation, which broke a loop over all names in the dynamic
+ library loader.) If you change this function, please try to leave
+ things in a consistent state even if abfd is NULL. */
struct objfile *
allocate_objfile (bfd *abfd, int flags)
@@ -152,109 +154,6 @@ allocate_objfile (bfd *abfd, int flags)
struct objfile *objfile = NULL;
struct objfile *last_one = NULL;
- if (mapped_symbol_files)
- flags |= OBJF_MAPPED;
-
-#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
- if (abfd != NULL)
- {
-
- /* If we can support mapped symbol files, try to open/reopen the
- mapped file that corresponds to the file from which we wish to
- read symbols. If the objfile is to be mapped, we must malloc
- the structure itself using the mmap version, and arrange that
- all memory allocation for the objfile uses the mmap routines.
- If we are reusing an existing mapped file, from which we get
- our objfile pointer, we have to make sure that we update the
- pointers to the alloc/free functions in the obstack, in case
- these functions have moved within the current gdb. */
-
- int fd;
-
- fd = open_mapped_file (bfd_get_filename (abfd), bfd_get_mtime (abfd),
- flags);
- if (fd >= 0)
- {
- PTR md;
-
- if ((md = map_to_file (fd)) == NULL)
- {
- close (fd);
- }
- else if ((objfile = (struct objfile *) mmalloc_getkey (md, 0)) != NULL)
- {
- /* Update memory corruption handler function addresses. */
- init_malloc (md);
- objfile->md = md;
- objfile->mmfd = fd;
- /* Update pointers to functions to *our* copies */
- obstack_chunkfun (&objfile->psymbol_cache.cache, xmmalloc);
- obstack_freefun (&objfile->psymbol_cache.cache, xmfree);
- obstack_chunkfun (&objfile->psymbol_obstack, xmmalloc);
- obstack_freefun (&objfile->psymbol_obstack, xmfree);
- obstack_chunkfun (&objfile->symbol_obstack, xmmalloc);
- obstack_freefun (&objfile->symbol_obstack, xmfree);
- obstack_chunkfun (&objfile->type_obstack, xmmalloc);
- obstack_freefun (&objfile->type_obstack, xmfree);
- /* If already in objfile list, unlink it. */
- unlink_objfile (objfile);
- /* Forget things specific to a particular gdb, may have changed. */
- objfile->sf = NULL;
- }
- else
- {
-
- /* Set up to detect internal memory corruption. MUST be
- done before the first malloc. See comments in
- init_malloc() and mmcheck(). */
-
- init_malloc (md);
-
- objfile = (struct objfile *)
- xmmalloc (md, sizeof (struct objfile));
- memset (objfile, 0, sizeof (struct objfile));
- objfile->md = md;
- objfile->mmfd = fd;
- objfile->flags |= OBJF_MAPPED;
- mmalloc_setkey (objfile->md, 0, objfile);
- obstack_specify_allocation_with_arg (&objfile->psymbol_cache.cache,
- 0, 0, xmmalloc, xmfree,
- objfile->md);
- obstack_specify_allocation_with_arg (&objfile->psymbol_obstack,
- 0, 0, xmmalloc, xmfree,
- objfile->md);
- obstack_specify_allocation_with_arg (&objfile->symbol_obstack,
- 0, 0, xmmalloc, xmfree,
- objfile->md);
- obstack_specify_allocation_with_arg (&objfile->type_obstack,
- 0, 0, xmmalloc, xmfree,
- objfile->md);
- }
- }
-
- if ((flags & OBJF_MAPPED) && (objfile == NULL))
- {
- warning ("symbol table for '%s' will not be mapped",
- bfd_get_filename (abfd));
- flags &= ~OBJF_MAPPED;
- }
- }
-#else /* !defined(USE_MMALLOC) || !defined(HAVE_MMAP) */
-
- if (flags & OBJF_MAPPED)
- {
- warning ("mapped symbol tables are not supported on this machine; missing or broken mmap().");
-
- /* Turn off the global flag so we don't try to do mapped symbol tables
- any more, which shuts up gdb unless the user specifically gives the
- "mapped" keyword again. */
-
- mapped_symbol_files = 0;
- flags &= ~OBJF_MAPPED;
- }
-
-#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
-
/* If we don't support mapped symbol files, didn't ask for the file to be
mapped, or failed to open the mapped file for some reason, then revert
back to an unmapped objfile. */
@@ -264,17 +163,16 @@ allocate_objfile (bfd *abfd, int flags)
objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
memset (objfile, 0, sizeof (struct objfile));
objfile->md = NULL;
- obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0,
- xmalloc, xfree);
- obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0, xmalloc,
- xfree);
- obstack_specify_allocation (&objfile->symbol_obstack, 0, 0, xmalloc,
- xfree);
- obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc,
- xfree);
- flags &= ~OBJF_MAPPED;
+ objfile->psymbol_cache = bcache_xmalloc ();
+ objfile->macro_cache = bcache_xmalloc ();
+ /* We could use obstack_specify_allocation here instead, but
+ gdb_obstack.h specifies the alloc/dealloc functions. */
+ obstack_init (&objfile->objfile_obstack);
+ terminate_minimal_symbol_table (objfile);
}
+ objfile_alloc_data (objfile);
+
/* Update the per-objfile information that comes from the bfd, ensuring
that any data that is reference is saved in the per-objfile data
region. */
@@ -297,14 +195,22 @@ allocate_objfile (bfd *abfd, int flags)
objfile->name, bfd_errmsg (bfd_get_error ()));
}
}
+ else
+ {
+ objfile->name = mstrsave (objfile->md, "<<anonymous objfile>>");
+ }
/* Initialize the section indexes for this objfile, so that we can
later detect if they are used w/o being properly assigned to. */
- objfile->sect_index_text = -1;
- objfile->sect_index_data = -1;
- objfile->sect_index_bss = -1;
- objfile->sect_index_rodata = -1;
+ objfile->sect_index_text = -1;
+ objfile->sect_index_data = -1;
+ objfile->sect_index_bss = -1;
+ objfile->sect_index_rodata = -1;
+
+ /* We don't yet have a C++-specific namespace symtab. */
+
+ objfile->cp_namespace_symtab = NULL;
/* Add this file onto the tail of the linked list of other such files. */
@@ -325,6 +231,89 @@ allocate_objfile (bfd *abfd, int flags)
return (objfile);
}
+/* Initialize entry point information for this objfile. */
+
+void
+init_entry_point_info (struct objfile *objfile)
+{
+ /* Save startup file's range of PC addresses to help blockframe.c
+ decide where the bottom of the stack is. */
+
+ if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
+ {
+ /* Executable file -- record its entry point so we'll recognize
+ the startup file because it contains the entry point. */
+ objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
+ }
+ else
+ {
+ /* Examination of non-executable.o files. Short-circuit this stuff. */
+ objfile->ei.entry_point = INVALID_ENTRY_POINT;
+ }
+ objfile->ei.deprecated_entry_file_lowpc = INVALID_ENTRY_LOWPC;
+ objfile->ei.deprecated_entry_file_highpc = INVALID_ENTRY_HIGHPC;
+ objfile->ei.entry_func_lowpc = INVALID_ENTRY_LOWPC;
+ objfile->ei.entry_func_highpc = INVALID_ENTRY_HIGHPC;
+ objfile->ei.main_func_lowpc = INVALID_ENTRY_LOWPC;
+ objfile->ei.main_func_highpc = INVALID_ENTRY_HIGHPC;
+}
+
+/* Get current entry point address. */
+
+CORE_ADDR
+entry_point_address (void)
+{
+ return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
+}
+
+/* Create the terminating entry of OBJFILE's minimal symbol table.
+ If OBJFILE->msymbols is zero, allocate a single entry from
+ OBJFILE->objfile_obstack; otherwise, just initialize
+ OBJFILE->msymbols[OBJFILE->minimal_symbol_count]. */
+void
+terminate_minimal_symbol_table (struct objfile *objfile)
+{
+ if (! objfile->msymbols)
+ objfile->msymbols = ((struct minimal_symbol *)
+ obstack_alloc (&objfile->objfile_obstack,
+ sizeof (objfile->msymbols[0])));
+
+ {
+ struct minimal_symbol *m
+ = &objfile->msymbols[objfile->minimal_symbol_count];
+
+ memset (m, 0, sizeof (*m));
+ /* Don't rely on these enumeration values being 0's. */
+ MSYMBOL_TYPE (m) = mst_unknown;
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (m, language_unknown);
+ }
+}
+
+
+/* Put one object file before a specified on in the global list.
+ This can be used to make sure an object file is destroyed before
+ another when using ALL_OBJFILES_SAFE to free all objfiles. */
+void
+put_objfile_before (struct objfile *objfile, struct objfile *before_this)
+{
+ struct objfile **objp;
+
+ unlink_objfile (objfile);
+
+ for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
+ {
+ if (*objp == before_this)
+ {
+ objfile->next = *objp;
+ *objp = objfile;
+ return;
+ }
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "put_objfile_before: before objfile not in list");
+}
+
/* Put OBJFILE at the front of the list. */
void
@@ -379,8 +368,8 @@ unlink_objfile (struct objfile *objfile)
/* Destroy an objfile and all the symtabs and psymtabs under it. Note
- that as much as possible is allocated on the symbol_obstack and
- psymbol_obstack, so that the memory can be efficiently freed.
+ that as much as possible is allocated on the objfile_obstack
+ so that the memory can be efficiently freed.
Things which we do NOT free because they are not in malloc'd memory
or not in memory specific to the objfile include:
@@ -397,6 +386,18 @@ unlink_objfile (struct objfile *objfile)
void
free_objfile (struct objfile *objfile)
{
+ if (objfile->separate_debug_objfile)
+ {
+ free_objfile (objfile->separate_debug_objfile);
+ }
+
+ if (objfile->separate_debug_objfile_backlink)
+ {
+ /* We freed the separate debug file, make sure the base objfile
+ doesn't reference it. */
+ objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
+ }
+
/* First do any symbol file specific actions required when we are
finished with a particular symbol file. Note that if the objfile
is using reusable symbol information (via mmalloc) then each of
@@ -441,48 +442,25 @@ free_objfile (struct objfile *objfile)
to call this here. */
clear_pc_function_cache ();
- /* The last thing we do is free the objfile struct itself for the
- non-reusable case, or detach from the mapped file for the
- reusable case. Note that the mmalloc_detach or the xmfree() is
- the last thing we can do with this objfile. */
+ /* The last thing we do is free the objfile struct itself. */
-#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
-
- if (objfile->flags & OBJF_MAPPED)
- {
- /* Remember the fd so we can close it. We can't close it before
- doing the detach, and after the detach the objfile is gone. */
- int mmfd;
-
- mmfd = objfile->mmfd;
- mmalloc_detach (objfile->md);
- objfile = NULL;
- close (mmfd);
- }
-
-#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
-
- /* If we still have an objfile, then either we don't support reusable
- objfiles or this one was not reusable. So free it normally. */
-
- if (objfile != NULL)
+ objfile_free_data (objfile);
+ if (objfile->name != NULL)
{
- if (objfile->name != NULL)
- {
- xmfree (objfile->md, objfile->name);
- }
- if (objfile->global_psymbols.list)
- xmfree (objfile->md, objfile->global_psymbols.list);
- if (objfile->static_psymbols.list)
- xmfree (objfile->md, objfile->static_psymbols.list);
- /* Free the obstacks for non-reusable objfiles */
- free_bcache (&objfile->psymbol_cache);
- obstack_free (&objfile->psymbol_obstack, 0);
- obstack_free (&objfile->symbol_obstack, 0);
- obstack_free (&objfile->type_obstack, 0);
- xmfree (objfile->md, objfile);
- objfile = NULL;
+ xmfree (objfile->md, objfile->name);
}
+ if (objfile->global_psymbols.list)
+ xmfree (objfile->md, objfile->global_psymbols.list);
+ if (objfile->static_psymbols.list)
+ xmfree (objfile->md, objfile->static_psymbols.list);
+ /* Free the obstacks for non-reusable objfiles */
+ bcache_xfree (objfile->psymbol_cache);
+ bcache_xfree (objfile->macro_cache);
+ if (objfile->demangled_names_hash)
+ htab_delete (objfile->demangled_names_hash);
+ obstack_free (&objfile->objfile_obstack, 0);
+ xmfree (objfile->md, objfile);
+ objfile = NULL;
}
static void
@@ -517,7 +495,8 @@ void
objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
{
struct section_offsets *delta =
- (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
+ ((struct section_offsets *)
+ alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)));
{
int i;
@@ -560,18 +539,18 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
{
struct block *b;
struct symbol *sym;
- int j;
+ struct dict_iterator iter;
b = BLOCKVECTOR_BLOCK (bv, i);
BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
- ALL_BLOCK_SYMBOLS (b, j, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
fixup_symbol_section (sym, objfile);
/* The RS6000 code from which this was taken skipped
- any symbols in STRUCT_NAMESPACE or UNDEF_NAMESPACE.
+ any symbols in STRUCT_DOMAIN or UNDEF_DOMAIN.
But I'm leaving out that test, on the theory that
they can't possibly pass the tests below. */
if ((SYMBOL_CLASS (sym) == LOC_LABEL
@@ -586,8 +565,8 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
/* Relocate Extra Function Info for ecoff. */
else if (SYMBOL_CLASS (sym) == LOC_CONST
- && SYMBOL_NAMESPACE (sym) == LABEL_NAMESPACE
- && strcmp (SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0)
+ && SYMBOL_DOMAIN (sym) == LABEL_DOMAIN
+ && strcmp (DEPRECATED_SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0)
ecoff_relocate_efi (sym, ANOFFSET (delta,
s->block_line_section));
#endif
@@ -678,10 +657,10 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
objfile->ei.entry_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
}
- if (objfile->ei.entry_file_lowpc != INVALID_ENTRY_LOWPC)
+ if (objfile->ei.deprecated_entry_file_lowpc != INVALID_ENTRY_LOWPC)
{
- objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
- objfile->ei.entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ objfile->ei.deprecated_entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+ objfile->ei.deprecated_entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
}
if (objfile->ei.main_func_lowpc != INVALID_ENTRY_LOWPC)
@@ -765,7 +744,7 @@ have_minimal_symbols (void)
ALL_OBJFILES (ofp)
{
- if (ofp->msymbols != NULL)
+ if (ofp->minimal_symbol_count > 0)
{
return 1;
}
@@ -773,176 +752,14 @@ have_minimal_symbols (void)
return 0;
}
-#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
-
-/* Given the name of a mapped symbol file in SYMSFILENAME, and the timestamp
- of the corresponding symbol file in MTIME, try to open an existing file
- with the name SYMSFILENAME and verify it is more recent than the base
- file by checking it's timestamp against MTIME.
-
- If SYMSFILENAME does not exist (or can't be stat'd), simply returns -1.
-
- If SYMSFILENAME does exist, but is out of date, we check to see if the
- user has specified creation of a mapped file. If so, we don't issue
- any warning message because we will be creating a new mapped file anyway,
- overwriting the old one. If not, then we issue a warning message so that
- the user will know why we aren't using this existing mapped symbol file.
- In either case, we return -1.
-
- If SYMSFILENAME does exist and is not out of date, but can't be opened for
- some reason, then prints an appropriate system error message and returns -1.
-
- Otherwise, returns the open file descriptor. */
-
-static int
-open_existing_mapped_file (char *symsfilename, long mtime, int flags)
-{
- int fd = -1;
- struct stat sbuf;
-
- if (stat (symsfilename, &sbuf) == 0)
- {
- if (sbuf.st_mtime < mtime)
- {
- if (!(flags & OBJF_MAPPED))
- {
- warning ("mapped symbol file `%s' is out of date, ignored it",
- symsfilename);
- }
- }
- else if ((fd = open (symsfilename, O_RDWR)) < 0)
- {
- if (error_pre_print)
- {
- printf_unfiltered (error_pre_print);
- }
- print_sys_errmsg (symsfilename, errno);
- }
- }
- return (fd);
-}
-
-/* Look for a mapped symbol file that corresponds to FILENAME and is more
- recent than MTIME. If MAPPED is nonzero, the user has asked that gdb
- use a mapped symbol file for this file, so create a new one if one does
- not currently exist.
-
- If found, then return an open file descriptor for the file, otherwise
- return -1.
-
- This routine is responsible for implementing the policy that generates
- the name of the mapped symbol file from the name of a file containing
- symbols that gdb would like to read. Currently this policy is to append
- ".syms" to the name of the file.
-
- This routine is also responsible for implementing the policy that
- determines where the mapped symbol file is found (the search path).
- This policy is that when reading an existing mapped file, a file of
- the correct name in the current directory takes precedence over a
- file of the correct name in the same directory as the symbol file.
- When creating a new mapped file, it is always created in the current
- directory. This helps to minimize the chances of a user unknowingly
- creating big mapped files in places like /bin and /usr/local/bin, and
- allows a local copy to override a manually installed global copy (in
- /bin for example). */
-
-static int
-open_mapped_file (char *filename, long mtime, int flags)
-{
- int fd;
- char *symsfilename;
-
- /* First try to open an existing file in the current directory, and
- then try the directory where the symbol file is located. */
-
- symsfilename = concat ("./", lbasename (filename), ".syms", (char *) NULL);
- if ((fd = open_existing_mapped_file (symsfilename, mtime, flags)) < 0)
- {
- xfree (symsfilename);
- symsfilename = concat (filename, ".syms", (char *) NULL);
- fd = open_existing_mapped_file (symsfilename, mtime, flags);
- }
-
- /* If we don't have an open file by now, then either the file does not
- already exist, or the base file has changed since it was created. In
- either case, if the user has specified use of a mapped file, then
- create a new mapped file, truncating any existing one. If we can't
- create one, print a system error message saying why we can't.
-
- By default the file is rw for everyone, with the user's umask taking
- care of turning off the permissions the user wants off. */
-
- if ((fd < 0) && (flags & OBJF_MAPPED))
- {
- xfree (symsfilename);
- symsfilename = concat ("./", lbasename (filename), ".syms",
- (char *) NULL);
- if ((fd = open (symsfilename, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0)
- {
- if (error_pre_print)
- {
- printf_unfiltered (error_pre_print);
- }
- print_sys_errmsg (symsfilename, errno);
- }
- }
-
- xfree (symsfilename);
- return (fd);
-}
-
-static PTR
-map_to_file (int fd)
-{
- PTR md;
- CORE_ADDR mapto;
-
- md = mmalloc_attach (fd, (PTR) 0);
- if (md != NULL)
- {
- mapto = (CORE_ADDR) mmalloc_getkey (md, 1);
- md = mmalloc_detach (md);
- if (md != NULL)
- {
- /* FIXME: should figure out why detach failed */
- md = NULL;
- }
- else if (mapto != (CORE_ADDR) NULL)
- {
- /* This mapping file needs to be remapped at "mapto" */
- md = mmalloc_attach (fd, (PTR) mapto);
- }
- else
- {
- /* This is a freshly created mapping file. */
- mapto = (CORE_ADDR) mmalloc_findbase (20 * 1024 * 1024);
- if (mapto != 0)
- {
- /* To avoid reusing the freshly created mapping file, at the
- address selected by mmap, we must truncate it before trying
- to do an attach at the address we want. */
- ftruncate (fd, 0);
- md = mmalloc_attach (fd, (PTR) mapto);
- if (md != NULL)
- {
- mmalloc_setkey (md, 1, (PTR) mapto);
- }
- }
- }
- }
- return (md);
-}
-
-#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
-
-/* Returns a section whose range includes PC and SECTION,
- or NULL if none found. Note the distinction between the return type,
- struct obj_section (which is defined in gdb), and the input type
- struct sec (which is a bfd-defined data type). The obj_section
- contains a pointer to the bfd struct sec section. */
+/* Returns a section whose range includes PC and SECTION, or NULL if
+ none found. Note the distinction between the return type, struct
+ obj_section (which is defined in gdb), and the input type "struct
+ bfd_section" (which is a bfd-defined data type). The obj_section
+ contains a pointer to the "struct bfd_section". */
struct obj_section *
-find_pc_sect_section (CORE_ADDR pc, struct sec *section)
+find_pc_sect_section (CORE_ADDR pc, struct bfd_section *section)
{
struct obj_section *s;
struct objfile *objfile;
@@ -979,7 +796,7 @@ in_plt_section (CORE_ADDR pc, char *name)
retval = (s != NULL
&& s->the_bfd_section->name != NULL
- && STREQ (s->the_bfd_section->name, ".plt"));
+ && strcmp (s->the_bfd_section->name, ".plt") == 0);
return (retval);
}
@@ -989,14 +806,91 @@ in_plt_section (CORE_ADDR pc, char *name)
int
is_in_import_list (char *name, struct objfile *objfile)
{
- register int i;
+ int i;
if (!objfile || !name || !*name)
return 0;
for (i = 0; i < objfile->import_list_size; i++)
- if (objfile->import_list[i] && STREQ (name, objfile->import_list[i]))
+ if (objfile->import_list[i] && DEPRECATED_STREQ (name, objfile->import_list[i]))
return 1;
return 0;
}
+
+
+/* Keep a registry of per-objfile data-pointers required by other GDB
+ modules. */
+
+struct objfile_data
+{
+ unsigned index;
+};
+
+struct objfile_data_registration
+{
+ struct objfile_data *data;
+ struct objfile_data_registration *next;
+};
+
+struct objfile_data_registry
+{
+ struct objfile_data_registration *registrations;
+ unsigned num_registrations;
+};
+
+static struct objfile_data_registry objfile_data_registry = { NULL, 0 };
+
+const struct objfile_data *
+register_objfile_data (void)
+{
+ struct objfile_data_registration **curr;
+
+ /* Append new registration. */
+ for (curr = &objfile_data_registry.registrations;
+ *curr != NULL; curr = &(*curr)->next);
+
+ *curr = XMALLOC (struct objfile_data_registration);
+ (*curr)->next = NULL;
+ (*curr)->data = XMALLOC (struct objfile_data);
+ (*curr)->data->index = objfile_data_registry.num_registrations++;
+
+ return (*curr)->data;
+}
+
+static void
+objfile_alloc_data (struct objfile *objfile)
+{
+ gdb_assert (objfile->data == NULL);
+ objfile->num_data = objfile_data_registry.num_registrations;
+ objfile->data = XCALLOC (objfile->num_data, void *);
+}
+
+static void
+objfile_free_data (struct objfile *objfile)
+{
+ gdb_assert (objfile->data != NULL);
+ xfree (objfile->data);
+ objfile->data = NULL;
+}
+
+void
+clear_objfile_data (struct objfile *objfile)
+{
+ gdb_assert (objfile->data != NULL);
+ memset (objfile->data, 0, objfile->num_data * sizeof (void *));
+}
+void
+set_objfile_data (struct objfile *objfile, const struct objfile_data *data,
+ void *value)
+{
+ gdb_assert (data->index < objfile->num_data);
+ objfile->data[data->index] = value;
+}
+
+void *
+objfile_data (struct objfile *objfile, const struct objfile_data *data)
+{
+ gdb_assert (data->index < objfile->num_data);
+ return objfile->data[data->index];
+}
diff --git a/contrib/gdb/gdb/remote.c b/contrib/gdb/gdb/remote.c
index 2d70baf..29bbbc8 100644
--- a/contrib/gdb/gdb/remote.c
+++ b/contrib/gdb/gdb/remote.c
@@ -1,7 +1,8 @@
/* Remote target communications for serial-line targets in custom GDB protocol
Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -55,6 +56,8 @@
#include "gdbcore.h" /* for exec_bfd */
+#include "remote-fileio.h"
+
/* Prototypes for local functions */
static void cleanup_sigint_signal_handler (void *dummy);
static void initialize_sigint_signal_handler (void);
@@ -67,10 +70,6 @@ void async_remote_interrupt_twice (gdb_client_data);
static void build_remote_gdbarch_data (void);
-static int remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len);
-
-static int remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len);
-
static void remote_files_info (struct target_ops *ignore);
static int remote_xfer_memory (CORE_ADDR memaddr, char *myaddr,
@@ -86,7 +85,7 @@ static void remote_resume (ptid_t ptid, int step,
enum target_signal siggnal);
static void remote_async_resume (ptid_t ptid, int step,
enum target_signal siggnal);
-static int remote_start_remote (PTR);
+static int remote_start_remote (struct ui_out *uiout, void *dummy);
static void remote_open (char *name, int from_tty);
static void remote_async_open (char *name, int from_tty);
@@ -94,9 +93,8 @@ static void remote_async_open (char *name, int from_tty);
static void extended_remote_open (char *name, int from_tty);
static void extended_remote_async_open (char *name, int from_tty);
-static void remote_open_1 (char *, int, struct target_ops *, int extended_p);
-static void remote_async_open_1 (char *, int, struct target_ops *,
- int extended_p);
+static void remote_open_1 (char *, int, struct target_ops *, int extended_p,
+ int async_p);
static void remote_close (int quitting);
@@ -129,7 +127,6 @@ static void remote_async_kill (void);
static int tohex (int nib);
static void remote_detach (char *args, int from_tty);
-static void remote_async_detach (char *args, int from_tty);
static void remote_interrupt (int signo);
@@ -155,18 +152,12 @@ static void init_remote_ops (void);
static void init_extended_remote_ops (void);
-static void init_remote_cisco_ops (void);
-
-static struct target_ops remote_cisco_ops;
-
static void remote_stop (void);
static int ishex (int ch, int *val);
static int stubhex (int ch);
-static int remote_query (int /*char */ , char *, char *, int *);
-
static int hexnumstr (char *, ULONGEST);
static int hexnumnstr (char *, ULONGEST, int);
@@ -205,16 +196,12 @@ static void show_packet_config_cmd (struct packet_config *config);
static void update_packet_config (struct packet_config *config);
-/* Define the target subroutine names */
-
-void open_remote_target (char *, int, struct target_ops *, int);
-
void _initialize_remote (void);
-/* Description of the remote protocol. Strictly speeking, when the
+/* Description of the remote protocol. Strictly speaking, when the
target is open()ed, remote.c should create a per-target description
of the remote protocol using that target's architecture.
- Unfortunatly, the target stack doesn't include local state. For
+ Unfortunately, the target stack doesn't include local state. For
the moment keep the information in the target's architecture
object. Sigh.. */
@@ -224,7 +211,7 @@ struct packet_reg
long regnum; /* GDB's internal register number. */
LONGEST pnum; /* Remote protocol register number. */
int in_g_packet; /* Always part of G packet. */
- /* long size in bytes; == REGISTER_RAW_SIZE (regnum); at present. */
+ /* long size in bytes; == DEPRECATED_REGISTER_RAW_SIZE (regnum); at present. */
/* char *name; == REGISTER_NAME (regnum); at present. */
};
@@ -250,36 +237,42 @@ struct remote_state
long remote_packet_size;
};
+
/* Handle for retreving the remote protocol data from gdbarch. */
static struct gdbarch_data *remote_gdbarch_data_handle;
static struct remote_state *
-get_remote_state ()
+get_remote_state (void)
{
- return gdbarch_data (remote_gdbarch_data_handle);
+ return gdbarch_data (current_gdbarch, remote_gdbarch_data_handle);
}
static void *
init_remote_state (struct gdbarch *gdbarch)
{
int regnum;
- struct remote_state *rs = xmalloc (sizeof (struct remote_state));
+ struct remote_state *rs = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_state);
- /* Start out by having the remote protocol mimic the existing
- behavour - just copy in the description of the register cache. */
- rs->sizeof_g_packet = REGISTER_BYTES; /* OK use. */
+ if (DEPRECATED_REGISTER_BYTES != 0)
+ rs->sizeof_g_packet = DEPRECATED_REGISTER_BYTES;
+ else
+ rs->sizeof_g_packet = 0;
/* Assume a 1:1 regnum<->pnum table. */
- rs->regs = xcalloc (NUM_REGS + NUM_PSEUDO_REGS, sizeof (struct packet_reg));
+ rs->regs = GDBARCH_OBSTACK_CALLOC (gdbarch, NUM_REGS + NUM_PSEUDO_REGS,
+ struct packet_reg);
for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
{
struct packet_reg *r = &rs->regs[regnum];
r->pnum = regnum;
r->regnum = regnum;
- r->offset = REGISTER_BYTE (regnum);
+ r->offset = DEPRECATED_REGISTER_BYTE (regnum);
r->in_g_packet = (regnum < NUM_REGS);
- /* ...size = REGISTER_RAW_SIZE (regnum); */
/* ...name = REGISTER_NAME (regnum); */
+
+ /* Compute packet size by accumulating the size of all registers. */
+ if (DEPRECATED_REGISTER_BYTES == 0)
+ rs->sizeof_g_packet += register_size (current_gdbarch, regnum);
}
/* Default maximum number of characters in a packet body. Many
@@ -299,21 +292,13 @@ init_remote_state (struct gdbarch *gdbarch)
little. */
if (rs->sizeof_g_packet > ((rs->remote_packet_size - 32) / 2))
rs->remote_packet_size = (rs->sizeof_g_packet * 2 + 32);
-
+
/* This one is filled in when a ``g'' packet is received. */
rs->actual_register_packet_size = 0;
return rs;
}
-static void
-free_remote_state (struct gdbarch *gdbarch, void *pointer)
-{
- struct remote_state *data = pointer;
- xfree (data->regs);
- xfree (data);
-}
-
static struct packet_reg *
packet_reg_from_regnum (struct remote_state *rs, long regnum)
{
@@ -340,7 +325,17 @@ packet_reg_from_pnum (struct remote_state *rs, LONGEST pnum)
return NULL;
}
-/* */
+/* FIXME: graces/2002-08-08: These variables should eventually be
+ bound to an instance of the target object (as in gdbarch-tdep()),
+ when such a thing exists. */
+
+/* This is set to the data address of the access causing the target
+ to stop for a watchpoint. */
+static CORE_ADDR remote_watch_data_address;
+
+/* This is non-zero if taregt stopped for a watchpoint. */
+static int remote_stopped_by_watchpoint_p;
+
static struct target_ops remote_ops;
@@ -374,10 +369,6 @@ static int remote_break;
starts. */
static struct serial *remote_desc = NULL;
-/* This is set by the target (thru the 'S' message)
- to denote that the target is in kernel mode. */
-static int cisco_kernel_mode = 0;
-
/* This variable sets the number of bits in an address that are to be
sent in a memory ("M" or "m") packet. Normally, after stripping
leading zeros, the entire address would be sent. This variable
@@ -583,7 +574,7 @@ struct packet_config
{
char *name;
char *title;
- enum cmd_auto_boolean detect;
+ enum auto_boolean detect;
enum packet_support support;
};
@@ -602,13 +593,13 @@ update_packet_config (struct packet_config *config)
{
switch (config->detect)
{
- case CMD_AUTO_BOOLEAN_TRUE:
+ case AUTO_BOOLEAN_TRUE:
config->support = PACKET_ENABLE;
break;
- case CMD_AUTO_BOOLEAN_FALSE:
+ case AUTO_BOOLEAN_FALSE:
config->support = PACKET_DISABLE;
break;
- case CMD_AUTO_BOOLEAN_AUTO:
+ case AUTO_BOOLEAN_AUTO:
config->support = PACKET_SUPPORT_UNKNOWN;
break;
}
@@ -632,12 +623,12 @@ show_packet_config_cmd (struct packet_config *config)
}
switch (config->detect)
{
- case CMD_AUTO_BOOLEAN_AUTO:
+ case AUTO_BOOLEAN_AUTO:
printf_filtered ("Support for remote protocol `%s' (%s) packet is auto-detected, currently %s.\n",
config->name, config->title, support);
break;
- case CMD_AUTO_BOOLEAN_TRUE:
- case CMD_AUTO_BOOLEAN_FALSE:
+ case AUTO_BOOLEAN_TRUE:
+ case AUTO_BOOLEAN_FALSE:
printf_filtered ("Support for remote protocol `%s' (%s) packet is currently %s.\n",
config->name, config->title, support);
break;
@@ -648,11 +639,8 @@ static void
add_packet_config_cmd (struct packet_config *config,
char *name,
char *title,
- void (*set_func) (char *args, int from_tty,
- struct cmd_list_element *
- c),
- void (*show_func) (char *name,
- int from_tty),
+ cmd_sfunc_ftype *set_func,
+ cmd_sfunc_ftype *show_func,
struct cmd_list_element **set_remote_list,
struct cmd_list_element **show_remote_list,
int legacy)
@@ -664,7 +652,7 @@ add_packet_config_cmd (struct packet_config *config,
char *cmd_name;
config->name = name;
config->title = title;
- config->detect = CMD_AUTO_BOOLEAN_AUTO;
+ config->detect = AUTO_BOOLEAN_AUTO;
config->support = PACKET_SUPPORT_UNKNOWN;
xasprintf (&set_doc, "Set use of remote protocol `%s' (%s) packet",
name, title);
@@ -672,12 +660,10 @@ add_packet_config_cmd (struct packet_config *config,
name, title);
/* set/show TITLE-packet {auto,on,off} */
xasprintf (&cmd_name, "%s-packet", title);
- set_cmd = add_set_auto_boolean_cmd (cmd_name, class_obscure,
- &config->detect, set_doc,
- set_remote_list);
- set_cmd_sfunc (set_cmd, set_func);
- show_cmd = add_cmd (cmd_name, class_obscure, show_func, show_doc,
- show_remote_list);
+ add_setshow_auto_boolean_cmd (cmd_name, class_obscure,
+ &config->detect, set_doc, show_doc,
+ set_func, show_func,
+ set_remote_list, show_remote_list);
/* set/show remote NAME-packet {auto,on,off} -- legacy */
if (legacy)
{
@@ -730,7 +716,7 @@ packet_ok (const char *buf, struct packet_config *config)
switch (config->support)
{
case PACKET_ENABLE:
- if (config->detect == CMD_AUTO_BOOLEAN_AUTO)
+ if (config->detect == AUTO_BOOLEAN_AUTO)
/* If the stub previously indicated that the packet was
supported then there is a protocol error.. */
error ("Protocol error: %s (%s) conflicting enabled responses.",
@@ -754,6 +740,23 @@ packet_ok (const char *buf, struct packet_config *config)
}
}
+/* Should we try the 'vCont' (descriptive resume) request? */
+static struct packet_config remote_protocol_vcont;
+
+static void
+set_remote_protocol_vcont_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_vcont);
+}
+
+static void
+show_remote_protocol_vcont_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ show_packet_config_cmd (&remote_protocol_vcont);
+}
+
/* Should we try the 'qSymbol' (target symbol lookup service) request? */
static struct packet_config remote_protocol_qSymbol;
@@ -765,7 +768,8 @@ set_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
}
static void
-show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty)
+show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
show_packet_config_cmd (&remote_protocol_qSymbol);
}
@@ -781,11 +785,12 @@ set_remote_protocol_e_packet_cmd (char *args, int from_tty,
}
static void
-show_remote_protocol_e_packet_cmd (char *args, int from_tty)
+show_remote_protocol_e_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
show_packet_config_cmd (&remote_protocol_e);
}
-
+
/* Should we try the 'E' (step over range / w signal #) request? */
static struct packet_config remote_protocol_E;
@@ -798,11 +803,12 @@ set_remote_protocol_E_packet_cmd (char *args, int from_tty,
}
static void
-show_remote_protocol_E_packet_cmd (char *args, int from_tty)
+show_remote_protocol_E_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
show_packet_config_cmd (&remote_protocol_E);
}
-
+
/* Should we try the 'P' (set register) request? */
@@ -816,7 +822,8 @@ set_remote_protocol_P_packet_cmd (char *args, int from_tty,
}
static void
-show_remote_protocol_P_packet_cmd (char *args, int from_tty)
+show_remote_protocol_P_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
show_packet_config_cmd (&remote_protocol_P);
}
@@ -846,7 +853,8 @@ set_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty,
}
static void
-show_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_BP]);
}
@@ -859,7 +867,8 @@ set_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty,
}
static void
-show_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_HARDWARE_BP]);
}
@@ -872,7 +881,8 @@ set_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty,
}
static void
-show_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_WRITE_WP]);
}
@@ -885,7 +895,8 @@ set_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty,
}
static void
-show_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_READ_WP]);
}
@@ -898,7 +909,8 @@ set_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty,
}
static void
-show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_ACCESS_WP]);
}
@@ -906,7 +918,7 @@ show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty)
/* For compatibility with older distributions. Provide a ``set remote
Z-packet ...'' command that updates all the Z packet types. */
-static enum cmd_auto_boolean remote_Z_packet_detect;
+static enum auto_boolean remote_Z_packet_detect;
static void
set_remote_protocol_Z_packet_cmd (char *args, int from_tty,
@@ -921,7 +933,8 @@ set_remote_protocol_Z_packet_cmd (char *args, int from_tty,
}
static void
-show_remote_protocol_Z_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
int i;
for (i = 0; i < NR_Z_PACKET_TYPES; i++)
@@ -947,7 +960,7 @@ static struct packet_config remote_protocol_binary_download;
This variable (NOT available to the user: auto-detect only!)
determines whether GDB will use the new, simpler "ThreadInfo"
query or the older, more complex syntax for thread queries.
- This is an auto-detect variable (set to true at each connect,
+ This is an auto-detect variable (set to true at each connect,
and set to false when the target fails to recognize it). */
static int use_threadinfo_query;
@@ -962,16 +975,33 @@ set_remote_protocol_binary_download_cmd (char *args,
}
static void
-show_remote_protocol_binary_download_cmd (char *args,
- int from_tty)
+show_remote_protocol_binary_download_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
show_packet_config_cmd (&remote_protocol_binary_download);
}
+/* Should we try the 'qPart:auxv' (target auxiliary vector read) request? */
+static struct packet_config remote_protocol_qPart_auxv;
+
+static void
+set_remote_protocol_qPart_auxv_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_qPart_auxv);
+}
+
+static void
+show_remote_protocol_qPart_auxv_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ show_packet_config_cmd (&remote_protocol_qPart_auxv);
+}
+
/* Tokens for use by the asynchronous signal handlers for SIGINT */
-PTR sigint_remote_twice_token;
-PTR sigint_remote_token;
+static void *sigint_remote_twice_token;
+static void *sigint_remote_token;
/* These are pointers to hook functions that may be set in order to
modify resume/wait behavior for a particular architecture. */
@@ -1102,7 +1132,7 @@ struct gdb_ext_thread_info
#define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES*2)
-char *unpack_varlen_hex (char *buff, int *result);
+char *unpack_varlen_hex (char *buff, ULONGEST *result);
static char *unpack_nibble (char *buf, int *val);
@@ -1141,10 +1171,6 @@ static int remote_unpack_thread_info_response (char *pkt,
static int remote_get_threadinfo (threadref * threadid, int fieldset, /*TAG mask */
struct gdb_ext_thread_info *info);
-static int adapt_remote_get_threadinfo (gdb_threadref * ref,
- int selection,
- struct gdb_ext_thread_info *info);
-
static char *pack_threadlist_request (char *pkt, int startflag,
int threadcount,
threadref * nextthread);
@@ -1223,7 +1249,7 @@ stub_unpack_int (char *buff, int fieldlength)
char *
unpack_varlen_hex (char *buff, /* packet to parse */
- int *result)
+ ULONGEST *result)
{
int nibble;
int retval = 0;
@@ -1446,7 +1472,7 @@ pack_threadinfo_request (char *pkt, int mode, threadref *id)
fetch registers and its stack */
#define TAG_DISPLAY 4 /* A short thing maybe to put on a window */
#define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */
-#define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about
+#define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about
the process */
static int
@@ -1556,19 +1582,6 @@ remote_get_threadinfo (threadref *threadid, int fieldset, /* TAG mask */
return result;
}
-/* Unfortunately, 61 bit thread-ids are bigger than the internal
- representation of a threadid. */
-
-static int
-adapt_remote_get_threadinfo (gdb_threadref *ref, int selection,
- struct gdb_ext_thread_info *info)
-{
- threadref lclref;
-
- int_to_threadref (&lclref, *ref);
- return remote_get_threadinfo (&lclref, selection, info);
-}
-
/* Format: i'Q':8,i"L":8,initflag:8,batchsize:16,lastthreadid:32 */
static char *
@@ -1747,8 +1760,8 @@ remote_current_thread (ptid_t oldpid)
return oldpid;
}
-/* Find new threads for info threads command.
- * Original version, using John Metzler's thread protocol.
+/* Find new threads for info threads command.
+ * Original version, using John Metzler's thread protocol.
*/
static void
@@ -1784,7 +1797,7 @@ remote_threads_info (void)
bufp = buf;
getpkt (bufp, (rs->remote_packet_size), 0);
if (bufp[0] != '\0') /* q packet recognized */
- {
+ {
while (*bufp++ == 'm') /* reply contains one or more TID */
{
do
@@ -1808,12 +1821,12 @@ remote_threads_info (void)
return;
}
-/*
+/*
* Collect a descriptive string about the given thread.
* The target may say anything it wants to about the thread
* (typically info about its blocked / runnable state, name, etc.).
* This string will appear in the info threads display.
- *
+ *
* Optional: targets are not required to implement this function.
*/
@@ -1898,7 +1911,6 @@ extended_remote_restart (void)
/* Clean up connection to a remote debugger. */
-/* ARGSUSED */
static void
remote_close (int quitting)
{
@@ -1974,8 +1986,10 @@ get_offsets (void)
if (symfile_objfile == NULL)
return;
- offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
- memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
+ offs = ((struct section_offsets *)
+ alloca (SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections)));
+ memcpy (offs, symfile_objfile->section_offsets,
+ SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections));
offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr;
@@ -1989,132 +2003,19 @@ get_offsets (void)
objfile_relocate (symfile_objfile, offs);
}
-/*
- * Cisco version of section offsets:
- *
- * Instead of having GDB query the target for the section offsets,
- * Cisco lets the target volunteer the information! It's also in
- * a different format, so here are the functions that will decode
- * a section offset packet from a Cisco target.
- */
-
-/*
- * Function: remote_cisco_section_offsets
- *
- * Returns: zero for success, non-zero for failure
- */
-
-static int
-remote_cisco_section_offsets (bfd_vma text_addr,
- bfd_vma data_addr,
- bfd_vma bss_addr,
- bfd_signed_vma *text_offs,
- bfd_signed_vma *data_offs,
- bfd_signed_vma *bss_offs)
-{
- bfd_vma text_base, data_base, bss_base;
- struct minimal_symbol *start;
- asection *sect;
- bfd *abfd;
- int len;
-
- if (symfile_objfile == NULL)
- return -1; /* no can do nothin' */
-
- start = lookup_minimal_symbol ("_start", NULL, NULL);
- if (start == NULL)
- return -1; /* Can't find "_start" symbol */
-
- data_base = bss_base = 0;
- text_base = SYMBOL_VALUE_ADDRESS (start);
-
- abfd = symfile_objfile->obfd;
- for (sect = abfd->sections;
- sect != 0;
- sect = sect->next)
- {
- const char *p = bfd_get_section_name (abfd, sect);
- len = strlen (p);
- if (strcmp (p + len - 4, "data") == 0) /* ends in "data" */
- if (data_base == 0 ||
- data_base > bfd_get_section_vma (abfd, sect))
- data_base = bfd_get_section_vma (abfd, sect);
- if (strcmp (p + len - 3, "bss") == 0) /* ends in "bss" */
- if (bss_base == 0 ||
- bss_base > bfd_get_section_vma (abfd, sect))
- bss_base = bfd_get_section_vma (abfd, sect);
- }
- *text_offs = text_addr - text_base;
- *data_offs = data_addr - data_base;
- *bss_offs = bss_addr - bss_base;
- if (remote_debug)
- {
- char tmp[128];
-
- sprintf (tmp, "VMA: text = 0x");
- sprintf_vma (tmp + strlen (tmp), text_addr);
- sprintf (tmp + strlen (tmp), " data = 0x");
- sprintf_vma (tmp + strlen (tmp), data_addr);
- sprintf (tmp + strlen (tmp), " bss = 0x");
- sprintf_vma (tmp + strlen (tmp), bss_addr);
- fprintf_filtered (gdb_stdlog, tmp);
- fprintf_filtered (gdb_stdlog,
- "Reloc offset: text = 0x%s data = 0x%s bss = 0x%s\n",
- paddr_nz (*text_offs),
- paddr_nz (*data_offs),
- paddr_nz (*bss_offs));
- }
-
- return 0;
-}
-
-/*
- * Function: remote_cisco_objfile_relocate
- *
- * Relocate the symbol file for a remote target.
- */
-
-void
-remote_cisco_objfile_relocate (bfd_signed_vma text_off, bfd_signed_vma data_off,
- bfd_signed_vma bss_off)
-{
- struct section_offsets *offs;
-
- if (text_off != 0 || data_off != 0 || bss_off != 0)
- {
- /* FIXME: This code assumes gdb-stabs.h is being used; it's
- broken for xcoff, dwarf, sdb-coff, etc. But there is no
- simple canonical representation for this stuff. */
-
- offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
- memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
-
- offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_off;
- offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_off;
- offs->offsets[SECT_OFF_BSS (symfile_objfile)] = bss_off;
-
- /* First call the standard objfile_relocate. */
- objfile_relocate (symfile_objfile, offs);
-
- /* Now we need to fix up the section entries already attached to
- the exec target. These entries will control memory transfers
- from the exec file. */
-
- exec_set_section_offsets (text_off, data_off, bss_off);
- }
-}
-
/* Stub for catch_errors. */
static int
-remote_start_remote_dummy (void *dummy)
+remote_start_remote_dummy (struct ui_out *uiout, void *dummy)
{
start_remote (); /* Initialize gdb process mechanisms */
+ /* NOTE: Return something >=0. A -ve value is reserved for
+ catch_exceptions. */
return 1;
}
static int
-remote_start_remote (PTR dummy)
+remote_start_remote (struct ui_out *uiout, void *dummy)
{
immediate_quit++; /* Allow user to interrupt it */
@@ -2131,7 +2032,9 @@ remote_start_remote (PTR dummy)
putpkt ("?"); /* initiate a query from remote machine */
immediate_quit--;
- return remote_start_remote_dummy (dummy);
+ /* NOTE: See comment above in remote_start_remote_dummy(). This
+ function returns something >=0. */
+ return remote_start_remote_dummy (uiout, dummy);
}
/* Open a connection to a remote debugger.
@@ -2140,14 +2043,14 @@ remote_start_remote (PTR dummy)
static void
remote_open (char *name, int from_tty)
{
- remote_open_1 (name, from_tty, &remote_ops, 0);
+ remote_open_1 (name, from_tty, &remote_ops, 0, 0);
}
/* Just like remote_open, but with asynchronous support. */
static void
remote_async_open (char *name, int from_tty)
{
- remote_async_open_1 (name, from_tty, &remote_async_ops, 0);
+ remote_open_1 (name, from_tty, &remote_async_ops, 0, 1);
}
/* Open a connection to a remote debugger using the extended
@@ -2156,14 +2059,16 @@ remote_async_open (char *name, int from_tty)
static void
extended_remote_open (char *name, int from_tty)
{
- remote_open_1 (name, from_tty, &extended_remote_ops, 1 /*extended_p */ );
+ remote_open_1 (name, from_tty, &extended_remote_ops, 1 /*extended_p */,
+ 0 /* async_p */);
}
/* Just like extended_remote_open, but with asynchronous support. */
static void
extended_remote_async_open (char *name, int from_tty)
{
- remote_async_open_1 (name, from_tty, &extended_async_remote_ops, 1 /*extended_p */ );
+ remote_open_1 (name, from_tty, &extended_async_remote_ops,
+ 1 /*extended_p */, 1 /* async_p */);
}
/* Generic code for opening a connection to a remote target. */
@@ -2176,11 +2081,13 @@ init_all_packet_configs (void)
update_packet_config (&remote_protocol_E);
update_packet_config (&remote_protocol_P);
update_packet_config (&remote_protocol_qSymbol);
+ update_packet_config (&remote_protocol_vcont);
for (i = 0; i < NR_Z_PACKET_TYPES; i++)
update_packet_config (&remote_protocol_Z[i]);
/* Force remote_write_bytes to check whether target supports binary
downloading. */
update_packet_config (&remote_protocol_binary_download);
+ update_packet_config (&remote_protocol_qPart_auxv);
}
/* Symbol look-up. */
@@ -2214,7 +2121,7 @@ remote_check_symbols (struct objfile *objfile)
if (sym == NULL)
sprintf (msg, "qSymbol::%s", &reply[8]);
else
- sprintf (msg, "qSymbol:%s:%s",
+ sprintf (msg, "qSymbol:%s:%s",
paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
&reply[8]);
putpkt (msg);
@@ -2222,122 +2129,46 @@ remote_check_symbols (struct objfile *objfile)
}
}
-static void
-remote_open_1 (char *name, int from_tty, struct target_ops *target,
- int extended_p)
+static struct serial *
+remote_serial_open (char *name)
{
- struct remote_state *rs = get_remote_state ();
- if (name == 0)
- error ("To open a remote debug connection, you need to specify what\n"
- "serial device is attached to the remote system\n"
- "(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
+ static int udp_warning = 0;
- /* See FIXME above */
- wait_forever_enabled_p = 1;
-
- target_preopen (from_tty);
-
- unpush_target (target);
-
- remote_desc = serial_open (name);
- if (!remote_desc)
- perror_with_name (name);
-
- if (baud_rate != -1)
+ /* FIXME: Parsing NAME here is a hack. But we want to warn here instead
+ of in ser-tcp.c, because it is the remote protocol assuming that the
+ serial connection is reliable and not the serial connection promising
+ to be. */
+ if (!udp_warning && strncmp (name, "udp:", 4) == 0)
{
- if (serial_setbaudrate (remote_desc, baud_rate))
- {
- serial_close (remote_desc);
- perror_with_name (name);
- }
- }
-
- serial_raw (remote_desc);
-
- /* If there is something sitting in the buffer we might take it as a
- response to a command, which would be bad. */
- serial_flush_input (remote_desc);
-
- if (from_tty)
- {
- puts_filtered ("Remote debugging using ");
- puts_filtered (name);
- puts_filtered ("\n");
+ warning ("The remote protocol may be unreliable over UDP.");
+ warning ("Some events may be lost, rendering further debugging "
+ "impossible.");
+ udp_warning = 1;
}
- push_target (target); /* Switch to using remote target now */
- init_all_packet_configs ();
-
- general_thread = -2;
- continue_thread = -2;
-
- /* Probe for ability to use "ThreadInfo" query, as required. */
- use_threadinfo_query = 1;
- use_threadextra_query = 1;
-
- /* Without this, some commands which require an active target (such
- as kill) won't work. This variable serves (at least) double duty
- as both the pid of the target process (if it has such), and as a
- flag indicating that a target is active. These functions should
- be split out into seperate variables, especially since GDB will
- someday have a notion of debugging several processes. */
-
- inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
- /* First delete any symbols previously loaded from shared libraries. */
- no_shared_libraries (NULL, 0);
-#endif
-
- /* Start the remote connection; if error (0), discard this target.
- In particular, if the user quits, be sure to discard it
- (we'd be in an inconsistent state otherwise). */
- if (!catch_errors (remote_start_remote, NULL,
- "Couldn't establish connection to remote target\n",
- RETURN_MASK_ALL))
- {
- pop_target ();
- return;
- }
-
- if (extended_p)
- {
- /* Tell the remote that we are using the extended protocol. */
- char *buf = alloca (rs->remote_packet_size);
- putpkt ("!");
- getpkt (buf, (rs->remote_packet_size), 0);
- }
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
- /* FIXME: need a master target_open vector from which all
- remote_opens can be called, so that stuff like this can
- go there. Failing that, the following code must be copied
- to the open function for any remote target that wants to
- support svr4 shared libraries. */
-
- /* Set up to detect and load shared libraries. */
- if (exec_bfd) /* No use without an exec file. */
- {
- SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
- remote_check_symbols (symfile_objfile);
- }
-#endif
+ return serial_open (name);
}
-/* Just like remote_open but with asynchronous support. */
static void
-remote_async_open_1 (char *name, int from_tty, struct target_ops *target,
- int extended_p)
+remote_open_1 (char *name, int from_tty, struct target_ops *target,
+ int extended_p, int async_p)
{
+ int ex;
struct remote_state *rs = get_remote_state ();
if (name == 0)
error ("To open a remote debug connection, you need to specify what\n"
"serial device is attached to the remote system\n"
"(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
+ /* See FIXME above */
+ if (!async_p)
+ wait_forever_enabled_p = 1;
+
target_preopen (from_tty);
unpush_target (target);
- remote_desc = serial_open (name);
+ remote_desc = remote_serial_open (name);
if (!remote_desc)
perror_with_name (name);
@@ -2345,7 +2176,12 @@ remote_async_open_1 (char *name, int from_tty, struct target_ops *target,
{
if (serial_setbaudrate (remote_desc, baud_rate))
{
+ /* The requested speed could not be set. Error out to
+ top level after closing remote_desc. Take care to
+ set remote_desc to NULL to avoid closing remote_desc
+ more than once. */
serial_close (remote_desc);
+ remote_desc = NULL;
perror_with_name (name);
}
}
@@ -2362,7 +2198,6 @@ remote_async_open_1 (char *name, int from_tty, struct target_ops *target,
puts_filtered (name);
puts_filtered ("\n");
}
-
push_target (target); /* Switch to using remote target now */
init_all_packet_configs ();
@@ -2380,38 +2215,59 @@ remote_async_open_1 (char *name, int from_tty, struct target_ops *target,
flag indicating that a target is active. These functions should
be split out into seperate variables, especially since GDB will
someday have a notion of debugging several processes. */
- inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
- /* With this target we start out by owning the terminal. */
- remote_async_terminal_ours_p = 1;
+ inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
- /* FIXME: cagney/1999-09-23: During the initial connection it is
- assumed that the target is already ready and able to respond to
- requests. Unfortunately remote_start_remote() eventually calls
- wait_for_inferior() with no timeout. wait_forever_enabled_p gets
- around this. Eventually a mechanism that allows
- wait_for_inferior() to expect/get timeouts will be
- implemented. */
- wait_forever_enabled_p = 0;
+ if (async_p)
+ {
+ /* With this target we start out by owning the terminal. */
+ remote_async_terminal_ours_p = 1;
+
+ /* FIXME: cagney/1999-09-23: During the initial connection it is
+ assumed that the target is already ready and able to respond to
+ requests. Unfortunately remote_start_remote() eventually calls
+ wait_for_inferior() with no timeout. wait_forever_enabled_p gets
+ around this. Eventually a mechanism that allows
+ wait_for_inferior() to expect/get timeouts will be
+ implemented. */
+ wait_forever_enabled_p = 0;
+ }
#ifdef SOLIB_CREATE_INFERIOR_HOOK
/* First delete any symbols previously loaded from shared libraries. */
no_shared_libraries (NULL, 0);
#endif
- /* Start the remote connection; if error (0), discard this target.
- In particular, if the user quits, be sure to discard it
- (we'd be in an inconsistent state otherwise). */
- if (!catch_errors (remote_start_remote, NULL,
- "Couldn't establish connection to remote target\n",
- RETURN_MASK_ALL))
+ /* Start the remote connection. If error() or QUIT, discard this
+ target (we'd otherwise be in an inconsistent state) and then
+ propogate the error on up the exception chain. This ensures that
+ the caller doesn't stumble along blindly assuming that the
+ function succeeded. The CLI doesn't have this problem but other
+ UI's, such as MI do.
+
+ FIXME: cagney/2002-05-19: Instead of re-throwing the exception,
+ this function should return an error indication letting the
+ caller restore the previous state. Unfortunately the command
+ ``target remote'' is directly wired to this function making that
+ impossible. On a positive note, the CLI side of this problem has
+ been fixed - the function set_cmd_context() makes it possible for
+ all the ``target ....'' commands to share a common callback
+ function. See cli-dump.c. */
+ ex = catch_exceptions (uiout,
+ remote_start_remote, NULL,
+ "Couldn't establish connection to remote"
+ " target\n",
+ RETURN_MASK_ALL);
+ if (ex < 0)
{
pop_target ();
- wait_forever_enabled_p = 1;
- return;
+ if (async_p)
+ wait_forever_enabled_p = 1;
+ throw_exception (ex);
}
- wait_forever_enabled_p = 1;
+ if (async_p)
+ wait_forever_enabled_p = 1;
if (extended_p)
{
@@ -2421,10 +2277,10 @@ remote_async_open_1 (char *name, int from_tty, struct target_ops *target,
getpkt (buf, (rs->remote_packet_size), 0);
}
#ifdef SOLIB_CREATE_INFERIOR_HOOK
- /* FIXME: need a master target_open vector from which all
- remote_opens can be called, so that stuff like this can
+ /* FIXME: need a master target_open vector from which all
+ remote_opens can be called, so that stuff like this can
go there. Failing that, the following code must be copied
- to the open function for any remote target that wants to
+ to the open function for any remote target that wants to
support svr4 shared libraries. */
/* Set up to detect and load shared libraries. */
@@ -2454,15 +2310,19 @@ remote_detach (char *args, int from_tty)
strcpy (buf, "D");
remote_send (buf, (rs->remote_packet_size));
+ /* Unregister the file descriptor from the event loop. */
+ if (target_is_async_p ())
+ serial_async (remote_desc, NULL, 0);
+
target_mourn_inferior ();
if (from_tty)
puts_filtered ("Ending remote debugging.\n");
-
}
-/* Same as remote_detach, but with async support. */
+/* Same as remote_detach, but don't send the "D" packet; just disconnect. */
+
static void
-remote_async_detach (char *args, int from_tty)
+remote_disconnect (char *args, int from_tty)
{
struct remote_state *rs = get_remote_state ();
char *buf = alloca (rs->remote_packet_size);
@@ -2470,10 +2330,6 @@ remote_async_detach (char *args, int from_tty)
if (args)
error ("Argument given to \"detach\" when remotely debugging.");
- /* Tell the remote target to detach. */
- strcpy (buf, "D");
- remote_send (buf, (rs->remote_packet_size));
-
/* Unregister the file descriptor from the event loop. */
if (target_is_async_p ())
serial_async (remote_desc, NULL, 0);
@@ -2545,115 +2401,149 @@ bin2hex (const char *bin, char *hex, int count)
return i;
}
-/* Tell the remote machine to resume. */
-
-static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
-
-static int last_sent_step;
+/* Check for the availability of vCont. This function should also check
+ the response. */
static void
-remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_vcont_probe (struct remote_state *rs, char *buf)
{
- struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
- int pid = PIDGET (ptid);
- char *p;
+ strcpy (buf, "vCont?");
+ putpkt (buf);
+ getpkt (buf, rs->remote_packet_size, 0);
- if (pid == -1)
- set_thread (0, 0); /* run any thread */
- else
- set_thread (pid, 0); /* run this thread */
+ /* Make sure that the features we assume are supported. */
+ if (strncmp (buf, "vCont", 5) == 0)
+ {
+ char *p = &buf[5];
+ int support_s, support_S, support_c, support_C;
+
+ support_s = 0;
+ support_S = 0;
+ support_c = 0;
+ support_C = 0;
+ while (p && *p == ';')
+ {
+ p++;
+ if (*p == 's' && (*(p + 1) == ';' || *(p + 1) == 0))
+ support_s = 1;
+ else if (*p == 'S' && (*(p + 1) == ';' || *(p + 1) == 0))
+ support_S = 1;
+ else if (*p == 'c' && (*(p + 1) == ';' || *(p + 1) == 0))
+ support_c = 1;
+ else if (*p == 'C' && (*(p + 1) == ';' || *(p + 1) == 0))
+ support_C = 1;
+
+ p = strchr (p, ';');
+ }
- last_sent_signal = siggnal;
- last_sent_step = step;
+ /* If s, S, c, and C are not all supported, we can't use vCont. Clearing
+ BUF will make packet_ok disable the packet. */
+ if (!support_s || !support_S || !support_c || !support_C)
+ buf[0] = 0;
+ }
- /* A hook for when we need to do something at the last moment before
- resumption. */
- if (target_resume_hook)
- (*target_resume_hook) ();
+ packet_ok (buf, &remote_protocol_vcont);
+}
+/* Resume the remote inferior by using a "vCont" packet. The thread
+ to be resumed is PTID; STEP and SIGGNAL indicate whether the
+ resumed thread should be single-stepped and/or signalled. If PTID's
+ PID is -1, then all threads are resumed; the thread to be stepped and/or
+ signalled is given in the global INFERIOR_PTID. This function returns
+ non-zero iff it resumes the inferior.
- /* The s/S/c/C packets do not return status. So if the target does
- not support the S or C packets, the debug agent returns an empty
- string which is detected in remote_wait(). This protocol defect
- is fixed in the e/E packets. */
+ This function issues a strict subset of all possible vCont commands at the
+ moment. */
- if (step && step_range_end)
- {
- /* If the target does not support the 'E' packet, we try the 'S'
- packet. Ideally we would fall back to the 'e' packet if that
- too is not supported. But that would require another copy of
- the code to issue the 'e' packet (and fall back to 's' if not
- supported) in remote_wait(). */
-
- if (siggnal != TARGET_SIGNAL_0)
- {
- if (remote_protocol_E.support != PACKET_DISABLE)
- {
- p = buf;
- *p++ = 'E';
- *p++ = tohex (((int) siggnal >> 4) & 0xf);
- *p++ = tohex (((int) siggnal) & 0xf);
- *p++ = ',';
- p += hexnumstr (p, (ULONGEST) step_range_start);
- *p++ = ',';
- p += hexnumstr (p, (ULONGEST) step_range_end);
- *p++ = 0;
-
- putpkt (buf);
- getpkt (buf, (rs->remote_packet_size), 0);
+static int
+remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ struct remote_state *rs = get_remote_state ();
+ int pid = PIDGET (ptid);
+ char *buf = NULL, *outbuf;
+ struct cleanup *old_cleanup;
- if (packet_ok (buf, &remote_protocol_E) == PACKET_OK)
- return;
- }
- }
- else
- {
- if (remote_protocol_e.support != PACKET_DISABLE)
- {
- p = buf;
- *p++ = 'e';
- p += hexnumstr (p, (ULONGEST) step_range_start);
- *p++ = ',';
- p += hexnumstr (p, (ULONGEST) step_range_end);
- *p++ = 0;
+ buf = xmalloc (rs->remote_packet_size);
+ old_cleanup = make_cleanup (xfree, buf);
- putpkt (buf);
- getpkt (buf, (rs->remote_packet_size), 0);
+ if (remote_protocol_vcont.support == PACKET_SUPPORT_UNKNOWN)
+ remote_vcont_probe (rs, buf);
- if (packet_ok (buf, &remote_protocol_e) == PACKET_OK)
- return;
- }
- }
+ if (remote_protocol_vcont.support == PACKET_DISABLE)
+ {
+ do_cleanups (old_cleanup);
+ return 0;
}
- if (siggnal != TARGET_SIGNAL_0)
+ /* If we could generate a wider range of packets, we'd have to worry
+ about overflowing BUF. Should there be a generic
+ "multi-part-packet" packet? */
+
+ if (PIDGET (inferior_ptid) == MAGIC_NULL_PID)
{
- buf[0] = step ? 'S' : 'C';
- buf[1] = tohex (((int) siggnal >> 4) & 0xf);
- buf[2] = tohex (((int) siggnal) & 0xf);
- buf[3] = '\0';
+ /* MAGIC_NULL_PTID means that we don't have any active threads, so we
+ don't have any PID numbers the inferior will understand. Make sure
+ to only send forms that do not specify a PID. */
+ if (step && siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;S%02x", siggnal);
+ else if (step)
+ outbuf = xstrprintf ("vCont;s");
+ else if (siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;C%02x", siggnal);
+ else
+ outbuf = xstrprintf ("vCont;c");
+ }
+ else if (pid == -1)
+ {
+ /* Resume all threads, with preference for INFERIOR_PTID. */
+ if (step && siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;S%02x:%x;c", siggnal,
+ PIDGET (inferior_ptid));
+ else if (step)
+ outbuf = xstrprintf ("vCont;s:%x;c", PIDGET (inferior_ptid));
+ else if (siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;C%02x:%x;c", siggnal,
+ PIDGET (inferior_ptid));
+ else
+ outbuf = xstrprintf ("vCont;c");
}
else
- strcpy (buf, step ? "s" : "c");
+ {
+ /* Scheduler locking; resume only PTID. */
+ if (step && siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;S%02x:%x", siggnal, pid);
+ else if (step)
+ outbuf = xstrprintf ("vCont;s:%x", pid);
+ else if (siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;C%02x:%x", siggnal, pid);
+ else
+ outbuf = xstrprintf ("vCont;c:%x", pid);
+ }
- putpkt (buf);
+ gdb_assert (outbuf && strlen (outbuf) < rs->remote_packet_size);
+ make_cleanup (xfree, outbuf);
+
+ putpkt (outbuf);
+
+ do_cleanups (old_cleanup);
+
+ return 1;
}
-/* Same as remote_resume, but with async support. */
+/* Tell the remote machine to resume. */
+
+static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
+
+static int last_sent_step;
+
static void
-remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
char *buf = alloca (rs->remote_packet_size);
int pid = PIDGET (ptid);
char *p;
- if (pid == -1)
- set_thread (0, 0); /* run any thread */
- else
- set_thread (pid, 0); /* run this thread */
-
last_sent_signal = siggnal;
last_sent_step = step;
@@ -2662,6 +2552,16 @@ remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
if (target_resume_hook)
(*target_resume_hook) ();
+ /* The vCont packet doesn't need to specify threads via Hc. */
+ if (remote_vcont_resume (ptid, step, siggnal))
+ return;
+
+ /* All other supported resume packets do use Hc, so call set_thread. */
+ if (pid == -1)
+ set_thread (0, 0); /* run any thread */
+ else
+ set_thread (pid, 0); /* run this thread */
+
/* The s/S/c/C packets do not return status. So if the target does
not support the S or C packets, the debug agent returns an empty
string which is detected in remote_wait(). This protocol defect
@@ -2674,7 +2574,7 @@ remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
too is not supported. But that would require another copy of
the code to issue the 'e' packet (and fall back to 's' if not
supported) in remote_wait(). */
-
+
if (siggnal != TARGET_SIGNAL_0)
{
if (remote_protocol_E.support != PACKET_DISABLE)
@@ -2693,7 +2593,7 @@ remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
getpkt (buf, (rs->remote_packet_size), 0);
if (packet_ok (buf, &remote_protocol_E) == PACKET_OK)
- goto register_event_loop;
+ return;
}
}
else
@@ -2711,7 +2611,7 @@ remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
getpkt (buf, (rs->remote_packet_size), 0);
if (packet_ok (buf, &remote_protocol_e) == PACKET_OK)
- goto register_event_loop;
+ return;
}
}
}
@@ -2720,15 +2620,21 @@ remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
{
buf[0] = step ? 'S' : 'C';
buf[1] = tohex (((int) siggnal >> 4) & 0xf);
- buf[2] = tohex ((int) siggnal & 0xf);
+ buf[2] = tohex (((int) siggnal) & 0xf);
buf[3] = '\0';
}
else
strcpy (buf, step ? "s" : "c");
-
+
putpkt (buf);
+}
+
+/* Same as remote_resume, but with async support. */
+static void
+remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ remote_resume (ptid, step, siggnal);
-register_event_loop:
/* We are about to start executing the inferior, let's register it
with the event loop. NOTE: this is the one place where all the
execution commands end up. We could alternatively do this in each
@@ -2950,7 +2856,7 @@ remote_console_output (char *msg)
/* Wait until the remote machine stops, then return,
storing status in STATUS just as `wait' would.
- Returns "pid", which in the case of a multi-threaded
+ Returns "pid", which in the case of a multi-threaded
remote OS, is the thread-id. */
static ptid_t
@@ -2958,7 +2864,8 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
{
struct remote_state *rs = get_remote_state ();
unsigned char *buf = alloca (rs->remote_packet_size);
- int thread_num = -1;
+ ULONGEST thread_num = -1;
+ ULONGEST addr;
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
@@ -2976,15 +2883,20 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
if (target_wait_loop_hook)
(*target_wait_loop_hook) ();
+ remote_stopped_by_watchpoint_p = 0;
+
switch (buf[0])
{
case 'E': /* Error of some sort */
warning ("Remote failure reply: %s", buf);
continue;
+ case 'F': /* File-I/O request */
+ remote_fileio_request (buf);
+ continue;
case 'T': /* Status with PC, SP, FP, ... */
{
int i;
- char* regs = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ char regs[MAX_REGISTER_SIZE];
/* Expedited reply, containing Signal, {regno, reg} repeat */
/* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where
@@ -2999,24 +2911,52 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
unsigned char *p1;
char *p_temp;
int fieldsize;
+ LONGEST pnum = 0;
- /* Read the ``P'' register number. */
- LONGEST pnum = strtol ((const char *) p, &p_temp, 16);
- p1 = (unsigned char *) p_temp;
+ /* If the packet contains a register number save it in pnum
+ and set p1 to point to the character following it.
+ Otherwise p1 points to p. */
+
+ /* If this packet is an awatch packet, don't parse the 'a'
+ as a register number. */
+
+ if (strncmp (p, "awatch", strlen("awatch")) != 0)
+ {
+ /* Read the ``P'' register number. */
+ pnum = strtol (p, &p_temp, 16);
+ p1 = (unsigned char *) p_temp;
+ }
+ else
+ p1 = p;
if (p1 == p) /* No register number present here */
{
- p1 = (unsigned char *) strchr ((const char *) p, ':');
+ p1 = (unsigned char *) strchr (p, ':');
if (p1 == NULL)
warning ("Malformed packet(a) (missing colon): %s\n\
Packet: '%s'\n",
p, buf);
- if (strncmp ((const char *) p, "thread", p1 - p) == 0)
+ if (strncmp (p, "thread", p1 - p) == 0)
{
p_temp = unpack_varlen_hex (++p1, &thread_num);
record_currthread (thread_num);
p = (unsigned char *) p_temp;
}
+ else if ((strncmp (p, "watch", p1 - p) == 0)
+ || (strncmp (p, "rwatch", p1 - p) == 0)
+ || (strncmp (p, "awatch", p1 - p) == 0))
+ {
+ remote_stopped_by_watchpoint_p = 1;
+ p = unpack_varlen_hex (++p1, &addr);
+ remote_watch_data_address = (CORE_ADDR)addr;
+ }
+ else
+ {
+ /* Silently skip unknown optional info. */
+ p_temp = strchr (p1 + 1, ';');
+ if (p_temp)
+ p = (unsigned char *) p_temp;
+ }
}
else
{
@@ -3024,27 +2964,22 @@ Packet: '%s'\n",
p = p1;
if (*p++ != ':')
- warning ("Malformed packet(b) (missing colon): %s\n\
-Packet: '%s'\n",
- p, buf);
+ error ("Malformed packet(b) (missing colon): %s\nPacket: '%s'\n",
+ p, buf);
if (reg == NULL)
- warning ("Remote sent bad register number %s: %s\n\
-Packet: '%s'\n",
- phex_nz (pnum, 0), p, buf);
+ error ("Remote sent bad register number %s: %s\nPacket: '%s'\n",
+ phex_nz (pnum, 0), p, buf);
- fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum));
+ fieldsize = hex2bin (p, regs, DEPRECATED_REGISTER_RAW_SIZE (reg->regnum));
p += 2 * fieldsize;
- if (fieldsize < REGISTER_RAW_SIZE (reg->regnum))
+ if (fieldsize < DEPRECATED_REGISTER_RAW_SIZE (reg->regnum))
warning ("Remote reply is too short: %s", buf);
supply_register (reg->regnum, regs);
}
if (*p++ != ';')
- {
- warning ("Remote register badly formatted: %s", buf);
- warning (" here: %s", p);
- }
+ error ("Remote register badly formatted: %s\nhere: %s", buf, p);
}
}
/* fall through */
@@ -3055,70 +2990,10 @@ Packet: '%s'\n",
if (buf[3] == 'p')
{
- /* Export Cisco kernel mode as a convenience variable
- (so that it can be used in the GDB prompt if desired). */
-
- if (cisco_kernel_mode == 1)
- set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
- value_from_string ("PDEBUG-"));
- cisco_kernel_mode = 0;
thread_num = strtol ((const char *) &buf[4], NULL, 16);
record_currthread (thread_num);
}
- else if (buf[3] == 'k')
- {
- /* Export Cisco kernel mode as a convenience variable
- (so that it can be used in the GDB prompt if desired). */
-
- if (cisco_kernel_mode == 1)
- set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
- value_from_string ("KDEBUG-"));
- cisco_kernel_mode = 1;
- }
goto got_status;
- case 'N': /* Cisco special: status and offsets */
- {
- bfd_vma text_addr, data_addr, bss_addr;
- bfd_signed_vma text_off, data_off, bss_off;
- unsigned char *p1;
-
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = (enum target_signal)
- (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
-
- if (symfile_objfile == NULL)
- {
- warning ("Relocation packet received with no symbol file. \
-Packet Dropped");
- goto got_status;
- }
-
- /* Relocate object file. Buffer format is NAATT;DD;BB
- * where AA is the signal number, TT is the new text
- * address, DD * is the new data address, and BB is the
- * new bss address. */
-
- p = &buf[3];
- text_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p || *p1 != ';')
- warning ("Malformed relocation packet: Packet '%s'", buf);
- p = p1 + 1;
- data_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p || *p1 != ';')
- warning ("Malformed relocation packet: Packet '%s'", buf);
- p = p1 + 1;
- bss_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p)
- warning ("Malformed relocation packet: Packet '%s'", buf);
-
- if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr,
- &text_off, &data_off, &bss_off)
- == 0)
- if (text_off != 0 || data_off != 0 || bss_off != 0)
- remote_cisco_objfile_relocate (text_off, data_off, bss_off);
-
- goto got_status;
- }
case 'W': /* Target exited */
{
/* The remote process exited. */
@@ -3172,11 +3047,14 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
{
struct remote_state *rs = get_remote_state ();
unsigned char *buf = alloca (rs->remote_packet_size);
- int thread_num = -1;
+ ULONGEST thread_num = -1;
+ ULONGEST addr;
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
+ remote_stopped_by_watchpoint_p = 0;
+
while (1)
{
unsigned char *p;
@@ -3201,10 +3079,13 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
case 'E': /* Error of some sort */
warning ("Remote failure reply: %s", buf);
continue;
+ case 'F': /* File-I/O request */
+ remote_fileio_request (buf);
+ continue;
case 'T': /* Status with PC, SP, FP, ... */
{
int i;
- char* regs = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+ char regs[MAX_REGISTER_SIZE];
/* Expedited reply, containing Signal, {regno, reg} repeat */
/* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where
@@ -3219,51 +3100,75 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
unsigned char *p1;
char *p_temp;
int fieldsize;
+ long pnum = 0;
+
+ /* If the packet contains a register number, save it in pnum
+ and set p1 to point to the character following it.
+ Otherwise p1 points to p. */
- /* Read the register number */
- long pnum = strtol ((const char *) p, &p_temp, 16);
- p1 = (unsigned char *) p_temp;
+ /* If this packet is an awatch packet, don't parse the 'a'
+ as a register number. */
+
+ if (!strncmp (p, "awatch", strlen ("awatch")) != 0)
+ {
+ /* Read the register number. */
+ pnum = strtol (p, &p_temp, 16);
+ p1 = (unsigned char *) p_temp;
+ }
+ else
+ p1 = p;
if (p1 == p) /* No register number present here */
{
- p1 = (unsigned char *) strchr ((const char *) p, ':');
+ p1 = (unsigned char *) strchr (p, ':');
if (p1 == NULL)
- warning ("Malformed packet(a) (missing colon): %s\n\
-Packet: '%s'\n",
- p, buf);
- if (strncmp ((const char *) p, "thread", p1 - p) == 0)
+ error ("Malformed packet(a) (missing colon): %s\nPacket: '%s'\n",
+ p, buf);
+ if (strncmp (p, "thread", p1 - p) == 0)
{
p_temp = unpack_varlen_hex (++p1, &thread_num);
record_currthread (thread_num);
p = (unsigned char *) p_temp;
}
+ else if ((strncmp (p, "watch", p1 - p) == 0)
+ || (strncmp (p, "rwatch", p1 - p) == 0)
+ || (strncmp (p, "awatch", p1 - p) == 0))
+ {
+ remote_stopped_by_watchpoint_p = 1;
+ p = unpack_varlen_hex (++p1, &addr);
+ remote_watch_data_address = (CORE_ADDR)addr;
+ }
+ else
+ {
+ /* Silently skip unknown optional info. */
+ p_temp = (unsigned char *) strchr (p1 + 1, ';');
+ if (p_temp)
+ p = p_temp;
+ }
}
+
else
{
struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
p = p1;
if (*p++ != ':')
- warning ("Malformed packet(b) (missing colon): %s\n\
-Packet: '%s'\n",
- p, buf);
+ error ("Malformed packet(b) (missing colon): %s\nPacket: '%s'\n",
+ p, buf);
if (reg == NULL)
- warning ("Remote sent bad register number %ld: %s\n\
-Packet: '%s'\n",
- pnum, p, buf);
+ error ("Remote sent bad register number %ld: %s\nPacket: '%s'\n",
+ pnum, p, buf);
- fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum));
+ fieldsize = hex2bin (p, regs, DEPRECATED_REGISTER_RAW_SIZE (reg->regnum));
p += 2 * fieldsize;
- if (fieldsize < REGISTER_RAW_SIZE (reg->regnum))
+ if (fieldsize < DEPRECATED_REGISTER_RAW_SIZE (reg->regnum))
warning ("Remote reply is too short: %s", buf);
supply_register (reg->regnum, regs);
}
if (*p++ != ';')
- {
- warning ("Remote register badly formatted: %s", buf);
- warning (" here: %s", p);
- }
+ error ("Remote register badly formatted: %s\nhere: %s",
+ buf, p);
}
}
/* fall through */
@@ -3274,70 +3179,10 @@ Packet: '%s'\n",
if (buf[3] == 'p')
{
- /* Export Cisco kernel mode as a convenience variable
- (so that it can be used in the GDB prompt if desired). */
-
- if (cisco_kernel_mode == 1)
- set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
- value_from_string ("PDEBUG-"));
- cisco_kernel_mode = 0;
thread_num = strtol ((const char *) &buf[4], NULL, 16);
record_currthread (thread_num);
}
- else if (buf[3] == 'k')
- {
- /* Export Cisco kernel mode as a convenience variable
- (so that it can be used in the GDB prompt if desired). */
-
- if (cisco_kernel_mode == 1)
- set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
- value_from_string ("KDEBUG-"));
- cisco_kernel_mode = 1;
- }
goto got_status;
- case 'N': /* Cisco special: status and offsets */
- {
- bfd_vma text_addr, data_addr, bss_addr;
- bfd_signed_vma text_off, data_off, bss_off;
- unsigned char *p1;
-
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = (enum target_signal)
- (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
-
- if (symfile_objfile == NULL)
- {
- warning ("Relocation packet recieved with no symbol file. \
-Packet Dropped");
- goto got_status;
- }
-
- /* Relocate object file. Buffer format is NAATT;DD;BB
- * where AA is the signal number, TT is the new text
- * address, DD * is the new data address, and BB is the
- * new bss address. */
-
- p = &buf[3];
- text_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p || *p1 != ';')
- warning ("Malformed relocation packet: Packet '%s'", buf);
- p = p1 + 1;
- data_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p || *p1 != ';')
- warning ("Malformed relocation packet: Packet '%s'", buf);
- p = p1 + 1;
- bss_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p)
- warning ("Malformed relocation packet: Packet '%s'", buf);
-
- if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr,
- &text_off, &data_off, &bss_off)
- == 0)
- if (text_off != 0 || data_off != 0 || bss_off != 0)
- remote_cisco_objfile_relocate (text_off, data_off, bss_off);
-
- goto got_status;
- }
case 'W': /* Target exited */
{
/* The remote process exited. */
@@ -3395,7 +3240,6 @@ static int register_bytes_found;
/* Read the remote registers into the block REGS. */
/* Currently we just read all the registers, so we don't use regnum. */
-/* ARGSUSED */
static void
remote_fetch_registers (int regnum)
{
@@ -3481,9 +3325,23 @@ remote_fetch_registers (int regnum)
struct packet_reg *r = &rs->regs[i];
if (r->in_g_packet)
{
- supply_register (r->regnum, regs + r->offset);
- if (buf[r->offset * 2] == 'x')
- set_register_cached (i, -1);
+ if (r->offset * 2 >= strlen (buf))
+ /* A short packet that didn't include the register's
+ value, this implies that the register is zero (and
+ not that the register is unavailable). Supply that
+ zero value. */
+ regcache_raw_supply (current_regcache, r->regnum, NULL);
+ else if (buf[r->offset * 2] == 'x')
+ {
+ gdb_assert (r->offset * 2 < strlen (buf));
+ /* The register isn't available, mark it as such (at
+ the same time setting the value to zero). */
+ regcache_raw_supply (current_regcache, r->regnum, NULL);
+ set_register_cached (i, -1);
+ }
+ else
+ regcache_raw_supply (current_regcache, r->regnum,
+ regs + r->offset);
}
}
}
@@ -3496,15 +3354,19 @@ remote_fetch_registers (int regnum)
static void
remote_prepare_to_store (void)
{
+ struct remote_state *rs = get_remote_state ();
+ int i;
+ char buf[MAX_REGISTER_SIZE];
+
/* Make sure the entire registers array is valid. */
switch (remote_protocol_P.support)
{
case PACKET_DISABLE:
case PACKET_SUPPORT_UNKNOWN:
- /* NOTE: This isn't rs->sizeof_g_packet because here, we are
- forcing the register cache to read its and not the target
- registers. */
- read_register_bytes (0, (char *) NULL, REGISTER_BYTES); /* OK use. */
+ /* Make sure all the necessary registers are cached. */
+ for (i = 0; i < NUM_REGS; i++)
+ if (rs->regs[i].in_g_packet)
+ regcache_raw_read (current_regcache, rs->regs[i].regnum, buf);
break;
case PACKET_ENABLE:
break;
@@ -3521,14 +3383,14 @@ store_register_using_P (int regnum)
struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
/* Try storing a single register. */
char *buf = alloca (rs->remote_packet_size);
- char *regp = alloca (MAX_REGISTER_RAW_SIZE);
+ char regp[MAX_REGISTER_SIZE];
char *p;
int i;
sprintf (buf, "P%s=", phex_nz (reg->pnum, 0));
p = buf + strlen (buf);
regcache_collect (reg->regnum, regp);
- bin2hex (regp, p, REGISTER_RAW_SIZE (reg->regnum));
+ bin2hex (regp, p, DEPRECATED_REGISTER_RAW_SIZE (reg->regnum));
remote_send (buf, rs->remote_packet_size);
return buf[0] != '\0';
@@ -3685,7 +3547,7 @@ check_binary_download (CORE_ADDR addr)
{
char *buf = alloca (rs->remote_packet_size);
char *p;
-
+
p = buf;
*p++ = 'X';
p += hexnumstr (p, (ULONGEST) addr);
@@ -3693,7 +3555,7 @@ check_binary_download (CORE_ADDR addr)
p += hexnumstr (p, (ULONGEST) 0);
*p++ = ':';
*p = '\0';
-
+
putpkt_binary (buf, (int) (p - buf));
getpkt (buf, (rs->remote_packet_size), 0);
@@ -3725,46 +3587,49 @@ check_binary_download (CORE_ADDR addr)
Returns number of bytes transferred, or 0 (setting errno) for
error. Only transfer a single packet. */
-static int
+int
remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
{
unsigned char *buf;
- int max_buf_size; /* Max size of packet output buffer */
unsigned char *p;
unsigned char *plen;
long sizeof_buf;
int plenlen;
int todo;
int nr_bytes;
+ int payload_size;
+ unsigned char *payload_start;
- /* Verify that the target can support a binary download */
+ /* Verify that the target can support a binary download. */
check_binary_download (memaddr);
- /* Determine the max packet size. */
- max_buf_size = get_memory_write_packet_size ();
- sizeof_buf = max_buf_size + 1; /* Space for trailing NUL */
+ /* Compute the size, and then allocate space for the largest
+ possible packet. Include space for an extra trailing NUL. */
+ sizeof_buf = get_memory_write_packet_size () + 1;
buf = alloca (sizeof_buf);
- /* Subtract header overhead from max payload size - $M<memaddr>,<len>:#nn */
- max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
+ /* Compute the size of the actual payload by subtracting out the
+ packet header and footer overhead: "$M<memaddr>,<len>:...#nn". */
+ payload_size = (get_memory_write_packet_size () - (strlen ("$M,:#NN")
+ + hexnumlen (memaddr)
+ + hexnumlen (len)));
- /* construct "M"<memaddr>","<len>":" */
- /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
- p = buf;
+ /* Construct the packet header: "[MX]<memaddr>,<len>:". */
- /* Append [XM]. Compute a best guess of the number of bytes
+ /* Append "[XM]". Compute a best guess of the number of bytes
actually transfered. */
+ p = buf;
switch (remote_protocol_binary_download.support)
{
case PACKET_ENABLE:
*p++ = 'X';
/* Best guess at number of bytes that will fit. */
- todo = min (len, max_buf_size);
+ todo = min (len, payload_size);
break;
case PACKET_DISABLE:
*p++ = 'M';
/* num bytes that will fit */
- todo = min (len, max_buf_size / 2);
+ todo = min (len, payload_size / 2);
break;
case PACKET_SUPPORT_UNKNOWN:
internal_error (__FILE__, __LINE__,
@@ -3772,21 +3637,26 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
default:
internal_error (__FILE__, __LINE__, "bad switch");
}
-
- /* Append <memaddr> */
+
+ /* Append "<memaddr>". */
memaddr = remote_address_masked (memaddr);
p += hexnumstr (p, (ULONGEST) memaddr);
+
+ /* Append ",". */
*p++ = ',';
-
- /* Append <len>. Retain the location/size of <len>. It may
- need to be adjusted once the packet body has been created. */
+
+ /* Append <len>. Retain the location/size of <len>. It may need to
+ be adjusted once the packet body has been created. */
plen = p;
plenlen = hexnumstr (p, (ULONGEST) todo);
p += plenlen;
+
+ /* Append ":". */
*p++ = ':';
*p = '\0';
-
- /* Append the packet body. */
+
+ /* Append the packet body. */
+ payload_start = p;
switch (remote_protocol_binary_download.support)
{
case PACKET_ENABLE:
@@ -3794,7 +3664,7 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
increasing byte addresses. Only escape certain critical
characters. */
for (nr_bytes = 0;
- (nr_bytes < todo) && (p - buf) < (max_buf_size - 2);
+ (nr_bytes < todo) && (p - payload_start) < payload_size;
nr_bytes++)
{
switch (myaddr[nr_bytes] & 0xff)
@@ -3813,11 +3683,10 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
}
if (nr_bytes < todo)
{
- /* Escape chars have filled up the buffer prematurely,
+ /* Escape chars have filled up the buffer prematurely,
and we have actually sent fewer bytes than planned.
Fix-up the length field of the packet. Use the same
number of characters as before. */
-
plen += hexnumnstr (plen, (ULONGEST) nr_bytes, plenlen);
*plen = ':'; /* overwrite \0 from hexnumnstr() */
}
@@ -3835,10 +3704,10 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
default:
internal_error (__FILE__, __LINE__, "bad switch");
}
-
+
putpkt_binary (buf, (int) (p - buf));
getpkt (buf, sizeof_buf, 0);
-
+
if (buf[0] == 'E')
{
/* There is no correspondance between what the remote protocol
@@ -3848,7 +3717,7 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
errno = EIO;
return 0;
}
-
+
/* Return NR_BYTES, not TODO, in case escape chars caused us to send fewer
bytes than we'd planned. */
return nr_bytes;
@@ -3869,7 +3738,7 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
caller and its callers caller ;-) already contains code for
handling partial reads. */
-static int
+int
remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
{
char *buf;
@@ -3904,7 +3773,9 @@ remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
putpkt (buf);
getpkt (buf, sizeof_buf, 0);
- if (buf[0] == 'E')
+ if (buf[0] == 'E'
+ && isxdigit (buf[1]) && isxdigit (buf[2])
+ && buf[3] == '\0')
{
/* There is no correspondance between what the remote protocol uses
for errors and errno codes. We would like a cleaner way of
@@ -3936,7 +3807,6 @@ remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
SHOULD_WRITE is nonzero. Returns length of data written or read; 0
for error. TARGET is unused. */
-/* ARGSUSED */
static int
remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
int should_write, struct mem_attrib *attrib,
@@ -3946,7 +3816,10 @@ remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
int targ_len;
int res;
- REMOTE_TRANSLATE_XFER_ADDRESS (mem_addr, mem_len, &targ_addr, &targ_len);
+ /* Should this be the selected frame? */
+ gdbarch_remote_translate_xfer_address (current_gdbarch, current_regcache,
+ mem_addr, mem_len,
+ &targ_addr, &targ_len);
if (targ_len <= 0)
return 0;
@@ -3958,73 +3831,6 @@ remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
return res;
}
-
-#if 0
-/* Enable after 4.12. */
-
-void
-remote_search (int len, char *data, char *mask, CORE_ADDR startaddr,
- int increment, CORE_ADDR lorange, CORE_ADDR hirange,
- CORE_ADDR *addr_found, char *data_found)
-{
- if (increment == -4 && len == 4)
- {
- long mask_long, data_long;
- long data_found_long;
- CORE_ADDR addr_we_found;
- char *buf = alloca (rs->remote_packet_size);
- long returned_long[2];
- char *p;
-
- mask_long = extract_unsigned_integer (mask, len);
- data_long = extract_unsigned_integer (data, len);
- sprintf (buf, "t%x:%x,%x", startaddr, data_long, mask_long);
- putpkt (buf);
- getpkt (buf, (rs->remote_packet_size), 0);
- if (buf[0] == '\0')
- {
- /* The stub doesn't support the 't' request. We might want to
- remember this fact, but on the other hand the stub could be
- switched on us. Maybe we should remember it only until
- the next "target remote". */
- generic_search (len, data, mask, startaddr, increment, lorange,
- hirange, addr_found, data_found);
- return;
- }
-
- if (buf[0] == 'E')
- /* There is no correspondance between what the remote protocol uses
- for errors and errno codes. We would like a cleaner way of
- representing errors (big enough to include errno codes, bfd_error
- codes, and others). But for now just use EIO. */
- memory_error (EIO, startaddr);
- p = buf;
- addr_we_found = 0;
- while (*p != '\0' && *p != ',')
- addr_we_found = (addr_we_found << 4) + fromhex (*p++);
- if (*p == '\0')
- error ("Protocol error: short return for search");
-
- data_found_long = 0;
- while (*p != '\0' && *p != ',')
- data_found_long = (data_found_long << 4) + fromhex (*p++);
- /* Ignore anything after this comma, for future extensions. */
-
- if (addr_we_found < lorange || addr_we_found >= hirange)
- {
- *addr_found = 0;
- return;
- }
-
- *addr_found = addr_we_found;
- *data_found = store_unsigned_integer (data_we_found, len);
- return;
- }
- generic_search (len, data, mask, startaddr, increment, lorange,
- hirange, addr_found, data_found);
-}
-#endif /* 0 */
-
static void
remote_files_info (struct target_ops *ignore)
{
@@ -4217,8 +4023,6 @@ putpkt_binary (char *buf, int cnt)
}
}
-static int remote_cisco_mode;
-
/* Come here after finding the start of the frame. Collect the rest
into BUF, verifying the checksum, length, and handling run-length
compression. No more than sizeof_buf-1 characters are read so that
@@ -4265,7 +4069,7 @@ read_frame (char *buf,
check_0 = readchar (remote_timeout);
if (check_0 >= 0)
check_1 = readchar (remote_timeout);
-
+
if (check_0 == SERIAL_TIMEOUT || check_1 == SERIAL_TIMEOUT)
{
if (remote_debug)
@@ -4300,28 +4104,13 @@ read_frame (char *buf,
int repeat;
csum += c;
- if (remote_cisco_mode == 0)
- {
- c = readchar (remote_timeout);
- csum += c;
- repeat = c - ' ' + 3; /* Compute repeat count */
- }
- else
- {
- /* Cisco's run-length encoding variant uses two
- hex chars to represent the repeat count. */
-
- c = readchar (remote_timeout);
- csum += c;
- repeat = fromhex (c) << 4;
- c = readchar (remote_timeout);
- csum += c;
- repeat += fromhex (c);
- }
+ c = readchar (remote_timeout);
+ csum += c;
+ repeat = c - ' ' + 3; /* Compute repeat count */
/* The character before ``*'' is repeated. */
- if (repeat > 0 && repeat <= 255
+ if (repeat > 0 && repeat <= 255
&& bc > 0
&& bc + repeat - 1 < sizeof_buf - 1)
{
@@ -4522,7 +4311,7 @@ extended_remote_mourn (void)
{
/* We do _not_ want to mourn the target like this; this will
remove the extended remote target from the target stack,
- and the next time the user says "run" it'll fail.
+ and the next time the user says "run" it'll fail.
FIXME: What is the right thing to do here? */
#if 0
@@ -4540,7 +4329,7 @@ remote_mourn_1 (struct target_ops *target)
/* In the extended protocol we want to be able to do things like
"run" and have them basically work as expected. So we need
- a special create_inferior function.
+ a special create_inferior function.
FIXME: One day add support for changing the exec file
we're debugging, arguments and an environment. */
@@ -4594,61 +4383,62 @@ extended_remote_async_create_inferior (char *exec_file, char *args, char **env)
}
-/* On some machines, e.g. 68k, we may use a different breakpoint instruction
- than other targets; in those use REMOTE_BREAKPOINT instead of just
- BREAKPOINT. Also, bi-endian targets may define LITTLE_REMOTE_BREAKPOINT
- and BIG_REMOTE_BREAKPOINT. If none of these are defined, we just call
- the standard routines that are in mem-break.c. */
+/* On some machines, e.g. 68k, we may use a different breakpoint
+ instruction than other targets; in those use
+ DEPRECATED_REMOTE_BREAKPOINT instead of just BREAKPOINT_FROM_PC.
+ Also, bi-endian targets may define
+ DEPRECATED_LITTLE_REMOTE_BREAKPOINT and
+ DEPRECATED_BIG_REMOTE_BREAKPOINT. If none of these are defined, we
+ just call the standard routines that are in mem-break.c. */
-/* FIXME, these ought to be done in a more dynamic fashion. For instance,
- the choice of breakpoint instruction affects target program design and
- vice versa, and by making it user-tweakable, the special code here
- goes away and we need fewer special GDB configurations. */
+/* NOTE: cagney/2003-06-08: This is silly. A remote and simulator
+ target should use an identical BREAKPOINT_FROM_PC. As for native,
+ the ARCH-OS-tdep.c code can override the default. */
-#if defined (LITTLE_REMOTE_BREAKPOINT) && defined (BIG_REMOTE_BREAKPOINT) && !defined(REMOTE_BREAKPOINT)
-#define REMOTE_BREAKPOINT
+#if defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && defined (DEPRECATED_BIG_REMOTE_BREAKPOINT) && !defined(DEPRECATED_REMOTE_BREAKPOINT)
+#define DEPRECATED_REMOTE_BREAKPOINT
#endif
-#ifdef REMOTE_BREAKPOINT
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
/* If the target isn't bi-endian, just pretend it is. */
-#if !defined (LITTLE_REMOTE_BREAKPOINT) && !defined (BIG_REMOTE_BREAKPOINT)
-#define LITTLE_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
-#define BIG_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
+#if !defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && !defined (DEPRECATED_BIG_REMOTE_BREAKPOINT)
+#define DEPRECATED_LITTLE_REMOTE_BREAKPOINT DEPRECATED_REMOTE_BREAKPOINT
+#define DEPRECATED_BIG_REMOTE_BREAKPOINT DEPRECATED_REMOTE_BREAKPOINT
#endif
-static unsigned char big_break_insn[] = BIG_REMOTE_BREAKPOINT;
-static unsigned char little_break_insn[] = LITTLE_REMOTE_BREAKPOINT;
+static unsigned char big_break_insn[] = DEPRECATED_BIG_REMOTE_BREAKPOINT;
+static unsigned char little_break_insn[] = DEPRECATED_LITTLE_REMOTE_BREAKPOINT;
-#endif /* REMOTE_BREAKPOINT */
+#endif /* DEPRECATED_REMOTE_BREAKPOINT */
-/* Insert a breakpoint on targets that don't have any better breakpoint
- support. We read the contents of the target location and stash it,
- then overwrite it with a breakpoint instruction. ADDR is the target
- location in the target machine. CONTENTS_CACHE is a pointer to
- memory allocated for saving the target contents. It is guaranteed
- by the caller to be long enough to save sizeof BREAKPOINT bytes (this
- is accomplished via BREAKPOINT_MAX). */
+/* Insert a breakpoint on targets that don't have any better
+ breakpoint support. We read the contents of the target location
+ and stash it, then overwrite it with a breakpoint instruction.
+ ADDR is the target location in the target machine. CONTENTS_CACHE
+ is a pointer to memory allocated for saving the target contents.
+ It is guaranteed by the caller to be long enough to save the number
+ of bytes returned by BREAKPOINT_FROM_PC. */
static int
remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
{
struct remote_state *rs = get_remote_state ();
-#ifdef REMOTE_BREAKPOINT
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
int val;
-#endif
+#endif
int bp_size;
/* Try the "Z" s/w breakpoint packet if it is not already disabled.
If it succeeds, then set the support to PACKET_ENABLE. If it
fails, and the user has explicitly requested the Z support then
report an error, otherwise, mark it disabled and go on. */
-
+
if (remote_protocol_Z[Z_PACKET_SOFTWARE_BP].support != PACKET_DISABLE)
{
char *buf = alloca (rs->remote_packet_size);
char *p = buf;
-
+
addr = remote_address_masked (addr);
*(p++) = 'Z';
*(p++) = '0';
@@ -4656,7 +4446,7 @@ remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
p += hexnumstr (p, (ULONGEST) addr);
BREAKPOINT_FROM_PC (&addr, &bp_size);
sprintf (p, ",%d", bp_size);
-
+
putpkt (buf);
getpkt (buf, (rs->remote_packet_size), 0);
@@ -4671,7 +4461,7 @@ remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
}
}
-#ifdef REMOTE_BREAKPOINT
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
val = target_read_memory (addr, contents_cache, sizeof big_break_insn);
if (val == 0)
@@ -4687,7 +4477,7 @@ remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
return val;
#else
return memory_insert_breakpoint (addr, contents_cache);
-#endif /* REMOTE_BREAKPOINT */
+#endif /* DEPRECATED_REMOTE_BREAKPOINT */
}
static int
@@ -4700,7 +4490,7 @@ remote_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
{
char *buf = alloca (rs->remote_packet_size);
char *p = buf;
-
+
*(p++) = 'z';
*(p++) = '0';
*(p++) = ',';
@@ -4709,18 +4499,18 @@ remote_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
p += hexnumstr (p, (ULONGEST) addr);
BREAKPOINT_FROM_PC (&addr, &bp_size);
sprintf (p, ",%d", bp_size);
-
+
putpkt (buf);
getpkt (buf, (rs->remote_packet_size), 0);
return (buf[0] == 'E');
}
-#ifdef REMOTE_BREAKPOINT
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
return target_write_memory (addr, contents_cache, sizeof big_break_insn);
#else
return memory_remove_breakpoint (addr, contents_cache);
-#endif /* REMOTE_BREAKPOINT */
+#endif /* DEPRECATED_REMOTE_BREAKPOINT */
}
static int
@@ -4743,10 +4533,7 @@ watchpoint_to_Z_packet (int type)
}
}
-/* FIXME: This function should be static and a member of the remote
- target vector. */
-
-int
+static int
remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
{
struct remote_state *rs = get_remote_state ();
@@ -4758,13 +4545,13 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
error ("Can't set hardware watchpoints without the '%s' (%s) packet\n",
remote_protocol_Z[packet].name,
remote_protocol_Z[packet].title);
-
+
sprintf (buf, "Z%x,", packet);
p = strchr (buf, '\0');
addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", len);
-
+
putpkt (buf);
getpkt (buf, (rs->remote_packet_size), 0);
@@ -4780,10 +4567,8 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
"remote_insert_watchpoint: reached end of function");
}
-/* FIXME: This function should be static and a member of the remote
- target vector. */
-int
+static int
remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
{
struct remote_state *rs = get_remote_state ();
@@ -4795,7 +4580,7 @@ remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
error ("Can't clear hardware watchpoints without the '%s' (%s) packet\n",
remote_protocol_Z[packet].name,
remote_protocol_Z[packet].title);
-
+
sprintf (buf, "z%x,", packet);
p = strchr (buf, '\0');
addr = remote_address_masked (addr);
@@ -4816,25 +4601,73 @@ remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
"remote_remove_watchpoint: reached end of function");
}
-/* FIXME: This function should be static and a member of the remote
- target vector. */
-int
-remote_insert_hw_breakpoint (CORE_ADDR addr, int len)
+int remote_hw_watchpoint_limit = -1;
+int remote_hw_breakpoint_limit = -1;
+
+static int
+remote_check_watch_resources (int type, int cnt, int ot)
{
+ if (type == bp_hardware_breakpoint)
+ {
+ if (remote_hw_breakpoint_limit == 0)
+ return 0;
+ else if (remote_hw_breakpoint_limit < 0)
+ return 1;
+ else if (cnt <= remote_hw_breakpoint_limit)
+ return 1;
+ }
+ else
+ {
+ if (remote_hw_watchpoint_limit == 0)
+ return 0;
+ else if (remote_hw_watchpoint_limit < 0)
+ return 1;
+ else if (ot)
+ return -1;
+ else if (cnt <= remote_hw_watchpoint_limit)
+ return 1;
+ }
+ return -1;
+}
+
+static int
+remote_stopped_by_watchpoint (void)
+{
+ return remote_stopped_by_watchpoint_p;
+}
+
+static CORE_ADDR
+remote_stopped_data_address (void)
+{
+ if (remote_stopped_by_watchpoint ())
+ return remote_watch_data_address;
+ return (CORE_ADDR)0;
+}
+
+
+static int
+remote_insert_hw_breakpoint (CORE_ADDR addr, char *shadow)
+{
+ int len = 0;
struct remote_state *rs = get_remote_state ();
char *buf = alloca (rs->remote_packet_size);
char *p = buf;
-
+
+ /* The length field should be set to the size of a breakpoint
+ instruction. */
+
+ BREAKPOINT_FROM_PC (&addr, &len);
+
if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE)
error ("Can't set hardware breakpoint without the '%s' (%s) packet\n",
remote_protocol_Z[Z_PACKET_HARDWARE_BP].name,
remote_protocol_Z[Z_PACKET_HARDWARE_BP].title);
-
+
*(p++) = 'Z';
*(p++) = '1';
*(p++) = ',';
-
+
addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", len);
@@ -4851,35 +4684,39 @@ remote_insert_hw_breakpoint (CORE_ADDR addr, int len)
return 0;
}
internal_error (__FILE__, __LINE__,
- "remote_remove_watchpoint: reached end of function");
+ "remote_insert_hw_breakpoint: reached end of function");
}
-/* FIXME: This function should be static and a member of the remote
- target vector. */
-int
-remote_remove_hw_breakpoint (CORE_ADDR addr, int len)
+static int
+remote_remove_hw_breakpoint (CORE_ADDR addr, char *shadow)
{
+ int len;
struct remote_state *rs = get_remote_state ();
char *buf = alloca (rs->remote_packet_size);
char *p = buf;
-
+
+ /* The length field should be set to the size of a breakpoint
+ instruction. */
+
+ BREAKPOINT_FROM_PC (&addr, &len);
+
if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE)
error ("Can't clear hardware breakpoint without the '%s' (%s) packet\n",
remote_protocol_Z[Z_PACKET_HARDWARE_BP].name,
remote_protocol_Z[Z_PACKET_HARDWARE_BP].title);
-
+
*(p++) = 'z';
*(p++) = '1';
*(p++) = ',';
-
+
addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", len);
putpkt(buf);
getpkt (buf, (rs->remote_packet_size), 0);
-
+
switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_HARDWARE_BP]))
{
case PACKET_ERROR:
@@ -4889,7 +4726,7 @@ remote_remove_hw_breakpoint (CORE_ADDR addr, int len)
return 0;
}
internal_error (__FILE__, __LINE__,
- "remote_remove_watchpoint: reached end of function");
+ "remote_remove_hw_breakpoint: reached end of function");
}
/* Some targets are only capable of doing downloads, and afterwards
@@ -4909,18 +4746,6 @@ push_remote_target (char *name, int from_tty)
remote_open (name, from_tty);
}
-/* Other targets want to use the entire remote serial module but with
- certain remote_ops overridden. */
-
-void
-open_remote_target (char *name, int from_tty, struct target_ops *target,
- int extended_p)
-{
- printf_filtered ("Selecting the %sremote protocol\n",
- (extended_p ? "extended-" : ""));
- remote_open_1 (name, from_tty, target, extended_p);
-}
-
/* Table used by the crc32 function to calcuate the checksum. */
static unsigned long crc32_table[256] =
@@ -5013,8 +4838,8 @@ compare_sections_command (char *args, int from_tty)
getpkt (buf, (rs->remote_packet_size), 0);
if (buf[0] == 'E')
- error ("target memory fault, section %s, range 0x%08x -- 0x%08x",
- sectname, lma, lma + size);
+ error ("target memory fault, section %s, range 0x%s -- 0x%s",
+ sectname, paddr (lma), paddr (lma + size));
if (buf[0] != 'C')
error ("remote target does not support this operation");
@@ -5040,41 +4865,86 @@ the loaded file\n");
printf_filtered ("No loaded section named '%s'.\n", args);
}
-static int
-remote_query (int query_type, char *buf, char *outbuf, int *bufsiz)
+static LONGEST
+remote_xfer_partial (struct target_ops *ops, enum target_object object,
+ const char *annex, void *readbuf, const void *writebuf,
+ ULONGEST offset, LONGEST len)
{
struct remote_state *rs = get_remote_state ();
int i;
char *buf2 = alloca (rs->remote_packet_size);
char *p2 = &buf2[0];
+ char query_type;
- if (!bufsiz)
- error ("null pointer to remote bufer size specified");
+ /* Only handle reads. */
+ if (writebuf != NULL || readbuf == NULL)
+ return -1;
- /* minimum outbuf size is (rs->remote_packet_size) - if bufsiz is not large enough let
- the caller know and return what the minimum size is */
- /* Note: a zero bufsiz can be used to query the minimum buffer size */
- if (*bufsiz < (rs->remote_packet_size))
+ /* Map pre-existing objects onto letters. DO NOT do this for new
+ objects!!! Instead specify new query packets. */
+ switch (object)
{
- *bufsiz = (rs->remote_packet_size);
+ case TARGET_OBJECT_KOD:
+ query_type = 'K';
+ break;
+ case TARGET_OBJECT_AVR:
+ query_type = 'R';
+ break;
+
+ case TARGET_OBJECT_AUXV:
+ if (remote_protocol_qPart_auxv.support != PACKET_DISABLE)
+ {
+ unsigned int total = 0;
+ while (len > 0)
+ {
+ LONGEST n = min ((rs->remote_packet_size - 2) / 2, len);
+ snprintf (buf2, rs->remote_packet_size,
+ "qPart:auxv:read::%s,%s",
+ phex_nz (offset, sizeof offset),
+ phex_nz (n, sizeof n));
+ i = putpkt (buf2);
+ if (i < 0)
+ return total > 0 ? total : i;
+ buf2[0] = '\0';
+ getpkt (buf2, rs->remote_packet_size, 0);
+ if (packet_ok (buf2, &remote_protocol_qPart_auxv) != PACKET_OK)
+ return total > 0 ? total : -1;
+ if (buf2[0] == 'O' && buf2[1] == 'K' && buf2[2] == '\0')
+ break; /* Got EOF indicator. */
+ /* Got some data. */
+ i = hex2bin (buf2, readbuf, len);
+ if (i > 0)
+ {
+ readbuf = (void *) ((char *) readbuf + i);
+ offset += i;
+ len -= i;
+ total += i;
+ }
+ }
+ return total;
+ }
+ return -1;
+
+ default:
return -1;
}
+ /* Note: a zero OFFSET and LEN can be used to query the minimum
+ buffer size. */
+ if (offset == 0 && len == 0)
+ return (rs->remote_packet_size);
+ /* Minimum outbuf size is (rs->remote_packet_size) - if bufsiz is
+ not large enough let the caller. */
+ if (len < (rs->remote_packet_size))
+ return -1;
+ len = rs->remote_packet_size;
+
/* except for querying the minimum buffer size, target must be open */
if (!remote_desc)
error ("remote query is only available after target open");
- /* we only take uppercase letters as query types, at least for now */
- if ((query_type < 'A') || (query_type > 'Z'))
- error ("invalid remote query type");
-
- if (!buf)
- error ("null remote query specified");
-
- if (!outbuf)
- error ("remote query requires a buffer to receive data");
-
- outbuf[0] = '\0';
+ gdb_assert (annex != NULL);
+ gdb_assert (readbuf != NULL);
*p2++ = 'q';
*p2++ = query_type;
@@ -5084,27 +4954,23 @@ remote_query (int query_type, char *buf, char *outbuf, int *bufsiz)
plus one extra in case we are debugging (remote_debug),
we have PBUFZIZ - 7 left to pack the query string */
i = 0;
- while (buf[i] && (i < ((rs->remote_packet_size) - 8)))
+ while (annex[i] && (i < ((rs->remote_packet_size) - 8)))
{
- /* bad caller may have sent forbidden characters */
- if ((!isprint (buf[i])) || (buf[i] == '$') || (buf[i] == '#'))
- error ("illegal characters in query string");
-
- *p2++ = buf[i];
+ /* Bad caller may have sent forbidden characters. */
+ gdb_assert (isprint (annex[i]) && annex[i] != '$' && annex[i] != '#');
+ *p2++ = annex[i];
i++;
}
- *p2 = buf[i];
-
- if (buf[i])
- error ("query larger than available buffer");
+ *p2 = '\0';
+ gdb_assert (annex[i] == '\0');
i = putpkt (buf2);
if (i < 0)
return i;
- getpkt (outbuf, *bufsiz, 0);
+ getpkt (readbuf, len, 0);
- return 0;
+ return strlen (readbuf);
}
static void
@@ -5357,6 +5223,7 @@ Specify the serial device it is connected to\n\
remote_ops.to_open = remote_open;
remote_ops.to_close = remote_close;
remote_ops.to_detach = remote_detach;
+ remote_ops.to_disconnect = remote_disconnect;
remote_ops.to_resume = remote_resume;
remote_ops.to_wait = remote_wait;
remote_ops.to_fetch_registers = remote_fetch_registers;
@@ -5366,6 +5233,13 @@ Specify the serial device it is connected to\n\
remote_ops.to_files_info = remote_files_info;
remote_ops.to_insert_breakpoint = remote_insert_breakpoint;
remote_ops.to_remove_breakpoint = remote_remove_breakpoint;
+ remote_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
+ remote_ops.to_stopped_data_address = remote_stopped_data_address;
+ remote_ops.to_can_use_hw_breakpoint = remote_check_watch_resources;
+ remote_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint;
+ remote_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
+ remote_ops.to_insert_watchpoint = remote_insert_watchpoint;
+ remote_ops.to_remove_watchpoint = remote_remove_watchpoint;
remote_ops.to_kill = remote_kill;
remote_ops.to_load = generic_load;
remote_ops.to_mourn_inferior = remote_mourn;
@@ -5374,7 +5248,7 @@ Specify the serial device it is connected to\n\
remote_ops.to_pid_to_str = remote_pid_to_str;
remote_ops.to_extra_thread_info = remote_threads_extra_info;
remote_ops.to_stop = remote_stop;
- remote_ops.to_query = remote_query;
+ remote_ops.to_xfer_partial = remote_xfer_partial;
remote_ops.to_rcmd = remote_rcmd;
remote_ops.to_stratum = process_stratum;
remote_ops.to_has_all_memory = 1;
@@ -5405,394 +5279,6 @@ Specify the serial device it is connected to (e.g. /dev/ttya).",
extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
}
-/*
- * Command: info remote-process
- *
- * This implements Cisco's version of the "info proc" command.
- *
- * This query allows the target stub to return an arbitrary string
- * (or strings) giving arbitrary information about the target process.
- * This is optional; the target stub isn't required to implement it.
- *
- * Syntax: qfProcessInfo request first string
- * qsProcessInfo request subsequent string
- * reply: 'O'<hex-encoded-string>
- * 'l' last reply (empty)
- */
-
-static void
-remote_info_process (char *args, int from_tty)
-{
- struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
-
- if (remote_desc == 0)
- error ("Command can only be used when connected to the remote target.");
-
- putpkt ("qfProcessInfo");
- getpkt (buf, (rs->remote_packet_size), 0);
- if (buf[0] == 0)
- return; /* Silently: target does not support this feature. */
-
- if (buf[0] == 'E')
- error ("info proc: target error.");
-
- while (buf[0] == 'O') /* Capitol-O packet */
- {
- remote_console_output (&buf[1]);
- putpkt ("qsProcessInfo");
- getpkt (buf, (rs->remote_packet_size), 0);
- }
-}
-
-/*
- * Target Cisco
- */
-
-static void
-remote_cisco_open (char *name, int from_tty)
-{
- if (name == 0)
- error ("To open a remote debug connection, you need to specify what \n"
- "device is attached to the remote system (e.g. host:port).");
-
- /* See FIXME above */
- wait_forever_enabled_p = 1;
-
- target_preopen (from_tty);
-
- unpush_target (&remote_cisco_ops);
-
- remote_desc = serial_open (name);
- if (!remote_desc)
- perror_with_name (name);
-
- /*
- * If a baud rate was specified on the gdb command line it will
- * be greater than the initial value of -1. If it is, use it otherwise
- * default to 9600
- */
-
- baud_rate = (baud_rate > 0) ? baud_rate : 9600;
- if (serial_setbaudrate (remote_desc, baud_rate))
- {
- serial_close (remote_desc);
- perror_with_name (name);
- }
-
- serial_raw (remote_desc);
-
- /* If there is something sitting in the buffer we might take it as a
- response to a command, which would be bad. */
- serial_flush_input (remote_desc);
-
- if (from_tty)
- {
- puts_filtered ("Remote debugging using ");
- puts_filtered (name);
- puts_filtered ("\n");
- }
-
- remote_cisco_mode = 1;
-
- push_target (&remote_cisco_ops); /* Switch to using cisco target now */
-
- init_all_packet_configs ();
-
- general_thread = -2;
- continue_thread = -2;
-
- /* Probe for ability to use "ThreadInfo" query, as required. */
- use_threadinfo_query = 1;
- use_threadextra_query = 1;
-
- /* Without this, some commands which require an active target (such
- as kill) won't work. This variable serves (at least) double duty
- as both the pid of the target process (if it has such), and as a
- flag indicating that a target is active. These functions should
- be split out into seperate variables, especially since GDB will
- someday have a notion of debugging several processes. */
- inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
-
- /* Start the remote connection; if error (0), discard this target. */
-
- if (!catch_errors (remote_start_remote_dummy, (char *) 0,
- "Couldn't establish connection to remote target\n",
- RETURN_MASK_ALL))
- {
- pop_target ();
- return;
- }
-}
-
-static void
-remote_cisco_close (int quitting)
-{
- remote_cisco_mode = 0;
- remote_close (quitting);
-}
-
-static void
-remote_cisco_mourn (void)
-{
- remote_mourn_1 (&remote_cisco_ops);
-}
-
-enum
-{
- READ_MORE,
- FATAL_ERROR,
- ENTER_DEBUG,
- DISCONNECT_TELNET
-}
-minitelnet_return;
-
-/* Shared between readsocket() and readtty(). The size is arbitrary,
- however all targets are known to support a 400 character packet. */
-static char tty_input[400];
-
-static int escape_count;
-static int echo_check;
-extern int quit_flag;
-
-static int
-readsocket (void)
-{
- int data;
-
- /* Loop until the socket doesn't have any more data */
-
- while ((data = readchar (0)) >= 0)
- {
- /* Check for the escape sequence */
- if (data == '|')
- {
- /* If this is the fourth escape, get out */
- if (++escape_count == 4)
- {
- return ENTER_DEBUG;
- }
- else
- { /* This is a '|', but not the fourth in a row.
- Continue without echoing it. If it isn't actually
- one of four in a row, it'll be echoed later. */
- continue;
- }
- }
- else
- /* Not a '|' */
- {
- /* Ensure any pending '|'s are flushed. */
-
- for (; escape_count > 0; escape_count--)
- putchar ('|');
- }
-
- if (data == '\r') /* If this is a return character, */
- continue; /* - just supress it. */
-
- if (echo_check != -1) /* Check for echo of user input. */
- {
- if (tty_input[echo_check] == data)
- {
- gdb_assert (echo_check <= sizeof (tty_input));
- echo_check++; /* Character matched user input: */
- continue; /* Continue without echoing it. */
- }
- else if ((data == '\n') && (tty_input[echo_check] == '\r'))
- { /* End of the line (and of echo checking). */
- echo_check = -1; /* No more echo supression */
- continue; /* Continue without echoing. */
- }
- else
- { /* Failed check for echo of user input.
- We now have some suppressed output to flush! */
- int j;
-
- for (j = 0; j < echo_check; j++)
- putchar (tty_input[j]);
- echo_check = -1;
- }
- }
- putchar (data); /* Default case: output the char. */
- }
-
- if (data == SERIAL_TIMEOUT) /* Timeout returned from readchar. */
- return READ_MORE; /* Try to read some more */
- else
- return FATAL_ERROR; /* Trouble, bail out */
-}
-
-static int
-readtty (void)
-{
- int tty_bytecount;
-
- /* First, read a buffer full from the terminal */
- tty_bytecount = read (fileno (stdin), tty_input, sizeof (tty_input) - 1);
- if (tty_bytecount == -1)
- {
- perror ("readtty: read failed");
- return FATAL_ERROR;
- }
-
- /* Remove a quoted newline. */
- if (tty_input[tty_bytecount - 1] == '\n' &&
- tty_input[tty_bytecount - 2] == '\\') /* line ending in backslash */
- {
- tty_input[--tty_bytecount] = 0; /* remove newline */
- tty_input[--tty_bytecount] = 0; /* remove backslash */
- }
-
- /* Turn trailing newlines into returns */
- if (tty_input[tty_bytecount - 1] == '\n')
- tty_input[tty_bytecount - 1] = '\r';
-
- /* If the line consists of a ~, enter debugging mode. */
- if ((tty_input[0] == '~') && (tty_bytecount == 2))
- return ENTER_DEBUG;
-
- /* Make this a zero terminated string and write it out */
- tty_input[tty_bytecount] = 0;
- if (serial_write (remote_desc, tty_input, tty_bytecount))
- {
- perror_with_name ("readtty: write failed");
- return FATAL_ERROR;
- }
-
- return READ_MORE;
-}
-
-static int
-minitelnet (void)
-{
- fd_set input; /* file descriptors for select */
- int tablesize; /* max number of FDs for select */
- int status;
- int quit_count = 0;
-
- extern int escape_count; /* global shared by readsocket */
- extern int echo_check; /* ditto */
-
- escape_count = 0;
- echo_check = -1;
-
- tablesize = 8 * sizeof (input);
-
- for (;;)
- {
- /* Check for anything from our socket - doesn't block. Note that
- this must be done *before* the select as there may be
- buffered I/O waiting to be processed. */
-
- if ((status = readsocket ()) == FATAL_ERROR)
- {
- error ("Debugging terminated by communications error");
- }
- else if (status != READ_MORE)
- {
- return (status);
- }
-
- fflush (stdout); /* Flush output before blocking */
-
- /* Now block on more socket input or TTY input */
-
- FD_ZERO (&input);
- FD_SET (fileno (stdin), &input);
- FD_SET (deprecated_serial_fd (remote_desc), &input);
-
- status = select (tablesize, &input, 0, 0, 0);
- if ((status == -1) && (errno != EINTR))
- {
- error ("Communications error on select %d", errno);
- }
-
- /* Handle Control-C typed */
-
- if (quit_flag)
- {
- if ((++quit_count) == 2)
- {
- if (query ("Interrupt GDB? "))
- {
- printf_filtered ("Interrupted by user.\n");
- throw_exception (RETURN_QUIT);
- }
- quit_count = 0;
- }
- quit_flag = 0;
-
- if (remote_break)
- serial_send_break (remote_desc);
- else
- serial_write (remote_desc, "\003", 1);
-
- continue;
- }
-
- /* Handle console input */
-
- if (FD_ISSET (fileno (stdin), &input))
- {
- quit_count = 0;
- echo_check = 0;
- status = readtty ();
- if (status == READ_MORE)
- continue;
-
- return status; /* telnet session ended */
- }
- }
-}
-
-static ptid_t
-remote_cisco_wait (ptid_t ptid, struct target_waitstatus *status)
-{
- if (minitelnet () != ENTER_DEBUG)
- {
- error ("Debugging session terminated by protocol error");
- }
- putpkt ("?");
- return remote_wait (ptid, status);
-}
-
-static void
-init_remote_cisco_ops (void)
-{
- remote_cisco_ops.to_shortname = "cisco";
- remote_cisco_ops.to_longname = "Remote serial target in cisco-specific protocol";
- remote_cisco_ops.to_doc =
- "Use a remote machine via TCP, using a cisco-specific protocol.\n\
-Specify the serial device it is connected to (e.g. host:2020).";
- remote_cisco_ops.to_open = remote_cisco_open;
- remote_cisco_ops.to_close = remote_cisco_close;
- remote_cisco_ops.to_detach = remote_detach;
- remote_cisco_ops.to_resume = remote_resume;
- remote_cisco_ops.to_wait = remote_cisco_wait;
- remote_cisco_ops.to_fetch_registers = remote_fetch_registers;
- remote_cisco_ops.to_store_registers = remote_store_registers;
- remote_cisco_ops.to_prepare_to_store = remote_prepare_to_store;
- remote_cisco_ops.to_xfer_memory = remote_xfer_memory;
- remote_cisco_ops.to_files_info = remote_files_info;
- remote_cisco_ops.to_insert_breakpoint = remote_insert_breakpoint;
- remote_cisco_ops.to_remove_breakpoint = remote_remove_breakpoint;
- remote_cisco_ops.to_kill = remote_kill;
- remote_cisco_ops.to_load = generic_load;
- remote_cisco_ops.to_mourn_inferior = remote_cisco_mourn;
- remote_cisco_ops.to_thread_alive = remote_thread_alive;
- remote_cisco_ops.to_find_new_threads = remote_threads_info;
- remote_cisco_ops.to_pid_to_str = remote_pid_to_str;
- remote_cisco_ops.to_extra_thread_info = remote_threads_extra_info;
- remote_cisco_ops.to_stratum = process_stratum;
- remote_cisco_ops.to_has_all_memory = 1;
- remote_cisco_ops.to_has_memory = 1;
- remote_cisco_ops.to_has_stack = 1;
- remote_cisco_ops.to_has_registers = 1;
- remote_cisco_ops.to_has_execution = 1;
- remote_cisco_ops.to_magic = OPS_MAGIC;
-}
-
static int
remote_can_async_p (void)
{
@@ -5856,7 +5342,8 @@ init_remote_async_ops (void)
Specify the serial device it is connected to (e.g. /dev/ttya).";
remote_async_ops.to_open = remote_async_open;
remote_async_ops.to_close = remote_close;
- remote_async_ops.to_detach = remote_async_detach;
+ remote_async_ops.to_detach = remote_detach;
+ remote_async_ops.to_disconnect = remote_disconnect;
remote_async_ops.to_resume = remote_async_resume;
remote_async_ops.to_wait = remote_async_wait;
remote_async_ops.to_fetch_registers = remote_fetch_registers;
@@ -5866,6 +5353,13 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
remote_async_ops.to_files_info = remote_files_info;
remote_async_ops.to_insert_breakpoint = remote_insert_breakpoint;
remote_async_ops.to_remove_breakpoint = remote_remove_breakpoint;
+ remote_async_ops.to_can_use_hw_breakpoint = remote_check_watch_resources;
+ remote_async_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint;
+ remote_async_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
+ remote_async_ops.to_insert_watchpoint = remote_insert_watchpoint;
+ remote_async_ops.to_remove_watchpoint = remote_remove_watchpoint;
+ remote_async_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
+ remote_async_ops.to_stopped_data_address = remote_stopped_data_address;
remote_async_ops.to_terminal_inferior = remote_async_terminal_inferior;
remote_async_ops.to_terminal_ours = remote_async_terminal_ours;
remote_async_ops.to_kill = remote_async_kill;
@@ -5876,7 +5370,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
remote_async_ops.to_pid_to_str = remote_pid_to_str;
remote_async_ops.to_extra_thread_info = remote_threads_extra_info;
remote_async_ops.to_stop = remote_stop;
- remote_async_ops.to_query = remote_query;
+ remote_async_ops.to_xfer_partial = remote_xfer_partial;
remote_async_ops.to_rcmd = remote_rcmd;
remote_async_ops.to_stratum = process_stratum;
remote_async_ops.to_has_all_memory = 1;
@@ -5919,13 +5413,16 @@ set_remote_cmd (char *args, int from_tty)
static void
show_remote_cmd (char *args, int from_tty)
{
-
- show_remote_protocol_Z_packet_cmd (args, from_tty);
- show_remote_protocol_e_packet_cmd (args, from_tty);
- show_remote_protocol_E_packet_cmd (args, from_tty);
- show_remote_protocol_P_packet_cmd (args, from_tty);
- show_remote_protocol_qSymbol_packet_cmd (args, from_tty);
- show_remote_protocol_binary_download_cmd (args, from_tty);
+ /* FIXME: cagney/2002-06-15: This function should iterate over
+ remote_show_cmdlist for a list of sub commands to show. */
+ show_remote_protocol_Z_packet_cmd (args, from_tty, NULL);
+ show_remote_protocol_e_packet_cmd (args, from_tty, NULL);
+ show_remote_protocol_E_packet_cmd (args, from_tty, NULL);
+ show_remote_protocol_P_packet_cmd (args, from_tty, NULL);
+ show_remote_protocol_qSymbol_packet_cmd (args, from_tty, NULL);
+ show_remote_protocol_vcont_packet_cmd (args, from_tty, NULL);
+ show_remote_protocol_binary_download_cmd (args, from_tty, NULL);
+ show_remote_protocol_qPart_auxv_packet_cmd (args, from_tty, NULL);
}
static void
@@ -5959,14 +5456,12 @@ _initialize_remote (void)
struct cmd_list_element *tmpcmd;
/* architecture specific data */
- remote_gdbarch_data_handle = register_gdbarch_data (init_remote_state,
- free_remote_state);
+ remote_gdbarch_data_handle = register_gdbarch_data (init_remote_state);
/* Old tacky stuff. NOTE: This comes after the remote protocol so
that the remote protocol has been initialized. */
- register_gdbarch_swap (&remote_address_size,
- sizeof (&remote_address_size), NULL);
- register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data);
+ DEPRECATED_REGISTER_GDBARCH_SWAP (remote_address_size);
+ deprecated_register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data);
init_remote_ops ();
add_target (&remote_ops);
@@ -5980,9 +5475,6 @@ _initialize_remote (void)
init_extended_async_remote_ops ();
add_target (&extended_async_remote_ops);
- init_remote_cisco_ops ();
- add_target (&remote_cisco_ops);
-
/* Hook into new objfile notification. */
remote_new_objfile_chain = target_new_objfile_hook;
target_new_objfile_hook = remote_new_objfile;
@@ -6020,11 +5512,11 @@ response packet. GDB supplies the initial `$' character, and the\n\
terminating `#' character and checksum.",
&maintenancelist);
- add_show_from_set
- (add_set_boolean_cmd ("remotebreak", no_class, &remote_break,
- "Set whether to send break if interrupted.\n",
- &setlist),
- &showlist);
+ add_setshow_boolean_cmd ("remotebreak", no_class, &remote_break,
+ "Set whether to send break if interrupted.\n",
+ "Show whether to send break if interrupted.\n",
+ NULL, NULL,
+ &setlist, &showlist);
/* Install commands for configuring memory read/write packets. */
@@ -6059,6 +5551,19 @@ terminating `#' character and checksum.",
"Show the maximum number of bytes per memory-read packet.\n",
&remote_show_cmdlist);
+ add_setshow_cmd ("hardware-watchpoint-limit", no_class,
+ var_zinteger, &remote_hw_watchpoint_limit, "\
+Set the maximum number of target hardware watchpoints.\n\
+Specify a negative limit for unlimited.", "\
+Show the maximum number of target hardware watchpoints.\n",
+ NULL, NULL, &remote_set_cmdlist, &remote_show_cmdlist);
+ add_setshow_cmd ("hardware-breakpoint-limit", no_class,
+ var_zinteger, &remote_hw_breakpoint_limit, "\
+Set the maximum number of target hardware breakpoints.\n\
+Specify a negative limit for unlimited.", "\
+Show the maximum number of target hardware breakpoints.\n",
+ NULL, NULL, &remote_set_cmdlist, &remote_show_cmdlist);
+
add_show_from_set
(add_set_cmd ("remoteaddresssize", class_obscure,
var_integer, (char *) &remote_address_size,
@@ -6083,8 +5588,12 @@ in a memory packet.\n",
&showlist);
#endif
- add_info ("remote-process", remote_info_process,
- "Query the remote system for process info.");
+ add_packet_config_cmd (&remote_protocol_vcont,
+ "vCont", "verbose-resume",
+ set_remote_protocol_vcont_packet_cmd,
+ show_remote_protocol_vcont_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
add_packet_config_cmd (&remote_protocol_qSymbol,
"qSymbol", "symbol-lookup",
@@ -6101,7 +5610,7 @@ in a memory packet.\n",
0);
/* Disable by default. The ``e'' packet has nasty interactions with
the threading code - it relies on global state. */
- remote_protocol_e.detect = CMD_AUTO_BOOLEAN_FALSE;
+ remote_protocol_e.detect = AUTO_BOOLEAN_FALSE;
update_packet_config (&remote_protocol_e);
add_packet_config_cmd (&remote_protocol_E,
@@ -6112,7 +5621,7 @@ in a memory packet.\n",
0);
/* Disable by default. The ``e'' packet has nasty interactions with
the threading code - it relies on global state. */
- remote_protocol_E.detect = CMD_AUTO_BOOLEAN_FALSE;
+ remote_protocol_E.detect = AUTO_BOOLEAN_FALSE;
update_packet_config (&remote_protocol_E);
add_packet_config_cmd (&remote_protocol_P,
@@ -6157,13 +5666,22 @@ in a memory packet.\n",
&remote_set_cmdlist, &remote_show_cmdlist,
0);
+ add_packet_config_cmd (&remote_protocol_qPart_auxv,
+ "qPart_auxv", "read-aux-vector",
+ set_remote_protocol_qPart_auxv_packet_cmd,
+ show_remote_protocol_qPart_auxv_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
/* Keep the old ``set remote Z-packet ...'' working. */
- tmpcmd = add_set_auto_boolean_cmd ("Z-packet", class_obscure,
- &remote_Z_packet_detect,
- "\
-Set use of remote protocol `Z' packets", &remote_set_cmdlist);
- set_cmd_sfunc (tmpcmd, set_remote_protocol_Z_packet_cmd);
- add_cmd ("Z-packet", class_obscure, show_remote_protocol_Z_packet_cmd,
- "Show use of remote protocol `Z' packets ",
- &remote_show_cmdlist);
+ add_setshow_auto_boolean_cmd ("Z-packet", class_obscure,
+ &remote_Z_packet_detect, "\
+Set use of remote protocol `Z' packets",
+ "Show use of remote protocol `Z' packets ",
+ set_remote_protocol_Z_packet_cmd,
+ show_remote_protocol_Z_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist);
+
+ /* Eventually initialize fileio. See fileio.c */
+ initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist);
}
diff --git a/contrib/gdb/gdb/ser-unix.c b/contrib/gdb/gdb/ser-unix.c
index f7ab28a..38b6716 100644
--- a/contrib/gdb/gdb/ser-unix.c
+++ b/contrib/gdb/gdb/ser-unix.c
@@ -1,6 +1,7 @@
/* Serial interface for local (hardwired) serial ports on Un*x like systems
- Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
- Free Software Foundation, Inc.
+
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+ 2003, 2004 Free Software Foundation, Inc.
This file is part of GDB.
@@ -1324,7 +1325,7 @@ ser_unix_async (struct serial *scb,
case FD_SCHEDULED:
delete_file_handler (scb->fd);
break;
- NOTHING_SCHEDULED:
+ case NOTHING_SCHEDULED:
break;
default: /* TIMER SCHEDULED */
delete_timer (scb->async_state);
@@ -1337,7 +1338,7 @@ void
_initialize_ser_hardwire (void)
{
struct serial_ops *ops = XMALLOC (struct serial_ops);
- memset (ops, sizeof (struct serial_ops), 0);
+ memset (ops, 0, sizeof (struct serial_ops));
ops->name = "hardwire";
ops->next = 0;
ops->open = hardwire_open;
diff --git a/contrib/gdb/gdb/solib.c b/contrib/gdb/gdb/solib.c
index c47c438..a98c3bd 100644
--- a/contrib/gdb/gdb/solib.c
+++ b/contrib/gdb/gdb/solib.c
@@ -1,7 +1,7 @@
/* Handle shared libraries for GDB, the GNU Debugger.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001
- Free Software Foundation, Inc.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GDB.
@@ -40,8 +40,9 @@
#include "gdbcmd.h"
#include "completer.h"
#include "filenames.h" /* for DOSish file names */
-
+#include "exec.h"
#include "solist.h"
+#include "readline/readline.h"
/* external data declarations */
@@ -56,7 +57,7 @@ static int solib_cleanup_queued = 0; /* make_run_cleanup called */
/* Local function prototypes */
-static void do_clear_solib (PTR);
+static void do_clear_solib (void *);
/* If non-zero, this is a prefix that will be added to the front of the name
shared libraries with an absolute filename for loading. */
@@ -86,12 +87,19 @@ static char *solib_search_path = NULL;
(or set of directories, as in LD_LIBRARY_PATH) to search for all
shared libraries if not found in SOLIB_ABSOLUTE_PREFIX.
- Search order:
- * If path is absolute, look in SOLIB_ABSOLUTE_PREFIX.
- * If path is absolute or relative, look for it literally (unmodified).
+ Search algorithm:
+ * If there is a solib_absolute_prefix and path is absolute:
+ * Search for solib_absolute_prefix/path.
+ * else
+ * Look for it literally (unmodified).
* Look in SOLIB_SEARCH_PATH.
- * Look in inferior's $PATH.
- * Look in inferior's $LD_LIBRARY_PATH.
+ * If available, use target defined search function.
+ * If solib_absolute_prefix is NOT set, perform the following two searches:
+ * Look in inferior's $PATH.
+ * Look in inferior's $LD_LIBRARY_PATH.
+ *
+ * The last check avoids doing this search when targetting remote
+ * machines since solib_absolute_prefix will almost always be set.
RETURNS
@@ -146,7 +154,7 @@ solib_open (char *in_pathname, char **found_pathname)
in_pathname++;
}
- /* If not found, next search the solib_search_path (if any). */
+ /* If not found, search the solib_search_path (if any). */
if (found_file < 0 && solib_search_path != NULL)
found_file = openp (solib_search_path,
1, in_pathname, O_RDONLY, 0, &temp_pathname);
@@ -159,14 +167,19 @@ solib_open (char *in_pathname, char **found_pathname)
1, lbasename (in_pathname), O_RDONLY, 0,
&temp_pathname);
+ /* If not found, try to use target supplied solib search method */
+ if (found_file < 0 && TARGET_SO_FIND_AND_OPEN_SOLIB != NULL)
+ found_file = TARGET_SO_FIND_AND_OPEN_SOLIB
+ (in_pathname, O_RDONLY, &temp_pathname);
+
/* If not found, next search the inferior's $PATH environment variable. */
- if (found_file < 0 && solib_search_path != NULL)
+ if (found_file < 0 && solib_absolute_prefix == NULL)
found_file = openp (get_in_environ (inferior_environ, "PATH"),
1, in_pathname, O_RDONLY, 0, &temp_pathname);
/* If not found, next search the inferior's $LD_LIBRARY_PATH
environment variable. */
- if (found_file < 0 && solib_search_path != NULL)
+ if (found_file < 0 && solib_absolute_prefix == NULL)
found_file = openp (get_in_environ (inferior_environ, "LD_LIBRARY_PATH"),
1, in_pathname, O_RDONLY, 0, &temp_pathname);
@@ -206,7 +219,7 @@ solib_open (char *in_pathname, char **found_pathname)
*/
static int
-solib_map_sections (PTR arg)
+solib_map_sections (void *arg)
{
struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
char *filename;
@@ -237,7 +250,7 @@ solib_map_sections (PTR arg)
/* Leave bfd open, core_xfer_memory and "info files" need it. */
so->abfd = abfd;
- abfd->cacheable = 1;
+ bfd_set_cacheable (abfd, 1);
/* copy full path name into so_name, so that later symbol_file_add
can find it */
@@ -262,7 +275,7 @@ solib_map_sections (PTR arg)
object's file by the base address to which the object was actually
mapped. */
TARGET_SO_RELOCATE_SECTION_ADDRESSES (so, p);
- if (STREQ (p->the_bfd_section->name, ".text"))
+ if (strcmp (p->the_bfd_section->name, ".text") == 0)
{
so->textsection = p;
}
@@ -323,9 +336,9 @@ free_so (struct so_list *so)
/* A small stub to get us past the arg-passing pinhole of catch_errors. */
static int
-symbol_add_stub (PTR arg)
+symbol_add_stub (void *arg)
{
- register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
+ struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
struct section_addr_info *sap;
/* Have we already loaded this shared object? */
@@ -375,7 +388,7 @@ symbol_add_stub (PTR arg)
the section table. But we only use this for core files and
processes we've just attached to, so that's okay. */
-void
+static void
update_solib_list (int from_tty, struct target_ops *target)
{
struct so_list *inferior = TARGET_SO_CURRENT_SOS ();
@@ -386,7 +399,7 @@ update_solib_list (int from_tty, struct target_ops *target)
symbols now! */
if (attach_flag &&
symfile_objfile == NULL)
- catch_errors (TARGET_SO_OPEN_SYMBOL_FILE_OBJECT, (PTR) &from_tty,
+ catch_errors (TARGET_SO_OPEN_SYMBOL_FILE_OBJECT, &from_tty,
"Error reading attached process's symbol file.\n",
RETURN_MASK_ALL);
@@ -614,7 +627,7 @@ solib_add (char *pattern, int from_tty, struct target_ops *target, int readsyms)
static void
info_sharedlibrary_command (char *ignore, int from_tty)
{
- register struct so_list *so = NULL; /* link map state variable */
+ struct so_list *so = NULL; /* link map state variable */
int header_done = 0;
int addr_width;
char *addr_fmt;
@@ -652,13 +665,13 @@ info_sharedlibrary_command (char *ignore, int from_tty)
printf_unfiltered ("%-*s", addr_width,
so->textsection != NULL
- ? longest_local_hex_string_custom (
+ ? local_hex_string_custom (
(LONGEST) so->textsection->addr,
addr_fmt)
: "");
printf_unfiltered ("%-*s", addr_width,
so->textsection != NULL
- ? longest_local_hex_string_custom (
+ ? local_hex_string_custom (
(LONGEST) so->textsection->endaddr,
addr_fmt)
: "");
@@ -696,7 +709,7 @@ info_sharedlibrary_command (char *ignore, int from_tty)
char *
solib_address (CORE_ADDR address)
{
- register struct so_list *so = 0; /* link map state variable */
+ struct so_list *so = 0; /* link map state variable */
for (so = so_list_head; so; so = so->next)
{
@@ -754,7 +767,7 @@ clear_solib (void)
}
static void
-do_clear_solib (PTR dummy)
+do_clear_solib (void *dummy)
{
solib_cleanup_queued = 0;
clear_solib ();
@@ -843,6 +856,15 @@ no_shared_libraries (char *ignored, int from_tty)
do_clear_solib (NULL);
}
+static void
+reload_shared_libraries (char *ignored, int from_tty)
+{
+ no_shared_libraries (NULL, from_tty);
+ solib_add (NULL, from_tty, NULL, auto_solib_add);
+}
+
+extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
+
void
_initialize_solib (void)
{
@@ -872,7 +894,12 @@ inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
For other (relative) files, you can add values using `set solib-search-path'.",
&setlist);
add_show_from_set (c, &showlist);
- c->completer = filename_completer;
+ set_cmd_cfunc (c, reload_shared_libraries);
+ set_cmd_completer (c, filename_completer);
+
+ /* Set the default value of "solib-absolute-prefix" from the sysroot, if
+ one is set. */
+ solib_absolute_prefix = xstrdup (gdb_sysroot);
c = add_set_cmd ("solib-search-path", class_support, var_string,
(char *) &solib_search_path,
@@ -880,5 +907,6 @@ For other (relative) files, you can add values using `set solib-search-path'.",
This takes precedence over the environment variables PATH and LD_LIBRARY_PATH.",
&setlist);
add_show_from_set (c, &showlist);
- c->completer = filename_completer;
+ set_cmd_cfunc (c, reload_shared_libraries);
+ set_cmd_completer (c, filename_completer);
}
diff --git a/contrib/gdb/gdb/symfile.c b/contrib/gdb/gdb/symfile.c
index c3c18bf..19ae294 100644
--- a/contrib/gdb/gdb/symfile.c
+++ b/contrib/gdb/gdb/symfile.c
@@ -1,7 +1,7 @@
/* Generic symbol file reading for the GNU debugger, GDB.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
@@ -23,6 +23,7 @@
Boston, MA 02111-1307, USA. */
#include "defs.h"
+#include "bfdlink.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcore.h"
@@ -31,15 +32,22 @@
#include "value.h"
#include "symfile.h"
#include "objfiles.h"
+#include "source.h"
#include "gdbcmd.h"
#include "breakpoint.h"
#include "language.h"
#include "complaints.h"
#include "demangle.h"
#include "inferior.h" /* for write_pc */
+#include "filenames.h" /* for DOSish file names */
#include "gdb-stabs.h"
-#include "obstack.h"
+#include "gdb_obstack.h"
#include "completer.h"
+#include "bcache.h"
+#include "hashtab.h"
+#include "readline/readline.h"
+#include "gdb_assert.h"
+#include "block.h"
#include <sys/types.h>
#include <fcntl.h>
@@ -80,21 +88,6 @@ static void clear_symtab_users_cleanup (void *ignore);
/* Global variables owned by this file */
int readnow_symbol_files; /* Read full symbols immediately */
-struct complaint oldsyms_complaint =
-{
- "Replacing old symbols for `%s'", 0, 0
-};
-
-struct complaint empty_symtab_complaint =
-{
- "Empty symbol table found for `%s'", 0, 0
-};
-
-struct complaint unknown_option_complaint =
-{
- "Unknown option `%s' ignored", 0, 0
-};
-
/* External variables and functions referenced. */
extern void report_transfer_performance (unsigned long, time_t, time_t);
@@ -116,6 +109,8 @@ static void add_symbol_file_command (char *, int);
static void add_shared_symbol_files_command (char *, int);
+static void reread_separate_symbols (struct objfile *objfile);
+
static void cashier_psymtab (struct partial_symtab *);
bfd *symfile_bfd_open (char *);
@@ -160,6 +155,8 @@ static void set_ext_lang_command (char *args, int from_tty);
static void info_ext_lang_command (char *args, int from_tty);
+static char *find_separate_debug_file (struct objfile *objfile);
+
static void init_filename_language_table (void);
void _initialize_symfile (void);
@@ -202,66 +199,17 @@ int auto_solib_add = 1;
int auto_solib_limit;
-/* Since this function is called from within qsort, in an ANSI environment
- it must conform to the prototype for qsort, which specifies that the
- comparison function takes two "void *" pointers. */
-
-static int
-compare_symbols (const void *s1p, const void *s2p)
-{
- register struct symbol **s1, **s2;
-
- s1 = (struct symbol **) s1p;
- s2 = (struct symbol **) s2p;
- return (strcmp (SYMBOL_SOURCE_NAME (*s1), SYMBOL_SOURCE_NAME (*s2)));
-}
-
-/*
-
- LOCAL FUNCTION
-
- compare_psymbols -- compare two partial symbols by name
-
- DESCRIPTION
-
- Given pointers to pointers to two partial symbol table entries,
- compare them by name and return -N, 0, or +N (ala strcmp).
- Typically used by sorting routines like qsort().
-
- NOTES
-
- Does direct compare of first two characters before punting
- and passing to strcmp for longer compares. Note that the
- original version had a bug whereby two null strings or two
- identically named one character strings would return the
- comparison of memory following the null byte.
-
- */
+/* This compares two partial symbols by names, using strcmp_iw_ordered
+ for the comparison. */
static int
compare_psymbols (const void *s1p, const void *s2p)
{
- register struct partial_symbol **s1, **s2;
- register char *st1, *st2;
-
- s1 = (struct partial_symbol **) s1p;
- s2 = (struct partial_symbol **) s2p;
- st1 = SYMBOL_SOURCE_NAME (*s1);
- st2 = SYMBOL_SOURCE_NAME (*s2);
-
+ struct partial_symbol *const *s1 = s1p;
+ struct partial_symbol *const *s2 = s2p;
- if ((st1[0] - st2[0]) || !st1[0])
- {
- return (st1[0] - st2[0]);
- }
- else if ((st1[1] - st2[1]) || !st1[1])
- {
- return (st1[1] - st2[1]);
- }
- else
- {
- return (strcmp (st1, st2));
- }
+ return strcmp_iw_ordered (SYMBOL_NATURAL_NAME (*s1),
+ SYMBOL_NATURAL_NAME (*s2));
}
void
@@ -274,54 +222,22 @@ sort_pst_symbols (struct partial_symtab *pst)
compare_psymbols);
}
-/* Call sort_block_syms to sort alphabetically the symbols of one block. */
-
-void
-sort_block_syms (register struct block *b)
-{
- qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
- sizeof (struct symbol *), compare_symbols);
-}
-
-/* Call sort_symtab_syms to sort alphabetically
- the symbols of each block of one symtab. */
-
-void
-sort_symtab_syms (register struct symtab *s)
-{
- register struct blockvector *bv;
- int nbl;
- int i;
- register struct block *b;
-
- if (s == 0)
- return;
- bv = BLOCKVECTOR (s);
- nbl = BLOCKVECTOR_NBLOCKS (bv);
- for (i = 0; i < nbl; i++)
- {
- b = BLOCKVECTOR_BLOCK (bv, i);
- if (BLOCK_SHOULD_SORT (b))
- sort_block_syms (b);
- }
-}
-
/* Make a null terminated copy of the string at PTR with SIZE characters in
the obstack pointed to by OBSTACKP . Returns the address of the copy.
Note that the string at PTR does not have to be null terminated, I.E. it
may be part of a larger string and we are only saving a substring. */
char *
-obsavestring (char *ptr, int size, struct obstack *obstackp)
+obsavestring (const char *ptr, int size, struct obstack *obstackp)
{
- register char *p = (char *) obstack_alloc (obstackp, size + 1);
+ char *p = (char *) obstack_alloc (obstackp, size + 1);
/* Open-coded memcpy--saves function call time. These strings are usually
short. FIXME: Is this really still true with a compiler that can
inline memcpy? */
{
- register char *p1 = ptr;
- register char *p2 = p;
- char *end = ptr + size;
+ const char *p1 = ptr;
+ char *p2 = p;
+ const char *end = ptr + size;
while (p1 != end)
*p2++ = *p1++;
}
@@ -336,8 +252,8 @@ char *
obconcat (struct obstack *obstackp, const char *s1, const char *s2,
const char *s3)
{
- register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
- register char *val = (char *) obstack_alloc (obstackp, len);
+ int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
+ char *val = (char *) obstack_alloc (obstackp, len);
strcpy (val, s1);
strcat (val, s2);
strcat (val, s3);
@@ -360,7 +276,7 @@ decrement_reading_symtab (void *dummy)
case inline. */
struct symtab *
-psymtab_to_symtab (register struct partial_symtab *pst)
+psymtab_to_symtab (struct partial_symtab *pst)
{
/* If it's been looked up before, return it. */
if (pst->symtab)
@@ -378,41 +294,6 @@ psymtab_to_symtab (register struct partial_symtab *pst)
return pst->symtab;
}
-/* Initialize entry point information for this objfile. */
-
-void
-init_entry_point_info (struct objfile *objfile)
-{
- /* Save startup file's range of PC addresses to help blockframe.c
- decide where the bottom of the stack is. */
-
- if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
- {
- /* Executable file -- record its entry point so we'll recognize
- the startup file because it contains the entry point. */
- objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
- }
- else
- {
- /* Examination of non-executable.o files. Short-circuit this stuff. */
- objfile->ei.entry_point = INVALID_ENTRY_POINT;
- }
- objfile->ei.entry_file_lowpc = INVALID_ENTRY_LOWPC;
- objfile->ei.entry_file_highpc = INVALID_ENTRY_HIGHPC;
- objfile->ei.entry_func_lowpc = INVALID_ENTRY_LOWPC;
- objfile->ei.entry_func_highpc = INVALID_ENTRY_HIGHPC;
- objfile->ei.main_func_lowpc = INVALID_ENTRY_LOWPC;
- objfile->ei.main_func_highpc = INVALID_ENTRY_HIGHPC;
-}
-
-/* Get current entry point address. */
-
-CORE_ADDR
-entry_point_address (void)
-{
- return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
-}
-
/* Remember the lowest-addressed loadable section we've seen.
This function is called via bfd_map_over_sections.
@@ -423,7 +304,7 @@ entry_point_address (void)
lowest-addressed loadable section. */
void
-find_lowest_section (bfd *abfd, asection *sect, PTR obj)
+find_lowest_section (bfd *abfd, asection *sect, void *obj)
{
asection **lowest = (asection **) obj;
@@ -439,6 +320,22 @@ find_lowest_section (bfd *abfd, asection *sect, PTR obj)
*lowest = sect;
}
+/* Create a new section_addr_info, with room for NUM_SECTIONS. */
+
+struct section_addr_info *
+alloc_section_addr_info (size_t num_sections)
+{
+ struct section_addr_info *sap;
+ size_t size;
+
+ size = (sizeof (struct section_addr_info)
+ + sizeof (struct other_sections) * (num_sections - 1));
+ sap = (struct section_addr_info *) xmalloc (size);
+ memset (sap, 0, size);
+ sap->num_sections = num_sections;
+
+ return sap;
+}
/* Build (allocate and populate) a section_addr_info struct from
an existing section table. */
@@ -451,14 +348,13 @@ build_section_addr_info_from_section_table (const struct section_table *start,
const struct section_table *stp;
int oidx;
- sap = xmalloc (sizeof (struct section_addr_info));
- memset (sap, 0, sizeof (struct section_addr_info));
+ sap = alloc_section_addr_info (end - start);
for (stp = start, oidx = 0; stp != end; stp++)
{
if (bfd_get_section_flags (stp->bfd,
stp->the_bfd_section) & (SEC_ALLOC | SEC_LOAD)
- && oidx < MAX_SECTIONS)
+ && oidx < end - start)
{
sap->other[oidx].addr = stp->addr;
sap->other[oidx].name
@@ -479,50 +375,20 @@ free_section_addr_info (struct section_addr_info *sap)
{
int idx;
- for (idx = 0; idx < MAX_SECTIONS; idx++)
+ for (idx = 0; idx < sap->num_sections; idx++)
if (sap->other[idx].name)
xfree (sap->other[idx].name);
xfree (sap);
}
-/* Parse the user's idea of an offset for dynamic linking, into our idea
- of how to represent it for fast symbol reading. This is the default
- version of the sym_fns.sym_offsets function for symbol readers that
- don't need to do anything special. It allocates a section_offsets table
- for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */
-
-void
-default_symfile_offsets (struct objfile *objfile,
- struct section_addr_info *addrs)
+/* Initialize OBJFILE's sect_index_* members. */
+static void
+init_objfile_sect_indices (struct objfile *objfile)
{
+ asection *sect;
int i;
- asection *sect = NULL;
-
- objfile->num_sections = SECT_OFF_MAX;
- objfile->section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
- memset (objfile->section_offsets, 0, SIZEOF_SECTION_OFFSETS);
-
- /* Now calculate offsets for section that were specified by the
- caller. */
- for (i = 0; i < MAX_SECTIONS && addrs->other[i].name; i++)
- {
- struct other_sections *osp ;
-
- osp = &addrs->other[i] ;
- if (osp->addr == 0)
- continue;
-
- /* Record all sections in offsets */
- /* The section_offsets in the objfile are here filled in using
- the BFD index. */
- (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr;
- }
-
- /* Remember the bfd indexes for the .text, .data, .bss and
- .rodata sections. */
-
+
sect = bfd_get_section_by_name (objfile->obfd, ".text");
if (sect)
objfile->sect_index_text = sect->index;
@@ -569,13 +435,73 @@ default_symfile_offsets (struct objfile *objfile,
}
}
+
+/* Parse the user's idea of an offset for dynamic linking, into our idea
+ of how to represent it for fast symbol reading. This is the default
+ version of the sym_fns.sym_offsets function for symbol readers that
+ don't need to do anything special. It allocates a section_offsets table
+ for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */
+
+void
+default_symfile_offsets (struct objfile *objfile,
+ struct section_addr_info *addrs)
+{
+ int i;
+
+ objfile->num_sections = bfd_count_sections (objfile->obfd);
+ objfile->section_offsets = (struct section_offsets *)
+ obstack_alloc (&objfile->objfile_obstack,
+ SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
+ memset (objfile->section_offsets, 0,
+ SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
+
+ /* Now calculate offsets for section that were specified by the
+ caller. */
+ for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
+ {
+ struct other_sections *osp ;
+
+ osp = &addrs->other[i] ;
+ if (osp->addr == 0)
+ continue;
+
+ /* Record all sections in offsets */
+ /* The section_offsets in the objfile are here filled in using
+ the BFD index. */
+ (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr;
+ }
+
+ /* Remember the bfd indexes for the .text, .data, .bss and
+ .rodata sections. */
+ init_objfile_sect_indices (objfile);
+}
+
+
/* Process a symbol file, as either the main file or as a dynamically
loaded file.
OBJFILE is where the symbols are to be read from.
- ADDR is the address where the text segment was loaded, unless the
- objfile is the main symbol file, in which case it is zero.
+ ADDRS is the list of section load addresses. If the user has given
+ an 'add-symbol-file' command, then this is the list of offsets and
+ addresses he or she provided as arguments to the command; or, if
+ we're handling a shared library, these are the actual addresses the
+ sections are loaded at, according to the inferior's dynamic linker
+ (as gleaned by GDB's shared library code). We convert each address
+ into an offset from the section VMA's as it appears in the object
+ file, and then call the file's sym_offsets function to convert this
+ into a format-specific offset table --- a `struct section_offsets'.
+ If ADDRS is non-zero, OFFSETS must be zero.
+
+ OFFSETS is a table of section offsets already in the right
+ format-specific representation. NUM_OFFSETS is the number of
+ elements present in OFFSETS->offsets. If OFFSETS is non-zero, we
+ assume this is the proper table the call to sym_offsets described
+ above would produce. Instead of calling sym_offsets, we just dump
+ it right into objfile->section_offsets. (When we're re-reading
+ symbols from an objfile, we don't have the original load address
+ list any more; all we have is the section offset table.) If
+ OFFSETS is non-zero, ADDRS must be zero.
MAINLINE is nonzero if this is the main symbol file, or zero if
it's an extra symbol file such as dynamically loaded code.
@@ -584,33 +510,41 @@ default_symfile_offsets (struct objfile *objfile,
the symbol reading (and complaints can be more terse about it). */
void
-syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
- int mainline, int verbo)
-{
- asection *lower_sect;
- asection *sect;
- CORE_ADDR lower_offset;
- struct section_addr_info local_addr;
+syms_from_objfile (struct objfile *objfile,
+ struct section_addr_info *addrs,
+ struct section_offsets *offsets,
+ int num_offsets,
+ int mainline,
+ int verbo)
+{
+ struct section_addr_info *local_addr = NULL;
struct cleanup *old_chain;
- int i;
- /* If ADDRS is NULL, initialize the local section_addr_info struct and
- point ADDRS to it. We now establish the convention that an addr of
- zero means no load address was specified. */
-
- if (addrs == NULL)
- {
- memset (&local_addr, 0, sizeof (local_addr));
- addrs = &local_addr;
- }
+ gdb_assert (! (addrs && offsets));
init_entry_point_info (objfile);
find_sym_fns (objfile);
+ if (objfile->sf == NULL)
+ return; /* No symbols. */
+
/* Make sure that partially constructed symbol tables will be cleaned up
if an error occurs during symbol reading. */
old_chain = make_cleanup_free_objfile (objfile);
+ /* If ADDRS and OFFSETS are both NULL, put together a dummy address
+ list. We now establish the convention that an addr of zero means
+ no load address was specified. */
+ if (! addrs && ! offsets)
+ {
+ local_addr
+ = alloc_section_addr_info (bfd_count_sections (objfile->obfd));
+ make_cleanup (xfree, local_addr);
+ addrs = local_addr;
+ }
+
+ /* Now either addrs or offsets is non-zero. */
+
if (mainline)
{
/* We will modify the main symbol table, make sure that all its users
@@ -639,15 +573,20 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
We no longer warn if the lowest section is not a text segment (as
happens for the PA64 port. */
- if (!mainline)
+ if (!mainline && addrs && addrs->other[0].name)
{
+ asection *lower_sect;
+ asection *sect;
+ CORE_ADDR lower_offset;
+ int i;
+
/* Find lowest loadable section to be used as starting point for
continguous sections. FIXME!! won't work without call to find
.text first, but this assumes text is lowest section. */
lower_sect = bfd_get_section_by_name (objfile->obfd, ".text");
if (lower_sect == NULL)
bfd_map_over_sections (objfile->obfd, find_lowest_section,
- (PTR) &lower_sect);
+ &lower_sect);
if (lower_sect == NULL)
warning ("no loadable sections found in added symbol-file %s",
objfile->name);
@@ -662,39 +601,41 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
else
lower_offset = 0;
- /* Calculate offsets for the loadable sections.
+ /* Calculate offsets for the loadable sections.
FIXME! Sections must be in order of increasing loadable section
so that contiguous sections can use the lower-offset!!!
- Adjust offsets if the segments are not contiguous.
- If the section is contiguous, its offset should be set to
+ Adjust offsets if the segments are not contiguous.
+ If the section is contiguous, its offset should be set to
the offset of the highest loadable section lower than it
(the loadable section directly below it in memory).
this_offset = lower_offset = lower_addr - lower_orig_addr */
- /* Calculate offsets for sections. */
- for (i=0 ; i < MAX_SECTIONS && addrs->other[i].name; i++)
- {
- if (addrs->other[i].addr != 0)
- {
- sect = bfd_get_section_by_name (objfile->obfd, addrs->other[i].name);
- if (sect)
- {
- addrs->other[i].addr -= bfd_section_vma (objfile->obfd, sect);
- lower_offset = addrs->other[i].addr;
- /* This is the index used by BFD. */
- addrs->other[i].sectindex = sect->index ;
- }
- else
- {
- warning ("section %s not found in %s", addrs->other[i].name,
- objfile->name);
- addrs->other[i].addr = 0;
- }
- }
- else
- addrs->other[i].addr = lower_offset;
- }
+ for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
+ {
+ if (addrs->other[i].addr != 0)
+ {
+ sect = bfd_get_section_by_name (objfile->obfd,
+ addrs->other[i].name);
+ if (sect)
+ {
+ addrs->other[i].addr
+ -= bfd_section_vma (objfile->obfd, sect);
+ lower_offset = addrs->other[i].addr;
+ /* This is the index used by BFD. */
+ addrs->other[i].sectindex = sect->index ;
+ }
+ else
+ {
+ warning ("section %s not found in %s",
+ addrs->other[i].name,
+ objfile->name);
+ addrs->other[i].addr = 0;
+ }
+ }
+ else
+ addrs->other[i].addr = lower_offset;
+ }
}
/* Initialize symbol reading routines for this objfile, allow complaints to
@@ -702,11 +643,25 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
initial symbol reading for this file. */
(*objfile->sf->sym_init) (objfile);
- clear_complaints (1, verbo);
+ clear_complaints (&symfile_complaints, 1, verbo);
+
+ if (addrs)
+ (*objfile->sf->sym_offsets) (objfile, addrs);
+ else
+ {
+ size_t size = SIZEOF_N_SECTION_OFFSETS (num_offsets);
- (*objfile->sf->sym_offsets) (objfile, addrs);
+ /* Just copy in the offset table directly as given to us. */
+ objfile->num_sections = num_offsets;
+ objfile->section_offsets
+ = ((struct section_offsets *)
+ obstack_alloc (&objfile->objfile_obstack, size));
+ memcpy (objfile->section_offsets, offsets, size);
-#ifndef IBM6000_TARGET
+ init_objfile_sect_indices (objfile);
+ }
+
+#ifndef DEPRECATED_IBM6000_TARGET
/* This is a SVR4/SunOS specific hack, I think. In any event, it
screws RS/6000. sym_offsets should be doing this sort of thing,
because it knows the mapping between bfd sections and
@@ -740,7 +695,7 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
int i;
for (i = 0;
- !s_addr && i < MAX_SECTIONS && addrs->other[i].name;
+ !s_addr && i < addrs->num_sections && addrs->other[i].name;
i++)
if (strcmp (bfd_section_name (s->objfile->obfd,
s->the_bfd_section),
@@ -754,17 +709,10 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
s->offset += s_addr;
}
}
-#endif /* not IBM6000_TARGET */
+#endif /* not DEPRECATED_IBM6000_TARGET */
(*objfile->sf->sym_read) (objfile, mainline);
- if (!have_partial_symbols () && !have_full_symbols ())
- {
- wrap_here ("");
- printf_filtered ("(no debugging symbols found)...");
- wrap_here ("");
- }
-
/* Don't allow char * to have a typename (else would get caddr_t).
Ditto void *. FIXME: Check whether this is now done by all the
symbol readers themselves (many of them now do), and if so remove
@@ -781,13 +729,6 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
/* Discard cleanups as symbol reading was successful. */
discard_cleanups (old_chain);
-
- /* Call this after reading in a new symbol table to give target
- dependent code a crack at the new symbols. For instance, this
- could be used to update the values of target-specific symbols GDB
- needs to keep track of (such as _sigtramp, or whatever). */
-
- TARGET_SYMFILE_POSTREAD (objfile);
}
/* Perform required actions after either reading in the initial
@@ -814,7 +755,7 @@ new_symfile_objfile (struct objfile *objfile, int mainline, int verbo)
}
/* We're done reading the symbol file; finish off complaints. */
- clear_complaints (0, verbo);
+ clear_complaints (&symfile_complaints, 0, verbo);
}
/* Process a symbol file, as either the main file or as a dynamically
@@ -822,21 +763,31 @@ new_symfile_objfile (struct objfile *objfile, int mainline, int verbo)
NAME is the file name (which will be tilde-expanded and made
absolute herein) (but we don't free or modify NAME itself).
- FROM_TTY says how verbose to be. MAINLINE specifies whether this
- is the main symbol file, or whether it's an extra symbol file such
- as dynamically loaded code. If !mainline, ADDR is the address
- where the text segment was loaded.
+
+ FROM_TTY says how verbose to be.
+
+ MAINLINE specifies whether this is the main symbol file, or whether
+ it's an extra symbol file such as dynamically loaded code.
+
+ ADDRS, OFFSETS, and NUM_OFFSETS are as described for
+ syms_from_objfile, above. ADDRS is ignored when MAINLINE is
+ non-zero.
Upon success, returns a pointer to the objfile that was added.
Upon failure, jumps back to command level (never returns). */
-
-struct objfile *
-symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
- int mainline, int flags)
+static struct objfile *
+symbol_file_add_with_addrs_or_offsets (char *name, int from_tty,
+ struct section_addr_info *addrs,
+ struct section_offsets *offsets,
+ int num_offsets,
+ int mainline, int flags)
{
struct objfile *objfile;
struct partial_symtab *psymtab;
+ char *debugfile;
bfd *abfd;
+ struct section_addr_info *orig_addrs;
+ struct cleanup *my_cleanups;
/* Open a bfd for the file, and give user a chance to burp if we'd be
interactively wiping out any existing symbols. */
@@ -851,42 +802,32 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
objfile = allocate_objfile (abfd, flags);
- /* If the objfile uses a mapped symbol file, and we have a psymtab for
- it, then skip reading any symbols at this time. */
+ orig_addrs = alloc_section_addr_info (bfd_count_sections (abfd));
+ my_cleanups = make_cleanup (xfree, orig_addrs);
+ if (addrs)
+ {
+ int i;
+ orig_addrs->num_sections = addrs->num_sections;
+ for (i = 0; i < addrs->num_sections; i++)
+ orig_addrs->other[i] = addrs->other[i];
+ }
- if ((objfile->flags & OBJF_MAPPED) && (objfile->flags & OBJF_SYMS))
+ /* We either created a new mapped symbol table, mapped an existing
+ symbol table file which has not had initial symbol reading
+ performed, or need to read an unmapped symbol table. */
+ if (from_tty || info_verbose)
{
- /* We mapped in an existing symbol table file that already has had
- initial symbol reading performed, so we can skip that part. Notify
- the user that instead of reading the symbols, they have been mapped.
- */
- if (from_tty || info_verbose)
+ if (pre_add_symbol_hook)
+ pre_add_symbol_hook (name);
+ else
{
- printf_filtered ("Mapped symbols for %s...", name);
+ printf_unfiltered ("Reading symbols from %s...", name);
wrap_here ("");
gdb_flush (gdb_stdout);
}
- init_entry_point_info (objfile);
- find_sym_fns (objfile);
- }
- else
- {
- /* We either created a new mapped symbol table, mapped an existing
- symbol table file which has not had initial symbol reading
- performed, or need to read an unmapped symbol table. */
- if (from_tty || info_verbose)
- {
- if (pre_add_symbol_hook)
- pre_add_symbol_hook (name);
- else
- {
- printf_filtered ("Reading symbols from %s...", name);
- wrap_here ("");
- gdb_flush (gdb_stdout);
- }
- }
- syms_from_objfile (objfile, addrs, mainline, from_tty);
}
+ syms_from_objfile (objfile, addrs, offsets, num_offsets,
+ mainline, from_tty);
/* We now have at least a partial symbol table. Check to see if the
user requested that all symbols be read on initial access via either
@@ -897,7 +838,7 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
{
if (from_tty || info_verbose)
{
- printf_filtered ("expanding to full symbols...");
+ printf_unfiltered ("expanding to full symbols...");
wrap_here ("");
gdb_flush (gdb_stdout);
}
@@ -910,17 +851,56 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
}
}
+ debugfile = find_separate_debug_file (objfile);
+ if (debugfile)
+ {
+ if (addrs != NULL)
+ {
+ objfile->separate_debug_objfile
+ = symbol_file_add (debugfile, from_tty, orig_addrs, 0, flags);
+ }
+ else
+ {
+ objfile->separate_debug_objfile
+ = symbol_file_add (debugfile, from_tty, NULL, 0, flags);
+ }
+ objfile->separate_debug_objfile->separate_debug_objfile_backlink
+ = objfile;
+
+ /* Put the separate debug object before the normal one, this is so that
+ usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+ put_objfile_before (objfile->separate_debug_objfile, objfile);
+
+ xfree (debugfile);
+ }
+
+ if (!have_partial_symbols () && !have_full_symbols ())
+ {
+ wrap_here ("");
+ printf_unfiltered ("(no debugging symbols found)...");
+ wrap_here ("");
+ }
+
if (from_tty || info_verbose)
{
if (post_add_symbol_hook)
post_add_symbol_hook ();
else
{
- printf_filtered ("done.\n");
- gdb_flush (gdb_stdout);
+ printf_unfiltered ("done.\n");
}
}
+ /* We print some messages regardless of whether 'from_tty ||
+ info_verbose' is true, so make sure they go out at the right
+ time. */
+ gdb_flush (gdb_stdout);
+
+ do_cleanups (my_cleanups);
+
+ if (objfile->sf == NULL)
+ return objfile; /* No symbols. */
+
new_symfile_objfile (objfile, mainline, from_tty);
if (target_new_objfile_hook)
@@ -929,6 +909,19 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
return (objfile);
}
+
+/* Process a symbol file, as either the main file or as a dynamically
+ loaded file. See symbol_file_add_with_addrs_or_offsets's comments
+ for details. */
+struct objfile *
+symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
+ int mainline, int flags)
+{
+ return symbol_file_add_with_addrs_or_offsets (name, from_tty, addrs, 0, 0,
+ mainline, flags);
+}
+
+
/* Call symbol_file_add() with default values and update whatever is
affected by the loading of a new main().
Used when the file is supplied in the gdb command line
@@ -985,6 +978,144 @@ symbol_file_clear (int from_tty)
#endif
}
+static char *
+get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
+{
+ asection *sect;
+ bfd_size_type debuglink_size;
+ unsigned long crc32;
+ char *contents;
+ int crc_offset;
+ unsigned char *p;
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
+
+ if (sect == NULL)
+ return NULL;
+
+ debuglink_size = bfd_section_size (objfile->obfd, sect);
+
+ contents = xmalloc (debuglink_size);
+ bfd_get_section_contents (objfile->obfd, sect, contents,
+ (file_ptr)0, (bfd_size_type)debuglink_size);
+
+ /* Crc value is stored after the filename, aligned up to 4 bytes. */
+ crc_offset = strlen (contents) + 1;
+ crc_offset = (crc_offset + 3) & ~3;
+
+ crc32 = bfd_get_32 (objfile->obfd, (bfd_byte *) (contents + crc_offset));
+
+ *crc32_out = crc32;
+ return contents;
+}
+
+static int
+separate_debug_file_exists (const char *name, unsigned long crc)
+{
+ unsigned long file_crc = 0;
+ int fd;
+ char buffer[8*1024];
+ int count;
+
+ fd = open (name, O_RDONLY | O_BINARY);
+ if (fd < 0)
+ return 0;
+
+ while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+ file_crc = gnu_debuglink_crc32 (file_crc, buffer, count);
+
+ close (fd);
+
+ return crc == file_crc;
+}
+
+static char *debug_file_directory = NULL;
+
+#if ! defined (DEBUG_SUBDIRECTORY)
+#define DEBUG_SUBDIRECTORY ".debug"
+#endif
+
+static char *
+find_separate_debug_file (struct objfile *objfile)
+{
+ asection *sect;
+ char *basename;
+ char *dir;
+ char *debugfile;
+ char *name_copy;
+ bfd_size_type debuglink_size;
+ unsigned long crc32;
+ int i;
+
+ basename = get_debug_link_info (objfile, &crc32);
+
+ if (basename == NULL)
+ return NULL;
+
+ dir = xstrdup (objfile->name);
+
+ /* Strip off the final filename part, leaving the directory name,
+ followed by a slash. Objfile names should always be absolute and
+ tilde-expanded, so there should always be a slash in there
+ somewhere. */
+ for (i = strlen(dir) - 1; i >= 0; i--)
+ {
+ if (IS_DIR_SEPARATOR (dir[i]))
+ break;
+ }
+ gdb_assert (i >= 0 && IS_DIR_SEPARATOR (dir[i]));
+ dir[i+1] = '\0';
+
+ debugfile = alloca (strlen (debug_file_directory) + 1
+ + strlen (dir)
+ + strlen (DEBUG_SUBDIRECTORY)
+ + strlen ("/")
+ + strlen (basename)
+ + 1);
+
+ /* First try in the same directory as the original file. */
+ strcpy (debugfile, dir);
+ strcat (debugfile, basename);
+
+ if (separate_debug_file_exists (debugfile, crc32))
+ {
+ xfree (basename);
+ xfree (dir);
+ return xstrdup (debugfile);
+ }
+
+ /* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */
+ strcpy (debugfile, dir);
+ strcat (debugfile, DEBUG_SUBDIRECTORY);
+ strcat (debugfile, "/");
+ strcat (debugfile, basename);
+
+ if (separate_debug_file_exists (debugfile, crc32))
+ {
+ xfree (basename);
+ xfree (dir);
+ return xstrdup (debugfile);
+ }
+
+ /* Then try in the global debugfile directory. */
+ strcpy (debugfile, debug_file_directory);
+ strcat (debugfile, "/");
+ strcat (debugfile, dir);
+ strcat (debugfile, basename);
+
+ if (separate_debug_file_exists (debugfile, crc32))
+ {
+ xfree (basename);
+ xfree (dir);
+ return xstrdup (debugfile);
+ }
+
+ xfree (basename);
+ xfree (dir);
+ return NULL;
+}
+
+
/* This is the symbol-file command. Read the file, analyze its
symbols, and add a struct symtab to a symtab list. The syntax of
the command is rather bizarre--(1) buildargv implements various
@@ -1022,20 +1153,16 @@ symbol_file_command (char *args, int from_tty)
cleanups = make_cleanup_freeargv (argv);
while (*argv != NULL)
{
- if (STREQ (*argv, "-mapped"))
- flags |= OBJF_MAPPED;
- else
- if (STREQ (*argv, "-readnow"))
- flags |= OBJF_READNOW;
- else
- if (**argv == '-')
- error ("unknown option `%s'", *argv);
- else
- {
- name = *argv;
-
- symbol_file_add_main_1 (name, from_tty, flags);
- }
+ if (strcmp (*argv, "-readnow") == 0)
+ flags |= OBJF_READNOW;
+ else if (**argv == '-')
+ error ("unknown option `%s'", *argv);
+ else
+ {
+ name = *argv;
+
+ symbol_file_add_main_1 (name, from_tty, flags);
+ }
argv++;
}
@@ -1124,7 +1251,7 @@ symfile_bfd_open (char *name)
error ("\"%s\": can't open to read symbols: %s.", name,
bfd_errmsg (bfd_get_error ()));
}
- sym_bfd->cacheable = 1;
+ bfd_set_cacheable (sym_bfd, 1);
if (!bfd_check_format (sym_bfd, bfd_object))
{
@@ -1176,9 +1303,10 @@ find_sym_fns (struct objfile *objfile)
enum bfd_flavour our_flavour = bfd_get_flavour (objfile->obfd);
char *our_target = bfd_get_target (objfile->obfd);
- /* Special kludge for apollo. See dstread.c. */
- if (STREQN (our_target, "apollo", 6))
- our_flavour = (enum bfd_flavour) -2;
+ if (our_flavour == bfd_target_srec_flavour
+ || our_flavour == bfd_target_ihex_flavour
+ || our_flavour == bfd_target_tekhex_flavour)
+ return; /* No symbols. */
for (sf = symtab_fns; sf != NULL; sf = sf->next)
{
@@ -1402,11 +1530,11 @@ generic_load (char *args, int from_tty)
for other targets too. */
write_pc (entry);
- /* FIXME: are we supposed to call symbol_file_add or not? According to
- a comment from remote-mips.c (where a call to symbol_file_add was
- commented out), making the call confuses GDB if more than one file is
- loaded in. remote-nindy.c had no call to symbol_file_add, but remote-vx.c
- does. */
+ /* FIXME: are we supposed to call symbol_file_add or not? According
+ to a comment from remote-mips.c (where a call to symbol_file_add
+ was commented out), making the call confuses GDB if more than one
+ file is loaded in. Some targets do (e.g., remote-vx.c) but
+ others don't (or didn't - perhaphs they have all been deleted). */
print_transfer_performance (gdb_stdout, cbdata.data_count,
cbdata.write_count, end_time - start_time);
@@ -1464,7 +1592,6 @@ print_transfer_performance (struct ui_file *stream,
instead a call to target_link() (in target.c) would supply the
value to use. We are now discontinuing this type of ad hoc syntax. */
-/* ARGSUSED */
static void
add_symbol_file_command (char *args, int from_tty)
{
@@ -1479,15 +1606,21 @@ add_symbol_file_command (char *args, int from_tty)
int expecting_sec_name = 0;
int expecting_sec_addr = 0;
- struct
+ struct sect_opt
{
char *name;
char *value;
- } sect_opts[SECT_OFF_MAX];
+ };
- struct section_addr_info section_addrs;
+ struct section_addr_info *section_addrs;
+ struct sect_opt *sect_opts = NULL;
+ size_t num_sect_opts = 0;
struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL);
+ num_sect_opts = 16;
+ sect_opts = (struct sect_opt *) xmalloc (num_sect_opts
+ * sizeof (struct sect_opt));
+
dont_repeat ();
if (args == NULL)
@@ -1496,9 +1629,6 @@ add_symbol_file_command (char *args, int from_tty)
/* Make a copy of the string that we can safely write into. */
args = xstrdup (args);
- /* Ensure section_addrs is initialized */
- memset (&section_addrs, 0, sizeof (section_addrs));
-
while (*args != '\000')
{
/* Any leading spaces? */
@@ -1531,7 +1661,14 @@ add_symbol_file_command (char *args, int from_tty)
to load the program. */
sect_opts[section_index].name = ".text";
sect_opts[section_index].value = arg;
- section_index++;
+ if (++section_index > num_sect_opts)
+ {
+ num_sect_opts *= 2;
+ sect_opts = ((struct sect_opt *)
+ xrealloc (sect_opts,
+ num_sect_opts
+ * sizeof (struct sect_opt)));
+ }
}
else
{
@@ -1540,19 +1677,13 @@ add_symbol_file_command (char *args, int from_tty)
if (*arg == '-')
{
- if (strcmp (arg, "-mapped") == 0)
- flags |= OBJF_MAPPED;
- else
- if (strcmp (arg, "-readnow") == 0)
- flags |= OBJF_READNOW;
- else
- if (strcmp (arg, "-s") == 0)
- {
- if (section_index >= SECT_OFF_MAX)
- error ("Too many sections specified.");
- expecting_sec_name = 1;
- expecting_sec_addr = 1;
- }
+ if (strcmp (arg, "-readnow") == 0)
+ flags |= OBJF_READNOW;
+ else if (strcmp (arg, "-s") == 0)
+ {
+ expecting_sec_name = 1;
+ expecting_sec_addr = 1;
+ }
}
else
{
@@ -1566,7 +1697,14 @@ add_symbol_file_command (char *args, int from_tty)
{
sect_opts[section_index].value = arg;
expecting_sec_addr = 0;
- section_index++;
+ if (++section_index > num_sect_opts)
+ {
+ num_sect_opts *= 2;
+ sect_opts = ((struct sect_opt *)
+ xrealloc (sect_opts,
+ num_sect_opts
+ * sizeof (struct sect_opt)));
+ }
}
else
error ("USAGE: add-symbol-file <filename> <textaddress> [-mapped] [-readnow] [-s <secname> <addr>]*");
@@ -1581,24 +1719,22 @@ add_symbol_file_command (char *args, int from_tty)
statements because local_hex_string returns a local static
string. */
- printf_filtered ("add symbol table from file \"%s\" at\n", filename);
+ printf_unfiltered ("add symbol table from file \"%s\" at\n", filename);
+ section_addrs = alloc_section_addr_info (section_index);
+ make_cleanup (xfree, section_addrs);
for (i = 0; i < section_index; i++)
{
CORE_ADDR addr;
char *val = sect_opts[i].value;
char *sec = sect_opts[i].name;
- val = sect_opts[i].value;
- if (val[0] == '0' && val[1] == 'x')
- addr = strtoul (val+2, NULL, 16);
- else
- addr = strtoul (val, NULL, 10);
+ addr = parse_and_eval_address (val);
/* Here we store the section offsets in the order they were
entered on the command line. */
- section_addrs.other[sec_num].name = sec;
- section_addrs.other[sec_num].addr = addr;
- printf_filtered ("\t%s_addr = %s\n",
+ section_addrs->other[sec_num].name = sec;
+ section_addrs->other[sec_num].addr = addr;
+ printf_unfiltered ("\t%s_addr = %s\n",
sec,
local_hex_string ((unsigned long)addr));
sec_num++;
@@ -1613,7 +1749,7 @@ add_symbol_file_command (char *args, int from_tty)
if (from_tty && (!query ("%s", "")))
error ("Not confirmed.");
- symbol_file_add (filename, from_tty, &section_addrs, 0, flags);
+ symbol_file_add (filename, from_tty, section_addrs, 0, flags);
/* Getting new symbols may change our opinion about what is
frameless. */
@@ -1651,7 +1787,7 @@ reread_symbols (void)
{
if (objfile->obfd)
{
-#ifdef IBM6000_TARGET
+#ifdef DEPRECATED_IBM6000_TARGET
/* If this object is from a shared library, then you should
stat on the library name, not member name. */
@@ -1663,7 +1799,7 @@ reread_symbols (void)
if (res != 0)
{
/* FIXME, should use print_sys_errmsg but it's not filtered. */
- printf_filtered ("`%s' has disappeared; keeping its symbols.\n",
+ printf_unfiltered ("`%s' has disappeared; keeping its symbols.\n",
objfile->name);
continue;
}
@@ -1675,7 +1811,7 @@ reread_symbols (void)
int num_offsets;
char *obfd_filename;
- printf_filtered ("`%s' has changed; re-reading symbols.\n",
+ printf_unfiltered ("`%s' has changed; re-reading symbols.\n",
objfile->name);
/* There are various functions like symbol_file_add,
@@ -1708,10 +1844,12 @@ reread_symbols (void)
bfd_errmsg (bfd_get_error ()));
/* Save the offsets, we will nuke them with the rest of the
- psymbol_obstack. */
+ objfile_obstack. */
num_offsets = objfile->num_sections;
- offsets = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
- memcpy (offsets, objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
+ offsets = ((struct section_offsets *)
+ alloca (SIZEOF_N_SECTION_OFFSETS (num_offsets)));
+ memcpy (offsets, objfile->section_offsets,
+ SIZEOF_N_SECTION_OFFSETS (num_offsets));
/* Nuke all the state that we will re-read. Much of the following
code which sets things to NULL really is necessary to tell
@@ -1729,21 +1867,30 @@ reread_symbols (void)
sizeof (objfile->static_psymbols));
/* Free the obstacks for non-reusable objfiles */
- free_bcache (&objfile->psymbol_cache);
- obstack_free (&objfile->psymbol_obstack, 0);
- obstack_free (&objfile->symbol_obstack, 0);
- obstack_free (&objfile->type_obstack, 0);
+ bcache_xfree (objfile->psymbol_cache);
+ objfile->psymbol_cache = bcache_xmalloc ();
+ bcache_xfree (objfile->macro_cache);
+ objfile->macro_cache = bcache_xmalloc ();
+ if (objfile->demangled_names_hash != NULL)
+ {
+ htab_delete (objfile->demangled_names_hash);
+ objfile->demangled_names_hash = NULL;
+ }
+ obstack_free (&objfile->objfile_obstack, 0);
objfile->sections = NULL;
objfile->symtabs = NULL;
objfile->psymtabs = NULL;
objfile->free_psymtabs = NULL;
+ objfile->cp_namespace_symtab = NULL;
objfile->msymbols = NULL;
+ objfile->sym_private = NULL;
objfile->minimal_symbol_count = 0;
memset (&objfile->msymbol_hash, 0,
sizeof (objfile->msymbol_hash));
memset (&objfile->msymbol_demangled_hash, 0,
sizeof (objfile->msymbol_demangled_hash));
objfile->fundamental_types = NULL;
+ clear_objfile_data (objfile);
if (objfile->sf != NULL)
{
(*objfile->sf->sym_finish) (objfile);
@@ -1751,27 +1898,27 @@ reread_symbols (void)
/* We never make this a mapped file. */
objfile->md = NULL;
- /* obstack_specify_allocation also initializes the obstack so
- it is empty. */
- obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0,
- xmalloc, xfree);
- obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0,
- xmalloc, xfree);
- obstack_specify_allocation (&objfile->symbol_obstack, 0, 0,
- xmalloc, xfree);
- obstack_specify_allocation (&objfile->type_obstack, 0, 0,
- xmalloc, xfree);
+ objfile->psymbol_cache = bcache_xmalloc ();
+ objfile->macro_cache = bcache_xmalloc ();
+ /* obstack_init also initializes the obstack so it is
+ empty. We could use obstack_specify_allocation but
+ gdb_obstack.h specifies the alloc/dealloc
+ functions. */
+ obstack_init (&objfile->objfile_obstack);
if (build_objfile_section_table (objfile))
{
error ("Can't find the file sections in `%s': %s",
objfile->name, bfd_errmsg (bfd_get_error ()));
}
+ terminate_minimal_symbol_table (objfile);
/* We use the same section offsets as from last time. I'm not
sure whether that is always correct for shared libraries. */
objfile->section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
- memcpy (objfile->section_offsets, offsets, SIZEOF_SECTION_OFFSETS);
+ obstack_alloc (&objfile->objfile_obstack,
+ SIZEOF_N_SECTION_OFFSETS (num_offsets));
+ memcpy (objfile->section_offsets, offsets,
+ SIZEOF_N_SECTION_OFFSETS (num_offsets));
objfile->num_sections = num_offsets;
/* What the hell is sym_new_init for, anyway? The concept of
@@ -1786,7 +1933,7 @@ reread_symbols (void)
}
(*objfile->sf->sym_init) (objfile);
- clear_complaints (1, 1);
+ clear_complaints (&symfile_complaints, 1, 1);
/* The "mainline" parameter is a hideous hack; I think leaving it
zero is OK since dbxread.c also does what it needs to do if
objfile->global_psymbols.size is 0. */
@@ -1794,13 +1941,13 @@ reread_symbols (void)
if (!have_partial_symbols () && !have_full_symbols ())
{
wrap_here ("");
- printf_filtered ("(no debugging symbols found)\n");
+ printf_unfiltered ("(no debugging symbols found)\n");
wrap_here ("");
}
objfile->flags |= OBJF_SYMS;
/* We're done reading the symbol file; finish off complaints. */
- clear_complaints (0, 1);
+ clear_complaints (&symfile_complaints, 0, 1);
/* Getting new symbols may change our opinion about what is
frameless. */
@@ -1815,13 +1962,7 @@ reread_symbols (void)
again now. */
objfile->mtime = new_modtime;
reread_one = 1;
-
- /* Call this after reading in a new symbol table to give target
- dependent code a crack at the new symbols. For instance, this
- could be used to update the values of target-specific symbols GDB
- needs to keep track of (such as _sigtramp, or whatever). */
-
- TARGET_SYMFILE_POSTREAD (objfile);
+ reread_separate_symbols (objfile);
}
}
}
@@ -1829,6 +1970,72 @@ reread_symbols (void)
if (reread_one)
clear_symtab_users ();
}
+
+
+/* Handle separate debug info for OBJFILE, which has just been
+ re-read:
+ - If we had separate debug info before, but now we don't, get rid
+ of the separated objfile.
+ - If we didn't have separated debug info before, but now we do,
+ read in the new separated debug info file.
+ - If the debug link points to a different file, toss the old one
+ and read the new one.
+ This function does *not* handle the case where objfile is still
+ using the same separate debug info file, but that file's timestamp
+ has changed. That case should be handled by the loop in
+ reread_symbols already. */
+static void
+reread_separate_symbols (struct objfile *objfile)
+{
+ char *debug_file;
+ unsigned long crc32;
+
+ /* Does the updated objfile's debug info live in a
+ separate file? */
+ debug_file = find_separate_debug_file (objfile);
+
+ if (objfile->separate_debug_objfile)
+ {
+ /* There are two cases where we need to get rid of
+ the old separated debug info objfile:
+ - if the new primary objfile doesn't have
+ separated debug info, or
+ - if the new primary objfile has separate debug
+ info, but it's under a different filename.
+
+ If the old and new objfiles both have separate
+ debug info, under the same filename, then we're
+ okay --- if the separated file's contents have
+ changed, we will have caught that when we
+ visited it in this function's outermost
+ loop. */
+ if (! debug_file
+ || strcmp (debug_file, objfile->separate_debug_objfile->name) != 0)
+ free_objfile (objfile->separate_debug_objfile);
+ }
+
+ /* If the new objfile has separate debug info, and we
+ haven't loaded it already, do so now. */
+ if (debug_file
+ && ! objfile->separate_debug_objfile)
+ {
+ /* Use the same section offset table as objfile itself.
+ Preserve the flags from objfile that make sense. */
+ objfile->separate_debug_objfile
+ = (symbol_file_add_with_addrs_or_offsets
+ (debug_file,
+ info_verbose, /* from_tty: Don't override the default. */
+ 0, /* No addr table. */
+ objfile->section_offsets, objfile->num_sections,
+ 0, /* Not mainline. See comments about this above. */
+ objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
+ | OBJF_USERLOADED)));
+ objfile->separate_debug_objfile->separate_debug_objfile_backlink
+ = objfile;
+ }
+}
+
+
@@ -1948,9 +2155,7 @@ init_filename_language_table (void)
add_filename_language (".c++", language_cplus);
add_filename_language (".java", language_java);
add_filename_language (".class", language_java);
- add_filename_language (".ch", language_chill);
- add_filename_language (".c186", language_chill);
- add_filename_language (".c286", language_chill);
+ add_filename_language (".m", language_objc);
add_filename_language (".f", language_fortran);
add_filename_language (".F", language_fortran);
add_filename_language (".s", language_asm);
@@ -1993,17 +2198,17 @@ deduce_language_from_filename (char *filename)
struct symtab *
allocate_symtab (char *filename, struct objfile *objfile)
{
- register struct symtab *symtab;
+ struct symtab *symtab;
symtab = (struct symtab *)
- obstack_alloc (&objfile->symbol_obstack, sizeof (struct symtab));
+ obstack_alloc (&objfile->objfile_obstack, sizeof (struct symtab));
memset (symtab, 0, sizeof (*symtab));
symtab->filename = obsavestring (filename, strlen (filename),
- &objfile->symbol_obstack);
+ &objfile->objfile_obstack);
symtab->fullname = NULL;
symtab->language = deduce_language_from_filename (filename);
symtab->debugformat = obsavestring ("unknown", 7,
- &objfile->symbol_obstack);
+ &objfile->objfile_obstack);
/* Hook it to the objfile it comes from */
@@ -2034,12 +2239,12 @@ allocate_psymtab (char *filename, struct objfile *objfile)
}
else
psymtab = (struct partial_symtab *)
- obstack_alloc (&objfile->psymbol_obstack,
+ obstack_alloc (&objfile->objfile_obstack,
sizeof (struct partial_symtab));
memset (psymtab, 0, sizeof (struct partial_symtab));
psymtab->filename = obsavestring (filename, strlen (filename),
- &objfile->psymbol_obstack);
+ &objfile->objfile_obstack);
psymtab->symtab = NULL;
/* Prepend it to the psymtab list for the objfile it belongs to.
@@ -2103,8 +2308,7 @@ clear_symtab_users (void)
clear_internalvars ();
breakpoint_re_set ();
set_default_breakpoint (0, 0, 0, 0);
- current_source_symtab = 0;
- current_source_line = 0;
+ clear_current_source_symtab_and_line ();
clear_pc_function_cache ();
if (target_new_objfile_hook)
target_new_objfile_hook (NULL);
@@ -2189,7 +2393,7 @@ cashier_psymtab (struct partial_symtab *pst)
partial_symbol lists (global_psymbols/static_psymbols) that
this psymtab points to. These just take up space until all
the psymtabs are reclaimed. Ditto the dependencies list and
- filename, which are all in the psymbol_obstack. */
+ filename, which are all in the objfile_obstack. */
/* We need to cashier any psymtab that has this one as a dependency... */
again:
@@ -2233,9 +2437,9 @@ free_named_symtabs (char *name)
compilation units. We want to blow away any old info about these
compilation units, regardless of which objfiles they arrived in. --gnu. */
- register struct symtab *s;
- register struct symtab *prev;
- register struct partial_symtab *ps;
+ struct symtab *s;
+ struct symtab *prev;
+ struct partial_symtab *ps;
struct blockvector *bv;
int blewit = 0;
@@ -2252,7 +2456,7 @@ free_named_symtabs (char *name)
again2:
for (ps = partial_symtab_list; ps; ps = ps->next)
{
- if (STREQ (name, ps->filename))
+ if (strcmp (name, ps->filename) == 0)
{
cashier_psymtab (ps); /* Blow it away...and its little dog, too. */
goto again2; /* Must restart, chain has been munged */
@@ -2263,7 +2467,7 @@ again2:
for (s = symtab_list; s; s = s->next)
{
- if (STREQ (name, s->filename))
+ if (strcmp (name, s->filename) == 0)
break;
prev = s;
}
@@ -2290,15 +2494,16 @@ again2:
|| BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK))
|| BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)))
{
- complain (&oldsyms_complaint, name);
-
+ complaint (&symfile_complaints, "Replacing old symbols for `%s'",
+ name);
clear_symtab_users_queued++;
make_cleanup (clear_symtab_users_once, 0);
blewit = 1;
}
else
{
- complain (&empty_symtab_complaint, name);
+ complaint (&symfile_complaints, "Empty symbol table found for `%s'",
+ name);
}
free_symtab (s);
@@ -2344,16 +2549,28 @@ start_psymtab_common (struct objfile *objfile,
}
/* Add a symbol with a long value to a psymtab.
- Since one arg is a struct, we pass in a ptr and deref it (sigh). */
-
-void
-add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
+ Since one arg is a struct, we pass in a ptr and deref it (sigh).
+ Return the partial symbol that has been added. */
+
+/* NOTE: carlton/2003-09-11: The reason why we return the partial
+ symbol is so that callers can get access to the symbol's demangled
+ name, which they don't have any cheap way to determine otherwise.
+ (Currenly, dwarf2read.c is the only file who uses that information,
+ though it's possible that other readers might in the future.)
+ Elena wasn't thrilled about that, and I don't blame her, but we
+ couldn't come up with a better way to get that information. If
+ it's needed in other situations, we could consider breaking up
+ SYMBOL_SET_NAMES to provide access to the demangled name lookup
+ cache. */
+
+const struct partial_symbol *
+add_psymbol_to_list (char *name, int namelength, domain_enum domain,
enum address_class class,
struct psymbol_allocation_list *list, long val, /* Value as a long */
CORE_ADDR coreaddr, /* Value as a CORE_ADDR */
enum language language, struct objfile *objfile)
{
- register struct partial_symbol *psym;
+ struct partial_symbol *psym;
char *buf = alloca (namelength + 1);
/* psymbol is static so that there will be no uninitialized gaps in the
structure which might contain random data, causing cache misses in
@@ -2363,7 +2580,6 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
/* Create local copy of the partial symbol */
memcpy (buf, name, namelength);
buf[namelength] = '\0';
- SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
/* val and coreaddr are mutually exclusive, one of them *will* be zero */
if (val != 0)
{
@@ -2375,12 +2591,14 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
}
SYMBOL_SECTION (&psymbol) = 0;
SYMBOL_LANGUAGE (&psymbol) = language;
- PSYMBOL_NAMESPACE (&psymbol) = namespace;
+ PSYMBOL_DOMAIN (&psymbol) = domain;
PSYMBOL_CLASS (&psymbol) = class;
- SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
+
+ SYMBOL_SET_NAMES (&psymbol, buf, namelength, objfile);
/* Stash the partial symbol away in the cache */
- psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
+ psym = deprecated_bcache (&psymbol, sizeof (struct partial_symbol),
+ objfile->psymbol_cache);
/* Save pointer to partial symbol in psymtab, growing symtab if needed. */
if (list->next >= list->list + list->size)
@@ -2389,6 +2607,8 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
}
*list->next++ = psym;
OBJSTAT (objfile, n_psyms++);
+
+ return psym;
}
/* Add a symbol with a long value to a psymtab. This differs from
@@ -2397,14 +2617,14 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
void
add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name,
- int dem_namelength, namespace_enum namespace,
+ int dem_namelength, domain_enum domain,
enum address_class class,
struct psymbol_allocation_list *list, long val, /* Value as a long */
CORE_ADDR coreaddr, /* Value as a CORE_ADDR */
enum language language,
struct objfile *objfile)
{
- register struct partial_symbol *psym;
+ struct partial_symbol *psym;
char *buf = alloca (namelength + 1);
/* psymbol is static so that there will be no uninitialized gaps in the
structure which might contain random data, causing cache misses in
@@ -2415,7 +2635,8 @@ add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name,
memcpy (buf, name, namelength);
buf[namelength] = '\0';
- SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
+ DEPRECATED_SYMBOL_NAME (&psymbol) = deprecated_bcache (buf, namelength + 1,
+ objfile->psymbol_cache);
buf = alloca (dem_namelength + 1);
memcpy (buf, dem_name, dem_namelength);
@@ -2426,12 +2647,8 @@ add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name,
case language_c:
case language_cplus:
SYMBOL_CPLUS_DEMANGLED_NAME (&psymbol) =
- bcache (buf, dem_namelength + 1, &objfile->psymbol_cache);
+ deprecated_bcache (buf, dem_namelength + 1, objfile->psymbol_cache);
break;
- case language_chill:
- SYMBOL_CHILL_DEMANGLED_NAME (&psymbol) =
- bcache (buf, dem_namelength + 1, &objfile->psymbol_cache);
-
/* FIXME What should be done for the default case? Ignoring for now. */
}
@@ -2446,12 +2663,13 @@ add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name,
}
SYMBOL_SECTION (&psymbol) = 0;
SYMBOL_LANGUAGE (&psymbol) = language;
- PSYMBOL_NAMESPACE (&psymbol) = namespace;
+ PSYMBOL_DOMAIN (&psymbol) = domain;
PSYMBOL_CLASS (&psymbol) = class;
SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
/* Stash the partial symbol away in the cache */
- psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
+ psym = deprecated_bcache (&psymbol, sizeof (struct partial_symbol),
+ objfile->psymbol_cache);
/* Save pointer to partial symbol in psymtab, growing symtab if needed. */
if (list->next >= list->list + list->size)
@@ -2471,11 +2689,11 @@ init_psymbol_list (struct objfile *objfile, int total_symbols)
if (objfile->global_psymbols.list)
{
- xmfree (objfile->md, (PTR) objfile->global_psymbols.list);
+ xmfree (objfile->md, objfile->global_psymbols.list);
}
if (objfile->static_psymbols.list)
{
- xmfree (objfile->md, (PTR) objfile->static_psymbols.list);
+ xmfree (objfile->md, objfile->static_psymbols.list);
}
/* Current best guess is that approximately a twentieth
@@ -2691,7 +2909,7 @@ pc_in_mapped_range (CORE_ADDR pc, asection *section)
/* Return true if the mapped ranges of sections A and B overlap, false
otherwise. */
-int
+static int
sections_overlap (asection *a, asection *b)
{
/* FIXME: need bfd *, so we can use bfd_section_vma methods. */
@@ -2893,7 +3111,7 @@ the 'overlay manual' command.");
sec2->the_bfd_section))
{
if (info_verbose)
- printf_filtered ("Note: section %s unmapped by overlap\n",
+ printf_unfiltered ("Note: section %s unmapped by overlap\n",
bfd_section_name (objfile->obfd,
sec2->the_bfd_section));
sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2 */
@@ -2943,7 +3161,7 @@ overlay_auto_command (char *args, int from_tty)
overlay_debugging = ovly_auto;
enable_overlay_breakpoints ();
if (info_verbose)
- printf_filtered ("Automatic overlay debugging enabled.");
+ printf_unfiltered ("Automatic overlay debugging enabled.");
}
/* Function: overlay_manual_command
@@ -2956,7 +3174,7 @@ overlay_manual_command (char *args, int from_tty)
overlay_debugging = ovly_on;
disable_overlay_breakpoints ();
if (info_verbose)
- printf_filtered ("Overlay debugging enabled.");
+ printf_unfiltered ("Overlay debugging enabled.");
}
/* Function: overlay_off_command
@@ -2969,7 +3187,7 @@ overlay_off_command (char *args, int from_tty)
overlay_debugging = ovly_off;
disable_overlay_breakpoints ();
if (info_verbose)
- printf_filtered ("Overlay debugging disabled.");
+ printf_unfiltered ("Overlay debugging disabled.");
}
static void
@@ -3247,6 +3465,45 @@ simple_overlay_update (struct obj_section *osect)
}
}
+/* Set the output sections and output offsets for section SECTP in
+ ABFD. The relocation code in BFD will read these offsets, so we
+ need to be sure they're initialized. We map each section to itself,
+ with no offset; this means that SECTP->vma will be honored. */
+
+static void
+symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy)
+{
+ sectp->output_section = sectp;
+ sectp->output_offset = 0;
+}
+
+/* Relocate the contents of a debug section SECTP in ABFD. The
+ contents are stored in BUF if it is non-NULL, or returned in a
+ malloc'd buffer otherwise.
+
+ For some platforms and debug info formats, shared libraries contain
+ relocations against the debug sections (particularly for DWARF-2;
+ one affected platform is PowerPC GNU/Linux, although it depends on
+ the version of the linker in use). Also, ELF object files naturally
+ have unresolved relocations for their debug sections. We need to apply
+ the relocations in order to get the locations of symbols correct. */
+
+bfd_byte *
+symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf)
+{
+ /* We're only interested in debugging sections with relocation
+ information. */
+ if ((sectp->flags & SEC_RELOC) == 0)
+ return NULL;
+ if ((sectp->flags & SEC_DEBUGGING) == 0)
+ return NULL;
+
+ /* We will handle section offsets properly elsewhere, so relocate as if
+ all sections begin at 0. */
+ bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL);
+
+ return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
+}
void
_initialize_symfile (void)
@@ -3257,7 +3514,7 @@ _initialize_symfile (void)
"Load symbol table from executable file FILE.\n\
The `file' command can also load symbol tables, as well as setting the file\n\
to execute.", &cmdlist);
- c->completer = filename_completer;
+ set_cmd_completer (c, filename_completer);
c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command,
"Usage: add-symbol-file FILE ADDR [-s <SECT> <SECT_ADDR> -s <SECT> <SECT_ADDR> ...]\n\
@@ -3265,9 +3522,9 @@ Load the symbols from FILE, assuming FILE has been dynamically loaded.\n\
ADDR is the starting address of the file's text.\n\
The optional arguments are section-name section-address pairs and\n\
should be specified if the data and bss segments are not contiguous\n\
-with the text. SECT is a section name to be loaded at SECT_ADDR.",
+with the text. SECT is a section name to be loaded at SECT_ADDR.",
&cmdlist);
- c->completer = filename_completer;
+ set_cmd_completer (c, filename_completer);
c = add_cmd ("add-shared-symbol-files", class_files,
add_shared_symbol_files_command,
@@ -3279,7 +3536,7 @@ with the text. SECT is a section name to be loaded at SECT_ADDR.",
c = add_cmd ("load", class_files, load_command,
"Dynamically load FILE into the running program, and record its symbols\n\
for access from GDB.", &cmdlist);
- c->completer = filename_completer;
+ set_cmd_completer (c, filename_completer);
add_show_from_set
(add_set_cmd ("symbol-reloading", class_support, var_boolean,
@@ -3336,4 +3593,18 @@ Usage: set extension-language .foo bar",
"cache.\n",
&setlist),
&showlist);
+
+ debug_file_directory = xstrdup (DEBUGDIR);
+ c = (add_set_cmd
+ ("debug-file-directory", class_support, var_string,
+ (char *) &debug_file_directory,
+ "Set the directory where separate debug symbols are searched for.\n"
+ "Separate debug symbols are first searched for in the same\n"
+ "directory as the binary, then in the `" DEBUG_SUBDIRECTORY
+ "' subdirectory,\n"
+ "and lastly at the path of the directory of the binary with\n"
+ "the global debug-file directory prepended\n",
+ &setlist));
+ add_show_from_set (c, &showlist);
+ set_cmd_completer (c, filename_completer);
}
diff --git a/contrib/gdb/gdb/symtab.c b/contrib/gdb/gdb/symtab.c
index e464b0b..6995891 100644
--- a/contrib/gdb/gdb/symtab.c
+++ b/contrib/gdb/gdb/symtab.c
@@ -1,8 +1,8 @@
/* Symbol table lookup for the GNU debugger, GDB.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
- Foundation, Inc.
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -38,9 +38,15 @@
#include "demangle.h"
#include "inferior.h"
#include "linespec.h"
+#include "source.h"
#include "filenames.h" /* for FILENAME_CMP */
+#include "objc-lang.h"
-#include "obstack.h"
+#include "hashtab.h"
+
+#include "gdb_obstack.h"
+#include "block.h"
+#include "dictionary.h"
#include <sys/types.h>
#include <fcntl.h>
@@ -49,11 +55,6 @@
#include <ctype.h>
#include "cp-abi.h"
-/* Prototype for one function in parser-defs.h,
- instead of including that entire file. */
-
-extern char *find_template_name_end (char *);
-
/* Prototypes for local functions */
static void completion_list_add_name (char *, char *, int, char *, char *);
@@ -76,18 +77,42 @@ static int find_line_common (struct linetable *, int, int *);
char *operator_chars (char *p, char **end);
-static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
- const char *, int,
- namespace_enum);
-
-static struct symbol *lookup_symbol_aux (const char *name, const
- struct block *block, const
- namespace_enum namespace, int
- *is_a_field_of_this, struct
- symtab **symtab);
-
+static struct symbol *lookup_symbol_aux (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ int *is_a_field_of_this,
+ struct symtab **symtab);
+
+static
+struct symbol *lookup_symbol_aux_local (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab);
+
+static
+struct symbol *lookup_symbol_aux_symtabs (int block_index,
+ const char *name,
+ const char *linkage_name,
+ const domain_enum domain,
+ struct symtab **symtab);
+
+static
+struct symbol *lookup_symbol_aux_psymtabs (int block_index,
+ const char *name,
+ const char *linkage_name,
+ const domain_enum domain,
+ struct symtab **symtab);
-static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
+#if 0
+static
+struct symbol *lookup_symbol_aux_minsyms (const char *name,
+ const char *linkage_name,
+ const domain_enum domain,
+ int *is_a_field_of_this,
+ struct symtab **symtab);
+#endif
/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
/* Signals the presence of objects compiled by HP compilers */
@@ -97,14 +122,12 @@ static void fixup_section (struct general_symbol_info *, struct objfile *);
static int file_matches (char *, char **, int);
-static void print_symbol_info (namespace_enum,
+static void print_symbol_info (domain_enum,
struct symtab *, struct symbol *, int, char *);
static void print_msymbol_info (struct minimal_symbol *);
-static void symtab_symbol_info (char *, namespace_enum, int);
-
-static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
+static void symtab_symbol_info (char *, domain_enum, int);
void _initialize_symtab (void);
@@ -119,19 +142,6 @@ struct type *builtin_type_error;
const struct block *block_found;
-/* While the C++ support is still in flux, issue a possibly helpful hint on
- using the new command completion feature on single quoted demangled C++
- symbols. Remove when loose ends are cleaned up. FIXME -fnf */
-
-static void
-cplusplus_hint (char *name)
-{
- while (*name == '\'')
- name++;
- printf_filtered ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
- printf_filtered ("(Note leading single quote.)\n");
-}
-
/* Check for a symtab of a specific name; first in symtabs, then in
psymtabs. *If* there is no '/' in the name, a match after a '/'
in the symtab filename will also work. */
@@ -139,15 +149,21 @@ cplusplus_hint (char *name)
struct symtab *
lookup_symtab (const char *name)
{
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct objfile *objfile;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct objfile *objfile;
char *real_path = NULL;
+ char *full_path = NULL;
/* Here we are interested in canonicalizing an absolute path, not
absolutizing a relative path. */
if (IS_ABSOLUTE_PATH (name))
- real_path = gdb_realpath (name);
+ {
+ full_path = xfullpath (name);
+ make_cleanup (xfree, full_path);
+ real_path = gdb_realpath (name);
+ make_cleanup (xfree, real_path);
+ }
got_symtab:
@@ -157,24 +173,32 @@ got_symtab:
{
if (FILENAME_CMP (name, s->filename) == 0)
{
- xfree (real_path);
return s;
}
+
/* If the user gave us an absolute path, try to find the file in
this symtab and use its absolute path. */
+
+ if (full_path != NULL)
+ {
+ const char *fp = symtab_to_filename (s);
+ if (FILENAME_CMP (full_path, fp) == 0)
+ {
+ return s;
+ }
+ }
+
if (real_path != NULL)
{
- char *rp = symtab_to_filename (s);
+ char *rp = gdb_realpath (symtab_to_filename (s));
+ make_cleanup (xfree, rp);
if (FILENAME_CMP (real_path, rp) == 0)
{
- xfree (real_path);
return s;
}
}
}
- xfree (real_path);
-
/* Now, search for a matching tail (only if name doesn't have any dirs) */
if (lbasename (name) == name)
@@ -218,38 +242,57 @@ got_symtab:
struct partial_symtab *
lookup_partial_symtab (const char *name)
{
- register struct partial_symtab *pst;
- register struct objfile *objfile;
+ struct partial_symtab *pst;
+ struct objfile *objfile;
+ char *full_path = NULL;
char *real_path = NULL;
/* Here we are interested in canonicalizing an absolute path, not
absolutizing a relative path. */
if (IS_ABSOLUTE_PATH (name))
- real_path = gdb_realpath (name);
+ {
+ full_path = xfullpath (name);
+ make_cleanup (xfree, full_path);
+ real_path = gdb_realpath (name);
+ make_cleanup (xfree, real_path);
+ }
ALL_PSYMTABS (objfile, pst)
{
if (FILENAME_CMP (name, pst->filename) == 0)
{
- xfree (real_path);
return (pst);
}
+
/* If the user gave us an absolute path, try to find the file in
this symtab and use its absolute path. */
- if (real_path != NULL)
+ if (full_path != NULL)
{
if (pst->fullname == NULL)
source_full_path_of (pst->filename, &pst->fullname);
if (pst->fullname != NULL
- && FILENAME_CMP (real_path, pst->fullname) == 0)
+ && FILENAME_CMP (full_path, pst->fullname) == 0)
{
- xfree (real_path);
return pst;
}
}
- }
- xfree (real_path);
+ if (real_path != NULL)
+ {
+ char *rp = NULL;
+ if (pst->fullname == NULL)
+ source_full_path_of (pst->filename, &pst->fullname);
+ if (pst->fullname != NULL)
+ {
+ rp = gdb_realpath (pst->fullname);
+ make_cleanup (xfree, rp);
+ }
+ if (rp != NULL && FILENAME_CMP (real_path, rp) == 0)
+ {
+ return pst;
+ }
+ }
+ }
/* Now, search for a matching tail (only if name doesn't have any dirs) */
@@ -300,7 +343,7 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
is_full_physname_constructor = is_constructor_name (physname);
is_constructor =
- is_full_physname_constructor || (newname && STREQ (field_name, newname));
+ is_full_physname_constructor || (newname && strcmp (field_name, newname) == 0);
if (!is_destructor)
is_destructor = (strncmp (physname, "__dt", 4) == 0);
@@ -348,16 +391,296 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
strcat (mangled_name, physname);
return (mangled_name);
}
+
+/* Initialize the language dependent portion of a symbol
+ depending upon the language for the symbol. */
+void
+symbol_init_language_specific (struct general_symbol_info *gsymbol,
+ enum language language)
+{
+ gsymbol->language = language;
+ if (gsymbol->language == language_cplus
+ || gsymbol->language == language_java
+ || gsymbol->language == language_objc)
+ {
+ gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+ }
+ else
+ {
+ memset (&gsymbol->language_specific, 0,
+ sizeof (gsymbol->language_specific));
+ }
+}
+
+/* Functions to initialize a symbol's mangled name. */
+
+/* Create the hash table used for demangled names. Each hash entry is
+ a pair of strings; one for the mangled name and one for the demangled
+ name. The entry is hashed via just the mangled name. */
+
+static void
+create_demangled_names_hash (struct objfile *objfile)
+{
+ /* Choose 256 as the starting size of the hash table, somewhat arbitrarily.
+ The hash table code will round this up to the next prime number.
+ Choosing a much larger table size wastes memory, and saves only about
+ 1% in symbol reading. */
+
+ objfile->demangled_names_hash = htab_create_alloc_ex
+ (256, htab_hash_string, (int (*) (const void *, const void *)) streq,
+ NULL, objfile->md, xmcalloc, xmfree);
+}
+
+/* Try to determine the demangled name for a symbol, based on the
+ language of that symbol. If the language is set to language_auto,
+ it will attempt to find any demangling algorithm that works and
+ then set the language appropriately. The returned name is allocated
+ by the demangler and should be xfree'd. */
+
+static char *
+symbol_find_demangled_name (struct general_symbol_info *gsymbol,
+ const char *mangled)
+{
+ char *demangled = NULL;
+
+ if (gsymbol->language == language_unknown)
+ gsymbol->language = language_auto;
+
+ if (gsymbol->language == language_objc
+ || gsymbol->language == language_auto)
+ {
+ demangled =
+ objc_demangle (mangled, 0);
+ if (demangled != NULL)
+ {
+ gsymbol->language = language_objc;
+ return demangled;
+ }
+ }
+ if (gsymbol->language == language_cplus
+ || gsymbol->language == language_auto)
+ {
+ demangled =
+ cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+ if (demangled != NULL)
+ {
+ gsymbol->language = language_cplus;
+ return demangled;
+ }
+ }
+ if (gsymbol->language == language_java)
+ {
+ demangled =
+ cplus_demangle (mangled,
+ DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA);
+ if (demangled != NULL)
+ {
+ gsymbol->language = language_java;
+ return demangled;
+ }
+ }
+ return NULL;
+}
+
+/* Set both the mangled and demangled (if any) names for GSYMBOL based
+ on LINKAGE_NAME and LEN. The hash table corresponding to OBJFILE
+ is used, and the memory comes from that objfile's objfile_obstack.
+ LINKAGE_NAME is copied, so the pointer can be discarded after
+ calling this function. */
+
+/* We have to be careful when dealing with Java names: when we run
+ into a Java minimal symbol, we don't know it's a Java symbol, so it
+ gets demangled as a C++ name. This is unfortunate, but there's not
+ much we can do about it: but when demangling partial symbols and
+ regular symbols, we'd better not reuse the wrong demangled name.
+ (See PR gdb/1039.) We solve this by putting a distinctive prefix
+ on Java names when storing them in the hash table. */
+
+/* FIXME: carlton/2003-03-13: This is an unfortunate situation. I
+ don't mind the Java prefix so much: different languages have
+ different demangling requirements, so it's only natural that we
+ need to keep language data around in our demangling cache. But
+ it's not good that the minimal symbol has the wrong demangled name.
+ Unfortunately, I can't think of any easy solution to that
+ problem. */
+
+#define JAVA_PREFIX "##JAVA$$"
+#define JAVA_PREFIX_LEN 8
+
+void
+symbol_set_names (struct general_symbol_info *gsymbol,
+ const char *linkage_name, int len, struct objfile *objfile)
+{
+ char **slot;
+ /* A 0-terminated copy of the linkage name. */
+ const char *linkage_name_copy;
+ /* A copy of the linkage name that might have a special Java prefix
+ added to it, for use when looking names up in the hash table. */
+ const char *lookup_name;
+ /* The length of lookup_name. */
+ int lookup_len;
+ if (objfile->demangled_names_hash == NULL)
+ create_demangled_names_hash (objfile);
+
+ /* The stabs reader generally provides names that are not
+ NUL-terminated; most of the other readers don't do this, so we
+ can just use the given copy, unless we're in the Java case. */
+ if (gsymbol->language == language_java)
+ {
+ char *alloc_name;
+ lookup_len = len + JAVA_PREFIX_LEN;
+
+ alloc_name = alloca (lookup_len + 1);
+ memcpy (alloc_name, JAVA_PREFIX, JAVA_PREFIX_LEN);
+ memcpy (alloc_name + JAVA_PREFIX_LEN, linkage_name, len);
+ alloc_name[lookup_len] = '\0';
+
+ lookup_name = alloc_name;
+ linkage_name_copy = alloc_name + JAVA_PREFIX_LEN;
+ }
+ else if (linkage_name[len] != '\0')
+ {
+ char *alloc_name;
+ lookup_len = len;
+
+ alloc_name = alloca (lookup_len + 1);
+ memcpy (alloc_name, linkage_name, len);
+ alloc_name[lookup_len] = '\0';
+
+ lookup_name = alloc_name;
+ linkage_name_copy = alloc_name;
+ }
+ else
+ {
+ lookup_len = len;
+ lookup_name = linkage_name;
+ linkage_name_copy = linkage_name;
+ }
+
+ slot = (char **) htab_find_slot (objfile->demangled_names_hash,
+ lookup_name, INSERT);
+
+ /* If this name is not in the hash table, add it. */
+ if (*slot == NULL)
+ {
+ char *demangled_name = symbol_find_demangled_name (gsymbol,
+ linkage_name_copy);
+ int demangled_len = demangled_name ? strlen (demangled_name) : 0;
+
+ /* If there is a demangled name, place it right after the mangled name.
+ Otherwise, just place a second zero byte after the end of the mangled
+ name. */
+ *slot = obstack_alloc (&objfile->objfile_obstack,
+ lookup_len + demangled_len + 2);
+ memcpy (*slot, lookup_name, lookup_len + 1);
+ if (demangled_name != NULL)
+ {
+ memcpy (*slot + lookup_len + 1, demangled_name, demangled_len + 1);
+ xfree (demangled_name);
+ }
+ else
+ (*slot)[lookup_len + 1] = '\0';
+ }
+
+ gsymbol->name = *slot + lookup_len - len;
+ if ((*slot)[lookup_len + 1] != '\0')
+ gsymbol->language_specific.cplus_specific.demangled_name
+ = &(*slot)[lookup_len + 1];
+ else
+ gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+}
+
+/* Initialize the demangled name of GSYMBOL if possible. Any required space
+ to store the name is obtained from the specified obstack. The function
+ symbol_set_names, above, should be used instead where possible for more
+ efficient memory usage. */
+
+void
+symbol_init_demangled_name (struct general_symbol_info *gsymbol,
+ struct obstack *obstack)
+{
+ char *mangled = gsymbol->name;
+ char *demangled = NULL;
+
+ demangled = symbol_find_demangled_name (gsymbol, mangled);
+ if (gsymbol->language == language_cplus
+ || gsymbol->language == language_java
+ || gsymbol->language == language_objc)
+ {
+ if (demangled)
+ {
+ gsymbol->language_specific.cplus_specific.demangled_name
+ = obsavestring (demangled, strlen (demangled), obstack);
+ xfree (demangled);
+ }
+ else
+ gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+ }
+ else
+ {
+ /* Unknown language; just clean up quietly. */
+ if (demangled)
+ xfree (demangled);
+ }
+}
+
+/* Return the source code name of a symbol. In languages where
+ demangling is necessary, this is the demangled name. */
+
+char *
+symbol_natural_name (const struct general_symbol_info *gsymbol)
+{
+ if ((gsymbol->language == language_cplus
+ || gsymbol->language == language_java
+ || gsymbol->language == language_objc)
+ && (gsymbol->language_specific.cplus_specific.demangled_name != NULL))
+ {
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ }
+ else
+ {
+ return gsymbol->name;
+ }
+}
+
+/* Return the demangled name for a symbol based on the language for
+ that symbol. If no demangled name exists, return NULL. */
+char *
+symbol_demangled_name (struct general_symbol_info *gsymbol)
+{
+ if (gsymbol->language == language_cplus
+ || gsymbol->language == language_java
+ || gsymbol->language == language_objc)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+
+ else
+ return NULL;
+}
+
+/* Initialize the structure fields to zero values. */
+void
+init_sal (struct symtab_and_line *sal)
+{
+ sal->symtab = 0;
+ sal->section = 0;
+ sal->line = 0;
+ sal->pc = 0;
+ sal->end = 0;
+}
+
-/* Find which partial symtab on contains PC and SECTION. Return 0 if none. */
+/* Find which partial symtab contains PC and SECTION. Return 0 if
+ none. We return the psymtab that contains a symbol whose address
+ exactly matches PC, or, if we cannot find an exact match, the
+ psymtab that contains a symbol whose address is closest to PC. */
struct partial_symtab *
find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
{
- register struct partial_symtab *pst;
- register struct objfile *objfile;
+ struct partial_symtab *pst;
+ struct objfile *objfile;
struct minimal_symbol *msymbol;
/* If we know that this is not a text address, return failure. This is
@@ -377,6 +700,8 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
if (pc >= pst->textlow && pc < pst->texthigh)
{
struct partial_symtab *tpst;
+ struct partial_symtab *best_pst = pst;
+ struct partial_symbol *best_psym = NULL;
/* An objfile that has its functions reordered might have
many partial symbol tables containing the PC, but
@@ -389,6 +714,13 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
if (msymbol == NULL)
return (pst);
+ /* The code range of partial symtabs sometimes overlap, so, in
+ the loop below, we need to check all partial symtabs and
+ find the one that fits better for the given PC address. We
+ select the partial symtab that contains a symbol whose
+ address is closest to the PC address. By closest we mean
+ that find_pc_sect_symbol returns the symbol with address
+ that is closest and still less than the given PC. */
for (tpst = pst; tpst != NULL; tpst = tpst->next)
{
if (pc >= tpst->textlow && pc < tpst->texthigh)
@@ -400,9 +732,33 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
&& SYMBOL_VALUE_ADDRESS (p)
== SYMBOL_VALUE_ADDRESS (msymbol))
return (tpst);
+ if (p != NULL)
+ {
+ /* We found a symbol in this partial symtab which
+ matches (or is closest to) PC, check whether it
+ is closer than our current BEST_PSYM. Since
+ this symbol address is necessarily lower or
+ equal to PC, the symbol closer to PC is the
+ symbol which address is the highest. */
+ /* This way we return the psymtab which contains
+ such best match symbol. This can help in cases
+ where the symbol information/debuginfo is not
+ complete, like for instance on IRIX6 with gcc,
+ where no debug info is emitted for
+ statics. (See also the nodebug.exp
+ testcase.) */
+ if (best_psym == NULL
+ || SYMBOL_VALUE_ADDRESS (p)
+ > SYMBOL_VALUE_ADDRESS (best_psym))
+ {
+ best_psym = p;
+ best_pst = tpst;
+ }
+ }
+
}
}
- return (pst);
+ return (best_pst);
}
}
return (NULL);
@@ -444,7 +800,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
pp++)
{
p = *pp;
- if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+ if (SYMBOL_DOMAIN (p) == VAR_DOMAIN
&& SYMBOL_CLASS (p) == LOC_BLOCK
&& pc >= SYMBOL_VALUE_ADDRESS (p)
&& (SYMBOL_VALUE_ADDRESS (p) > best_pc
@@ -468,7 +824,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
pp++)
{
p = *pp;
- if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+ if (SYMBOL_DOMAIN (p) == VAR_DOMAIN
&& SYMBOL_CLASS (p) == LOC_BLOCK
&& pc >= SYMBOL_VALUE_ADDRESS (p)
&& (SYMBOL_VALUE_ADDRESS (p) > best_pc
@@ -543,7 +899,7 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
}
/* Find the definition for a specified symbol name NAME
- in namespace NAMESPACE, visible from lexical block BLOCK.
+ in domain DOMAIN, visible from lexical block BLOCK.
Returns the struct symbol pointer, or zero if no symbol is found.
If SYMTAB is non-NULL, store the symbol table in which the
symbol was found there, or NULL if not found.
@@ -557,22 +913,38 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
attractive to put in some QUIT's (though I'm not really sure
whether it can run long enough to be really important). But there
are a few calls for which it would appear to be bad news to quit
- out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c, and
- nindy_frame_chain_valid in nindy-tdep.c. (Note that there is C++
- code below which can error(), but that probably doesn't affect
- these calls since they are looking for a known variable and thus
- can probably assume it will never hit the C++ code). */
+ out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c. (Note
+ that there is C++ code below which can error(), but that probably
+ doesn't affect these calls since they are looking for a known
+ variable and thus can probably assume it will never hit the C++
+ code). */
struct symbol *
lookup_symbol (const char *name, const struct block *block,
- const namespace_enum namespace, int *is_a_field_of_this,
+ const domain_enum domain, int *is_a_field_of_this,
struct symtab **symtab)
{
- char *modified_name = NULL;
- char *modified_name2 = NULL;
+ char *demangled_name = NULL;
+ const char *modified_name = NULL;
+ const char *mangled_name = NULL;
int needtofreename = 0;
struct symbol *returnval;
+ modified_name = name;
+
+ /* If we are using C++ language, demangle the name before doing a lookup, so
+ we can always binary search. */
+ if (current_language->la_language == language_cplus)
+ {
+ demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name)
+ {
+ mangled_name = name;
+ modified_name = demangled_name;
+ needtofreename = 1;
+ }
+ }
+
if (case_sensitivity == case_sensitive_off)
{
char *copy;
@@ -585,120 +957,51 @@ lookup_symbol (const char *name, const struct block *block,
copy[len] = 0;
modified_name = copy;
}
- else
- modified_name = (char *) name;
-
- /* If we are using C++ language, demangle the name before doing a lookup, so
- we can always binary search. */
- if (current_language->la_language == language_cplus)
- {
- modified_name2 = cplus_demangle (modified_name, DMGL_ANSI | DMGL_PARAMS);
- if (modified_name2)
- {
- modified_name = modified_name2;
- needtofreename = 1;
- }
- }
- returnval = lookup_symbol_aux (modified_name, block, namespace,
- is_a_field_of_this, symtab);
+ returnval = lookup_symbol_aux (modified_name, mangled_name, block,
+ domain, is_a_field_of_this, symtab);
if (needtofreename)
- xfree (modified_name2);
+ xfree (demangled_name);
return returnval;
}
-static struct symbol *
-lookup_symbol_aux (const char *name, const struct block *block,
- const namespace_enum namespace, int *is_a_field_of_this,
- struct symtab **symtab)
-{
- register struct symbol *sym;
- register struct symtab *s = NULL;
- register struct partial_symtab *ps;
- register struct blockvector *bv;
- register struct objfile *objfile = NULL;
- register struct block *b;
- register struct minimal_symbol *msymbol;
-
-
- /* Search specified block and its superiors. */
-
- while (block != 0)
- {
- sym = lookup_block_symbol (block, name, namespace);
- if (sym)
- {
- block_found = block;
- if (symtab != NULL)
- {
- /* Search the list of symtabs for one which contains the
- address of the start of this block. */
- ALL_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- if (BLOCK_START (b) <= BLOCK_START (block)
- && BLOCK_END (b) > BLOCK_START (block))
- goto found;
- }
- found:
- *symtab = s;
- }
-
- return fixup_symbol_section (sym, objfile);
- }
- block = BLOCK_SUPERBLOCK (block);
- }
+/* Behave like lookup_symbol_aux except that NAME is the natural name
+ of the symbol that we're looking for and, if LINKAGE_NAME is
+ non-NULL, ensure that the symbol's linkage name matches as
+ well. */
- /* FIXME: this code is never executed--block is always NULL at this
- point. What is it trying to do, anyway? We already should have
- checked the STATIC_BLOCK above (it is the superblock of top-level
- blocks). Why is VAR_NAMESPACE special-cased? */
- /* Don't need to mess with the psymtabs; if we have a block,
- that file is read in. If we don't, then we deal later with
- all the psymtab stuff that needs checking. */
- /* Note (RT): The following never-executed code looks unnecessary to me also.
- * If we change the code to use the original (passed-in)
- * value of 'block', we could cause it to execute, but then what
- * would it do? The STATIC_BLOCK of the symtab containing the passed-in
- * 'block' was already searched by the above code. And the STATIC_BLOCK's
- * of *other* symtabs (those files not containing 'block' lexically)
- * should not contain 'block' address-wise. So we wouldn't expect this
- * code to find any 'sym''s that were not found above. I vote for
- * deleting the following paragraph of code.
- */
- if (namespace == VAR_NAMESPACE && block != NULL)
- {
- struct block *b;
- /* Find the right symtab. */
- ALL_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- if (BLOCK_START (b) <= BLOCK_START (block)
- && BLOCK_END (b) > BLOCK_START (block))
- {
- sym = lookup_block_symbol (b, name, VAR_NAMESPACE);
- if (sym)
- {
- block_found = b;
- if (symtab != NULL)
- *symtab = s;
- return fixup_symbol_section (sym, objfile);
- }
- }
- }
- }
+static struct symbol *
+lookup_symbol_aux (const char *name, const char *linkage_name,
+ const struct block *block, const domain_enum domain,
+ int *is_a_field_of_this, struct symtab **symtab)
+{
+ struct symbol *sym;
+
+ /* Make sure we do something sensible with is_a_field_of_this, since
+ the callers that set this parameter to some non-null value will
+ certainly use it later and expect it to be either 0 or 1.
+ If we don't set it, the contents of is_a_field_of_this are
+ undefined. */
+ if (is_a_field_of_this != NULL)
+ *is_a_field_of_this = 0;
+
+ /* Search specified block and its superiors. Don't search
+ STATIC_BLOCK or GLOBAL_BLOCK. */
+
+ sym = lookup_symbol_aux_local (name, linkage_name, block, domain,
+ symtab);
+ if (sym != NULL)
+ return sym;
+ /* If requested to do so by the caller and if appropriate for the
+ current language, check to see if NAME is a field of `this'. */
- /* C++: If requested to do so by the caller,
- check to see if NAME is a field of `this'. */
- if (is_a_field_of_this)
+ if (current_language->la_value_of_this != NULL
+ && is_a_field_of_this != NULL)
{
- struct value *v = value_of_this (0);
+ struct value *v = current_language->la_value_of_this (0);
- *is_a_field_of_this = 0;
if (v && check_field (v, name))
{
*is_a_field_of_this = 1;
@@ -708,129 +1011,130 @@ lookup_symbol_aux (const char *name, const struct block *block,
}
}
- /* Now search all global blocks. Do the symtab's first, then
- check the psymtab's. If a psymtab indicates the existence
- of the desired name as a global, then do psymtab-to-symtab
+ /* Now do whatever is appropriate for the current language to look
+ up static and global variables. */
+
+ sym = current_language->la_lookup_symbol_nonlocal (name, linkage_name,
+ block, domain,
+ symtab);
+ if (sym != NULL)
+ return sym;
+
+ /* Now search all static file-level symbols. Not strictly correct,
+ but more useful than an error. Do the symtabs first, then check
+ the psymtabs. If a psymtab indicates the existence of the
+ desired name as a file-level static, then do psymtab-to-symtab
conversion on the fly and return the found symbol. */
- ALL_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, namespace);
- if (sym)
- {
- block_found = block;
- if (symtab != NULL)
- *symtab = s;
- return fixup_symbol_section (sym, objfile);
- }
- }
+ sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name,
+ domain, symtab);
+ if (sym != NULL)
+ return sym;
+
+ sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name,
+ domain, symtab);
+ if (sym != NULL)
+ return sym;
+
+ if (symtab != NULL)
+ *symtab = NULL;
+ return NULL;
+}
+
+/* Check to see if the symbol is defined in BLOCK or its superiors.
+ Don't search STATIC_BLOCK or GLOBAL_BLOCK. */
+
+static struct symbol *
+lookup_symbol_aux_local (const char *name, const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ struct symbol *sym;
+ const struct block *static_block = block_static_block (block);
-#ifndef HPUXHPPA
+ /* Check if either no block is specified or it's a global block. */
- /* Check for the possibility of the symbol being a function or
- a mangled variable that is stored in one of the minimal symbol tables.
- Eventually, all global symbols might be resolved in this way. */
+ if (static_block == NULL)
+ return NULL;
- if (namespace == VAR_NAMESPACE)
+ while (block != static_block)
{
- msymbol = lookup_minimal_symbol (name, NULL, NULL);
- if (msymbol != NULL)
- {
- s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol),
- SYMBOL_BFD_SECTION (msymbol));
- if (s != NULL)
- {
- /* This is a function which has a symtab for its address. */
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- namespace);
- /* We kept static functions in minimal symbol table as well as
- in static scope. We want to find them in the symbol table. */
- if (!sym)
- {
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- namespace);
- }
+ sym = lookup_symbol_aux_block (name, linkage_name, block, domain,
+ symtab);
+ if (sym != NULL)
+ return sym;
+ block = BLOCK_SUPERBLOCK (block);
+ }
- /* sym == 0 if symbol was found in the minimal symbol table
- but not in the symtab.
- Return 0 to use the msymbol definition of "foo_".
+ /* We've reached the static block without finding a result. */
- This happens for Fortran "foo_" symbols,
- which are "foo" in the symtab.
+ return NULL;
+}
- This can also happen if "asm" is used to make a
- regular symbol but not a debugging symbol, e.g.
- asm(".globl _main");
- asm("_main:");
- */
+/* Look up a symbol in a block; if found, locate its symtab, fixup the
+ symbol, and set block_found appropriately. */
- if (symtab != NULL)
- *symtab = s;
- return fixup_symbol_section (sym, objfile);
- }
- else if (MSYMBOL_TYPE (msymbol) != mst_text
- && MSYMBOL_TYPE (msymbol) != mst_file_text
- && !STREQ (name, SYMBOL_NAME (msymbol)))
+struct symbol *
+lookup_symbol_aux_block (const char *name, const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ struct symbol *sym;
+ struct objfile *objfile = NULL;
+ struct blockvector *bv;
+ struct block *b;
+ struct symtab *s = NULL;
+
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
+ if (sym)
+ {
+ block_found = block;
+ if (symtab != NULL)
+ {
+ /* Search the list of symtabs for one which contains the
+ address of the start of this block. */
+ ALL_SYMTABS (objfile, s)
{
- /* This is a mangled variable, look it up by its
- mangled name. */
- return lookup_symbol_aux (SYMBOL_NAME (msymbol), block,
- namespace, is_a_field_of_this, symtab);
+ bv = BLOCKVECTOR (s);
+ b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ if (BLOCK_START (b) <= BLOCK_START (block)
+ && BLOCK_END (b) > BLOCK_START (block))
+ goto found;
}
- /* There are no debug symbols for this file, or we are looking
- for an unmangled variable.
- Try to find a matching static symbol below. */
+ found:
+ *symtab = s;
}
+
+ return fixup_symbol_section (sym, objfile);
}
-#endif
+ return NULL;
+}
- ALL_PSYMTABS (objfile, ps)
- {
- if (!ps->readin && lookup_partial_symbol (ps, name, 1, namespace))
- {
- s = PSYMTAB_TO_SYMTAB (ps);
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, namespace);
- if (!sym)
- {
- /* This shouldn't be necessary, but as a last resort
- * try looking in the statics even though the psymtab
- * claimed the symbol was global. It's possible that
- * the psymtab gets it wrong in some cases.
- */
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, namespace);
- if (!sym)
- error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
-%s may be an inlined function, or may be a template function\n\
-(if a template, try specifying an instantiation: %s<type>).",
- name, ps->filename, name, name);
- }
- if (symtab != NULL)
- *symtab = s;
- return fixup_symbol_section (sym, objfile);
- }
- }
+/* Check to see if the symbol is defined in one of the symtabs.
+ BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK,
+ depending on whether or not we want to search global symbols or
+ static symbols. */
- /* Now search all static file-level symbols.
- Not strictly correct, but more useful than an error.
- Do the symtabs first, then check the psymtabs.
- If a psymtab indicates the existence
- of the desired name as a file-level static, then do psymtab-to-symtab
- conversion on the fly and return the found symbol. */
+static struct symbol *
+lookup_symbol_aux_symtabs (int block_index,
+ const char *name, const char *linkage_name,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ struct symbol *sym;
+ struct objfile *objfile;
+ struct blockvector *bv;
+ const struct block *block;
+ struct symtab *s;
ALL_SYMTABS (objfile, s)
{
bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, namespace);
+ block = BLOCKVECTOR_BLOCK (bv, block_index);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
if (sym)
{
block_found = block;
@@ -840,27 +1144,58 @@ lookup_symbol_aux (const char *name, const struct block *block,
}
}
+ return NULL;
+}
+
+/* Check to see if the symbol is defined in one of the partial
+ symtabs. BLOCK_INDEX should be either GLOBAL_BLOCK or
+ STATIC_BLOCK, depending on whether or not we want to search global
+ symbols or static symbols. */
+
+static struct symbol *
+lookup_symbol_aux_psymtabs (int block_index, const char *name,
+ const char *linkage_name,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ struct symbol *sym;
+ struct objfile *objfile;
+ struct blockvector *bv;
+ const struct block *block;
+ struct partial_symtab *ps;
+ struct symtab *s;
+ const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
+
ALL_PSYMTABS (objfile, ps)
{
- if (!ps->readin && lookup_partial_symbol (ps, name, 0, namespace))
+ if (!ps->readin
+ && lookup_partial_symbol (ps, name, linkage_name,
+ psymtab_index, domain))
{
s = PSYMTAB_TO_SYMTAB (ps);
bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, namespace);
+ block = BLOCKVECTOR_BLOCK (bv, block_index);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
if (!sym)
{
- /* This shouldn't be necessary, but as a last resort
- * try looking in the globals even though the psymtab
- * claimed the symbol was static. It's possible that
- * the psymtab gets it wrong in some cases.
- */
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, namespace);
+ /* This shouldn't be necessary, but as a last resort try
+ looking in the statics even though the psymtab claimed
+ the symbol was global, or vice-versa. It's possible
+ that the psymtab gets it wrong in some cases. */
+
+ /* FIXME: carlton/2002-09-30: Should we really do that?
+ If that happens, isn't it likely to be a GDB error, in
+ which case we should fix the GDB error rather than
+ silently dealing with it here? So I'd vote for
+ removing the check for the symbol in the other
+ block. */
+ block = BLOCKVECTOR_BLOCK (bv,
+ block_index == GLOBAL_BLOCK ?
+ STATIC_BLOCK : GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
if (!sym)
- error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
-%s may be an inlined function, or may be a template function\n\
-(if a template, try specifying an instantiation: %s<type>).",
+ error ("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>).",
+ block_index == GLOBAL_BLOCK ? "global" : "static",
name, ps->filename, name, name);
}
if (symtab != NULL)
@@ -869,67 +1204,106 @@ lookup_symbol_aux (const char *name, const struct block *block,
}
}
-#ifdef HPUXHPPA
-
- /* Check for the possibility of the symbol being a function or
- a global variable that is stored in one of the minimal symbol tables.
- The "minimal symbol table" is built from linker-supplied info.
-
- RT: I moved this check to last, after the complete search of
- the global (p)symtab's and static (p)symtab's. For HP-generated
- symbol tables, this check was causing a premature exit from
- lookup_symbol with NULL return, and thus messing up symbol lookups
- of things like "c::f". It seems to me a check of the minimal
- symbol table ought to be a last resort in any case. I'm vaguely
- worried about the comment below which talks about FORTRAN routines "foo_"
- though... is it saying we need to do the "minsym" check before
- the static check in this case?
- */
+ return NULL;
+}
- if (namespace == VAR_NAMESPACE)
+#if 0
+/* Check for the possibility of the symbol being a function or a
+ mangled variable that is stored in one of the minimal symbol
+ tables. Eventually, all global symbols might be resolved in this
+ way. */
+
+/* NOTE: carlton/2002-12-05: At one point, this function was part of
+ lookup_symbol_aux, and what are now 'return' statements within
+ lookup_symbol_aux_minsyms returned from lookup_symbol_aux, even if
+ sym was NULL. As far as I can tell, this was basically accidental;
+ it didn't happen every time that msymbol was non-NULL, but only if
+ some additional conditions held as well, and it caused problems
+ with HP-generated symbol tables. */
+
+/* NOTE: carlton/2003-05-14: This function was once used as part of
+ lookup_symbol. It is currently unnecessary for correctness
+ reasons, however, and using it doesn't seem to be any faster than
+ using lookup_symbol_aux_psymtabs, so I'm commenting it out. */
+
+static struct symbol *
+lookup_symbol_aux_minsyms (const char *name,
+ const char *linkage_name,
+ const domain_enum domain,
+ int *is_a_field_of_this,
+ struct symtab **symtab)
+{
+ struct symbol *sym;
+ struct blockvector *bv;
+ const struct block *block;
+ struct minimal_symbol *msymbol;
+ struct symtab *s;
+
+ if (domain == VAR_DOMAIN)
{
msymbol = lookup_minimal_symbol (name, NULL, NULL);
+
if (msymbol != NULL)
{
- /* OK, we found a minimal symbol in spite of not
- * finding any symbol. There are various possible
- * explanations for this. One possibility is the symbol
- * exists in code not compiled -g. Another possibility
- * is that the 'psymtab' isn't doing its job.
- * A third possibility, related to #2, is that we were confused
- * by name-mangling. For instance, maybe the psymtab isn't
- * doing its job because it only know about demangled
- * names, but we were given a mangled name...
- */
-
- /* We first use the address in the msymbol to try to
- * locate the appropriate symtab. Note that find_pc_symtab()
- * has a side-effect of doing psymtab-to-symtab expansion,
- * for the found symtab.
- */
- s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
+ /* OK, we found a minimal symbol in spite of not finding any
+ symbol. There are various possible explanations for
+ this. One possibility is the symbol exists in code not
+ compiled -g. Another possibility is that the 'psymtab'
+ isn't doing its job. A third possibility, related to #2,
+ is that we were confused by name-mangling. For instance,
+ maybe the psymtab isn't doing its job because it only
+ know about demangled names, but we were given a mangled
+ name... */
+
+ /* We first use the address in the msymbol to try to locate
+ the appropriate symtab. Note that find_pc_sect_symtab()
+ has a side-effect of doing psymtab-to-symtab expansion,
+ for the found symtab. */
+ s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol),
+ SYMBOL_BFD_SECTION (msymbol));
if (s != NULL)
{
+ /* This is a function which has a symtab for its address. */
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- namespace);
+
+ /* This call used to pass `SYMBOL_LINKAGE_NAME (msymbol)' as the
+ `name' argument to lookup_block_symbol. But the name
+ of a minimal symbol is always mangled, so that seems
+ to be clearly the wrong thing to pass as the
+ unmangled name. */
+ sym =
+ lookup_block_symbol (block, name, linkage_name, domain);
/* We kept static functions in minimal symbol table as well as
in static scope. We want to find them in the symbol table. */
if (!sym)
{
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- namespace);
- }
- /* If we found one, return it */
- if (sym)
- {
- if (symtab != NULL)
- *symtab = s;
- return sym;
+ sym = lookup_block_symbol (block, name,
+ linkage_name, domain);
}
+ /* NOTE: carlton/2002-12-04: The following comment was
+ taken from a time when two versions of this function
+ were part of the body of lookup_symbol_aux: this
+ comment was taken from the version of the function
+ that was #ifdef HPUXHPPA, and the comment was right
+ before the 'return NULL' part of lookup_symbol_aux.
+ (Hence the "Fall through and return 0" comment.)
+ Elena did some digging into the situation for
+ Fortran, and she reports:
+
+ "I asked around (thanks to Jeff Knaggs), and I think
+ the story for Fortran goes like this:
+
+ "Apparently, in older Fortrans, '_' was not part of
+ the user namespace. g77 attached a final '_' to
+ procedure names as the exported symbols for linkage
+ (foo_) , but the symbols went in the debug info just
+ like 'foo'. The rationale behind this is not
+ completely clear, and maybe it was done to other
+ symbols as well, not just procedures." */
+
/* If we get here with sym == 0, the symbol was
found in the minimal symbol table
but not in the symtab.
@@ -947,39 +1321,118 @@ lookup_symbol_aux (const char *name, const struct block *block,
asm(".globl _main");
asm("_main:");
*/
- }
- /* If the lookup-by-address fails, try repeating the
- * entire lookup process with the symbol name from
- * the msymbol (if different from the original symbol name).
- */
- else if (MSYMBOL_TYPE (msymbol) != mst_text
- && MSYMBOL_TYPE (msymbol) != mst_file_text
- && !STREQ (name, SYMBOL_NAME (msymbol)))
- {
- return lookup_symbol_aux (SYMBOL_NAME (msymbol), block,
- namespace, is_a_field_of_this, symtab);
+ if (symtab != NULL && sym != NULL)
+ *symtab = s;
+ return fixup_symbol_section (sym, s->objfile);
}
}
}
-#endif
+ return NULL;
+}
+#endif /* 0 */
- if (symtab != NULL)
- *symtab = NULL;
- return 0;
+/* A default version of lookup_symbol_nonlocal for use by languages
+ that can't think of anything better to do. This implements the C
+ lookup rules. */
+
+struct symbol *
+basic_lookup_symbol_nonlocal (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ struct symbol *sym;
+
+ /* NOTE: carlton/2003-05-19: The comments below were written when
+ this (or what turned into this) was part of lookup_symbol_aux;
+ I'm much less worried about these questions now, since these
+ decisions have turned out well, but I leave these comments here
+ for posterity. */
+
+ /* NOTE: carlton/2002-12-05: There is a question as to whether or
+ not it would be appropriate to search the current global block
+ here as well. (That's what this code used to do before the
+ is_a_field_of_this check was moved up.) On the one hand, it's
+ redundant with the lookup_symbol_aux_symtabs search that happens
+ next. On the other hand, if decode_line_1 is passed an argument
+ like filename:var, then the user presumably wants 'var' to be
+ searched for in filename. On the third hand, there shouldn't be
+ multiple global variables all of which are named 'var', and it's
+ not like decode_line_1 has ever restricted its search to only
+ global variables in a single filename. All in all, only
+ searching the static block here seems best: it's correct and it's
+ cleanest. */
+
+ /* NOTE: carlton/2002-12-05: There's also a possible performance
+ issue here: if you usually search for global symbols in the
+ current file, then it would be slightly better to search the
+ current global block before searching all the symtabs. But there
+ are other factors that have a much greater effect on performance
+ than that one, so I don't think we should worry about that for
+ now. */
+
+ sym = lookup_symbol_static (name, linkage_name, block, domain, symtab);
+ if (sym != NULL)
+ return sym;
+
+ return lookup_symbol_global (name, linkage_name, domain, symtab);
+}
+
+/* Lookup a symbol in the static block associated to BLOCK, if there
+ is one; do nothing if BLOCK is NULL or a global block. */
+
+struct symbol *
+lookup_symbol_static (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ const struct block *static_block = block_static_block (block);
+
+ if (static_block != NULL)
+ return lookup_symbol_aux_block (name, linkage_name, static_block,
+ domain, symtab);
+ else
+ return NULL;
+}
+
+/* Lookup a symbol in all files' global blocks (searching psymtabs if
+ necessary). */
+
+struct symbol *
+lookup_symbol_global (const char *name,
+ const char *linkage_name,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ struct symbol *sym;
+
+ sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
+ domain, symtab);
+ if (sym != NULL)
+ return sym;
+
+ return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name,
+ domain, symtab);
}
-
-/* Look, in partial_symtab PST, for symbol NAME. Check the global
- symbols if GLOBAL, the static symbols if not */
-static struct partial_symbol *
-lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
- namespace_enum namespace)
+/* Look, in partial_symtab PST, for symbol whose natural name is NAME.
+ If LINKAGE_NAME is non-NULL, check in addition that the symbol's
+ linkage name matches it. Check the global symbols if GLOBAL, the
+ static symbols if not */
+
+struct partial_symbol *
+lookup_partial_symbol (struct partial_symtab *pst, const char *name,
+ const char *linkage_name, int global,
+ domain_enum domain)
{
struct partial_symbol *temp;
struct partial_symbol **start, **psym;
- struct partial_symbol **top, **bottom, **center;
+ struct partial_symbol **top, **real_top, **bottom, **center;
int length = (global ? pst->n_global_syms : pst->n_static_syms);
int do_linear_search = 1;
@@ -996,12 +1449,14 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
do_linear_search = 0;
/* Binary search. This search is guaranteed to end with center
- pointing at the earliest partial symbol with the correct
- name. At that point *all* partial symbols with that name
- will be checked against the correct namespace. */
+ pointing at the earliest partial symbol whose name might be
+ correct. At that point *all* partial symbols with an
+ appropriate name will be checked against the correct
+ domain. */
bottom = start;
top = start + length - 1;
+ real_top = top;
while (top > bottom)
{
center = bottom + (top - bottom) / 2;
@@ -1012,7 +1467,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
{
do_linear_search = 1;
}
- if (strcmp (SYMBOL_SOURCE_NAME (*center), name) >= 0)
+ if (strcmp_iw_ordered (SYMBOL_NATURAL_NAME (*center), name) >= 0)
{
top = center;
}
@@ -1024,12 +1479,12 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
if (!(top == bottom))
internal_error (__FILE__, __LINE__, "failed internal consistency check");
- /* djb - 2000-06-03 - Use SYMBOL_MATCHES_NAME, not a strcmp, so
- we don't have to force a linear search on C++. Probably holds true
- for JAVA as well, no way to check.*/
- while (SYMBOL_MATCHES_NAME (*top,name))
+ while (top <= real_top
+ && (linkage_name != NULL
+ ? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0
+ : SYMBOL_MATCHES_NATURAL_NAME (*top,name)))
{
- if (SYMBOL_NAMESPACE (*top) == namespace)
+ if (SYMBOL_DOMAIN (*top) == domain)
{
return (*top);
}
@@ -1044,9 +1499,11 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
{
for (psym = start; psym < start + length; psym++)
{
- if (namespace == SYMBOL_NAMESPACE (*psym))
+ if (domain == SYMBOL_DOMAIN (*psym))
{
- if (SYMBOL_MATCHES_NAME (*psym, name))
+ if (linkage_name != NULL
+ ? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0
+ : SYMBOL_MATCHES_NATURAL_NAME (*psym, name))
{
return (*psym);
}
@@ -1057,23 +1514,31 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
return (NULL);
}
-/* Look up a type named NAME in the struct_namespace. The type returned
- must not be opaque -- i.e., must have at least one field defined
+/* Look up a type named NAME in the struct_domain. The type returned
+ must not be opaque -- i.e., must have at least one field
+ defined. */
- This code was modelled on lookup_symbol -- the parts not relevant to looking
- up types were just left out. In particular it's assumed here that types
- are available in struct_namespace and only at file-static or global blocks. */
+struct type *
+lookup_transparent_type (const char *name)
+{
+ return current_language->la_lookup_transparent_type (name);
+}
+/* The standard implementation of lookup_transparent_type. This code
+ was modeled on lookup_symbol -- the parts not relevant to looking
+ up types were just left out. In particular it's assumed here that
+ types are available in struct_domain and only at file-static or
+ global blocks. */
struct type *
-lookup_transparent_type (const char *name)
+basic_lookup_transparent_type (const char *name)
{
- register struct symbol *sym;
- register struct symtab *s = NULL;
- register struct partial_symtab *ps;
+ struct symbol *sym;
+ struct symtab *s = NULL;
+ struct partial_symtab *ps;
struct blockvector *bv;
- register struct objfile *objfile;
- register struct block *block;
+ struct objfile *objfile;
+ struct block *block;
/* Now search all the global symbols. Do the symtab's first, then
check the psymtab's. If a psymtab indicates the existence
@@ -1084,7 +1549,7 @@ lookup_transparent_type (const char *name)
{
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
{
return SYMBOL_TYPE (sym);
@@ -1093,12 +1558,13 @@ lookup_transparent_type (const char *name)
ALL_PSYMTABS (objfile, ps)
{
- if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_NAMESPACE))
+ if (!ps->readin && lookup_partial_symbol (ps, name, NULL,
+ 1, STRUCT_DOMAIN))
{
s = PSYMTAB_TO_SYMTAB (ps);
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
{
/* This shouldn't be necessary, but as a last resort
@@ -1107,7 +1573,7 @@ lookup_transparent_type (const char *name)
* the psymtab gets it wrong in some cases.
*/
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
%s may be an inlined function, or may be a template function\n\
@@ -1131,7 +1597,7 @@ lookup_transparent_type (const char *name)
{
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
{
return SYMBOL_TYPE (sym);
@@ -1140,12 +1606,12 @@ lookup_transparent_type (const char *name)
ALL_PSYMTABS (objfile, ps)
{
- if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_NAMESPACE))
+ if (!ps->readin && lookup_partial_symbol (ps, name, NULL, 0, STRUCT_DOMAIN))
{
s = PSYMTAB_TO_SYMTAB (ps);
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
{
/* This shouldn't be necessary, but as a last resort
@@ -1154,7 +1620,7 @@ lookup_transparent_type (const char *name)
* the psymtab gets it wrong in some cases.
*/
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
%s may be an inlined function, or may be a template function\n\
@@ -1176,12 +1642,12 @@ lookup_transparent_type (const char *name)
struct partial_symtab *
find_main_psymtab (void)
{
- register struct partial_symtab *pst;
- register struct objfile *objfile;
+ struct partial_symtab *pst;
+ struct objfile *objfile;
ALL_PSYMTABS (objfile, pst)
{
- if (lookup_partial_symbol (pst, main_name (), 1, VAR_NAMESPACE))
+ if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN))
{
return (pst);
}
@@ -1189,202 +1655,75 @@ find_main_psymtab (void)
return (NULL);
}
-/* Search BLOCK for symbol NAME in NAMESPACE.
+/* Search BLOCK for symbol NAME in DOMAIN.
Note that if NAME is the demangled form of a C++ symbol, we will fail
to find a match during the binary search of the non-encoded names, but
for now we don't worry about the slight inefficiency of looking for
a match we'll never find, since it will go pretty quick. Once the
binary search terminates, we drop through and do a straight linear
- search on the symbols. Each symbol which is marked as being a C++
- symbol (language_cplus set) has both the encoded and non-encoded names
- tested for a match. */
+ search on the symbols. Each symbol which is marked as being a ObjC/C++
+ symbol (language_cplus or language_objc set) has both the encoded and
+ non-encoded names tested for a match.
+
+ If LINKAGE_NAME is non-NULL, verify that any symbol we find has this
+ particular mangled name.
+*/
struct symbol *
-lookup_block_symbol (register const struct block *block, const char *name,
- const namespace_enum namespace)
+lookup_block_symbol (const struct block *block, const char *name,
+ const char *linkage_name,
+ const domain_enum domain)
{
- register int bot, top, inc;
- register struct symbol *sym;
- register struct symbol *sym_found = NULL;
- register int do_linear_search = 1;
-
- /* If the blocks's symbols were sorted, start with a binary search. */
+ struct dict_iterator iter;
+ struct symbol *sym;
- if (BLOCK_SHOULD_SORT (block))
+ if (!BLOCK_FUNCTION (block))
{
- /* Reset the linear search flag so if the binary search fails, we
- won't do the linear search once unless we find some reason to
- do so */
-
- do_linear_search = 0;
- top = BLOCK_NSYMS (block);
- bot = 0;
-
- /* Advance BOT to not far before the first symbol whose name is NAME. */
-
- while (1)
- {
- inc = (top - bot + 1);
- /* No need to keep binary searching for the last few bits worth. */
- if (inc < 4)
- {
- break;
- }
- inc = (inc >> 1) + bot;
- sym = BLOCK_SYM (block, inc);
- if (!do_linear_search && (SYMBOL_LANGUAGE (sym) == language_java))
- {
- do_linear_search = 1;
- }
- if (SYMBOL_SOURCE_NAME (sym)[0] < name[0])
- {
- bot = inc;
- }
- else if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
- {
- top = inc;
- }
- else if (strcmp (SYMBOL_SOURCE_NAME (sym), name) < 0)
- {
- bot = inc;
- }
- else
- {
- top = inc;
- }
- }
-
- /* Now scan forward until we run out of symbols, find one whose
- name is greater than NAME, or find one we want. If there is
- more than one symbol with the right name and namespace, we
- return the first one; I believe it is now impossible for us
- to encounter two symbols with the same name and namespace
- here, because blocks containing argument symbols are no
- longer sorted. */
-
- top = BLOCK_NSYMS (block);
- while (bot < top)
+ for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter);
+ sym != NULL;
+ sym = dict_iter_name_next (name, &iter))
{
- sym = BLOCK_SYM (block, bot);
- if (SYMBOL_NAMESPACE (sym) == namespace &&
- SYMBOL_MATCHES_NAME (sym, name))
- {
- return sym;
- }
- if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
- {
- break;
- }
- bot++;
+ if (SYMBOL_DOMAIN (sym) == domain
+ && (linkage_name != NULL
+ ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
+ return sym;
}
+ return NULL;
}
+ else
+ {
+ /* Note that parameter symbols do not always show up last in the
+ list; this loop makes sure to take anything else other than
+ parameter symbols first; it only uses parameter symbols as a
+ last resort. Note that this only takes up extra computation
+ time on a match. */
- /* Here if block isn't sorted, or we fail to find a match during the
- binary search above. If during the binary search above, we find a
- symbol which is a Java symbol, then we have re-enabled the linear
- search flag which was reset when starting the binary search.
-
- This loop is equivalent to the loop above, but hacked greatly for speed.
-
- Note that parameter symbols do not always show up last in the
- list; this loop makes sure to take anything else other than
- parameter symbols first; it only uses parameter symbols as a
- last resort. Note that this only takes up extra computation
- time on a match. */
+ struct symbol *sym_found = NULL;
- if (do_linear_search)
- {
- top = BLOCK_NSYMS (block);
- bot = 0;
- while (bot < top)
+ for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter);
+ sym != NULL;
+ sym = dict_iter_name_next (name, &iter))
{
- sym = BLOCK_SYM (block, bot);
- if (SYMBOL_NAMESPACE (sym) == namespace &&
- SYMBOL_MATCHES_NAME (sym, name))
+ if (SYMBOL_DOMAIN (sym) == domain
+ && (linkage_name != NULL
+ ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
{
- /* If SYM has aliases, then use any alias that is active
- at the current PC. If no alias is active at the current
- PC, then use the main symbol.
-
- ?!? Is checking the current pc correct? Is this routine
- ever called to look up a symbol from another context?
-
- FIXME: No, it's not correct. If someone sets a
- conditional breakpoint at an address, then the
- breakpoint's `struct expression' should refer to the
- `struct symbol' appropriate for the breakpoint's
- address, which may not be the PC.
-
- Even if it were never called from another context,
- it's totally bizarre for lookup_symbol's behavior to
- depend on the value of the inferior's current PC. We
- should pass in the appropriate PC as well as the
- block. The interface to lookup_symbol should change
- to require the caller to provide a PC. */
-
- if (SYMBOL_ALIASES (sym))
- sym = find_active_alias (sym, read_pc ());
-
sym_found = sym;
if (SYMBOL_CLASS (sym) != LOC_ARG &&
SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
SYMBOL_CLASS (sym) != LOC_REF_ARG &&
SYMBOL_CLASS (sym) != LOC_REGPARM &&
SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
- SYMBOL_CLASS (sym) != LOC_BASEREG_ARG)
+ SYMBOL_CLASS (sym) != LOC_BASEREG_ARG &&
+ SYMBOL_CLASS (sym) != LOC_COMPUTED_ARG)
{
break;
}
}
- bot++;
- }
- }
- return (sym_found); /* Will be NULL if not found. */
-}
-
-/* Given a main symbol SYM and ADDR, search through the alias
- list to determine if an alias is active at ADDR and return
- the active alias.
-
- If no alias is active, then return SYM. */
-
-static struct symbol *
-find_active_alias (struct symbol *sym, CORE_ADDR addr)
-{
- struct range_list *r;
- struct alias_list *aliases;
-
- /* If we have aliases, check them first. */
- aliases = SYMBOL_ALIASES (sym);
-
- while (aliases)
- {
- if (!SYMBOL_RANGES (aliases->sym))
- return aliases->sym;
- for (r = SYMBOL_RANGES (aliases->sym); r; r = r->next)
- {
- if (r->start <= addr && r->end > addr)
- return aliases->sym;
}
- aliases = aliases->next;
+ return (sym_found); /* Will be NULL if not found. */
}
-
- /* Nothing found, return the main symbol. */
- return sym;
-}
-
-
-/* Return the symbol for the function which contains a specified
- lexical block, described by a struct block BL. */
-
-struct symbol *
-block_function (struct block *bl)
-{
- while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)
- bl = BLOCK_SUPERBLOCK (bl);
-
- return BLOCK_FUNCTION (bl);
}
/* Find the symtab associated with PC and SECTION. Look through the
@@ -1393,12 +1732,12 @@ block_function (struct block *bl)
struct symtab *
find_pc_sect_symtab (CORE_ADDR pc, asection *section)
{
- register struct block *b;
+ struct block *b;
struct blockvector *bv;
- register struct symtab *s = NULL;
- register struct symtab *best_s = NULL;
- register struct partial_symtab *ps;
- register struct objfile *objfile;
+ struct symtab *s = NULL;
+ struct symtab *best_s = NULL;
+ struct partial_symtab *ps;
+ struct objfile *objfile;
CORE_ADDR distance = 0;
struct minimal_symbol *msymbol;
@@ -1455,15 +1794,16 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
}
if (section != 0)
{
- int i;
+ struct dict_iterator iter;
+ struct symbol *sym = NULL;
- for (i = 0; i < b->nsyms; i++)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
- fixup_symbol_section (b->sym[i], objfile);
- if (section == SYMBOL_BFD_SECTION (b->sym[i]))
+ fixup_symbol_section (sym, objfile);
+ if (section == SYMBOL_BFD_SECTION (sym))
break;
}
- if (i >= b->nsyms)
+ if (sym == NULL)
continue; /* no symbol in this symtab matches section */
}
distance = BLOCK_END (b) - BLOCK_START (b);
@@ -1500,96 +1840,6 @@ find_pc_symtab (CORE_ADDR pc)
}
-#if 0
-
-/* Find the closest symbol value (of any sort -- function or variable)
- for a given address value. Slow but complete. (currently unused,
- mainly because it is too slow. We could fix it if each symtab and
- psymtab had contained in it the addresses ranges of each of its
- sections, which also would be required to make things like "info
- line *0x2345" cause psymtabs to be converted to symtabs). */
-
-struct symbol *
-find_addr_symbol (CORE_ADDR addr, struct symtab **symtabp, CORE_ADDR *symaddrp)
-{
- struct symtab *symtab, *best_symtab;
- struct objfile *objfile;
- register int bot, top;
- register struct symbol *sym;
- register CORE_ADDR sym_addr;
- struct block *block;
- int blocknum;
-
- /* Info on best symbol seen so far */
-
- register CORE_ADDR best_sym_addr = 0;
- struct symbol *best_sym = 0;
-
- /* FIXME -- we should pull in all the psymtabs, too! */
- ALL_SYMTABS (objfile, symtab)
- {
- /* Search the global and static blocks in this symtab for
- the closest symbol-address to the desired address. */
-
- for (blocknum = GLOBAL_BLOCK; blocknum <= STATIC_BLOCK; blocknum++)
- {
- QUIT;
- block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum);
- top = BLOCK_NSYMS (block);
- for (bot = 0; bot < top; bot++)
- {
- sym = BLOCK_SYM (block, bot);
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_STATIC:
- case LOC_LABEL:
- sym_addr = SYMBOL_VALUE_ADDRESS (sym);
- break;
-
- case LOC_INDIRECT:
- sym_addr = SYMBOL_VALUE_ADDRESS (sym);
- /* An indirect symbol really lives at *sym_addr,
- * so an indirection needs to be done.
- * However, I am leaving this commented out because it's
- * expensive, and it's possible that symbolization
- * could be done without an active process (in
- * case this read_memory will fail). RT
- sym_addr = read_memory_unsigned_integer
- (sym_addr, TARGET_PTR_BIT / TARGET_CHAR_BIT);
- */
- break;
-
- case LOC_BLOCK:
- sym_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- break;
-
- default:
- continue;
- }
-
- if (sym_addr <= addr)
- if (sym_addr > best_sym_addr)
- {
- /* Quit if we found an exact match. */
- best_sym = sym;
- best_sym_addr = sym_addr;
- best_symtab = symtab;
- if (sym_addr == addr)
- goto done;
- }
- }
- }
- }
-
-done:
- if (symtabp)
- *symtabp = best_symtab;
- if (symaddrp)
- *symaddrp = best_sym_addr;
- return best_sym;
-}
-#endif /* 0 */
-
/* Find the source file and line number for a given PC value and SECTION.
Return a structure containing a symtab pointer, a line number,
and a pc range for the entire source line.
@@ -1608,13 +1858,13 @@ done:
/* If it's worth the effort, we could be using a binary search. */
struct symtab_and_line
-find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
+find_pc_sect_line (CORE_ADDR pc, struct bfd_section *section, int notcurrent)
{
struct symtab *s;
- register struct linetable *l;
- register int len;
- register int i;
- register struct linetable_entry *item;
+ struct linetable *l;
+ int len;
+ int i;
+ struct linetable_entry *item;
struct symtab_and_line val;
struct blockvector *bv;
struct minimal_symbol *msymbol;
@@ -1644,7 +1894,7 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
But what we want is the statement containing the instruction.
Fudge the pc to make sure we get that. */
- INIT_SAL (&val); /* initialize to zeroes */
+ init_sal (&val); /* initialize to zeroes */
/* It's tempting to assume that, if we can't find debugging info for
any function enclosing PC, that we shouldn't search for line
@@ -1704,7 +1954,8 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
if (msymbol != NULL)
if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
{
- mfunsym = lookup_minimal_symbol_text (SYMBOL_NAME (msymbol), NULL, NULL);
+ mfunsym = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol),
+ NULL);
if (mfunsym == NULL)
/* I eliminated this warning since it is coming out
* in the following situation:
@@ -1715,12 +1966,12 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
* so of course we can't find the real func/line info,
* but the "break" still works, and the warning is annoying.
* So I commented out the warning. RT */
- /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ;
+ /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ;
/* fall through */
else if (SYMBOL_VALUE (mfunsym) == SYMBOL_VALUE (msymbol))
/* Avoid infinite recursion */
/* See above comment about why warning is commented out */
- /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ;
+ /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ;
/* fall through */
else
return find_pc_line (SYMBOL_VALUE (mfunsym), 0);
@@ -1786,9 +2037,11 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
the first line, prev will not be set. */
/* Is this file's best line closer than the best in the other files?
- If so, record this file, and its best line, as best so far. */
+ If so, record this file, and its best line, as best so far. Don't
+ save prev if it represents the end of a function (i.e. line number
+ 0) instead of a real line. */
- if (prev && (!best || prev->pc > best->pc))
+ if (prev && prev->line && (!best || prev->pc > best->pc))
{
best = prev;
best_symtab = s;
@@ -1915,7 +2168,7 @@ find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match)
struct linetable *l;
int ind;
- if (!STREQ (symtab->filename, s->filename))
+ if (strcmp (symtab->filename, s->filename) != 0)
continue;
l = LINETABLE (s);
ind = find_line_common (l, line, &exact);
@@ -2021,11 +2274,11 @@ find_line_pc_range (struct symtab_and_line sal, CORE_ADDR *startptr,
Set *EXACT_MATCH nonzero if the value returned is an exact match. */
static int
-find_line_common (register struct linetable *l, register int lineno,
+find_line_common (struct linetable *l, int lineno,
int *exact_match)
{
- register int i;
- register int len;
+ int i;
+ int len;
/* BEST is the smallest linenumber > LINENO so far seen,
or 0 if none has been seen so far.
@@ -2042,7 +2295,7 @@ find_line_common (register struct linetable *l, register int lineno,
len = l->nitems;
for (i = 0; i < len; i++)
{
- register struct linetable_entry *item = &(l->item[i]);
+ struct linetable_entry *item = &(l->item[i]);
if (item->line == lineno)
{
@@ -2104,10 +2357,6 @@ find_function_start_sal (struct symbol *sym, int funfirstline)
}
sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
-#ifdef PROLOGUE_FIRSTLINE_OVERLAP
- /* Convex: no need to suppress code on first line, if any */
- sal.pc = pc;
-#else
/* Check if SKIP_PROLOGUE left us in mid-line, and the next
line is still part of the same function. */
if (sal.pc != pc
@@ -2120,7 +2369,6 @@ find_function_start_sal (struct symbol *sym, int funfirstline)
sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
}
sal.pc = pc;
-#endif
return sal;
}
@@ -2150,7 +2398,7 @@ operator_chars (char *p, char **end)
if (isalpha (*p) || *p == '_' || *p == '$')
{
- register char *q = p + 1;
+ char *q = p + 1;
while (isalnum (*q) || *q == '_' || *q == '$')
q++;
*end = q;
@@ -2340,9 +2588,9 @@ output_source_filename (char *name, int *first)
static void
sources_info (char *ignore, int from_tty)
{
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct objfile *objfile;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct objfile *objfile;
int first;
if (!have_full_symbols () && !have_partial_symbols ())
@@ -2424,8 +2672,8 @@ compare_search_syms (const void *sa, const void *sb)
struct symbol_search **sym_a = (struct symbol_search **) sa;
struct symbol_search **sym_b = (struct symbol_search **) sb;
- return strcmp (SYMBOL_SOURCE_NAME ((*sym_a)->symbol),
- SYMBOL_SOURCE_NAME ((*sym_b)->symbol));
+ return strcmp (SYMBOL_PRINT_NAME ((*sym_a)->symbol),
+ SYMBOL_PRINT_NAME ((*sym_b)->symbol));
}
/* Sort the ``nfound'' symbols in the list after prevtail. Leave
@@ -2467,10 +2715,10 @@ sort_search_symbols (struct symbol_search *prevtail, int nfound)
returning the results in *MATCHES.
Only symbols of KIND are searched:
- FUNCTIONS_NAMESPACE - search all functions
- TYPES_NAMESPACE - search all type names
- METHODS_NAMESPACE - search all methods NOT IMPLEMENTED
- VARIABLES_NAMESPACE - search all symbols, excluding functions, type names,
+ FUNCTIONS_DOMAIN - search all functions
+ TYPES_DOMAIN - search all type names
+ METHODS_DOMAIN - search all methods NOT IMPLEMENTED
+ VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
and constants (enums)
free_search_symbols should be called when *MATCHES is no longer needed.
@@ -2479,17 +2727,17 @@ sort_search_symbols (struct symbol_search *prevtail, int nfound)
separately alphabetized.
*/
void
-search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
+search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
struct symbol_search **matches)
{
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct blockvector *bv;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct blockvector *bv;
struct blockvector *prev_bv = 0;
- register struct block *b;
- register int i = 0;
- register int j;
- register struct symbol *sym;
+ struct block *b;
+ int i = 0;
+ struct dict_iterator iter;
+ struct symbol *sym;
struct partial_symbol **psym;
struct objfile *objfile;
struct minimal_symbol *msymbol;
@@ -2516,13 +2764,13 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
struct symbol_search *tail;
struct cleanup *old_chain = NULL;
- if (kind < VARIABLES_NAMESPACE)
- error ("must search on specific namespace");
+ if (kind < VARIABLES_DOMAIN)
+ error ("must search on specific domain");
- ourtype = types[(int) (kind - VARIABLES_NAMESPACE)];
- ourtype2 = types2[(int) (kind - VARIABLES_NAMESPACE)];
- ourtype3 = types3[(int) (kind - VARIABLES_NAMESPACE)];
- ourtype4 = types4[(int) (kind - VARIABLES_NAMESPACE)];
+ ourtype = types[(int) (kind - VARIABLES_DOMAIN)];
+ ourtype2 = types2[(int) (kind - VARIABLES_DOMAIN)];
+ ourtype3 = types3[(int) (kind - VARIABLES_DOMAIN)];
+ ourtype4 = types4[(int) (kind - VARIABLES_DOMAIN)];
sr = *matches = NULL;
tail = NULL;
@@ -2602,12 +2850,13 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
/* If it would match (logic taken from loop below)
load the file and go on to the next one */
if (file_matches (ps->filename, files, nfiles)
- && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym))
- && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
+ && ((regexp == NULL
+ || re_exec (SYMBOL_NATURAL_NAME (*psym)) != 0)
+ && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
&& SYMBOL_CLASS (*psym) != LOC_BLOCK)
- || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK)
- || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
- || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK))))
+ || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (*psym) == LOC_BLOCK)
+ || (kind == TYPES_DOMAIN && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
+ || (kind == METHODS_DOMAIN && SYMBOL_CLASS (*psym) == LOC_BLOCK))))
{
PSYMTAB_TO_SYMTAB (ps);
keep_going = 0;
@@ -2630,7 +2879,7 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
any matching symbols without debug info.
*/
- if (nfiles == 0 && (kind == VARIABLES_NAMESPACE || kind == FUNCTIONS_NAMESPACE))
+ if (nfiles == 0 && (kind == VARIABLES_DOMAIN || kind == FUNCTIONS_DOMAIN))
{
ALL_MSYMBOLS (objfile, msymbol)
{
@@ -2639,14 +2888,21 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
MSYMBOL_TYPE (msymbol) == ourtype3 ||
MSYMBOL_TYPE (msymbol) == ourtype4)
{
- if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+ if (regexp == NULL
+ || re_exec (SYMBOL_NATURAL_NAME (msymbol)) != 0)
{
if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
{
- if (kind == FUNCTIONS_NAMESPACE
- || lookup_symbol (SYMBOL_NAME (msymbol),
+ /* FIXME: carlton/2003-02-04: Given that the
+ semantics of lookup_symbol keeps on changing
+ slightly, it would be a nice idea if we had a
+ function lookup_symbol_minsym that found the
+ symbol associated to a given minimal symbol (if
+ any). */
+ if (kind == FUNCTIONS_DOMAIN
+ || lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
(struct block *) NULL,
- VAR_NAMESPACE,
+ VAR_DOMAIN,
0, (struct symtab **) NULL) == NULL)
found_misc = 1;
}
@@ -2669,18 +2925,18 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
struct symbol_search *prevtail = tail;
int nfound = 0;
b = BLOCKVECTOR_BLOCK (bv, i);
- for (j = 0; j < BLOCK_NSYMS (b); j++)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
QUIT;
- sym = BLOCK_SYM (b, j);
if (file_matches (s->filename, files, nfiles)
- && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
- && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+ && ((regexp == NULL
+ || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0)
+ && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF
&& SYMBOL_CLASS (sym) != LOC_BLOCK
&& SYMBOL_CLASS (sym) != LOC_CONST)
- || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK)
- || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
- || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK))))
+ || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ || (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ || (kind == METHODS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK))))
{
/* match */
psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
@@ -2719,7 +2975,7 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
/* If there are no eyes, avoid all contact. I mean, if there are
no debug symbols, then print directly from the msymbol_vector. */
- if (found_misc || kind != FUNCTIONS_NAMESPACE)
+ if (found_misc || kind != FUNCTIONS_DOMAIN)
{
ALL_MSYMBOLS (objfile, msymbol)
{
@@ -2728,15 +2984,16 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
MSYMBOL_TYPE (msymbol) == ourtype3 ||
MSYMBOL_TYPE (msymbol) == ourtype4)
{
- if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+ if (regexp == NULL
+ || re_exec (SYMBOL_NATURAL_NAME (msymbol)) != 0)
{
/* Functions: Look up by address. */
- if (kind != FUNCTIONS_NAMESPACE ||
+ if (kind != FUNCTIONS_DOMAIN ||
(0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))))
{
/* Variables/Absolutes: Look up by name */
- if (lookup_symbol (SYMBOL_NAME (msymbol),
- (struct block *) NULL, VAR_NAMESPACE,
+ if (lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
+ (struct block *) NULL, VAR_DOMAIN,
0, (struct symtab **) NULL) == NULL)
{
/* match */
@@ -2771,7 +3028,7 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
regarding the match to gdb_stdout.
*/
static void
-print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym,
+print_symbol_info (domain_enum kind, struct symtab *s, struct symbol *sym,
int block, char *last)
{
if (last == NULL || strcmp (last, s->filename) != 0)
@@ -2781,49 +3038,25 @@ print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym,
fputs_filtered (":\n", gdb_stdout);
}
- if (kind != TYPES_NAMESPACE && block == STATIC_BLOCK)
+ if (kind != TYPES_DOMAIN && block == STATIC_BLOCK)
printf_filtered ("static ");
/* Typedef that is not a C++ class */
- if (kind == TYPES_NAMESPACE
- && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE)
+ if (kind == TYPES_DOMAIN
+ && SYMBOL_DOMAIN (sym) != STRUCT_DOMAIN)
typedef_print (SYMBOL_TYPE (sym), sym, gdb_stdout);
/* variable, func, or typedef-that-is-c++-class */
- else if (kind < TYPES_NAMESPACE ||
- (kind == TYPES_NAMESPACE &&
- SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE))
+ else if (kind < TYPES_DOMAIN ||
+ (kind == TYPES_DOMAIN &&
+ SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN))
{
type_print (SYMBOL_TYPE (sym),
(SYMBOL_CLASS (sym) == LOC_TYPEDEF
- ? "" : SYMBOL_SOURCE_NAME (sym)),
+ ? "" : SYMBOL_PRINT_NAME (sym)),
gdb_stdout, 0);
printf_filtered (";\n");
}
- else
- {
-#if 0
- /* Tiemann says: "info methods was never implemented." */
- char *demangled_name;
- c_type_print_base (TYPE_FN_FIELD_TYPE (t, block),
- gdb_stdout, 0, 0);
- c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (t, block),
- gdb_stdout, 0);
- if (TYPE_FN_FIELD_STUB (t, block))
- check_stub_method (TYPE_DOMAIN_TYPE (type), j, block);
- demangled_name =
- cplus_demangle (TYPE_FN_FIELD_PHYSNAME (t, block),
- DMGL_ANSI | DMGL_PARAMS);
- if (demangled_name == NULL)
- fprintf_filtered (stream, "<badly mangled name %s>",
- TYPE_FN_FIELD_PHYSNAME (t, block));
- else
- {
- fputs_filtered (demangled_name, stream);
- xfree (demangled_name);
- }
-#endif
- }
}
/* This help function for symtab_symbol_info() prints information
@@ -2835,14 +3068,14 @@ print_msymbol_info (struct minimal_symbol *msymbol)
char *tmp;
if (TARGET_ADDR_BIT <= 32)
- tmp = longest_local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
- & (CORE_ADDR) 0xffffffff,
- "08l");
+ tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
+ & (CORE_ADDR) 0xffffffff,
+ "08l");
else
- tmp = longest_local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
- "016l");
+ tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
+ "016l");
printf_filtered ("%s %s\n",
- tmp, SYMBOL_SOURCE_NAME (msymbol));
+ tmp, SYMBOL_PRINT_NAME (msymbol));
}
/* This is the guts of the commands "info functions", "info types", and
@@ -2851,7 +3084,7 @@ print_msymbol_info (struct minimal_symbol *msymbol)
matches.
*/
static void
-symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty)
+symtab_symbol_info (char *regexp, domain_enum kind, int from_tty)
{
static char *classnames[]
=
@@ -2869,7 +3102,7 @@ symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty)
printf_filtered (regexp
? "All %ss matching regular expression \"%s\":\n"
: "All defined %ss:\n",
- classnames[(int) (kind - VARIABLES_NAMESPACE)], regexp);
+ classnames[(int) (kind - VARIABLES_DOMAIN)], regexp);
for (p = symbols; p != NULL; p = p->next)
{
@@ -2901,30 +3134,21 @@ symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty)
static void
variables_info (char *regexp, int from_tty)
{
- symtab_symbol_info (regexp, VARIABLES_NAMESPACE, from_tty);
+ symtab_symbol_info (regexp, VARIABLES_DOMAIN, from_tty);
}
static void
functions_info (char *regexp, int from_tty)
{
- symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty);
+ symtab_symbol_info (regexp, FUNCTIONS_DOMAIN, from_tty);
}
static void
types_info (char *regexp, int from_tty)
{
- symtab_symbol_info (regexp, TYPES_NAMESPACE, from_tty);
-}
-
-#if 0
-/* Tiemann says: "info methods was never implemented." */
-static void
-methods_info (char *regexp)
-{
- symtab_symbol_info (regexp, METHODS_NAMESPACE, 0, from_tty);
+ symtab_symbol_info (regexp, TYPES_DOMAIN, from_tty);
}
-#endif /* 0 */
/* Breakpoint all functions matching regular expression. */
@@ -2941,22 +3165,22 @@ rbreak_command (char *regexp, int from_tty)
struct symbol_search *p;
struct cleanup *old_chain;
- search_symbols (regexp, FUNCTIONS_NAMESPACE, 0, (char **) NULL, &ss);
+ search_symbols (regexp, FUNCTIONS_DOMAIN, 0, (char **) NULL, &ss);
old_chain = make_cleanup_free_search_symbols (ss);
for (p = ss; p != NULL; p = p->next)
{
if (p->msymbol == NULL)
{
- char *string = (char *) alloca (strlen (p->symtab->filename)
- + strlen (SYMBOL_NAME (p->symbol))
- + 4);
+ char *string = alloca (strlen (p->symtab->filename)
+ + strlen (SYMBOL_LINKAGE_NAME (p->symbol))
+ + 4);
strcpy (string, p->symtab->filename);
strcat (string, ":'");
- strcat (string, SYMBOL_NAME (p->symbol));
+ strcat (string, SYMBOL_LINKAGE_NAME (p->symbol));
strcat (string, "'");
break_command (string, from_tty);
- print_symbol_info (FUNCTIONS_NAMESPACE,
+ print_symbol_info (FUNCTIONS_DOMAIN,
p->symtab,
p->symbol,
p->block,
@@ -2964,9 +3188,9 @@ rbreak_command (char *regexp, int from_tty)
}
else
{
- break_command (SYMBOL_NAME (p->msymbol), from_tty);
+ break_command (SYMBOL_LINKAGE_NAME (p->msymbol), from_tty);
printf_filtered ("<function, no debug info> %s;\n",
- SYMBOL_SOURCE_NAME (p->msymbol));
+ SYMBOL_PRINT_NAME (p->msymbol));
}
}
@@ -2974,19 +3198,6 @@ rbreak_command (char *regexp, int from_tty)
}
-/* Return Nonzero if block a is lexically nested within block b,
- or if a and b have the same pc range.
- Return zero otherwise. */
-int
-contained_in (struct block *a, struct block *b)
-{
- if (!a || !b)
- return 0;
- return BLOCK_START (a) >= BLOCK_START (b)
- && BLOCK_END (a) <= BLOCK_END (b);
-}
-
-
/* Helper routine for make_symbol_completion_list. */
static int return_val_size;
@@ -2994,17 +3205,8 @@ static int return_val_index;
static char **return_val;
#define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
- do { \
- if (SYMBOL_DEMANGLED_NAME (symbol) != NULL) \
- /* Put only the mangled name on the list. */ \
- /* Advantage: "b foo<TAB>" completes to "b foo(int, int)" */ \
- /* Disadvantage: "b foo__i<TAB>" doesn't complete. */ \
completion_list_add_name \
- (SYMBOL_DEMANGLED_NAME (symbol), (sym_text), (len), (text), (word)); \
- else \
- completion_list_add_name \
- (SYMBOL_NAME (symbol), (sym_text), (len), (text), (word)); \
- } while (0)
+ (SYMBOL_NATURAL_NAME (symbol), (sym_text), (len), (text), (word))
/* Test to see if the symbol specified by SYMNAME (which is already
demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
@@ -3059,6 +3261,112 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
}
}
+/* ObjC: In case we are completing on a selector, look as the msymbol
+ again and feed all the selectors into the mill. */
+
+static void
+completion_list_objc_symbol (struct minimal_symbol *msymbol, char *sym_text,
+ int sym_text_len, char *text, char *word)
+{
+ static char *tmp = NULL;
+ static unsigned int tmplen = 0;
+
+ char *method, *category, *selector;
+ char *tmp2 = NULL;
+
+ method = SYMBOL_NATURAL_NAME (msymbol);
+
+ /* Is it a method? */
+ if ((method[0] != '-') && (method[0] != '+'))
+ return;
+
+ if (sym_text[0] == '[')
+ /* Complete on shortened method method. */
+ completion_list_add_name (method + 1, sym_text, sym_text_len, text, word);
+
+ while ((strlen (method) + 1) >= tmplen)
+ {
+ if (tmplen == 0)
+ tmplen = 1024;
+ else
+ tmplen *= 2;
+ tmp = xrealloc (tmp, tmplen);
+ }
+ selector = strchr (method, ' ');
+ if (selector != NULL)
+ selector++;
+
+ category = strchr (method, '(');
+
+ if ((category != NULL) && (selector != NULL))
+ {
+ memcpy (tmp, method, (category - method));
+ tmp[category - method] = ' ';
+ memcpy (tmp + (category - method) + 1, selector, strlen (selector) + 1);
+ completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
+ if (sym_text[0] == '[')
+ completion_list_add_name (tmp + 1, sym_text, sym_text_len, text, word);
+ }
+
+ if (selector != NULL)
+ {
+ /* Complete on selector only. */
+ strcpy (tmp, selector);
+ tmp2 = strchr (tmp, ']');
+ if (tmp2 != NULL)
+ *tmp2 = '\0';
+
+ completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
+ }
+}
+
+/* Break the non-quoted text based on the characters which are in
+ symbols. FIXME: This should probably be language-specific. */
+
+static char *
+language_search_unquoted_string (char *text, char *p)
+{
+ for (; p > text; --p)
+ {
+ if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+ continue;
+ else
+ {
+ if ((current_language->la_language == language_objc))
+ {
+ if (p[-1] == ':') /* might be part of a method name */
+ continue;
+ else if (p[-1] == '[' && (p[-2] == '-' || p[-2] == '+'))
+ p -= 2; /* beginning of a method name */
+ else if (p[-1] == ' ' || p[-1] == '(' || p[-1] == ')')
+ { /* might be part of a method name */
+ char *t = p;
+
+ /* Seeing a ' ' or a '(' is not conclusive evidence
+ that we are in the middle of a method name. However,
+ finding "-[" or "+[" should be pretty un-ambiguous.
+ Unfortunately we have to find it now to decide. */
+
+ while (t > text)
+ if (isalnum (t[-1]) || t[-1] == '_' ||
+ t[-1] == ' ' || t[-1] == ':' ||
+ t[-1] == '(' || t[-1] == ')')
+ --t;
+ else
+ break;
+
+ if (t[-1] == '[' && (t[-2] == '-' || t[-2] == '+'))
+ p = t - 2; /* method name detected */
+ /* else we leave with p unchanged */
+ }
+ }
+ break;
+ }
+ }
+ return p;
+}
+
+
/* Return a NULL terminated array of all symbols (regardless of class)
which begin by matching TEXT. If the answer is no symbols, then
the return value is an array which contains only a NULL pointer.
@@ -3069,13 +3377,14 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
char **
make_symbol_completion_list (char *text, char *word)
{
- register struct symbol *sym;
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct minimal_symbol *msymbol;
- register struct objfile *objfile;
- register struct block *b, *surrounding_static_block = 0;
- register int i, j;
+ struct symbol *sym;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct minimal_symbol *msymbol;
+ struct objfile *objfile;
+ struct block *b, *surrounding_static_block = 0;
+ struct dict_iterator iter;
+ int j;
struct partial_symbol **psym;
/* The symbol we are completing on. Points in same buffer as text. */
char *sym_text;
@@ -3181,12 +3490,14 @@ make_symbol_completion_list (char *text, char *word)
{
QUIT;
COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word);
+
+ completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, word);
}
/* Search upwards from currently selected frame (so that we can
complete on local vars. */
- for (b = get_selected_block (); b != NULL; b = BLOCK_SUPERBLOCK (b))
+ for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
{
if (!BLOCK_SUPERBLOCK (b))
{
@@ -3196,8 +3507,9 @@ make_symbol_completion_list (char *text, char *word)
/* Also catch fields of types defined in this places which match our
text string. Only complete on types visible from current context. */
- ALL_BLOCK_SYMBOLS (b, i, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
+ QUIT;
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
{
@@ -3226,7 +3538,7 @@ make_symbol_completion_list (char *text, char *word)
{
QUIT;
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
- ALL_BLOCK_SYMBOLS (b, i, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
}
@@ -3239,7 +3551,7 @@ make_symbol_completion_list (char *text, char *word)
/* Don't do this block twice. */
if (b == surrounding_static_block)
continue;
- ALL_BLOCK_SYMBOLS (b, i, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
}
@@ -3254,10 +3566,10 @@ make_symbol_completion_list (char *text, char *word)
char **
make_file_symbol_completion_list (char *text, char *word, char *srcfile)
{
- register struct symbol *sym;
- register struct symtab *s;
- register struct block *b;
- register int i;
+ struct symbol *sym;
+ struct symtab *s;
+ struct block *b;
+ struct dict_iterator iter;
/* The symbol we are completing on. Points in same buffer as text. */
char *sym_text;
/* Length of sym_text. */
@@ -3303,16 +3615,8 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile)
}
else
{
- /* It is not a quoted string. Break it based on the characters
- which are in symbols. */
- while (p > text)
- {
- if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
- --p;
- else
- break;
- }
- sym_text = p;
+ /* Not a quoted string. */
+ sym_text = language_search_unquoted_string (text, p);
}
}
@@ -3344,13 +3648,13 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile)
symbols which match. */
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
- ALL_BLOCK_SYMBOLS (b, i, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
}
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
- ALL_BLOCK_SYMBOLS (b, i, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
}
@@ -3425,9 +3729,9 @@ not_interesting_fname (const char *fname)
char **
make_source_files_completion_list (char *text, char *word)
{
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct objfile *objfile;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct objfile *objfile;
int first = 1;
int list_alloced = 1;
int list_used = 0;
@@ -3591,192 +3895,78 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
return func_addr <= pc && pc < sal.end;
}
+/* Given PC at the function's start address, attempt to find the
+ prologue end using SAL information. Return zero if the skip fails.
-/* Begin overload resolution functions */
-/* Helper routine for make_symbol_completion_list. */
-
-static int sym_return_val_size;
-static int sym_return_val_index;
-static struct symbol **sym_return_val;
-
-/* Test to see if the symbol specified by SYMNAME (which is already
- demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
- characters. If so, add it to the current completion list. */
-
-static void
-overload_list_add_symbol (struct symbol *sym, char *oload_name)
-{
- int newsize;
- int i;
+ A non-optimized prologue traditionally has one SAL for the function
+ and a second for the function body. A single line function has
+ them both pointing at the same line.
- /* Get the demangled name without parameters */
- char *sym_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ARM | DMGL_ANSI);
- if (!sym_name)
- {
- sym_name = (char *) xmalloc (strlen (SYMBOL_NAME (sym)) + 1);
- strcpy (sym_name, SYMBOL_NAME (sym));
- }
-
- /* skip symbols that cannot match */
- if (strcmp (sym_name, oload_name) != 0)
- {
- xfree (sym_name);
- return;
- }
+ An optimized prologue is similar but the prologue may contain
+ instructions (SALs) from the instruction body. Need to skip those
+ while not getting into the function body.
- /* If there is no type information, we can't do anything, so skip */
- if (SYMBOL_TYPE (sym) == NULL)
- return;
+ The functions end point and an increasing SAL line are used as
+ indicators of the prologue's endpoint.
- /* skip any symbols that we've already considered. */
- for (i = 0; i < sym_return_val_index; ++i)
- if (!strcmp (SYMBOL_NAME (sym), SYMBOL_NAME (sym_return_val[i])))
- return;
+ This code is based on the function refine_prologue_limit (versions
+ found in both ia64 and ppc). */
- /* We have a match for an overload instance, so add SYM to the current list
- * of overload instances */
- if (sym_return_val_index + 3 > sym_return_val_size)
- {
- newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *);
- sym_return_val = (struct symbol **) xrealloc ((char *) sym_return_val, newsize);
- }
- sym_return_val[sym_return_val_index++] = sym;
- sym_return_val[sym_return_val_index] = NULL;
-
- xfree (sym_name);
-}
-
-/* Return a null-terminated list of pointers to function symbols that
- * match name of the supplied symbol FSYM.
- * This is used in finding all overloaded instances of a function name.
- * This has been modified from make_symbol_completion_list. */
-
-
-struct symbol **
-make_symbol_overload_list (struct symbol *fsym)
+CORE_ADDR
+skip_prologue_using_sal (CORE_ADDR func_addr)
{
- register struct symbol *sym;
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct objfile *objfile;
- register struct block *b, *surrounding_static_block = 0;
- register int i;
- /* The name we are completing on. */
- char *oload_name = NULL;
- /* Length of name. */
- int oload_name_len = 0;
+ struct symtab_and_line prologue_sal;
+ CORE_ADDR start_pc;
+ CORE_ADDR end_pc;
- /* Look for the symbol we are supposed to complete on.
- * FIXME: This should be language-specific. */
+ /* Get an initial range for the function. */
+ find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
+ start_pc += FUNCTION_START_OFFSET;
- oload_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_ARM | DMGL_ANSI);
- if (!oload_name)
+ prologue_sal = find_pc_line (start_pc, 0);
+ if (prologue_sal.line != 0)
{
- oload_name = (char *) xmalloc (strlen (SYMBOL_NAME (fsym)) + 1);
- strcpy (oload_name, SYMBOL_NAME (fsym));
- }
- oload_name_len = strlen (oload_name);
-
- sym_return_val_size = 100;
- sym_return_val_index = 0;
- sym_return_val = (struct symbol **) xmalloc ((sym_return_val_size + 1) * sizeof (struct symbol *));
- sym_return_val[0] = NULL;
-
- /* Look through the partial symtabs for all symbols which begin
- by matching OLOAD_NAME. Make sure we read that symbol table in. */
-
- ALL_PSYMTABS (objfile, ps)
- {
- struct partial_symbol **psym;
-
- /* If the psymtab's been read in we'll get it when we search
- through the blockvector. */
- if (ps->readin)
- continue;
-
- for (psym = objfile->global_psymbols.list + ps->globals_offset;
- psym < (objfile->global_psymbols.list + ps->globals_offset
- + ps->n_global_syms);
- psym++)
- {
- /* If interrupted, then quit. */
- QUIT;
- /* This will cause the symbol table to be read if it has not yet been */
- s = PSYMTAB_TO_SYMTAB (ps);
- }
-
- for (psym = objfile->static_psymbols.list + ps->statics_offset;
- psym < (objfile->static_psymbols.list + ps->statics_offset
- + ps->n_static_syms);
- psym++)
- {
- QUIT;
- /* This will cause the symbol table to be read if it has not yet been */
- s = PSYMTAB_TO_SYMTAB (ps);
- }
- }
-
- /* Search upwards from currently selected frame (so that we can
- complete on local vars. */
-
- for (b = get_selected_block (); b != NULL; b = BLOCK_SUPERBLOCK (b))
- {
- if (!BLOCK_SUPERBLOCK (b))
+ while (prologue_sal.end < end_pc)
{
- surrounding_static_block = b; /* For elimination of dups */
- }
-
- /* Also catch fields of types defined in this places which match our
- text string. Only complete on types visible from current context. */
+ struct symtab_and_line sal;
- ALL_BLOCK_SYMBOLS (b, i, sym)
- {
- overload_list_add_symbol (sym, oload_name);
+ sal = find_pc_line (prologue_sal.end, 0);
+ if (sal.line == 0)
+ break;
+ /* Assume that a consecutive SAL for the same (or larger)
+ line mark the prologue -> body transition. */
+ if (sal.line >= prologue_sal.line)
+ break;
+ /* The case in which compiler's optimizer/scheduler has
+ moved instructions into the prologue. We look ahead in
+ the function looking for address ranges whose
+ corresponding line number is less the first one that we
+ found for the function. This is more conservative then
+ refine_prologue_limit which scans a large number of SALs
+ looking for any in the prologue */
+ prologue_sal = sal;
}
}
-
- /* Go through the symtabs and check the externs and statics for
- symbols which match. */
-
- ALL_SYMTABS (objfile, s)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
- ALL_BLOCK_SYMBOLS (b, i, sym)
- {
- overload_list_add_symbol (sym, oload_name);
- }
- }
-
- ALL_SYMTABS (objfile, s)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
- /* Don't do this block twice. */
- if (b == surrounding_static_block)
- continue;
- ALL_BLOCK_SYMBOLS (b, i, sym)
- {
- overload_list_add_symbol (sym, oload_name);
- }
- }
-
- xfree (oload_name);
-
- return (sym_return_val);
+ return prologue_sal.end;
}
-
-/* End of overload resolution functions */
struct symtabs_and_lines
decode_line_spec (char *string, int funfirstline)
{
struct symtabs_and_lines sals;
+ struct symtab_and_line cursal;
+
if (string == 0)
error ("Empty line specification.");
+
+ /* We use whatever is set as the current source line. We do not try
+ and get a default or it will recursively call us! */
+ cursal = get_current_source_symtab_and_line ();
+
sals = decode_line_1 (&string, funfirstline,
- current_source_symtab, current_source_line,
- (char ***) NULL);
+ cursal.symtab, cursal.line,
+ (char ***) NULL, NULL);
+
if (*string)
error ("Junk at end of line specification: %s", string);
return sals;
@@ -3833,13 +4023,6 @@ _initialize_symtab (void)
add_info ("types", types_info,
"All type names, or those matching REGEXP.");
-#if 0
- add_info ("methods", methods_info,
- "All method names, or those matching REGEXP::REGEXP.\n\
-If the class qualifier is omitted, it is assumed to be the current scope.\n\
-If the first REGEXP is omitted, then all methods matching the second REGEXP\n\
-are listed.");
-#endif
add_info ("sources", sources_info,
"Source files in the program.");
diff --git a/contrib/gdb/gdb/target.c b/contrib/gdb/gdb/target.c
index d5f205f..ff47ac1 100644
--- a/contrib/gdb/gdb/target.c
+++ b/contrib/gdb/gdb/target.c
@@ -1,7 +1,8 @@
/* Select target systems and architectures at runtime for GDB.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002
- Free Software Foundation, Inc.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
Contributed by Cygnus Support.
This file is part of GDB.
@@ -35,23 +36,21 @@
#include "dcache.h"
#include <signal.h>
#include "regcache.h"
-
-extern int errno;
+#include "gdb_assert.h"
+#include "gdbcore.h"
static void target_info (char *, int);
-static void cleanup_target (struct target_ops *);
-
static void maybe_kill_then_create_inferior (char *, char *, char **);
-static void default_clone_and_follow_inferior (int, int *);
-
static void maybe_kill_then_attach (char *, int);
static void kill_or_be_killed (int);
static void default_terminal_info (char *, int);
+static int default_region_size_ok_for_hw_watchpoint (int);
+
static int nosymbol (char *, CORE_ADDR *);
static void tcomplain (void);
@@ -62,17 +61,21 @@ static int return_zero (void);
static int return_one (void);
+static int return_minus_one (void);
+
void target_ignore (void);
static void target_command (char *, int);
static struct target_ops *find_default_run_target (char *);
-static void update_current_target (void);
-
static void nosupport_runtime (void);
-static void normal_target_post_startup_inferior (ptid_t ptid);
+static LONGEST default_xfer_partial (struct target_ops *ops,
+ enum target_object object,
+ const char *annex, void *readbuf,
+ const void *writebuf,
+ ULONGEST offset, LONGEST len);
/* Transfer LEN bytes between target address MEMADDR and GDB address
MYADDR. Returns 0 for success, errno code for failure (which
@@ -80,8 +83,8 @@ static void normal_target_post_startup_inferior (ptid_t ptid);
partial transfers, try either target_read_memory_partial or
target_write_memory_partial). */
-static int
-target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write);
+static int target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write);
static void init_dummy_target (void);
@@ -93,6 +96,8 @@ static void debug_to_attach (char *, int);
static void debug_to_detach (char *, int);
+static void debug_to_disconnect (char *, int);
+
static void debug_to_resume (ptid_t, int, enum target_signal);
static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *);
@@ -103,9 +108,8 @@ static void debug_to_store_registers (int);
static void debug_to_prepare_to_store (void);
-static int
-debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct mem_attrib *,
- struct target_ops *);
+static int debug_to_xfer_memory (CORE_ADDR, char *, int, int,
+ struct mem_attrib *, struct target_ops *);
static void debug_to_files_info (struct target_ops *);
@@ -113,12 +117,30 @@ static int debug_to_insert_breakpoint (CORE_ADDR, char *);
static int debug_to_remove_breakpoint (CORE_ADDR, char *);
+static int debug_to_can_use_hw_breakpoint (int, int, int);
+
+static int debug_to_insert_hw_breakpoint (CORE_ADDR, char *);
+
+static int debug_to_remove_hw_breakpoint (CORE_ADDR, char *);
+
+static int debug_to_insert_watchpoint (CORE_ADDR, int, int);
+
+static int debug_to_remove_watchpoint (CORE_ADDR, int, int);
+
+static int debug_to_stopped_by_watchpoint (void);
+
+static CORE_ADDR debug_to_stopped_data_address (void);
+
+static int debug_to_region_size_ok_for_hw_watchpoint (int);
+
static void debug_to_terminal_init (void);
static void debug_to_terminal_inferior (void);
static void debug_to_terminal_ours_for_output (void);
+static void debug_to_terminal_save_ours (void);
+
static void debug_to_terminal_ours (void);
static void debug_to_terminal_info (char *, int);
@@ -141,8 +163,6 @@ static int debug_to_thread_alive (ptid_t);
static void debug_to_stop (void);
-static int debug_to_query (int /*char */ , char *, char *, int *);
-
/* Pointer to array of target architecture structures; the size of the
array; the current index into the array; the allocated size of the
array. */
@@ -159,7 +179,7 @@ static struct target_ops dummy_target;
/* Top of target stack. */
-struct target_stack_item *target_stack;
+static struct target_ops *target_stack;
/* The target structure we are currently using to talk to a process
or file or whatever "inferior" we have. */
@@ -185,7 +205,6 @@ DCACHE *target_dcache;
/* The user just typed 'target' without the name of a target. */
-/* ARGSUSED */
static void
target_command (char *arg, int from_tty)
{
@@ -198,6 +217,10 @@ target_command (char *arg, int from_tty)
void
add_target (struct target_ops *t)
{
+ /* Provide default values for all "must have" methods. */
+ if (t->to_xfer_partial == NULL)
+ t->to_xfer_partial = default_xfer_partial;
+
if (!target_structs)
{
target_struct_allocsize = DEFAULT_ALLOCSIZE;
@@ -212,7 +235,6 @@ add_target (struct target_ops *t)
target_struct_allocsize * sizeof (*target_structs));
}
target_structs[target_struct_size++] = t;
-/* cleanup_target (t); */
if (targetlist == NULL)
add_prefix_cmd ("target", class_run, target_command,
@@ -239,7 +261,6 @@ target_load (char *arg, int from_tty)
(*current_target.to_load) (arg, from_tty);
}
-/* ARGSUSED */
static int
nomemory (CORE_ADDR memaddr, char *myaddr, int len, int write,
struct target_ops *t)
@@ -261,14 +282,12 @@ noprocess (void)
error ("You can't do that without a process to debug.");
}
-/* ARGSUSED */
static int
nosymbol (char *name, CORE_ADDR *addrp)
{
return 1; /* Symbol does not exist in target env */
}
-/* ARGSUSED */
static void
nosupport_runtime (void)
{
@@ -279,7 +298,6 @@ nosupport_runtime (void)
}
-/* ARGSUSED */
static void
default_terminal_info (char *args, int from_tty)
{
@@ -327,22 +345,121 @@ maybe_kill_then_create_inferior (char *exec, char *args, char **env)
target_create_inferior (exec, args, env);
}
-static void
-default_clone_and_follow_inferior (int child_pid, int *followed_child)
-{
- target_clone_and_follow_inferior (child_pid, followed_child);
-}
+/* Go through the target stack from top to bottom, copying over zero
+ entries in current_target, then filling in still empty entries. In
+ effect, we are doing class inheritance through the pushed target
+ vectors.
-/* Clean up a target struct so it no longer has any zero pointers in it.
- We default entries, at least to stubs that print error messages. */
+ NOTE: cagney/2003-10-17: The problem with this inheritance, as it
+ is currently implemented, is that it discards any knowledge of
+ which target an inherited method originally belonged to.
+ Consequently, new new target methods should instead explicitly and
+ locally search the target stack for the target that can handle the
+ request. */
static void
-cleanup_target (struct target_ops *t)
+update_current_target (void)
{
+ struct target_ops *t;
+
+ /* First, reset curren'ts contents. */
+ memset (&current_target, 0, sizeof (current_target));
+
+#define INHERIT(FIELD, TARGET) \
+ if (!current_target.FIELD) \
+ current_target.FIELD = (TARGET)->FIELD
+
+ for (t = target_stack; t; t = t->beneath)
+ {
+ INHERIT (to_shortname, t);
+ INHERIT (to_longname, t);
+ INHERIT (to_doc, t);
+ INHERIT (to_open, t);
+ INHERIT (to_close, t);
+ INHERIT (to_attach, t);
+ INHERIT (to_post_attach, t);
+ INHERIT (to_detach, t);
+ INHERIT (to_disconnect, t);
+ INHERIT (to_resume, t);
+ INHERIT (to_wait, t);
+ INHERIT (to_post_wait, t);
+ INHERIT (to_fetch_registers, t);
+ INHERIT (to_store_registers, t);
+ INHERIT (to_prepare_to_store, t);
+ INHERIT (to_xfer_memory, t);
+ INHERIT (to_files_info, t);
+ INHERIT (to_insert_breakpoint, t);
+ INHERIT (to_remove_breakpoint, t);
+ INHERIT (to_can_use_hw_breakpoint, t);
+ INHERIT (to_insert_hw_breakpoint, t);
+ INHERIT (to_remove_hw_breakpoint, t);
+ INHERIT (to_insert_watchpoint, t);
+ INHERIT (to_remove_watchpoint, t);
+ INHERIT (to_stopped_data_address, t);
+ INHERIT (to_stopped_by_watchpoint, t);
+ INHERIT (to_have_continuable_watchpoint, t);
+ INHERIT (to_region_size_ok_for_hw_watchpoint, t);
+ INHERIT (to_terminal_init, t);
+ INHERIT (to_terminal_inferior, t);
+ INHERIT (to_terminal_ours_for_output, t);
+ INHERIT (to_terminal_ours, t);
+ INHERIT (to_terminal_save_ours, t);
+ INHERIT (to_terminal_info, t);
+ INHERIT (to_kill, t);
+ INHERIT (to_load, t);
+ INHERIT (to_lookup_symbol, t);
+ INHERIT (to_create_inferior, t);
+ INHERIT (to_post_startup_inferior, t);
+ INHERIT (to_acknowledge_created_inferior, t);
+ INHERIT (to_insert_fork_catchpoint, t);
+ INHERIT (to_remove_fork_catchpoint, t);
+ INHERIT (to_insert_vfork_catchpoint, t);
+ INHERIT (to_remove_vfork_catchpoint, t);
+ INHERIT (to_follow_fork, t);
+ INHERIT (to_insert_exec_catchpoint, t);
+ INHERIT (to_remove_exec_catchpoint, t);
+ INHERIT (to_reported_exec_events_per_exec_call, t);
+ INHERIT (to_has_exited, t);
+ INHERIT (to_mourn_inferior, t);
+ INHERIT (to_can_run, t);
+ INHERIT (to_notice_signals, t);
+ INHERIT (to_thread_alive, t);
+ INHERIT (to_find_new_threads, t);
+ INHERIT (to_pid_to_str, t);
+ INHERIT (to_extra_thread_info, t);
+ INHERIT (to_stop, t);
+ /* Do not inherit to_xfer_partial. */
+ INHERIT (to_rcmd, t);
+ INHERIT (to_enable_exception_callback, t);
+ INHERIT (to_get_current_exception_event, t);
+ INHERIT (to_pid_to_exec_file, t);
+ INHERIT (to_stratum, t);
+ INHERIT (to_has_all_memory, t);
+ INHERIT (to_has_memory, t);
+ INHERIT (to_has_stack, t);
+ INHERIT (to_has_registers, t);
+ INHERIT (to_has_execution, t);
+ INHERIT (to_has_thread_control, t);
+ INHERIT (to_sections, t);
+ INHERIT (to_sections_end, t);
+ INHERIT (to_can_async_p, t);
+ INHERIT (to_is_async_p, t);
+ INHERIT (to_async, t);
+ INHERIT (to_async_mask_value, t);
+ INHERIT (to_find_memory_regions, t);
+ INHERIT (to_make_corefile_notes, t);
+ INHERIT (to_get_thread_local_address, t);
+ INHERIT (to_magic, t);
+ }
+#undef INHERIT
+
+ /* Clean up a target struct so it no longer has any zero pointers in
+ it. Some entries are defaulted to a method that print an error,
+ others are hard-wired to a standard recursive default. */
#define de_fault(field, value) \
- if (!t->field) \
- t->field = value
+ if (!current_target.field) \
+ current_target.field = value
de_fault (to_open,
(void (*) (char *, int))
@@ -355,14 +472,12 @@ cleanup_target (struct target_ops *t)
de_fault (to_post_attach,
(void (*) (int))
target_ignore);
- de_fault (to_require_attach,
- maybe_kill_then_attach);
de_fault (to_detach,
(void (*) (char *, int))
target_ignore);
- de_fault (to_require_detach,
- (void (*) (int, char *, int))
- target_ignore);
+ de_fault (to_disconnect,
+ (void (*) (char *, int))
+ tcomplain);
de_fault (to_resume,
(void (*) (ptid_t, int, enum target_signal))
noprocess);
@@ -391,6 +506,29 @@ cleanup_target (struct target_ops *t)
memory_insert_breakpoint);
de_fault (to_remove_breakpoint,
memory_remove_breakpoint);
+ de_fault (to_can_use_hw_breakpoint,
+ (int (*) (int, int, int))
+ return_zero);
+ de_fault (to_insert_hw_breakpoint,
+ (int (*) (CORE_ADDR, char *))
+ return_minus_one);
+ de_fault (to_remove_hw_breakpoint,
+ (int (*) (CORE_ADDR, char *))
+ return_minus_one);
+ de_fault (to_insert_watchpoint,
+ (int (*) (CORE_ADDR, int, int))
+ return_minus_one);
+ de_fault (to_remove_watchpoint,
+ (int (*) (CORE_ADDR, int, int))
+ return_minus_one);
+ de_fault (to_stopped_by_watchpoint,
+ (int (*) (void))
+ return_zero);
+ de_fault (to_stopped_data_address,
+ (CORE_ADDR (*) (void))
+ return_zero);
+ de_fault (to_region_size_ok_for_hw_watchpoint,
+ default_region_size_ok_for_hw_watchpoint);
de_fault (to_terminal_init,
(void (*) (void))
target_ignore);
@@ -403,6 +541,9 @@ cleanup_target (struct target_ops *t)
de_fault (to_terminal_ours,
(void (*) (void))
target_ignore);
+ de_fault (to_terminal_save_ours,
+ (void (*) (void))
+ target_ignore);
de_fault (to_terminal_info,
default_terminal_info);
de_fault (to_kill,
@@ -422,11 +563,6 @@ cleanup_target (struct target_ops *t)
de_fault (to_acknowledge_created_inferior,
(void (*) (int))
target_ignore);
- de_fault (to_clone_and_follow_inferior,
- default_clone_and_follow_inferior);
- de_fault (to_post_follow_inferior_by_clone,
- (void (*) (void))
- target_ignore);
de_fault (to_insert_fork_catchpoint,
(int (*) (int))
tcomplain);
@@ -439,17 +575,8 @@ cleanup_target (struct target_ops *t)
de_fault (to_remove_vfork_catchpoint,
(int (*) (int))
tcomplain);
- de_fault (to_has_forked,
- (int (*) (int, int *))
- return_zero);
- de_fault (to_has_vforked,
- (int (*) (int, int *))
- return_zero);
- de_fault (to_can_follow_vfork_prior_to_exec,
- (int (*) (void))
- return_zero);
- de_fault (to_post_follow_vfork,
- (void (*) (int, int, int, int))
+ de_fault (to_follow_fork,
+ (int (*) (int))
target_ignore);
de_fault (to_insert_exec_catchpoint,
(int (*) (int))
@@ -457,15 +584,9 @@ cleanup_target (struct target_ops *t)
de_fault (to_remove_exec_catchpoint,
(int (*) (int))
tcomplain);
- de_fault (to_has_execd,
- (int (*) (int, char **))
- return_zero);
de_fault (to_reported_exec_events_per_exec_call,
(int (*) (void))
return_one);
- de_fault (to_has_syscall_event,
- (int (*) (int, enum target_waitkind *, int *))
- return_zero);
de_fault (to_has_exited,
(int (*) (int, int, int *))
return_zero);
@@ -489,6 +610,7 @@ cleanup_target (struct target_ops *t)
de_fault (to_stop,
(void (*) (void))
target_ignore);
+ current_target.to_xfer_partial = default_xfer_partial;
de_fault (to_rcmd,
(void (*) (char *, struct ui_file *))
tcomplain);
@@ -511,109 +633,11 @@ cleanup_target (struct target_ops *t)
(void (*) (void (*) (enum inferior_event_type, void*), void*))
tcomplain);
#undef de_fault
-}
-/* Go through the target stack from top to bottom, copying over zero entries in
- current_target. In effect, we are doing class inheritance through the
- pushed target vectors. */
-
-static void
-update_current_target (void)
-{
- struct target_stack_item *item;
- struct target_ops *t;
-
- /* First, reset current_target */
- memset (&current_target, 0, sizeof current_target);
-
- for (item = target_stack; item; item = item->next)
- {
- t = item->target_ops;
-
-#define INHERIT(FIELD, TARGET) \
- if (!current_target.FIELD) \
- current_target.FIELD = TARGET->FIELD
-
- INHERIT (to_shortname, t);
- INHERIT (to_longname, t);
- INHERIT (to_doc, t);
- INHERIT (to_open, t);
- INHERIT (to_close, t);
- INHERIT (to_attach, t);
- INHERIT (to_post_attach, t);
- INHERIT (to_require_attach, t);
- INHERIT (to_detach, t);
- INHERIT (to_require_detach, t);
- INHERIT (to_resume, t);
- INHERIT (to_wait, t);
- INHERIT (to_post_wait, t);
- INHERIT (to_fetch_registers, t);
- INHERIT (to_store_registers, t);
- INHERIT (to_prepare_to_store, t);
- INHERIT (to_xfer_memory, t);
- INHERIT (to_files_info, t);
- INHERIT (to_insert_breakpoint, t);
- INHERIT (to_remove_breakpoint, t);
- INHERIT (to_terminal_init, t);
- INHERIT (to_terminal_inferior, t);
- INHERIT (to_terminal_ours_for_output, t);
- INHERIT (to_terminal_ours, t);
- INHERIT (to_terminal_info, t);
- INHERIT (to_kill, t);
- INHERIT (to_load, t);
- INHERIT (to_lookup_symbol, t);
- INHERIT (to_create_inferior, t);
- INHERIT (to_post_startup_inferior, t);
- INHERIT (to_acknowledge_created_inferior, t);
- INHERIT (to_clone_and_follow_inferior, t);
- INHERIT (to_post_follow_inferior_by_clone, t);
- INHERIT (to_insert_fork_catchpoint, t);
- INHERIT (to_remove_fork_catchpoint, t);
- INHERIT (to_insert_vfork_catchpoint, t);
- INHERIT (to_remove_vfork_catchpoint, t);
- INHERIT (to_has_forked, t);
- INHERIT (to_has_vforked, t);
- INHERIT (to_can_follow_vfork_prior_to_exec, t);
- INHERIT (to_post_follow_vfork, t);
- INHERIT (to_insert_exec_catchpoint, t);
- INHERIT (to_remove_exec_catchpoint, t);
- INHERIT (to_has_execd, t);
- INHERIT (to_reported_exec_events_per_exec_call, t);
- INHERIT (to_has_syscall_event, t);
- INHERIT (to_has_exited, t);
- INHERIT (to_mourn_inferior, t);
- INHERIT (to_can_run, t);
- INHERIT (to_notice_signals, t);
- INHERIT (to_thread_alive, t);
- INHERIT (to_find_new_threads, t);
- INHERIT (to_pid_to_str, t);
- INHERIT (to_extra_thread_info, t);
- INHERIT (to_stop, t);
- INHERIT (to_query, t);
- INHERIT (to_rcmd, t);
- INHERIT (to_enable_exception_callback, t);
- INHERIT (to_get_current_exception_event, t);
- INHERIT (to_pid_to_exec_file, t);
- INHERIT (to_stratum, t);
- INHERIT (DONT_USE, t);
- INHERIT (to_has_all_memory, t);
- INHERIT (to_has_memory, t);
- INHERIT (to_has_stack, t);
- INHERIT (to_has_registers, t);
- INHERIT (to_has_execution, t);
- INHERIT (to_has_thread_control, t);
- INHERIT (to_sections, t);
- INHERIT (to_sections_end, t);
- INHERIT (to_can_async_p, t);
- INHERIT (to_is_async_p, t);
- INHERIT (to_async, t);
- INHERIT (to_async_mask_value, t);
- INHERIT (to_find_memory_regions, t);
- INHERIT (to_make_corefile_notes, t);
- INHERIT (to_magic, t);
-
-#undef INHERIT
- }
+ /* Finally, position the target-stack beneath the squashed
+ "current_target". That way code looking for a non-inherited
+ target method can quickly and simply find it. */
+ current_target.beneath = target_stack;
}
/* Push a new target type into the stack of the existing target accessors,
@@ -629,7 +653,7 @@ update_current_target (void)
int
push_target (struct target_ops *t)
{
- struct target_stack_item *cur, *prev, *tmp;
+ struct target_ops **cur;
/* Check magic number. If wrong, it probably means someone changed
the struct definition, but not all the places that initialize one. */
@@ -641,51 +665,37 @@ push_target (struct target_ops *t)
internal_error (__FILE__, __LINE__, "failed internal consistency check");
}
- /* Find the proper stratum to install this target in. */
-
- for (prev = NULL, cur = target_stack; cur; prev = cur, cur = cur->next)
+ /* Find the proper stratum to install this target in. */
+ for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath)
{
- if ((int) (t->to_stratum) >= (int) (cur->target_ops->to_stratum))
+ if ((int) (t->to_stratum) >= (int) (*cur)->to_stratum)
break;
}
- /* If there's already targets at this stratum, remove them. */
-
- if (cur)
- while (t->to_stratum == cur->target_ops->to_stratum)
- {
- /* There's already something on this stratum. Close it off. */
- if (cur->target_ops->to_close)
- (cur->target_ops->to_close) (0);
- if (prev)
- prev->next = cur->next; /* Unchain old target_ops */
- else
- target_stack = cur->next; /* Unchain first on list */
- tmp = cur->next;
- xfree (cur);
- cur = tmp;
- }
+ /* If there's already targets at this stratum, remove them. */
+ /* FIXME: cagney/2003-10-15: I think this should be poping all
+ targets to CUR, and not just those at this stratum level. */
+ while ((*cur) != NULL && t->to_stratum == (*cur)->to_stratum)
+ {
+ /* There's already something at this stratum level. Close it,
+ and un-hook it from the stack. */
+ struct target_ops *tmp = (*cur);
+ (*cur) = (*cur)->beneath;
+ tmp->beneath = NULL;
+ target_close (tmp, 0);
+ }
/* We have removed all targets in our stratum, now add the new one. */
-
- tmp = (struct target_stack_item *)
- xmalloc (sizeof (struct target_stack_item));
- tmp->next = cur;
- tmp->target_ops = t;
-
- if (prev)
- prev->next = tmp;
- else
- target_stack = tmp;
+ t->beneath = (*cur);
+ (*cur) = t;
update_current_target ();
- cleanup_target (&current_target); /* Fill in the gaps */
-
if (targetdebug)
setup_target_debug ();
- return prev != 0;
+ /* Not on top? */
+ return (t != target_stack);
}
/* Remove a target_ops vector from the stack, wherever it may be.
@@ -694,32 +704,35 @@ push_target (struct target_ops *t)
int
unpush_target (struct target_ops *t)
{
- struct target_stack_item *cur, *prev;
-
- if (t->to_close)
- t->to_close (0); /* Let it clean up */
+ struct target_ops **cur;
+ struct target_ops *tmp;
/* Look for the specified target. Note that we assume that a target
can only occur once in the target stack. */
- for (cur = target_stack, prev = NULL; cur; prev = cur, cur = cur->next)
- if (cur->target_ops == t)
- break;
+ for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath)
+ {
+ if ((*cur) == t)
+ break;
+ }
- if (!cur)
+ if ((*cur) == NULL)
return 0; /* Didn't find target_ops, quit now */
- /* Unchain the target */
-
- if (!prev)
- target_stack = cur->next;
- else
- prev->next = cur->next;
+ /* NOTE: cagney/2003-12-06: In '94 the close call was made
+ unconditional by moving it to before the above check that the
+ target was in the target stack (something about "Change the way
+ pushing and popping of targets work to support target overlays
+ and inheritance"). This doesn't make much sense - only open
+ targets should be closed. */
+ target_close (t, 0);
- xfree (cur); /* Release the target_stack_item */
+ /* Unchain the target */
+ tmp = (*cur);
+ (*cur) = (*cur)->beneath;
+ tmp->beneath = NULL;
update_current_target ();
- cleanup_target (&current_target);
return 1;
}
@@ -727,8 +740,8 @@ unpush_target (struct target_ops *t)
void
pop_target (void)
{
- (current_target.to_close) (0); /* Let it clean up */
- if (unpush_target (target_stack->target_ops) == 1)
+ target_close (&current_target, 0); /* Let it clean up */
+ if (unpush_target (target_stack) == 1)
return;
fprintf_unfiltered (gdb_stderr,
@@ -813,6 +826,21 @@ done:
return nbytes_read;
}
+/* Find a section containing ADDR. */
+struct section_table *
+target_section_by_addr (struct target_ops *target, CORE_ADDR addr)
+{
+ struct section_table *secp;
+ for (secp = target->to_sections;
+ secp < target->to_sections_end;
+ secp++)
+ {
+ if (addr >= secp->addr && addr < secp->endaddr)
+ return secp;
+ }
+ return NULL;
+}
+
/* Read LEN bytes of target memory at address MEMADDR, placing the results in
GDB's memory at MYADDR. Returns either 0 for success or an errno value
if any error occurs.
@@ -849,7 +877,6 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
int res;
int done = 0;
struct target_ops *t;
- struct target_stack_item *item;
/* Zero length requests are ok and require no work. */
if (len == 0)
@@ -861,22 +888,15 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
if (!write && trust_readonly)
{
- /* User-settable option, "trust-readonly". If true, then
- memory from any SEC_READONLY bfd section may be read
- directly from the bfd file. */
-
struct section_table *secp;
-
- for (secp = current_target.to_sections;
- secp < current_target.to_sections_end;
- secp++)
- {
- if (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
- & SEC_READONLY)
- if (memaddr >= secp->addr && memaddr < secp->endaddr)
- return xfer_memory (memaddr, myaddr, len, 0,
- attrib, &current_target);
- }
+ /* User-settable option, "trust-readonly-sections". If true,
+ then memory from any SEC_READONLY bfd section may be read
+ directly from the bfd file. */
+ secp = target_section_by_addr (&current_target, memaddr);
+ if (secp != NULL
+ && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
+ & SEC_READONLY))
+ return xfer_memory (memaddr, myaddr, len, 0, attrib, &current_target);
}
/* The quick case is that the top target can handle the transfer. */
@@ -886,9 +906,8 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
/* If res <= 0 then we call it again in the loop. Ah well. */
if (res <= 0)
{
- for (item = target_stack; item; item = item->next)
+ for (t = target_stack; t != NULL; t = t->beneath)
{
- t = item->target_ops;
if (!t->to_has_memory)
continue;
@@ -1056,12 +1075,145 @@ target_write_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err)
return target_xfer_memory_partial (memaddr, buf, len, 1, err);
}
-/* ARGSUSED */
+/* More generic transfers. */
+
+static LONGEST
+default_xfer_partial (struct target_ops *ops, enum target_object object,
+ const char *annex, void *readbuf,
+ const void *writebuf, ULONGEST offset, LONGEST len)
+{
+ if (object == TARGET_OBJECT_MEMORY
+ && ops->to_xfer_memory != NULL)
+ /* If available, fall back to the target's "to_xfer_memory"
+ method. */
+ {
+ int xfered = -1;
+ errno = 0;
+ if (writebuf != NULL)
+ {
+ void *buffer = xmalloc (len);
+ struct cleanup *cleanup = make_cleanup (xfree, buffer);
+ memcpy (buffer, writebuf, len);
+ xfered = ops->to_xfer_memory (offset, buffer, len, 1/*write*/, NULL,
+ ops);
+ do_cleanups (cleanup);
+ }
+ if (readbuf != NULL)
+ xfered = ops->to_xfer_memory (offset, readbuf, len, 0/*read*/, NULL,
+ ops);
+ if (xfered > 0)
+ return xfered;
+ else if (xfered == 0 && errno == 0)
+ /* "to_xfer_memory" uses 0, cross checked against ERRNO as one
+ indication of an error. */
+ return 0;
+ else
+ return -1;
+ }
+ else if (ops->beneath != NULL)
+ return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+ readbuf, writebuf, offset, len);
+ else
+ return -1;
+}
+
+/* Target vector read/write partial wrapper functions.
+
+ NOTE: cagney/2003-10-21: I wonder if having "to_xfer_partial
+ (inbuf, outbuf)", instead of separate read/write methods, make life
+ easier. */
+
+LONGEST
+target_read_partial (struct target_ops *ops,
+ enum target_object object,
+ const char *annex, void *buf,
+ ULONGEST offset, LONGEST len)
+{
+ gdb_assert (ops->to_xfer_partial != NULL);
+ return ops->to_xfer_partial (ops, object, annex, buf, NULL, offset, len);
+}
+
+LONGEST
+target_write_partial (struct target_ops *ops,
+ enum target_object object,
+ const char *annex, const void *buf,
+ ULONGEST offset, LONGEST len)
+{
+ gdb_assert (ops->to_xfer_partial != NULL);
+ return ops->to_xfer_partial (ops, object, annex, NULL, buf, offset, len);
+}
+
+/* Wrappers to perform the full transfer. */
+LONGEST
+target_read (struct target_ops *ops,
+ enum target_object object,
+ const char *annex, void *buf,
+ ULONGEST offset, LONGEST len)
+{
+ LONGEST xfered = 0;
+ while (xfered < len)
+ {
+ LONGEST xfer = target_read_partial (ops, object, annex,
+ (bfd_byte *) buf + xfered,
+ offset + xfered, len - xfered);
+ /* Call an observer, notifying them of the xfer progress? */
+ if (xfer <= 0)
+ /* Call memory_error? */
+ return -1;
+ xfered += xfer;
+ QUIT;
+ }
+ return len;
+}
+
+LONGEST
+target_write (struct target_ops *ops,
+ enum target_object object,
+ const char *annex, const void *buf,
+ ULONGEST offset, LONGEST len)
+{
+ LONGEST xfered = 0;
+ while (xfered < len)
+ {
+ LONGEST xfer = target_write_partial (ops, object, annex,
+ (bfd_byte *) buf + xfered,
+ offset + xfered, len - xfered);
+ /* Call an observer, notifying them of the xfer progress? */
+ if (xfer <= 0)
+ /* Call memory_error? */
+ return -1;
+ xfered += xfer;
+ QUIT;
+ }
+ return len;
+}
+
+/* Memory transfer methods. */
+
+void
+get_target_memory (struct target_ops *ops, CORE_ADDR addr, void *buf,
+ LONGEST len)
+{
+ if (target_read (ops, TARGET_OBJECT_MEMORY, NULL, buf, addr, len)
+ != len)
+ memory_error (EIO, addr);
+}
+
+ULONGEST
+get_target_memory_unsigned (struct target_ops *ops,
+ CORE_ADDR addr, int len)
+{
+ char buf[sizeof (ULONGEST)];
+
+ gdb_assert (len <= sizeof (buf));
+ get_target_memory (ops, addr, buf, len);
+ return extract_unsigned_integer (buf, len);
+}
+
static void
target_info (char *args, int from_tty)
{
struct target_ops *t;
- struct target_stack_item *item;
int has_all_mem = 0;
if (symfile_objfile != NULL)
@@ -1072,10 +1224,8 @@ target_info (char *args, int from_tty)
return;
#endif
- for (item = target_stack; item; item = item->next)
+ for (t = target_stack; t != NULL; t = t->beneath)
{
- t = item->target_ops;
-
if (!t->to_has_memory)
continue;
@@ -1126,9 +1276,19 @@ target_detach (char *args, int from_tty)
}
void
+target_disconnect (char *args, int from_tty)
+{
+ /* Handle any optimized stores to the inferior. */
+#ifdef DO_DEFERRED_STORES
+ DO_DEFERRED_STORES;
+#endif
+ (current_target.to_disconnect) (args, from_tty);
+}
+
+void
target_link (char *modname, CORE_ADDR *t_reloc)
{
- if (STREQ (current_target.to_shortname, "rombug"))
+ if (DEPRECATED_STREQ (current_target.to_shortname, "rombug"))
{
(current_target.to_lookup_symbol) (modname, t_reloc);
if (*t_reloc == 0)
@@ -1188,26 +1348,6 @@ find_default_attach (char *args, int from_tty)
}
void
-find_default_require_attach (char *args, int from_tty)
-{
- struct target_ops *t;
-
- t = find_default_run_target ("require_attach");
- (t->to_require_attach) (args, from_tty);
- return;
-}
-
-void
-find_default_require_detach (int pid, char *args, int from_tty)
-{
- struct target_ops *t;
-
- t = find_default_run_target ("require_detach");
- (t->to_require_detach) (pid, args, from_tty);
- return;
-}
-
-void
find_default_create_inferior (char *exec_file, char *allargs, char **env)
{
struct target_ops *t;
@@ -1217,14 +1357,10 @@ find_default_create_inferior (char *exec_file, char *allargs, char **env)
return;
}
-void
-find_default_clone_and_follow_inferior (int child_pid, int *followed_child)
+static int
+default_region_size_ok_for_hw_watchpoint (int byte_count)
{
- struct target_ops *t;
-
- t = find_default_run_target ("run");
- (t->to_clone_and_follow_inferior) (child_pid, followed_child);
- return;
+ return (byte_count <= TYPE_LENGTH (builtin_type_void_data_ptr));
}
static int
@@ -1239,6 +1375,12 @@ return_one (void)
return 1;
}
+static int
+return_minus_one (void)
+{
+ return -1;
+}
+
/*
* Resize the to_sections pointer. Also make sure that anyone that
* was holding on to an old value of it gets updated.
@@ -1378,16 +1520,7 @@ find_core_target (void)
struct target_ops *
find_target_beneath (struct target_ops *t)
{
- struct target_stack_item *cur;
-
- for (cur = target_stack; cur; cur = cur->next)
- if (cur->target_ops == t)
- break;
-
- if (cur == NULL || cur->next == NULL)
- return NULL;
- else
- return cur->next->target_ops;
+ return t->beneath;
}
@@ -1468,26 +1601,7 @@ normal_pid_to_str (ptid_t ptid)
return buf;
}
-/* Some targets (such as ttrace-based HPUX) don't allow us to request
- notification of inferior events such as fork and vork immediately
- after the inferior is created. (This because of how gdb gets an
- inferior created via invoking a shell to do it. In such a scenario,
- if the shell init file has commands in it, the shell will fork and
- exec for each of those commands, and we will see each such fork
- event. Very bad.)
-
- This function is used by all targets that allow us to request
- notification of forks, etc at inferior creation time; e.g., in
- target_acknowledge_forked_child.
- */
-static void
-normal_target_post_startup_inferior (ptid_t ptid)
-{
- /* This space intentionally left blank. */
-}
-
/* Error-catcher for target_find_memory_regions */
-/* ARGSUSED */
static int dummy_find_memory_regions (int (*ignore1) (), void *ignore2)
{
error ("No target.");
@@ -1495,7 +1609,6 @@ static int dummy_find_memory_regions (int (*ignore1) (), void *ignore2)
}
/* Error-catcher for target_make_corefile_notes */
-/* ARGSUSED */
static char * dummy_make_corefile_notes (bfd *ignore1, int *ignore2)
{
error ("No target.");
@@ -1512,14 +1625,12 @@ init_dummy_target (void)
dummy_target.to_longname = "None";
dummy_target.to_doc = "";
dummy_target.to_attach = find_default_attach;
- dummy_target.to_require_attach = find_default_require_attach;
- dummy_target.to_require_detach = find_default_require_detach;
dummy_target.to_create_inferior = find_default_create_inferior;
- dummy_target.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
dummy_target.to_pid_to_str = normal_pid_to_str;
dummy_target.to_stratum = dummy_stratum;
dummy_target.to_find_memory_regions = dummy_find_memory_regions;
dummy_target.to_make_corefile_notes = dummy_make_corefile_notes;
+ dummy_target.to_xfer_partial = default_xfer_partial;
dummy_target.to_magic = OPS_MAGIC;
}
@@ -1537,11 +1648,19 @@ debug_to_open (char *args, int from_tty)
static void
debug_to_close (int quitting)
{
- debug_target.to_close (quitting);
-
+ target_close (&debug_target, quitting);
fprintf_unfiltered (gdb_stdlog, "target_close (%d)\n", quitting);
}
+void
+target_close (struct target_ops *targ, int quitting)
+{
+ if (targ->to_xclose != NULL)
+ targ->to_xclose (targ, quitting);
+ else if (targ->to_close != NULL)
+ targ->to_close (quitting);
+}
+
static void
debug_to_attach (char *args, int from_tty)
{
@@ -1560,15 +1679,6 @@ debug_to_post_attach (int pid)
}
static void
-debug_to_require_attach (char *args, int from_tty)
-{
- debug_target.to_require_attach (args, from_tty);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_require_attach (%s, %d)\n", args, from_tty);
-}
-
-static void
debug_to_detach (char *args, int from_tty)
{
debug_target.to_detach (args, from_tty);
@@ -1577,12 +1687,12 @@ debug_to_detach (char *args, int from_tty)
}
static void
-debug_to_require_detach (int pid, char *args, int from_tty)
+debug_to_disconnect (char *args, int from_tty)
{
- debug_target.to_require_detach (pid, args, from_tty);
+ debug_target.to_disconnect (args, from_tty);
- fprintf_unfiltered (gdb_stdlog,
- "target_require_detach (%d, %s, %d)\n", pid, args, from_tty);
+ fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n",
+ args, from_tty);
}
static void
@@ -1653,31 +1763,47 @@ debug_to_post_wait (ptid_t ptid, int status)
}
static void
+debug_print_register (const char * func, int regno)
+{
+ fprintf_unfiltered (gdb_stdlog, "%s ", func);
+ if (regno >= 0 && regno < NUM_REGS + NUM_PSEUDO_REGS
+ && REGISTER_NAME (regno) != NULL && REGISTER_NAME (regno)[0] != '\0')
+ fprintf_unfiltered (gdb_stdlog, "(%s)", REGISTER_NAME (regno));
+ else
+ fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
+ if (regno >= 0)
+ {
+ int i;
+ unsigned char buf[MAX_REGISTER_SIZE];
+ deprecated_read_register_gen (regno, buf);
+ fprintf_unfiltered (gdb_stdlog, " = ");
+ for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i++)
+ {
+ fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
+ }
+ if (DEPRECATED_REGISTER_RAW_SIZE (regno) <= sizeof (LONGEST))
+ {
+ fprintf_unfiltered (gdb_stdlog, " 0x%s %s",
+ paddr_nz (read_register (regno)),
+ paddr_d (read_register (regno)));
+ }
+ }
+ fprintf_unfiltered (gdb_stdlog, "\n");
+}
+
+static void
debug_to_fetch_registers (int regno)
{
debug_target.to_fetch_registers (regno);
-
- fprintf_unfiltered (gdb_stdlog, "target_fetch_registers (%s)",
- regno != -1 ? REGISTER_NAME (regno) : "-1");
- if (regno != -1)
- fprintf_unfiltered (gdb_stdlog, " = 0x%lx %ld",
- (unsigned long) read_register (regno),
- (unsigned long) read_register (regno));
- fprintf_unfiltered (gdb_stdlog, "\n");
+ debug_print_register ("target_fetch_registers", regno);
}
static void
debug_to_store_registers (int regno)
{
debug_target.to_store_registers (regno);
-
- if (regno >= 0 && regno < NUM_REGS)
- fprintf_unfiltered (gdb_stdlog, "target_store_registers (%s) = 0x%lx %ld\n",
- REGISTER_NAME (regno),
- (unsigned long) read_register (regno),
- (unsigned long) read_register (regno));
- else
- fprintf_unfiltered (gdb_stdlog, "target_store_registers (%d)\n", regno);
+ debug_print_register ("target_store_registers", regno);
+ fprintf_unfiltered (gdb_stdlog, "\n");
}
static void
@@ -1759,6 +1885,116 @@ debug_to_remove_breakpoint (CORE_ADDR addr, char *save)
return retval;
}
+static int
+debug_to_can_use_hw_breakpoint (int type, int cnt, int from_tty)
+{
+ int retval;
+
+ retval = debug_target.to_can_use_hw_breakpoint (type, cnt, from_tty);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_can_use_hw_breakpoint (%ld, %ld, %ld) = %ld\n",
+ (unsigned long) type,
+ (unsigned long) cnt,
+ (unsigned long) from_tty,
+ (unsigned long) retval);
+ return retval;
+}
+
+static int
+debug_to_region_size_ok_for_hw_watchpoint (int byte_count)
+{
+ CORE_ADDR retval;
+
+ retval = debug_target.to_region_size_ok_for_hw_watchpoint (byte_count);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (%ld) = 0x%lx\n",
+ (unsigned long) byte_count,
+ (unsigned long) retval);
+ return retval;
+}
+
+static int
+debug_to_stopped_by_watchpoint (void)
+{
+ int retval;
+
+ retval = debug_target.to_stopped_by_watchpoint ();
+
+ fprintf_unfiltered (gdb_stdlog,
+ "STOPPED_BY_WATCHPOINT () = %ld\n",
+ (unsigned long) retval);
+ return retval;
+}
+
+static CORE_ADDR
+debug_to_stopped_data_address (void)
+{
+ CORE_ADDR retval;
+
+ retval = debug_target.to_stopped_data_address ();
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_stopped_data_address () = 0x%lx\n",
+ (unsigned long) retval);
+ return retval;
+}
+
+static int
+debug_to_insert_hw_breakpoint (CORE_ADDR addr, char *save)
+{
+ int retval;
+
+ retval = debug_target.to_insert_hw_breakpoint (addr, save);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_insert_hw_breakpoint (0x%lx, xxx) = %ld\n",
+ (unsigned long) addr,
+ (unsigned long) retval);
+ return retval;
+}
+
+static int
+debug_to_remove_hw_breakpoint (CORE_ADDR addr, char *save)
+{
+ int retval;
+
+ retval = debug_target.to_remove_hw_breakpoint (addr, save);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_remove_hw_breakpoint (0x%lx, xxx) = %ld\n",
+ (unsigned long) addr,
+ (unsigned long) retval);
+ return retval;
+}
+
+static int
+debug_to_insert_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ int retval;
+
+ retval = debug_target.to_insert_watchpoint (addr, len, type);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_insert_watchpoint (0x%lx, %d, %d) = %ld\n",
+ (unsigned long) addr, len, type, (unsigned long) retval);
+ return retval;
+}
+
+static int
+debug_to_remove_watchpoint (CORE_ADDR addr, int len, int type)
+{
+ int retval;
+
+ retval = debug_target.to_insert_watchpoint (addr, len, type);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "target_insert_watchpoint (0x%lx, %d, %d) = %ld\n",
+ (unsigned long) addr, len, type, (unsigned long) retval);
+ return retval;
+}
+
static void
debug_to_terminal_init (void)
{
@@ -1792,6 +2028,14 @@ debug_to_terminal_ours (void)
}
static void
+debug_to_terminal_save_ours (void)
+{
+ debug_target.to_terminal_save_ours ();
+
+ fprintf_unfiltered (gdb_stdlog, "target_terminal_save_ours ()\n");
+}
+
+static void
debug_to_terminal_info (char *arg, int from_tty)
{
debug_target.to_terminal_info (arg, from_tty);
@@ -1855,24 +2099,6 @@ debug_to_acknowledge_created_inferior (int pid)
pid);
}
-static void
-debug_to_clone_and_follow_inferior (int child_pid, int *followed_child)
-{
- debug_target.to_clone_and_follow_inferior (child_pid, followed_child);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_clone_and_follow_inferior (%d, %d)\n",
- child_pid, *followed_child);
-}
-
-static void
-debug_to_post_follow_inferior_by_clone (void)
-{
- debug_target.to_post_follow_inferior_by_clone ();
-
- fprintf_unfiltered (gdb_stdlog, "target_post_follow_inferior_by_clone ()\n");
-}
-
static int
debug_to_insert_fork_catchpoint (int pid)
{
@@ -1926,53 +2152,14 @@ debug_to_remove_vfork_catchpoint (int pid)
}
static int
-debug_to_has_forked (int pid, int *child_pid)
-{
- int has_forked;
-
- has_forked = debug_target.to_has_forked (pid, child_pid);
-
- fprintf_unfiltered (gdb_stdlog, "target_has_forked (%d, %d) = %d\n",
- pid, *child_pid, has_forked);
-
- return has_forked;
-}
-
-static int
-debug_to_has_vforked (int pid, int *child_pid)
+debug_to_follow_fork (int follow_child)
{
- int has_vforked;
-
- has_vforked = debug_target.to_has_vforked (pid, child_pid);
-
- fprintf_unfiltered (gdb_stdlog, "target_has_vforked (%d, %d) = %d\n",
- pid, *child_pid, has_vforked);
-
- return has_vforked;
-}
-
-static int
-debug_to_can_follow_vfork_prior_to_exec (void)
-{
- int can_immediately_follow_vfork;
-
- can_immediately_follow_vfork = debug_target.to_can_follow_vfork_prior_to_exec ();
-
- fprintf_unfiltered (gdb_stdlog, "target_can_follow_vfork_prior_to_exec () = %d\n",
- can_immediately_follow_vfork);
-
- return can_immediately_follow_vfork;
-}
+ int retval = debug_target.to_follow_fork (follow_child);
-static void
-debug_to_post_follow_vfork (int parent_pid, int followed_parent, int child_pid,
- int followed_child)
-{
- debug_target.to_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child);
+ fprintf_unfiltered (gdb_stdlog, "target_follow_fork (%d) = %d\n",
+ follow_child, retval);
- fprintf_unfiltered (gdb_stdlog,
- "target_post_follow_vfork (%d, %d, %d, %d)\n",
- parent_pid, followed_parent, child_pid, followed_child);
+ return retval;
}
static int
@@ -2002,20 +2189,6 @@ debug_to_remove_exec_catchpoint (int pid)
}
static int
-debug_to_has_execd (int pid, char **execd_pathname)
-{
- int has_execd;
-
- has_execd = debug_target.to_has_execd (pid, execd_pathname);
-
- fprintf_unfiltered (gdb_stdlog, "target_has_execd (%d, %s) = %d\n",
- pid, (*execd_pathname ? *execd_pathname : "<NULL>"),
- has_execd);
-
- return has_execd;
-}
-
-static int
debug_to_reported_exec_events_per_exec_call (void)
{
int reported_exec_events;
@@ -2030,36 +2203,6 @@ debug_to_reported_exec_events_per_exec_call (void)
}
static int
-debug_to_has_syscall_event (int pid, enum target_waitkind *kind,
- int *syscall_id)
-{
- int has_syscall_event;
- char *kind_spelling = "??";
-
- has_syscall_event = debug_target.to_has_syscall_event (pid, kind, syscall_id);
- if (has_syscall_event)
- {
- switch (*kind)
- {
- case TARGET_WAITKIND_SYSCALL_ENTRY:
- kind_spelling = "SYSCALL_ENTRY";
- break;
- case TARGET_WAITKIND_SYSCALL_RETURN:
- kind_spelling = "SYSCALL_RETURN";
- break;
- default:
- break;
- }
- }
-
- fprintf_unfiltered (gdb_stdlog,
- "target_has_syscall_event (%d, %s, %d) = %d\n",
- pid, kind_spelling, *syscall_id, has_syscall_event);
-
- return has_syscall_event;
-}
-
-static int
debug_to_has_exited (int pid, int wait_status, int *exit_status)
{
int has_exited;
@@ -2130,14 +2273,21 @@ debug_to_stop (void)
fprintf_unfiltered (gdb_stdlog, "target_stop ()\n");
}
-static int
-debug_to_query (int type, char *req, char *resp, int *siz)
+static LONGEST
+debug_to_xfer_partial (struct target_ops *ops, enum target_object object,
+ const char *annex, void *readbuf, const void *writebuf,
+ ULONGEST offset, LONGEST len)
{
- int retval;
+ LONGEST retval;
- retval = debug_target.to_query (type, req, resp, siz);
+ retval = debug_target.to_xfer_partial (&debug_target, object, annex,
+ readbuf, writebuf, offset, len);
- fprintf_unfiltered (gdb_stdlog, "target_query (%c, %s, %s, %d) = %d\n", type, req, resp, *siz, retval);
+ fprintf_unfiltered (gdb_stdlog,
+ "target_xfer_partial (%d, %s, 0x%lx, 0x%lx, 0x%s, %s) = %s\n",
+ (int) object, (annex ? annex : "(null)"),
+ (long) readbuf, (long) writebuf, paddr_nz (offset),
+ paddr_d (len), paddr_d (retval));
return retval;
}
@@ -2192,9 +2342,8 @@ setup_target_debug (void)
current_target.to_close = debug_to_close;
current_target.to_attach = debug_to_attach;
current_target.to_post_attach = debug_to_post_attach;
- current_target.to_require_attach = debug_to_require_attach;
current_target.to_detach = debug_to_detach;
- current_target.to_require_detach = debug_to_require_detach;
+ current_target.to_disconnect = debug_to_disconnect;
current_target.to_resume = debug_to_resume;
current_target.to_wait = debug_to_wait;
current_target.to_post_wait = debug_to_post_wait;
@@ -2205,10 +2354,19 @@ setup_target_debug (void)
current_target.to_files_info = debug_to_files_info;
current_target.to_insert_breakpoint = debug_to_insert_breakpoint;
current_target.to_remove_breakpoint = debug_to_remove_breakpoint;
+ current_target.to_can_use_hw_breakpoint = debug_to_can_use_hw_breakpoint;
+ current_target.to_insert_hw_breakpoint = debug_to_insert_hw_breakpoint;
+ current_target.to_remove_hw_breakpoint = debug_to_remove_hw_breakpoint;
+ current_target.to_insert_watchpoint = debug_to_insert_watchpoint;
+ current_target.to_remove_watchpoint = debug_to_remove_watchpoint;
+ current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint;
+ current_target.to_stopped_data_address = debug_to_stopped_data_address;
+ current_target.to_region_size_ok_for_hw_watchpoint = debug_to_region_size_ok_for_hw_watchpoint;
current_target.to_terminal_init = debug_to_terminal_init;
current_target.to_terminal_inferior = debug_to_terminal_inferior;
current_target.to_terminal_ours_for_output = debug_to_terminal_ours_for_output;
current_target.to_terminal_ours = debug_to_terminal_ours;
+ current_target.to_terminal_save_ours = debug_to_terminal_save_ours;
current_target.to_terminal_info = debug_to_terminal_info;
current_target.to_kill = debug_to_kill;
current_target.to_load = debug_to_load;
@@ -2216,21 +2374,14 @@ setup_target_debug (void)
current_target.to_create_inferior = debug_to_create_inferior;
current_target.to_post_startup_inferior = debug_to_post_startup_inferior;
current_target.to_acknowledge_created_inferior = debug_to_acknowledge_created_inferior;
- current_target.to_clone_and_follow_inferior = debug_to_clone_and_follow_inferior;
- current_target.to_post_follow_inferior_by_clone = debug_to_post_follow_inferior_by_clone;
current_target.to_insert_fork_catchpoint = debug_to_insert_fork_catchpoint;
current_target.to_remove_fork_catchpoint = debug_to_remove_fork_catchpoint;
current_target.to_insert_vfork_catchpoint = debug_to_insert_vfork_catchpoint;
current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint;
- current_target.to_has_forked = debug_to_has_forked;
- current_target.to_has_vforked = debug_to_has_vforked;
- current_target.to_can_follow_vfork_prior_to_exec = debug_to_can_follow_vfork_prior_to_exec;
- current_target.to_post_follow_vfork = debug_to_post_follow_vfork;
+ current_target.to_follow_fork = debug_to_follow_fork;
current_target.to_insert_exec_catchpoint = debug_to_insert_exec_catchpoint;
current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint;
- current_target.to_has_execd = debug_to_has_execd;
current_target.to_reported_exec_events_per_exec_call = debug_to_reported_exec_events_per_exec_call;
- current_target.to_has_syscall_event = debug_to_has_syscall_event;
current_target.to_has_exited = debug_to_has_exited;
current_target.to_mourn_inferior = debug_to_mourn_inferior;
current_target.to_can_run = debug_to_can_run;
@@ -2238,7 +2389,7 @@ setup_target_debug (void)
current_target.to_thread_alive = debug_to_thread_alive;
current_target.to_find_new_threads = debug_to_find_new_threads;
current_target.to_stop = debug_to_stop;
- current_target.to_query = debug_to_query;
+ current_target.to_xfer_partial = debug_to_xfer_partial;
current_target.to_rcmd = debug_to_rcmd;
current_target.to_enable_exception_callback = debug_to_enable_exception_callback;
current_target.to_get_current_exception_event = debug_to_get_current_exception_event;
@@ -2283,16 +2434,15 @@ initialize_targets (void)
When non-zero, target debugging is enabled.", &setdebuglist),
&showdebuglist);
- add_show_from_set
- (add_set_boolean_cmd
- ("trust-readonly-sections", class_support,
- &trust_readonly,
- "Set mode for reading from readonly sections.\n\
+ add_setshow_boolean_cmd ("trust-readonly-sections", class_support,
+ &trust_readonly, "\
+Set mode for reading from readonly sections.\n\
When this mode is on, memory reads from readonly sections (such as .text)\n\
will be read from the object file instead of from the target. This will\n\
-result in significant performance improvement for remote targets.",
- &setlist),
- &showlist);
+result in significant performance improvement for remote targets.", "\
+Show mode for reading from readonly sections.\n",
+ NULL, NULL,
+ &setlist, &showlist);
add_com ("monitor", class_obscure, do_monitor_command,
"Send a command to the remote monitor (remote targets only).");
diff --git a/contrib/gdb/gdb/target.h b/contrib/gdb/gdb/target.h
index b5d036b..2d8ce37 100644
--- a/contrib/gdb/gdb/target.h
+++ b/contrib/gdb/gdb/target.h
@@ -1,6 +1,8 @@
/* Interface between GDB and target environments, including files and processes
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
Contributed by Cygnus Support. Written by John Gilmore.
This file is part of GDB.
@@ -23,13 +25,18 @@
#if !defined (TARGET_H)
#define TARGET_H
+struct objfile;
+struct ui_file;
+struct mem_attrib;
+struct target_ops;
+
/* This include file defines the interface between the main part
of the debugger, and the part which is target-specific, or
specific to the communications interface between us and the
target.
- A TARGET is an interface between the debugger and a particular
- kind of file or process. Targets can be STACKED in STRATA,
+ A TARGET is an interface between the debugger and a particular
+ kind of file or process. Targets can be STACKED in STRATA,
so that more than one target can potentially respond to a request.
In particular, memory accesses will walk down the stack of targets
until they find a target that is interested in handling that particular
@@ -112,8 +119,8 @@ enum target_waitkind
inferior. */
TARGET_WAITKIND_SPURIOUS,
- /* This is used for target async and extended-async
- only. Remote_async_wait() returns this when there is an event
+ /* An event has occured, but we should wait again.
+ 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
@@ -148,7 +155,7 @@ enum inferior_event_type
INF_QUIT_REQ,
/* Process a normal inferior event which will result in target_wait
being called. */
- INF_REG_EVENT,
+ INF_REG_EVENT,
/* Deal with an error on the inferior. */
INF_ERROR,
/* We are called because a timer went off. */
@@ -171,6 +178,95 @@ extern char *target_signal_to_name (enum target_signal);
/* Given a name (SIGHUP, etc.), return its signal. */
enum target_signal target_signal_from_name (char *);
+/* Request the transfer of up to LEN 8-bit bytes of the target's
+ OBJECT. The OFFSET, for a seekable object, specifies the starting
+ point. The ANNEX can be used to provide additional data-specific
+ information to the target.
+
+ Return the number of bytes actually transfered, zero when no
+ further transfer is possible, and -1 when the transfer is not
+ supported.
+
+ NOTE: cagney/2003-10-17: The current interface does not support a
+ "retry" mechanism. Instead it assumes that at least one byte will
+ be transfered on each call.
+
+ NOTE: cagney/2003-10-17: The current interface can lead to
+ fragmented transfers. Lower target levels should not implement
+ hacks, such as enlarging the transfer, in an attempt to compensate
+ for this. Instead, the target stack should be extended so that it
+ implements supply/collect methods and a look-aside object cache.
+ With that available, the lowest target can safely and freely "push"
+ data up the stack.
+
+ NOTE: cagney/2003-10-17: Unlike the old query and the memory
+ transfer mechanisms, these methods are explicitly parameterized by
+ the target that it should be applied to.
+
+ NOTE: cagney/2003-10-17: Just like the old query and memory xfer
+ methods, these new methods perform partial transfers. The only
+ difference is that these new methods thought to include "partial"
+ in the name. The old code's failure to do this lead to much
+ confusion and duplication of effort as each target object attempted
+ to locally take responsibility for something it didn't have to
+ worry about.
+
+ NOTE: cagney/2003-10-17: With a TARGET_OBJECT_KOD object, for
+ backward compatibility with the "target_query" method that this
+ replaced, when OFFSET and LEN are both zero, return the "minimum"
+ buffer size. See "remote.c" for further information. */
+
+enum target_object
+{
+ /* Kernel Object Display transfer. See "kod.c" and "remote.c". */
+ TARGET_OBJECT_KOD,
+ /* AVR target specific transfer. See "avr-tdep.c" and "remote.c". */
+ TARGET_OBJECT_AVR,
+ /* Transfer up-to LEN bytes of memory starting at OFFSET. */
+ TARGET_OBJECT_MEMORY,
+ /* Kernel Unwind Table. See "ia64-tdep.c". */
+ TARGET_OBJECT_UNWIND_TABLE,
+ /* Transfer auxilliary vector. */
+ TARGET_OBJECT_AUXV,
+ /* StackGhost cookie. See "sparc-tdep.c". */
+ TARGET_OBJECT_WCOOKIE
+
+ /* Possible future objects: TARGET_OBJECT_FILE, TARGET_OBJECT_PROC, ... */
+};
+
+extern LONGEST target_read_partial (struct target_ops *ops,
+ enum target_object object,
+ const char *annex, void *buf,
+ ULONGEST offset, LONGEST len);
+
+extern LONGEST target_write_partial (struct target_ops *ops,
+ enum target_object object,
+ const char *annex, const void *buf,
+ ULONGEST offset, LONGEST len);
+
+/* Wrappers to perform the full transfer. */
+extern LONGEST target_read (struct target_ops *ops,
+ enum target_object object,
+ const char *annex, void *buf,
+ ULONGEST offset, LONGEST len);
+
+extern LONGEST target_write (struct target_ops *ops,
+ enum target_object object,
+ const char *annex, const void *buf,
+ ULONGEST offset, LONGEST len);
+
+/* Wrappers to target read/write that perform memory transfers. They
+ throw an error if the memory transfer fails.
+
+ NOTE: cagney/2003-10-23: The naming schema is lifted from
+ "frame.h". The parameter order is lifted from get_frame_memory,
+ which in turn lifted it from read_memory. */
+
+extern void get_target_memory (struct target_ops *ops, CORE_ADDR addr,
+ void *buf, LONGEST len);
+extern ULONGEST get_target_memory_unsigned (struct target_ops *ops,
+ CORE_ADDR addr, int len);
+
/* If certain kinds of activity happen, target_wait should perform
callbacks. */
@@ -184,18 +280,28 @@ struct thread_info; /* fwd decl for parameter list below: */
struct target_ops
{
+ struct target_ops *beneath; /* To the target under this one. */
char *to_shortname; /* Name this target type */
char *to_longname; /* Name for printing */
char *to_doc; /* Documentation. Does not include trailing
newline, and starts with a one-line descrip-
tion (probably similar to to_longname). */
+ /* Per-target scratch pad. */
+ void *to_data;
+ /* The open routine takes the rest of the parameters from the
+ command, and (if successful) pushes a new target onto the
+ stack. Targets should supply this routine, if only to provide
+ an error message. */
void (*to_open) (char *, int);
+ /* Old targets with a static target vector provide "to_close".
+ New re-entrant targets provide "to_xclose" and that is expected
+ to xfree everything (including the "struct target_ops"). */
+ void (*to_xclose) (struct target_ops *targ, int quitting);
void (*to_close) (int);
void (*to_attach) (char *, int);
void (*to_post_attach) (int);
- void (*to_require_attach) (char *, int);
void (*to_detach) (char *, int);
- void (*to_require_detach) (int, char *, int);
+ void (*to_disconnect) (char *, int);
void (*to_resume) (ptid_t, int, enum target_signal);
ptid_t (*to_wait) (ptid_t, struct target_waitstatus *);
void (*to_post_wait) (ptid_t, int);
@@ -222,40 +328,27 @@ struct target_ops
something at MEMADDR + N. */
int (*to_xfer_memory) (CORE_ADDR memaddr, char *myaddr,
- int len, int write,
+ int len, int write,
struct mem_attrib *attrib,
struct target_ops *target);
-#if 0
- /* Enable this after 4.12. */
-
- /* Search target memory. Start at STARTADDR and take LEN bytes of
- target memory, and them with MASK, and compare to DATA. If they
- match, set *ADDR_FOUND to the address we found it at, store the data
- we found at LEN bytes starting at DATA_FOUND, and return. If
- not, add INCREMENT to the search address and keep trying until
- the search address is outside of the range [LORANGE,HIRANGE).
-
- If we don't find anything, set *ADDR_FOUND to (CORE_ADDR)0 and
- return. */
-
- void (*to_search) (int len, char *data, char *mask,
- CORE_ADDR startaddr, int increment,
- CORE_ADDR lorange, CORE_ADDR hirange,
- CORE_ADDR * addr_found, char *data_found);
-
-#define target_search(len, data, mask, startaddr, increment, lorange, hirange, addr_found, data_found) \
- (*current_target.to_search) (len, data, mask, startaddr, increment, \
- lorange, hirange, addr_found, data_found)
-#endif /* 0 */
-
void (*to_files_info) (struct target_ops *);
int (*to_insert_breakpoint) (CORE_ADDR, char *);
int (*to_remove_breakpoint) (CORE_ADDR, char *);
+ int (*to_can_use_hw_breakpoint) (int, int, int);
+ int (*to_insert_hw_breakpoint) (CORE_ADDR, char *);
+ int (*to_remove_hw_breakpoint) (CORE_ADDR, char *);
+ int (*to_remove_watchpoint) (CORE_ADDR, int, int);
+ int (*to_insert_watchpoint) (CORE_ADDR, int, int);
+ int (*to_stopped_by_watchpoint) (void);
+ int to_have_continuable_watchpoint;
+ CORE_ADDR (*to_stopped_data_address) (void);
+ int (*to_region_size_ok_for_hw_watchpoint) (int);
void (*to_terminal_init) (void);
void (*to_terminal_inferior) (void);
void (*to_terminal_ours_for_output) (void);
void (*to_terminal_ours) (void);
+ void (*to_terminal_save_ours) (void);
void (*to_terminal_info) (char *, int);
void (*to_kill) (void);
void (*to_load) (char *, int);
@@ -263,21 +356,14 @@ struct target_ops
void (*to_create_inferior) (char *, char *, char **);
void (*to_post_startup_inferior) (ptid_t);
void (*to_acknowledge_created_inferior) (int);
- void (*to_clone_and_follow_inferior) (int, int *);
- void (*to_post_follow_inferior_by_clone) (void);
int (*to_insert_fork_catchpoint) (int);
int (*to_remove_fork_catchpoint) (int);
int (*to_insert_vfork_catchpoint) (int);
int (*to_remove_vfork_catchpoint) (int);
- int (*to_has_forked) (int, int *);
- int (*to_has_vforked) (int, int *);
- int (*to_can_follow_vfork_prior_to_exec) (void);
- void (*to_post_follow_vfork) (int, int, int, int);
+ int (*to_follow_fork) (int);
int (*to_insert_exec_catchpoint) (int);
int (*to_remove_exec_catchpoint) (int);
- int (*to_has_execd) (int, char **);
int (*to_reported_exec_events_per_exec_call) (void);
- int (*to_has_syscall_event) (int, enum target_waitkind *, int *);
int (*to_has_exited) (int, int, int *);
void (*to_mourn_inferior) (void);
int (*to_can_run) (void);
@@ -287,7 +373,6 @@ struct target_ops
char *(*to_pid_to_str) (ptid_t);
char *(*to_extra_thread_info) (struct thread_info *);
void (*to_stop) (void);
- int (*to_query) (int /*char */ , char *, char *, int *);
void (*to_rcmd) (char *command, struct ui_file *output);
struct symtab_and_line *(*to_enable_exception_callback) (enum
exception_event_kind,
@@ -295,8 +380,6 @@ struct target_ops
struct exception_event_record *(*to_get_current_exception_event) (void);
char *(*to_pid_to_exec_file) (int pid);
enum strata to_stratum;
- struct target_ops
- *DONT_USE; /* formerly to_next */
int to_has_all_memory;
int to_has_memory;
int to_has_stack;
@@ -313,12 +396,30 @@ struct target_ops
void (*to_async) (void (*cb) (enum inferior_event_type, void *context),
void *context);
int to_async_mask_value;
- int (*to_find_memory_regions) (int (*) (CORE_ADDR,
- unsigned long,
- int, int, int,
- void *),
+ int (*to_find_memory_regions) (int (*) (CORE_ADDR,
+ unsigned long,
+ int, int, int,
+ void *),
void *);
char * (*to_make_corefile_notes) (bfd *, int *);
+
+ /* Return the thread-local address at OFFSET in the
+ thread-local storage for the thread PTID and the shared library
+ or executable file given by OBJFILE. If that block of
+ thread-local storage hasn't been allocated yet, this function
+ may return an error. */
+ CORE_ADDR (*to_get_thread_local_address) (ptid_t ptid,
+ struct objfile *objfile,
+ CORE_ADDR offset);
+
+ /* Perform partial transfers on OBJECT. See target_read_partial
+ and target_write_partial for details of each variant. One, and
+ only one, of readbuf or writebuf must be non-NULL. */
+ LONGEST (*to_xfer_partial) (struct target_ops *ops,
+ enum target_object object, const char *annex,
+ void *readbuf, const void *writebuf,
+ ULONGEST offset, LONGEST len);
+
int to_magic;
/* Need sub-structure for target machine related rather than comm related?
*/
@@ -335,50 +436,28 @@ struct target_ops
extern struct target_ops current_target;
-/* An item on the target stack. */
-
-struct target_stack_item
- {
- struct target_stack_item *next;
- struct target_ops *target_ops;
- };
-
-/* The target stack. */
-
-extern struct target_stack_item *target_stack;
-
/* Define easy words for doing these operations on our current target. */
#define target_shortname (current_target.to_shortname)
#define target_longname (current_target.to_longname)
-/* The open routine takes the rest of the parameters from the command,
- and (if successful) pushes a new target onto the stack.
- Targets should supply this routine, if only to provide an error message. */
-
-#define target_open(name, from_tty) \
- do { \
- dcache_invalidate (target_dcache); \
- (*current_target.to_open) (name, from_tty); \
- } while (0)
+/* Does whatever cleanup is required for a target that we are no
+ longer going to be calling. QUITTING indicates that GDB is exiting
+ and should not get hung on an error (otherwise it is important to
+ perform clean termination, even if it takes a while). This routine
+ is automatically always called when popping the target off the
+ target stack (to_beneath is undefined). Closing file descriptors
+ and freeing all memory allocated memory are typical things it
+ should do. */
-/* Does whatever cleanup is required for a target that we are no longer
- going to be calling. Argument says whether we are quitting gdb and
- should not get hung in case of errors, or whether we want a clean
- termination even if it takes a while. This routine is automatically
- always called just before a routine is popped off the target stack.
- Closing file descriptors and freeing memory are typical things it should
- do. */
-
-#define target_close(quitting) \
- (*current_target.to_close) (quitting)
+void target_close (struct target_ops *targ, int quitting);
/* Attaches to a process on the target side. Arguments are as passed
to the `attach' command by the user. This routine can be called
when the target is not on the target-stack, if the target_can_run
- routine returns 1; in that case, it must push itself onto the stack.
+ routine returns 1; in that case, it must push itself onto the stack.
Upon exit, the target should be ready for normal operations, and
- should be ready to deliver the status of the process immediately
+ should be ready to deliver the status of the process immediately
(without waiting) to an upcoming target_wait call. */
#define target_attach(args, from_tty) \
@@ -392,17 +471,6 @@ extern struct target_stack_item *target_stack;
#define target_post_attach(pid) \
(*current_target.to_post_attach) (pid)
-/* Attaches to a process on the target side, if not already attached.
- (If already attached, takes no action.)
-
- This operation can be used to follow the child process of a fork.
- On some targets, such child processes of an original inferior process
- are automatically under debugger control, and thus do not require an
- actual attach operation. */
-
-#define target_require_attach(args, from_tty) \
- (*current_target.to_require_attach) (args, from_tty)
-
/* Takes a program previously attached to and detaches it.
The program may resume execution (some targets do, some don't) and will
no longer stop on signals, etc. We better not have left any breakpoints
@@ -412,20 +480,10 @@ extern struct target_stack_item *target_stack;
extern void target_detach (char *, int);
-/* Detaches from a process on the target side, if not already dettached.
- (If already detached, takes no action.)
-
- This operation can be used to follow the parent process of a fork.
- On some targets, such child processes of an original inferior process
- are automatically under debugger control, and thus do require an actual
- detach operation.
+/* Disconnect from the current target without resuming it (leaving it
+ waiting for a debugger). */
- PID is the process id of the child to detach from.
- ARGS is arguments typed by the user (e.g. a signal to send the process).
- FROM_TTY says whether to be verbose or not. */
-
-#define target_require_detach(pid, args, from_tty) \
- (*current_target.to_require_detach) (pid, args, from_tty)
+extern void target_disconnect (char *, int);
/* Resume execution of the target process PTID. STEP says whether to
single-step or to run free; SIGGNAL is the signal to be given to
@@ -494,10 +552,10 @@ extern int target_read_memory (CORE_ADDR memaddr, char *myaddr, int len);
extern int target_write_memory (CORE_ADDR memaddr, char *myaddr, int len);
-extern int xfer_memory (CORE_ADDR, char *, int, int,
+extern int xfer_memory (CORE_ADDR, char *, int, int,
struct mem_attrib *, struct target_ops *);
-extern int child_xfer_memory (CORE_ADDR, char *, int, int,
+extern int child_xfer_memory (CORE_ADDR, char *, int, int,
struct mem_attrib *, struct target_ops *);
/* Make a single attempt at transfering LEN bytes. On a successful
@@ -506,11 +564,11 @@ extern int child_xfer_memory (CORE_ADDR, char *, int, int,
of bytes actually transfered is not defined) and ERR is set to a
non-zero error indication. */
-extern int
-target_read_memory_partial (CORE_ADDR addr, char *buf, int len, int *err);
+extern int target_read_memory_partial (CORE_ADDR addr, char *buf, int len,
+ int *err);
-extern int
-target_write_memory_partial (CORE_ADDR addr, char *buf, int len, int *err);
+extern int target_write_memory_partial (CORE_ADDR addr, char *buf, int len,
+ int *err);
extern char *child_pid_to_exec_file (int);
@@ -526,10 +584,6 @@ extern void child_post_startup_inferior (ptid_t);
extern void child_acknowledge_created_inferior (int);
-extern void child_clone_and_follow_inferior (int, int *);
-
-extern void child_post_follow_inferior_by_clone (void);
-
extern int child_insert_fork_catchpoint (int);
extern int child_remove_fork_catchpoint (int);
@@ -538,30 +592,28 @@ extern int child_insert_vfork_catchpoint (int);
extern int child_remove_vfork_catchpoint (int);
-extern int child_has_forked (int, int *);
-
-extern int child_has_vforked (int, int *);
-
extern void child_acknowledge_created_inferior (int);
-extern int child_can_follow_vfork_prior_to_exec (void);
-
-extern void child_post_follow_vfork (int, int, int, int);
+extern int child_follow_fork (int);
extern int child_insert_exec_catchpoint (int);
extern int child_remove_exec_catchpoint (int);
-extern int child_has_execd (int, char **);
-
extern int child_reported_exec_events_per_exec_call (void);
-extern int child_has_syscall_event (int, enum target_waitkind *, int *);
-
extern int child_has_exited (int, int, int *);
extern int child_thread_alive (ptid_t);
+/* From infrun.c. */
+
+extern int inferior_has_forked (int pid, int *child_pid);
+
+extern int inferior_has_vforked (int pid, int *child_pid);
+
+extern int inferior_has_execd (int pid, char **execd_pathname);
+
/* From exec.c */
extern void print_section_info (struct target_ops *, bfd *);
@@ -571,18 +623,18 @@ extern void print_section_info (struct target_ops *, bfd *);
#define target_files_info() \
(*current_target.to_files_info) (&current_target)
-/* Insert a breakpoint at address ADDR in the target machine.
- SAVE is a pointer to memory allocated for saving the
- target contents. It is guaranteed by the caller to be long enough
- to save "sizeof BREAKPOINT" bytes. Result is 0 for success, or
- an errno value. */
+/* Insert a breakpoint at address ADDR in the target machine. SAVE is
+ a pointer to memory allocated for saving the target contents. It
+ is guaranteed by the caller to be long enough to save the number of
+ breakpoint bytes indicated by BREAKPOINT_FROM_PC. Result is 0 for
+ success, or an errno value. */
#define target_insert_breakpoint(addr, save) \
(*current_target.to_insert_breakpoint) (addr, save)
/* Remove a breakpoint at address ADDR in the target machine.
- SAVE is a pointer to the same save area
- that was previously passed to target_insert_breakpoint.
+ SAVE is a pointer to the same save area
+ that was previously passed to target_insert_breakpoint.
Result is 0 for success, or an errno value. */
#define target_remove_breakpoint(addr, save) \
@@ -618,6 +670,14 @@ extern void print_section_info (struct target_ops *, bfd *);
#define target_terminal_ours() \
(*current_target.to_terminal_ours) ()
+/* Save our terminal settings.
+ This is called from TUI after entering or leaving the curses
+ mode. Since curses modifies our terminal this call is here
+ to take this change into account. */
+
+#define target_terminal_save_ours() \
+ (*current_target.to_terminal_save_ours) ()
+
/* Print useful information about our terminal status, if such a thing
exists. */
@@ -675,33 +735,6 @@ extern void target_load (char *arg, int from_tty);
#define target_acknowledge_created_inferior(pid) \
(*current_target.to_acknowledge_created_inferior) (pid)
-/* An inferior process has been created via a fork() or similar
- system call. This function will clone the debugger, then ensure
- that CHILD_PID is attached to by that debugger.
-
- FOLLOWED_CHILD is set TRUE on return *for the clone debugger only*,
- and FALSE otherwise. (The original and clone debuggers can use this
- to determine which they are, if need be.)
-
- (This is not a terribly useful feature without a GUI to prevent
- the two debuggers from competing for shell input.) */
-
-#define target_clone_and_follow_inferior(child_pid,followed_child) \
- (*current_target.to_clone_and_follow_inferior) (child_pid, followed_child)
-
-/* This operation is intended to be used as the last in a sequence of
- steps taken when following both parent and child of a fork. This
- is used by a clone of the debugger, which will follow the child.
-
- The original debugger has detached from this process, and the
- clone has attached to it.
-
- On some targets, this requires a bit of cleanup to make it work
- correctly. */
-
-#define target_post_follow_inferior_by_clone() \
- (*current_target.to_post_follow_inferior_by_clone) ()
-
/* On some targets, we can catch an inferior fork or vfork event when
it occurs. These functions insert/remove an already-created
catchpoint for such events. */
@@ -718,42 +751,16 @@ extern void target_load (char *arg, int from_tty);
#define target_remove_vfork_catchpoint(pid) \
(*current_target.to_remove_vfork_catchpoint) (pid)
-/* Returns TRUE if PID has invoked the fork() system call. And,
- also sets CHILD_PID to the process id of the other ("child")
- inferior process that was created by that call. */
-
-#define target_has_forked(pid,child_pid) \
- (*current_target.to_has_forked) (pid,child_pid)
-
-/* Returns TRUE if PID has invoked the vfork() system call. And,
- also sets CHILD_PID to the process id of the other ("child")
- inferior process that was created by that call. */
+/* If the inferior forks or vforks, this function will be called at
+ the next resume in order to perform any bookkeeping and fiddling
+ necessary to continue debugging either the parent or child, as
+ requested, and releasing the other. Information about the fork
+ or vfork event is available via get_last_target_status ().
+ This function returns 1 if the inferior should not be resumed
+ (i.e. there is another event pending). */
-#define target_has_vforked(pid,child_pid) \
- (*current_target.to_has_vforked) (pid,child_pid)
-
-/* Some platforms (such as pre-10.20 HP-UX) don't allow us to do
- anything to a vforked child before it subsequently calls exec().
- On such platforms, we say that the debugger cannot "follow" the
- child until it has vforked.
-
- This function should be defined to return 1 by those targets
- which can allow the debugger to immediately follow a vforked
- child, and 0 if they cannot. */
-
-#define target_can_follow_vfork_prior_to_exec() \
- (*current_target.to_can_follow_vfork_prior_to_exec) ()
-
-/* An inferior process has been created via a vfork() system call.
- The debugger has followed the parent, the child, or both. The
- process of setting up for that follow may have required some
- target-specific trickery to track the sequence of reported events.
- If so, this function should be defined by those targets that
- require the debugger to perform cleanup or initialization after
- the vfork follow. */
-
-#define target_post_follow_vfork(parent_pid,followed_parent,child_pid,followed_child) \
- (*current_target.to_post_follow_vfork) (parent_pid,followed_parent,child_pid,followed_child)
+#define target_follow_fork(follow_child) \
+ (*current_target.to_follow_fork) (follow_child)
/* On some targets, we can catch an inferior exec event when it
occurs. These functions insert/remove an already-created
@@ -765,13 +772,6 @@ extern void target_load (char *arg, int from_tty);
#define target_remove_exec_catchpoint(pid) \
(*current_target.to_remove_exec_catchpoint) (pid)
-/* Returns TRUE if PID has invoked a flavor of the exec() system call.
- And, also sets EXECD_PATHNAME to the pathname of the executable
- file that was passed to exec(), and is now being executed. */
-
-#define target_has_execd(pid,execd_pathname) \
- (*current_target.to_has_execd) (pid,execd_pathname)
-
/* Returns the number of exec events that are reported when a process
invokes a flavor of the exec() system call on this target, if exec
events are being reported. */
@@ -779,13 +779,6 @@ extern void target_load (char *arg, int from_tty);
#define target_reported_exec_events_per_exec_call() \
(*current_target.to_reported_exec_events_per_exec_call) ()
-/* Returns TRUE if PID has reported a syscall event. And, also sets
- KIND to the appropriate TARGET_WAITKIND_, and sets SYSCALL_ID to
- the unique integer ID of the syscall. */
-
-#define target_has_syscall_event(pid,kind,syscall_id) \
- (*current_target.to_has_syscall_event) (pid,kind,syscall_id)
-
/* Returns TRUE if PID has exited. And, also sets EXIT_STATUS to the
exit code of PID, if any. */
@@ -793,7 +786,7 @@ extern void target_load (char *arg, int from_tty);
(*current_target.to_has_exited) (pid,wait_status,exit_status)
/* The debugger has completed a blocking wait() call. There is now
- some process event that must be processed. This function should
+ some process event that must be processed. This function should
be defined by those targets that require the debugger to perform
cleanup or internal state changes in response to the process event. */
@@ -828,16 +821,6 @@ extern void target_load (char *arg, int from_tty);
#define target_stop current_target.to_stop
-/* Queries the target side for some information. The first argument is a
- letter specifying the type of the query, which is used to determine who
- should process it. The second argument is a string that specifies which
- information is desired and the third is a buffer that carries back the
- response from the target side. The fourth parameter is the size of the
- output buffer supplied. */
-
-#define target_query(query_type, query, resp_buffer, bufffer_size) \
- (*current_target.to_query) (query_type, query, resp_buffer, bufffer_size)
-
/* Send the specified COMMAND to the target's monitor
(shell,interpreter) for execution. The result of the query is
placed in OUTBUF. */
@@ -847,7 +830,7 @@ extern void target_load (char *arg, int from_tty);
/* Get the symbol information for a breakpointable routine called when
- an exception event occurs.
+ an exception event occurs.
Intended mainly for C++, and for those
platforms/implementations where such a callback mechanism is available,
e.g. HP-UX with ANSI C++ (aCC). Some compilers (e.g. g++) support
@@ -861,11 +844,6 @@ extern void target_load (char *arg, int from_tty);
#define target_get_current_exception_event() \
(*current_target.to_get_current_exception_event) ()
-/* Pointer to next target in the chain, e.g. a core file and an exec file. */
-
-#define target_next \
- (current_target.to_next)
-
/* Does the target include all of memory, or only part of it? This
determines whether we look up the target chain for other parts of
memory if this target can't satisfy a request. */
@@ -919,15 +897,15 @@ extern void target_load (char *arg, int from_tty);
#define target_async(CALLBACK,CONTEXT) \
(current_target.to_async((CALLBACK), (CONTEXT)))
-/* This is to be used ONLY within run_stack_dummy(). It
- provides a workaround, to have inferior function calls done in
- sychronous mode, even though the target is asynchronous. After
+/* This is to be used ONLY within call_function_by_hand(). It provides
+ a workaround, to have inferior function calls done in sychronous
+ mode, even though the target is asynchronous. After
target_async_mask(0) is called, calls to target_can_async_p() will
return FALSE , so that target_resume() will not try to start the
target asynchronously. After the inferior stops, we IMMEDIATELY
restore the previous nature of the target, by calling
target_async_mask(1). After that, target_can_async_p() will return
- TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED.
+ TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED.
FIXME ezannoni 1999-12-13: we won't need this once we move
the turning async on and off to the single execution commands,
@@ -936,7 +914,7 @@ extern void target_load (char *arg, int from_tty);
#define target_async_mask_value \
(current_target.to_async_mask_value)
-extern int target_async_mask (int mask);
+extern int target_async_mask (int mask);
extern void target_link (char *, CORE_ADDR *);
@@ -964,7 +942,7 @@ extern char *normal_pid_to_str (ptid_t ptid);
* New Objfile Event Hook:
*
* Sometimes a GDB component wants to get notified whenever a new
- * objfile is loaded. Mainly this is used by thread-debugging
+ * objfile is loaded. Mainly this is used by thread-debugging
* implementations that need to know when symbols for the target
* thread implemenation are available.
*
@@ -1009,7 +987,7 @@ extern void (*target_new_objfile_hook) (struct objfile *);
* Iterator function for target memory regions.
* Calls a callback function once for each memory region 'mapped'
* in the child process. Defined as a simple macro rather than
- * as a function macro so that it can be tested for nullity.
+ * as a function macro so that it can be tested for nullity.
*/
#define target_find_memory_regions(FUNC, DATA) \
@@ -1022,11 +1000,11 @@ extern void (*target_new_objfile_hook) (struct objfile *);
#define target_make_corefile_notes(BFD, SIZE_P) \
(current_target.to_make_corefile_notes) (BFD, SIZE_P)
-/* Hook to call target-dependent code after reading in a new symbol table. */
-
-#ifndef TARGET_SYMFILE_POSTREAD
-#define TARGET_SYMFILE_POSTREAD(OBJFILE)
-#endif
+/* Thread-local values. */
+#define target_get_thread_local_address \
+ (current_target.to_get_thread_local_address)
+#define target_get_thread_local_address_p() \
+ (target_get_thread_local_address != NULL)
/* Hook to call target dependent code just after inferior target process has
started. */
@@ -1041,7 +1019,15 @@ extern void (*target_new_objfile_hook) (struct objfile *);
write). */
#ifndef STOPPED_BY_WATCHPOINT
-#define STOPPED_BY_WATCHPOINT(w) 0
+#define STOPPED_BY_WATCHPOINT(w) \
+ (*current_target.to_stopped_by_watchpoint) ()
+#endif
+
+/* Non-zero if we have continuable watchpoints */
+
+#ifndef HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT \
+ (current_target.to_have_continuable_watchpoint)
#endif
/* HP-UX supplies these operations, which respectively disable and enable
@@ -1056,20 +1042,24 @@ extern void (*target_new_objfile_hook) (struct objfile *);
#define TARGET_ENABLE_HW_WATCHPOINTS(pid)
#endif
-/* Provide defaults for systems that don't support hardware watchpoints. */
+/* Provide defaults for hardware watchpoint functions. */
-#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS
+/* If the *_hw_beakpoint functions have not been defined
+ elsewhere use the definitions in the target vector. */
/* Returns non-zero if we can set a hardware watchpoint of type TYPE. TYPE is
one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint, or
bp_hardware_breakpoint. CNT is the number of such watchpoints used so far
(including this one?). OTHERTYPE is who knows what... */
-#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) 0
+#ifndef TARGET_CAN_USE_HARDWARE_WATCHPOINT
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) \
+ (*current_target.to_can_use_hw_breakpoint) (TYPE, CNT, OTHERTYPE);
+#endif
#if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_count) \
- ((LONGEST)(byte_count) <= REGISTER_SIZE)
+ (*current_target.to_region_size_ok_for_hw_watchpoint) (byte_count)
#endif
@@ -1077,25 +1067,25 @@ extern void (*target_new_objfile_hook) (struct objfile *);
for write, 1 for read, and 2 for read/write accesses. Returns 0 for
success, non-zero for failure. */
-#define target_remove_watchpoint(ADDR,LEN,TYPE) -1
-#define target_insert_watchpoint(ADDR,LEN,TYPE) -1
+#ifndef target_insert_watchpoint
+#define target_insert_watchpoint(addr, len, type) \
+ (*current_target.to_insert_watchpoint) (addr, len, type)
-#endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */
+#define target_remove_watchpoint(addr, len, type) \
+ (*current_target.to_remove_watchpoint) (addr, len, type)
+#endif
#ifndef target_insert_hw_breakpoint
-#define target_remove_hw_breakpoint(ADDR,SHADOW) -1
-#define target_insert_hw_breakpoint(ADDR,SHADOW) -1
-#endif
+#define target_insert_hw_breakpoint(addr, save) \
+ (*current_target.to_insert_hw_breakpoint) (addr, save)
-#ifndef target_stopped_data_address
-#define target_stopped_data_address() 0
+#define target_remove_hw_breakpoint(addr, save) \
+ (*current_target.to_remove_hw_breakpoint) (addr, save)
#endif
-/* If defined, then we need to decr pc by this much after a hardware break-
- point. Presumably this overrides DECR_PC_AFTER_BREAK... */
-
-#ifndef DECR_PC_AFTER_HW_BREAK
-#define DECR_PC_AFTER_HW_BREAK 0
+#ifndef target_stopped_data_address
+#define target_stopped_data_address() \
+ (*current_target.to_stopped_data_address) ()
#endif
/* Sometimes gdb may pick up what appears to be a valid target address
@@ -1163,16 +1153,15 @@ struct section_table
CORE_ADDR addr; /* Lowest address in section */
CORE_ADDR endaddr; /* 1+highest address in section */
- sec_ptr the_bfd_section;
+ struct bfd_section *the_bfd_section;
bfd *bfd; /* BFD file pointer */
};
-/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
- Returns 0 if OK, 1 on error. */
+/* Return the "section" containing the specified address. */
+struct section_table *target_section_by_addr (struct target_ops *target,
+ CORE_ADDR addr);
-extern int
-build_section_table (bfd *, struct section_table **, struct section_table **);
/* From mem-break.c */
@@ -1184,8 +1173,6 @@ extern int default_memory_remove_breakpoint (CORE_ADDR, char *);
extern int default_memory_insert_breakpoint (CORE_ADDR, char *);
-extern breakpoint_from_pc_fn memory_breakpoint_from_pc;
-
/* From target.c */
@@ -1195,22 +1182,16 @@ extern void noprocess (void);
extern void find_default_attach (char *, int);
-extern void find_default_require_attach (char *, int);
-
-extern void find_default_require_detach (int, char *, int);
-
extern void find_default_create_inferior (char *, char *, char **);
-extern void find_default_clone_and_follow_inferior (int, int *);
-
extern struct target_ops *find_run_target (void);
extern struct target_ops *find_core_target (void);
extern struct target_ops *find_target_beneath (struct target_ops *);
-extern int
-target_resize_to_sections (struct target_ops *target, int num_added);
+extern int target_resize_to_sections (struct target_ops *target,
+ int num_added);
extern void remove_target_sections (bfd *abfd);
diff --git a/contrib/gdb/gdb/thread.c b/contrib/gdb/gdb/thread.c
index b9c1f02..f8cc18d 100644
--- a/contrib/gdb/gdb/thread.c
+++ b/contrib/gdb/gdb/thread.c
@@ -1,7 +1,7 @@
/* Multi-process/thread control for GDB, the GNU debugger.
Copyright 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
@@ -34,6 +34,7 @@
#include "gdbcmd.h"
#include "regcache.h"
#include "gdb.h"
+#include "gdb_string.h"
#include <ctype.h>
#include <sys/types.h>
@@ -254,14 +255,17 @@ in_thread_list (ptid_t ptid)
/* Print a list of thread ids currently known, and the total number of
threads. To be used from within catch_errors. */
-static int
-do_captured_list_thread_ids (struct ui_out *uiout,
- void *arg)
+static int
+do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
{
struct thread_info *tp;
int num = 0;
+ struct cleanup *cleanup_chain;
- ui_out_tuple_begin (uiout, "thread-ids");
+ prune_threads ();
+ target_find_new_threads ();
+
+ cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");
for (tp = thread_list; tp; tp = tp->next)
{
@@ -269,7 +273,7 @@ do_captured_list_thread_ids (struct ui_out *uiout,
ui_out_field_int (uiout, "thread-id", tp->num);
}
- ui_out_tuple_end (uiout);
+ do_cleanups (cleanup_chain);
ui_out_field_int (uiout, "number-of-threads", num);
return GDB_RC_OK;
}
@@ -286,24 +290,21 @@ gdb_list_thread_ids (struct ui_out *uiout)
/* Load infrun state for the thread PID. */
void
-load_infrun_state (ptid_t ptid,
- CORE_ADDR *prev_pc,
- CORE_ADDR *prev_func_start,
- char **prev_func_name,
+load_infrun_state (ptid_t ptid,
+ CORE_ADDR *prev_pc,
int *trap_expected,
struct breakpoint **step_resume_breakpoint,
struct breakpoint **through_sigtramp_breakpoint,
- CORE_ADDR *step_range_start,
+ CORE_ADDR *step_range_start,
CORE_ADDR *step_range_end,
- CORE_ADDR *step_frame_address,
+ struct frame_id *step_frame_id,
int *handling_longjmp,
- int *another_trap,
+ int *another_trap,
int *stepping_through_solib_after_catch,
bpstat *stepping_through_solib_catchpoints,
int *stepping_through_sigtramp,
- int *current_line,
- struct symtab **current_symtab,
- CORE_ADDR *step_sp)
+ int *current_line,
+ struct symtab **current_symtab, CORE_ADDR *step_sp)
{
struct thread_info *tp;
@@ -314,18 +315,18 @@ load_infrun_state (ptid_t ptid,
return;
*prev_pc = tp->prev_pc;
- *prev_func_start = tp->prev_func_start;
- *prev_func_name = tp->prev_func_name;
*trap_expected = tp->trap_expected;
*step_resume_breakpoint = tp->step_resume_breakpoint;
*through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
*step_range_start = tp->step_range_start;
*step_range_end = tp->step_range_end;
- *step_frame_address = tp->step_frame_address;
+ *step_frame_id = tp->step_frame_id;
*handling_longjmp = tp->handling_longjmp;
*another_trap = tp->another_trap;
- *stepping_through_solib_after_catch = tp->stepping_through_solib_after_catch;
- *stepping_through_solib_catchpoints = tp->stepping_through_solib_catchpoints;
+ *stepping_through_solib_after_catch =
+ tp->stepping_through_solib_after_catch;
+ *stepping_through_solib_catchpoints =
+ tp->stepping_through_solib_catchpoints;
*stepping_through_sigtramp = tp->stepping_through_sigtramp;
*current_line = tp->current_line;
*current_symtab = tp->current_symtab;
@@ -335,24 +336,21 @@ load_infrun_state (ptid_t ptid,
/* Save infrun state for the thread PID. */
void
-save_infrun_state (ptid_t ptid,
- CORE_ADDR prev_pc,
- CORE_ADDR prev_func_start,
- char *prev_func_name,
+save_infrun_state (ptid_t ptid,
+ CORE_ADDR prev_pc,
int trap_expected,
struct breakpoint *step_resume_breakpoint,
struct breakpoint *through_sigtramp_breakpoint,
- CORE_ADDR step_range_start,
+ CORE_ADDR step_range_start,
CORE_ADDR step_range_end,
- CORE_ADDR step_frame_address,
+ const struct frame_id *step_frame_id,
int handling_longjmp,
- int another_trap,
+ int another_trap,
int stepping_through_solib_after_catch,
bpstat stepping_through_solib_catchpoints,
- int stepping_through_sigtramp,
+ int stepping_through_sigtramp,
int current_line,
- struct symtab *current_symtab,
- CORE_ADDR step_sp)
+ struct symtab *current_symtab, CORE_ADDR step_sp)
{
struct thread_info *tp;
@@ -363,14 +361,12 @@ save_infrun_state (ptid_t ptid,
return;
tp->prev_pc = prev_pc;
- tp->prev_func_start = prev_func_start;
- tp->prev_func_name = prev_func_name;
tp->trap_expected = trap_expected;
tp->step_resume_breakpoint = step_resume_breakpoint;
tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint;
tp->step_range_start = step_range_start;
tp->step_range_end = step_range_end;
- tp->step_frame_address = step_frame_address;
+ tp->step_frame_id = (*step_frame_id);
tp->handling_longjmp = handling_longjmp;
tp->another_trap = another_trap;
tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
@@ -421,14 +417,14 @@ info_threads_command (char *arg, int from_tty)
struct thread_info *tp;
ptid_t current_ptid;
struct frame_info *cur_frame;
- int saved_frame_level = selected_frame_level;
+ int saved_frame_level = frame_relative_level (get_selected_frame ());
int counter;
char *extra_info;
- /* Avoid coredumps which would happen if we tried to access a NULL
- selected_frame. */
- if (!target_has_stack)
- error ("No stack.");
+ /* Check that there really is a frame. This happens when a simulator
+ is connected but not loaded or running, for instance. */
+ if (legacy_frame_p (current_gdbarch) && saved_frame_level < 0)
+ error ("No frame.");
prune_threads ();
target_find_new_threads ();
@@ -452,10 +448,7 @@ info_threads_command (char *arg, int from_tty)
puts_filtered (" ");
switch_to_thread (tp->ptid);
- if (selected_frame)
- print_only_stack_frame (selected_frame, -1, 0);
- else
- printf_filtered ("[No stack.]\n");
+ print_stack_frame (get_selected_frame (), -1, 0);
}
switch_to_thread (current_ptid);
@@ -467,16 +460,16 @@ info_threads_command (char *arg, int from_tty)
* of the stack (leaf frame).
*/
counter = saved_frame_level;
- cur_frame = find_relative_frame (selected_frame, &counter);
+ cur_frame = find_relative_frame (get_selected_frame (), &counter);
if (counter != 0)
{
/* Ooops, can't restore, tell user where we are. */
warning ("Couldn't restore frame in current thread, at frame 0");
- print_stack_frame (selected_frame, -1, 0);
+ print_stack_frame (get_selected_frame (), -1, 0);
}
else
{
- select_frame (cur_frame, saved_frame_level);
+ select_frame (cur_frame);
}
/* re-show current frame. */
@@ -495,13 +488,13 @@ switch_to_thread (ptid_t ptid)
flush_cached_frames ();
registers_changed ();
stop_pc = read_pc ();
- select_frame (get_current_frame (), 0);
+ select_frame (get_current_frame ());
}
static void
restore_current_thread (ptid_t ptid)
{
- if (! ptid_equal (ptid, inferior_ptid))
+ if (!ptid_equal (ptid, inferior_ptid))
{
switch_to_thread (ptid);
print_stack_frame (get_current_frame (), 0, -1);
@@ -566,14 +559,13 @@ thread_apply_all_command (char *cmd, int from_tty)
switch_to_thread (tp->ptid);
#ifdef HPUXHPPA
printf_filtered ("\nThread %d (%s):\n",
- tp->num,
- target_tid_to_str (inferior_ptid));
+ tp->num, target_tid_to_str (inferior_ptid));
#else
printf_filtered ("\nThread %d (%s):\n", tp->num,
target_pid_to_str (inferior_ptid));
#endif
execute_command (cmd, from_tty);
- strcpy (cmd, saved_cmd); /* Restore exact command used previously */
+ strcpy (cmd, saved_cmd); /* Restore exact command used previously */
}
do_cleanups (saved_cmd_cleanup_chain);
@@ -685,8 +677,7 @@ thread_command (char *tidstr, int from_tty)
}
static int
-do_captured_thread_select (struct ui_out *uiout,
- void *tidstr)
+do_captured_thread_select (struct ui_out *uiout, void *tidstr)
{
int num;
struct thread_info *tp;
@@ -713,13 +704,13 @@ do_captured_thread_select (struct ui_out *uiout,
#endif
ui_out_text (uiout, ")]");
- print_stack_frame (selected_frame, selected_frame_level, 1);
+ print_stack_frame (deprecated_selected_frame,
+ frame_relative_level (deprecated_selected_frame), 1);
return GDB_RC_OK;
}
enum gdb_rc
-gdb_thread_select (struct ui_out *uiout,
- char *tidstr)
+gdb_thread_select (struct ui_out *uiout, char *tidstr)
{
return catch_exceptions (uiout, do_captured_thread_select, tidstr,
NULL, RETURN_MASK_ALL);
@@ -738,16 +729,14 @@ _initialize_thread (void)
add_prefix_cmd ("thread", class_run, thread_command,
"Use this command to switch between threads.\n\
-The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1,
- &cmdlist);
+The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1, &cmdlist);
add_prefix_cmd ("apply", class_run, thread_apply_command,
"Apply a command to a list of threads.",
&thread_apply_list, "apply ", 1, &thread_cmd_list);
add_cmd ("all", class_run, thread_apply_all_command,
- "Apply a command to all threads.",
- &thread_apply_list);
+ "Apply a command to all threads.", &thread_apply_list);
if (!xdb_commands)
add_com_alias ("t", "thread", class_run, 1);
diff --git a/contrib/gdb/gdb/top.c b/contrib/gdb/gdb/top.c
index 972a557..d6bdfd0 100644
--- a/contrib/gdb/gdb/top.c
+++ b/contrib/gdb/gdb/top.c
@@ -1,7 +1,7 @@
/* Top level stuff for GDB, the GNU debugger.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GDB.
@@ -27,6 +27,7 @@
#include "cli/cli-cmds.h"
#include "cli/cli-script.h"
#include "cli/cli-setshow.h"
+#include "cli/cli-decode.h"
#include "symtab.h"
#include "inferior.h"
#include <signal.h>
@@ -46,8 +47,8 @@
#include "gdb_assert.h"
/* readline include files */
-#include <readline/readline.h>
-#include <readline/history.h>
+#include "readline/readline.h"
+#include "readline/history.h"
/* readline defines this. */
#undef savestring
@@ -81,7 +82,7 @@ int inhibit_gdbinit = 0;
/* If nonzero, and GDB has been configured to be able to use windows,
attempt to open them upon startup. */
-int use_windows = 1;
+int use_windows = 0;
extern char lang_frame_mismatch_warn[]; /* language.c */
@@ -146,7 +147,7 @@ int baud_rate = -1;
In mid-1996, remote_timeout was moved from remote.c to top.c and
it began being used in other remote-* targets. It appears that the
default was changed to 20 seconds at that time, perhaps because the
- Hitachi E7000 ICE didn't always respond in a timely manner.
+ Renesas E7000 ICE didn't always respond in a timely manner.
But if 5 seconds is a long time to sit and wait for retransmissions,
20 seconds is far worse. This demonstrates the difficulty of using
@@ -170,6 +171,11 @@ int target_executing = 0;
/* Level of control structure. */
static int control_level;
+/* Sbrk location on entry to main. Used for statistics only. */
+#ifdef HAVE_SBRK
+char *lim_at_start;
+#endif
+
/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */
#ifndef STOP_SIGNAL
@@ -377,6 +383,7 @@ catcher (catch_exceptions_ftype *func,
int *func_val,
enum return_reason *func_caught,
char *errstring,
+ char **gdberrmsg,
return_mask mask)
{
SIGJMP_BUF *saved_catch;
@@ -422,7 +429,14 @@ catcher (catch_exceptions_ftype *func,
if (!caught)
val = (*func) (func_uiout, func_args);
else
- val = 0;
+ {
+ val = 0;
+ /* If caller wants a copy of the low-level error message, make one.
+ This is used in the case of a silent error whereby the caller
+ may optionally want to issue the message. */
+ if (gdberrmsg)
+ *gdberrmsg = error_last_message ();
+ }
catch_return = saved_catch;
/* FIXME: cagney/1999-11-05: A correct FUNC implementation will
@@ -470,7 +484,25 @@ catch_exceptions (struct ui_out *uiout,
{
int val;
enum return_reason caught;
- catcher (func, uiout, func_args, &val, &caught, errstring, mask);
+ catcher (func, uiout, func_args, &val, &caught, errstring, NULL, mask);
+ gdb_assert (val >= 0);
+ gdb_assert (caught <= 0);
+ if (caught < 0)
+ return caught;
+ return val;
+}
+
+int
+catch_exceptions_with_msg (struct ui_out *uiout,
+ catch_exceptions_ftype *func,
+ void *func_args,
+ char *errstring,
+ char **gdberrmsg,
+ return_mask mask)
+{
+ int val;
+ enum return_reason caught;
+ catcher (func, uiout, func_args, &val, &caught, errstring, gdberrmsg, mask);
gdb_assert (val >= 0);
gdb_assert (caught <= 0);
if (caught < 0)
@@ -484,7 +516,7 @@ struct catch_errors_args
void *func_args;
};
-int
+static int
do_catch_errors (struct ui_out *uiout, void *data)
{
struct catch_errors_args *args = data;
@@ -500,7 +532,8 @@ catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
struct catch_errors_args args;
args.func = func;
args.func_args = func_args;
- catcher (do_catch_errors, uiout, &args, &val, &caught, errstring, mask);
+ catcher (do_catch_errors, uiout, &args, &val, &caught, errstring,
+ NULL, mask);
if (caught != 0)
return 0;
return val;
@@ -634,8 +667,8 @@ do_chdir_cleanup (void *old_dir)
void
execute_command (char *p, int from_tty)
{
- register struct cmd_list_element *c;
- register enum language flang;
+ struct cmd_list_element *c;
+ enum language flang;
static int warned = 0;
char *line;
@@ -663,10 +696,10 @@ execute_command (char *p, int from_tty)
/* If the target is running, we allow only a limited set of
commands. */
if (event_loop_p && target_can_async_p () && target_executing)
- if (!strcmp (c->name, "help")
- && !strcmp (c->name, "pwd")
- && !strcmp (c->name, "show")
- && !strcmp (c->name, "stop"))
+ if (strcmp (c->name, "help") != 0
+ && strcmp (c->name, "pwd") != 0
+ && strcmp (c->name, "show") != 0
+ && strcmp (c->name, "stop") != 0)
error ("Cannot execute this command while the target is running.");
/* Pass null arg rather than an empty one. */
@@ -693,12 +726,7 @@ execute_command (char *p, int from_tty)
}
/* If this command has been pre-hooked, run the hook first. */
- if ((c->hook_pre) && (!c->hook_in))
- {
- c->hook_in = 1; /* Prevent recursive hooking */
- execute_user_command (c->hook_pre, (char *) 0);
- c->hook_in = 0; /* Allow hook to work again once it is complete */
- }
+ execute_cmd_pre_hook (c);
if (c->flags & DEPRECATED_WARN_USER)
deprecated_cmd_warning (&line);
@@ -707,20 +735,15 @@ 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. */
- if ((c->hook_post) && (!c->hook_in))
- {
- c->hook_in = 1; /* Prevent recursive hooking */
- execute_user_command (c->hook_post, (char *) 0);
- c->hook_in = 0; /* allow hook to work again once it is complete */
- }
+ execute_cmd_post_hook (c);
}
@@ -791,10 +814,8 @@ command_loop (void)
if (display_space)
{
#ifdef HAVE_SBRK
- extern char **environ;
char *lim = (char *) sbrk (0);
-
- space_at_cmd_start = (long) (lim - (char *) &environ);
+ space_at_cmd_start = lim - lim_at_start;
#endif
}
@@ -814,9 +835,8 @@ command_loop (void)
if (display_space)
{
#ifdef HAVE_SBRK
- extern char **environ;
char *lim = (char *) sbrk (0);
- long space_now = lim - (char *) &environ;
+ long space_now = lim - lim_at_start;
long space_diff = space_now - space_at_cmd_start;
printf_unfiltered ("Space used: %ld (%c%ld for this command)\n",
@@ -956,6 +976,29 @@ static int write_history_p;
static int history_size;
static char *history_filename;
+/* This is like readline(), but it has some gdb-specific behavior.
+ gdb can use readline in both the synchronous and async modes during
+ a single gdb invocation. At the ordinary top-level prompt we might
+ be using the async readline. That means we can't use
+ rl_pre_input_hook, since it doesn't work properly in async mode.
+ However, for a secondary prompt (" >", such as occurs during a
+ `define'), gdb just calls readline() directly, running it in
+ synchronous mode. So for operate-and-get-next to work in this
+ situation, we have to switch the hooks around. That is what
+ gdb_readline_wrapper is for. */
+char *
+gdb_readline_wrapper (char *prompt)
+{
+ /* Set the hook that works in this case. */
+ if (event_loop_p && after_char_processing_hook)
+ {
+ rl_pre_input_hook = (Function *) after_char_processing_hook;
+ after_char_processing_hook = NULL;
+ }
+
+ return readline (prompt);
+}
+
#ifdef STOP_SIGNAL
static void
@@ -1045,8 +1088,8 @@ static int operate_saved_history = -1;
/* This is put on the appropriate hook and helps operate-and-get-next
do its work. */
-void
-gdb_rl_operate_and_get_next_completion ()
+static void
+gdb_rl_operate_and_get_next_completion (void)
{
int delta = where_history () - operate_saved_history;
/* The `key' argument to rl_get_previous_history is ignored. */
@@ -1068,6 +1111,8 @@ gdb_rl_operate_and_get_next_completion ()
static int
gdb_rl_operate_and_get_next (int count, int key)
{
+ int where;
+
if (event_loop_p)
{
/* Use the async hook. */
@@ -1080,8 +1125,20 @@ gdb_rl_operate_and_get_next (int count, int key)
rl_pre_input_hook = (Function *) gdb_rl_operate_and_get_next_completion;
}
- /* Add 1 because we eventually want the next line. */
- operate_saved_history = where_history () + 1;
+ /* Find the current line, and find the next line to use. */
+ where = where_history();
+
+ /* FIXME: kettenis/20020817: max_input_history is renamed into
+ history_max_entries in readline-4.2. When we do a new readline
+ import, we should probably change it here too, even though
+ readline maintains backwards compatibility for now by still
+ defining max_input_history. */
+ if ((history_is_stifled () && (history_length >= max_input_history)) ||
+ (where >= history_length - 1))
+ operate_saved_history = where;
+ else
+ operate_saved_history = where + 1;
+
return rl_newline (1, key);
}
@@ -1105,7 +1162,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
{
static char *linebuffer = 0;
static unsigned linelength = 0;
- register char *p;
+ char *p;
char *p1;
char *rl;
char *local_prompt = prompt_arg;
@@ -1171,9 +1228,9 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
if (annotation_level > 1 && instream == stdin)
{
- printf_unfiltered ("\n\032\032pre-");
- printf_unfiltered (annotation_suffix);
- printf_unfiltered ("\n");
+ puts_unfiltered ("\n\032\032pre-");
+ puts_unfiltered (annotation_suffix);
+ puts_unfiltered ("\n");
}
/* Don't use fancy stuff if not talking to stdin. */
@@ -1183,7 +1240,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
}
else if (command_editing_p && instream == stdin && ISATTY (instream))
{
- rl = readline (local_prompt);
+ rl = gdb_readline_wrapper (local_prompt);
}
else
{
@@ -1192,9 +1249,9 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
if (annotation_level > 1 && instream == stdin)
{
- printf_unfiltered ("\n\032\032post-");
- printf_unfiltered (annotation_suffix);
- printf_unfiltered ("\n");
+ puts_unfiltered ("\n\032\032post-");
+ puts_unfiltered (annotation_suffix);
+ puts_unfiltered ("\n");
}
if (!rl || rl == (char *) EOF)
@@ -1236,7 +1293,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
#define SERVER_COMMAND_LENGTH 7
server_command =
(p - linebuffer > SERVER_COMMAND_LENGTH)
- && STREQN (linebuffer, "server ", SERVER_COMMAND_LENGTH);
+ && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0;
if (server_command)
{
/* Note that we don't set `line'. Between this and the check in
@@ -1329,7 +1386,7 @@ print_gdb_version (struct ui_file *stream)
/* Second line is a copyright notice. */
- fprintf_filtered (stream, "Copyright 2002 Free Software Foundation, Inc.\n");
+ fprintf_filtered (stream, "Copyright 2004 Free Software Foundation, Inc.\n");
/* Following the copyright is a brief statement that the program is
free software, that users are free to copy and change it on
@@ -1345,7 +1402,7 @@ There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n"
/* After the required info we print the configuration information. */
fprintf_filtered (stream, "This GDB was configured as \"");
- if (!STREQ (host_name, target_name))
+ if (strcmp (host_name, target_name) != 0)
{
fprintf_filtered (stream, "--host=%s --target=%s", host_name, target_name);
}
@@ -1358,267 +1415,13 @@ There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n"
/* get_prompt: access method for the GDB prompt string. */
-#define MAX_PROMPT_SIZE 256
-
-/*
- * int get_prompt_1 (char * buf);
- *
- * Work-horse for get_prompt (called via catch_errors).
- * Argument is buffer to hold the formatted prompt.
- *
- * Returns: 1 for success (use formatted prompt)
- * 0 for failure (use gdb_prompt_string).
- */
-
-static int gdb_prompt_escape;
-
-static int
-get_prompt_1 (void *data)
-{
- char *formatted_prompt = data;
- char *local_prompt;
-
- if (event_loop_p)
- local_prompt = PROMPT (0);
- else
- local_prompt = gdb_prompt_string;
-
-
- if (gdb_prompt_escape == 0)
- {
- return 0; /* do no formatting */
- }
- else
- /* formatted prompt */
- {
- char fmt[40], *promptp, *outp, *tmp;
- struct value *arg_val;
- DOUBLEST doubleval;
- LONGEST longval;
- CORE_ADDR addrval;
-
- int i, len;
- struct type *arg_type, *elt_type;
-
- promptp = local_prompt;
- outp = formatted_prompt;
-
- while (*promptp != '\0')
- {
- int available = MAX_PROMPT_SIZE - (outp - formatted_prompt) - 1;
-
- if (*promptp != gdb_prompt_escape)
- {
- if (available >= 1) /* overflow protect */
- *outp++ = *promptp++;
- }
- else
- {
- /* GDB prompt string contains escape char. Parse for arg.
- Two consecutive escape chars followed by arg followed by
- a comma means to insert the arg using a default format.
- Otherwise a printf format string may be included between
- the two escape chars. eg:
- %%foo, insert foo using default format
- %2.2f%foo, insert foo using "%2.2f" format
- A mismatch between the format string and the data type
- of "foo" is an error (which we don't know how to protect
- against). */
-
- fmt[0] = '\0'; /* assume null format string */
- if (promptp[1] == gdb_prompt_escape) /* double esc char */
- {
- promptp += 2; /* skip past two escape chars. */
- }
- else
- {
- /* extract format string from between two esc chars */
- i = 0;
- do
- {
- fmt[i++] = *promptp++; /* copy format string */
- }
- while (i < sizeof (fmt) - 1 &&
- *promptp != gdb_prompt_escape &&
- *promptp != '\0');
-
- if (*promptp != gdb_prompt_escape)
- error ("Syntax error at prompt position %d",
- promptp - local_prompt);
- else
- {
- promptp++; /* skip second escape char */
- fmt[i++] = '\0'; /* terminate the format string */
- }
- }
-
- arg_val = parse_to_comma_and_eval (&promptp);
- if (*promptp == ',')
- promptp++; /* skip past the comma */
- arg_type = check_typedef (VALUE_TYPE (arg_val));
- switch (TYPE_CODE (arg_type))
- {
- case TYPE_CODE_ARRAY:
- elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
- if (TYPE_LENGTH (arg_type) > 0 &&
- TYPE_LENGTH (elt_type) == 1 &&
- TYPE_CODE (elt_type) == TYPE_CODE_INT)
- {
- int len = TYPE_LENGTH (arg_type);
-
- if (VALUE_LAZY (arg_val))
- value_fetch_lazy (arg_val);
- tmp = VALUE_CONTENTS (arg_val);
-
- if (len > available)
- len = available; /* overflow protect */
-
- /* FIXME: how to protect GDB from crashing
- from bad user-supplied format string? */
- if (fmt[0] != 0)
- sprintf (outp, fmt, tmp);
- else
- strncpy (outp, tmp, len);
- outp[len] = '\0';
- }
- break;
- case TYPE_CODE_PTR:
- elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
- addrval = value_as_address (arg_val);
-
- if (TYPE_LENGTH (elt_type) == 1 &&
- TYPE_CODE (elt_type) == TYPE_CODE_INT &&
- addrval != 0)
- {
- /* display it as a string */
- char *default_fmt = "%s";
- char *tmp;
- int err = 0;
-
- /* Limiting the number of bytes that the following call
- will read protects us from sprintf overflow later. */
- i = target_read_string (addrval, /* src */
- &tmp, /* dest */
- available, /* len */
- &err);
- if (err) /* read failed */
- error ("%s on target_read", safe_strerror (err));
-
- tmp[i] = '\0'; /* force-terminate string */
- /* FIXME: how to protect GDB from crashing
- from bad user-supplied format string? */
- sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
- tmp);
- xfree (tmp);
- }
- else
- {
- /* display it as a pointer */
- char *default_fmt = "0x%x";
-
- /* FIXME: how to protect GDB from crashing
- from bad user-supplied format string? */
- if (available >= 16 /*? */ ) /* overflow protect */
- sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
- (long) addrval);
- }
- break;
- case TYPE_CODE_FLT:
- {
- char *default_fmt = "%g";
-
- doubleval = value_as_double (arg_val);
- /* FIXME: how to protect GDB from crashing
- from bad user-supplied format string? */
- if (available >= 16 /*? */ ) /* overflow protect */
- sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
- (double) doubleval);
- break;
- }
- case TYPE_CODE_INT:
- {
- char *default_fmt = "%d";
-
- longval = value_as_long (arg_val);
- /* FIXME: how to protect GDB from crashing
- from bad user-supplied format string? */
- if (available >= 16 /*? */ ) /* overflow protect */
- sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
- (long) longval);
- break;
- }
- case TYPE_CODE_BOOL:
- {
- /* no default format for bool */
- longval = value_as_long (arg_val);
- if (available >= 8 /*? */ ) /* overflow protect */
- {
- if (longval)
- strcpy (outp, "<true>");
- else
- strcpy (outp, "<false>");
- }
- break;
- }
- case TYPE_CODE_ENUM:
- {
- /* no default format for enum */
- longval = value_as_long (arg_val);
- len = TYPE_NFIELDS (arg_type);
- /* find enum name if possible */
- for (i = 0; i < len; i++)
- if (TYPE_FIELD_BITPOS (arg_type, i) == longval)
- break; /* match -- end loop */
-
- if (i < len) /* enum name found */
- {
- char *name = TYPE_FIELD_NAME (arg_type, i);
-
- strncpy (outp, name, available);
- /* in casel available < strlen (name), */
- outp[available] = '\0';
- }
- else
- {
- if (available >= 16 /*? */ ) /* overflow protect */
- sprintf (outp, "%ld", (long) longval);
- }
- break;
- }
- case TYPE_CODE_VOID:
- *outp = '\0';
- break; /* void type -- no output */
- default:
- error ("bad data type at prompt position %d",
- promptp - local_prompt);
- break;
- }
- outp += strlen (outp);
- }
- }
- *outp++ = '\0'; /* terminate prompt string */
- return 1;
- }
-}
-
char *
get_prompt (void)
{
- static char buf[MAX_PROMPT_SIZE];
-
- if (catch_errors (get_prompt_1, buf, "bad formatted prompt: ",
- RETURN_MASK_ALL))
- {
- return &buf[0]; /* successful formatted prompt */
- }
+ if (event_loop_p)
+ return PROMPT (0);
else
- {
- /* Prompt could not be formatted. */
- if (event_loop_p)
- return PROMPT (0);
- else
- return gdb_prompt_string;
- }
+ return gdb_prompt_string;
}
void
@@ -1656,39 +1459,36 @@ quit_confirm (void)
else
s = "The program is running. Exit anyway? ";
- if (!query (s))
+ if (!query ("%s", s))
return 0;
}
return 1;
}
-/* Quit without asking for confirmation. */
+/* Helper routine for quit_force that requires error handling. */
-void
-quit_force (char *args, int from_tty)
+struct qt_args
{
- int exit_code = 0;
-
- /* An optional expression may be used to cause gdb to terminate with the
- value of that expression. */
- if (args)
- {
- struct value *val = parse_and_eval (args);
+ char *args;
+ int from_tty;
+};
- exit_code = (int) value_as_long (val);
- }
+static int
+quit_target (void *arg)
+{
+ struct qt_args *qt = (struct qt_args *)arg;
if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
{
if (attach_flag)
- target_detach (args, from_tty);
+ target_detach (qt->args, qt->from_tty);
else
- target_kill ();
+ target_kill ();
}
/* UDI wants this, to kill the TIP. */
- target_close (1);
+ target_close (&current_target, 1);
/* Save the history information if it is appropriate to do so. */
if (write_history_p && history_filename)
@@ -1696,6 +1496,33 @@ quit_force (char *args, int from_tty)
do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before exiting */
+ return 0;
+}
+
+/* Quit without asking for confirmation. */
+
+void
+quit_force (char *args, int from_tty)
+{
+ int exit_code = 0;
+ struct qt_args qt;
+
+ /* An optional expression may be used to cause gdb to terminate with the
+ value of that expression. */
+ if (args)
+ {
+ struct value *val = parse_and_eval (args);
+
+ exit_code = (int) value_as_long (val);
+ }
+
+ qt.args = args;
+ qt.from_tty = from_tty;
+
+ /* We want to handle any quit errors and exit regardless. */
+ catch_errors (quit_target, &qt,
+ "Quitting: ", RETURN_MASK_ALL);
+
exit (exit_code);
}
@@ -1708,7 +1535,6 @@ input_from_terminal_p (void)
return gdb_has_a_terminal () && (instream == stdin) & caution;
}
-/* ARGSUSED */
static void
dont_repeat_command (char *ignored, int from_tty)
{
@@ -1794,7 +1620,6 @@ show_commands (char *args, int from_tty)
}
/* Called by do_setshow_command. */
-/* ARGSUSED */
static void
set_history_size_command (char *args, int from_tty, struct cmd_list_element *c)
{
@@ -1809,7 +1634,6 @@ set_history_size_command (char *args, int from_tty, struct cmd_list_element *c)
}
}
-/* ARGSUSED */
void
set_history (char *args, int from_tty)
{
@@ -1817,7 +1641,6 @@ set_history (char *args, int from_tty)
help_list (sethistlist, "set history ", -1, gdb_stdout);
}
-/* ARGSUSED */
void
show_history (char *args, int from_tty)
{
@@ -1827,7 +1650,6 @@ show_history (char *args, int from_tty)
int info_verbose = 0; /* Default verbose msgs off */
/* Called by do_setshow_command. An elaborate joke. */
-/* ARGSUSED */
void
set_verbose (char *args, int from_tty, struct cmd_list_element *c)
{
@@ -1916,7 +1738,6 @@ init_main (void)
if (annotation_level > 1)
set_async_annotation_level (NULL, 0, NULL);
}
- gdb_prompt_escape = 0; /* default to none. */
/* Set the important stuff up for command editing. */
command_editing_p = 1;
@@ -1924,11 +1745,11 @@ init_main (void)
write_history_p = 0;
/* Setup important stuff for command line editing. */
- rl_completion_entry_function = (int (*)()) readline_line_completion_function;
- rl_completer_word_break_characters =
- get_gdb_completer_word_break_characters ();
+ rl_completion_entry_function = readline_line_completion_function;
+ rl_completer_word_break_characters = default_word_break_characters ();
rl_completer_quote_characters = get_gdb_completer_quote_characters ();
rl_readline_name = "gdb";
+ rl_terminal_name = getenv ("TERM");
/* The name for this defun comes from Bash, where it originated.
15 is Control-o, the same binding this function has in Bash. */
@@ -1955,13 +1776,6 @@ init_main (void)
set_cmd_sfunc (c, set_async_prompt);
}
- add_show_from_set
- (add_set_cmd ("prompt-escape-char", class_support, var_zinteger,
- (char *) &gdb_prompt_escape,
- "Set escape character for formatting of gdb's prompt",
- &setlist),
- &showlist);
-
add_com ("dont-repeat", class_support, dont_repeat_command, "Don't repeat this command.\n\
Primarily used inside of user-defined commands that should not be repeated when\n\
hitting return.");
@@ -1999,7 +1813,7 @@ Without an argument, saving is enabled.", &sethistlist),
&showhistlist);
c = add_set_cmd ("size", no_class, var_integer, (char *) &history_size,
- "Set the size of the command history, \n\
+ "Set the size of the command history,\n\
ie. the number of previous commands to keep a record of.", &sethistlist);
add_show_from_set (c, &showhistlist);
set_cmd_sfunc (c, set_history_size_command);
@@ -2007,8 +1821,8 @@ ie. the number of previous commands to keep a record of.", &sethistlist);
c = add_set_cmd ("filename", no_class, var_filename,
(char *) &history_filename,
"Set the filename in which to record the command history\n\
- (the list of previous commands of which a record is kept).", &sethistlist);
- c->completer = filename_completer;
+(the list of previous commands of which a record is kept).", &sethistlist);
+ set_cmd_completer (c, filename_completer);
add_show_from_set (c, &showhistlist);
add_show_from_set
@@ -2095,19 +1909,4 @@ gdb_init (char *argv0)
it wants GDB to revert to the CLI, it should clear init_ui_hook. */
if (init_ui_hook)
init_ui_hook (argv0);
-
- /* Install the default UI */
- if (!init_ui_hook)
- {
- uiout = cli_out_new (gdb_stdout);
-
- /* All the interpreters should have had a look at things by now.
- Initialize the selected interpreter. */
- if (interpreter_p)
- {
- fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n",
- interpreter_p);
- exit (1);
- }
- }
}
diff --git a/contrib/gdb/gdb/utils.c b/contrib/gdb/gdb/utils.c
index 75f65e1..30ccebe 100644
--- a/contrib/gdb/gdb/utils.c
+++ b/contrib/gdb/gdb/utils.c
@@ -1,7 +1,8 @@
/* General utility routines for GDB, the GNU debugger.
+
Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
This file is part of GDB.
@@ -20,29 +21,16 @@
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
- "defs.h" should be included first. Unfortunatly some systems
- (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
- and they clash with "bfd.h"'s definiton of true/false. The correct
- fix is to remove true/false from "bfd.h", however, until that
- happens, hack around it by including "config.h" and <curses.h>
- first. */
-
-#include "config.h"
-
-#ifdef HAVE_CURSES_H
-#include <curses.h>
-#endif
-#ifdef HAVE_TERM_H
-#include <term.h>
-#endif
-
#include "defs.h"
#include "gdb_assert.h"
#include <ctype.h>
#include "gdb_string.h"
#include "event-top.h"
+#ifdef TUI
+#include "tui/tui.h" /* For tui_get_command_dimension. */
+#endif
+
#ifdef __GO32__
#include <pc.h>
#endif
@@ -60,23 +48,28 @@
#include "demangle.h"
#include "expression.h"
#include "language.h"
+#include "charset.h"
#include "annotate.h"
+#include "filenames.h"
-#include "inferior.h" /* for signed_pointer_to_address */
+#include "inferior.h" /* for signed_pointer_to_address */
#include <sys/param.h> /* For MAXPATHLEN */
-#include <readline/readline.h>
-
-#ifdef USE_MMALLOC
-#include "mmalloc.h"
+#ifdef HAVE_CURSES_H
+#include <curses.h>
#endif
+#ifdef HAVE_TERM_H
+#include <term.h>
+#endif
+
+#include "readline/readline.h"
#ifdef NEED_DECLARATION_MALLOC
-extern PTR malloc ();
+extern PTR malloc (); /* OK: PTR */
#endif
#ifdef NEED_DECLARATION_REALLOC
-extern PTR realloc ();
+extern PTR realloc (); /* OK: PTR */
#endif
#ifdef NEED_DECLARATION_FREE
extern void free ();
@@ -87,9 +80,6 @@ extern void free ();
extern char *canonicalize_file_name (const char *);
#endif
-#undef XMALLOC
-#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
-
/* readline defines this. */
#undef savestring
@@ -106,14 +96,11 @@ static void vfprintf_maybe_filtered (struct ui_file *, const char *,
static void fputs_maybe_filtered (const char *, struct ui_file *, int);
-#if defined (USE_MMALLOC) && !defined (NO_MMCHECK)
-static void malloc_botch (void);
-#endif
+static void do_my_cleanups (struct cleanup **, struct cleanup *);
static void prompt_for_continue (void);
-static void set_width_command (char *, int, struct cmd_list_element *);
-
+static void set_screen_size (void);
static void set_width (void);
/* Chain of cleanup actions established with make_cleanup,
@@ -124,7 +111,7 @@ static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */
static struct cleanup *run_cleanup_chain; /* cleaned up on each 'run' */
static struct cleanup *exec_cleanup_chain; /* cleaned up on each execution command */
/* cleaned up on each error from within an execution command */
-static struct cleanup *exec_error_cleanup_chain;
+static struct cleanup *exec_error_cleanup_chain;
/* Pointer to what is left to do for an execution command after the
target stops. Used only in asynchronous mode, by targets that
@@ -154,13 +141,13 @@ int quit_flag;
int immediate_quit;
-/* Nonzero means that encoded C++ names should be printed out in their
- C++ form rather than raw. */
+/* Nonzero means that encoded C++/ObjC names should be printed out in their
+ C++/ObjC form rather than raw. */
int demangle = 1;
-/* Nonzero means that encoded C++ names should be printed out in their
- C++ form even in assembler language displays. If this is set, but
+/* Nonzero means that encoded C++/ObjC names should be printed out in their
+ C++/ObjC form even in assembler language displays. If this is set, but
DEMANGLE is zero, names are printed raw, i.e. DEMANGLE controls. */
int asm_demangle = 0;
@@ -277,9 +264,9 @@ struct cleanup *
make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
void *arg)
{
- register struct cleanup *new
- = (struct cleanup *) xmalloc (sizeof (struct cleanup));
- register struct cleanup *old_chain = *pmy_chain;
+ struct cleanup *new
+ = (struct cleanup *) xmalloc (sizeof (struct cleanup));
+ struct cleanup *old_chain = *pmy_chain;
new->next = *pmy_chain;
new->function = function;
@@ -293,40 +280,40 @@ make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
until we get back to the point OLD_CHAIN in the cleanup_chain. */
void
-do_cleanups (register struct cleanup *old_chain)
+do_cleanups (struct cleanup *old_chain)
{
do_my_cleanups (&cleanup_chain, old_chain);
}
void
-do_final_cleanups (register struct cleanup *old_chain)
+do_final_cleanups (struct cleanup *old_chain)
{
do_my_cleanups (&final_cleanup_chain, old_chain);
}
void
-do_run_cleanups (register struct cleanup *old_chain)
+do_run_cleanups (struct cleanup *old_chain)
{
do_my_cleanups (&run_cleanup_chain, old_chain);
}
void
-do_exec_cleanups (register struct cleanup *old_chain)
+do_exec_cleanups (struct cleanup *old_chain)
{
do_my_cleanups (&exec_cleanup_chain, old_chain);
}
void
-do_exec_error_cleanups (register struct cleanup *old_chain)
+do_exec_error_cleanups (struct cleanup *old_chain)
{
do_my_cleanups (&exec_error_cleanup_chain, old_chain);
}
-void
-do_my_cleanups (register struct cleanup **pmy_chain,
- register struct cleanup *old_chain)
+static void
+do_my_cleanups (struct cleanup **pmy_chain,
+ struct cleanup *old_chain)
{
- register struct cleanup *ptr;
+ struct cleanup *ptr;
while ((ptr = *pmy_chain) != old_chain)
{
*pmy_chain = ptr->next; /* Do this first incase recursion */
@@ -339,28 +326,28 @@ do_my_cleanups (register struct cleanup **pmy_chain,
until we get back to the point OLD_CHAIN in the cleanup_chain. */
void
-discard_cleanups (register struct cleanup *old_chain)
+discard_cleanups (struct cleanup *old_chain)
{
discard_my_cleanups (&cleanup_chain, old_chain);
}
void
-discard_final_cleanups (register struct cleanup *old_chain)
+discard_final_cleanups (struct cleanup *old_chain)
{
discard_my_cleanups (&final_cleanup_chain, old_chain);
}
void
-discard_exec_error_cleanups (register struct cleanup *old_chain)
+discard_exec_error_cleanups (struct cleanup *old_chain)
{
discard_my_cleanups (&exec_error_cleanup_chain, old_chain);
}
void
-discard_my_cleanups (register struct cleanup **pmy_chain,
- register struct cleanup *old_chain)
+discard_my_cleanups (struct cleanup **pmy_chain,
+ struct cleanup *old_chain)
{
- register struct cleanup *ptr;
+ struct cleanup *ptr;
while ((ptr = *pmy_chain) != old_chain)
{
*pmy_chain = ptr->next;
@@ -438,7 +425,6 @@ free_current_contents (void *ptr)
In such cases, we may not be certain where the first cleanup is, unless
we have a do-nothing one to always use as the base. */
-/* ARGSUSED */
void
null_cleanup (void *arg)
{
@@ -452,7 +438,8 @@ add_continuation (void (*continuation_hook) (struct continuation_arg *),
{
struct continuation *continuation_ptr;
- continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation));
+ continuation_ptr =
+ (struct continuation *) xmalloc (sizeof (struct continuation));
continuation_ptr->continuation_hook = continuation_hook;
continuation_ptr->arg_list = arg_list;
continuation_ptr->next = cmd_continuation;
@@ -482,12 +469,12 @@ do_all_continuations (void)
/* Work now on the list we have set aside. */
while (continuation_ptr)
- {
- (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
- saved_continuation = continuation_ptr;
- continuation_ptr = continuation_ptr->next;
- xfree (saved_continuation);
- }
+ {
+ (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
+ saved_continuation = continuation_ptr;
+ continuation_ptr = continuation_ptr->next;
+ xfree (saved_continuation);
+ }
}
/* Walk down the cmd_continuation list, and get rid of all the
@@ -514,7 +501,8 @@ add_intermediate_continuation (void (*continuation_hook)
{
struct continuation *continuation_ptr;
- continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation));
+ continuation_ptr =
+ (struct continuation *) xmalloc (sizeof (struct continuation));
continuation_ptr->continuation_hook = continuation_hook;
continuation_ptr->arg_list = arg_list;
continuation_ptr->next = intermediate_continuation;
@@ -544,12 +532,12 @@ do_all_intermediate_continuations (void)
/* Work now on the list we have set aside. */
while (continuation_ptr)
- {
- (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
- saved_continuation = continuation_ptr;
- continuation_ptr = continuation_ptr->next;
- xfree (saved_continuation);
- }
+ {
+ (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
+ saved_continuation = continuation_ptr;
+ continuation_ptr = continuation_ptr->next;
+ xfree (saved_continuation);
+ }
}
/* Walk down the cmd_continuation list, and get rid of all the
@@ -566,9 +554,9 @@ discard_all_intermediate_continuations (void)
xfree (continuation_ptr);
}
}
-
+
/* Print a warning message. The first argument STRING is the warning
message, used as an fprintf format string, the second is the
va_list of arguments for that string. A warning is unfiltered (not
@@ -586,7 +574,7 @@ vwarning (const char *string, va_list args)
wrap_here (""); /* Force out any buffered output */
gdb_flush (gdb_stdout);
if (warning_pre_print)
- fprintf_unfiltered (gdb_stderr, warning_pre_print);
+ fputs_unfiltered (warning_pre_print, gdb_stderr);
vfprintf_unfiltered (gdb_stderr, string, args);
fprintf_unfiltered (gdb_stderr, "\n");
va_end (args);
@@ -600,7 +588,7 @@ vwarning (const char *string, va_list args)
does not force the return to command level. */
void
-warning (const char *string,...)
+warning (const char *string, ...)
{
va_list args;
va_start (args, string);
@@ -622,7 +610,7 @@ verror (const char *string, va_list args)
}
NORETURN void
-error (const char *string,...)
+error (const char *string, ...)
{
va_list args;
va_start (args, string);
@@ -636,6 +624,38 @@ do_write (void *data, const char *buffer, long length_buffer)
ui_file_write (data, buffer, length_buffer);
}
+/* Cause a silent error to occur. Any error message is recorded
+ though it is not issued. */
+NORETURN void
+error_silent (const char *string, ...)
+{
+ va_list args;
+ struct ui_file *tmp_stream = mem_fileopen ();
+ va_start (args, string);
+ make_cleanup_ui_file_delete (tmp_stream);
+ vfprintf_unfiltered (tmp_stream, string, args);
+ /* Copy the stream into the GDB_LASTERR buffer. */
+ ui_file_rewind (gdb_lasterr);
+ ui_file_put (tmp_stream, do_write, gdb_lasterr);
+ va_end (args);
+
+ throw_exception (RETURN_ERROR);
+}
+
+/* Output an error message including any pre-print text to gdb_stderr. */
+void
+error_output_message (char *pre_print, char *msg)
+{
+ target_terminal_ours ();
+ wrap_here (""); /* Force out any buffered output */
+ gdb_flush (gdb_stdout);
+ annotate_error_begin ();
+ if (pre_print)
+ fputs_filtered (pre_print, gdb_stderr);
+ fputs_filtered (msg, gdb_stderr);
+ fprintf_filtered (gdb_stderr, "\n");
+}
+
NORETURN void
error_stream (struct ui_file *stream)
{
@@ -652,7 +672,7 @@ error_stream (struct ui_file *stream)
gdb_flush (gdb_stdout);
annotate_error_begin ();
if (error_pre_print)
- fprintf_filtered (gdb_stderr, error_pre_print);
+ fputs_filtered (error_pre_print, gdb_stderr);
ui_file_put (stream, do_write, gdb_stderr);
fprintf_filtered (gdb_stderr, "\n");
@@ -667,7 +687,7 @@ error_last_message (void)
long len;
return ui_file_xstrdup (gdb_lasterr, &len);
}
-
+
/* This is to be called by main() at the very beginning */
void
@@ -676,56 +696,112 @@ error_init (void)
gdb_lasterr = mem_fileopen ();
}
-/* Print a message reporting an internal error. Ask the user if they
- want to continue, dump core, or just exit. */
+/* Print a message reporting an internal error/warning. Ask the user
+ if they want to continue, dump core, or just exit. Return
+ something to indicate a quit. */
-NORETURN void
-internal_verror (const char *file, int line,
- const char *fmt, va_list ap)
+struct internal_problem
{
- static char msg[] = "Internal GDB error: recursive internal error.\n";
- static int dejavu = 0;
+ const char *name;
+ /* FIXME: cagney/2002-08-15: There should be ``maint set/show''
+ commands available for controlling these variables. */
+ enum auto_boolean should_quit;
+ enum auto_boolean should_dump_core;
+};
+
+/* Report a problem, internal to GDB, to the user. Once the problem
+ has been reported, and assuming GDB didn't quit, the caller can
+ either allow execution to resume or throw an error. */
+
+static void
+internal_vproblem (struct internal_problem *problem,
+ const char *file, int line, const char *fmt, va_list ap)
+{
+ static int dejavu;
int quit_p;
int dump_core_p;
+ char *reason;
+
+ /* Don't allow infinite error/warning recursion. */
+ {
+ static char msg[] = "Recursive internal problem.\n";
+ switch (dejavu)
+ {
+ case 0:
+ dejavu = 1;
+ break;
+ case 1:
+ dejavu = 2;
+ fputs_unfiltered (msg, gdb_stderr);
+ abort (); /* NOTE: GDB has only three calls to abort(). */
+ default:
+ dejavu = 3;
+ write (STDERR_FILENO, msg, sizeof (msg));
+ exit (1);
+ }
+ }
- /* don't allow infinite error recursion. */
- switch (dejavu)
+ /* Try to get the message out and at the start of a new line. */
+ target_terminal_ours ();
+ begin_line ();
+
+ /* Create a string containing the full error/warning message. Need
+ to call query with this full string, as otherwize the reason
+ (error/warning) and question become separated. Format using a
+ style similar to a compiler error message. Include extra detail
+ so that the user knows that they are living on the edge. */
+ {
+ char *msg;
+ xvasprintf (&msg, fmt, ap);
+ xasprintf (&reason, "\
+%s:%d: %s: %s\n\
+A problem internal to GDB has been detected,\n\
+further debugging may prove unreliable.", file, line, problem->name, msg);
+ xfree (msg);
+ make_cleanup (xfree, reason);
+ }
+
+ switch (problem->should_quit)
{
- case 0:
- dejavu = 1;
+ case AUTO_BOOLEAN_AUTO:
+ /* Default (yes/batch case) is to quit GDB. When in batch mode
+ this lessens the likelhood of GDB going into an infinate
+ loop. */
+ quit_p = query ("%s\nQuit this debugging session? ", reason);
+ break;
+ case AUTO_BOOLEAN_TRUE:
+ quit_p = 1;
+ break;
+ case AUTO_BOOLEAN_FALSE:
+ quit_p = 0;
break;
- case 1:
- dejavu = 2;
- fputs_unfiltered (msg, gdb_stderr);
- abort (); /* NOTE: GDB has only three calls to abort(). */
default:
- dejavu = 3;
- write (STDERR_FILENO, msg, sizeof (msg));
- exit (1);
+ internal_error (__FILE__, __LINE__, "bad switch");
}
- /* Try to get the message out */
- target_terminal_ours ();
- fprintf_unfiltered (gdb_stderr, "%s:%d: gdb-internal-error: ", file, line);
- vfprintf_unfiltered (gdb_stderr, fmt, ap);
- fputs_unfiltered ("\n", gdb_stderr);
-
- /* Default (yes/batch case) is to quit GDB. When in batch mode this
- lessens the likelhood of GDB going into an infinate loop. */
- quit_p = query ("\
-An internal GDB error was detected. This may make further\n\
-debugging unreliable. Quit this debugging session? ");
-
- /* Default (yes/batch case) is to dump core. This leaves a GDB
- dropping so that it is easier to see that something went wrong to
- GDB. */
- dump_core_p = query ("\
-Create a core file containing the current state of GDB? ");
+ switch (problem->should_dump_core)
+ {
+ case AUTO_BOOLEAN_AUTO:
+ /* Default (yes/batch case) is to dump core. This leaves a GDB
+ `dropping' so that it is easier to see that something went
+ wrong in GDB. */
+ dump_core_p = query ("%s\nCreate a core file of GDB? ", reason);
+ break;
+ break;
+ case AUTO_BOOLEAN_TRUE:
+ dump_core_p = 1;
+ break;
+ case AUTO_BOOLEAN_FALSE:
+ dump_core_p = 0;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
if (quit_p)
{
if (dump_core_p)
- abort (); /* NOTE: GDB has only three calls to abort(). */
+ abort (); /* NOTE: GDB has only three calls to abort(). */
else
exit (1);
}
@@ -734,11 +810,21 @@ Create a core file containing the current state of GDB? ");
if (dump_core_p)
{
if (fork () == 0)
- abort (); /* NOTE: GDB has only three calls to abort(). */
+ abort (); /* NOTE: GDB has only three calls to abort(). */
}
}
dejavu = 0;
+}
+
+static struct internal_problem internal_error_problem = {
+ "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+};
+
+NORETURN void
+internal_verror (const char *file, int line, const char *fmt, va_list ap)
+{
+ internal_vproblem (&internal_error_problem, file, line, fmt, ap);
throw_exception (RETURN_ERROR);
}
@@ -747,11 +833,29 @@ internal_error (const char *file, int line, const char *string, ...)
{
va_list ap;
va_start (ap, string);
-
internal_verror (file, line, string, ap);
va_end (ap);
}
+static struct internal_problem internal_warning_problem = {
+ "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+};
+
+void
+internal_vwarning (const char *file, int line, const char *fmt, va_list ap)
+{
+ internal_vproblem (&internal_warning_problem, file, line, fmt, ap);
+}
+
+void
+internal_warning (const char *file, int line, const char *string, ...)
+{
+ va_list ap;
+ va_start (ap, string);
+ internal_vwarning (file, line, string, ap);
+ va_end (ap);
+}
+
/* The strerror() function can return NULL for errno values that are
out of range. Provide a "safe" version that always returns a
printable string. */
@@ -762,7 +866,8 @@ safe_strerror (int errnum)
char *msg;
static char buf[32];
- if ((msg = strerror (errnum)) == NULL)
+ msg = strerror (errnum);
+ if (msg == NULL)
{
sprintf (buf, "(undocumented errno %d)", errnum);
msg = buf;
@@ -845,7 +950,7 @@ quit (void)
/* Don't use *_filtered; we don't want to prompt the user to continue. */
if (quit_pre_print)
- fprintf_unfiltered (gdb_stderr, quit_pre_print);
+ fputs_unfiltered (quit_pre_print, gdb_stderr);
#ifdef __MSDOS__
/* No steenking SIGINT will ever be coming our way when the
@@ -853,13 +958,13 @@ quit (void)
fprintf_unfiltered (gdb_stderr, "Quit\n");
#else
if (job_control
- /* If there is no terminal switching for this target, then we can't
- possibly get screwed by the lack of job control. */
+ /* If there is no terminal switching for this target, then we can't
+ possibly get screwed by the lack of job control. */
|| current_target.to_terminal_ours == NULL)
fprintf_unfiltered (gdb_stderr, "Quit\n");
else
fprintf_unfiltered (gdb_stderr,
- "Quit (expect signal SIGINT when the program is resumed)\n");
+ "Quit (expect signal SIGINT when the program is resumed)\n");
#endif
throw_exception (RETURN_QUIT);
}
@@ -874,25 +979,16 @@ request_quit (int signo)
about USG defines and stuff like that. */
signal (signo, request_quit);
-#ifdef REQUEST_QUIT
- REQUEST_QUIT;
-#else
if (immediate_quit)
quit ();
-#endif
}
/* Memory management stuff (malloc friends). */
-#if !defined (USE_MMALLOC)
-
-/* NOTE: These must use PTR so that their definition matches the
- declaration found in "mmalloc.h". */
-
static void *
mmalloc (void *md, size_t size)
{
- return malloc (size); /* NOTE: GDB's only call to malloc() */
+ return malloc (size); /* NOTE: GDB's only call to malloc() */
}
static void *
@@ -901,77 +997,28 @@ mrealloc (void *md, void *ptr, size_t size)
if (ptr == 0) /* Guard against old realloc's */
return mmalloc (md, size);
else
- return realloc (ptr, size); /* NOTE: GDB's only call to ralloc() */
+ return realloc (ptr, size); /* NOTE: GDB's only call to ralloc() */
}
static void *
mcalloc (void *md, size_t number, size_t size)
{
- return calloc (number, size); /* NOTE: GDB's only call to calloc() */
+ return calloc (number, size); /* NOTE: GDB's only call to calloc() */
}
static void
mfree (void *md, void *ptr)
{
- free (ptr); /* NOTE: GDB's only call to free() */
+ free (ptr); /* NOTE: GDB's only call to free() */
}
-#endif /* USE_MMALLOC */
-
-#if !defined (USE_MMALLOC) || defined (NO_MMCHECK)
-
+/* This used to do something interesting with USE_MMALLOC.
+ * It can be retired any time. -- chastain 2004-01-19. */
void
init_malloc (void *md)
{
}
-#else /* Have mmalloc and want corruption checking */
-
-static void
-malloc_botch (void)
-{
- fprintf_unfiltered (gdb_stderr, "Memory corruption\n");
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
-}
-
-/* Attempt to install hooks in mmalloc/mrealloc/mfree for the heap specified
- by MD, to detect memory corruption. Note that MD may be NULL to specify
- the default heap that grows via sbrk.
-
- Note that for freshly created regions, we must call mmcheckf prior to any
- mallocs in the region. Otherwise, any region which was allocated prior to
- installing the checking hooks, which is later reallocated or freed, will
- fail the checks! The mmcheck function only allows initial hooks to be
- installed before the first mmalloc. However, anytime after we have called
- mmcheck the first time to install the checking hooks, we can call it again
- to update the function pointer to the memory corruption handler.
-
- Returns zero on failure, non-zero on success. */
-
-#ifndef MMCHECK_FORCE
-#define MMCHECK_FORCE 0
-#endif
-
-void
-init_malloc (void *md)
-{
- if (!mmcheckf (md, malloc_botch, MMCHECK_FORCE))
- {
- /* Don't use warning(), which relies on current_target being set
- to something other than dummy_target, until after
- initialize_all_files(). */
-
- fprintf_unfiltered
- (gdb_stderr, "warning: failed to install memory consistency checks; ");
- fprintf_unfiltered
- (gdb_stderr, "configuration should define NO_MMCHECK or MMCHECK_FORCE\n");
- }
-
- mmtrace ();
-}
-
-#endif /* Have mmalloc and want corruption checking */
-
/* Called when a memory allocation fails, with the number of bytes of
memory requested in SIZE. */
@@ -981,12 +1028,12 @@ nomem (long size)
if (size > 0)
{
internal_error (__FILE__, __LINE__,
- "virtual memory exhausted: can't allocate %ld bytes.", size);
+ "virtual memory exhausted: can't allocate %ld bytes.",
+ size);
}
else
{
- internal_error (__FILE__, __LINE__,
- "virtual memory exhausted.");
+ internal_error (__FILE__, __LINE__, "virtual memory exhausted.");
}
}
@@ -1005,16 +1052,15 @@ xmmalloc (void *md, size_t size)
{
void *val;
+ /* See libiberty/xmalloc.c. This function need's to match that's
+ semantics. It never returns NULL. */
if (size == 0)
- {
- val = NULL;
- }
- else
- {
- val = mmalloc (md, size);
- if (val == NULL)
- nomem (size);
- }
+ size = 1;
+
+ val = mmalloc (md, size);
+ if (val == NULL)
+ nomem (size);
+
return (val);
}
@@ -1023,27 +1069,18 @@ xmrealloc (void *md, void *ptr, size_t size)
{
void *val;
+ /* See libiberty/xmalloc.c. This function need's to match that's
+ semantics. It never returns NULL. */
if (size == 0)
- {
- if (ptr != NULL)
- mfree (md, ptr);
- val = NULL;
- }
+ size = 1;
+
+ if (ptr != NULL)
+ val = mrealloc (md, ptr, size);
else
- {
- if (ptr != NULL)
- {
- val = mrealloc (md, ptr, size);
- }
- else
- {
- val = mmalloc (md, size);
- }
- if (val == NULL)
- {
- nomem (size);
- }
- }
+ val = mmalloc (md, size);
+ if (val == NULL)
+ nomem (size);
+
return (val);
}
@@ -1051,14 +1088,19 @@ void *
xmcalloc (void *md, size_t number, size_t size)
{
void *mem;
+
+ /* See libiberty/xmalloc.c. This function need's to match that's
+ semantics. It never returns NULL. */
if (number == 0 || size == 0)
- mem = NULL;
- else
{
- mem = mcalloc (md, number, size);
- if (mem == NULL)
- nomem (number * size);
+ number = 1;
+ size = 1;
}
+
+ mem = mcalloc (md, number, size);
+ if (mem == NULL)
+ nomem (number * size);
+
return mem;
}
@@ -1080,19 +1122,19 @@ xmfree (void *md, void *ptr)
/* NOTE: These are declared using PTR to ensure consistency with
"libiberty.h". xfree() is GDB local. */
-PTR
+PTR /* OK: PTR */
xmalloc (size_t size)
{
return xmmalloc (NULL, size);
}
-PTR
-xrealloc (PTR ptr, size_t size)
+PTR /* OK: PTR */
+xrealloc (PTR ptr, size_t size) /* OK: PTR */
{
return xmrealloc (NULL, ptr, size);
}
-PTR
+PTR /* OK: PTR */
xcalloc (size_t number, size_t size)
{
return xmcalloc (NULL, number, size);
@@ -1108,6 +1150,17 @@ xfree (void *ptr)
/* Like asprintf/vasprintf but get an internal_error if the call
fails. */
+char *
+xstrprintf (const char *format, ...)
+{
+ char *ret;
+ va_list args;
+ va_start (args, format);
+ xvasprintf (&ret, format, args);
+ va_end (args);
+ return ret;
+}
+
void
xasprintf (char **ret, const char *format, ...)
{
@@ -1125,14 +1178,12 @@ xvasprintf (char **ret, const char *format, va_list ap)
badly format string; or something else. */
if ((*ret) == NULL)
internal_error (__FILE__, __LINE__,
- "vasprintf returned NULL buffer (errno %d)",
- errno);
+ "vasprintf returned NULL buffer (errno %d)", errno);
/* A negative status with a non-NULL buffer shouldn't never
happen. But to be sure. */
if (status < 0)
internal_error (__FILE__, __LINE__,
- "vasprintf call failed (errno %d)",
- errno);
+ "vasprintf call failed (errno %d)", errno);
}
@@ -1142,7 +1193,7 @@ xvasprintf (char **ret, const char *format, va_list ap)
int
myread (int desc, char *addr, int len)
{
- register int val;
+ int val;
int orglen = len;
while (len > 0)
@@ -1165,7 +1216,7 @@ myread (int desc, char *addr, int len)
char *
savestring (const char *ptr, size_t size)
{
- register char *p = (char *) xmalloc (size + 1);
+ char *p = (char *) xmalloc (size + 1);
memcpy (p, ptr, size);
p[size] = 0;
return p;
@@ -1174,7 +1225,7 @@ savestring (const char *ptr, size_t size)
char *
msavestring (void *md, const char *ptr, size_t size)
{
- register char *p = (char *) xmmalloc (md, size + 1);
+ char *p = (char *) xmmalloc (md, size + 1);
memcpy (p, ptr, size);
p[size] = 0;
return p;
@@ -1187,7 +1238,7 @@ mstrsave (void *md, const char *ptr)
}
void
-print_spaces (register int n, register struct ui_file *file)
+print_spaces (int n, struct ui_file *file)
{
fputs_unfiltered (n_spaces (n), file);
}
@@ -1195,7 +1246,7 @@ print_spaces (register int n, register struct ui_file *file)
/* Print a host address. */
void
-gdb_print_host_address (void *addr, struct ui_file *stream)
+gdb_print_host_address (const void *addr, struct ui_file *stream)
{
/* We could use the %p conversion specifier to fprintf if we had any
@@ -1212,11 +1263,11 @@ gdb_print_host_address (void *addr, struct ui_file *stream)
/* VARARGS */
int
-query (const char *ctlstr,...)
+query (const char *ctlstr, ...)
{
va_list args;
- register int answer;
- register int ans2;
+ int answer;
+ int ans2;
int retval;
va_start (args, ctlstr);
@@ -1258,7 +1309,7 @@ query (const char *ctlstr,...)
if (answer != '\n')
do
{
- ans2 = fgetc (stdin);
+ ans2 = fgetc (stdin);
clearerr (stdin);
}
while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
@@ -1284,6 +1335,162 @@ query (const char *ctlstr,...)
}
+/* This function supports the nquery() and yquery() functions.
+ Ask user a y-or-n question and return 0 if answer is no, 1 if
+ answer is yes, or default the answer to the specified default.
+ DEFCHAR is either 'y' or 'n' and refers to the default answer.
+ CTLSTR is the control string and should end in "? ". It should
+ not say how to answer, because we do that.
+ ARGS are the arguments passed along with the CTLSTR argument to
+ printf. */
+
+static int
+defaulted_query (const char *ctlstr, const char defchar, va_list args)
+{
+ int answer;
+ int ans2;
+ int retval;
+ int def_value;
+ char def_answer, not_def_answer;
+ char *y_string, *n_string;
+
+ /* Set up according to which answer is the default. */
+ if (defchar == 'y')
+ {
+ def_value = 1;
+ def_answer = 'Y';
+ not_def_answer = 'N';
+ y_string = "[y]";
+ n_string = "n";
+ }
+ else
+ {
+ def_value = 0;
+ def_answer = 'N';
+ not_def_answer = 'Y';
+ y_string = "y";
+ n_string = "[n]";
+ }
+
+ if (query_hook)
+ {
+ return query_hook (ctlstr, args);
+ }
+
+ /* Automatically answer default value if input is not from a terminal. */
+ if (!input_from_terminal_p ())
+ return def_value;
+
+ while (1)
+ {
+ wrap_here (""); /* Flush any buffered output */
+ gdb_flush (gdb_stdout);
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032pre-query\n");
+
+ vfprintf_filtered (gdb_stdout, ctlstr, args);
+ printf_filtered ("(%s or %s) ", y_string, n_string);
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032query\n");
+
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+
+ answer = fgetc (stdin);
+ clearerr (stdin); /* in case of C-d */
+ if (answer == EOF) /* C-d */
+ {
+ retval = def_value;
+ break;
+ }
+ /* Eat rest of input line, to EOF or newline */
+ if (answer != '\n')
+ do
+ {
+ ans2 = fgetc (stdin);
+ clearerr (stdin);
+ }
+ while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
+
+ if (answer >= 'a')
+ answer -= 040;
+ /* Check answer. For the non-default, the user must specify
+ the non-default explicitly. */
+ if (answer == not_def_answer)
+ {
+ retval = !def_value;
+ break;
+ }
+ /* Otherwise, for the default, the user may either specify
+ the required input or have it default by entering nothing. */
+ if (answer == def_answer || answer == '\n' ||
+ answer == '\r' || answer == EOF)
+ {
+ retval = def_value;
+ break;
+ }
+ /* Invalid entries are not defaulted and require another selection. */
+ printf_filtered ("Please answer %s or %s.\n",
+ y_string, n_string);
+ }
+
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032post-query\n");
+ return retval;
+}
+
+
+/* Ask user a y-or-n question and return 0 if answer is no, 1 if
+ answer is yes, or 0 if answer is defaulted.
+ Takes three args which are given to printf to print the question.
+ The first, a control string, should end in "? ".
+ It should not say how to answer, because we do that. */
+
+int
+nquery (const char *ctlstr, ...)
+{
+ va_list args;
+
+ va_start (args, ctlstr);
+ return defaulted_query (ctlstr, 'n', args);
+ va_end (args);
+}
+
+/* Ask user a y-or-n question and return 0 if answer is no, 1 if
+ answer is yes, or 1 if answer is defaulted.
+ Takes three args which are given to printf to print the question.
+ The first, a control string, should end in "? ".
+ It should not say how to answer, because we do that. */
+
+int
+yquery (const char *ctlstr, ...)
+{
+ va_list args;
+
+ va_start (args, ctlstr);
+ return defaulted_query (ctlstr, 'y', args);
+ va_end (args);
+}
+
+/* Print an error message saying that we couldn't make sense of a
+ \^mumble sequence in a string or character constant. START and END
+ indicate a substring of some larger string that contains the
+ erroneous backslash sequence, missing the initial backslash. */
+static NORETURN int
+no_control_char_error (const char *start, const char *end)
+{
+ int len = end - start;
+ char *copy = alloca (end - start + 1);
+
+ memcpy (copy, start, len);
+ copy[len] = '\0';
+
+ error ("There is no control character `\\%s' in the `%s' character set.",
+ copy, target_charset ());
+}
+
/* Parse a C escape sequence. STRING_PTR points to a variable
containing a pointer to the string to parse. That pointer
should point to the character after the \. That pointer
@@ -1302,67 +1509,91 @@ query (const char *ctlstr,...)
int
parse_escape (char **string_ptr)
{
- register int c = *(*string_ptr)++;
- switch (c)
- {
- case 'a':
- return 007; /* Bell (alert) char */
- case 'b':
- return '\b';
- case 'e': /* Escape character */
- return 033;
- case 'f':
- return '\f';
- case 'n':
- return '\n';
- case 'r':
- return '\r';
- case 't':
- return '\t';
- case 'v':
- return '\v';
- case '\n':
- return -2;
- case 0:
- (*string_ptr)--;
- return 0;
- case '^':
- c = *(*string_ptr)++;
- if (c == '\\')
- c = parse_escape (string_ptr);
- if (c == '?')
- return 0177;
- return (c & 0200) | (c & 037);
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
+ int target_char;
+ int c = *(*string_ptr)++;
+ if (c_parse_backslash (c, &target_char))
+ return target_char;
+ else
+ switch (c)
{
- register int i = c - '0';
- register int count = 0;
- while (++count < 3)
- {
- if ((c = *(*string_ptr)++) >= '0' && c <= '7')
- {
- i *= 8;
- i += c - '0';
- }
- else
- {
- (*string_ptr)--;
- break;
- }
- }
- return i;
+ case '\n':
+ return -2;
+ case 0:
+ (*string_ptr)--;
+ return 0;
+ case '^':
+ {
+ /* Remember where this escape sequence started, for reporting
+ errors. */
+ char *sequence_start_pos = *string_ptr - 1;
+
+ c = *(*string_ptr)++;
+
+ if (c == '?')
+ {
+ /* XXXCHARSET: What is `delete' in the host character set? */
+ c = 0177;
+
+ if (!host_char_to_target (c, &target_char))
+ error ("There is no character corresponding to `Delete' "
+ "in the target character set `%s'.", host_charset ());
+
+ return target_char;
+ }
+ else if (c == '\\')
+ target_char = parse_escape (string_ptr);
+ else
+ {
+ if (!host_char_to_target (c, &target_char))
+ no_control_char_error (sequence_start_pos, *string_ptr);
+ }
+
+ /* Now target_char is something like `c', and we want to find
+ its control-character equivalent. */
+ if (!target_char_to_control_char (target_char, &target_char))
+ no_control_char_error (sequence_start_pos, *string_ptr);
+
+ return target_char;
+ }
+
+ /* XXXCHARSET: we need to use isdigit and value-of-digit
+ methods of the host character set here. */
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ {
+ int i = c - '0';
+ int count = 0;
+ while (++count < 3)
+ {
+ c = (**string_ptr);
+ if (c >= '0' && c <= '7')
+ {
+ (*string_ptr)++;
+ i *= 8;
+ i += c - '0';
+ }
+ else
+ {
+ break;
+ }
+ }
+ return i;
+ }
+ default:
+ if (!host_char_to_target (c, &target_char))
+ error
+ ("The escape sequence `\%c' is equivalent to plain `%c', which"
+ " has no equivalent\n" "in the `%s' character set.", c, c,
+ target_charset ());
+ return target_char;
}
- default:
- return c;
- }
}
/* Print the character C on STREAM as part of the contents of a literal
@@ -1438,19 +1669,21 @@ fputstr_unfiltered (const char *str, int quoter, struct ui_file *stream)
}
void
-fputstrn_unfiltered (const char *str, int n, int quoter, struct ui_file *stream)
+fputstrn_unfiltered (const char *str, int n, int quoter,
+ struct ui_file *stream)
{
int i;
for (i = 0; i < n; i++)
printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter);
}
-
/* Number of lines per page or UINT_MAX if paging is disabled. */
static unsigned int lines_per_page;
+
/* Number of chars per line or UINT_MAX if line folding is disabled. */
static unsigned int chars_per_line;
+
/* Current count of lines printed on this page, chars on this line. */
static unsigned int lines_printed, chars_printed;
@@ -1479,7 +1712,8 @@ static char *wrap_indent;
static int wrap_column;
-/* Inialize the lines and chars per page */
+/* Inialize the number of lines per page and chars per line. */
+
void
init_page_info (void)
{
@@ -1487,68 +1721,67 @@ init_page_info (void)
if (!tui_get_command_dimension (&chars_per_line, &lines_per_page))
#endif
{
- /* These defaults will be used if we are unable to get the correct
- values from termcap. */
+ int rows, cols;
+
#if defined(__GO32__)
- lines_per_page = ScreenRows ();
- chars_per_line = ScreenCols ();
+ rows = ScreenRows ();
+ cols = ScreenCols ();
+ lines_per_page = rows;
+ chars_per_line = cols;
#else
- lines_per_page = 24;
- chars_per_line = 80;
-
-#if !defined (_WIN32)
- /* No termcap under MPW, although might be cool to do something
- by looking at worksheet or console window sizes. */
- /* Initialize the screen height and width from termcap. */
- {
- char *termtype = getenv ("TERM");
-
- /* Positive means success, nonpositive means failure. */
- int status;
+ /* Make sure Readline has initialized its terminal settings. */
+ rl_reset_terminal (NULL);
- /* 2048 is large enough for all known terminals, according to the
- GNU termcap manual. */
- char term_buffer[2048];
+ /* Get the screen size from Readline. */
+ rl_get_screen_size (&rows, &cols);
+ lines_per_page = rows;
+ chars_per_line = cols;
- if (termtype)
- {
- status = tgetent (term_buffer, termtype);
- if (status > 0)
- {
- int val;
- int running_in_emacs = getenv ("EMACS") != NULL;
-
- val = tgetnum ("li");
- if (val >= 0 && !running_in_emacs)
- lines_per_page = val;
- else
- /* The number of lines per page is not mentioned
- in the terminal description. This probably means
- that paging is not useful (e.g. emacs shell window),
- so disable paging. */
- lines_per_page = UINT_MAX;
-
- val = tgetnum ("co");
- if (val >= 0)
- chars_per_line = val;
- }
- }
- }
-#endif /* MPW */
+ /* Readline should have fetched the termcap entry for us. */
+ if (tgetnum ("li") < 0 || getenv ("EMACS"))
+ {
+ /* The number of lines per page is not mentioned in the
+ terminal description. This probably means that paging is
+ not useful (e.g. emacs shell window), so disable paging. */
+ lines_per_page = UINT_MAX;
+ }
+ /* FIXME: Get rid of this junk. */
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-
- /* If there is a better way to determine the window size, use it. */
SIGWINCH_HANDLER (SIGWINCH);
#endif
-#endif
+
/* If the output is not a terminal, don't paginate it. */
if (!ui_file_isatty (gdb_stdout))
lines_per_page = UINT_MAX;
- } /* the command_line_version */
+#endif
+ }
+
+ set_screen_size ();
set_width ();
}
+/* Set the screen size based on LINES_PER_PAGE and CHARS_PER_LINE. */
+
+static void
+set_screen_size (void)
+{
+ int rows = lines_per_page;
+ int cols = chars_per_line;
+
+ if (rows <= 0)
+ rows = INT_MAX;
+
+ if (cols <= 0)
+ rl_get_screen_size (NULL, &cols);
+
+ /* Update Readline's idea of the terminal size. */
+ rl_set_screen_size (rows, cols);
+}
+
+/* Reinitialize WRAP_BUFFER according to the current value of
+ CHARS_PER_LINE. */
+
static void
set_width (void)
{
@@ -1562,16 +1795,22 @@ set_width (void)
}
else
wrap_buffer = (char *) xrealloc (wrap_buffer, chars_per_line + 2);
- wrap_pointer = wrap_buffer; /* Start it at the beginning */
+ wrap_pointer = wrap_buffer; /* Start it at the beginning. */
}
-/* ARGSUSED */
static void
set_width_command (char *args, int from_tty, struct cmd_list_element *c)
{
+ set_screen_size ();
set_width ();
}
+static void
+set_height_command (char *args, int from_tty, struct cmd_list_element *c)
+{
+ set_screen_size ();
+}
+
/* Wait, so the user can read what's on the screen. Prompt the user
to continue by pressing RETURN. */
@@ -1605,7 +1844,7 @@ prompt_for_continue (void)
/* Call readline, not gdb_readline, because GO32 readline handles control-C
whereas control-C to gdb_readline will cause the user to get dumped
out to DOS. */
- ignore = readline (cont_prompt);
+ ignore = gdb_readline_wrapper (cont_prompt);
if (annotation_level > 1)
printf_unfiltered ("\n\032\032post-prompt-for-continue\n");
@@ -1698,6 +1937,51 @@ wrap_here (char *indent)
}
}
+/* Print input string to gdb_stdout, filtered, with wrap,
+ arranging strings in columns of n chars. String can be
+ right or left justified in the column. Never prints
+ trailing spaces. String should never be longer than
+ width. FIXME: this could be useful for the EXAMINE
+ command, which currently doesn't tabulate very well */
+
+void
+puts_filtered_tabular (char *string, int width, int right)
+{
+ int spaces = 0;
+ int stringlen;
+ char *spacebuf;
+
+ gdb_assert (chars_per_line > 0);
+ if (chars_per_line == UINT_MAX)
+ {
+ fputs_filtered (string, gdb_stdout);
+ fputs_filtered ("\n", gdb_stdout);
+ return;
+ }
+
+ if (((chars_printed - 1) / width + 2) * width >= chars_per_line)
+ fputs_filtered ("\n", gdb_stdout);
+
+ if (width >= chars_per_line)
+ width = chars_per_line - 1;
+
+ stringlen = strlen (string);
+
+ if (chars_printed > 0)
+ spaces = width - (chars_printed - 1) % width - 1;
+ if (right)
+ spaces += width - stringlen;
+
+ spacebuf = alloca (spaces + 1);
+ spacebuf[spaces] = '\0';
+ while (spaces--)
+ spacebuf[spaces] = ' ';
+
+ fputs_filtered (spacebuf, gdb_stdout);
+ fputs_filtered (string, gdb_stdout);
+}
+
+
/* Ensure that whatever gets printed next, using the filtered output
commands, starts at the beginning of the line. I.E. if there is
any pending output for the current line, flush it and start a new
@@ -1751,8 +2035,7 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
while (*lineptr)
{
/* Possible new page. */
- if (filter &&
- (lines_printed >= lines_per_page - 1))
+ if (filter && (lines_printed >= lines_per_page - 1))
prompt_for_continue ();
while (*lineptr && *lineptr != '\n')
@@ -1800,7 +2083,7 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
if (wrap_column)
{
fputs_unfiltered (wrap_indent, stream);
- *wrap_pointer = '\0'; /* Null-terminate saved stuff */
+ *wrap_pointer = '\0'; /* Null-terminate saved stuff */
fputs_unfiltered (wrap_buffer, stream); /* and eject it */
/* FIXME, this strlen is what prevents wrap_indent from
containing tabs. However, if we recurse to print it
@@ -2014,7 +2297,7 @@ vprintf_unfiltered (const char *format, va_list args)
}
void
-fprintf_filtered (struct ui_file * stream, const char *format,...)
+fprintf_filtered (struct ui_file *stream, const char *format, ...)
{
va_list args;
va_start (args, format);
@@ -2023,7 +2306,7 @@ fprintf_filtered (struct ui_file * stream, const char *format,...)
}
void
-fprintf_unfiltered (struct ui_file * stream, const char *format,...)
+fprintf_unfiltered (struct ui_file *stream, const char *format, ...)
{
va_list args;
va_start (args, format);
@@ -2035,7 +2318,8 @@ fprintf_unfiltered (struct ui_file * stream, const char *format,...)
Called as fprintfi_filtered (spaces, stream, format, ...); */
void
-fprintfi_filtered (int spaces, struct ui_file * stream, const char *format,...)
+fprintfi_filtered (int spaces, struct ui_file *stream, const char *format,
+ ...)
{
va_list args;
va_start (args, format);
@@ -2047,7 +2331,7 @@ fprintfi_filtered (int spaces, struct ui_file * stream, const char *format,...)
void
-printf_filtered (const char *format,...)
+printf_filtered (const char *format, ...)
{
va_list args;
va_start (args, format);
@@ -2057,7 +2341,7 @@ printf_filtered (const char *format,...)
void
-printf_unfiltered (const char *format,...)
+printf_unfiltered (const char *format, ...)
{
va_list args;
va_start (args, format);
@@ -2069,7 +2353,7 @@ printf_unfiltered (const char *format,...)
Called as printfi_filtered (spaces, format, ...); */
void
-printfi_filtered (int spaces, const char *format,...)
+printfi_filtered (int spaces, const char *format, ...)
{
va_list args;
va_start (args, format);
@@ -2125,7 +2409,7 @@ print_spaces_filtered (int n, struct ui_file *stream)
fputs_filtered (n_spaces (n), stream);
}
-/* C++ demangler stuff. */
+/* C++/ObjC demangler stuff. */
/* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language
LANG, using demangling args ARG_MODE, and print it filtered to STREAM.
@@ -2133,8 +2417,8 @@ print_spaces_filtered (int n, struct ui_file *stream)
demangling is off, the name is printed in its "raw" form. */
void
-fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang,
- int arg_mode)
+fprintf_symbol_filtered (struct ui_file *stream, char *name,
+ enum language lang, int arg_mode)
{
char *demangled;
@@ -2147,21 +2431,7 @@ fprintf_symbol_filtered (struct ui_file *stream, char *name, enum language lang,
}
else
{
- switch (lang)
- {
- case language_cplus:
- demangled = cplus_demangle (name, arg_mode);
- break;
- case language_java:
- demangled = cplus_demangle (name, arg_mode | DMGL_JAVA);
- break;
- case language_chill:
- demangled = chill_demangle (name);
- break;
- default:
- demangled = NULL;
- break;
- }
+ demangled = language_demangle (language_def (lang), name, arg_mode);
fputs_filtered (demangled ? demangled : name, stream);
if (demangled != NULL)
{
@@ -2205,6 +2475,94 @@ strcmp_iw (const char *string1, const char *string2)
}
return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
}
+
+/* This is like strcmp except that it ignores whitespace and treats
+ '(' as the first non-NULL character in terms of ordering. Like
+ strcmp (and unlike strcmp_iw), it returns negative if STRING1 <
+ STRING2, 0 if STRING2 = STRING2, and positive if STRING1 > STRING2
+ according to that ordering.
+
+ If a list is sorted according to this function and if you want to
+ find names in the list that match some fixed NAME according to
+ strcmp_iw(LIST_ELT, NAME), then the place to start looking is right
+ where this function would put NAME.
+
+ Here are some examples of why using strcmp to sort is a bad idea:
+
+ Whitespace example:
+
+ Say your partial symtab contains: "foo<char *>", "goo". Then, if
+ we try to do a search for "foo<char*>", strcmp will locate this
+ after "foo<char *>" and before "goo". Then lookup_partial_symbol
+ will start looking at strings beginning with "goo", and will never
+ see the correct match of "foo<char *>".
+
+ Parenthesis example:
+
+ In practice, this is less like to be an issue, but I'll give it a
+ shot. Let's assume that '$' is a legitimate character to occur in
+ symbols. (Which may well even be the case on some systems.) Then
+ say that the partial symbol table contains "foo$" and "foo(int)".
+ strcmp will put them in this order, since '$' < '('. Now, if the
+ user searches for "foo", then strcmp will sort "foo" before "foo$".
+ Then lookup_partial_symbol will notice that strcmp_iw("foo$",
+ "foo") is false, so it won't proceed to the actual match of
+ "foo(int)" with "foo". */
+
+int
+strcmp_iw_ordered (const char *string1, const char *string2)
+{
+ while ((*string1 != '\0') && (*string2 != '\0'))
+ {
+ while (isspace (*string1))
+ {
+ string1++;
+ }
+ while (isspace (*string2))
+ {
+ string2++;
+ }
+ if (*string1 != *string2)
+ {
+ break;
+ }
+ if (*string1 != '\0')
+ {
+ string1++;
+ string2++;
+ }
+ }
+
+ switch (*string1)
+ {
+ /* Characters are non-equal unless they're both '\0'; we want to
+ make sure we get the comparison right according to our
+ comparison in the cases where one of them is '\0' or '('. */
+ case '\0':
+ if (*string2 == '\0')
+ return 0;
+ else
+ return -1;
+ case '(':
+ if (*string2 == '\0')
+ return 1;
+ else
+ return -1;
+ default:
+ if (*string2 == '(')
+ return 1;
+ else
+ return *string1 - *string2;
+ }
+}
+
+/* A simple comparison function with opposite semantics to strcmp. */
+
+int
+streq (const char *lhs, const char *rhs)
+{
+ return !strcmp (lhs, rhs);
+}
/*
@@ -2217,11 +2575,11 @@ int
subset_compare (char *string_to_compare, char *template_string)
{
int match;
- if (template_string != (char *) NULL && string_to_compare != (char *) NULL &&
- strlen (string_to_compare) <= strlen (template_string))
- match = (strncmp (template_string,
- string_to_compare,
- strlen (string_to_compare)) == 0);
+ if (template_string != (char *) NULL && string_to_compare != (char *) NULL
+ && strlen (string_to_compare) <= strlen (template_string))
+ match =
+ (strncmp
+ (template_string, string_to_compare, strlen (string_to_compare)) == 0);
else
match = 0;
return match;
@@ -2248,39 +2606,29 @@ initialize_utils (void)
{
struct cmd_list_element *c;
- c = add_set_cmd ("width", class_support, var_uinteger,
- (char *) &chars_per_line,
+ c = add_set_cmd ("width", class_support, var_uinteger, &chars_per_line,
"Set number of characters gdb thinks are in a line.",
&setlist);
add_show_from_set (c, &showlist);
set_cmd_sfunc (c, set_width_command);
- add_show_from_set
- (add_set_cmd ("height", class_support,
- var_uinteger, (char *) &lines_per_page,
- "Set number of lines gdb thinks are in a page.", &setlist),
- &showlist);
+ c = add_set_cmd ("height", class_support, var_uinteger, &lines_per_page,
+ "Set number of lines gdb thinks are in a page.", &setlist);
+ add_show_from_set (c, &showlist);
+ set_cmd_sfunc (c, set_height_command);
init_page_info ();
- /* If the output is not a terminal, don't paginate it. */
- if (!ui_file_isatty (gdb_stdout))
- lines_per_page = UINT_MAX;
-
- set_width_command ((char *) NULL, 0, c);
-
add_show_from_set
(add_set_cmd ("demangle", class_support, var_boolean,
(char *) &demangle,
- "Set demangling of encoded C++ names when displaying symbols.",
- &setprintlist),
- &showprintlist);
+ "Set demangling of encoded C++/ObjC names when displaying symbols.",
+ &setprintlist), &showprintlist);
add_show_from_set
(add_set_cmd ("pagination", class_support,
var_boolean, (char *) &pagination_enabled,
- "Set state of pagination.", &setlist),
- &showlist);
+ "Set state of pagination.", &setlist), &showlist);
if (xdb_commands)
{
@@ -2294,15 +2642,13 @@ initialize_utils (void)
(add_set_cmd ("sevenbit-strings", class_support, var_boolean,
(char *) &sevenbit_strings,
"Set printing of 8-bit characters in strings as \\nnn.",
- &setprintlist),
- &showprintlist);
+ &setprintlist), &showprintlist);
add_show_from_set
(add_set_cmd ("asm-demangle", class_support, var_boolean,
(char *) &asm_demangle,
- "Set demangling of C++ names in disassembly listings.",
- &setprintlist),
- &showprintlist);
+ "Set demangling of C++/ObjC names in disassembly listings.",
+ &setprintlist), &showprintlist);
}
/* Machine specific function to handle SIGWINCH signal. */
@@ -2310,9 +2656,7 @@ initialize_utils (void)
#ifdef SIGWINCH_HANDLER_BODY
SIGWINCH_HANDLER_BODY
#endif
-
/* print routines to handle variable size regs, etc. */
-
/* temporary storage using circular buffer */
#define NUMCELLS 16
#define CELLSIZE 32
@@ -2361,19 +2705,17 @@ decimal2str (char *paddr_str, char *sign, ULONGEST addr)
switch (i)
{
case 1:
- sprintf (paddr_str, "%s%lu",
- sign, temp[0]);
+ sprintf (paddr_str, "%s%lu", sign, temp[0]);
break;
case 2:
- sprintf (paddr_str, "%s%lu%09lu",
- sign, temp[1], temp[0]);
+ sprintf (paddr_str, "%s%lu%09lu", sign, temp[1], temp[0]);
break;
case 3:
- sprintf (paddr_str, "%s%lu%09lu%09lu",
- sign, temp[2], temp[1], temp[0]);
+ sprintf (paddr_str, "%s%lu%09lu%09lu", sign, temp[2], temp[1], temp[0]);
break;
default:
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ internal_error (__FILE__, __LINE__,
+ "failed internal consistency check");
}
}
@@ -2439,8 +2781,7 @@ phex_nz (ULONGEST l, int sizeof_l)
if (high == 0)
sprintf (str, "%lx", (unsigned long) (l & 0xffffffff));
else
- sprintf (str, "%lx%08lx",
- high, (unsigned long) (l & 0xffffffff));
+ sprintf (str, "%lx%08lx", high, (unsigned long) (l & 0xffffffff));
break;
}
case 4:
@@ -2459,28 +2800,6 @@ phex_nz (ULONGEST l, int sizeof_l)
}
-/* Convert to / from the hosts pointer to GDB's internal CORE_ADDR
- using the target's conversion routines. */
-CORE_ADDR
-host_pointer_to_address (void *ptr)
-{
- if (sizeof (ptr) != TYPE_LENGTH (builtin_type_void_data_ptr))
- internal_error (__FILE__, __LINE__,
- "core_addr_to_void_ptr: bad cast");
- return POINTER_TO_ADDRESS (builtin_type_void_data_ptr, &ptr);
-}
-
-void *
-address_to_host_pointer (CORE_ADDR addr)
-{
- void *ptr;
- if (sizeof (ptr) != TYPE_LENGTH (builtin_type_void_data_ptr))
- internal_error (__FILE__, __LINE__,
- "core_addr_to_void_ptr: bad cast");
- ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr);
- return ptr;
-}
-
/* Convert a CORE_ADDR into a string. */
const char *
core_addr_to_string (const CORE_ADDR addr)
@@ -2513,7 +2832,7 @@ string_to_core_addr (const char *my_string)
{
if (isdigit (my_string[i]))
addr = (my_string[i] - '0') + (addr * 16);
- else if (isxdigit (my_string[i]))
+ else if (isxdigit (my_string[i]))
addr = (tolower (my_string[i]) - 'a' + 0xa) + (addr * 16);
else
internal_error (__FILE__, __LINE__, "invalid hex");
@@ -2537,29 +2856,204 @@ string_to_core_addr (const char *my_string)
char *
gdb_realpath (const char *filename)
{
+ /* Method 1: The system has a compile time upper bound on a filename
+ path. Use that and realpath() to canonicalize the name. This is
+ the most common case. Note that, if there isn't a compile time
+ upper bound, you want to avoid realpath() at all costs. */
#if defined(HAVE_REALPATH)
+ {
# if defined (PATH_MAX)
- char buf[PATH_MAX];
+ char buf[PATH_MAX];
# define USE_REALPATH
# elif defined (MAXPATHLEN)
- char buf[MAXPATHLEN];
-# define USE_REALPATH
-# elif defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA)
- char *buf = alloca ((size_t)pathconf ("/", _PC_PATH_MAX));
+ char buf[MAXPATHLEN];
# define USE_REALPATH
# endif
+# if defined (USE_REALPATH)
+ const char *rp = realpath (filename, buf);
+ if (rp == NULL)
+ rp = filename;
+ return xstrdup (rp);
+# endif
+ }
#endif /* HAVE_REALPATH */
-#if defined(USE_REALPATH)
- char *rp = realpath (filename, buf);
- return xstrdup (rp ? rp : filename);
-#elif defined(HAVE_CANONICALIZE_FILE_NAME)
- char *rp = canonicalize_file_name (filename);
- if (rp == NULL)
- return xstrdup (filename);
- else
- return rp;
-#else
+ /* Method 2: The host system (i.e., GNU) has the function
+ canonicalize_file_name() which malloc's a chunk of memory and
+ returns that, use that. */
+#if defined(HAVE_CANONICALIZE_FILE_NAME)
+ {
+ char *rp = canonicalize_file_name (filename);
+ if (rp == NULL)
+ return xstrdup (filename);
+ else
+ return rp;
+ }
+#endif
+
+ /* FIXME: cagney/2002-11-13:
+
+ Method 2a: Use realpath() with a NULL buffer. Some systems, due
+ to the problems described in in method 3, have modified their
+ realpath() implementation so that it will allocate a buffer when
+ NULL is passed in. Before this can be used, though, some sort of
+ configure time test would need to be added. Otherwize the code
+ will likely core dump. */
+
+ /* Method 3: Now we're getting desperate! The system doesn't have a
+ compile time buffer size and no alternative function. Query the
+ OS, using pathconf(), for the buffer limit. Care is needed
+ though, some systems do not limit PATH_MAX (return -1 for
+ pathconf()) making it impossible to pass a correctly sized buffer
+ to realpath() (it could always overflow). On those systems, we
+ skip this. */
+#if defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA)
+ {
+ /* Find out the max path size. */
+ long path_max = pathconf ("/", _PC_PATH_MAX);
+ if (path_max > 0)
+ {
+ /* PATH_MAX is bounded. */
+ char *buf = alloca (path_max);
+ char *rp = realpath (filename, buf);
+ return xstrdup (rp ? rp : filename);
+ }
+ }
+#endif
+
+ /* This system is a lost cause, just dup the buffer. */
return xstrdup (filename);
+}
+
+/* Return a copy of FILENAME, with its directory prefix canonicalized
+ by gdb_realpath. */
+
+char *
+xfullpath (const char *filename)
+{
+ const char *base_name = lbasename (filename);
+ char *dir_name;
+ char *real_path;
+ char *result;
+
+ /* Extract the basename of filename, and return immediately
+ a copy of filename if it does not contain any directory prefix. */
+ if (base_name == filename)
+ return xstrdup (filename);
+
+ dir_name = alloca ((size_t) (base_name - filename + 2));
+ /* Allocate enough space to store the dir_name + plus one extra
+ character sometimes needed under Windows (see below), and
+ then the closing \000 character */
+ strncpy (dir_name, filename, base_name - filename);
+ dir_name[base_name - filename] = '\000';
+
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ /* We need to be careful when filename is of the form 'd:foo', which
+ is equivalent of d:./foo, which is totally different from d:/foo. */
+ if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':')
+ {
+ dir_name[2] = '.';
+ dir_name[3] = '\000';
+ }
#endif
+
+ /* Canonicalize the directory prefix, and build the resulting
+ filename. If the dirname realpath already contains an ending
+ directory separator, avoid doubling it. */
+ real_path = gdb_realpath (dir_name);
+ if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1]))
+ result = concat (real_path, base_name, NULL);
+ else
+ result = concat (real_path, SLASH_STRING, base_name, NULL);
+
+ xfree (real_path);
+ return result;
+}
+
+
+/* This is the 32-bit CRC function used by the GNU separate debug
+ facility. An executable may contain a section named
+ .gnu_debuglink, which holds the name of a separate executable file
+ containing its debug info, and a checksum of that file's contents,
+ computed using this function. */
+unsigned long
+gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+{
+ static const unsigned long crc32_table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d
+ };
+ unsigned char *end;
+
+ crc = ~crc & 0xffffffff;
+ for (end = buf + len; buf < end; ++buf)
+ crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+ return ~crc & 0xffffffff;;
+}
+
+ULONGEST
+align_up (ULONGEST v, int n)
+{
+ /* Check that N is really a power of two. */
+ gdb_assert (n && (n & (n-1)) == 0);
+ return (v + n - 1) & -n;
+}
+
+ULONGEST
+align_down (ULONGEST v, int n)
+{
+ /* Check that N is really a power of two. */
+ gdb_assert (n && (n & (n-1)) == 0);
+ return (v & -n);
}
diff --git a/contrib/gdb/gdb/version.in b/contrib/gdb/gdb/version.in
index 26d99a2..f3b5af3 100644
--- a/contrib/gdb/gdb/version.in
+++ b/contrib/gdb/gdb/version.in
@@ -1 +1 @@
-5.2.1
+6.1.1
OpenPOWER on IntegriCloud