mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 02:24:46 +08:00
Delete files for last commit.
This commit is contained in:
parent
ea35711cf6
commit
cb2a4ac5da
@ -1,489 +0,0 @@
|
||||
/* Target-dependent code for the MDEBUG MIPS architecture, for GDB,
|
||||
the GNU Debugger.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "mips-tdep.h"
|
||||
#include "trad-frame.h"
|
||||
#include "block.h"
|
||||
#include "symtab.h"
|
||||
#include "objfiles.h"
|
||||
#include "elf/mips.h"
|
||||
#include "elf-bfd.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "frame-unwind.h"
|
||||
#include "frame-base.h"
|
||||
#include "mips-mdebug-tdep.h"
|
||||
#include "mdebugread.h"
|
||||
|
||||
#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */
|
||||
#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)
|
||||
/* FIXME drow/2002-06-10: If a pointer on the host is bigger than a long,
|
||||
this will corrupt pdr.iline. Fortunately we don't use it. */
|
||||
#define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->pdr.isym)
|
||||
#define _PROC_MAGIC_ 0x0F0F0F0F
|
||||
|
||||
struct mips_objfile_private
|
||||
{
|
||||
bfd_size_type size;
|
||||
char *contents;
|
||||
};
|
||||
|
||||
/* Global used to communicate between non_heuristic_proc_desc and
|
||||
compare_pdr_entries within qsort (). */
|
||||
static bfd *the_bfd;
|
||||
|
||||
static int
|
||||
compare_pdr_entries (const void *a, const void *b)
|
||||
{
|
||||
CORE_ADDR lhs = bfd_get_signed_32 (the_bfd, (bfd_byte *) a);
|
||||
CORE_ADDR rhs = bfd_get_signed_32 (the_bfd, (bfd_byte *) b);
|
||||
|
||||
if (lhs < rhs)
|
||||
return -1;
|
||||
else if (lhs == rhs)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct objfile_data *mips_pdr_data;
|
||||
|
||||
static struct mdebug_extra_func_info *
|
||||
non_heuristic_proc_desc (CORE_ADDR pc, CORE_ADDR *addrptr)
|
||||
{
|
||||
CORE_ADDR startaddr;
|
||||
struct mdebug_extra_func_info *proc_desc;
|
||||
struct block *b = block_for_pc (pc);
|
||||
struct symbol *sym;
|
||||
struct obj_section *sec;
|
||||
struct mips_objfile_private *priv;
|
||||
|
||||
find_pc_partial_function (pc, NULL, &startaddr, NULL);
|
||||
if (addrptr)
|
||||
*addrptr = startaddr;
|
||||
|
||||
priv = NULL;
|
||||
|
||||
sec = find_pc_section (pc);
|
||||
if (sec != NULL)
|
||||
{
|
||||
priv = (struct mips_objfile_private *) objfile_data (sec->objfile, mips_pdr_data);
|
||||
|
||||
/* Search the ".pdr" section generated by GAS. This includes most of
|
||||
the information normally found in ECOFF PDRs. */
|
||||
|
||||
the_bfd = sec->objfile->obfd;
|
||||
if (priv == NULL
|
||||
&& (the_bfd->format == bfd_object
|
||||
&& bfd_get_flavour (the_bfd) == bfd_target_elf_flavour
|
||||
&& elf_elfheader (the_bfd)->e_ident[EI_CLASS] == ELFCLASS64))
|
||||
{
|
||||
/* Right now GAS only outputs the address as a four-byte sequence.
|
||||
This means that we should not bother with this method on 64-bit
|
||||
targets (until that is fixed). */
|
||||
|
||||
priv = obstack_alloc (&sec->objfile->objfile_obstack,
|
||||
sizeof (struct mips_objfile_private));
|
||||
priv->size = 0;
|
||||
set_objfile_data (sec->objfile, mips_pdr_data, priv);
|
||||
}
|
||||
else if (priv == NULL)
|
||||
{
|
||||
asection *bfdsec;
|
||||
|
||||
priv = obstack_alloc (&sec->objfile->objfile_obstack,
|
||||
sizeof (struct mips_objfile_private));
|
||||
|
||||
bfdsec = bfd_get_section_by_name (sec->objfile->obfd, ".pdr");
|
||||
if (bfdsec != NULL)
|
||||
{
|
||||
priv->size = bfd_section_size (sec->objfile->obfd, bfdsec);
|
||||
priv->contents = obstack_alloc (&sec->objfile->objfile_obstack,
|
||||
priv->size);
|
||||
bfd_get_section_contents (sec->objfile->obfd, bfdsec,
|
||||
priv->contents, 0, priv->size);
|
||||
|
||||
/* In general, the .pdr section is sorted. However, in the
|
||||
presence of multiple code sections (and other corner cases)
|
||||
it can become unsorted. Sort it so that we can use a faster
|
||||
binary search. */
|
||||
qsort (priv->contents, priv->size / 32, 32,
|
||||
compare_pdr_entries);
|
||||
}
|
||||
else
|
||||
priv->size = 0;
|
||||
|
||||
set_objfile_data (sec->objfile, mips_pdr_data, priv);
|
||||
}
|
||||
the_bfd = NULL;
|
||||
|
||||
if (priv->size != 0)
|
||||
{
|
||||
int low, mid, high;
|
||||
char *ptr;
|
||||
CORE_ADDR pdr_pc;
|
||||
|
||||
low = 0;
|
||||
high = priv->size / 32;
|
||||
|
||||
/* We've found a .pdr section describing this objfile. We want to
|
||||
find the entry which describes this code address. The .pdr
|
||||
information is not very descriptive; we have only a function
|
||||
start address. We have to look for the closest entry, because
|
||||
the local symbol at the beginning of this function may have
|
||||
been stripped - so if we ask the symbol table for the start
|
||||
address we may get a preceding global function. */
|
||||
|
||||
/* First, find the last .pdr entry starting at or before PC. */
|
||||
do
|
||||
{
|
||||
mid = (low + high) / 2;
|
||||
|
||||
ptr = priv->contents + mid * 32;
|
||||
pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr);
|
||||
pdr_pc += ANOFFSET (sec->objfile->section_offsets,
|
||||
SECT_OFF_TEXT (sec->objfile));
|
||||
|
||||
if (pdr_pc > pc)
|
||||
high = mid;
|
||||
else
|
||||
low = mid + 1;
|
||||
}
|
||||
while (low != high);
|
||||
|
||||
/* Both low and high point one past the PDR of interest. If
|
||||
both are zero, that means this PC is before any region
|
||||
covered by a PDR, i.e. pdr_pc for the first PDR entry is
|
||||
greater than PC. */
|
||||
if (low > 0)
|
||||
{
|
||||
ptr = priv->contents + (low - 1) * 32;
|
||||
pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr);
|
||||
pdr_pc += ANOFFSET (sec->objfile->section_offsets,
|
||||
SECT_OFF_TEXT (sec->objfile));
|
||||
}
|
||||
|
||||
/* We don't have a range, so we have no way to know for sure
|
||||
whether we're in the correct PDR or a PDR for a preceding
|
||||
function and the current function was a stripped local
|
||||
symbol. But if the PDR's PC is at least as great as the
|
||||
best guess from the symbol table, assume that it does cover
|
||||
the right area; if a .pdr section is present at all then
|
||||
nearly every function will have an entry. The biggest exception
|
||||
will be the dynamic linker stubs; conveniently these are
|
||||
placed before .text instead of after. */
|
||||
|
||||
if (pc >= pdr_pc && pdr_pc >= startaddr)
|
||||
{
|
||||
struct symbol *sym = find_pc_function (pc);
|
||||
|
||||
if (addrptr)
|
||||
*addrptr = pdr_pc;
|
||||
|
||||
/* Fill in what we need of the proc_desc. */
|
||||
proc_desc = (struct mdebug_extra_func_info *)
|
||||
obstack_alloc (&sec->objfile->objfile_obstack,
|
||||
sizeof (struct mdebug_extra_func_info));
|
||||
PROC_LOW_ADDR (proc_desc) = pdr_pc;
|
||||
|
||||
PROC_FRAME_OFFSET (proc_desc)
|
||||
= bfd_get_signed_32 (sec->objfile->obfd, ptr + 20);
|
||||
PROC_FRAME_REG (proc_desc) = bfd_get_32 (sec->objfile->obfd,
|
||||
ptr + 24);
|
||||
PROC_REG_MASK (proc_desc) = bfd_get_32 (sec->objfile->obfd,
|
||||
ptr + 4);
|
||||
PROC_FREG_MASK (proc_desc) = bfd_get_32 (sec->objfile->obfd,
|
||||
ptr + 12);
|
||||
PROC_REG_OFFSET (proc_desc)
|
||||
= bfd_get_signed_32 (sec->objfile->obfd, ptr + 8);
|
||||
PROC_FREG_OFFSET (proc_desc)
|
||||
= bfd_get_signed_32 (sec->objfile->obfd, ptr + 16);
|
||||
PROC_PC_REG (proc_desc) = bfd_get_32 (sec->objfile->obfd,
|
||||
ptr + 28);
|
||||
proc_desc->pdr.isym = (long) sym;
|
||||
|
||||
return proc_desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (b == NULL)
|
||||
return NULL;
|
||||
|
||||
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. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0, NULL);
|
||||
|
||||
/* If we never found a PDR for this function in symbol reading, then
|
||||
examine prologues to find the information. */
|
||||
if (sym)
|
||||
{
|
||||
proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE (sym);
|
||||
if (PROC_FRAME_REG (proc_desc) == -1)
|
||||
return NULL;
|
||||
else
|
||||
return proc_desc;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mips_frame_cache
|
||||
{
|
||||
CORE_ADDR base;
|
||||
struct trad_frame_saved_reg *saved_regs;
|
||||
};
|
||||
|
||||
static struct mips_frame_cache *
|
||||
mips_mdebug_frame_cache (struct frame_info *next_frame, void **this_cache)
|
||||
{
|
||||
CORE_ADDR startaddr = 0;
|
||||
struct mdebug_extra_func_info *proc_desc;
|
||||
struct mips_frame_cache *cache;
|
||||
struct gdbarch *gdbarch = get_frame_arch (next_frame);
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
/* r0 bit means kernel trap */
|
||||
int kernel_trap;
|
||||
/* What registers have been saved? Bitmasks. */
|
||||
unsigned long gen_mask, float_mask;
|
||||
|
||||
if ((*this_cache) != NULL)
|
||||
return (*this_cache);
|
||||
cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
|
||||
(*this_cache) = cache;
|
||||
cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
|
||||
|
||||
/* Get the mdebug proc descriptor. */
|
||||
proc_desc = non_heuristic_proc_desc (frame_pc_unwind (next_frame),
|
||||
&startaddr);
|
||||
/* Must be true. This is only called when the sniffer detected a
|
||||
proc descriptor. */
|
||||
gdb_assert (proc_desc != NULL);
|
||||
|
||||
/* Extract the frame's base. */
|
||||
cache->base = (frame_unwind_register_signed (next_frame, NUM_REGS + PROC_FRAME_REG (proc_desc))
|
||||
+ PROC_FRAME_OFFSET (proc_desc));
|
||||
|
||||
kernel_trap = PROC_REG_MASK (proc_desc) & 1;
|
||||
gen_mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK (proc_desc);
|
||||
float_mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK (proc_desc);
|
||||
|
||||
/* Must be true. The in_prologue case is left for the heuristic
|
||||
unwinder. This is always used on kernel traps. */
|
||||
gdb_assert (!in_prologue (frame_pc_unwind (next_frame), PROC_LOW_ADDR (proc_desc))
|
||||
|| kernel_trap);
|
||||
|
||||
/* Fill in the offsets for the registers which gen_mask says were
|
||||
saved. */
|
||||
{
|
||||
CORE_ADDR reg_position = (cache->base + PROC_REG_OFFSET (proc_desc));
|
||||
int ireg;
|
||||
|
||||
for (ireg = MIPS_NUMREGS - 1; gen_mask; --ireg, gen_mask <<= 1)
|
||||
if (gen_mask & 0x80000000)
|
||||
{
|
||||
cache->saved_regs[NUM_REGS + ireg].addr = reg_position;
|
||||
reg_position -= mips_abi_regsize (gdbarch);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in the offsets for the registers which float_mask says were
|
||||
saved. */
|
||||
{
|
||||
CORE_ADDR reg_position = (cache->base
|
||||
+ PROC_FREG_OFFSET (proc_desc));
|
||||
int ireg;
|
||||
/* Fill in the offsets for the float registers which float_mask
|
||||
says were saved. */
|
||||
for (ireg = MIPS_NUMREGS - 1; float_mask; --ireg, float_mask <<= 1)
|
||||
if (float_mask & 0x80000000)
|
||||
{
|
||||
if (mips_abi_regsize (gdbarch) == 4
|
||||
&& TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
|
||||
{
|
||||
/* On a big endian 32 bit ABI, floating point registers
|
||||
are paired to form doubles such that the most
|
||||
significant part is in $f[N+1] and the least
|
||||
significant in $f[N] vis: $f[N+1] ||| $f[N]. The
|
||||
registers are also spilled as a pair and stored as a
|
||||
double.
|
||||
|
||||
When little-endian the least significant part is
|
||||
stored first leading to the memory order $f[N] and
|
||||
then $f[N+1].
|
||||
|
||||
Unfortunately, when big-endian the most significant
|
||||
part of the double is stored first, and the least
|
||||
significant is stored second. This leads to the
|
||||
registers being ordered in memory as firt $f[N+1] and
|
||||
then $f[N].
|
||||
|
||||
For the big-endian case make certain that the
|
||||
addresses point at the correct (swapped) locations
|
||||
$f[N] and $f[N+1] pair (keep in mind that
|
||||
reg_position is decremented each time through the
|
||||
loop). */
|
||||
if ((ireg & 1))
|
||||
cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->fp0 + ireg]
|
||||
.addr = reg_position - mips_abi_regsize (gdbarch);
|
||||
else
|
||||
cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->fp0 + ireg]
|
||||
.addr = reg_position + mips_abi_regsize (gdbarch);
|
||||
}
|
||||
else
|
||||
cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->fp0 + ireg]
|
||||
.addr = reg_position;
|
||||
reg_position -= mips_abi_regsize (gdbarch);
|
||||
}
|
||||
|
||||
cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc]
|
||||
= cache->saved_regs[NUM_REGS + MIPS_RA_REGNUM];
|
||||
}
|
||||
|
||||
/* SP_REGNUM, contains the value and not the address. */
|
||||
trad_frame_set_value (cache->saved_regs, NUM_REGS + MIPS_SP_REGNUM, cache->base);
|
||||
|
||||
return (*this_cache);
|
||||
}
|
||||
|
||||
static void
|
||||
mips_mdebug_frame_this_id (struct frame_info *next_frame, void **this_cache,
|
||||
struct frame_id *this_id)
|
||||
{
|
||||
struct mips_frame_cache *info = mips_mdebug_frame_cache (next_frame,
|
||||
this_cache);
|
||||
(*this_id) = frame_id_build (info->base,
|
||||
frame_func_unwind (next_frame, NORMAL_FRAME));
|
||||
}
|
||||
|
||||
static void
|
||||
mips_mdebug_frame_prev_register (struct frame_info *next_frame,
|
||||
void **this_cache,
|
||||
int regnum, int *optimizedp,
|
||||
enum lval_type *lvalp, CORE_ADDR *addrp,
|
||||
int *realnump, gdb_byte *valuep)
|
||||
{
|
||||
struct mips_frame_cache *info = mips_mdebug_frame_cache (next_frame,
|
||||
this_cache);
|
||||
trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
|
||||
optimizedp, lvalp, addrp, realnump, valuep);
|
||||
}
|
||||
|
||||
static const struct frame_unwind mips_mdebug_frame_unwind =
|
||||
{
|
||||
NORMAL_FRAME,
|
||||
mips_mdebug_frame_this_id,
|
||||
mips_mdebug_frame_prev_register
|
||||
};
|
||||
|
||||
static const struct frame_unwind *
|
||||
mips_mdebug_frame_sniffer (struct frame_info *next_frame)
|
||||
{
|
||||
CORE_ADDR pc = frame_unwind_address_in_block (next_frame, NORMAL_FRAME);
|
||||
CORE_ADDR startaddr = 0;
|
||||
struct mdebug_extra_func_info *proc_desc;
|
||||
int kernel_trap;
|
||||
|
||||
/* Don't use this on MIPS16. */
|
||||
if (mips_pc_is_mips16 (pc))
|
||||
return NULL;
|
||||
|
||||
/* Only use the mdebug frame unwinder on mdebug frames where all the
|
||||
registers have been saved. Leave hard cases such as no mdebug or
|
||||
in prologue for the heuristic unwinders. */
|
||||
|
||||
proc_desc = non_heuristic_proc_desc (pc, &startaddr);
|
||||
if (proc_desc == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Not sure exactly what kernel_trap means, but if it means the
|
||||
kernel saves the registers without a prologue doing it, we better
|
||||
not examine the prologue to see whether registers have been saved
|
||||
yet. */
|
||||
kernel_trap = PROC_REG_MASK (proc_desc) & 1;
|
||||
if (kernel_trap)
|
||||
return &mips_mdebug_frame_unwind;
|
||||
|
||||
/* In any frame other than the innermost or a frame interrupted by a
|
||||
signal, we assume that all registers have been saved. This
|
||||
assumes that all register saves in a function happen before the
|
||||
first function call. */
|
||||
if (!in_prologue (pc, PROC_LOW_ADDR (proc_desc)))
|
||||
return &mips_mdebug_frame_unwind;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
mips_mdebug_frame_base_address (struct frame_info *next_frame,
|
||||
void **this_cache)
|
||||
{
|
||||
struct mips_frame_cache *info = mips_mdebug_frame_cache (next_frame,
|
||||
this_cache);
|
||||
return info->base;
|
||||
}
|
||||
|
||||
static const struct frame_base mips_mdebug_frame_base = {
|
||||
&mips_mdebug_frame_unwind,
|
||||
mips_mdebug_frame_base_address,
|
||||
mips_mdebug_frame_base_address,
|
||||
mips_mdebug_frame_base_address
|
||||
};
|
||||
|
||||
static const struct frame_base *
|
||||
mips_mdebug_frame_base_sniffer (struct frame_info *next_frame)
|
||||
{
|
||||
if (mips_mdebug_frame_sniffer (next_frame) != NULL)
|
||||
return &mips_mdebug_frame_base;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
mips_mdebug_append_sniffers (struct gdbarch *gdbarch)
|
||||
{
|
||||
frame_unwind_append_sniffer (gdbarch, mips_mdebug_frame_sniffer);
|
||||
frame_base_append_sniffer (gdbarch, mips_mdebug_frame_base_sniffer);
|
||||
}
|
||||
|
||||
|
||||
extern void _initialize_mips_mdebug_tdep (void);
|
||||
void
|
||||
_initialize_mips_mdebug_tdep (void)
|
||||
{
|
||||
mips_pdr_data = register_objfile_data ();
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/* Target-dependent code for the MDEBUG MIPS architecture, for GDB,
|
||||
the GNU Debugger.
|
||||
|
||||
Copyright (C) 2004, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef MIPS_MDEBUG_TDEP_H
|
||||
#define MIPS_MDEBUG_TDEP_H
|
||||
|
||||
extern void mips_mdebug_append_sniffers (struct gdbarch *gdbarch);
|
||||
|
||||
#endif
|
144
gdb/ocd.h
144
gdb/ocd.h
@ -1,144 +0,0 @@
|
||||
/* Definitions for the Macraigor Systems BDM Wiggler
|
||||
Copyright (C) 1996, 1997, 1998, 2000, 2001, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef OCD_H
|
||||
#define OCD_H
|
||||
|
||||
struct mem_attrib;
|
||||
struct target_ops;
|
||||
|
||||
/* Wiggler serial protocol definitions */
|
||||
|
||||
#define DLE 020 /* Quote char */
|
||||
#define SYN 026 /* Start of packet */
|
||||
#define RAW_SYN ((026 << 8) | 026) /* get_quoted_char found a naked SYN */
|
||||
|
||||
/* Status flags */
|
||||
|
||||
#define OCD_FLAG_RESET 0x01 /* Target is being reset */
|
||||
#define OCD_FLAG_STOPPED 0x02 /* Target is halted */
|
||||
#define OCD_FLAG_BDM 0x04 /* Target is in BDM */
|
||||
#define OCD_FLAG_PWF 0x08 /* Power failed */
|
||||
#define OCD_FLAG_CABLE_DISC 0x10 /* BDM cable disconnected */
|
||||
|
||||
/* Commands */
|
||||
|
||||
#define OCD_AYT 0x0 /* Are you there? */
|
||||
#define OCD_GET_VERSION 0x1 /* Get Version */
|
||||
#define OCD_SET_BAUD_RATE 0x2 /* Set Baud Rate */
|
||||
#define OCD_INIT 0x10 /* Initialize Wiggler */
|
||||
#define OCD_SET_SPEED 0x11 /* Set Speed */
|
||||
#define OCD_GET_STATUS_MASK 0x12 /* Get Status Mask */
|
||||
#define OCD_GET_CTRS 0x13 /* Get Error Counters */
|
||||
#define OCD_SET_FUNC_CODE 0x14 /* Set Function Code */
|
||||
#define OCD_SET_CTL_FLAGS 0x15 /* Set Control Flags */
|
||||
#define OCD_SET_BUF_ADDR 0x16 /* Set Register Buffer Address */
|
||||
#define OCD_RUN 0x20 /* Run Target from PC */
|
||||
#define OCD_RUN_ADDR 0x21 /* Run Target from Specified Address */
|
||||
#define OCD_STOP 0x22 /* Stop Target */
|
||||
#define OCD_RESET_RUN 0x23 /* Reset Target and Run */
|
||||
#define OCD_RESET 0x24 /* Reset Target and Halt */
|
||||
#define OCD_STEP 0x25 /* Single step */
|
||||
#define OCD_READ_REGS 0x30 /* Read Registers */
|
||||
#define OCD_WRITE_REGS 0x31 /* Write Registers */
|
||||
#define OCD_READ_MEM 0x32 /* Read Memory */
|
||||
#define OCD_WRITE_MEM 0x33 /* Write Memory */
|
||||
#define OCD_FILL_MEM 0x34 /* Fill Memory */
|
||||
#define OCD_MOVE_MEM 0x35 /* Move Memory */
|
||||
|
||||
#define OCD_READ_INT_MEM 0x80 /* Read Internal Memory */
|
||||
#define OCD_WRITE_INT_MEM 0x81 /* Write Internal Memory */
|
||||
#define OCD_JUMP 0x82 /* Jump to Subroutine */
|
||||
|
||||
#define OCD_ERASE_FLASH 0x90 /* Erase flash memory */
|
||||
#define OCD_PROGRAM_FLASH 0x91 /* Write flash memory */
|
||||
#define OCD_EXIT_MON 0x93 /* Exit the flash programming monitor */
|
||||
#define OCD_ENTER_MON 0x94 /* Enter the flash programming monitor */
|
||||
|
||||
#define OCD_SET_STATUS 0x0a /* Set status */
|
||||
#define OCD_SET_CONNECTION 0xf0 /* Set connection (init Wigglers.dll) */
|
||||
#define OCD_LOG_FILE 0xf1 /* Cmd to get Wigglers.dll to log cmds */
|
||||
#define OCD_FLAG_STOP 0x0 /* Stop the target, enter BDM */
|
||||
#define OCD_FLAG_START 0x01 /* Start the target at PC */
|
||||
#define OCD_FLAG_RETURN_STATUS 0x04 /* Return async status */
|
||||
|
||||
/* Target type (for OCD_INIT command) */
|
||||
|
||||
enum ocd_target_type
|
||||
{
|
||||
OCD_TARGET_CPU32 = 0x0, /* Moto cpu32 family */
|
||||
OCD_TARGET_CPU16 = 0x1,
|
||||
OCD_TARGET_MOTO_PPC = 0x2, /* Motorola PPC 5xx/8xx */
|
||||
OCD_TARGET_IBM_PPC = 0x3
|
||||
}; /* IBM PPC 4xx */
|
||||
|
||||
void ocd_open (char *name, int from_tty, enum ocd_target_type,
|
||||
struct target_ops *ops);
|
||||
|
||||
void ocd_close (int quitting);
|
||||
|
||||
void ocd_detach (char *args, int from_tty);
|
||||
|
||||
void ocd_resume (ptid_t ptid, int step, enum target_signal siggnal);
|
||||
|
||||
void ocd_prepare_to_store (void);
|
||||
|
||||
void ocd_stop (void);
|
||||
|
||||
void ocd_files_info (struct target_ops *ignore);
|
||||
|
||||
|
||||
int ocd_xfer_memory (CORE_ADDR memaddr, char *myaddr,
|
||||
int len, int should_write,
|
||||
struct mem_attrib *attrib,
|
||||
struct target_ops *target);
|
||||
|
||||
void ocd_mourn (void);
|
||||
|
||||
void ocd_create_inferior (char *exec_file, char *args, char **env,
|
||||
int from_tty);
|
||||
|
||||
int ocd_thread_alive (ptid_t th);
|
||||
|
||||
void ocd_error (char *s, int error_code);
|
||||
|
||||
void ocd_kill (void);
|
||||
|
||||
void ocd_load (char *args, int from_tty);
|
||||
|
||||
unsigned char *ocd_read_bdm_registers (int first_bdm_regno,
|
||||
int last_bdm_regno, int *reglen);
|
||||
|
||||
CORE_ADDR ocd_read_bdm_register (int bdm_regno);
|
||||
|
||||
void ocd_write_bdm_registers (int first_bdm_regno,
|
||||
unsigned char *regptr, int reglen);
|
||||
|
||||
void ocd_write_bdm_register (int bdm_regno, CORE_ADDR reg);
|
||||
|
||||
int ocd_wait (void);
|
||||
|
||||
int ocd_insert_breakpoint (struct bp_target_info *bp_tgt);
|
||||
int ocd_remove_breakpoint (struct bp_target_info *bp_tgt);
|
||||
|
||||
int ocd_write_bytes (CORE_ADDR memaddr, char *myaddr, int len);
|
||||
|
||||
#endif /* OCD_H */
|
354
gdb/ppc-bdm.c
354
gdb/ppc-bdm.c
@ -1,354 +0,0 @@
|
||||
/* Remote target communications for the Macraigor Systems BDM Wiggler
|
||||
talking to a Motorola PPC 8xx ADS board
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdbcore.h"
|
||||
#include "gdb_string.h"
|
||||
#include <fcntl.h>
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
#include "bfd.h"
|
||||
#include "symfile.h"
|
||||
#include "target.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "objfiles.h"
|
||||
#include "gdb-stabs.h"
|
||||
#include <sys/types.h>
|
||||
#include "serial.h"
|
||||
#include "ocd.h"
|
||||
#include "ppc-tdep.h"
|
||||
#include "regcache.h"
|
||||
#include "gdb_assert.h"
|
||||
|
||||
static void bdm_ppc_open (char *name, int from_tty);
|
||||
|
||||
static ptid_t bdm_ppc_wait (ptid_t ptid,
|
||||
struct target_waitstatus *target_status);
|
||||
|
||||
static void bdm_ppc_fetch_registers (int regno);
|
||||
|
||||
static void bdm_ppc_store_registers (int regno);
|
||||
|
||||
extern struct target_ops bdm_ppc_ops; /* Forward decl */
|
||||
|
||||
/*#define BDM_NUM_REGS 71 */
|
||||
#define BDM_NUM_REGS 24
|
||||
|
||||
#define BDM_REGMAP \
|
||||
2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, /* r0-r7 */ \
|
||||
2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, /* r8-r15 */ \
|
||||
2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, /* r16-r23 */ \
|
||||
2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, /* r24-r31 */ \
|
||||
\
|
||||
2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, /* fp0->fp8 */ \
|
||||
2096, 2098, 2100, 2102, 2104, 2106, 2108, 2110, /* fp0->fp8 */ \
|
||||
2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, /* fp0->fp8 */ \
|
||||
2128, 2130, 2132, 2134, 2136, 2138, 2140, 2142, /* fp0->fp8 */ \
|
||||
\
|
||||
26, /* pc (SRR0 (SPR 26)) */ \
|
||||
2146, /* ps (MSR) */ \
|
||||
2144, /* cnd (CR) */ \
|
||||
8, /* lr (SPR 8) */ \
|
||||
9, /* cnt (CTR (SPR 9)) */ \
|
||||
1, /* xer (SPR 1) */ \
|
||||
0, /* mq (SPR 0) */
|
||||
|
||||
|
||||
char nowatchdog[4] =
|
||||
{0xff, 0xff, 0xff, 0x88};
|
||||
|
||||
/* Open a connection to a remote debugger.
|
||||
NAME is the filename used for communication. */
|
||||
|
||||
static void
|
||||
bdm_ppc_open (char *name, int from_tty)
|
||||
{
|
||||
CORE_ADDR watchdogaddr = 0xff000004;
|
||||
|
||||
ocd_open (name, from_tty, OCD_TARGET_MOTO_PPC, &bdm_ppc_ops);
|
||||
|
||||
/* We want interrupts to drop us into debugging mode. */
|
||||
/* Modify the DER register to accomplish this. */
|
||||
ocd_write_bdm_register (149, 0x20024000);
|
||||
|
||||
/* Disable watchdog timer on the board */
|
||||
ocd_write_bytes (watchdogaddr, nowatchdog, 4);
|
||||
}
|
||||
|
||||
/* Wait until the remote machine stops, then return,
|
||||
storing status in STATUS just as `wait' would.
|
||||
Returns "pid" (though it's not clear what, if anything, that
|
||||
means in the case of this target). */
|
||||
|
||||
static ptid_t
|
||||
bdm_ppc_wait (ptid_t ptid, struct target_waitstatus *target_status)
|
||||
{
|
||||
int stop_reason;
|
||||
|
||||
target_status->kind = TARGET_WAITKIND_STOPPED;
|
||||
|
||||
stop_reason = ocd_wait ();
|
||||
|
||||
if (stop_reason)
|
||||
{
|
||||
target_status->value.sig = TARGET_SIGNAL_INT;
|
||||
return inferior_ptid;
|
||||
}
|
||||
|
||||
target_status->value.sig = TARGET_SIGNAL_TRAP; /* XXX for now */
|
||||
|
||||
#if 0
|
||||
{
|
||||
unsigned long ecr, der;
|
||||
|
||||
ecr = ocd_read_bdm_register (148); /* Read the exception cause register */
|
||||
der = ocd_read_bdm_register (149); /* Read the debug enables register */
|
||||
fprintf_unfiltered (gdb_stdout, "ecr = 0x%x, der = 0x%x\n", ecr, der);
|
||||
}
|
||||
#endif
|
||||
|
||||
return inferior_ptid;
|
||||
}
|
||||
|
||||
static int bdm_regmap[] =
|
||||
{BDM_REGMAP};
|
||||
|
||||
/* Read the remote registers into regs.
|
||||
Fetch register REGNO, or all registers if REGNO == -1
|
||||
|
||||
The Wiggler uses the following codes to access the registers:
|
||||
|
||||
0 -> 1023 SPR 0 -> 1023
|
||||
0 - SPR 0 - MQ
|
||||
1 - SPR 1 - XER
|
||||
8 - SPR 8 - LR
|
||||
9 - SPR 9 - CTR (known as cnt in GDB)
|
||||
26 - SPR 26 - SRR0 - pc
|
||||
1024 -> 2047 DCR 0 -> DCR 1023 (IBM PPC 4xx only)
|
||||
2048 -> 2079 R0 -> R31
|
||||
2080 -> 2143 FP0 -> FP31 (64 bit regs) (IBM PPC 5xx only)
|
||||
2144 CR (known as cnd in GDB)
|
||||
2145 FPCSR
|
||||
2146 MSR (known as ps in GDB)
|
||||
*/
|
||||
|
||||
static void
|
||||
bdm_ppc_fetch_registers (int regno)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
|
||||
int i;
|
||||
unsigned char *regs;
|
||||
int first_regno, last_regno;
|
||||
int first_bdm_regno, last_bdm_regno;
|
||||
int reglen;
|
||||
|
||||
if (regno == -1)
|
||||
{
|
||||
first_regno = 0;
|
||||
last_regno = NUM_REGS - 1;
|
||||
|
||||
first_bdm_regno = 0;
|
||||
last_bdm_regno = BDM_NUM_REGS - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_regno = regno;
|
||||
last_regno = regno;
|
||||
|
||||
first_bdm_regno = bdm_regmap[regno];
|
||||
last_bdm_regno = bdm_regmap[regno];
|
||||
}
|
||||
|
||||
if (first_bdm_regno == -1)
|
||||
{
|
||||
regcache_raw_supply (current_regcache, first_regno, NULL);
|
||||
return; /* Unsupported register */
|
||||
}
|
||||
|
||||
/* FIXME: jimb/2004-05-04: I'm not sure how to adapt this code to
|
||||
processors that lack floating point registers, and I don't have
|
||||
have the equipment to test it. So we'll leave that case for the
|
||||
next person who encounters it. */
|
||||
gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
|
||||
|
||||
#if 1
|
||||
/* Can't ask for floating point regs on ppc 8xx, also need to
|
||||
avoid asking for the mq register. */
|
||||
if (first_regno == last_regno) /* only want one reg */
|
||||
{
|
||||
/* printf("Asking for register %d\n", first_regno); */
|
||||
|
||||
/* if asking for an invalid register */
|
||||
if ((first_regno == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
|
||||
|| (first_regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
|
||||
|| ((first_regno >= tdep->ppc_fp0_regnum)
|
||||
&& (first_regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
|
||||
{
|
||||
/* printf("invalid reg request!\n"); */
|
||||
regcache_raw_supply (current_regcache, first_regno, NULL);
|
||||
return; /* Unsupported register */
|
||||
}
|
||||
else
|
||||
{
|
||||
regs = ocd_read_bdm_registers (first_bdm_regno,
|
||||
last_bdm_regno, ®len);
|
||||
}
|
||||
}
|
||||
else
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("ppc_bdm_fetch_registers: "
|
||||
"'all registers' case not implemented"));
|
||||
|
||||
#endif
|
||||
#if 0
|
||||
regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, ®len);
|
||||
#endif
|
||||
|
||||
for (i = first_regno; i <= last_regno; i++)
|
||||
{
|
||||
int bdm_regno, regoffset;
|
||||
|
||||
bdm_regno = bdm_regmap[i];
|
||||
if (bdm_regno != -1)
|
||||
{
|
||||
regoffset = bdm_regno - first_bdm_regno;
|
||||
|
||||
if (regoffset >= reglen / 4)
|
||||
continue;
|
||||
|
||||
regcache_raw_supply (current_regcache, i, regs + 4 * regoffset);
|
||||
}
|
||||
else
|
||||
regcache_raw_supply (current_regcache, i, NULL); /* Unsupported register */
|
||||
}
|
||||
}
|
||||
|
||||
/* Store register REGNO, or all registers if REGNO == -1, from the contents
|
||||
of REGISTERS. FIXME: ignores errors. */
|
||||
|
||||
static void
|
||||
bdm_ppc_store_registers (int regno)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
|
||||
int i;
|
||||
int first_regno, last_regno;
|
||||
int first_bdm_regno, last_bdm_regno;
|
||||
|
||||
if (regno == -1)
|
||||
{
|
||||
first_regno = 0;
|
||||
last_regno = NUM_REGS - 1;
|
||||
|
||||
first_bdm_regno = 0;
|
||||
last_bdm_regno = BDM_NUM_REGS - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_regno = regno;
|
||||
last_regno = regno;
|
||||
|
||||
first_bdm_regno = bdm_regmap[regno];
|
||||
last_bdm_regno = bdm_regmap[regno];
|
||||
}
|
||||
|
||||
if (first_bdm_regno == -1)
|
||||
return; /* Unsupported register */
|
||||
|
||||
/* FIXME: jimb/2004-05-04: I'm not sure how to adapt this code to
|
||||
processors that lack floating point registers, and I don't have
|
||||
have the equipment to test it. So we'll leave that case for the
|
||||
next person who encounters it. */
|
||||
gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
|
||||
|
||||
for (i = first_regno; i <= last_regno; i++)
|
||||
{
|
||||
int bdm_regno;
|
||||
|
||||
bdm_regno = bdm_regmap[i];
|
||||
|
||||
/* only attempt to write if it's a valid ppc 8xx register */
|
||||
/* (need to avoid FP regs and MQ reg) */
|
||||
if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
|
||||
&& (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
|
||||
&& ((i < tdep->ppc_fp0_regnum)
|
||||
|| (i >= tdep->ppc_fp0_regnum + ppc_num_fprs)))
|
||||
{
|
||||
/* printf("write valid reg %d\n", bdm_regno); */
|
||||
ocd_write_bdm_registers (bdm_regno, deprecated_registers + DEPRECATED_REGISTER_BYTE (i), 4);
|
||||
}
|
||||
/*
|
||||
else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
|
||||
printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno);
|
||||
else
|
||||
printf("don't write invalid reg %d\n", bdm_regno);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/* Define the target subroutine names */
|
||||
|
||||
struct target_ops bdm_ppc_ops;
|
||||
|
||||
static void
|
||||
init_bdm_ppc_ops (void)
|
||||
{
|
||||
bdm_ppc_ops.to_shortname = "ocd";
|
||||
bdm_ppc_ops.to_longname = "Remote target with On-Chip Debugging";
|
||||
bdm_ppc_ops.to_doc = "Use a remote target with On-Chip Debugging. To use a target box;\n\
|
||||
specify the serial device it is connected to (e.g. /dev/ttya). To use\n\
|
||||
a wiggler, specify wiggler and then the port it is connected to\n\
|
||||
(e.g. wiggler lpt1)."; /* to_doc */
|
||||
bdm_ppc_ops.to_open = bdm_ppc_open;
|
||||
bdm_ppc_ops.to_close = ocd_close;
|
||||
bdm_ppc_ops.to_detach = ocd_detach;
|
||||
bdm_ppc_ops.to_resume = ocd_resume;
|
||||
bdm_ppc_ops.to_wait = bdm_ppc_wait;
|
||||
bdm_ppc_ops.to_fetch_registers = bdm_ppc_fetch_registers;
|
||||
bdm_ppc_ops.to_store_registers = bdm_ppc_store_registers;
|
||||
bdm_ppc_ops.to_prepare_to_store = ocd_prepare_to_store;
|
||||
bdm_ppc_ops.deprecated_xfer_memory = ocd_xfer_memory;
|
||||
bdm_ppc_ops.to_files_info = ocd_files_info;
|
||||
bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint;
|
||||
bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint;
|
||||
bdm_ppc_ops.to_kill = ocd_kill;
|
||||
bdm_ppc_ops.to_load = ocd_load;
|
||||
bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
|
||||
bdm_ppc_ops.to_mourn_inferior = ocd_mourn;
|
||||
bdm_ppc_ops.to_thread_alive = ocd_thread_alive;
|
||||
bdm_ppc_ops.to_stop = ocd_stop;
|
||||
bdm_ppc_ops.to_stratum = process_stratum;
|
||||
bdm_ppc_ops.to_has_all_memory = 1;
|
||||
bdm_ppc_ops.to_has_memory = 1;
|
||||
bdm_ppc_ops.to_has_stack = 1;
|
||||
bdm_ppc_ops.to_has_registers = 1;
|
||||
bdm_ppc_ops.to_has_execution = 1;
|
||||
bdm_ppc_ops.to_magic = OPS_MAGIC;
|
||||
} /* init_bdm_ppc_ops */
|
||||
|
||||
extern initialize_file_ftype _initialize_bdm_ppc; /* -Wmissing-prototypes */
|
||||
|
||||
void
|
||||
_initialize_bdm_ppc (void)
|
||||
{
|
||||
init_bdm_ppc_ops ();
|
||||
add_target (&bdm_ppc_ops);
|
||||
}
|
2221
gdb/remote-e7000.c
2221
gdb/remote-e7000.c
File diff suppressed because it is too large
Load Diff
161
gdb/remote-hms.c
161
gdb/remote-hms.c
@ -1,161 +0,0 @@
|
||||
/* Remote debugging interface for Renesas HMS Monitor Version 1.0
|
||||
Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2007
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Cygnus Support. Written by Steve Chamberlain
|
||||
(sac@cygnus.com).
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdbcore.h"
|
||||
#include "target.h"
|
||||
#include "monitor.h"
|
||||
#include "serial.h"
|
||||
#include "regcache.h"
|
||||
|
||||
#define CCR_REGNUM 8
|
||||
|
||||
static void hms_open (char *args, int from_tty);
|
||||
static void
|
||||
hms_supply_register (char *regname, int regnamelen, char *val, int vallen)
|
||||
{
|
||||
int regno;
|
||||
|
||||
if (regnamelen != 2)
|
||||
return;
|
||||
if (regname[0] != 'P')
|
||||
return;
|
||||
/* We scan off all the registers in one go */
|
||||
|
||||
val = monitor_supply_register (PC_REGNUM, val);
|
||||
/* Skip the ccr string */
|
||||
while (*val != '=' && *val)
|
||||
val++;
|
||||
|
||||
val = monitor_supply_register (CCR_REGNUM, val + 1);
|
||||
|
||||
/* Skip up to rest of regs */
|
||||
while (*val != '=' && *val)
|
||||
val++;
|
||||
|
||||
for (regno = 0; regno < 7; regno++)
|
||||
{
|
||||
val = monitor_supply_register (regno, val + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This array of registers needs to match the indexes used by GDB. The
|
||||
* whole reason this exists is because the various ROM monitors use
|
||||
* different names than GDB does, and don't support all the
|
||||
* registers either. So, typing "info reg sp" becomes a "r30".
|
||||
*/
|
||||
|
||||
static char *hms_regnames[] =
|
||||
{
|
||||
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "CCR", "PC", "", "", "", ""
|
||||
};
|
||||
|
||||
/*
|
||||
* Define the monitor command strings. Since these are passed directly
|
||||
* through to a printf style function, we need can include formatting
|
||||
* strings. We also need a CR or LF on the end.
|
||||
*/
|
||||
|
||||
static struct target_ops hms_ops;
|
||||
|
||||
static char *hms_inits[] =
|
||||
{"\003", /* Resets the prompt, and clears repeated cmds */
|
||||
NULL};
|
||||
|
||||
static struct monitor_ops hms_cmds;
|
||||
|
||||
static void
|
||||
init_hms_cmds (void)
|
||||
{
|
||||
hms_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_GETMEM_NEEDS_RANGE;
|
||||
hms_cmds.init = hms_inits; /* Init strings */
|
||||
hms_cmds.cont = "g\r"; /* continue command */
|
||||
hms_cmds.step = "s\r"; /* single step */
|
||||
hms_cmds.stop = "\003"; /* ^C interrupts the program */
|
||||
hms_cmds.set_break = "b %x\r"; /* set a breakpoint */
|
||||
hms_cmds.clr_break = "b - %x\r"; /* clear a breakpoint */
|
||||
hms_cmds.clr_all_break = "b -\r"; /* clear all breakpoints */
|
||||
hms_cmds.fill = "f %x %x %x\r"; /* fill (start end val) */
|
||||
hms_cmds.setmem.cmdb = "m.b %x=%x\r"; /* setmem.cmdb (addr, value) */
|
||||
hms_cmds.setmem.cmdw = "m.w %x=%x\r"; /* setmem.cmdw (addr, value) */
|
||||
hms_cmds.setmem.cmdl = NULL; /* setmem.cmdl (addr, value) */
|
||||
hms_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
|
||||
hms_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
|
||||
hms_cmds.setmem.term = NULL; /* setreg.term */
|
||||
hms_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
|
||||
hms_cmds.getmem.cmdb = "m.b %x %x\r"; /* getmem.cmdb (addr, addr) */
|
||||
hms_cmds.getmem.cmdw = "m.w %x %x\r"; /* getmem.cmdw (addr, addr) */
|
||||
hms_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, addr) */
|
||||
hms_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, addr) */
|
||||
hms_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
|
||||
hms_cmds.getmem.term = ">"; /* getmem.term */
|
||||
hms_cmds.getmem.term_cmd = "\003"; /* getmem.term_cmd */
|
||||
hms_cmds.setreg.cmd = "r %s=%x\r"; /* setreg.cmd (name, value) */
|
||||
hms_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
|
||||
hms_cmds.setreg.term = NULL; /* setreg.term */
|
||||
hms_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
|
||||
hms_cmds.getreg.cmd = "r %s\r"; /* getreg.cmd (name) */
|
||||
hms_cmds.getreg.resp_delim = " ("; /* getreg.resp_delim */
|
||||
hms_cmds.getreg.term = ":"; /* getreg.term */
|
||||
hms_cmds.getreg.term_cmd = "\003"; /* getreg.term_cmd */
|
||||
hms_cmds.dump_registers = "r\r"; /* dump_registers */
|
||||
hms_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
|
||||
hms_cmds.supply_register = hms_supply_register;
|
||||
hms_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
|
||||
hms_cmds.load = "tl\r"; /* download command */
|
||||
hms_cmds.loadresp = NULL; /* load response */
|
||||
hms_cmds.prompt = ">"; /* monitor command prompt */
|
||||
hms_cmds.line_term = "\r"; /* end-of-command delimitor */
|
||||
hms_cmds.cmd_end = NULL; /* optional command terminator */
|
||||
hms_cmds.target = &hms_ops; /* target operations */
|
||||
hms_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
|
||||
hms_cmds.regnames = hms_regnames; /* registers names */
|
||||
hms_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
|
||||
} /* init_hms-cmds */
|
||||
|
||||
static void
|
||||
hms_open (char *args, int from_tty)
|
||||
{
|
||||
monitor_open (args, &hms_cmds, from_tty);
|
||||
}
|
||||
|
||||
int write_dos_tick_delay;
|
||||
|
||||
extern initialize_file_ftype _initialize_remote_hms; /* -Wmissing-prototypes */
|
||||
|
||||
void
|
||||
_initialize_remote_hms (void)
|
||||
{
|
||||
init_hms_cmds ();
|
||||
init_monitor_ops (&hms_ops);
|
||||
|
||||
hms_ops.to_shortname = "hms";
|
||||
hms_ops.to_longname = "Renesas Microsystems H8/300 debug monitor";
|
||||
hms_ops.to_doc = "Debug via the HMS monitor.\n\
|
||||
Specify the serial device it is connected to (e.g. /dev/ttya).";
|
||||
hms_ops.to_open = hms_open;
|
||||
/* By trial and error I've found that this delay doesn't break things */
|
||||
write_dos_tick_delay = 1;
|
||||
add_target (&hms_ops);
|
||||
}
|
@ -1,610 +0,0 @@
|
||||
/* Generic support for remote debugging interfaces.
|
||||
|
||||
Copyright (C) 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* This file actually contains two distinct logical "packages". They
|
||||
are packaged together in this one file because they are typically
|
||||
used together.
|
||||
|
||||
The first package is an addition to the serial package. The
|
||||
addition provides reading and writing with debugging output and
|
||||
timeouts based on user settable variables. These routines are
|
||||
intended to support serial port based remote backends. These
|
||||
functions are prefixed with sr_.
|
||||
|
||||
The second package is a collection of more or less generic
|
||||
functions for use by remote backends. They support user settable
|
||||
variables for debugging, retries, and the like.
|
||||
|
||||
Todo:
|
||||
|
||||
* a pass through mode a la kermit or telnet.
|
||||
* autobaud.
|
||||
* ask remote to change his baud rate.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdb_string.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "target.h"
|
||||
#include "serial.h"
|
||||
#include "gdbcore.h" /* for exec_bfd */
|
||||
#include "inferior.h" /* for generic_mourn_inferior */
|
||||
#include "remote-utils.h"
|
||||
#include "regcache.h"
|
||||
|
||||
|
||||
void _initialize_sr_support (void);
|
||||
|
||||
struct _sr_settings sr_settings =
|
||||
{
|
||||
4, /* timeout:
|
||||
remote-hms.c had 2
|
||||
remote-bug.c had "with a timeout of 2, we time out waiting for
|
||||
the prompt after an s-record dump."
|
||||
|
||||
remote.c had (2): This was 5 seconds, which is a long time to
|
||||
sit and wait. Unless this is going though some terminal server
|
||||
or multiplexer or other form of hairy serial connection, I
|
||||
would think 2 seconds would be plenty.
|
||||
*/
|
||||
|
||||
10, /* retries */
|
||||
NULL, /* device */
|
||||
NULL, /* descriptor */
|
||||
};
|
||||
|
||||
struct gr_settings *gr_settings = NULL;
|
||||
|
||||
static void usage (char *, char *);
|
||||
static void sr_com (char *, int);
|
||||
|
||||
static void
|
||||
usage (char *proto, char *junk)
|
||||
{
|
||||
if (junk != NULL)
|
||||
fprintf_unfiltered (gdb_stderr, "Unrecognized arguments: `%s'.\n", junk);
|
||||
|
||||
error (_("Usage: target %s [DEVICE [SPEED [DEBUG]]]\n\
|
||||
where DEVICE is the name of a device or HOST:PORT"), proto);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#define CHECKDONE(p, q) \
|
||||
{ \
|
||||
if (q == p) \
|
||||
{ \
|
||||
if (*p == '\0') \
|
||||
return; \
|
||||
else \
|
||||
usage(proto, p); \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
sr_scan_args (char *proto, char *args)
|
||||
{
|
||||
int n;
|
||||
char *p, *q;
|
||||
|
||||
/* if no args, then nothing to do. */
|
||||
if (args == NULL || *args == '\0')
|
||||
return;
|
||||
|
||||
/* scan off white space. */
|
||||
for (p = args; isspace (*p); ++p);;
|
||||
|
||||
/* find end of device name. */
|
||||
for (q = p; *q != '\0' && !isspace (*q); ++q);;
|
||||
|
||||
/* check for missing or empty device name. */
|
||||
CHECKDONE (p, q);
|
||||
sr_set_device (savestring (p, q - p));
|
||||
|
||||
/* look for baud rate. */
|
||||
n = strtol (q, &p, 10);
|
||||
|
||||
/* check for missing or empty baud rate. */
|
||||
CHECKDONE (p, q);
|
||||
baud_rate = n;
|
||||
|
||||
/* look for debug value. */
|
||||
n = strtol (p, &q, 10);
|
||||
|
||||
/* check for missing or empty debug value. */
|
||||
CHECKDONE (p, q);
|
||||
sr_set_debug (n);
|
||||
|
||||
/* scan off remaining white space. */
|
||||
for (p = q; isspace (*p); ++p);;
|
||||
|
||||
/* if not end of string, then there's unrecognized junk. */
|
||||
if (*p != '\0')
|
||||
usage (proto, p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_generic_checkin (void)
|
||||
{
|
||||
sr_write_cr ("");
|
||||
gr_expect_prompt ();
|
||||
}
|
||||
|
||||
void
|
||||
gr_open (char *args, int from_tty, struct gr_settings *gr)
|
||||
{
|
||||
target_preopen (from_tty);
|
||||
sr_scan_args (gr->ops->to_shortname, args);
|
||||
unpush_target (gr->ops);
|
||||
|
||||
gr_settings = gr;
|
||||
|
||||
if (sr_get_desc () != NULL)
|
||||
gr_close (0);
|
||||
|
||||
/* If no args are specified, then we use the device specified by a
|
||||
previous command or "set remotedevice". But if there is no
|
||||
device, better stop now, not dump core. */
|
||||
|
||||
if (sr_get_device () == NULL)
|
||||
usage (gr->ops->to_shortname, NULL);
|
||||
|
||||
sr_set_desc (serial_open (sr_get_device ()));
|
||||
if (!sr_get_desc ())
|
||||
perror_with_name ((char *) sr_get_device ());
|
||||
|
||||
if (baud_rate != -1)
|
||||
{
|
||||
if (serial_setbaudrate (sr_get_desc (), baud_rate) != 0)
|
||||
{
|
||||
serial_close (sr_get_desc ());
|
||||
perror_with_name (sr_get_device ());
|
||||
}
|
||||
}
|
||||
|
||||
serial_raw (sr_get_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 (sr_get_desc ());
|
||||
|
||||
/* default retries */
|
||||
if (sr_get_retries () == 0)
|
||||
sr_set_retries (1);
|
||||
|
||||
/* default clear breakpoint function */
|
||||
if (gr_settings->clear_all_breakpoints == NULL)
|
||||
gr_settings->clear_all_breakpoints = remove_breakpoints;
|
||||
|
||||
if (from_tty)
|
||||
{
|
||||
printf_filtered ("Remote debugging using `%s'", sr_get_device ());
|
||||
if (baud_rate != -1)
|
||||
printf_filtered (" at baud rate of %d",
|
||||
baud_rate);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
|
||||
push_target (gr->ops);
|
||||
gr_checkin ();
|
||||
gr_clear_all_breakpoints ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read a character from the remote system masking it down to 7 bits
|
||||
and doing all the fancy timeout stuff. */
|
||||
|
||||
int
|
||||
sr_readchar (void)
|
||||
{
|
||||
int buf;
|
||||
|
||||
buf = serial_readchar (sr_get_desc (), sr_get_timeout ());
|
||||
|
||||
if (buf == SERIAL_TIMEOUT)
|
||||
error (_("Timeout reading from remote system."));
|
||||
|
||||
if (sr_get_debug () > 0)
|
||||
printf_unfiltered ("%c", buf);
|
||||
|
||||
return buf & 0x7f;
|
||||
}
|
||||
|
||||
int
|
||||
sr_pollchar (void)
|
||||
{
|
||||
int buf;
|
||||
|
||||
buf = serial_readchar (sr_get_desc (), 0);
|
||||
if (buf == SERIAL_TIMEOUT)
|
||||
buf = 0;
|
||||
if (sr_get_debug () > 0)
|
||||
{
|
||||
if (buf)
|
||||
printf_unfiltered ("%c", buf);
|
||||
else
|
||||
printf_unfiltered ("<empty character poll>");
|
||||
}
|
||||
|
||||
return buf & 0x7f;
|
||||
}
|
||||
|
||||
/* Keep discarding input from the remote system, until STRING is found.
|
||||
Let the user break out immediately. */
|
||||
void
|
||||
sr_expect (char *string)
|
||||
{
|
||||
char *p = string;
|
||||
|
||||
immediate_quit++;
|
||||
while (1)
|
||||
{
|
||||
if (sr_readchar () == *p)
|
||||
{
|
||||
p++;
|
||||
if (*p == '\0')
|
||||
{
|
||||
immediate_quit--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
p = string;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sr_write (char *a, int l)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (serial_write (sr_get_desc (), a, l) != 0)
|
||||
perror_with_name (_("sr_write: Error writing to remote"));
|
||||
|
||||
if (sr_get_debug () > 0)
|
||||
for (i = 0; i < l; i++)
|
||||
printf_unfiltered ("%c", a[i]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
sr_write_cr (char *s)
|
||||
{
|
||||
sr_write (s, strlen (s));
|
||||
sr_write ("\r", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
sr_timed_read (char *buf, int n)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
i = 0;
|
||||
while (i < n)
|
||||
{
|
||||
c = sr_readchar ();
|
||||
|
||||
if (c == 0)
|
||||
return i;
|
||||
buf[i] = c;
|
||||
i++;
|
||||
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Get a hex digit from the remote system & return its value. If
|
||||
ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
|
||||
|
||||
int
|
||||
sr_get_hex_digit (int ignore_space)
|
||||
{
|
||||
int ch;
|
||||
|
||||
while (1)
|
||||
{
|
||||
ch = sr_readchar ();
|
||||
if (ch >= '0' && ch <= '9')
|
||||
return ch - '0';
|
||||
else if (ch >= 'A' && ch <= 'F')
|
||||
return ch - 'A' + 10;
|
||||
else if (ch >= 'a' && ch <= 'f')
|
||||
return ch - 'a' + 10;
|
||||
else if (ch != ' ' || !ignore_space)
|
||||
{
|
||||
gr_expect_prompt ();
|
||||
error (_("Invalid hex digit from remote system."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a byte from the remote and put it in *BYT. Accept any number
|
||||
leading spaces. */
|
||||
void
|
||||
sr_get_hex_byte (char *byt)
|
||||
{
|
||||
int val;
|
||||
|
||||
val = sr_get_hex_digit (1) << 4;
|
||||
val |= sr_get_hex_digit (0);
|
||||
*byt = val;
|
||||
}
|
||||
|
||||
/* Read a 32-bit hex word from the remote, preceded by a space */
|
||||
long
|
||||
sr_get_hex_word (void)
|
||||
{
|
||||
long val;
|
||||
int j;
|
||||
|
||||
val = 0;
|
||||
for (j = 0; j < 8; j++)
|
||||
val = (val << 4) + sr_get_hex_digit (j == 0);
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Put a command string, in args, out to the remote. The remote is assumed to
|
||||
be in raw mode, all writing/reading done through desc.
|
||||
Ouput from the remote is placed on the users terminal until the
|
||||
prompt from the remote is seen.
|
||||
FIXME: Can't handle commands that take input. */
|
||||
|
||||
static void
|
||||
sr_com (char *args, int fromtty)
|
||||
{
|
||||
sr_check_open ();
|
||||
|
||||
if (!args)
|
||||
return;
|
||||
|
||||
/* Clear all input so only command relative output is displayed */
|
||||
|
||||
sr_write_cr (args);
|
||||
sr_write ("\030", 1);
|
||||
registers_changed ();
|
||||
gr_expect_prompt ();
|
||||
}
|
||||
|
||||
void
|
||||
gr_close (int quitting)
|
||||
{
|
||||
gr_clear_all_breakpoints ();
|
||||
|
||||
if (sr_is_open ())
|
||||
{
|
||||
serial_close (sr_get_desc ());
|
||||
sr_set_desc (NULL);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* gr_detach()
|
||||
takes a program previously attached to and detaches it.
|
||||
We better not have left any breakpoints
|
||||
in the program or it'll die when it hits one.
|
||||
Close the open connection to the remote debugger.
|
||||
Use this when you want to detach and do something else
|
||||
with your gdb. */
|
||||
|
||||
void
|
||||
gr_detach (char *args, int from_tty)
|
||||
{
|
||||
if (args)
|
||||
error (_("Argument given to \"detach\" when remotely debugging."));
|
||||
|
||||
if (sr_is_open ())
|
||||
gr_clear_all_breakpoints ();
|
||||
|
||||
pop_target ();
|
||||
if (from_tty)
|
||||
puts_filtered ("Ending remote debugging.\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_files_info (struct target_ops *ops)
|
||||
{
|
||||
#ifdef __GO32__
|
||||
printf_filtered ("\tAttached to DOS asynctsr\n");
|
||||
#else
|
||||
printf_filtered ("\tAttached to %s", sr_get_device ());
|
||||
if (baud_rate != -1)
|
||||
printf_filtered ("at %d baud", baud_rate);
|
||||
printf_filtered ("\n");
|
||||
#endif
|
||||
|
||||
if (exec_bfd)
|
||||
{
|
||||
printf_filtered ("\tand running program %s\n",
|
||||
bfd_get_filename (exec_bfd));
|
||||
}
|
||||
printf_filtered ("\tusing the %s protocol.\n", ops->to_shortname);
|
||||
}
|
||||
|
||||
void
|
||||
gr_mourn (void)
|
||||
{
|
||||
gr_clear_all_breakpoints ();
|
||||
unpush_target (gr_get_ops ());
|
||||
generic_mourn_inferior ();
|
||||
}
|
||||
|
||||
void
|
||||
gr_kill (void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is called not only when we first attach, but also when the
|
||||
user types "run" after having attached. */
|
||||
void
|
||||
gr_create_inferior (char *execfile, char *args, char **env)
|
||||
{
|
||||
int entry_pt;
|
||||
|
||||
if (args && *args)
|
||||
error (_("Can't pass arguments to remote process."));
|
||||
|
||||
if (execfile == 0 || exec_bfd == 0)
|
||||
error (_("No executable file specified"));
|
||||
|
||||
entry_pt = (int) bfd_get_start_address (exec_bfd);
|
||||
sr_check_open ();
|
||||
|
||||
gr_kill ();
|
||||
gr_clear_all_breakpoints ();
|
||||
|
||||
init_wait_for_inferior ();
|
||||
gr_checkin ();
|
||||
|
||||
insert_breakpoints (); /* Needed to get correct instruction in cache */
|
||||
proceed (entry_pt, -1, 0);
|
||||
}
|
||||
|
||||
/* Given a null terminated list of strings LIST, read the input until we find one of
|
||||
them. Return the index of the string found or -1 on error. '?' means match
|
||||
any single character. Note that with the algorithm we use, the initial
|
||||
character of the string cannot recur in the string, or we will not find some
|
||||
cases of the string in the input. If PASSTHROUGH is non-zero, then
|
||||
pass non-matching data on. */
|
||||
|
||||
int
|
||||
gr_multi_scan (char *list[], int passthrough)
|
||||
{
|
||||
char *swallowed = NULL; /* holding area */
|
||||
char *swallowed_p = swallowed; /* Current position in swallowed. */
|
||||
int ch;
|
||||
int ch_handled;
|
||||
int i;
|
||||
int string_count;
|
||||
int max_length;
|
||||
char **plist;
|
||||
|
||||
/* Look through the strings. Count them. Find the largest one so we can
|
||||
allocate a holding area. */
|
||||
|
||||
for (max_length = string_count = i = 0;
|
||||
list[i] != NULL;
|
||||
++i, ++string_count)
|
||||
{
|
||||
int length = strlen (list[i]);
|
||||
|
||||
if (length > max_length)
|
||||
max_length = length;
|
||||
}
|
||||
|
||||
/* if we have no strings, then something is wrong. */
|
||||
if (string_count == 0)
|
||||
return (-1);
|
||||
|
||||
/* otherwise, we will need a holding area big enough to hold almost two
|
||||
copies of our largest string. */
|
||||
swallowed_p = swallowed = alloca (max_length << 1);
|
||||
|
||||
/* and a list of pointers to current scan points. */
|
||||
plist = (char **) alloca (string_count * sizeof (*plist));
|
||||
|
||||
/* and initialize */
|
||||
for (i = 0; i < string_count; ++i)
|
||||
plist[i] = list[i];
|
||||
|
||||
for (ch = sr_readchar (); /* loop forever */ ; ch = sr_readchar ())
|
||||
{
|
||||
QUIT; /* Let user quit and leave process running */
|
||||
ch_handled = 0;
|
||||
|
||||
for (i = 0; i < string_count; ++i)
|
||||
{
|
||||
if (ch == *plist[i] || *plist[i] == '?')
|
||||
{
|
||||
++plist[i];
|
||||
if (*plist[i] == '\0')
|
||||
return (i);
|
||||
|
||||
if (!ch_handled)
|
||||
*swallowed_p++ = ch;
|
||||
|
||||
ch_handled = 1;
|
||||
}
|
||||
else
|
||||
plist[i] = list[i];
|
||||
}
|
||||
|
||||
if (!ch_handled)
|
||||
{
|
||||
char *p;
|
||||
|
||||
/* Print out any characters which have been swallowed. */
|
||||
if (passthrough)
|
||||
{
|
||||
for (p = swallowed; p < swallowed_p; ++p)
|
||||
fputc_unfiltered (*p, gdb_stdout);
|
||||
|
||||
fputc_unfiltered (ch, gdb_stdout);
|
||||
}
|
||||
|
||||
swallowed_p = swallowed;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* Never reached. */
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get ready to modify the registers array. On machines which store
|
||||
individual registers, this doesn't need to do anything. On machines
|
||||
which store all the registers in one fell swoop, this makes sure
|
||||
that registers contains all the registers from the program being
|
||||
debugged. */
|
||||
|
||||
void
|
||||
gr_prepare_to_store (void)
|
||||
{
|
||||
/* Do nothing, since we assume we can store individual regs */
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_sr_support (void)
|
||||
{
|
||||
/* FIXME-now: if target is open... */
|
||||
add_setshow_filename_cmd ("remotedevice", no_class, &sr_settings.device, _("\
|
||||
Set device for remote serial I/O."), _("\
|
||||
Show device for remote serial I/O."), _("\
|
||||
This device is used as the serial port when debugging using remote targets."),
|
||||
NULL,
|
||||
NULL, /* FIXME: i18n: */
|
||||
&setlist, &showlist);
|
||||
|
||||
add_com ("remote", class_obscure, sr_com,
|
||||
_("Send a command to the remote monitor."));
|
||||
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
/* Generic support for remote debugging interfaces.
|
||||
|
||||
Copyright (C) 1993, 1994, 2000, 2001, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef REMOTE_UTILS_H
|
||||
#define REMOTE_UTILS_H
|
||||
|
||||
struct target_ops;
|
||||
|
||||
#include "target.h"
|
||||
struct serial;
|
||||
|
||||
/* Stuff that should be shared (and handled consistently) among the various
|
||||
remote targets. */
|
||||
|
||||
struct _sr_settings
|
||||
{
|
||||
unsigned int timeout;
|
||||
|
||||
int retries;
|
||||
|
||||
char *device;
|
||||
struct serial *desc;
|
||||
|
||||
};
|
||||
|
||||
extern struct _sr_settings sr_settings;
|
||||
|
||||
/* get and set debug value. */
|
||||
#define sr_get_debug() (remote_debug)
|
||||
#define sr_set_debug(newval) (remote_debug = (newval))
|
||||
|
||||
/* get and set timeout. */
|
||||
#define sr_get_timeout() (sr_settings.timeout)
|
||||
#define sr_set_timeout(newval) (sr_settings.timeout = (newval))
|
||||
|
||||
/* get and set device. */
|
||||
#define sr_get_device() (sr_settings.device)
|
||||
#define sr_set_device(newval) \
|
||||
{ \
|
||||
if (sr_settings.device) xfree (sr_settings.device); \
|
||||
sr_settings.device = (newval); \
|
||||
}
|
||||
|
||||
/* get and set descriptor value. */
|
||||
#define sr_get_desc() (sr_settings.desc)
|
||||
#define sr_set_desc(newval) (sr_settings.desc = (newval))
|
||||
|
||||
/* get and set retries. */
|
||||
#define sr_get_retries() (sr_settings.retries)
|
||||
#define sr_set_retries(newval) (sr_settings.retries = (newval))
|
||||
|
||||
#define sr_is_open() (sr_settings.desc != NULL)
|
||||
|
||||
#define sr_check_open() { if (!sr_is_open()) \
|
||||
error (_("Remote device not open")); }
|
||||
|
||||
struct gr_settings
|
||||
{
|
||||
char *prompt;
|
||||
struct target_ops *ops;
|
||||
int (*clear_all_breakpoints) (void);
|
||||
void (*checkin) (void);
|
||||
};
|
||||
|
||||
extern struct gr_settings *gr_settings;
|
||||
|
||||
/* get and set prompt. */
|
||||
#define gr_get_prompt() (gr_settings->prompt)
|
||||
#define gr_set_prompt(newval) (gr_settings->prompt = (newval))
|
||||
|
||||
/* get and set ops. */
|
||||
#define gr_get_ops() (gr_settings->ops)
|
||||
#define gr_set_ops(newval) (gr_settings->ops = (newval))
|
||||
|
||||
#define gr_clear_all_breakpoints() ((gr_settings->clear_all_breakpoints)())
|
||||
#define gr_checkin() ((gr_settings->checkin)())
|
||||
|
||||
/* Keep discarding input until we see the prompt.
|
||||
|
||||
The convention for dealing with the prompt is that you
|
||||
o give your command
|
||||
o *then* wait for the prompt.
|
||||
|
||||
Thus the last thing that a procedure does with the serial line
|
||||
will be an gr_expect_prompt(). Exception: resume does not
|
||||
wait for the prompt, because the terminal is being handed over
|
||||
to the inferior. However, the next thing which happens after that
|
||||
is a bug_wait which does wait for the prompt.
|
||||
Note that this includes abnormal exit, e.g. error(). This is
|
||||
necessary to prevent getting into states from which we can't
|
||||
recover. */
|
||||
|
||||
#define gr_expect_prompt() sr_expect(gr_get_prompt())
|
||||
|
||||
int gr_multi_scan (char *list[], int passthrough);
|
||||
int sr_get_hex_digit (int ignore_space);
|
||||
int sr_pollchar (void);
|
||||
int sr_readchar (void);
|
||||
int sr_timed_read (char *buf, int n);
|
||||
long sr_get_hex_word (void);
|
||||
void gr_close (int quitting);
|
||||
void gr_create_inferior (char *execfile, char *args, char **env);
|
||||
void gr_detach (char *args, int from_tty);
|
||||
void gr_files_info (struct target_ops *ops);
|
||||
void gr_generic_checkin (void);
|
||||
void gr_kill (void);
|
||||
void gr_mourn (void);
|
||||
void gr_prepare_to_store (void);
|
||||
void sr_expect (char *string);
|
||||
void sr_get_hex_byte (char *byt);
|
||||
void sr_scan_args (char *proto, char *args);
|
||||
void sr_write (char *a, int l);
|
||||
void sr_write_cr (char *s);
|
||||
|
||||
void gr_open (char *args, int from_tty, struct gr_settings *gr_settings);
|
||||
void gr_load_image (char *, int from_tty);
|
||||
#endif /* REMOTE_UTILS_H */
|
497
gdb/scm-exp.c
497
gdb/scm-exp.c
@ -1,497 +0,0 @@
|
||||
/* Scheme/Guile language support routines for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1995, 1996, 2000, 2003, 2005, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "parser-defs.h"
|
||||
#include "language.h"
|
||||
#include "value.h"
|
||||
#include "c-lang.h"
|
||||
#include "scm-lang.h"
|
||||
#include "scm-tags.h"
|
||||
|
||||
#define USE_EXPRSTRING 0
|
||||
|
||||
static void scm_lreadparen (int);
|
||||
static int scm_skip_ws (void);
|
||||
static void scm_read_token (int, int);
|
||||
static LONGEST scm_istring2number (char *, int, int);
|
||||
static LONGEST scm_istr2int (char *, int, int);
|
||||
static void scm_lreadr (int);
|
||||
|
||||
static LONGEST
|
||||
scm_istr2int (char *str, int len, int radix)
|
||||
{
|
||||
int i = 0;
|
||||
LONGEST inum = 0;
|
||||
int c;
|
||||
int sign = 0;
|
||||
|
||||
if (0 >= len)
|
||||
return SCM_BOOL_F; /* zero scm_length */
|
||||
switch (str[0])
|
||||
{ /* leading sign */
|
||||
case '-':
|
||||
case '+':
|
||||
sign = str[0];
|
||||
if (++i == len)
|
||||
return SCM_BOOL_F; /* bad if lone `+' or `-' */
|
||||
}
|
||||
do
|
||||
{
|
||||
switch (c = str[i++])
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
c = c - '0';
|
||||
goto accumulate;
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
c = c - 'A' + 10;
|
||||
goto accumulate;
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
c = c - 'a' + 10;
|
||||
accumulate:
|
||||
if (c >= radix)
|
||||
return SCM_BOOL_F; /* bad digit for radix */
|
||||
inum *= radix;
|
||||
inum += c;
|
||||
break;
|
||||
default:
|
||||
return SCM_BOOL_F; /* not a digit */
|
||||
}
|
||||
}
|
||||
while (i < len);
|
||||
if (sign == '-')
|
||||
inum = -inum;
|
||||
return SCM_MAKINUM (inum);
|
||||
}
|
||||
|
||||
static LONGEST
|
||||
scm_istring2number (char *str, int len, int radix)
|
||||
{
|
||||
int i = 0;
|
||||
char ex = 0;
|
||||
char ex_p = 0, rx_p = 0; /* Only allow 1 exactness and 1 radix prefix */
|
||||
#if 0
|
||||
SCM res;
|
||||
#endif
|
||||
if (len == 1)
|
||||
if (*str == '+' || *str == '-') /* Catches lone `+' and `-' for speed */
|
||||
return SCM_BOOL_F;
|
||||
|
||||
while ((len - i) >= 2 && str[i] == '#' && ++i)
|
||||
switch (str[i++])
|
||||
{
|
||||
case 'b':
|
||||
case 'B':
|
||||
if (rx_p++)
|
||||
return SCM_BOOL_F;
|
||||
radix = 2;
|
||||
break;
|
||||
case 'o':
|
||||
case 'O':
|
||||
if (rx_p++)
|
||||
return SCM_BOOL_F;
|
||||
radix = 8;
|
||||
break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
if (rx_p++)
|
||||
return SCM_BOOL_F;
|
||||
radix = 10;
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
if (rx_p++)
|
||||
return SCM_BOOL_F;
|
||||
radix = 16;
|
||||
break;
|
||||
case 'i':
|
||||
case 'I':
|
||||
if (ex_p++)
|
||||
return SCM_BOOL_F;
|
||||
ex = 2;
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
if (ex_p++)
|
||||
return SCM_BOOL_F;
|
||||
ex = 1;
|
||||
break;
|
||||
default:
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
|
||||
switch (ex)
|
||||
{
|
||||
case 1:
|
||||
return scm_istr2int (&str[i], len - i, radix);
|
||||
case 0:
|
||||
return scm_istr2int (&str[i], len - i, radix);
|
||||
#if 0
|
||||
if NFALSEP
|
||||
(res) return res;
|
||||
#ifdef FLOATS
|
||||
case 2:
|
||||
return scm_istr2flo (&str[i], len - i, radix);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
|
||||
static void
|
||||
scm_read_token (int c, int weird)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
c = *lexptr++;
|
||||
switch (c)
|
||||
{
|
||||
case '[':
|
||||
case ']':
|
||||
case '(':
|
||||
case ')':
|
||||
case '\"':
|
||||
case ';':
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\f':
|
||||
case '\n':
|
||||
if (weird)
|
||||
goto default_case;
|
||||
case '\0': /* End of line */
|
||||
eof_case:
|
||||
--lexptr;
|
||||
return;
|
||||
case '\\':
|
||||
if (!weird)
|
||||
goto default_case;
|
||||
else
|
||||
{
|
||||
c = *lexptr++;
|
||||
if (c == '\0')
|
||||
goto eof_case;
|
||||
else
|
||||
goto default_case;
|
||||
}
|
||||
case '}':
|
||||
if (!weird)
|
||||
goto default_case;
|
||||
|
||||
c = *lexptr++;
|
||||
if (c == '#')
|
||||
return;
|
||||
else
|
||||
{
|
||||
--lexptr;
|
||||
c = '}';
|
||||
goto default_case;
|
||||
}
|
||||
|
||||
default:
|
||||
default_case:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
scm_skip_ws (void)
|
||||
{
|
||||
int c;
|
||||
while (1)
|
||||
switch ((c = *lexptr++))
|
||||
{
|
||||
case '\0':
|
||||
goteof:
|
||||
return c;
|
||||
case ';':
|
||||
lp:
|
||||
switch ((c = *lexptr++))
|
||||
{
|
||||
case '\0':
|
||||
goto goteof;
|
||||
default:
|
||||
goto lp;
|
||||
case '\n':
|
||||
break;
|
||||
}
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\f':
|
||||
case '\n':
|
||||
break;
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
scm_lreadparen (int skipping)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int c = scm_skip_ws ();
|
||||
if (')' == c || ']' == c)
|
||||
return;
|
||||
--lexptr;
|
||||
if (c == '\0')
|
||||
error ("missing close paren");
|
||||
scm_lreadr (skipping);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
scm_lreadr (int skipping)
|
||||
{
|
||||
int c, j;
|
||||
struct stoken str;
|
||||
LONGEST svalue = 0;
|
||||
tryagain:
|
||||
c = *lexptr++;
|
||||
switch (c)
|
||||
{
|
||||
case '\0':
|
||||
lexptr--;
|
||||
return;
|
||||
case '[':
|
||||
case '(':
|
||||
scm_lreadparen (skipping);
|
||||
return;
|
||||
case ']':
|
||||
case ')':
|
||||
error ("unexpected #\\%c", c);
|
||||
goto tryagain;
|
||||
case '\'':
|
||||
case '`':
|
||||
str.ptr = lexptr - 1;
|
||||
scm_lreadr (skipping);
|
||||
if (!skipping)
|
||||
{
|
||||
struct value *val = scm_evaluate_string (str.ptr, lexptr - str.ptr);
|
||||
if (!is_scmvalue_type (value_type (val)))
|
||||
error ("quoted scm form yields non-SCM value");
|
||||
svalue = extract_signed_integer (value_contents (val),
|
||||
TYPE_LENGTH (value_type (val)));
|
||||
goto handle_immediate;
|
||||
}
|
||||
return;
|
||||
case ',':
|
||||
c = *lexptr++;
|
||||
if ('@' != c)
|
||||
lexptr--;
|
||||
scm_lreadr (skipping);
|
||||
return;
|
||||
case '#':
|
||||
c = *lexptr++;
|
||||
switch (c)
|
||||
{
|
||||
case '[':
|
||||
case '(':
|
||||
scm_lreadparen (skipping);
|
||||
return;
|
||||
case 't':
|
||||
case 'T':
|
||||
svalue = SCM_BOOL_T;
|
||||
goto handle_immediate;
|
||||
case 'f':
|
||||
case 'F':
|
||||
svalue = SCM_BOOL_F;
|
||||
goto handle_immediate;
|
||||
case 'b':
|
||||
case 'B':
|
||||
case 'o':
|
||||
case 'O':
|
||||
case 'd':
|
||||
case 'D':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'i':
|
||||
case 'I':
|
||||
case 'e':
|
||||
case 'E':
|
||||
lexptr--;
|
||||
c = '#';
|
||||
goto num;
|
||||
case '*': /* bitvector */
|
||||
scm_read_token (c, 0);
|
||||
return;
|
||||
case '{':
|
||||
scm_read_token (c, 1);
|
||||
return;
|
||||
case '\\': /* character */
|
||||
c = *lexptr++;
|
||||
scm_read_token (c, 0);
|
||||
return;
|
||||
case '|':
|
||||
j = 1; /* here j is the comment nesting depth */
|
||||
lp:
|
||||
c = *lexptr++;
|
||||
lpc:
|
||||
switch (c)
|
||||
{
|
||||
case '\0':
|
||||
error ("unbalanced comment");
|
||||
default:
|
||||
goto lp;
|
||||
case '|':
|
||||
if ('#' != (c = *lexptr++))
|
||||
goto lpc;
|
||||
if (--j)
|
||||
goto lp;
|
||||
break;
|
||||
case '#':
|
||||
if ('|' != (c = *lexptr++))
|
||||
goto lpc;
|
||||
++j;
|
||||
goto lp;
|
||||
}
|
||||
goto tryagain;
|
||||
case '.':
|
||||
default:
|
||||
#if 0
|
||||
callshrp:
|
||||
#endif
|
||||
scm_lreadr (skipping);
|
||||
return;
|
||||
}
|
||||
case '\"':
|
||||
while ('\"' != (c = *lexptr++))
|
||||
{
|
||||
if (c == '\\')
|
||||
switch (c = *lexptr++)
|
||||
{
|
||||
case '\0':
|
||||
error ("non-terminated string literal");
|
||||
case '\n':
|
||||
continue;
|
||||
case '0':
|
||||
case 'f':
|
||||
case 'n':
|
||||
case 'r':
|
||||
case 't':
|
||||
case 'a':
|
||||
case 'v':
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '.':
|
||||
case '-':
|
||||
case '+':
|
||||
num:
|
||||
{
|
||||
str.ptr = lexptr - 1;
|
||||
scm_read_token (c, 0);
|
||||
if (!skipping)
|
||||
{
|
||||
svalue = scm_istring2number (str.ptr, lexptr - str.ptr, 10);
|
||||
if (svalue != SCM_BOOL_F)
|
||||
goto handle_immediate;
|
||||
goto tok;
|
||||
}
|
||||
}
|
||||
return;
|
||||
case ':':
|
||||
scm_read_token ('-', 0);
|
||||
return;
|
||||
#if 0
|
||||
do_symbol:
|
||||
#endif
|
||||
default:
|
||||
str.ptr = lexptr - 1;
|
||||
scm_read_token (c, 0);
|
||||
tok:
|
||||
if (!skipping)
|
||||
{
|
||||
str.length = lexptr - str.ptr;
|
||||
if (str.ptr[0] == '$')
|
||||
{
|
||||
write_dollar_variable (str);
|
||||
return;
|
||||
}
|
||||
write_exp_elt_opcode (OP_NAME);
|
||||
write_exp_string (str);
|
||||
write_exp_elt_opcode (OP_NAME);
|
||||
}
|
||||
return;
|
||||
}
|
||||
handle_immediate:
|
||||
if (!skipping)
|
||||
{
|
||||
write_exp_elt_opcode (OP_LONG);
|
||||
write_exp_elt_type (builtin_type_scm);
|
||||
write_exp_elt_longcst (svalue);
|
||||
write_exp_elt_opcode (OP_LONG);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
scm_parse (void)
|
||||
{
|
||||
char *start;
|
||||
while (*lexptr == ' ')
|
||||
lexptr++;
|
||||
start = lexptr;
|
||||
scm_lreadr (USE_EXPRSTRING);
|
||||
#if USE_EXPRSTRING
|
||||
str.length = lexptr - start;
|
||||
str.ptr = start;
|
||||
write_exp_elt_opcode (OP_EXPRSTRING);
|
||||
write_exp_string (str);
|
||||
write_exp_elt_opcode (OP_EXPRSTRING);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
283
gdb/scm-lang.c
283
gdb/scm-lang.c
@ -1,283 +0,0 @@
|
||||
/* Scheme/Guile language support routines for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1995, 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "parser-defs.h"
|
||||
#include "language.h"
|
||||
#include "value.h"
|
||||
#include "c-lang.h"
|
||||
#include "scm-lang.h"
|
||||
#include "scm-tags.h"
|
||||
#include "source.h"
|
||||
#include "gdb_string.h"
|
||||
#include "gdbcore.h"
|
||||
#include "infcall.h"
|
||||
|
||||
extern void _initialize_scheme_language (void);
|
||||
static struct value *evaluate_subexp_scm (struct type *, struct expression *,
|
||||
int *, enum noside);
|
||||
static struct value *scm_lookup_name (char *);
|
||||
static int in_eval_c (void);
|
||||
|
||||
struct type *builtin_type_scm;
|
||||
|
||||
void
|
||||
scm_printchar (int c, struct ui_file *stream)
|
||||
{
|
||||
fprintf_filtered (stream, "#\\%c", c);
|
||||
}
|
||||
|
||||
static void
|
||||
scm_printstr (struct ui_file *stream, const gdb_byte *string,
|
||||
unsigned int length, int width, int force_ellipses)
|
||||
{
|
||||
fprintf_filtered (stream, "\"%s\"", string);
|
||||
}
|
||||
|
||||
int
|
||||
is_scmvalue_type (struct type *type)
|
||||
{
|
||||
if (TYPE_CODE (type) == TYPE_CODE_INT
|
||||
&& TYPE_NAME (type) && strcmp (TYPE_NAME (type), "SCM") == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the INDEX'th SCM value, assuming SVALUE is the address
|
||||
of the 0'th one. */
|
||||
|
||||
LONGEST
|
||||
scm_get_field (LONGEST svalue, int index)
|
||||
{
|
||||
gdb_byte buffer[20];
|
||||
read_memory (SCM2PTR (svalue) + index * TYPE_LENGTH (builtin_type_scm),
|
||||
buffer, TYPE_LENGTH (builtin_type_scm));
|
||||
return extract_signed_integer (buffer, TYPE_LENGTH (builtin_type_scm));
|
||||
}
|
||||
|
||||
/* Unpack a value of type TYPE in buffer VALADDR as an integer
|
||||
(if CONTEXT == TYPE_CODE_IN), a pointer (CONTEXT == TYPE_CODE_PTR),
|
||||
or Boolean (CONTEXT == TYPE_CODE_BOOL). */
|
||||
|
||||
LONGEST
|
||||
scm_unpack (struct type *type, const gdb_byte *valaddr, enum type_code context)
|
||||
{
|
||||
if (is_scmvalue_type (type))
|
||||
{
|
||||
LONGEST svalue = extract_signed_integer (valaddr, TYPE_LENGTH (type));
|
||||
if (context == TYPE_CODE_BOOL)
|
||||
{
|
||||
if (svalue == SCM_BOOL_F)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
switch (7 & (int) svalue)
|
||||
{
|
||||
case 2:
|
||||
case 6: /* fixnum */
|
||||
return svalue >> 2;
|
||||
case 4: /* other immediate value */
|
||||
if (SCM_ICHRP (svalue)) /* character */
|
||||
return SCM_ICHR (svalue);
|
||||
else if (SCM_IFLAGP (svalue))
|
||||
{
|
||||
switch ((int) svalue)
|
||||
{
|
||||
#ifndef SICP
|
||||
case SCM_EOL:
|
||||
#endif
|
||||
case SCM_BOOL_F:
|
||||
return 0;
|
||||
case SCM_BOOL_T:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
error (_("Value can't be converted to integer."));
|
||||
default:
|
||||
return svalue;
|
||||
}
|
||||
}
|
||||
else
|
||||
return unpack_long (type, valaddr);
|
||||
}
|
||||
|
||||
/* True if we're correctly in Guile's eval.c (the evaluator and apply). */
|
||||
|
||||
static int
|
||||
in_eval_c (void)
|
||||
{
|
||||
struct symtab_and_line cursal = get_current_source_symtab_and_line ();
|
||||
|
||||
if (cursal.symtab && cursal.symtab->filename)
|
||||
{
|
||||
char *filename = cursal.symtab->filename;
|
||||
int len = strlen (filename);
|
||||
if (len >= 6 && strcmp (filename + len - 6, "eval.c") == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Lookup a value for the variable named STR.
|
||||
First lookup in Scheme context (using the scm_lookup_cstr inferior
|
||||
function), then try lookup_symbol for compiled variables. */
|
||||
|
||||
static struct value *
|
||||
scm_lookup_name (char *str)
|
||||
{
|
||||
struct value *args[3];
|
||||
int len = strlen (str);
|
||||
struct value *func;
|
||||
struct value *val;
|
||||
struct symbol *sym;
|
||||
args[0] = value_allocate_space_in_inferior (len);
|
||||
args[1] = value_from_longest (builtin_type_int, len);
|
||||
write_memory (value_as_long (args[0]), (gdb_byte *) str, len);
|
||||
|
||||
if (in_eval_c ()
|
||||
&& (sym = lookup_symbol ("env",
|
||||
expression_context_block,
|
||||
VAR_DOMAIN, (int *) NULL,
|
||||
(struct symtab **) NULL)) != NULL)
|
||||
args[2] = value_of_variable (sym, expression_context_block);
|
||||
else
|
||||
/* FIXME in this case, we should try lookup_symbol first */
|
||||
args[2] = value_from_longest (builtin_type_scm, SCM_EOL);
|
||||
|
||||
func = find_function_in_inferior ("scm_lookup_cstr");
|
||||
val = call_function_by_hand (func, 3, args);
|
||||
if (!value_logical_not (val))
|
||||
return value_ind (val);
|
||||
|
||||
sym = lookup_symbol (str,
|
||||
expression_context_block,
|
||||
VAR_DOMAIN, (int *) NULL,
|
||||
(struct symtab **) NULL);
|
||||
if (sym)
|
||||
return value_of_variable (sym, NULL);
|
||||
error (_("No symbol \"%s\" in current context."), str);
|
||||
}
|
||||
|
||||
struct value *
|
||||
scm_evaluate_string (char *str, int len)
|
||||
{
|
||||
struct value *func;
|
||||
struct value *addr = value_allocate_space_in_inferior (len + 1);
|
||||
LONGEST iaddr = value_as_long (addr);
|
||||
write_memory (iaddr, (gdb_byte *) str, len);
|
||||
/* FIXME - should find and pass env */
|
||||
write_memory (iaddr + len, (gdb_byte *) "", 1);
|
||||
func = find_function_in_inferior ("scm_evstr");
|
||||
return call_function_by_hand (func, 1, &addr);
|
||||
}
|
||||
|
||||
static struct value *
|
||||
evaluate_subexp_scm (struct type *expect_type, struct expression *exp,
|
||||
int *pos, enum noside noside)
|
||||
{
|
||||
enum exp_opcode op = exp->elts[*pos].opcode;
|
||||
int len, pc;
|
||||
char *str;
|
||||
switch (op)
|
||||
{
|
||||
case OP_NAME:
|
||||
pc = (*pos)++;
|
||||
len = longest_to_int (exp->elts[pc + 1].longconst);
|
||||
(*pos) += 3 + BYTES_TO_EXP_ELEM (len + 1);
|
||||
if (noside == EVAL_SKIP)
|
||||
goto nosideret;
|
||||
str = &exp->elts[pc + 2].string;
|
||||
return scm_lookup_name (str);
|
||||
case OP_EXPRSTRING:
|
||||
pc = (*pos)++;
|
||||
len = longest_to_int (exp->elts[pc + 1].longconst);
|
||||
(*pos) += 3 + BYTES_TO_EXP_ELEM (len + 1);
|
||||
if (noside == EVAL_SKIP)
|
||||
goto nosideret;
|
||||
str = &exp->elts[pc + 2].string;
|
||||
return scm_evaluate_string (str, len);
|
||||
default:;
|
||||
}
|
||||
return evaluate_subexp_standard (expect_type, exp, pos, noside);
|
||||
nosideret:
|
||||
return value_from_longest (builtin_type_long, (LONGEST) 1);
|
||||
}
|
||||
|
||||
const struct exp_descriptor exp_descriptor_scm =
|
||||
{
|
||||
print_subexp_standard,
|
||||
operator_length_standard,
|
||||
op_name_standard,
|
||||
dump_subexp_body_standard,
|
||||
evaluate_subexp_scm
|
||||
};
|
||||
|
||||
const struct language_defn scm_language_defn =
|
||||
{
|
||||
"scheme", /* Language name */
|
||||
language_scm,
|
||||
NULL,
|
||||
range_check_off,
|
||||
type_check_off,
|
||||
case_sensitive_off,
|
||||
array_row_major,
|
||||
&exp_descriptor_scm,
|
||||
scm_parse,
|
||||
c_error,
|
||||
null_post_parser,
|
||||
scm_printchar, /* Print a character constant */
|
||||
scm_printstr, /* Function to print string constant */
|
||||
NULL, /* Function to print a single character */
|
||||
NULL, /* Create fundamental type in this language */
|
||||
c_print_type, /* Print a type using appropriate syntax */
|
||||
scm_val_print, /* Print a value using appropriate syntax */
|
||||
scm_value_print, /* Print a top-level value */
|
||||
NULL, /* Language specific skip_trampoline */
|
||||
value_of_this, /* value_of_this */
|
||||
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
|
||||
basic_lookup_transparent_type,/* lookup_transparent_type */
|
||||
NULL, /* Language specific symbol demangler */
|
||||
NULL, /* Language specific class_name_from_physname */
|
||||
NULL, /* expression operators for printing */
|
||||
1, /* c-style arrays */
|
||||
0, /* String lower bound */
|
||||
NULL,
|
||||
default_word_break_characters,
|
||||
c_language_arch_info,
|
||||
default_print_array_index,
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
void
|
||||
_initialize_scheme_language (void)
|
||||
{
|
||||
add_language (&scm_language_defn);
|
||||
builtin_type_scm = init_type (TYPE_CODE_INT,
|
||||
TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0, "SCM", (struct objfile *) NULL);
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/* Scheme/Guile language support routines for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1995, 1996, 1998, 1999, 2000, 2003, 2005, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#define SICP
|
||||
#include "scm-tags.h"
|
||||
#undef SCM_NCELLP
|
||||
#define SCM_NCELLP(x) ((SCM_SIZE-1) & (int)(x))
|
||||
#define SCM_ITAG8_DATA(X) ((X)>>8)
|
||||
#define SCM_ICHR(x) ((unsigned char)SCM_ITAG8_DATA(x))
|
||||
#define SCM_ICHRP(x) (SCM_ITAG8(x) == scm_tc8_char)
|
||||
#define scm_tc8_char 0xf4
|
||||
#define SCM_IFLAGP(n) ((0x87 & (int)(n))==4)
|
||||
#define SCM_ISYMNUM(n) ((int)((n)>>9))
|
||||
#define SCM_ISYMCHARS(n) (scm_isymnames[SCM_ISYMNUM(n)])
|
||||
#define SCM_ILOCP(n) ((0xff & (int)(n))==0xfc)
|
||||
#define SCM_ITAG8(X) ((int)(X) & 0xff)
|
||||
#define SCM_TYP7(x) (0x7f & (int)SCM_CAR(x))
|
||||
#define SCM_LENGTH(x) (((unsigned long)SCM_CAR(x))>>8)
|
||||
#define SCM_NCONSP(x) (1 & (int)SCM_CAR(x))
|
||||
#define SCM_NECONSP(x) (SCM_NCONSP(x) && (1 != SCM_TYP3(x)))
|
||||
#define SCM_CAR(x) scm_get_field (x, 0)
|
||||
#define SCM_CDR(x) scm_get_field (x, 1)
|
||||
#define SCM_VELTS(x) ((SCM *)SCM_CDR(x))
|
||||
#define SCM_CLOSCAR(x) (SCM_CAR(x)-scm_tc3_closure)
|
||||
#define SCM_CODE(x) SCM_CAR(SCM_CLOSCAR (x))
|
||||
#define SCM_MAKINUM(x) (((x)<<2)+2L)
|
||||
|
||||
/* Forward decls for prototypes */
|
||||
struct value;
|
||||
|
||||
extern int scm_value_print (struct value *, struct ui_file *,
|
||||
int, enum val_prettyprint);
|
||||
|
||||
extern int scm_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
|
||||
struct ui_file *, int, int, int,
|
||||
enum val_prettyprint);
|
||||
|
||||
extern LONGEST scm_get_field (LONGEST, int);
|
||||
|
||||
extern void scm_scmval_print (LONGEST, struct ui_file *, int, int, int,
|
||||
enum val_prettyprint);
|
||||
|
||||
extern int is_scmvalue_type (struct type *);
|
||||
|
||||
extern void scm_printchar (int, struct ui_file *);
|
||||
|
||||
extern struct value *scm_evaluate_string (char *, int);
|
||||
|
||||
extern struct type *builtin_type_scm;
|
||||
|
||||
extern int scm_parse (void);
|
||||
|
||||
extern LONGEST scm_unpack (struct type *, const gdb_byte *, enum type_code);
|
380
gdb/scm-tags.h
380
gdb/scm-tags.h
@ -1,380 +0,0 @@
|
||||
/* This is a minimally edited version of Guile's tags.h. */
|
||||
/* classes: h_files */
|
||||
|
||||
#ifndef TAGSH
|
||||
#define TAGSH
|
||||
/* Copyright (C) 1995, 1999, 2007 Free Software Foundation, Inc.
|
||||
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As a special exception, the Free Software Foundation gives permission
|
||||
* for additional uses of the text contained in its release of GUILE.
|
||||
*
|
||||
* The exception is that, if you link the GUILE library with other files
|
||||
* to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the GUILE library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the
|
||||
* Free Software Foundation under the name GUILE. If you copy
|
||||
* code from other Free Software Foundation releases into a copy of
|
||||
* GUILE, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for GUILE, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice.
|
||||
*/
|
||||
|
||||
|
||||
/** This file defines the format of SCM values and cons pairs.
|
||||
** It is here that tag bits are assigned for various purposes.
|
||||
**/
|
||||
|
||||
|
||||
/* Three Bit Tags
|
||||
|
||||
* 000 -- a non-immediate value. Points into the pair heap.
|
||||
*
|
||||
* 001 -- a gloc (i.e., a resolved global variable in a CAR in a code graph)
|
||||
* or the CAR of an object handle (i.e., the tagged pointer to the
|
||||
* vtable part of a user-defined object).
|
||||
*
|
||||
* If X has this tag, the value at CDAR(X - 1) distinguishes
|
||||
* glocs from object handles. The distinction only needs
|
||||
* to be made in a few places. Only a few parts of the code know
|
||||
* about glocs. In most cases, when a value in the CAR of a pair
|
||||
* has the tag 001, it means that the pair is an object handle.
|
||||
*
|
||||
* 010 -- the tag for immediate, exact integers.
|
||||
*
|
||||
* 011 -- in the CAR of a pair, this tag indicates that the pair is a closure.
|
||||
* The remaining bits of the CAR are a pointer into the pair heap
|
||||
* to the code graph for the closure.
|
||||
*
|
||||
* 1xy -- an extension tag which means that there is a five or six bit
|
||||
* tag to the left of the low three bits. See the nice diagrams
|
||||
* in ../doc/code.doc if you want to know what the bits mean.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define scm_tc3_cons 0
|
||||
#define scm_tc3_cons_gloc 1
|
||||
#define scm_tc3_closure 3
|
||||
|
||||
#define scm_tc7_ssymbol 5
|
||||
#define scm_tc7_msymbol 7
|
||||
#define scm_tc7_string 13
|
||||
#define scm_tc7_bvect 15
|
||||
#define scm_tc7_vector 21
|
||||
#define scm_tc7_lvector 23
|
||||
#define scm_tc7_ivect 29
|
||||
#define scm_tc7_uvect 31
|
||||
/* spare 37 39 */
|
||||
#define scm_tc7_fvect 45
|
||||
#define scm_tc7_dvect 47
|
||||
#define scm_tc7_cvect 53
|
||||
#define scm_tc7_port 55
|
||||
#define scm_tc7_contin 61
|
||||
#define scm_tc7_cclo 63
|
||||
/* spare 69 71 77 79 */
|
||||
#define scm_tc7_subr_0 85
|
||||
#define scm_tc7_subr_1 87
|
||||
#define scm_tc7_cxr 93
|
||||
#define scm_tc7_subr_3 95
|
||||
#define scm_tc7_subr_2 101
|
||||
#define scm_tc7_asubr 103
|
||||
#define scm_tc7_subr_1o 109
|
||||
#define scm_tc7_subr_2o 111
|
||||
#define scm_tc7_lsubr_2 117
|
||||
#define scm_tc7_lsubr 119
|
||||
#define scm_tc7_rpsubr 125
|
||||
|
||||
#define scm_tc7_smob 127
|
||||
#define scm_tc_free_cell 127
|
||||
|
||||
#define scm_tc16_flo 0x017f
|
||||
#define scm_tc_flo 0x017fL
|
||||
|
||||
#define SCM_REAL_PART (1L<<16)
|
||||
#define SCM_IMAG_PART (2L<<16)
|
||||
#define scm_tc_dblr (scm_tc16_flo|REAL_PART)
|
||||
#define scm_tc_dblc (scm_tc16_flo|REAL_PART|IMAG_PART)
|
||||
|
||||
#define scm_tc16_bigpos 0x027f
|
||||
#define scm_tc16_bigneg 0x037f
|
||||
|
||||
#define scm_tc16_fport (scm_tc7_port + 0*256L)
|
||||
#define scm_tc16_pipe (scm_tc7_port + 1*256L)
|
||||
#define scm_tc16_strport (scm_tc7_port + 2*256L)
|
||||
#define scm_tc16_sfport (scm_tc7_port + 3*256L)
|
||||
|
||||
|
||||
|
||||
/* For cons pairs with immediate values in the CAR */
|
||||
#define scm_tcs_cons_imcar 2:case 4:case 6:case 10:\
|
||||
case 12:case 14:case 18:case 20:\
|
||||
case 22:case 26:case 28:case 30:\
|
||||
case 34:case 36:case 38:case 42:\
|
||||
case 44:case 46:case 50:case 52:\
|
||||
case 54:case 58:case 60:case 62:\
|
||||
case 66:case 68:case 70:case 74:\
|
||||
case 76:case 78:case 82:case 84:\
|
||||
case 86:case 90:case 92:case 94:\
|
||||
case 98:case 100:case 102:case 106:\
|
||||
case 108:case 110:case 114:case 116:\
|
||||
case 118:case 122:case 124:case 126
|
||||
|
||||
/* For cons pairs with non-immediate values in the CAR */
|
||||
#define scm_tcs_cons_nimcar 0:case 8:case 16:case 24:\
|
||||
case 32:case 40:case 48:case 56:\
|
||||
case 64:case 72:case 80:case 88:\
|
||||
case 96:case 104:case 112:case 120
|
||||
|
||||
/* A CONS_GLOC occurs in code. It's CAR is a pointer to the
|
||||
* CDR of a variable. The low order bits of the CAR are 001.
|
||||
* The CDR of the gloc is the code continuation.
|
||||
*/
|
||||
#define scm_tcs_cons_gloc 1:case 9:case 17:case 25:\
|
||||
case 33:case 41:case 49:case 57:\
|
||||
case 65:case 73:case 81:case 89:\
|
||||
case 97:case 105:case 113:case 121
|
||||
|
||||
#define scm_tcs_closures 3:case 11:case 19:case 27:\
|
||||
case 35:case 43:case 51:case 59:\
|
||||
case 67:case 75:case 83:case 91:\
|
||||
case 99:case 107:case 115:case 123
|
||||
|
||||
#define scm_tcs_subrs scm_tc7_asubr:case scm_tc7_subr_0:case scm_tc7_subr_1:case scm_tc7_cxr:\
|
||||
case scm_tc7_subr_3:case scm_tc7_subr_2:case scm_tc7_rpsubr:case scm_tc7_subr_1o:\
|
||||
case scm_tc7_subr_2o:case scm_tc7_lsubr_2:case scm_tc7_lsubr
|
||||
|
||||
#define scm_tcs_symbols scm_tc7_ssymbol:case scm_tc7_msymbol
|
||||
|
||||
#define scm_tcs_bignums tc16_bigpos:case tc16_bigneg
|
||||
|
||||
|
||||
|
||||
/* References to objects are of type SCM. Values may be non-immediate
|
||||
* (pointers) or immediate (encoded, immutable, scalar values that fit
|
||||
* in an SCM variable).
|
||||
*/
|
||||
|
||||
typedef long SCM;
|
||||
|
||||
/* Cray machines have pointers that are incremented once for each word,
|
||||
* rather than each byte, the 3 most significant bits encode the byte
|
||||
* within the word. The following macros deal with this by storing the
|
||||
* native Cray pointers like the ones that looks like scm expects. This
|
||||
* is done for any pointers that might appear in the car of a scm_cell, pointers
|
||||
* to scm_vector elts, functions, &c are not munged.
|
||||
*/
|
||||
#ifdef _UNICOS
|
||||
#define SCM2PTR(x) ((int)(x) >> 3)
|
||||
#define PTR2SCM(x) (((SCM)(x)) << 3)
|
||||
#define SCM_POINTERS_MUNGED
|
||||
#else
|
||||
#define SCM2PTR(x) (x)
|
||||
#define PTR2SCM(x) ((SCM)(x))
|
||||
#endif /* def _UNICOS */
|
||||
|
||||
|
||||
|
||||
/* Immediate? Predicates
|
||||
*/
|
||||
#define SCM_IMP(x) (6 & (int)(x))
|
||||
#define SCM_NIMP(x) (!SCM_IMP(x))
|
||||
|
||||
|
||||
|
||||
enum scm_tags
|
||||
{
|
||||
scm_tc8_char = 0xf4
|
||||
};
|
||||
|
||||
#define SCM_ITAG8(X) ((int)(X) & 0xff)
|
||||
#define SCM_MAKE_ITAG8(X, TAG) (((X)<<8) + TAG)
|
||||
#define SCM_ITAG8_DATA(X) ((X)>>8)
|
||||
|
||||
|
||||
|
||||
/* Local Environment Structure
|
||||
*/
|
||||
#define SCM_ILOCP(n) ((0xff & (int)(n))==0xfc)
|
||||
#define SCM_ILOC00 (0x000000fcL)
|
||||
#define SCM_IDINC (0x00100000L)
|
||||
#define SCM_ICDR (0x00080000L)
|
||||
#define SCM_IFRINC (0x00000100L)
|
||||
#define SCM_IDSTMSK (-SCM_IDINC)
|
||||
#define SCM_IFRAME(n) ((int)((SCM_ICDR-SCM_IFRINC)>>8) & ((int)(n)>>8))
|
||||
#define SCM_IDIST(n) (((unsigned long)(n))>>20)
|
||||
#define SCM_ICDRP(n) (SCM_ICDR & (n))
|
||||
|
||||
|
||||
/* Immediate Symbols, Special Symbols, Flags (various constants).
|
||||
*/
|
||||
|
||||
/* ISYMP tests for ISPCSYM and ISYM */
|
||||
#define SCM_ISYMP(n) ((0x187 & (int)(n))==4)
|
||||
|
||||
/* IFLAGP tests for ISPCSYM, ISYM and IFLAG */
|
||||
#define SCM_IFLAGP(n) ((0x87 & (int)(n))==4)
|
||||
#define SCM_ISYMNUM(n) ((int)((n)>>9))
|
||||
#define SCM_ISYMCHARS(n) (scm_isymnames[SCM_ISYMNUM(n)])
|
||||
#define SCM_MAKSPCSYM(n) (((n)<<9)+((n)<<3)+4L)
|
||||
#define SCM_MAKISYM(n) (((n)<<9)+0x74L)
|
||||
#define SCM_MAKIFLAG(n) (((n)<<9)+0x174L)
|
||||
|
||||
/* This table must agree with the declarations
|
||||
* in repl.c: {Names of immediate symbols}.
|
||||
*
|
||||
* These are used only in eval but their values
|
||||
* have to be allocated here.
|
||||
*
|
||||
*/
|
||||
|
||||
#define SCM_IM_AND SCM_MAKSPCSYM(0)
|
||||
#define SCM_IM_BEGIN SCM_MAKSPCSYM(1)
|
||||
#define SCM_IM_CASE SCM_MAKSPCSYM(2)
|
||||
#define SCM_IM_COND SCM_MAKSPCSYM(3)
|
||||
#define SCM_IM_DO SCM_MAKSPCSYM(4)
|
||||
#define SCM_IM_IF SCM_MAKSPCSYM(5)
|
||||
#define SCM_IM_LAMBDA SCM_MAKSPCSYM(6)
|
||||
#define SCM_IM_LET SCM_MAKSPCSYM(7)
|
||||
#define SCM_IM_LETSTAR SCM_MAKSPCSYM(8)
|
||||
#define SCM_IM_LETREC SCM_MAKSPCSYM(9)
|
||||
#define SCM_IM_OR SCM_MAKSPCSYM(10)
|
||||
#define SCM_IM_QUOTE SCM_MAKSPCSYM(11)
|
||||
#define SCM_IM_SET SCM_MAKSPCSYM(12)
|
||||
#define SCM_IM_DEFINE SCM_MAKSPCSYM(13)
|
||||
#define SCM_IM_APPLY SCM_MAKISYM(14)
|
||||
#define SCM_IM_CONT SCM_MAKISYM(15)
|
||||
#define SCM_NUM_ISYMS 16
|
||||
|
||||
/* Important immediates
|
||||
*/
|
||||
|
||||
#define SCM_BOOL_F SCM_MAKIFLAG(SCM_NUM_ISYMS+0)
|
||||
#define SCM_BOOL_T SCM_MAKIFLAG(SCM_NUM_ISYMS+1)
|
||||
#define SCM_UNDEFINED SCM_MAKIFLAG(SCM_NUM_ISYMS+2)
|
||||
#define SCM_EOF_VAL SCM_MAKIFLAG(SCM_NUM_ISYMS+3)
|
||||
|
||||
#ifdef SICP
|
||||
#define SCM_EOL SCM_BOOL_F
|
||||
#else
|
||||
#define SCM_EOL SCM_MAKIFLAG(SCM_NUM_ISYMS+4)
|
||||
#endif
|
||||
|
||||
#define SCM_UNSPECIFIED SCM_MAKIFLAG(SCM_NUM_ISYMS+5)
|
||||
|
||||
|
||||
|
||||
/* Heap Pairs and the Empty List Predicates
|
||||
*/
|
||||
#define SCM_NULLP(x) (SCM_EOL == (x))
|
||||
#define SCM_NNULLP(x) (SCM_EOL != (x))
|
||||
#define SCM_CELLP(x) (!SCM_NCELLP(x))
|
||||
#define SCM_NCELLP(x) ((sizeof(scm_cell)-1) & (int)(x))
|
||||
|
||||
|
||||
|
||||
#define SCM_UNBNDP(x) (SCM_UNDEFINED==(x))
|
||||
|
||||
|
||||
|
||||
/* Testing and Changing GC Marks in Various Standard Positions
|
||||
*/
|
||||
#define SCM_GCMARKP(x) (1 & (int)SCM_CDR(x))
|
||||
#define SCM_GC8MARKP(x) (0x80 & (int)SCM_CAR(x))
|
||||
#define SCM_SETGCMARK(x) (SCM_CDR(x) |= 1)
|
||||
#define SCM_CLRGCMARK(x) (SCM_CDR(x) &= ~1L)
|
||||
#define SCM_SETGC8MARK(x) (SCM_CAR(x) |= 0x80)
|
||||
#define SCM_CLRGC8MARK(x) (SCM_CAR(x) &= ~0x80L)
|
||||
|
||||
|
||||
/* Extracting Tag Bits, With or Without GC Safety and Optional Bits
|
||||
*/
|
||||
#define SCM_TYP3(x) (7 & (int)SCM_CAR(x))
|
||||
#define SCM_TYP7(x) (0x7f & (int)SCM_CAR(x))
|
||||
#define SCM_TYP7S(x) (0x7d & (int)SCM_CAR(x))
|
||||
#define SCM_TYP16(x) (0xffff & (int)SCM_CAR(x))
|
||||
#define SCM_TYP16S(x) (0xfeff & (int)SCM_CAR(x))
|
||||
#define SCM_GCTYP16(x) (0xff7f & (int)SCM_CAR(x))
|
||||
|
||||
|
||||
/* Two slightly extensible types: smobs and ptobs.
|
||||
|
||||
*/
|
||||
#define SCM_SMOBNUM(x) (0x0ff & (CAR(x)>>8));
|
||||
#define SCM_PTOBNUM(x) (0x0ff & (CAR(x)>>8));
|
||||
|
||||
|
||||
|
||||
|
||||
#define SCM_DIRP(x) (SCM_NIMP(x) && (TYP16(x)==(scm_tc16_dir)))
|
||||
#define SCM_OPDIRP(x) (SCM_NIMP(x) && (CAR(x)==(scm_tc16_dir | OPN)))
|
||||
|
||||
|
||||
|
||||
/* Lvectors
|
||||
*/
|
||||
#define SCM_LVECTORP(x) (TYP7(x)==tc7_lvector)
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* Sockets
|
||||
*/
|
||||
#define tc_socket (tc7_port | OPN)
|
||||
#define SCM_SOCKP(x) (((0x7f | OPN | RDNG | WRTNG) & CAR(x))==(tc_socket))
|
||||
#define SCM_SOCKTYP(x) (CAR(x)>>24)
|
||||
|
||||
|
||||
|
||||
extern int scm_tc16_key_vector;
|
||||
#define SCM_KEYVECP(X) (scm_tc16_key_vector == TYP16 (X))
|
||||
#define SCM_KEYVECLEN(OBJ) (((unsigned long)CAR (obj)) >> 16)
|
||||
|
||||
|
||||
#define SCM_MALLOCDATA(obj) ((char *)CDR(obj))
|
||||
#define SCM_MALLOCLEN(obj) (((unsigned long)CAR (obj)) >> 16)
|
||||
#define SCM_WORDDATA(obj) (CDR (obj))
|
||||
|
||||
|
||||
#define SCM_BYTECODEP(X) ((TYP7 (X) == tc7_cclo) && (CCLO_SUBR (X) == rb_proc))
|
||||
#define SCM_BYTECODE_CONSTANTS(X) (VELTS(X)[1])
|
||||
#define SCM_BYTECODE_CODE(X) (VELTS(X)[2])
|
||||
#define SCM_BYTECODE_NAME(X) (VELTS(X)[3])
|
||||
#define SCM_BYTECODE_BCODE(X) (VELTS(X)[4])
|
||||
#define SCM_BYTECODE_ELTS 5
|
||||
|
||||
|
||||
#define SCM_FREEP(x) (CAR(x)==tc_free_cell)
|
||||
#define SCM_NFREEP(x) (!FREEP(x))
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
#endif /* TAGSH */
|
@ -1,395 +0,0 @@
|
||||
/* Scheme/Guile language support routines for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2005, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "parser-defs.h"
|
||||
#include "language.h"
|
||||
#include "value.h"
|
||||
#include "scm-lang.h"
|
||||
#include "valprint.h"
|
||||
#include "gdbcore.h"
|
||||
#include "c-lang.h"
|
||||
|
||||
static void scm_ipruk (char *, LONGEST, struct ui_file *);
|
||||
static void scm_scmlist_print (LONGEST, struct ui_file *, int, int,
|
||||
int, enum val_prettyprint);
|
||||
static int scm_inferior_print (LONGEST, struct ui_file *, int, int,
|
||||
int, enum val_prettyprint);
|
||||
|
||||
/* Prints the SCM value VALUE by invoking the inferior, if appropraite.
|
||||
Returns >= 0 on succes; retunr -1 if the inferior cannot/should not
|
||||
print VALUE. */
|
||||
|
||||
static int
|
||||
scm_inferior_print (LONGEST value, struct ui_file *stream, int format,
|
||||
int deref_ref, int recurse, enum val_prettyprint pretty)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* {Names of immediate symbols}
|
||||
* This table must agree with the declarations in scm.h: {Immediate Symbols}.*/
|
||||
|
||||
static char *scm_isymnames[] =
|
||||
{
|
||||
/* This table must agree with the declarations */
|
||||
"and",
|
||||
"begin",
|
||||
"case",
|
||||
"cond",
|
||||
"do",
|
||||
"if",
|
||||
"lambda",
|
||||
"let",
|
||||
"let*",
|
||||
"letrec",
|
||||
"or",
|
||||
"quote",
|
||||
"set!",
|
||||
"define",
|
||||
#if 0
|
||||
"literal-variable-ref",
|
||||
"literal-variable-set!",
|
||||
#endif
|
||||
"apply",
|
||||
"call-with-current-continuation",
|
||||
|
||||
/* user visible ISYMS */
|
||||
/* other keywords */
|
||||
/* Flags */
|
||||
|
||||
"#f",
|
||||
"#t",
|
||||
"#<undefined>",
|
||||
"#<eof>",
|
||||
"()",
|
||||
"#<unspecified>"
|
||||
};
|
||||
|
||||
static void
|
||||
scm_scmlist_print (LONGEST svalue, struct ui_file *stream, int format,
|
||||
int deref_ref, int recurse, enum val_prettyprint pretty)
|
||||
{
|
||||
unsigned int more = print_max;
|
||||
if (recurse > 6)
|
||||
{
|
||||
fputs_filtered ("...", stream);
|
||||
return;
|
||||
}
|
||||
scm_scmval_print (SCM_CAR (svalue), stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
svalue = SCM_CDR (svalue);
|
||||
for (; SCM_NIMP (svalue); svalue = SCM_CDR (svalue))
|
||||
{
|
||||
if (SCM_NECONSP (svalue))
|
||||
break;
|
||||
fputs_filtered (" ", stream);
|
||||
if (--more == 0)
|
||||
{
|
||||
fputs_filtered ("...", stream);
|
||||
return;
|
||||
}
|
||||
scm_scmval_print (SCM_CAR (svalue), stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
}
|
||||
if (SCM_NNULLP (svalue))
|
||||
{
|
||||
fputs_filtered (" . ", stream);
|
||||
scm_scmval_print (svalue, stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
scm_ipruk (char *hdr, LONGEST ptr, struct ui_file *stream)
|
||||
{
|
||||
fprintf_filtered (stream, "#<unknown-%s", hdr);
|
||||
#define SCM_SIZE TYPE_LENGTH (builtin_type_scm)
|
||||
if (SCM_CELLP (ptr))
|
||||
fprintf_filtered (stream, " (0x%lx . 0x%lx) @",
|
||||
(long) SCM_CAR (ptr), (long) SCM_CDR (ptr));
|
||||
fprintf_filtered (stream, " 0x%s>", paddr_nz (ptr));
|
||||
}
|
||||
|
||||
void
|
||||
scm_scmval_print (LONGEST svalue, struct ui_file *stream, int format,
|
||||
int deref_ref, int recurse, enum val_prettyprint pretty)
|
||||
{
|
||||
taloop:
|
||||
switch (7 & (int) svalue)
|
||||
{
|
||||
case 2:
|
||||
case 6:
|
||||
print_longest (stream, format ? format : 'd', 1, svalue >> 2);
|
||||
break;
|
||||
case 4:
|
||||
if (SCM_ICHRP (svalue))
|
||||
{
|
||||
svalue = SCM_ICHR (svalue);
|
||||
scm_printchar (svalue, stream);
|
||||
break;
|
||||
}
|
||||
else if (SCM_IFLAGP (svalue)
|
||||
&& (SCM_ISYMNUM (svalue)
|
||||
< (sizeof scm_isymnames / sizeof (char *))))
|
||||
{
|
||||
fputs_filtered (SCM_ISYMCHARS (svalue), stream);
|
||||
break;
|
||||
}
|
||||
else if (SCM_ILOCP (svalue))
|
||||
{
|
||||
fprintf_filtered (stream, "#@%ld%c%ld",
|
||||
(long) SCM_IFRAME (svalue),
|
||||
SCM_ICDRP (svalue) ? '-' : '+',
|
||||
(long) SCM_IDIST (svalue));
|
||||
break;
|
||||
}
|
||||
else
|
||||
goto idef;
|
||||
break;
|
||||
case 1:
|
||||
/* gloc */
|
||||
svalue = SCM_CAR (svalue - 1);
|
||||
goto taloop;
|
||||
default:
|
||||
idef:
|
||||
scm_ipruk ("immediate", svalue, stream);
|
||||
break;
|
||||
case 0:
|
||||
|
||||
switch (SCM_TYP7 (svalue))
|
||||
{
|
||||
case scm_tcs_cons_gloc:
|
||||
if (SCM_CDR (SCM_CAR (svalue) - 1L) == 0)
|
||||
{
|
||||
#if 0
|
||||
SCM name;
|
||||
#endif
|
||||
fputs_filtered ("#<latte ", stream);
|
||||
#if 1
|
||||
fputs_filtered ("???", stream);
|
||||
#else
|
||||
name = ((SCM n *) (STRUCT_TYPE (exp)))[struct_i_name];
|
||||
scm_lfwrite (CHARS (name),
|
||||
(sizet) sizeof (char),
|
||||
(sizet) LENGTH (name),
|
||||
port);
|
||||
#endif
|
||||
fprintf_filtered (stream, " #X%s>", paddr_nz (svalue));
|
||||
break;
|
||||
}
|
||||
case scm_tcs_cons_imcar:
|
||||
case scm_tcs_cons_nimcar:
|
||||
fputs_filtered ("(", stream);
|
||||
scm_scmlist_print (svalue, stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
fputs_filtered (")", stream);
|
||||
break;
|
||||
case scm_tcs_closures:
|
||||
fputs_filtered ("#<CLOSURE ", stream);
|
||||
scm_scmlist_print (SCM_CODE (svalue), stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
fputs_filtered (">", stream);
|
||||
break;
|
||||
case scm_tc7_string:
|
||||
{
|
||||
int len = SCM_LENGTH (svalue);
|
||||
CORE_ADDR addr = (CORE_ADDR) SCM_CDR (svalue);
|
||||
int i;
|
||||
int done = 0;
|
||||
int buf_size;
|
||||
gdb_byte buffer[64];
|
||||
int truncate = print_max && len > (int) print_max;
|
||||
if (truncate)
|
||||
len = print_max;
|
||||
fputs_filtered ("\"", stream);
|
||||
for (; done < len; done += buf_size)
|
||||
{
|
||||
buf_size = min (len - done, 64);
|
||||
read_memory (addr + done, buffer, buf_size);
|
||||
|
||||
for (i = 0; i < buf_size; ++i)
|
||||
switch (buffer[i])
|
||||
{
|
||||
case '\"':
|
||||
case '\\':
|
||||
fputs_filtered ("\\", stream);
|
||||
default:
|
||||
fprintf_filtered (stream, "%c", buffer[i]);
|
||||
}
|
||||
}
|
||||
fputs_filtered (truncate ? "...\"" : "\"", stream);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case scm_tcs_symbols:
|
||||
{
|
||||
int len = SCM_LENGTH (svalue);
|
||||
|
||||
char *str = alloca (len);
|
||||
read_memory (SCM_CDR (svalue), (gdb_byte *) str, len + 1);
|
||||
/* Should handle weird characters FIXME */
|
||||
str[len] = '\0';
|
||||
fputs_filtered (str, stream);
|
||||
break;
|
||||
}
|
||||
case scm_tc7_vector:
|
||||
{
|
||||
int len = SCM_LENGTH (svalue);
|
||||
int i;
|
||||
LONGEST elements = SCM_CDR (svalue);
|
||||
fputs_filtered ("#(", stream);
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
fputs_filtered (" ", stream);
|
||||
scm_scmval_print (scm_get_field (elements, i), stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
}
|
||||
fputs_filtered (")", stream);
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
case tc7_lvector:
|
||||
{
|
||||
SCM result;
|
||||
SCM hook;
|
||||
hook = scm_get_lvector_hook (exp, LV_PRINT_FN);
|
||||
if (hook == BOOL_F)
|
||||
{
|
||||
scm_puts ("#<locked-vector ", port);
|
||||
scm_intprint (CDR (exp), 16, port);
|
||||
scm_puts (">", port);
|
||||
}
|
||||
else
|
||||
{
|
||||
result
|
||||
= scm_apply (hook,
|
||||
scm_listify (exp, port,
|
||||
(writing ? BOOL_T : BOOL_F),
|
||||
SCM_UNDEFINED),
|
||||
EOL);
|
||||
if (result == BOOL_F)
|
||||
goto punk;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case tc7_bvect:
|
||||
case tc7_ivect:
|
||||
case tc7_uvect:
|
||||
case tc7_fvect:
|
||||
case tc7_dvect:
|
||||
case tc7_cvect:
|
||||
scm_raprin1 (exp, port, writing);
|
||||
break;
|
||||
#endif
|
||||
case scm_tcs_subrs:
|
||||
{
|
||||
int index = SCM_CAR (svalue) >> 8;
|
||||
#if 1
|
||||
char str[20];
|
||||
sprintf (str, "#%d", index);
|
||||
#else
|
||||
char *str = index ? SCM_CHARS (scm_heap_org + index) : "";
|
||||
#define SCM_CHARS(x) ((char *)(SCM_CDR(x)))
|
||||
char *str = CHARS (SNAME (exp));
|
||||
#endif
|
||||
fprintf_filtered (stream, "#<primitive-procedure %s>",
|
||||
str);
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
#ifdef CCLO
|
||||
case tc7_cclo:
|
||||
scm_puts ("#<compiled-closure ", port);
|
||||
scm_iprin1 (CCLO_SUBR (exp), port, writing);
|
||||
scm_putc ('>', port);
|
||||
break;
|
||||
#endif
|
||||
case tc7_contin:
|
||||
fprintf_filtered (stream, "#<continuation %d @ #X%lx >",
|
||||
LENGTH (svalue),
|
||||
(long) CHARS (svalue));
|
||||
break;
|
||||
case tc7_port:
|
||||
i = PTOBNUM (exp);
|
||||
if (i < scm_numptob
|
||||
&& scm_ptobs[i].print
|
||||
&& (scm_ptobs[i].print) (exp, port, writing))
|
||||
break;
|
||||
goto punk;
|
||||
case tc7_smob:
|
||||
i = SMOBNUM (exp);
|
||||
if (i < scm_numsmob && scm_smobs[i].print
|
||||
&& (scm_smobs[i].print) (exp, port, writing))
|
||||
break;
|
||||
goto punk;
|
||||
#endif
|
||||
default:
|
||||
#if 0
|
||||
punk:
|
||||
#endif
|
||||
scm_ipruk ("type", svalue, stream);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
scm_val_print (struct type *type, const gdb_byte *valaddr,
|
||||
int embedded_offset, CORE_ADDR address,
|
||||
struct ui_file *stream, int format, int deref_ref,
|
||||
int recurse, enum val_prettyprint pretty)
|
||||
{
|
||||
if (is_scmvalue_type (type))
|
||||
{
|
||||
LONGEST svalue = extract_signed_integer (valaddr, TYPE_LENGTH (type));
|
||||
if (scm_inferior_print (svalue, stream, format,
|
||||
deref_ref, recurse, pretty) >= 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
scm_scmval_print (svalue, stream, format,
|
||||
deref_ref, recurse, pretty);
|
||||
}
|
||||
|
||||
gdb_flush (stream);
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return c_val_print (type, valaddr, 0, address, stream, format,
|
||||
deref_ref, recurse, pretty);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
scm_value_print (struct value *val, struct ui_file *stream, int format,
|
||||
enum val_prettyprint pretty)
|
||||
{
|
||||
return (common_val_print (val, stream, format, 1, 0, pretty));
|
||||
}
|
440
gdb/ser-e7kpc.c
440
gdb/ser-e7kpc.c
@ -1,440 +0,0 @@
|
||||
/* Remote serial interface using Renesas E7000 PC ISA card in a PC
|
||||
Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#if defined __GO32__ || defined _WIN32
|
||||
#include "serial.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GO32__
|
||||
#include <sys/dos.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
static int e7000pc_open (struct serial *scb, const char *name);
|
||||
static void e7000pc_raw (struct serial *scb);
|
||||
static int e7000pc_readchar (struct serial *scb, int timeout);
|
||||
static int e7000pc_setbaudrate (struct serial *scb, int rate);
|
||||
static int e7000pc_write (struct serial *scb, const char *str, int len);
|
||||
static void e7000pc_close (struct serial *scb);
|
||||
static serial_ttystate e7000pc_get_tty_state (struct serial *scb);
|
||||
static int e7000pc_set_tty_state (struct serial *scb, serial_ttystate state);
|
||||
|
||||
#define OFF_DPD 0x0000
|
||||
#define OFF_DDP 0x1000
|
||||
#define OFF_CPD 0x2000
|
||||
#define OFF_CDP 0x2400
|
||||
#define OFF_FA 0x3000
|
||||
#define OFF_FB 0x3002
|
||||
#define OFF_FC 0x3004
|
||||
#define OFF_IRQTOD 0x3008
|
||||
#define OFF_IRQTOP 0x300a
|
||||
#define OFF_READY 0x300c
|
||||
#define OFF_PON 0x300e
|
||||
|
||||
#define IDLE 0x0000
|
||||
#define CMD_CI 0x4349
|
||||
#define CMD_CO 0x434f
|
||||
#define CMD_LO 0x4c4f
|
||||
#define CMD_LS 0x4c53
|
||||
#define CMD_SV 0x5356
|
||||
#define CMD_SS 0x5353
|
||||
#define CMD_OK 0x4f4b
|
||||
#define CMD_ER 0x4552
|
||||
#define CMD_NF 0x4e46
|
||||
#define CMD_AB 0x4142
|
||||
#define CMD_ED 0x4544
|
||||
#define CMD_CE 0x4345
|
||||
|
||||
static unsigned long fa;
|
||||
static unsigned long irqtod;
|
||||
static unsigned long ready;
|
||||
static unsigned long fb;
|
||||
static unsigned long cpd;
|
||||
static unsigned long cdp;
|
||||
static unsigned long ready;
|
||||
static unsigned long pon;
|
||||
static unsigned long irqtop;
|
||||
static unsigned long board_at;
|
||||
|
||||
#ifdef __GO32__
|
||||
|
||||
#define SET_BYTE(x,y) { char _buf = y;dosmemput(&_buf,1, x);}
|
||||
#define SET_WORD(x,y) { short _buf = y;dosmemput(&_buf,2, x);}
|
||||
#define GET_BYTE(x) ( dosmemget(x,1,&bb), bb)
|
||||
#define GET_WORD(x) ( dosmemget(x,2,&sb), sb)
|
||||
static unsigned char bb;
|
||||
static unsigned short sb;
|
||||
|
||||
#else /* win32 */
|
||||
|
||||
#define SET_BYTE(x,y) *(volatile unsigned char *)(x) = (y)
|
||||
#define SET_WORD(x,y) *(volatile unsigned short *)(x) = (y)
|
||||
#define GET_BYTE(x) (*(volatile unsigned char *)(x))
|
||||
#define GET_WORD(x) (*(volatile unsigned short *)(x))
|
||||
#define dosmemget(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN))
|
||||
#define dosmemput(FROM, LEN, TO) memcpy ((void *)(TO), (void *)(FROM), (LEN))
|
||||
#endif
|
||||
|
||||
static struct sw
|
||||
{
|
||||
int sw;
|
||||
int addr;
|
||||
}
|
||||
sigs[] =
|
||||
{
|
||||
{
|
||||
0x14, 0xd0000
|
||||
}
|
||||
,
|
||||
{
|
||||
0x15, 0xd4000
|
||||
}
|
||||
,
|
||||
{
|
||||
0x16, 0xd8000
|
||||
}
|
||||
,
|
||||
{
|
||||
0x17, 0xdc000
|
||||
}
|
||||
,
|
||||
0
|
||||
};
|
||||
|
||||
#define get_ds_base() 0
|
||||
|
||||
static int
|
||||
e7000pc_init (void)
|
||||
{
|
||||
int try;
|
||||
unsigned long dsbase;
|
||||
|
||||
dsbase = get_ds_base ();
|
||||
|
||||
/* Look around in memory for the board's signature */
|
||||
|
||||
for (try = 0; sigs[try].sw; try++)
|
||||
{
|
||||
int val;
|
||||
board_at = sigs[try].addr - dsbase;
|
||||
fa = board_at + OFF_FA;
|
||||
fb = board_at + OFF_FB;
|
||||
cpd = board_at + OFF_CPD;
|
||||
cdp = board_at + OFF_CDP;
|
||||
ready = board_at + OFF_READY;
|
||||
pon = board_at + OFF_PON;
|
||||
irqtop = board_at + OFF_IRQTOP;
|
||||
irqtod = board_at + OFF_IRQTOD;
|
||||
|
||||
val = GET_WORD (ready);
|
||||
|
||||
if (val == (0xaaa0 | sigs[try].sw))
|
||||
{
|
||||
if (GET_WORD (pon) & 0xf)
|
||||
{
|
||||
SET_WORD (fa, 0);
|
||||
SET_WORD (fb, 0);
|
||||
|
||||
SET_WORD (irqtop, 1); /* Disable interrupts from e7000 */
|
||||
SET_WORD (ready, 1);
|
||||
printf_filtered ("\nConnected to the E7000PC at address 0x%x\n",
|
||||
sigs[try].addr);
|
||||
return 1;
|
||||
}
|
||||
error (_("The E7000 PC board is working, but the E7000 is turned off."));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
error (_("GDB cannot connect to the E7000 PC board, check that it is installed\n\
|
||||
and that the switch settings are correct. Some other DOS programs can \n\
|
||||
stop the board from working. Try starting from a very minimal boot, \n\
|
||||
perhaps you need to disable EMM386 over the region where the board has\n\
|
||||
its I/O space, remove other unneeded cards, etc etc\n"));
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int pbuf_size;
|
||||
static int pbuf_index;
|
||||
|
||||
/* Return next byte from cdp. If no more, then return -1. */
|
||||
|
||||
static int
|
||||
e7000_get (void)
|
||||
{
|
||||
static char pbuf[1000];
|
||||
char tmp[1000];
|
||||
int x;
|
||||
|
||||
if (pbuf_index < pbuf_size)
|
||||
{
|
||||
x = pbuf[pbuf_index++];
|
||||
}
|
||||
else if ((GET_WORD (fb) & 1))
|
||||
{
|
||||
int i;
|
||||
pbuf_size = GET_WORD (cdp + 2);
|
||||
|
||||
dosmemget (cdp + 8, pbuf_size + 1, tmp);
|
||||
|
||||
/* Tell the E7000 we've eaten */
|
||||
SET_WORD (fb, 0);
|
||||
/* Swap it around */
|
||||
for (i = 0; i < pbuf_size; i++)
|
||||
{
|
||||
pbuf[i] = tmp[i ^ 1];
|
||||
}
|
||||
pbuf_index = 0;
|
||||
x = pbuf[pbuf_index++];
|
||||
}
|
||||
else
|
||||
{
|
||||
x = -1;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Works just like read(), except that it takes a TIMEOUT in seconds. Note
|
||||
that TIMEOUT == 0 is a poll, and TIMEOUT == -1 means wait forever. */
|
||||
|
||||
static int
|
||||
dosasync_read (int fd, char *buf, int len, int timeout)
|
||||
{
|
||||
long now;
|
||||
long then;
|
||||
int i = 0;
|
||||
|
||||
/* Then look for some more if we're still hungry */
|
||||
time (&now);
|
||||
then = now + timeout;
|
||||
while (i < len)
|
||||
{
|
||||
int ch = e7000_get ();
|
||||
|
||||
/* While there's room in the buffer, and we've already
|
||||
read the stuff in, suck it over */
|
||||
if (ch != -1)
|
||||
{
|
||||
buf[i++] = ch;
|
||||
while (i < len && pbuf_index < pbuf_size)
|
||||
{
|
||||
ch = e7000_get ();
|
||||
if (ch == -1)
|
||||
break;
|
||||
buf[i++] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
time (&now);
|
||||
|
||||
if (timeout == 0)
|
||||
return i;
|
||||
if (now >= then && timeout > 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dosasync_write (int fd, const char *buf, int len)
|
||||
{
|
||||
int i;
|
||||
char dummy[1000];
|
||||
|
||||
/* Construct copy locally */
|
||||
((short *) dummy)[0] = CMD_CI;
|
||||
((short *) dummy)[1] = len;
|
||||
((short *) dummy)[2] = 0;
|
||||
((short *) dummy)[3] = 0;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
dummy[(8 + i) ^ 1] = buf[i];
|
||||
}
|
||||
|
||||
/* Wait for the card to get ready */
|
||||
while (GET_WORD (fa) & 1);
|
||||
|
||||
/* Blast onto the ISA card */
|
||||
dosmemput (dummy, 8 + len + 1, cpd);
|
||||
|
||||
SET_WORD (fa, 1);
|
||||
SET_WORD (irqtod, 1); /* Interrupt the E7000 */
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
e7000pc_open (struct serial *scb, const char *name)
|
||||
{
|
||||
if (strncasecmp (name, "pc", 2) != 0)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
scb->fd = e7000pc_init ();
|
||||
|
||||
if (!scb->fd)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
e7000pc_noop (struct serial *scb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
e7000pc_raw (struct serial *scb)
|
||||
{
|
||||
/* Always in raw mode */
|
||||
}
|
||||
|
||||
static int
|
||||
e7000pc_readchar (struct serial *scb, int timeout)
|
||||
{
|
||||
char buf;
|
||||
|
||||
top:
|
||||
|
||||
if (dosasync_read (scb->fd, &buf, 1, timeout))
|
||||
{
|
||||
if (buf == 0)
|
||||
goto top;
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
return SERIAL_TIMEOUT;
|
||||
}
|
||||
|
||||
struct e7000pc_ttystate
|
||||
{
|
||||
int dummy;
|
||||
};
|
||||
|
||||
/* e7000pc_{get set}_tty_state() are both dummys to fill out the function
|
||||
vector. Someday, they may do something real... */
|
||||
|
||||
static serial_ttystate
|
||||
e7000pc_get_tty_state (struct serial *scb)
|
||||
{
|
||||
struct e7000pc_ttystate *state;
|
||||
|
||||
state = (struct e7000pc_ttystate *) xmalloc (sizeof *state);
|
||||
|
||||
return (serial_ttystate) state;
|
||||
}
|
||||
|
||||
static int
|
||||
e7000pc_set_tty_state (struct serial *scb, serial_ttystate ttystate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
e7000pc_noflush_set_tty_state (struct serial *scb,
|
||||
serial_ttystate new_ttystate,
|
||||
serial_ttystate old_ttystate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
e7000pc_print_tty_state (struct serial *scb,
|
||||
serial_ttystate ttystate,
|
||||
struct ui_file *stream)
|
||||
{
|
||||
/* Nothing to print. */
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
e7000pc_setbaudrate (struct serial *scb, int rate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
e7000pc_setstopbits (struct serial *scb, int rate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
e7000pc_write (struct serial *scb, const char *str, int len)
|
||||
{
|
||||
dosasync_write (scb->fd, str, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
e7000pc_close (struct serial *scb)
|
||||
{
|
||||
}
|
||||
|
||||
static struct serial_ops e7000pc_ops =
|
||||
{
|
||||
"pc",
|
||||
0,
|
||||
e7000pc_open,
|
||||
e7000pc_close,
|
||||
e7000pc_readchar,
|
||||
e7000pc_write,
|
||||
e7000pc_noop, /* flush output */
|
||||
e7000pc_noop, /* flush input */
|
||||
e7000pc_noop, /* send break -- currently used only for nindy */
|
||||
e7000pc_raw,
|
||||
e7000pc_get_tty_state,
|
||||
e7000pc_set_tty_state,
|
||||
e7000pc_print_tty_state,
|
||||
e7000pc_noflush_set_tty_state,
|
||||
e7000pc_setbaudrate,
|
||||
e7000pc_setstopbits,
|
||||
e7000pc_noop, /* wait for output to drain */
|
||||
};
|
||||
|
||||
#endif /*_WIN32 or __GO32__*/
|
||||
|
||||
extern initialize_file_ftype _initialize_ser_e7000pc; /* -Wmissing-prototypes */
|
||||
|
||||
void
|
||||
_initialize_ser_e7000pc (void)
|
||||
{
|
||||
#if defined __GO32__ || defined _WIN32
|
||||
serial_add_interface (&e7000pc_ops);
|
||||
#endif
|
||||
}
|
400
gdb/sh3-rom.c
400
gdb/sh3-rom.c
@ -1,400 +0,0 @@
|
||||
/* Remote target glue for the Renesas SH-3 ROM monitor.
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdbcore.h"
|
||||
#include "target.h"
|
||||
#include "monitor.h"
|
||||
#include "serial.h"
|
||||
#include "srec.h"
|
||||
#include "arch-utils.h"
|
||||
#include "regcache.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "sh-tdep.h"
|
||||
|
||||
static struct serial *parallel;
|
||||
static int parallel_in_use;
|
||||
|
||||
static void sh3_open (char *args, int from_tty);
|
||||
|
||||
static void
|
||||
sh3_supply_register (char *regname, int regnamelen, char *val, int vallen)
|
||||
{
|
||||
int numregs;
|
||||
int regno;
|
||||
|
||||
numregs = 1;
|
||||
regno = -1;
|
||||
|
||||
if (regnamelen == 2)
|
||||
{
|
||||
switch (regname[0])
|
||||
{
|
||||
case 'S':
|
||||
if (regname[1] == 'R')
|
||||
regno = SR_REGNUM;
|
||||
break;
|
||||
case 'P':
|
||||
if (regname[1] == 'C')
|
||||
regno = PC_REGNUM;
|
||||
else if (regname[1] == 'R')
|
||||
regno = PR_REGNUM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (regnamelen == 3)
|
||||
{
|
||||
switch (regname[0])
|
||||
{
|
||||
case 'G':
|
||||
case 'V':
|
||||
if (regname[1] == 'B' && regname[2] == 'R')
|
||||
{
|
||||
if (regname[0] == 'G')
|
||||
regno = VBR_REGNUM;
|
||||
else
|
||||
regno = GBR_REGNUM;
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
if (regname[1] == 'S' && regname[2] == 'R')
|
||||
regno = SSR_REGNUM;
|
||||
else if (regname[1] == 'P' && regname[2] == 'C')
|
||||
regno = SPC_REGNUM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (regnamelen == 4)
|
||||
{
|
||||
switch (regname[0])
|
||||
{
|
||||
case 'M':
|
||||
if (regname[1] == 'A' && regname[2] == 'C')
|
||||
{
|
||||
if (regname[3] == 'H')
|
||||
regno = MACH_REGNUM;
|
||||
else if (regname[3] == 'L')
|
||||
regno = MACL_REGNUM;
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
if (regname[1] == '0' && regname[2] == '-' && regname[3] == '7')
|
||||
{
|
||||
regno = R0_REGNUM;
|
||||
numregs = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (regnamelen == 5)
|
||||
{
|
||||
if (regname[1] == '8' && regname[2] == '-' && regname[3] == '1'
|
||||
&& regname[4] == '5')
|
||||
{
|
||||
regno = R0_REGNUM + 8;
|
||||
numregs = 8;
|
||||
}
|
||||
}
|
||||
else if (regnamelen == 17)
|
||||
{
|
||||
}
|
||||
|
||||
if (regno >= 0)
|
||||
while (numregs-- > 0)
|
||||
val = monitor_supply_register (regno++, val);
|
||||
}
|
||||
|
||||
static void
|
||||
sh3_load (struct serial *desc, char *file, int hashmark)
|
||||
{
|
||||
if (parallel_in_use)
|
||||
{
|
||||
monitor_printf ("pl;s\r");
|
||||
load_srec (parallel, file, 0, 80, SREC_ALL, hashmark, NULL);
|
||||
monitor_expect_prompt (NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
monitor_printf ("il;s:x\r");
|
||||
monitor_expect ("\005", NULL, 0); /* Look for ENQ */
|
||||
serial_write (desc, "\006", 1); /* Send ACK */
|
||||
monitor_expect ("LO x\r", NULL, 0); /* Look for filename */
|
||||
|
||||
load_srec (desc, file, 0, 80, SREC_ALL, hashmark, NULL);
|
||||
|
||||
monitor_expect ("\005", NULL, 0); /* Look for ENQ */
|
||||
serial_write (desc, "\006", 1); /* Send ACK */
|
||||
monitor_expect_prompt (NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* This array of registers need to match the indexes used by GDB.
|
||||
This exists because the various ROM monitors use different strings
|
||||
than does GDB, and don't necessarily support all the registers
|
||||
either. So, typing "info reg sp" becomes a "r30". */
|
||||
|
||||
static char *sh3_regnames[] =
|
||||
{
|
||||
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
|
||||
"R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
|
||||
"PC", "PR", "GBR", "VBR", "MACH", "MACL", "SR",
|
||||
NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
"SSR", "SPC",
|
||||
"R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
|
||||
"R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
|
||||
"R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
|
||||
"R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
|
||||
};
|
||||
|
||||
static char *sh3e_regnames[] =
|
||||
{
|
||||
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
|
||||
"R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
|
||||
"PC", "PR", "GBR", "VBR", "MACH", "MACL", "SR",
|
||||
"FPUL", "FPSCR",
|
||||
"FR0", "FR1", "FR2", "FR3", "FR4", "FR5", "FR6", "FR7",
|
||||
"FR8", "FR9", "FR10", "FR11", "FR12", "FR13", "FR14", "FR15",
|
||||
"SSR", "SPC",
|
||||
"R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
|
||||
"R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
|
||||
"R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
|
||||
"R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
|
||||
};
|
||||
|
||||
/* Define the monitor command strings. Since these are passed directly
|
||||
through to a printf style function, we may include formatting
|
||||
strings. We also need a CR or LF on the end. */
|
||||
|
||||
static struct target_ops sh3_ops, sh3e_ops;
|
||||
|
||||
static char *sh3_inits[] =
|
||||
{"\003", NULL}; /* Exits sub-command mode & download cmds */
|
||||
|
||||
static struct monitor_ops sh3_cmds;
|
||||
|
||||
static void
|
||||
init_sh3_cmds (void)
|
||||
{
|
||||
sh3_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_GETMEM_READ_SINGLE; /* flags */
|
||||
sh3_cmds.init = sh3_inits; /* monitor init string */
|
||||
sh3_cmds.cont = "g\r"; /* continue command */
|
||||
sh3_cmds.step = "s\r"; /* single step */
|
||||
sh3_cmds.stop = "\003"; /* Interrupt program */
|
||||
sh3_cmds.set_break = "b %x\r"; /* set a breakpoint */
|
||||
sh3_cmds.clr_break = "b -%x\r"; /* clear a breakpoint */
|
||||
sh3_cmds.clr_all_break = "b -\r"; /* clear all breakpoints */
|
||||
sh3_cmds.fill = "f %x @%x %x\r"; /* fill (start len val) */
|
||||
sh3_cmds.setmem.cmdb = "m %x %x\r"; /* setmem.cmdb (addr, value) */
|
||||
sh3_cmds.setmem.cmdw = "m %x %x;w\r"; /* setmem.cmdw (addr, value) */
|
||||
sh3_cmds.setmem.cmdl = "m %x %x;l\r"; /* setmem.cmdl (addr, value) */
|
||||
sh3_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
|
||||
sh3_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
|
||||
sh3_cmds.setmem.term = NULL; /* setreg.term */
|
||||
sh3_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
|
||||
sh3_cmds.getmem.cmdb = "m %x\r"; /* getmem.cmdb (addr, len) */
|
||||
sh3_cmds.getmem.cmdw = "m %x;w\r"; /* getmem.cmdw (addr, len) */
|
||||
sh3_cmds.getmem.cmdl = "m %x;l\r"; /* getmem.cmdl (addr, len) */
|
||||
sh3_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
|
||||
sh3_cmds.getmem.resp_delim = "^ [0-9A-F]+ "; /* getmem.resp_delim */
|
||||
sh3_cmds.getmem.term = "? "; /* getmem.term */
|
||||
sh3_cmds.getmem.term_cmd = ".\r"; /* getmem.term_cmd */
|
||||
sh3_cmds.setreg.cmd = ".%s %x\r"; /* setreg.cmd (name, value) */
|
||||
sh3_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
|
||||
sh3_cmds.setreg.term = NULL; /* setreg.term */
|
||||
sh3_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
|
||||
sh3_cmds.getreg.cmd = ".%s\r"; /* getreg.cmd (name) */
|
||||
sh3_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
|
||||
sh3_cmds.getreg.term = "? "; /* getreg.term */
|
||||
sh3_cmds.getreg.term_cmd = ".\r"; /* getreg.term_cmd */
|
||||
sh3_cmds.dump_registers = "r\r"; /* dump_registers */
|
||||
sh3_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\( +[0-9a-fA-F]+\\b\\)*\\)";
|
||||
sh3_cmds.supply_register = sh3_supply_register;
|
||||
sh3_cmds.load_routine = sh3_load; /* load_routine */
|
||||
sh3_cmds.load = NULL; /* download command */
|
||||
sh3_cmds.loadresp = NULL; /* Load response */
|
||||
sh3_cmds.prompt = "\n:"; /* monitor command prompt */
|
||||
sh3_cmds.line_term = "\r"; /* end-of-line terminator */
|
||||
sh3_cmds.cmd_end = ".\r"; /* optional command terminator */
|
||||
sh3_cmds.target = &sh3_ops; /* target operations */
|
||||
sh3_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
|
||||
sh3_cmds.regnames = sh3_regnames; /* registers names */
|
||||
sh3_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
|
||||
} /* init_sh3_cmds */
|
||||
|
||||
/* This monitor structure is identical except for a couple slots, so
|
||||
we will fill it in from the base structure when needed. */
|
||||
|
||||
static struct monitor_ops sh3e_cmds;
|
||||
|
||||
static void
|
||||
sh3_open (char *args, int from_tty)
|
||||
{
|
||||
char *serial_port_name = args;
|
||||
char *parallel_port_name = 0;
|
||||
|
||||
if (args)
|
||||
{
|
||||
char *cursor = serial_port_name = xstrdup (args);
|
||||
|
||||
while (*cursor && *cursor != ' ')
|
||||
cursor++;
|
||||
|
||||
if (*cursor)
|
||||
*cursor++ = 0;
|
||||
|
||||
while (*cursor == ' ')
|
||||
cursor++;
|
||||
|
||||
if (*cursor)
|
||||
parallel_port_name = cursor;
|
||||
}
|
||||
|
||||
monitor_open (serial_port_name, &sh3_cmds, from_tty);
|
||||
|
||||
if (parallel_port_name)
|
||||
{
|
||||
parallel = serial_open (parallel_port_name);
|
||||
|
||||
if (!parallel)
|
||||
perror_with_name (_("Unable to open parallel port."));
|
||||
|
||||
parallel_in_use = 1;
|
||||
}
|
||||
|
||||
|
||||
/* If we connected successfully, we know the processor is an SH3. */
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
gdbarch_info_init (&info);
|
||||
info.bfd_arch_info = bfd_lookup_arch (bfd_arch_sh, bfd_mach_sh3);
|
||||
if (!gdbarch_update_p (info))
|
||||
error (_("Target is not an SH3"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sh3e_open (char *args, int from_tty)
|
||||
{
|
||||
char *serial_port_name = args;
|
||||
char *parallel_port_name = 0;
|
||||
|
||||
if (args)
|
||||
{
|
||||
char *cursor = serial_port_name = xstrdup (args);
|
||||
|
||||
while (*cursor && *cursor != ' ')
|
||||
cursor++;
|
||||
|
||||
if (*cursor)
|
||||
*cursor++ = 0;
|
||||
|
||||
while (*cursor == ' ')
|
||||
cursor++;
|
||||
|
||||
if (*cursor)
|
||||
parallel_port_name = cursor;
|
||||
}
|
||||
|
||||
/* Set up the SH-3E monitor commands structure. */
|
||||
|
||||
memcpy (&sh3e_cmds, &sh3_cmds, sizeof (struct monitor_ops));
|
||||
|
||||
sh3e_cmds.target = &sh3e_ops;
|
||||
sh3e_cmds.regnames = sh3e_regnames;
|
||||
|
||||
monitor_open (serial_port_name, &sh3e_cmds, from_tty);
|
||||
|
||||
if (parallel_port_name)
|
||||
{
|
||||
parallel = serial_open (parallel_port_name);
|
||||
|
||||
if (!parallel)
|
||||
perror_with_name (_("Unable to open parallel port."));
|
||||
|
||||
parallel_in_use = 1;
|
||||
}
|
||||
|
||||
/* If we connected successfully, we know the processor is an SH3E. */
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
gdbarch_info_init (&info);
|
||||
info.bfd_arch_info = bfd_lookup_arch (bfd_arch_sh, bfd_mach_sh3);
|
||||
if (!gdbarch_update_p (info))
|
||||
error (_("Target is not an SH3"));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sh3_close (int quitting)
|
||||
{
|
||||
monitor_close (quitting);
|
||||
if (parallel_in_use)
|
||||
{
|
||||
serial_close (parallel);
|
||||
parallel_in_use = 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern initialize_file_ftype _initialize_sh3_rom; /* -Wmissing-prototypes */
|
||||
|
||||
void
|
||||
_initialize_sh3_rom (void)
|
||||
{
|
||||
init_sh3_cmds ();
|
||||
init_monitor_ops (&sh3_ops);
|
||||
|
||||
sh3_ops.to_shortname = "sh3";
|
||||
sh3_ops.to_longname = "Renesas SH-3 rom monitor";
|
||||
|
||||
sh3_ops.to_doc =
|
||||
/* We can download through the parallel port too. */
|
||||
"Debug on a Renesas eval board running the SH-3E rom monitor.\n"
|
||||
"Specify the serial device it is connected to.\n"
|
||||
"If you want to use the parallel port to download to it, specify that\n"
|
||||
"as an additional second argument.";
|
||||
|
||||
sh3_ops.to_open = sh3_open;
|
||||
sh3_ops.to_close = sh3_close;
|
||||
|
||||
add_target (&sh3_ops);
|
||||
|
||||
/* Setup the SH3e, which has float registers. */
|
||||
|
||||
init_monitor_ops (&sh3e_ops);
|
||||
|
||||
sh3e_ops.to_shortname = "sh3e";
|
||||
sh3e_ops.to_longname = "Renesas SH-3E rom monitor";
|
||||
|
||||
sh3e_ops.to_doc =
|
||||
/* We can download through the parallel port too. */
|
||||
"Debug on a Renesas eval board running the SH-3E rom monitor.\n"
|
||||
"Specify the serial device it is connected to.\n"
|
||||
"If you want to use the parallel port to download to it, specify that\n"
|
||||
"as an additional second argument.";
|
||||
|
||||
sh3e_ops.to_open = sh3e_open;
|
||||
sh3e_ops.to_close = sh3_close;
|
||||
|
||||
add_target (&sh3e_ops);
|
||||
}
|
109
gdb/stop-gdb.c
109
gdb/stop-gdb.c
@ -1,109 +0,0 @@
|
||||
/* A client to make GDB return to command level in Mach 3.
|
||||
Copyright (C) 1992, 1993, 1994, 2000, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* Authors: Jukka Virtanen <jtv@hut.fi> and Peter Stout <pds@cs.cmu.edu>.
|
||||
|
||||
A simple client to make GDB (versions 4.4 and later) on Mach 3 return
|
||||
to the command level when it is waiting for the inferior to stop.
|
||||
|
||||
Actions: Lookup the send right to the GDB message port from the
|
||||
NetMsgServer.
|
||||
|
||||
Send an asynchronous message with msgh_id
|
||||
GDB_MESSAGE_ID_STOP to that port.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#include <mach.h>
|
||||
#include <mach/message.h>
|
||||
#include <mach_error.h>
|
||||
#include <servers/netname.h>
|
||||
#include <servers/netname_defs.h>
|
||||
|
||||
void
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
kern_return_t kr;
|
||||
mach_msg_header_t msg;
|
||||
mach_port_t gdb_port;
|
||||
char *host;
|
||||
char *name;
|
||||
|
||||
if (argc == 1)
|
||||
argv[argc++] = GDB_DEF_NAME;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf (stderr, "Usage : %s <GDB name>\n", argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Allow the user to specify a remote host. */
|
||||
host = strchr (argv[1], '@');
|
||||
if (host)
|
||||
*(host++) = '\0';
|
||||
else
|
||||
host = (char *) "";
|
||||
|
||||
name = malloc (strlen (argv[1]) + sizeof (GDB_NAME_PREFIX));
|
||||
if (name == NULL)
|
||||
{
|
||||
fprintf (stderr, "Unable to allocate memory for name.");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
strcpy (name, GDB_NAME_PREFIX);
|
||||
strcat (name, argv[1]);
|
||||
|
||||
/* Look up the GDB service port. For convenience, add the
|
||||
GDB_NAME_PREFIX the argument before looking up the name.
|
||||
For backwards compatibility, do it without. */
|
||||
|
||||
kr = netname_look_up (name_server_port, host, name, &gdb_port);
|
||||
if (kr == NETNAME_NOT_CHECKED_IN)
|
||||
kr = netname_look_up (name_server_port, host, argv[1], &gdb_port);
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf (stderr, "Unable to lookup the GDB service port: %s.\n",
|
||||
mach_error_string (kr));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Code generated by mig stub generator, with minor cleanups :-)
|
||||
|
||||
simpleroutine stop_inferior(gdb_port : mach_port_t); */
|
||||
|
||||
msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);
|
||||
msg.msgh_remote_port = gdb_port;
|
||||
msg.msgh_local_port = MACH_PORT_NULL;
|
||||
msg.msgh_size = sizeof (msg);
|
||||
msg.msgh_seqno = 0;
|
||||
msg.msgh_id = GDB_MESSAGE_ID_STOP;
|
||||
|
||||
kr = mach_msg_send (&msg);
|
||||
if (kr != KERN_SUCCESS)
|
||||
fprintf (stderr, "Message not sent, return code %d : %s\n", kr,
|
||||
mach_error_string (kr));
|
||||
|
||||
exit (kr != KERN_SUCCESS);
|
||||
}
|
Loading…
Reference in New Issue
Block a user