[patch] Add QNX remote protocol headers.

Kris Warkentin
2005-09-06T16:07:07Z

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

Hi,

I'm trying to break things up into smaller patches. The actual remote
support is the biggest patch. These headers are nice and bite sized and
most of our other targets are fairly discrete as well.

The file dsmsgs.h describes the structures used by the remote protocol
(pdebug). This is identical to what the pdebug server uses on the
target side.

The debug.h is a subset of our system header of the same name (and some
others) and describes the structures returned by various debug interface
system commands. Basically allows the same stuff as in our native
'nto-procfs.c' to work in the absence of system headers.

ChangeLog:

2005-09-06 Kris Warkentin <kewarken@qnx.com>

* nto-share/debug.h: New file.
* nto-share/dsmsgs.h: New file.

Look okay?

cheers,

Kris

[-- Attachment #2: debug.h --]
[-- Type: text/x-chdr, Size: 5608 bytes --]

/* QNX Neutrino debug interface.

Copyright 2005 Free Software Foundation, Inc.

Contributed by QNX Software Systems Ltd.

This file is part of GDB.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

/* __DEBUG_H_INCLUDED is Neutrino's native debug.h header. We don't want
these duplicate definitions if we're compiling natively and have already
included it. */
#ifndef __DEBUG_H_INCLUDED
#define __DEBUG_H_INCLUDED

#define QNX_NOTE_NAME "QNX"

typedef char qnx_64[8];

enum Elf_nto_note_types
{
QNT_NULL = 0,
QNT_DEBUG_FULLPATH,
QNT_DEBUG_RELOC,
QNT_STACK,
QNT_GENERATOR,
QNT_DEFAULT_LIB,
QNT_CORE_SYSINFO,
QNT_CORE_INFO,
QNT_CORE_STATUS,
QNT_CORE_GREG,
QNT_CORE_FPREG,
QNT_NUM
};

typedef struct
{
long bits[2];
} nto_sigset_t;

union nto_sigval
{
int sival_int;
void *sival_ptr;
};

typedef struct nto_siginfo
{
int si_signo;
int si_code;
void (*si_handler) ();
union
{
int _pad[6];
struct
{
pid_t _pid;
union
{
struct
{
union nto_sigval _value;
uid_t _uid;
} _kill;
struct
{
int _status;
clock_t _utime;
clock_t _stime;
} _chld;
} _pdata;
} _proc;
struct
{
int _fltno;
void *_addr;
void *_fltip;
} _fault;
} _data;
} nto_siginfo_t;

#ifdef __QNX__
__BEGIN_DECLS
#include <_pack64.h>
#endif
#define _DEBUG_FLAG_STOPPED 0x00000001 /* Thread is not running. */
#define DEBUG_FLAG_ISTOP 0x00000002 /* Stopped at point of interest. */
#define _DEBUG_FLAG_IPINVAL 0x00000010 /* IP is not valid. */
#define _DEBUG_FLAG_ISSYS 0x00000020 /* System process. */
#define _DEBUG_FLAG_SSTEP 0x00000040 /* Stopped because of single step. */
#define _DEBUG_FLAG_CURTID 0x00000080 /* Thread is current thread. */
#define DEBUG_FLAG_TRACE_EXEC 0x00000100 /* Stopped because of breakpoint. */
#define _DEBUG_FLAG_TRACE_RD 0x00000200 /* Stopped because of read access. */
#define _DEBUG_FLAG_TRACE_WR 0x00000400 /* Stopped because of write access. */
#define _DEBUG_FLAG_TRACE_MODIFY 0x00000800 /* Stopped because of modified memory. */
#define _DEBUG_FLAG_RLC 0x00010000 /* Run-on-Last-Close flag is set. */
#define _DEBUG_FLAG_KLC 0x00020000 /* Kill-on-Last-Close flag is set. */
#define _DEBUG_FLAG_FORK 0x00040000 /* Child inherits flags (Stop on fork/spawn). */
#define _DEBUG_FLAG_MASK 0x000f0000 /* Flags that can be changed. */
enum
{
_DEBUG_WHY_REQUESTED,
_DEBUG_WHY_SIGNALLED,
_DEBUG_WHY_FAULTED,
_DEBUG_WHY_JOBCONTROL,
_DEBUG_WHY_TERMINATED,
_DEBUG_WHY_CHILD,
_DEBUG_WHY_EXEC
};

#define _DEBUG_RUN_CLRSIG 0x00000001 /* Clear pending signal */
#define _DEBUG_RUN_CLRFLT 0x00000002 /* Clear pending fault */
#define DEBUG_RUN_TRACE 0x00000004 /* Trace mask flags interesting signals */
#define DEBUG_RUN_HOLD 0x00000008 /* Hold mask flags interesting signals */
#define DEBUG_RUN_FAULT 0x00000010 /* Fault mask flags interesting faults */
#define _DEBUG_RUN_VADDR 0x00000020 /* Change ip before running */
#define _DEBUG_RUN_STEP 0x00000040 /* Single step only one thread */
#define _DEBUG_RUN_STEP_ALL 0x00000080 /* Single step one thread, other threads run */
#define _DEBUG_RUN_CURTID 0x00000100 /* Change current thread (target thread) */
#define DEBUG_RUN_ARM 0x00000200 /* Deliver event at point of interest */

typedef struct _debug_process_info
{
pid_t pid;
pid_t parent;
unsigned flags;
unsigned umask;
pid_t child;
pid_t sibling;
pid_t pgrp;
pid_t sid;
int base_address;
int initial_stack;
uid_t uid;
gid_t gid;
uid_t euid;
gid_t egid;
uid_t suid;
gid_t sgid;
nto_sigset_t sig_ignore;
nto_sigset_t sig_queue;
nto_sigset_t sig_pending;
unsigned num_chancons;
unsigned num_fdcons;
unsigned num_threads;
unsigned num_timers;
qnx_64 reserved[20];
} nto_procfs_info;

typedef struct _debug_thread_info
{
pid_t pid;
unsigned tid;
unsigned flags;
unsigned short why;
unsigned short what;
int ip;
int sp;
int stkbase;
int tls;
unsigned stksize;
unsigned tid_flags;
unsigned char priority;
unsigned char real_priority;
unsigned char policy;
unsigned char state;
short syscall;
unsigned short last_cpu;
unsigned timeout;
int last_chid;
nto_sigset_t sig_blocked;
nto_sigset_t sig_pending;
nto_siginfo_t info;
unsigned reserved1;
union
{
struct
{
unsigned tid;
} join;
struct
{
int id;
int sync;
} sync;
struct
{
unsigned nid;
pid_t pid;
int coid;
int chid;
int scoid;
} connect;
struct
{
int chid;
} channel;
struct
{
pid_t pid;
int vaddr;
unsigned flags;
} waitpage;
struct
{
unsigned size;
} stack;
qnx_64 filler[4];
} blocked;
qnx_64 reserved2[8];
} nto_procfs_status;

#ifdef __QNX__
#include <_packpop.h>

__END_DECLS
#endif
#endif /* __DEBUG_H_INCLUDED */

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: dsmsgs.h --]
[-- Type: text/x-chdr; name="dsmsgs.h", Size: 15365 bytes --]

/* QNX Neutrino remote protocol definition.

Copyright 2005 Free Software Foundation, Inc.

Contributed by QNX Software Systems Ltd.

This file is part of GDB.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

#ifndef __DSMSGS_H__
#define __DSMSGS_H__

/* These are the protocol versioning numbers.
Update them with changes that introduce potential
compatibility issues. */
#define PDEBUG_PROTOVER_MAJOR 0x00000000
#define PDEBUG_PROTOVER_MINOR 0x00000003

#include <stddef.h>

/* These are pdebug specific errors, sent sometimes with the errno after
an action failed. Simply provides additional info on the reason for the
error. Sent in the DSrMsg_err_t.hdr.subcmd byte. */

#define PDEBUG_ENOERR 0 /* No error. */
#define PDEBUG_ENOPTY 1 /* No Pseudo Terminals found. */
#define PDEBUG_ETHREAD 2 /* Thread Create error. */
#define PDEBUG_ECONINV 3 /* Invalid Console number. */
#define PDEBUG_ESPAWN 4 /* Spawn error. */
#define PDEBUG_EPROCFS 5 /* NTO Proc File System error. */
#define PDEBUG_EPROCSTOP 6 /* NTO Process Stop error. */
#define PDEBUG_EQPSINFO 7 /* QNX4 PSINFO error. */
#define PDEBUG_EQMEMMODEL 8 /* QNX4 - Flat Memory Model only supported. */
#define PDEBUG_EQPROXY 9 /* QNX4 Proxy error. */
#define PDEBUG_EQDBG 10 /* QNX4 qnx_debug_* error. */

/* There is room for pdebugerrnos up to sizeof(unsigned char).

We are moving away from the channel commands - only the RESET
and NAK are required. The DEBUG and TEXT channels are now part
of the DShdr and TShdr structs, 4th byte. GP June 1 1999.
They are still supported, but not required.

A packet containg a single byte is a set channel command.
IE: 7e xx chksum 7e

After a set channel all following packets are in the format
for the specified channel. Currently three channels are defined.
The raw channel has no structure. The other channels are all framed.
The contents of each channel is defined by structures below.

0 - Reset channel. Used when either end starts.

1 - Debug channel with the structure which follows below.
Uses DS (Debug Services) prefix.

2 - Text channel with the structure which follows below.
Uses TS (Text Services) prefix.

0xff - Negative acknowledgment of a packet transmission. */

#define SET_CHANNEL_RESET 0
#define SET_CHANNEL_DEBUG 1
#define SET_CHANNEL_TEXT 2
#define SET_CHANNEL_NAK 0xff

/* Debug channel Messages: DS - Debug services. */

/* Defines and structures for the debug channel. */

#define DS_DATA_MAX_SIZE 1024
#define DS_DATA_RCV_SIZE(msg, total) ((total) - (sizeof(*(msg)) - DS_DATA_MAX_SIZE))
#define DS_MSG_OKSTATUS_FLAG 0x20000000
#define DS_MSG_OKDATA_FLAG 0x40000000
#define DS_MSG_NO_RESPONSE 0x80000000

#define QNXNTO_NSIG 57 /* From signals.h NSIG. */

/* Common message header. It must be 32 or 64 bit aligned.
The top bit of cmd is 1 for BIG endian data format. */
#define DSHDR_MSG_BIG_ENDIAN 0x80
struct DShdr
{
unsigned char cmd;
unsigned char subcmd;
unsigned char mid;
unsigned char channel;
};

/* Command types. */
enum
{
DStMsg_connect, /* 0 0x0 */
DStMsg_disconnect, /* 1 0x1 */
DStMsg_select, /* 2 0x2 */
DStMsg_mapinfo, /* 3 0x3 */
DStMsg_load, /* 4 0x4 */
DStMsg_attach, /* 5 0x5 */
DStMsg_detach, /* 6 0x6 */
DStMsg_kill, /* 7 0x7 */
DStMsg_stop, /* 8 0x8 */
DStMsg_memrd, /* 9 0x9 */
DStMsg_memwr, /* 10 0xA */
DStMsg_regrd, /* 11 0xB */
DStMsg_regwr, /* 12 0xC */
DStMsg_run, /* 13 0xD */
DStMsg_brk, /* 14 0xE */
DStMsg_fileopen, /* 15 0xF */
DStMsg_filerd, /* 16 0x10 */
DStMsg_filewr, /* 17 0x11 */
DStMsg_fileclose, /* 18 0x12 */
DStMsg_pidlist, /* 19 0x13 */
DStMsg_cwd, /* 20 0x14 */
DStMsg_env, /* 21 0x15 */
DStMsg_base_address, /* 22 0x16 */
DStMsg_protover, /* 23 0x17 */
DStMsg_handlesig, /* 24 0x18 */
DStMsg_cpuinfo, /* 25 0x19 */
/* Room for new codes here. */
DSrMsg_err = 32, /* 32 0x20 */
DSrMsg_ok, /* 33 0x21 */
DSrMsg_okstatus, /* 34 0x22 */
DSrMsg_okdata, /* 35 0x23 */
/* Room for new codes here. */
DShMsg_notify = 64 /* 64 0x40 */
};

/* Subcommand types. */
enum
{
DSMSG_SELECT_SET,
DSMSG_SELECT_QUERY
};

enum
{
DSMSG_MAPINFO_BEGIN = 0x01,
DSMSG_MAPINFO_NEXT = 0x02,
DSMSG_MAPINFO_SPECIFIC = 0x04,
DSMSG_MAPINFO_ELF = 0x80,
};

enum
{
DSMSG_LOAD_DEBUG,
DSMSG_LOAD_RUN,
DSMSG_LOAD_RUN_PERSIST,
DSMSG_LOAD_INHERIT_ENV = 0x80
};

enum
{
DSMSG_KILL_PIDTID,
DSMSG_KILL_PID,
DSMSG_KILL_PIDS
};

enum
{
DSMSG_STOP_PID,
DSMSG_STOP_PIDS
};

enum
{
DSMSG_MEM_VIRTUAL,
DSMSG_MEM_PHYSICAL,
DSMSG_MEM_IO,
DSMSG_MEM_BASEREL
};

enum
{
DSMSG_REG_GENERAL,
DSMSG_REG_FLOAT,
DSMSG_REG_SYSTEM,
DSMSG_REG_ALT,
DSMSG_REG_END
};

enum
{
DSMSG_RUN,
DSMSG_RUN_COUNT,
DSMSG_RUN_RANGE,
};

enum
{
DSMSG_BRK_EXEC = 0x0001, /* Execution breakpoint. */
DSMSG_BRK_RD = 0x0002, /* Read access (fail if not supported). */
DSMSG_BRK_WR = 0x0004, /* Write access (fail if not supported). */
DSMSG_BRK_RW = 0x0006, /* Read or write access (fail if not supported). */
DSMSG_BRK_MODIFY = 0x0008, /* Memory modified. */
DSMSG_BRK_RDM = 0x000a, /* Read access if suported otherwise modified. */
DSMSG_BRK_WRM = 0x000c, /* Write access if suported otherwise modified. */
DSMSG_BRK_RWM = 0x000e, /* Read or write access if suported otherwise modified. */
DSMSG_BRK_HW = 0x0010, /* Only use hardware debugging (i.e. no singlestep). */
};

enum
{
DSMSG_PIDLIST_BEGIN,
DSMSG_PIDLIST_NEXT,
DSMSG_PIDLIST_SPECIFIC,
DSMSG_PIDLIST_SPECIFIC_TID, /* *_TID - send starting tid for the request, */
}; /* and the response will have total to be sent. */

enum
{
DSMSG_CWD_QUERY,
DSMSG_CWD_SET,
};

enum
{
DSMSG_ENV_CLEARARGV,
DSMSG_ENV_ADDARG,
DSMSG_ENV_CLEARENV,
DSMSG_ENV_SETENV,
DSMSG_ENV_SETENV_MORE
};

enum
{
DSMSG_PROTOVER_MINOR = 0x000000FF, /* bit field (status & DSMSG_PROTOVER_MAJOR) */
DSMSG_PROTOVER_MAJOR = 0x0000FF00, /* bit field (status & DSMSG_PROTOVER_MINOR) */
};

enum
{
DSMSG_NOTIFY_PIDLOAD, /* 0 */
DSMSG_NOTIFY_TIDLOAD, /* 1 */
DSMSG_NOTIFY_DLLLOAD, /* 2 */
DSMSG_NOTIFY_PIDUNLOAD, /* 3 */
DSMSG_NOTIFY_TIDUNLOAD, /* 4 */
DSMSG_NOTIFY_DLLUNLOAD, /* 5 */
DSMSG_NOTIFY_BRK, /* 6 */
DSMSG_NOTIFY_STEP, /* 7 */
DSMSG_NOTIFY_SIGEV, /* 8 */
DSMSG_NOTIFY_STOPPED /* 9 */
};

/* Messages sent to the target. DStMsg_* (t - for target messages). */

/* Connect to the agent running on the target. */
typedef struct
{
struct DShdr hdr;
unsigned char major;
unsigned char minor;
unsigned char spare[2];
} DStMsg_connect_t;

/* Disconnect from the agent running on the target. */
typedef struct
{
struct DShdr hdr;
} DStMsg_disconnect_t;

/* Select a pid, tid for subsequent messages or query their validity. */
typedef struct
{
struct DShdr hdr;
int pid;
int tid;
} DStMsg_select_t;

/* Return information on what is at the specified virtual address.
If nothing is there we return info on the next thing in the address. */
typedef struct
{
struct DShdr hdr;
int pid;
int addr;
} DStMsg_mapinfo_t;

/* Load a new process into memory for a filesystem. */
typedef struct
{
struct DShdr hdr;
int argc;
int envc;
char cmdline[DS_DATA_MAX_SIZE];
} DStMsg_load_t;

/* Attach to an already running process. */
typedef struct
{
struct DShdr hdr;
int pid;
} DStMsg_attach_t;

/* Detach from a running process which was attached to or loaded. */
typedef struct
{
struct DShdr hdr;
int pid;
} DStMsg_detach_t;

/* Set a signal on a process. */
typedef struct
{
struct DShdr hdr;
int signo;
} DStMsg_kill_t;

/* Stop one or more processes/threads. */
typedef struct
{
struct DShdr hdr;
} DStMsg_stop_t;

/* Memory read request. */
typedef struct
{
struct DShdr hdr;
unsigned spare0;
unsigned long long addr;
unsigned short size;
} DStMsg_memrd_t;

/* Memory write request. */
typedef struct
{
struct DShdr hdr;
unsigned spare0;
unsigned long long addr;
unsigned char data[DS_DATA_MAX_SIZE];
} DStMsg_memwr_t;

/* Register read request. */
typedef struct
{
struct DShdr hdr;
unsigned short offset;
unsigned short size;
} DStMsg_regrd_t;

/* Register write request. */
typedef struct
{
struct DShdr hdr;
unsigned short offset;
unsigned char data[DS_DATA_MAX_SIZE];
} DStMsg_regwr_t;

/* Run. */
typedef struct
{
struct DShdr hdr;
union
{
unsigned count;
unsigned addr[2];
} step;
} DStMsg_run_t;

/* Break. */
typedef struct
{
struct DShdr hdr;
unsigned addr;
unsigned size;
} DStMsg_brk_t;

/* Open a file on the target. */
typedef struct
{
struct DShdr hdr;
int mode;
int perms;
char pathname[DS_DATA_MAX_SIZE];
} DStMsg_fileopen_t;

/* Read a file on the target. */
typedef struct
{
struct DShdr hdr;
unsigned short size;
} DStMsg_filerd_t;

/* Write a file on the target. */
typedef struct
{
struct DShdr hdr;
unsigned char data[DS_DATA_MAX_SIZE];
} DStMsg_filewr_t;

/* Close a file on the target. */
typedef struct
{
struct DShdr hdr;
int mtime;
} DStMsg_fileclose_t;

/* Get pids and process names in the system. */
typedef struct
{
struct DShdr hdr;
int pid; /* Only valid for type subtype SPECIFIC. */
int tid; /* Tid to start reading from. */
} DStMsg_pidlist_t;

/* Set current working directory of process. */
typedef struct
{
struct DShdr hdr;
unsigned char path[DS_DATA_MAX_SIZE];
} DStMsg_cwd_t;

/* Clear, set, get environment for new process. */
typedef struct
{
struct DShdr hdr;
char data[DS_DATA_MAX_SIZE];
} DStMsg_env_t;

/* Get the base address of a process. */
typedef struct
{
struct DShdr hdr;
} DStMsg_baseaddr_t;

/* Send pdebug protocol version info, get the same in response_ok_status. */
typedef struct
{
struct DShdr hdr;
unsigned char major;
unsigned char minor;
} DStMsg_protover_t;

/* Handle signal message. */
typedef struct
{
struct DShdr hdr;
unsigned char signals[QNXNTO_NSIG];
unsigned sig_to_pass;
} DStMsg_handlesig_t;

/* Get some cpu info. */
typedef struct
{
struct DShdr hdr;
unsigned spare;
} DStMsg_cpuinfo_t;

/* Messages sent to the host. DStMsg_* (h - for host messages). */

/* Notify host that something happened it needs to know about. */
#define NOTIFY_HDR_SIZE offsetof(DShMsg_notify_t, un)
#define NOTIFY_MEMBER_SIZE(member) sizeof(member)

typedef struct
{
struct DShdr hdr;
int pid;
int tid;
union
{
struct
{
unsigned codeoff;
unsigned dataoff;
unsigned short ostype;
unsigned short cputype;
unsigned cpuid; /* CPU dependant value. */
char name[DS_DATA_MAX_SIZE];
} pidload;
struct
{
int status;
} pidunload;
struct
{
int status;
unsigned char faulted;
unsigned char reserved[3];
} pidunload_v3;
struct
{
unsigned ip;
unsigned dp;
unsigned flags; /* Defined in <sys/debug.h>. */
} brk;
struct
{
unsigned ip;
unsigned lastip;
} step;
struct
{
int signo;
int code;
int value;
} sigev;
} un;
} DShMsg_notify_t;

/* Responses to a message. DSrMsg_* (r - for response messages). */

/* Error response packet. */
typedef struct
{
struct DShdr hdr;
int err;
} DSrMsg_err_t;

/* Simple OK response. */
typedef struct
{
struct DShdr hdr;
} DSrMsg_ok_t;

/* Simple OK response with a result. Used where limited data needs
to be returned. For example, if the number of bytes which were
successfully written was less than requested on any write cmd the
status will be the number actually written.
The 'subcmd' will always be zero. */
typedef struct
{
struct DShdr hdr;
int status;
} DSrMsg_okstatus_t;

/* The following structures overlay data[..] on a DSrMsg_okdata_t. */
struct dslinkmap
{
unsigned addr;
unsigned size;
unsigned flags;
unsigned debug_vaddr;
unsigned long long offset;
};

struct dsmapinfo
{
struct dsmapinfo *next;
unsigned spare0;
unsigned long long ino;
unsigned dev;
unsigned spare1;
struct dslinkmap text;
struct dslinkmap data;
char name[256];
};

struct dspidlist
{
int pid;
int num_tids; /* Num of threads this pid has. */
int spare[6];
struct tidinfo
{
short tid;
unsigned char state;
unsigned char flags;
} tids[1]; /* Variable length terminated by tid==0. */
char name[1]; /* Variable length terminated by \0. */
};

struct dscpuinfo
{
unsigned cpuflags;
unsigned spare1;
unsigned spare2;
unsigned spare3;
};

/* Long OK response with 0..DS_DATA_MAX_SIZE data.
The 'subcmd' will always be zero. */
typedef struct
{
struct DShdr hdr;
unsigned char data[DS_DATA_MAX_SIZE];
} DSrMsg_okdata_t;

/* A union of all possible messages and responses. */
typedef union
{
struct DShdr hdr;
DStMsg_connect_t connect;
DStMsg_disconnect_t disconnect;
DStMsg_select_t select;
DStMsg_load_t load;
DStMsg_attach_t attach;
DStMsg_detach_t detach;
DStMsg_kill_t kill;
DStMsg_stop_t stop;
DStMsg_memrd_t memrd;
DStMsg_memwr_t memwr;
DStMsg_regrd_t regrd;
DStMsg_regwr_t regwr;
DStMsg_run_t run;
DStMsg_brk_t brk;
DStMsg_fileopen_t fileopen;
DStMsg_filerd_t filerd;
DStMsg_filewr_t filewr;
DStMsg_fileclose_t fileclose;
DStMsg_pidlist_t pidlist;
DStMsg_mapinfo_t mapinfo;
DStMsg_cwd_t cwd;
DStMsg_env_t env;
DStMsg_baseaddr_t baseaddr;
DStMsg_protover_t protover;
DStMsg_handlesig_t handlesig;
DStMsg_cpuinfo_t cpuinfo;
DShMsg_notify_t notify;
DSrMsg_err_t err;
DSrMsg_ok_t ok;
DSrMsg_okstatus_t okstatus;
DSrMsg_okdata_t okdata;
} DSMsg_union_t;

/* Text channel Messages: TS - Text services. */
#define TS_TEXT_MAX_SIZE 100

/* Command types. */
enum
{
TSMsg_text, /* 0 */
TSMsg_done, /* 1 */
TSMsg_start, /* 2 */
TSMsg_stop, /* 3 */
TSMsg_ack, /* 4 */
};

struct TShdr
{
unsigned char cmd;
unsigned char console;
unsigned char spare1;
unsigned char channel;
};

/* Deliver text. This message can be sent by either side.
The debugger displays it in a window. The agent gives it to a pty
which a program may be listening on. */
typedef struct
{
struct TShdr hdr;
char text[TS_TEXT_MAX_SIZE];
} TSMsg_text_t;

/* There is no longer a program connected to this console. */
typedef struct
{
struct TShdr hdr;
} TSMsg_done_t;

/* TextStart or TextStop flow controlÿ. */
typedef struct
{
struct TShdr hdr;
} TSMsg_flowctl_t;

/* Ack a flowctl message. */
typedef struct
{
struct TShdr hdr;
} TSMsg_ack_t;

#endif