Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Kris Warkentin" <kewarken@qnx.com>
To: "Mark Kettenis" <kettenis@chello.nl>
Cc: <gdb-patches@sources.redhat.com>
Subject: Re: [RFC] QNX Neutrino/i386 support
Date: Sun, 09 Mar 2003 17:51:00 -0000	[thread overview]
Message-ID: <002501c2e665$150a09e0$2a00a8c0@dash> (raw)
In-Reply-To: <200303090013.h290DnBU000820@elgar.kettenis.dyndns.org>

[-- Attachment #1: Type: text/plain, Size: 407 bytes --]

> Here are my comments about the i386-nto-tdep.c file.  Some general
> stuff first (which probably applies to the other files as well):

Hi Mark,

I've done the cleaning that you proposed and attached the revised files.
I'm not really fond of the branch and merging idea so if you really don't
want to put all of this stuff in, we'll rip everything out, start with the
minimum and work up from there.

Kris

[-- Attachment #2: nto-tdep.c --]
[-- Type: application/octet-stream, Size: 8792 bytes --]

/* nto-tdep.c - general QNX Neutrino target functionality */

/* Copyright 2003 Free Software Foundation */

/* Contributed by QNX Software Systems Ltd. */

#include <sys/stat.h>
#include "nto-tdep.h"
#include "top.h"
#include "cli/cli-decode.h"
#include "cli/cli-cmds.h"
#include "inferior.h"
#include "gdbarch.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "solib-svr4.h"
#include "gdbcore.h"

#ifdef __CYGWIN__
#include <sys/cygwin.h>
#endif

#ifdef __CYGWIN__
static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
#elif defined(__sun__) || defined(linux)
static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
#else
static char default_nto_target[] = "";
#endif

/* Maintenance debugging flag */
int nto_internal_debugging;

/* Filled in cpu info structure and flag to indicate its validity. 
 * This is initialized in procfs_attach or nto_start_remote depending on
 * our host/target.  It would only be invalid if we were talking to an
 * older pdebug which didn't support the cpuinfo message. */
unsigned nto_cpuinfo_flags;
int nto_cpuinfo_valid;

static char *
nto_target (void)
{
  char *p = getenv ("QNX_TARGET");

#ifdef __CYGWIN__
  static char buf[PATH_MAX];
  if (p)
    cygwin_conv_to_posix_path (p, buf);
  else
    cygwin_conv_to_posix_path (default_nto_target, buf);
  return buf;
#else
  return p ? p : default_nto_target;
#endif
}

/* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,
   CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */
int
nto_map_arch_to_cputype(const char *arch)
{
  if(!strcmp(arch, "i386") || !strcmp(arch, "x86"))
    return CPUTYPE_X86;
  if(!strcmp(arch, "rs6000") || !strcmp(arch, "ppc"))
    return CPUTYPE_PPC;
  if(!strcmp(arch, "mips"))
    return CPUTYPE_MIPS;
  if(!strcmp(arch, "arm"))
    return CPUTYPE_ARM;
  if(!strcmp(arch, "sh"))
    return CPUTYPE_SH;
  return CPUTYPE_UNKNOWN;
}

int
nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
{
  char *buf, arch_path[PATH_MAX], *nto_root, *endian;
  const char *arch;
  char *path_fmt = "%s/lib:%s/usr/lib:%s/usr/photon/lib\
:%s/usr/photon/dll:%s/lib/dll";

  nto_root = nto_target ();
  if (strcmp (TARGET_ARCHITECTURE->arch_name, "i386") == 0)
    {
      arch = "x86";
      endian = "";
    }
  else if (strcmp (TARGET_ARCHITECTURE->arch_name, "rs6000") == 0)
    {
      arch = "ppc";
      endian = "be";
    }
  else
    {
      arch = TARGET_ARCHITECTURE->arch_name;
      endian = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "be" : "le";
    }

  sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);

  buf = alloca (strlen(path_fmt) + strlen(arch_path) * 5 + 1);
  sprintf (buf, path_fmt, arch_path, arch_path, arch_path, arch_path, arch_path);

  return openp(buf, 1, solib, o_flags, 0, temp_pathname);
}

void
nto_init_solib_absolute_prefix (void)
{
  char buf[PATH_MAX * 2], arch_path[PATH_MAX];
  char *nto_root, *endian;
  const char *arch;

  nto_root = nto_target ();
  if (strcmp (TARGET_ARCHITECTURE->arch_name, "i386") == 0)
    {
      arch = "x86";
      endian = "";
    }
  else if (strcmp (TARGET_ARCHITECTURE->arch_name, "rs6000") == 0)
    {
      arch = "ppc";
      endian = "be";
    }
  else
    {
      arch = TARGET_ARCHITECTURE->arch_name;
      endian = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "be" : "le";
    }

  sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);

  sprintf (buf, "set solib-absolute-prefix %s", arch_path);
  execute_command (buf, 0);
}

char **
nto_parse_redirection (char *pargv[], char **pin, char **pout, char **perr)
{
  char **argv;
  char *in, *out, *err, *p;
  int argc, i, n;

  for (n = 0; pargv[n]; n++);
  if (n == 0)
    return NULL;
  in = "";
  out = "";
  err = "";

  argv = xcalloc (n + 1, sizeof argv[0]);
  argc = n;
  for (i = 0, n = 0; n < argc; n++)
    {
      p = pargv[n];
      if (*p == '>')
	{
	  p++;
	  if (*p)
	    out = p;
	  else
	    out = pargv[++n];
	}
      else if (*p == '<')
	{
	  p++;
	  if (*p)
	    in = p;
	  else
	    in = pargv[++n];
	}
      else if (*p++ == '2' && *p++ == '>')
	{
	  if (*p == '&' && *(p + 1) == '1')
	    err = out;
	  else if (*p)
	    err = p;
	  else
	    err = pargv[++n];
	}
      else
	argv[i++] = pargv[n];
    }
  *pin = in;
  *pout = out;
  *perr = err;
  return argv;
}

void
nto_source_extra_gdbinit (char *file)
{
  char *homedir, *homeinit;
  struct stat statbuf;

  homedir = getenv ("HOME");

  if (homedir && !inhibit_gdbinit)
    {
      homeinit = (char *) alloca (strlen (homedir) + strlen (file) + 10);
      sprintf (homeinit, "%s/%s", homedir, file);
      if (stat (homeinit, &statbuf) == 0)
	catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL);
    }
}

/* struct lm_info, LM_ADDR, and nto_truncate_ptr are copied from
   solib-svr4.c to support nto_relocate_section_addresses
   which is different from the svr4 version. */

struct lm_info
{
  /* Pointer to copy of link map from inferior.  The type is char *
     rather than void *, so that we may use byte offsets to find the
     various fields without the need for a cast.  */
  char *lm;
};

static CORE_ADDR
LM_ADDR (struct so_list *so)
{
  struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();

  return (CORE_ADDR) extract_signed_integer (so->lm_info->lm +
					     lmo->l_addr_offset,
					     lmo->l_addr_size);
}

static CORE_ADDR
nto_truncate_ptr (CORE_ADDR addr)
{
  if (TARGET_PTR_BIT == sizeof (CORE_ADDR) * 8)
    /* We don't need to truncate anything, and the bit twiddling below
       will fail due to overflow problems.  */
    return addr;
  else
    return addr & (((CORE_ADDR) 1 << TARGET_PTR_BIT) - 1);
}

Elf_Internal_Phdr *
find_load_phdr (bfd *abfd)
{
  Elf_Internal_Phdr *phdr;
  unsigned int i;

  if (!elf_tdata (abfd))
    return NULL;

  phdr = elf_tdata (abfd)->phdr;
  for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
    {
      if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
	return phdr;
    }
  return NULL;
}

void
nto_relocate_section_addresses (struct so_list *so, struct section_table *sec)
{
  /* Neutrino treats the l_addr base address field in link.h as different than
     the base address in the System V ABI and so the offset needs to be
     calculated and applied to relocations.  */
  Elf_Internal_Phdr *phdr = find_load_phdr (sec->bfd);
  unsigned vaddr = phdr ? phdr->p_vaddr : 0;

  sec->addr = nto_truncate_ptr (sec->addr + LM_ADDR (so) - vaddr);
  sec->endaddr = nto_truncate_ptr (sec->endaddr + LM_ADDR (so) - vaddr);
}

static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
  int which, CORE_ADDR reg_addr)
{
  nto_gregset_t gregset;
  nto_fpregset_t fpregset;

  nto_init_solib_absolute_prefix ();

  if (which == 0)
    {
      memcpy ((char *) &gregset, core_reg_sect,
	      min (core_reg_size, sizeof (gregset)));
      nto_supply_gregset (&gregset);
    }
  else if (which == 2)
    {
      memcpy ((char *) &fpregset, core_reg_sect,
	      min (core_reg_size, sizeof (fpregset)));
      nto_supply_fpregset (&fpregset);
    }
}

/* Register that we are able to handle ELF file formats using standard
   procfs "regset" structures.  */

static struct core_fns regset_core_fns = {
  bfd_target_elf_flavour,	/* core_flavour */
  default_check_format,		/* check_format */
  default_core_sniffer,		/* core_sniffer */
  fetch_core_registers,		/* core_read_registers */
  NULL				/* next */
};

void
_initialize_nto_tdep ()
{
  add_show_from_set (add_set_cmd ("nto-debug", class_maintenance, var_zinteger, (char *) &nto_internal_debugging, "Set QNX NTO internal debugging.\n\
When non-zero, nto specific debug info is\n\
displayed. Different information is displayed\n\
for different positive values.", &setdebuglist),
		     &showdebuglist);

  /* We use SIG45 for pulses, or something, so nostop, noprint
     and pass them. */
  signal_stop_update (target_signal_from_name ("SIG45"), 0);
  signal_print_update (target_signal_from_name ("SIG45"), 0);
  signal_pass_update (target_signal_from_name ("SIG45"), 1);

  /* By default we don't want to stop on these two, but we do want to pass. */
#if defined(SIGSELECT)
  signal_stop_update (SIGSELECT, 0);
  signal_print_update (SIGSELECT, 0);
  signal_pass_update (SIGSELECT, 1);
#endif

#if defined(SIGPHOTON)
  signal_stop_update (SIGPHOTON, 0);
  signal_print_update (SIGPHOTON, 0);
  signal_pass_update (SIGPHOTON, 1);
#endif

  /* Register core file support. */
  add_core_fns (&regset_core_fns);
}

[-- Attachment #3: nto-tdep.h --]
[-- Type: application/octet-stream, Size: 1894 bytes --]

/* nto-tdep.h - QNX Neutrino target header */

/* Copyright 2003 Free Software Foundation */

/* Contributed by QNX Software Systems Ltd. */

#ifndef _NTO_TDEP_H
#define _NTO_TDEP_H

#include "defs.h"
#include "nto-share/debug.h"
#include "solist.h"

/* Generic functions in nto-tdep.c. */

extern void nto_init_solib_absolute_prefix PARAMS ((void));

char **nto_parse_redirection
PARAMS ((char *start_argv[], char **in, char **out, char **err));

int proc_iterate_over_mappings PARAMS ((int (*func) (int, CORE_ADDR)));

void nto_source_extra_gdbinit PARAMS ((char *));

void nto_relocate_section_addresses
PARAMS ((struct so_list *, struct section_table *));

int nto_map_arch_to_cputype PARAMS((const char *));

int nto_find_and_open_solib PARAMS((char *, unsigned, char **));

/* Functions exported from all Neutrino targets (<target>-nto-tdep.c). */

unsigned nto_get_regset_id PARAMS ((int regno));

void nto_cpu_regset_fetch PARAMS ((int endian, int regset, void *data));

unsigned nto_get_regset_area PARAMS ((unsigned regset, char *subcmd));

unsigned nto_cpu_register_area
PARAMS ((unsigned first_regno, unsigned last_regno, unsigned char *subcmd,
	 unsigned *off, unsigned *len));

int nto_cpu_register_store
PARAMS ((int endian, unsigned first_regno, unsigned last_regno, void *data));

void nto_supply_gregset PARAMS ((union _debug_gregs *));

void nto_supply_fpregset PARAMS ((union _debug_fpregs *));

struct link_map_offsets *nto_fetch_link_map_offsets PARAMS ((void));

/* Globals. */

/* For 'maintenance debug nto-debug' command. */
extern int nto_internal_debugging;

/* The CPUINFO flags from the remote.  Currently used by
   i386 for fxsave but future proofing other hosts */
extern unsigned nto_cpuinfo_flags;

/* True if successfully retrieved cpuinfo from remote */
extern int nto_cpuinfo_valid;

#endif

[-- Attachment #4: i386-nto-tdep.c --]
[-- Type: application/octet-stream, Size: 9401 bytes --]

/* i386-nto-tdep.c - i386 specific functionality for QNX Neutrino */

/* Copyright 2003 Free Software Foundation */

/* Contributed by QNX Software Systems Ltd. */

#include "defs.h"
#include "frame.h"
#include "target.h"
#include "regcache.h"
#include "solib-svr4.h"
#include "i386-tdep.h"
#include "nto-tdep.h"
#include "osabi.h"
#include "nto-share/debug.h"
#include "i387-tdep.h"

#define NUM_GPREGS 13
static int gdb_to_nto[NUM_GPREGS] =
  { 7, 6, 5, 4, 11, 2, 1, 0, 8, 10, 9, 12, -1 };

#define GDB_TO_OS(x)	((x >= 0 && x < NUM_GPREGS) ? gdb_to_nto[x] : -1)

#ifndef X86_CPU_FXSR
#define X86_CPU_FXSR (1L << 12)
#endif

enum QNX_REGS
{
  QNX_REGS_GP = 0,
  QNX_REGS_FP = 1,
  QNX_REGS_END = 2
};

/* Given a register, return an id that represents the Neutrino
   regset it came from.  If reg == -1 update all regsets.  */
unsigned
nto_get_regset_id (int regno)
{
  if (regno == -1)
    return QNX_REGS_END;
  else if (regno < FP0_REGNUM)
    return QNX_REGS_GP;
  else if (regno < FPC_REGNUM)
    return QNX_REGS_FP;

  return -1; /* error */
}

/* Tell GDB about the regset contained in the 'data' buffer.  */
static void
gp_regset_fetch (char *data)
{
  unsigned first_regno;

  for (first_regno = 0; first_regno < FP0_REGNUM; first_regno++)
    {
      int regno = GDB_TO_OS (first_regno);
      int const blank = 0;

      if (data == NULL || regno == -1)
	  supply_register (first_regno, (char *) &blank);
      else
	  supply_register (first_regno, &data[regno * 4]);
    }
}

/* Get 8087 data.  */
static void
fp_regset_fetch (char *data)
{
  if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
    i387_supply_fxsave (data);
  else
    i387_supply_fsave (data);
}

void
nto_cpu_regset_fetch (int endian, int regset, void *data)
{
  endian = endian;  /* For i386, we don't care about endian. */

  switch (regset)
    {
    case QNX_REGS_GP:  /* QNX has different ordering of GP regs than GDB. */
      gp_regset_fetch ((char *) data);
      break;
    case QNX_REGS_FP:
      fp_regset_fetch ((char *) data);
      break;
    }
}

/* Get regset characteristics. */
unsigned
nto_get_regset_area (unsigned regset, char *subcmd)
{
  unsigned length = 0;
  switch (regset)
    {
    case QNX_REGS_GP:
      *subcmd = NTO_REG_GENERAL;
      length = NUM_GPREGS * sizeof (unsigned);
      break;
    case QNX_REGS_FP:
      *subcmd = NTO_REG_FLOAT;
      /* FIXME: should we calculate based on fxsave/fsave? */
      length = 512;
      break;
    default:
      length = 0;
    }
  return length;
}

/* Given the first and last register number, figure out the size/len
   of the Neutrino register save area to ask for/tell about.  Also set
   the register set that's being dealt with in *subcmd.  Watch out for
   the range crossing a register set boundry.  */
unsigned
nto_cpu_register_area (unsigned first_regno, unsigned last_regno, 
  unsigned char *subcmd, unsigned *off, unsigned *len)
{
  int regno = -1;

  if (first_regno < FP0_REGNUM)
    {
      if (last_regno >= FP0_REGNUM)
	last_regno = FP0_REGNUM - 1;
      *subcmd = NTO_REG_GENERAL;
      regno = GDB_TO_OS (first_regno);
      *off = regno * sizeof (unsigned);
      if (regno == -1)
	*len = 0;
      else
	*len = (last_regno - first_regno + 1) * sizeof (unsigned);
    }
  else if (first_regno == FP_REGNUM)
    {
      /* Frame Pointer Psuedo-register */
      *off = SP_REGNUM * sizeof (unsigned);
      *len = sizeof (unsigned);
      return FP_REGNUM;
    }
  else if (first_regno >= FP0_REGNUM && first_regno < FPC_REGNUM)
    {
      unsigned off_adjust, regsize;

      if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
	{
	  off_adjust = 32;
	  regsize = 16;
	}
      else
	{
	  off_adjust = 28;
	  regsize = 10;
	}

      if (last_regno >= FPC_REGNUM)
	last_regno = FPC_REGNUM - 1;
      *subcmd = NTO_REG_FLOAT;
      *off = (first_regno - FP0_REGNUM) * regsize + off_adjust;
      *len = (last_regno - first_regno + 1) * 10;
      /* Why 10?  GDB only stores 10 bytes per FP register so if we're
         sending a register back to the target, we only want pdebug to write
         10 bytes so as not to clobber the reserved 6 bytes in the fxsave
         structure.  The astute reader will note that this will fail if we
         try to send a range of fpregs rather than 1 at a time but, as far
         as I know, there is no way to send more than one fpreg at a time
         anyway.  If this turns out to be wrong, we may need to put more code
         in pdebug to deal with this - perhaps by masking off part of the
         register when it writes it in.*/
    }
  else
    {
      *len = 0;
      return last_regno;
    }
  return last_regno;
}

/* Build the Neutrino register set info into the 'data' buffer. */
int
nto_cpu_register_store (int endian, unsigned first_regno,
  unsigned last_regno, void *data)
{
  /* Mostly (always?) you're only storing one at a time. */
  if (first_regno == last_regno)
    {
      regcache_collect (first_regno, data);
      return 1;
    }
  /* Floating point is the same for gdb and target */
  if (first_regno >= FP0_REGNUM)
    {
      for (; first_regno <= last_regno; first_regno++)
	{
	  regcache_collect (first_regno, data);
	  (char *) data += REGISTER_RAW_SIZE (first_regno);
	}
      return 1;
    }
  /* GP registers are mapped differently for NTO than GDB */
  for (; first_regno <= last_regno; first_regno++)
    {
      int regnum = GDB_TO_OS (first_regno);
      if (regnum == -1)
	continue;
      regcache_collect (first_regno,
			(char *) data + sizeof (unsigned) * regnum);
    }
  return 1;
}

void
nto_supply_gregset (nto_gregset_t *gregsetp)
{
  int regi, i = 0;
  unsigned *regp = (unsigned *) gregsetp;

  for (regi = 0; regi < (NUM_REGS - FP0_REGNUM); regi++)
    {
      i = GDB_TO_OS (regi);
      supply_register (regi, (char *) &regp[i]);
    }
}

void
nto_supply_fpregset (nto_fpregset_t *fpregsetp)
{
  if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
    i387_supply_fxsave ((char *) fpregsetp);
  else
    i387_supply_fsave ((char *) fpregsetp);
}

/* Fetch (and possibly build) an appropriate link_map_offsets
   structure for native x86 targets using the struct offsets
   defined in link.h (but without actual reference to that file).

   This makes it possible to access x86 shared libraries from a GDB
   that was not built on an x86 host (for cross debugging).  */

static struct link_map_offsets *
i386_nto_svr4_fetch_link_map_offsets (void)
{
  static struct link_map_offsets lmo;
  static struct link_map_offsets *lmp = NULL;

  if (lmp == NULL)
    {
      lmp = &lmo;

      lmo.r_debug_size = 8;	/* The actual size is 20 bytes, but
				   this is all we need.  */
      lmo.r_map_offset = 4;
      lmo.r_map_size = 4;

      lmo.link_map_size = 20;	/* The actual size is 552 bytes, but
				   this is all we need.  */
      lmo.l_addr_offset = 0;
      lmo.l_addr_size = 4;

      lmo.l_name_offset = 4;
      lmo.l_name_size = 4;

      lmo.l_next_offset = 12;
      lmo.l_next_size = 4;

      lmo.l_prev_offset = 16;
      lmo.l_prev_size = 4;
    }

  return lmp;
}

struct link_map_offsets *
nto_fetch_link_map_offsets (void)
{
  return i386_nto_svr4_fetch_link_map_offsets ();
}

static int
i386_nto_pc_in_sigtramp (CORE_ADDR pc, char *name)
{
  return name && strcmp ("__signalstub", name) == 0;
}

static CORE_ADDR
i386_nto_sigcontext_addr (struct frame_info *frame)
{
  int sigcontext_offset = 136;

  if (get_next_frame (frame))
    return get_frame_base (get_next_frame (frame)) + sigcontext_offset;

  return read_register (SP_REGNUM) + sigcontext_offset;
}

static void
i386_nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  /* NTO uses ELF.  */
  i386_elf_init_abi (info, gdbarch);

  /* neutrino rewinds to look more normal */
  set_gdbarch_decr_pc_after_break (gdbarch, 0);

  /* NTO has shared libraries.  */
  set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);

  set_gdbarch_pc_in_sigtramp (gdbarch, i386_nto_pc_in_sigtramp);
  tdep->sigcontext_addr = i386_nto_sigcontext_addr;
  tdep->sc_pc_offset = 56;
  tdep->sc_sp_offset = 68;

  /* setjmp()'s return PC saved in EDX (5) */
  tdep->jb_pc_offset = 20; /* 5x32 bit ints in. */

  set_solib_svr4_fetch_link_map_offsets (gdbarch,
					 i386_nto_svr4_fetch_link_map_offsets);

  /* Our loader handles solib relocations slightly differently than svr4 */
  TARGET_SO_RELOCATE_SECTION_ADDRESSES = nto_relocate_section_addresses;

  /* Supply a nice function to find our solibs */
  TARGET_SO_FIND_AND_OPEN_SOLIB = nto_find_and_open_solib;

/* After a watchpoint trap, the PC points to the instruction after
   the one that caused the trap.  Therefore we don't need to step over it.
   But we do need to reset the status register to avoid another trap.  */
  HAVE_CONTINUABLE_WATCHPOINT = 1;
}

void
_initialize_i386_nto_tdep (void)
{
  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO,
			  i386_nto_init_abi);
}

  parent reply	other threads:[~2003-03-09 17:51 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-03-08 13:45 Mark Kettenis
2003-03-08 15:02 ` Kris Warkentin
2003-03-08 23:49   ` Mark Kettenis
2003-03-09  0:14   ` Mark Kettenis
2003-03-09  4:34     ` Kris Warkentin
2003-03-09 17:51     ` Kris Warkentin [this message]
2003-03-19 18:19       ` Kris Warkentin
2003-03-19 18:27         ` Mark Kettenis
2003-03-08 15:19 ` Kris Warkentin
2003-03-08 15:22   ` Kris Warkentin
2003-03-09 14:54 Kris Warkentin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='002501c2e665$150a09e0$2a00a8c0@dash' \
    --to=kewarken@qnx.com \
    --cc=gdb-patches@sources.redhat.com \
    --cc=kettenis@chello.nl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox